@@ -14,8 +14,8 @@ export class SecretsManager implements ISecretsManager {
1414 return this . _connector . fetch ( id ) ;
1515 }
1616
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 ) ;
1919 }
2020
2121 async remove ( id : string ) : Promise < void > {
@@ -26,5 +26,64 @@ export class SecretsManager implements ISecretsManager {
2626 return ( await this . _connector . list ( namespace ) ) . ids ;
2727 }
2828
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+
2987 private _connector : ISecretsConnector ;
88+ private _attachedInputs = new Map < string , HTMLInputElement > ( ) ;
3089}
0 commit comments