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