Skip to content

Commit

Permalink
Update subscribed accounts when connected site authorizations are mod…
Browse files Browse the repository at this point in the history
…ified (#1412)

* Update subscribed accounts when connected site authorizations are modified

* restore udateCurrentTabsUrl and mark as deprecated

* lint
  • Loading branch information
F-OBrien authored Jul 29, 2024
1 parent b7e3211 commit aa5d99b
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ export default class Extension {
}

private updateCurrentTabs ({ urls }: RequestActiveTabsUrlUpdate) {
this.#state.udateCurrentTabsUrl(urls);
this.#state.updateCurrentTabsUrl(urls);
}

private getConnectedTabsUrl () {
Expand Down
40 changes: 33 additions & 7 deletions packages/extension-base/src/background/handlers/State.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ export default class State {

public readonly signSubject: BehaviorSubject<SigningRequest[]> = new BehaviorSubject<SigningRequest[]>([]);

public readonly authUrlSubjects: Record<string, BehaviorSubject<AuthUrlInfo>> = {};

public defaultAuthAccountSelection: string[] = [];

constructor (providers: Providers = {}) {
Expand All @@ -169,6 +171,11 @@ export default class State {

this.#authUrls = previousAuth;

// Initialize authUrlSubjects for each URL
Object.entries(previousAuth).forEach(([url, authInfo]) => {
this.authUrlSubjects[url] = new BehaviorSubject<AuthUrlInfo>(authInfo);
});

// retrieve previously set default auth accounts
const storageDefaultAuthAccounts: Record<string, string> = await chrome.storage.local.get(DEFAULT_AUTH_ACCOUNTS);
const defaultAuthString: string = storageDefaultAuthAccounts?.[DEFAULT_AUTH_ACCOUNTS] || '[]';
Expand Down Expand Up @@ -215,10 +222,6 @@ export default class State {
return this.#authUrls;
}

private set authUrls (urls: AuthUrls) {
this.#authUrls = urls;
}

private popupClose (): void {
this.#windows.forEach((id: number) =>
withErrorLog(() => chrome.windows.remove(id))
Expand All @@ -243,14 +246,24 @@ export default class State {
const complete = async (authorizedAccounts: string[] = []) => {
const { idStr, request: { origin }, url } = this.#authRequests[id];

this.#authUrls[this.stripUrl(url)] = {
const strippedUrl = this.stripUrl(url);

const authInfo: AuthUrlInfo = {
authorizedAccounts,
count: 0,
id: idStr,
origin,
url
};

this.#authUrls[strippedUrl] = authInfo;

if (!this.authUrlSubjects[strippedUrl]) {
this.authUrlSubjects[strippedUrl] = new BehaviorSubject<AuthUrlInfo>(authInfo);
} else {
this.authUrlSubjects[strippedUrl].next(authInfo);
}

await this.saveCurrentAuthList();
await this.updateDefaultAuthAccounts(authorizedAccounts);
delete this.#authRequests[id];
Expand All @@ -271,7 +284,14 @@ export default class State {
};
};

/**
* @deprecated This method is deprecated in favor of {@link updateCurrentTabs} and will be removed in a future release.
*/
public udateCurrentTabsUrl (urls: string[]) {
this.updateCurrentTabsUrl(urls);
}

public updateCurrentTabsUrl (urls: string[]) {
const connectedTabs = urls.map((url) => {
let strippedUrl = '';

Expand Down Expand Up @@ -385,6 +405,11 @@ export default class State {
delete this.#authUrls[url];
await this.saveCurrentAuthList();

if (this.authUrlSubjects[url]) {
entry.authorizedAccounts = [];
this.authUrlSubjects[url].next(entry);
}

return this.#authUrls;
}

Expand All @@ -403,9 +428,10 @@ export default class State {
this.updateIcon(shouldClose);
}

public async updateAuthorizedAccounts (authorizedAccountDiff: AuthorizedAccountsDiff): Promise<void> {
authorizedAccountDiff.forEach(([url, authorizedAccountDiff]) => {
public async updateAuthorizedAccounts (authorizedAccountsDiff: AuthorizedAccountsDiff): Promise<void> {
authorizedAccountsDiff.forEach(([url, authorizedAccountDiff]) => {
this.#authUrls[url].authorizedAccounts = authorizedAccountDiff;
this.authUrlSubjects[url].next(this.#authUrls[url]);
});

await this.saveCurrentAuthList();
Expand Down
21 changes: 18 additions & 3 deletions packages/extension-base/src/background/handlers/Tabs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@

/* global chrome */

import type { Subscription } from 'rxjs';
import type { InjectedAccount, InjectedMetadataKnown, MetadataDef, ProviderMeta } from '@polkadot/extension-inject/types';
import type { KeyringPair } from '@polkadot/keyring/types';
import type { JsonRpcResponse } from '@polkadot/rpc-provider/types';
import type { SignerPayloadJSON, SignerPayloadRaw } from '@polkadot/types/types';
import type { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
import type { MessageTypes, RequestAccountList, RequestAccountUnsubscribe, RequestAuthorizeTab, RequestRpcSend, RequestRpcSubscribe, RequestRpcUnsubscribe, RequestTypes, ResponseRpcListProviders, ResponseSigning, ResponseTypes, SubscriptionMessageTypes } from '../types.js';
import type { AuthUrlInfo, MessageTypes, RequestAccountList, RequestAccountUnsubscribe, RequestAuthorizeTab, RequestRpcSend, RequestRpcSubscribe, RequestRpcUnsubscribe, RequestTypes, ResponseRpcListProviders, ResponseSigning, ResponseTypes, SubscriptionMessageTypes } from '../types.js';
import type { AuthResponse } from './State.js';
import type State from './State.js';

import { combineLatest, type Subscription } from 'rxjs';

import { checkIfDenied } from '@polkadot/phishing';
import { keyring } from '@polkadot/ui-keyring';
import { accounts as accountsObservable } from '@polkadot/ui-keyring/observable/accounts';
Expand Down Expand Up @@ -56,6 +57,10 @@ export default class Tabs {
private filterForAuthorizedAccounts (accounts: InjectedAccount[], url: string): InjectedAccount[] {
const auth = this.#state.authUrls[this.#state.stripUrl(url)];

if (!auth) {
return [];
}

return accounts.filter(
(allAcc) =>
auth.authorizedAccounts
Expand All @@ -79,8 +84,18 @@ export default class Tabs {
private accountsSubscribeAuthorized (url: string, id: string, port: chrome.runtime.Port): string {
const cb = createSubscription<'pub(accounts.subscribe)'>(id, port);

const strippedUrl = this.#state.stripUrl(url);

const authUrlObservable = this.#state.authUrlSubjects[strippedUrl]?.asObservable();

if (!authUrlObservable) {
console.error(`No authUrlSubject found for ${strippedUrl}`);

return id;
}

this.#accountSubs[id] = {
subscription: accountsObservable.subject.subscribe((accounts: SubjectInfo): void => {
subscription: combineLatest([accountsObservable.subject, authUrlObservable]).subscribe(([accounts, _authUrlInfo]: [SubjectInfo, AuthUrlInfo]): void => {
const transformedAccounts = transformAccounts(accounts);

cb(this.filterForAuthorizedAccounts(transformedAccounts, url));
Expand Down

0 comments on commit aa5d99b

Please sign in to comment.