1+ import { Injectable } from "@angular/core" ;
2+
3+ export interface SecureStoragePort {
4+ save ( service : string , value : string ) : Promise < void > ;
5+ saveSession ( service : string , value : string ) : void ;
6+ retrieve ( service : string ) : Promise < string | null > ;
7+ delete ( service : string ) : Promise < void > ;
8+ }
9+
10+ type TauriStorage = {
11+ invoke ?: ( command : string , args ?: Record < string , unknown > ) => Promise < unknown > ;
12+ } ;
13+
14+ @Injectable ( { providedIn : "root" } )
15+ export class SecureStorageService implements SecureStoragePort {
16+ private readonly session = new Map < string , string > ( ) ;
17+
18+ async save ( service : string , value : string ) : Promise < void > {
19+ const tauri = this . tauri ( ) ;
20+ if ( tauri ?. invoke ) {
21+ await tauri . invoke ( "secure_storage_save" , { service, value } ) ;
22+ return ;
23+ }
24+ this . session . set ( service , value ) ;
25+ }
26+
27+ saveSession ( service : string , value : string ) : void {
28+ this . session . set ( service , value ) ;
29+ }
30+
31+ async retrieve ( service : string ) : Promise < string | null > {
32+ const tauri = this . tauri ( ) ;
33+ if ( tauri ?. invoke ) {
34+ const value = await tauri . invoke ( "secure_storage_retrieve" , { service } ) ;
35+ return typeof value === "string" ? value : null ;
36+ }
37+ return this . session . get ( service ) ?? null ;
38+ }
39+
40+ async delete ( service : string ) : Promise < void > {
41+ const tauri = this . tauri ( ) ;
42+ if ( tauri ?. invoke ) {
43+ await tauri . invoke ( "secure_storage_delete" , { service } ) ;
44+ return ;
45+ }
46+ this . session . delete ( service ) ;
47+ }
48+
49+ masked ( service : string ) : string {
50+ return this . session . has ( service ) ? "********" : "" ;
51+ }
52+
53+ clearSession ( ) : void {
54+ this . session . clear ( ) ;
55+ }
56+
57+ private tauri ( ) : TauriStorage | undefined {
58+ return ( globalThis as { __TAURI__ ?: TauriStorage } ) . __TAURI__ ;
59+ }
60+ }
0 commit comments