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:
@@ -3,6 +3,7 @@ import { FormsModule } from '@angular/forms';
|
||||
import { Router } from '@angular/router';
|
||||
import {
|
||||
ConfirmComponent,
|
||||
DerivingModalComponent,
|
||||
NostrHelper,
|
||||
ProfileMetadataService,
|
||||
StartupService,
|
||||
@@ -14,10 +15,11 @@ import { getNewStorageServiceConfig } from '../../common/data/get-new-storage-se
|
||||
selector: 'app-vault-login',
|
||||
templateUrl: './vault-login.component.html',
|
||||
styleUrl: './vault-login.component.scss',
|
||||
imports: [FormsModule, ConfirmComponent],
|
||||
imports: [FormsModule, ConfirmComponent, DerivingModalComponent],
|
||||
})
|
||||
export class VaultLoginComponent implements AfterViewInit {
|
||||
@ViewChild('passwordInputElement') passwordInput!: ElementRef<HTMLInputElement>;
|
||||
@ViewChild('derivingModal') derivingModal!: DerivingModalComponent;
|
||||
|
||||
loginPassword = '';
|
||||
showInvalidPasswordAlert = false;
|
||||
@@ -40,24 +42,38 @@ export class VaultLoginComponent implements AfterViewInit {
|
||||
}
|
||||
|
||||
async loginVault() {
|
||||
console.log('[login] loginVault called');
|
||||
if (!this.loginPassword) {
|
||||
console.log('[login] No password, returning');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('[login] Showing deriving modal');
|
||||
// Show deriving modal during key derivation (~3-6 seconds)
|
||||
this.derivingModal.show('Unlocking vault');
|
||||
|
||||
try {
|
||||
console.log('[login] Calling unlockVault...');
|
||||
await this.#storage.unlockVault(this.loginPassword);
|
||||
|
||||
// Fetch profile metadata for all identities in the background
|
||||
this.#fetchAllProfiles();
|
||||
|
||||
this.#router.navigateByUrl('/home/identity');
|
||||
console.log('[login] unlockVault succeeded!');
|
||||
} catch (error) {
|
||||
console.error('[login] unlockVault FAILED:', error);
|
||||
this.derivingModal.hide();
|
||||
this.showInvalidPasswordAlert = true;
|
||||
console.log(error);
|
||||
window.setTimeout(() => {
|
||||
this.showInvalidPasswordAlert = false;
|
||||
}, 2000);
|
||||
return;
|
||||
}
|
||||
|
||||
// Unlock succeeded - hide modal and navigate
|
||||
console.log('[login] Hiding modal and navigating');
|
||||
this.derivingModal.hide();
|
||||
|
||||
// Fetch profile metadata for all identities in the background
|
||||
this.#fetchAllProfiles();
|
||||
|
||||
this.#router.navigateByUrl('/home/identity');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user