vault-login.component.ts raw
1 import { AfterViewInit, Component, ElementRef, inject, ViewChild } from '@angular/core';
2 import { FormsModule } from '@angular/forms';
3 import { Router } from '@angular/router';
4 import {
5 ConfirmComponent,
6 DerivingModalComponent,
7 LoggerService,
8 NostrHelper,
9 ProfileMetadataService,
10 StartupService,
11 StorageService,
12 } from '@common';
13 import { getNewStorageServiceConfig } from '../../common/data/get-new-storage-service-config';
14
15 @Component({
16 selector: 'app-vault-login',
17 templateUrl: './vault-login.component.html',
18 styleUrl: './vault-login.component.scss',
19 imports: [FormsModule, ConfirmComponent, DerivingModalComponent],
20 })
21 export class VaultLoginComponent implements AfterViewInit {
22 @ViewChild('passwordInputElement') passwordInput!: ElementRef<HTMLInputElement>;
23 @ViewChild('derivingModal') derivingModal!: DerivingModalComponent;
24
25 loginPassword = '';
26 showInvalidPasswordAlert = false;
27
28 readonly #storage = inject(StorageService);
29 readonly router = inject(Router);
30 readonly #startup = inject(StartupService);
31 readonly #profileMetadata = inject(ProfileMetadataService);
32 readonly #logger = inject(LoggerService);
33
34 ngAfterViewInit() {
35 this.passwordInput.nativeElement.focus();
36 }
37
38 toggleType(element: HTMLInputElement) {
39 if (element.type === 'password') {
40 element.type = 'text';
41 } else {
42 element.type = 'password';
43 }
44 }
45
46 async loginVault() {
47 if (!this.loginPassword) {
48 return;
49 }
50
51 this.derivingModal.show('Unlocking vault');
52
53 try {
54 await this.#storage.unlockVault(this.loginPassword);
55 } catch (error) {
56 this.derivingModal.hide();
57 this.showInvalidPasswordAlert = true;
58 window.setTimeout(() => {
59 this.showInvalidPasswordAlert = false;
60 }, 2000);
61 return;
62 }
63
64 this.derivingModal.hide();
65 this.#logger.logVaultUnlock();
66
67 // Fetch profile metadata for all identities in the background
68 this.#fetchAllProfiles();
69
70 this.router.navigateByUrl('/home/identity');
71 }
72
73 /**
74 * Fetch profile metadata for all identities (runs in background)
75 */
76 async #fetchAllProfiles() {
77 try {
78 const identities =
79 this.#storage.getBrowserSessionHandler().browserSessionData?.identities ?? [];
80
81 if (identities.length === 0) {
82 return;
83 }
84
85 // Get all pubkeys from identities
86 const pubkeys = identities.map((identity) =>
87 NostrHelper.pubkeyFromPrivkey(identity.privkey)
88 );
89
90 // Fetch all profiles in parallel
91 await this.#profileMetadata.fetchProfiles(pubkeys);
92 } catch (error) {
93 console.error('Failed to fetch profiles:', error);
94 }
95 }
96
97 async onClickResetExtension() {
98 try {
99 this.#logger.logVaultReset();
100 await this.#storage.resetExtension();
101 this.#startup.startOver(getNewStorageServiceConfig());
102 } catch (error) {
103 console.error('reset failed:', error);
104 }
105 }
106 }
107