import { SecureStore , SecureStoreCredentials } from './SecureStore' ; import * as fs from 'fs-extra' ; interface Service { [ account ] : string ; } interface Store { [ service ] : Service ; } export class FileSystemSecureStore implements SecureStore { constructor ( private path ) { } async getPassword ( service , account ) { const store = await this . load ( ) ; if ( ! store [ service ] ) { return null ; } const password = store [ service ] [ account ] ; if ( ! password ) { return null ; } return password ; } async setPassword ( service , account , password ) { const store = await this . load ( ) ; if ( ! store [ service ] ) { store [ service ] = { } ; } store [ service ] [ account ] = password ; await this . save ( store ) ; } async deletePassword ( service , account ) { const store = await this . load ( ) ; if ( ! store [ service ] || ! store [ service ] [ account ] ) { return false ; } delete store [ service ] [ account ] ; await this . save ( store ) ; return true ; } async findCredentials ( service ) { const store = await this . load ( ) ; if ( ! store [ service ] ) { return [ ] ; } const result = [ ] ; for ( const [ account , password ] of Object . entries ( store [ service ] ) ) { result . push ( { account , password } ) ; } return result ; } async findPassword ( _service ) { throw new Error ( 'Operation not supported' ) ; } private async load ( ) { try { const data = await fs . readFile ( this . path , 'utf8' ) ; return JSON . parse ( Buffer . from ( data , 'base64' ) . toString ( 'utf8' ) ) ; } catch ( error ) { return { } ; } } private async save ( store ) { const data = Buffer . from ( JSON . stringify ( store ) , 'utf8' ) . toString ( 'base64' ) ; return fs . writeFile ( this . path , data , { encoding : 'utf8' , mode : 0o600 } ) ; } }