Fix invitee access to shared logbooks by listing collaborated logbooks in API and saving them locally on accept
This commit is contained in:
@@ -4,6 +4,7 @@ import { Ship, LogIn, UserPlus, AlertTriangle, ShieldCheck, Languages, ArrowRigh
|
|||||||
import { getActiveMasterKey, registerUser, loginUser } from '../services/auth.js'
|
import { getActiveMasterKey, registerUser, loginUser } from '../services/auth.js'
|
||||||
import { decryptJson, encryptBuffer } from '../services/crypto.js'
|
import { decryptJson, encryptBuffer } from '../services/crypto.js'
|
||||||
import { saveLogbookKey } from '../services/logbookKeys.js'
|
import { saveLogbookKey } from '../services/logbookKeys.js'
|
||||||
|
import { db } from '../services/db.js'
|
||||||
import { useDialog } from './ModalDialog.tsx'
|
import { useDialog } from './ModalDialog.tsx'
|
||||||
|
|
||||||
interface InvitationAcceptanceProps {
|
interface InvitationAcceptanceProps {
|
||||||
@@ -36,6 +37,7 @@ export default function InvitationAcceptance({ onAccepted, onCancel }: Invitatio
|
|||||||
const [ownerUsername, setOwnerUsername] = useState('')
|
const [ownerUsername, setOwnerUsername] = useState('')
|
||||||
const [decryptedTitle, setDecryptedTitle] = useState('')
|
const [decryptedTitle, setDecryptedTitle] = useState('')
|
||||||
const [logbookId, setLogbookId] = useState('')
|
const [logbookId, setLogbookId] = useState('')
|
||||||
|
const [rawEncryptedTitle, setRawEncryptedTitle] = useState('')
|
||||||
|
|
||||||
// Authentication states
|
// Authentication states
|
||||||
const [isLoggedIn, setIsLoggedIn] = useState(false)
|
const [isLoggedIn, setIsLoggedIn] = useState(false)
|
||||||
@@ -104,6 +106,8 @@ export default function InvitationAcceptance({ onAccepted, onCancel }: Invitatio
|
|||||||
setOwnerUsername(details.ownerUsername)
|
setOwnerUsername(details.ownerUsername)
|
||||||
setLogbookId(details.logbookId)
|
setLogbookId(details.logbookId)
|
||||||
|
|
||||||
|
setRawEncryptedTitle(details.encryptedTitle)
|
||||||
|
|
||||||
// Decrypt title client-side using URL key
|
// Decrypt title client-side using URL key
|
||||||
const parsed = JSON.parse(details.encryptedTitle)
|
const parsed = JSON.parse(details.encryptedTitle)
|
||||||
const title = await decryptJson(parsed.ciphertext, parsed.iv, parsed.tag, logbookKey!)
|
const title = await decryptJson(parsed.ciphertext, parsed.iv, parsed.tag, logbookKey!)
|
||||||
@@ -158,6 +162,16 @@ export default function InvitationAcceptance({ onAccepted, onCancel }: Invitatio
|
|||||||
// 3. Save key locally in Dexie
|
// 3. Save key locally in Dexie
|
||||||
await saveLogbookKey(logbookId, logbookKey)
|
await saveLogbookKey(logbookId, logbookKey)
|
||||||
|
|
||||||
|
// 3b. Save logbook index locally in Dexie so sync is triggered immediately
|
||||||
|
if (rawEncryptedTitle) {
|
||||||
|
await db.logbooks.put({
|
||||||
|
id: logbookId,
|
||||||
|
encryptedTitle: rawEncryptedTitle,
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
isSynced: 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 4. Redirect to workspace
|
// 4. Redirect to workspace
|
||||||
onAccepted(logbookId, decryptedTitle)
|
onAccepted(logbookId, decryptedTitle)
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
|||||||
@@ -15,11 +15,25 @@ const requireUser = (req: any, res: any, next: any) => {
|
|||||||
|
|
||||||
router.use(requireUser)
|
router.use(requireUser)
|
||||||
|
|
||||||
// 1. Get all logbooks for the authenticated user
|
// 1. Get all logbooks for the authenticated user (owned and shared)
|
||||||
router.get('/', async (req: any, res) => {
|
router.get('/', async (req: any, res) => {
|
||||||
try {
|
try {
|
||||||
const logbooks = await prisma.logbook.findMany({
|
const logbooks = await prisma.logbook.findMany({
|
||||||
where: { userId: req.userId },
|
where: {
|
||||||
|
OR: [
|
||||||
|
{ userId: req.userId },
|
||||||
|
{
|
||||||
|
collaborators: {
|
||||||
|
some: { userId: req.userId }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
collaborators: {
|
||||||
|
where: { userId: req.userId }
|
||||||
|
}
|
||||||
|
},
|
||||||
orderBy: { createdAt: 'desc' }
|
orderBy: { createdAt: 'desc' }
|
||||||
})
|
})
|
||||||
return res.json(logbooks)
|
return res.json(logbooks)
|
||||||
|
|||||||
Reference in New Issue
Block a user