52 lines
1.8 KiB
TypeScript
52 lines
1.8 KiB
TypeScript
import type { EncryptedPayload } from '../keyManagementEncryption'
|
|
|
|
type PasswordCredentialData = {
|
|
id: string
|
|
name: string
|
|
password: string
|
|
iconURL?: string
|
|
}
|
|
|
|
type PasswordCredentialType = new (data: PasswordCredentialData) => Credential & { id: string; password: string }
|
|
|
|
function getPasswordCredentialConstructor(): PasswordCredentialType | undefined {
|
|
if (typeof window === 'undefined') {
|
|
return undefined
|
|
}
|
|
const ctor = (window as unknown as { PasswordCredential?: PasswordCredentialType }).PasswordCredential
|
|
return ctor
|
|
}
|
|
|
|
export async function storeEncryptedKEK(encryptedKEK: EncryptedPayload): Promise<void> {
|
|
if (typeof window === 'undefined') {
|
|
throw new Error('Window not available')
|
|
}
|
|
const PasswordCredentialConstructor = getPasswordCredentialConstructor()
|
|
if (!PasswordCredentialConstructor || !navigator.credentials?.store) {
|
|
throw new Error('PasswordCredential API not available')
|
|
}
|
|
const credential = new PasswordCredentialConstructor({
|
|
id: 'nostr_kek',
|
|
name: 'Nostr KEK',
|
|
password: JSON.stringify(encryptedKEK),
|
|
iconURL: `${window.location.origin}/favicon.ico`,
|
|
})
|
|
await navigator.credentials.store(credential)
|
|
}
|
|
|
|
export async function getEncryptedKEK(): Promise<EncryptedPayload | null> {
|
|
if (typeof window === 'undefined' || !navigator.credentials?.get) {
|
|
return null
|
|
}
|
|
try {
|
|
const credential = await navigator.credentials.get({ password: true } as CredentialRequestOptions)
|
|
if (credential && 'password' in credential && typeof credential.password === 'string' && credential.id === 'nostr_kek') {
|
|
return JSON.parse(credential.password) as EncryptedPayload
|
|
}
|
|
return null
|
|
} catch (e) {
|
|
console.error('[keyManagementTwoLevel] Error retrieving encrypted KEK:', e)
|
|
return null
|
|
}
|
|
}
|