diff --git a/packages/shared/src/chat/messages.ts b/packages/shared/src/chat/messages.ts index df2e295..61754b5 100644 --- a/packages/shared/src/chat/messages.ts +++ b/packages/shared/src/chat/messages.ts @@ -91,7 +91,11 @@ export interface SendMessageParams { conversationId: string; plaintext: string; senderUserId: string; - senderDeviceId: string; + // Optional now: post-conv-keys this is pure telemetry. The 0.18 builds + // started passing a localStorage UUID that doesn't exist in the devices + // table; messages.sender_device_id RLS then 403'd every insert. Senders + // pass null (or an actually-registered device id, if they have one). + senderDeviceId?: string | null; senderPrivateKey: Uint8Array; replyToId?: string; // Optional encrypted attachments — their handles are already materialised @@ -124,7 +128,12 @@ export async function sendEncryptedMessage(params: SendMessageParams): Promise = { conversation_id: params.conversationId, sender_id: params.senderUserId, - sender_device_id: params.senderDeviceId, + // ALWAYS null until we re-introduce a real per-install devices row. + // Desktop callers currently pass a localStorage UUID (ensureInstallId) + // which doesn't exist in the devices table; the messages_insert_member + // RLS policy then 403s because the id can't be proven to belong to the + // caller. NULL satisfies the policy ("sender_device_id IS NULL OR …"). + sender_device_id: null, ciphertext: bytesToPgHex(cipher.ciphertext), nonce: bytesToPgHex(cipher.nonce), key_version: handle.keyVersion, @@ -174,7 +183,7 @@ export interface EditMessageParams { // Re-encrypts the message body with the conv-key and updates the row. // Server-side trigger enforces 24h window + sender-only rule. export async function editEncryptedMessage( - params: EditMessageParams & { senderUserId: string; senderDeviceId: string }, + params: EditMessageParams & { senderUserId: string; senderDeviceId?: string | null }, ): Promise { const ownCtx: OwnUserCtx = { userId: params.senderUserId,