fix(auth): store BankID personnummer ciphertext as raw bytea, not JSON-serialized Buffer (#1233)
Both writers of bankid_identities.personal_number_enc passed a raw Buffer
to supabase-js, which PostgREST serializes as JSON: every row stored the
literal text {"type":"Buffer","data":[...]} instead of iv|tag|ciphertext
bytes, so decryptPersonalNumber could never have read them (issue #1232).
- encryptPersonalNumberForStorage(): hex-encode for PostgREST bytea input
- decryptStoredPersonalNumber(): tolerant decode (raw bytea read-back,
legacy JSON-Buffer text, Buffer, serialized object)
- migration 20260727170000 rewrites existing rows to raw bytes; prefix
guard keeps it idempotent and skips already-raw rows. Conversion SQL
verified read-only against prod: converted bytes decrypt with the live
key (GCM tag valid, 12-digit result).
Closes #1232
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
88099f5390
commit
ff205951b1
@@ -27,7 +27,7 @@ import { TICAPIError } from './lib/tic-types'
|
||||
import type { TICCompanyProfile, TICFinancialReportSummary } from './lib/tic-types'
|
||||
import type { BankIdCompleteRequest } from './lib/bankid-types'
|
||||
import type { CompanyLookupResult } from '@/lib/company-lookup/types'
|
||||
import { hashPersonalNumber, encryptPersonalNumber } from '@/lib/auth/bankid'
|
||||
import { hashPersonalNumber, encryptPersonalNumberForStorage } from '@/lib/auth/bankid'
|
||||
import { requireAuth } from '@/lib/auth/require-auth'
|
||||
import { createServiceClient } from '@/lib/supabase/server'
|
||||
import { createLogger } from '@/lib/logger'
|
||||
@@ -1046,7 +1046,7 @@ export const ticExtension: Extension = {
|
||||
.insert({
|
||||
user_id: userId,
|
||||
personal_number_hash: pnrHash,
|
||||
personal_number_enc: encryptPersonalNumber(personalNumber),
|
||||
personal_number_enc: encryptPersonalNumberForStorage(personalNumber),
|
||||
given_name: givenName,
|
||||
surname,
|
||||
})
|
||||
@@ -1190,7 +1190,7 @@ export const ticExtension: Extension = {
|
||||
.insert({
|
||||
user_id: userId,
|
||||
personal_number_hash: pnrHash,
|
||||
personal_number_enc: encryptPersonalNumber(personalNumber),
|
||||
personal_number_enc: encryptPersonalNumberForStorage(personalNumber),
|
||||
given_name: givenName,
|
||||
surname,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user