Fall back to memory password storage if keytar is not available

Summary:
Not in all environments keytar is available, but still it will be useful to be able to login to intern with Flipper, even for temporarily sessions. This solution falls back to in memory storage.

Note that the underlying assuption is that multiple different users are not connected to the same Flipper server, as this would share their session!

https://fb.workplace.com/groups/flippersupport/permalink/1498550730625580/

Reviewed By: passy

Differential Revision: D41218132

fbshipit-source-id: 6e518d742df639bfbdc9a36ed1fa56ecb363a0b0
This commit is contained in:
Michel Weststrate
2022-11-11 08:28:25 -08:00
committed by Facebook GitHub Bot
parent 79bf56e72c
commit 7626453f55

View File

@@ -19,11 +19,17 @@ export type KeytarModule = {
}; };
export class KeytarManager { export class KeytarManager {
private memoryFallback = new Map<string, string>();
constructor(private keytar: KeytarModule | undefined) {} constructor(private keytar: KeytarModule | undefined) {}
public async writeKeychain(service: string, password: string): Promise<void> { public async writeKeychain(service: string, password: string): Promise<void> {
if (this.keytar == null) { if (this.keytar == null) {
throw new Error('Keytar is not available.'); console.warn(
'Keytar is not available, using session only memory storage as fallback',
);
this.memoryFallback.set(service, password);
return;
} }
await this.keytar.deletePassword(service, os.userInfo().username); await this.keytar.deletePassword(service, os.userInfo().username);
@@ -31,17 +37,17 @@ export class KeytarManager {
} }
public async unsetKeychain(service: string): Promise<void> { public async unsetKeychain(service: string): Promise<void> {
await this.keytar?.deletePassword(service, os.userInfo().username); if (this.keytar) {
await this.keytar.deletePassword(service, os.userInfo().username);
} else {
this.memoryFallback.delete(service);
}
} }
public async retrieveToken(service: string): Promise<string> { public async retrieveToken(service: string): Promise<string> {
if (this.keytar == null) { const token = this.keytar
throw new Error('Keytar is not available.'); ? await this.keytar.getPassword(service, os.userInfo().username)
} : this.memoryFallback.get(service);
const token = await this.keytar.getPassword(
service,
os.userInfo().username,
);
if (!token) { if (!token) {
throw new UserNotSignedInError(); throw new UserNotSignedInError();
} }