fix(realtime): handle base64 bytea payloads from postgres_changes
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "ChatApp",
|
"productName": "ChatApp",
|
||||||
"version": "0.3.4",
|
"version": "0.3.5",
|
||||||
"identifier": "com.meinname.chatapp",
|
"identifier": "com.meinname.chatapp",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "pnpm vite:dev",
|
"beforeDevCommand": "pnpm vite:dev",
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
type MessageWithCipher,
|
type MessageWithCipher,
|
||||||
sendEncryptedMessage,
|
sendEncryptedMessage,
|
||||||
} from '@chat-app/shared/chat';
|
} from '@chat-app/shared/chat';
|
||||||
import { bytesToPgHex, pgHexToBytes } from '@chat-app/shared/supabase';
|
import { bytesToPgHex, pgBytesToBytes } from '@chat-app/shared/supabase';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
|
|
||||||
import { devLocalSecretStore } from './secretStore';
|
import { devLocalSecretStore } from './secretStore';
|
||||||
@@ -44,8 +44,8 @@ function rowToMessage(row: Record<string, unknown>): MessageWithCipher {
|
|||||||
editedAt: row.edited_at ? String(row.edited_at) : null,
|
editedAt: row.edited_at ? String(row.edited_at) : null,
|
||||||
deletedAt: row.deleted_at ? String(row.deleted_at) : null,
|
deletedAt: row.deleted_at ? String(row.deleted_at) : null,
|
||||||
createdAt: String(row.created_at),
|
createdAt: String(row.created_at),
|
||||||
ciphertext: pgHexToBytes(String(row.ciphertext ?? '\\x')),
|
ciphertext: pgBytesToBytes(String(row.ciphertext ?? '\\x')),
|
||||||
nonce: pgHexToBytes(String(row.nonce ?? '\\x')),
|
nonce: pgBytesToBytes(String(row.nonce ?? '\\x')),
|
||||||
keyVersion: typeof row.key_version === 'number' ? row.key_version : 1,
|
keyVersion: typeof row.key_version === 'number' ? row.key_version : 1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,3 +23,20 @@ export function pgHexToBytes(hex: string): Uint8Array {
|
|||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Accepts either:
|
||||||
|
// - PostgREST/REST `\x<hex>` strings (what the .from('table').select() path
|
||||||
|
// returns for bytea), or
|
||||||
|
// - Realtime `postgres_changes` payloads, which encode bytea as plain
|
||||||
|
// base64 (no `\x` prefix).
|
||||||
|
// Useful when the same row can arrive through both paths in the same UI.
|
||||||
|
export function pgBytesToBytes(value: string): Uint8Array {
|
||||||
|
if (value.startsWith('\\x')) {
|
||||||
|
return pgHexToBytes(value);
|
||||||
|
}
|
||||||
|
// Assume base64 (the realtime serializer's default for bytea).
|
||||||
|
const bin = atob(value);
|
||||||
|
const out = new Uint8Array(bin.length);
|
||||||
|
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user