@@ -14,8 +14,8 @@ export class SecretsManager implements ISecretsManager {
14
14
return this . _connector . fetch ( id ) ;
15
15
}
16
16
17
- async set ( secret : ISecret ) : Promise < void > {
18
- this . _connector . save ( secret . id , secret ) ;
17
+ async set ( id : string , secret : ISecret ) : Promise < void > {
18
+ this . _connector . save ( id , secret ) ;
19
19
}
20
20
21
21
async remove ( id : string ) : Promise < void > {
@@ -26,5 +26,64 @@ export class SecretsManager implements ISecretsManager {
26
26
return ( await this . _connector . list ( namespace ) ) . ids ;
27
27
}
28
28
29
+ private _onchange = ( e : Event ) : void => {
30
+ const target = e . target as HTMLInputElement ;
31
+ const attachedId = target . dataset . secretsId ;
32
+ if ( attachedId ) {
33
+ const splitId = attachedId . split ( ':' ) ;
34
+ const namespace = splitId . shift ( ) ;
35
+ const id = splitId . join ( ':' ) ;
36
+ if ( namespace && id ) {
37
+ this . set ( attachedId , { namespace, id, value : target . value } ) ;
38
+ }
39
+ }
40
+ } ;
41
+
42
+ async attach (
43
+ namespace : string ,
44
+ id : string ,
45
+ input : HTMLInputElement
46
+ ) : Promise < void > {
47
+ const attachedId = `${ namespace } :${ id } ` ;
48
+ const attachedInput = this . _attachedInputs . get ( attachedId ) ;
49
+
50
+ // Do not attach the input if it is already attached.
51
+ if ( attachedInput === input ) {
52
+ return ;
53
+ }
54
+
55
+ // Detach the previous input.
56
+ if ( attachedInput ) {
57
+ this . detach ( namespace , id ) ;
58
+ }
59
+ this . _attachedInputs . set ( attachedId , input ) ;
60
+
61
+ // Fill the password if the input is empty and a value is fetched by the data
62
+ // connector.
63
+ input . dataset . secretsId = attachedId ;
64
+ const value = await this . get ( attachedId ) ;
65
+ if ( ! input . value && value ) {
66
+ input . value = value . value ;
67
+ }
68
+ input . addEventListener ( 'change' , this . _onchange ) ;
69
+ }
70
+
71
+ detach ( namespace : string , id : string ) : void {
72
+ const attachedId = `${ namespace } :${ id } ` ;
73
+ const input = this . _attachedInputs . get ( attachedId ) ;
74
+ if ( input ) {
75
+ input . removeEventListener ( 'change' , this . _onchange ) ;
76
+ }
77
+ this . _attachedInputs . delete ( attachedId ) ;
78
+ }
79
+
80
+ async detachAll ( namespace : string ) : Promise < void > {
81
+ const attachedIds = await this . list ( namespace ) ;
82
+ attachedIds . forEach ( id => {
83
+ this . detach ( namespace , id ) ;
84
+ } ) ;
85
+ }
86
+
29
87
private _connector : ISecretsConnector ;
88
+ private _attachedInputs = new Map < string , HTMLInputElement > ( ) ;
30
89
}
0 commit comments