Release v1.0.0 - Major security upgrade with Argon2id encryption
- Upgrade vault encryption from PBKDF2 (1000 iterations) to Argon2id
(256MB memory, 8 iterations, 4 threads, ~3 second derivation)
- Add automatic migration from v1 to v2 vault format on unlock
- Add WebAssembly CSP support for hash-wasm Argon2id implementation
- Add NIP-42 relay authentication support for auth-required relays
- Add profile edit feature with pencil icon on identity page
- Add direct NIP-05 validation (removes NDK dependency for validation)
- Add deriving modal with progress timer during key derivation
- Add client tag "plebeian-signer" to profile events
- Fix modal colors (dark theme for visibility)
- Fix NIP-05 badge styling to include check/error indicator
- Add release zip packages for Chrome and Firefox
New files:
- projects/common/src/lib/helpers/argon2-crypto.ts
- projects/common/src/lib/helpers/websocket-auth.ts
- projects/common/src/lib/helpers/nip05-validator.ts
- projects/common/src/lib/components/deriving-modal/
- projects/{chrome,firefox}/src/app/components/profile-edit/
- releases/plebeian-signer-{chrome,firefox}-v1.0.0.zip
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -166,10 +166,19 @@ export const encryptIdentity = async function (
|
||||
return encryptedIdentity;
|
||||
};
|
||||
|
||||
/**
|
||||
* Locked vault context for decryption during unlock
|
||||
* - v1 vaults use password (PBKDF2)
|
||||
* - v2 vaults use keyBase64 (pre-derived Argon2id key)
|
||||
*/
|
||||
export type LockedVaultContext =
|
||||
| { iv: string; password: string; keyBase64?: undefined }
|
||||
| { iv: string; keyBase64: string; password?: undefined };
|
||||
|
||||
export const decryptIdentities = async function (
|
||||
this: StorageService,
|
||||
identities: Identity_ENCRYPTED[],
|
||||
withLockedVault: { iv: string; password: string } | undefined = undefined
|
||||
withLockedVault: LockedVaultContext | undefined = undefined
|
||||
): Promise<Identity_DECRYPTED[]> {
|
||||
const decryptedIdentities: Identity_DECRYPTED[] = [];
|
||||
|
||||
@@ -188,7 +197,7 @@ export const decryptIdentities = async function (
|
||||
export const decryptIdentity = async function (
|
||||
this: StorageService,
|
||||
identity: Identity_ENCRYPTED,
|
||||
withLockedVault: { iv: string; password: string } | undefined = undefined
|
||||
withLockedVault: LockedVaultContext | undefined = undefined
|
||||
): Promise<Identity_DECRYPTED> {
|
||||
if (typeof withLockedVault === 'undefined') {
|
||||
const decryptedIdentity: Identity_DECRYPTED = {
|
||||
@@ -201,30 +210,62 @@ export const decryptIdentity = async function (
|
||||
return decryptedIdentity;
|
||||
}
|
||||
|
||||
// v2: Use pre-derived key
|
||||
if (withLockedVault.keyBase64) {
|
||||
const decryptedIdentity: Identity_DECRYPTED = {
|
||||
id: await this.decryptWithLockedVaultV2(
|
||||
identity.id,
|
||||
'string',
|
||||
withLockedVault.iv,
|
||||
withLockedVault.keyBase64
|
||||
),
|
||||
nick: await this.decryptWithLockedVaultV2(
|
||||
identity.nick,
|
||||
'string',
|
||||
withLockedVault.iv,
|
||||
withLockedVault.keyBase64
|
||||
),
|
||||
createdAt: await this.decryptWithLockedVaultV2(
|
||||
identity.createdAt,
|
||||
'string',
|
||||
withLockedVault.iv,
|
||||
withLockedVault.keyBase64
|
||||
),
|
||||
privkey: await this.decryptWithLockedVaultV2(
|
||||
identity.privkey,
|
||||
'string',
|
||||
withLockedVault.iv,
|
||||
withLockedVault.keyBase64
|
||||
),
|
||||
};
|
||||
return decryptedIdentity;
|
||||
}
|
||||
|
||||
// v1: Use password (PBKDF2)
|
||||
const decryptedIdentity: Identity_DECRYPTED = {
|
||||
id: await this.decryptWithLockedVault(
|
||||
identity.id,
|
||||
'string',
|
||||
withLockedVault.iv,
|
||||
withLockedVault.password
|
||||
withLockedVault.password!
|
||||
),
|
||||
nick: await this.decryptWithLockedVault(
|
||||
identity.nick,
|
||||
'string',
|
||||
withLockedVault.iv,
|
||||
withLockedVault.password
|
||||
withLockedVault.password!
|
||||
),
|
||||
createdAt: await this.decryptWithLockedVault(
|
||||
identity.createdAt,
|
||||
'string',
|
||||
withLockedVault.iv,
|
||||
withLockedVault.password
|
||||
withLockedVault.password!
|
||||
),
|
||||
privkey: await this.decryptWithLockedVault(
|
||||
identity.privkey,
|
||||
'string',
|
||||
withLockedVault.iv,
|
||||
withLockedVault.password
|
||||
withLockedVault.password!
|
||||
),
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user