From 8324ae0868d599df8e80ab316f0c1dc6ec09930b Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Thu, 1 Sep 2022 06:59:23 +0100 Subject: [PATCH] Remember last account selection for authorization (#1133) * remember last selection * nit for readability --- .gitignore | 1 + .../src/background/handlers/Extension.ts | 25 ++++++++++++------- .../src/background/handlers/State.ts | 21 +++++++++++++++- .../extension-base/src/background/types.ts | 1 + .../src/Popup/Authorize/Request.tsx | 8 ++++-- 5 files changed, 44 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index f97f47fe..b1ac1184 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ package-lock.json _book docs/html .idea +.vscode \ No newline at end of file diff --git a/packages/extension-base/src/background/handlers/Extension.ts b/packages/extension-base/src/background/handlers/Extension.ts index aa68b63f..0a557854 100644 --- a/packages/extension-base/src/background/handlers/Extension.ts +++ b/packages/extension-base/src/background/handlers/Extension.ts @@ -34,14 +34,6 @@ function getSuri (seed: string, type?: KeypairType): string { : seed; } -function transformAccounts (accounts: SubjectInfo): AccountJson[] { - return Object.values(accounts).map(({ json: { address, meta }, type }): AccountJson => ({ - address, - ...meta, - type - })); -} - function isJsonPayload (value: SignerPayloadJSON | SignerPayloadRaw): value is SignerPayloadJSON { return (value as SignerPayloadJSON).genesisHash !== undefined; } @@ -56,6 +48,15 @@ export default class Extension { this.#state = state; } + private transformAccounts (accounts: SubjectInfo): AccountJson[] { + return Object.values(accounts).map(({ json: { address, meta }, type }): AccountJson => ({ + address, + isDefaultAuthSelected: this.#state.defaultAuthAccountSelection.includes(address), + ...meta, + type + })); + } + private accountsCreateExternal ({ address, genesisHash, name }: RequestAccountCreateExternal): boolean { keyring.addExternal(address, { genesisHash, name }); @@ -127,6 +128,12 @@ export default class Extension { }); this.#state.updateAuthorizedAccounts(authorizedAccountsDiff); + + // cycle through default account selection for auth and remove any occurence of the account + const newDefaultAuthAccounts = this.#state.defaultAuthAccountSelection.filter((defaultSelectionAddress) => defaultSelectionAddress !== address); + + this.#state.updateDefaultAuthAccounts(newDefaultAuthAccounts); + keyring.forgetAccount(address); return true; @@ -181,7 +188,7 @@ export default class Extension { private accountsSubscribe (id: string, port: chrome.runtime.Port): boolean { const cb = createSubscription<'pri(accounts.subscribe)'>(id, port); const subscription = accountsObservable.subject.subscribe((accounts: SubjectInfo): void => - cb(transformAccounts(accounts)) + cb(this.transformAccounts(accounts)) ); port.onDisconnect.addListener((): void => { diff --git a/packages/extension-base/src/background/handlers/State.ts b/packages/extension-base/src/background/handlers/State.ts index b7b1696a..9609c78c 100644 --- a/packages/extension-base/src/background/handlers/State.ts +++ b/packages/extension-base/src/background/handlers/State.ts @@ -16,7 +16,7 @@ import { assert } from '@polkadot/util'; import { MetadataStore } from '../../stores'; import { withErrorLog } from './helpers'; -interface Resolver { +interface Resolver { reject: (error: Error) => void; resolve: (result: T) => void; } @@ -94,6 +94,7 @@ export enum NotificationOptions { } const AUTH_URLS_KEY = 'authUrls'; +const DEFAULT_AUTH_ACCOUNTS = 'defaultAuthAccounts'; function extractMetadata (store: MetadataStore): void { store.allMap((map): void => { @@ -158,6 +159,8 @@ export default class State { public readonly signSubject: BehaviorSubject = new BehaviorSubject([]); + public defaultAuthAccountSelection: string[] = []; + constructor (providers: Providers = {}) { this.#providers = providers; @@ -168,6 +171,12 @@ export default class State { const previousAuth = JSON.parse(authString) as AuthUrls; this.#authUrls = previousAuth; + + // retrieve previously set default auth accounts + const defaultAuthString = localStorage.getItem(DEFAULT_AUTH_ACCOUNTS) || '[]'; + const previousDefaultAuth = JSON.parse(defaultAuthString) as string[]; + + this.defaultAuthAccountSelection = previousDefaultAuth; } public get knownMetadata (): MetadataDef[] { @@ -241,6 +250,7 @@ export default class State { }; this.saveCurrentAuthList(); + this.updateDefaultAuthAccounts(authorizedAccounts); delete this.#authRequests[id]; this.updateIconAuth(true); }; @@ -266,6 +276,15 @@ export default class State { localStorage.setItem(AUTH_URLS_KEY, JSON.stringify(this.#authUrls)); } + private saveDefaultAuthAccounts () { + localStorage.setItem(DEFAULT_AUTH_ACCOUNTS, JSON.stringify(this.defaultAuthAccountSelection)); + } + + public updateDefaultAuthAccounts (newList: string[]) { + this.defaultAuthAccountSelection = newList; + this.saveDefaultAuthAccounts(); + } + private metaComplete = (id: string, resolve: (result: boolean) => void, reject: (error: Error) => void): Resolver => { const complete = (): void => { delete this.#metaRequests[id]; diff --git a/packages/extension-base/src/background/types.ts b/packages/extension-base/src/background/types.ts index e63cc507..879afad7 100644 --- a/packages/extension-base/src/background/types.ts +++ b/packages/extension-base/src/background/types.ts @@ -36,6 +36,7 @@ export interface AccountJson extends KeyringPair$Meta { isExternal?: boolean; isHardware?: boolean; isHidden?: boolean; + isDefaultAuthSelected?: boolean name?: string; parentAddress?: string; suri?: string; diff --git a/packages/extension-ui/src/Popup/Authorize/Request.tsx b/packages/extension-ui/src/Popup/Authorize/Request.tsx index e3746d02..86a80cc0 100644 --- a/packages/extension-ui/src/Popup/Authorize/Request.tsx +++ b/packages/extension-ui/src/Popup/Authorize/Request.tsx @@ -27,8 +27,12 @@ function Request ({ authId, className, isFirst, request: { origin }, url }: Prop const onAction = useContext(ActionContext); useEffect(() => { - setSelectedAccounts && setSelectedAccounts([]); - }, [setSelectedAccounts]); + const defaultAccountSelection = accounts + .filter(({ isDefaultAuthSelected }) => !!isDefaultAuthSelected) + .map(({ address }) => address); + + setSelectedAccounts && setSelectedAccounts(defaultAccountSelection); + }, [accounts, setSelectedAccounts]); const _onApprove = useCallback( (): void => {