From 5227fa9a2b6a3a2fbd9e8833fed8cf690af44eae Mon Sep 17 00:00:00 2001 From: Jack Works Date: Wed, 16 Feb 2022 17:08:09 +0800 Subject: [PATCH 1/2] feat: delegate sns query --- packages/mask/src/social-network/ui.ts | 11 ++++++++++ packages/mask/src/utils/native-rpc/Web.ts | 24 +++++++++++++++++++++- packages/public-api/src/types/index.ts | 25 +++++++++++++++++++++++ packages/public-api/src/web.ts | 2 ++ packages/public-api/tsconfig.json | 4 +++- packages/shared-base/src/Messages/Mask.ts | 1 + 6 files changed, 65 insertions(+), 2 deletions(-) diff --git a/packages/mask/src/social-network/ui.ts b/packages/mask/src/social-network/ui.ts index f90b55fbbe35..7a520bc1a68f 100644 --- a/packages/mask/src/social-network/ui.ts +++ b/packages/mask/src/social-network/ui.ts @@ -129,6 +129,17 @@ export async function activateSocialNetworkUIInner(ui_deferred: SocialNetworkUI. function $unknownIdentityResolution() { const provider = ui.collecting.identityProvider provider?.start(signal) + MaskMessages.events.Native_delegate_getCurrentDetectedProfile.on( + ([type]) => { + if (type === 'request') { + MaskMessages.events.Native_delegate_getCurrentDetectedProfile.sendToBackgroundPage([ + 'response', + provider?.recognized.value.identifier.toText(), + ]) + } + }, + { signal }, + ) if (provider?.hasDeprecatedPlaceholderName) { provider.recognized.addListener((id) => { if (signal.aborted) return diff --git a/packages/mask/src/utils/native-rpc/Web.ts b/packages/mask/src/utils/native-rpc/Web.ts index 5710a140a93e..5415cd1e13cf 100644 --- a/packages/mask/src/utils/native-rpc/Web.ts +++ b/packages/mask/src/utils/native-rpc/Web.ts @@ -7,7 +7,7 @@ import type { AESJsonWebKey as Native_AESJsonWebKey, } from '@masknet/public-api' import { encodeArrayBuffer, encodeText } from '@dimensiondev/kit' -import { Environment, assertEnvironment } from '@dimensiondev/holoflows-kit' +import { Environment, assertEnvironment, isEnvironment } from '@dimensiondev/holoflows-kit' import { ECKeyIdentifier, Identifier, ProfileIdentifier } from '@masknet/shared-base' import { definedSocialNetworkWorkers } from '../../social-network/define' import { launchPageSettings } from '../../settings/settings' @@ -293,6 +293,28 @@ export const MaskNetworkAPI: MaskNetworkAPIs = { const { activatedSocialNetworkUI } = await import('../../social-network') return activatedSocialNetworkUI.collecting.identityProvider?.recognized.value.identifier.toText() }, + async getCurrentDetectedProfile_delegate_to_SNSAdaptor() { + if (isEnvironment(Environment.ManifestBackground)) { + return new Promise((resolve) => { + MaskMessages.events.Native_delegate_getCurrentDetectedProfile.sendToVisiblePages(['request']) + const removeListener = MaskMessages.events.Native_delegate_getCurrentDetectedProfile.on( + ([type, data]) => { + if (type === 'request') return + resolve(data) + removeListener() + }, + ) + setTimeout(() => { + removeListener() + resolve(undefined) + }, 500) + }) + } else { + console.warn('This should not happen.') + const { activatedSocialNetworkUI } = await import('../../social-network') + return activatedSocialNetworkUI.collecting.identityProvider?.recognized.value.identifier.toText() + } + }, get_all_indexedDB_records: async () => { const personas = await Services.Identity.queryPersonaRecordsFromIndexedDB() const profiles = await Services.Identity.queryProfileRecordFromIndexedDB() diff --git a/packages/public-api/src/types/index.ts b/packages/public-api/src/types/index.ts index 6eeb8c317c3d..318044d3afe3 100644 --- a/packages/public-api/src/types/index.ts +++ b/packages/public-api/src/types/index.ts @@ -17,6 +17,31 @@ export interface LinkedProfileDetails { } // These type MUST be sync with packages/shared-base/src/crypto/JWKType +export interface JsonWebKey { + alg?: string + crv?: string + d?: string + dp?: string + dq?: string + e?: string + ext?: boolean + k?: string + key_ops?: string[] + kty?: string + n?: string + oth?: RsaOtherPrimesInfo[] + p?: string + q?: string + qi?: string + use?: string + x?: string + y?: string +} +export interface RsaOtherPrimesInfo { + d?: string + r?: string + t?: string +} export interface EC_Public_JsonWebKey extends JsonWebKey, Nominal<'EC public'> {} export interface EC_Private_JsonWebKey extends JsonWebKey, Nominal<'EC private'> {} export interface AESJsonWebKey extends JsonWebKey, Nominal<'AES'> {} diff --git a/packages/public-api/src/web.ts b/packages/public-api/src/web.ts index d507b9b8c2b6..fe485cd5365f 100644 --- a/packages/public-api/src/web.ts +++ b/packages/public-api/src/web.ts @@ -79,7 +79,9 @@ export interface MaskNetworkAPIs { wallet_updateEthereumAccount(params: { account: string }): Promise wallet_updateEthereumChainId(params: { chainId: number }): Promise wallet_getLegacyWalletInfo(): Promise + /** @deprecated */ SNSAdaptor_getCurrentDetectedProfile(): Promise + getCurrentDetectedProfile_delegate_to_SNSAdaptor(): Promise get_all_indexedDB_records(): Promise<{ personas: PersonaRecord[] profiles: ProfileRecord[] diff --git a/packages/public-api/tsconfig.json b/packages/public-api/tsconfig.json index 79cc5a5ace48..075f17e485aa 100644 --- a/packages/public-api/tsconfig.json +++ b/packages/public-api/tsconfig.json @@ -3,7 +3,9 @@ "compilerOptions": { "rootDir": "./src/", "outDir": "./dist/", - "tsBuildInfoFile": "./dist/.tsbuildinfo" + "tsBuildInfoFile": "./dist/.tsbuildinfo", + // NOT including web or node. + "types": [] }, "include": ["./src"], // This package MUST NOT use any other package. diff --git a/packages/shared-base/src/Messages/Mask.ts b/packages/shared-base/src/Messages/Mask.ts index 8d7a3839406f..4f67a572ea90 100644 --- a/packages/shared-base/src/Messages/Mask.ts +++ b/packages/shared-base/src/Messages/Mask.ts @@ -43,6 +43,7 @@ export interface MaskSNSEvents { NFTAvatarUpdated: NFTAvatarEvent NFTAvatarTimelineUpdated: NFTAvatarEvent nftAvatarSettingDialogUpdated: NFTAvatarSettingDialogEvent + Native_delegate_getCurrentDetectedProfile: [type: 'request'] | [type: 'response', answer: string | undefined] } export interface MaskEvents extends MaskSettingsEvents, MaskMobileOnlyEvents, MaskSNSEvents { From d411bfbb7eb36a210b74f19e0d47a9998151a5f2 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Thu, 17 Feb 2022 16:25:29 +0800 Subject: [PATCH 2/2] feat: update --- .../Cancellable/NotificationsToMobile.ts | 10 +++++++ packages/mask/background/tasks/setup.hmr.ts | 2 ++ packages/mask/src/social-network/ui.ts | 25 ++++++++--------- packages/mask/src/utils/native-rpc/Web.ts | 28 +------------------ packages/public-api/src/mobile.ts | 2 ++ packages/public-api/src/web.ts | 7 ++--- packages/shared-base/src/Messages/Mask.ts | 2 +- 7 files changed, 30 insertions(+), 46 deletions(-) create mode 100644 packages/mask/background/tasks/Cancellable/NotificationsToMobile.ts diff --git a/packages/mask/background/tasks/Cancellable/NotificationsToMobile.ts b/packages/mask/background/tasks/Cancellable/NotificationsToMobile.ts new file mode 100644 index 000000000000..5f0d53bef240 --- /dev/null +++ b/packages/mask/background/tasks/Cancellable/NotificationsToMobile.ts @@ -0,0 +1,10 @@ +import { notify } from 'async-call-rpc/full' +import { MaskMessages } from '../../../shared' +import { nativeAPI, hasNativeAPI } from '../../../shared/native-rpc' +export default function NotificationsToMobile(signal: AbortSignal) { + if (!hasNativeAPI) return + + // we don't need response + const forwardToMobile = notify(nativeAPI!.api.notify_visible_detected_profile_changed) + MaskMessages.events.Native_visibleSNS_currentDetectedProfileUpdated.on(forwardToMobile, { signal }) +} diff --git a/packages/mask/background/tasks/setup.hmr.ts b/packages/mask/background/tasks/setup.hmr.ts index c272019430d5..50ae02834047 100644 --- a/packages/mask/background/tasks/setup.hmr.ts +++ b/packages/mask/background/tasks/setup.hmr.ts @@ -3,6 +3,7 @@ import * as InjectContentScript from './Cancellable/InjectContentScripts' import * as InjectContentScriptMV3 from './Cancellable/InjectContentScripts-mv3' import * as IsolatedDashboardBridge from './Cancellable/IsolatedDashboardBridge' import * as CleanupProfileDatabase from './Cancellable/CleanProfileAndAvatar' +import * as NotificationsToMobile from './Cancellable/NotificationsToMobile' type CancelableJob = { default: (signal: AbortSignal) => void } const CancelableJobs: CancelableJob[] = [ @@ -10,6 +11,7 @@ const CancelableJobs: CancelableJob[] = [ process.env.manifest === '2' ? InjectContentScript : InjectContentScriptMV3, IsolatedDashboardBridge, CleanupProfileDatabase, + NotificationsToMobile, ] const abort = new AbortController() diff --git a/packages/mask/src/social-network/ui.ts b/packages/mask/src/social-network/ui.ts index 7a520bc1a68f..f00be8ef66cd 100644 --- a/packages/mask/src/social-network/ui.ts +++ b/packages/mask/src/social-network/ui.ts @@ -128,19 +128,18 @@ export async function activateSocialNetworkUIInner(ui_deferred: SocialNetworkUI. function $unknownIdentityResolution() { const provider = ui.collecting.identityProvider - provider?.start(signal) - MaskMessages.events.Native_delegate_getCurrentDetectedProfile.on( - ([type]) => { - if (type === 'request') { - MaskMessages.events.Native_delegate_getCurrentDetectedProfile.sendToBackgroundPage([ - 'response', - provider?.recognized.value.identifier.toText(), - ]) - } - }, - { signal }, - ) - if (provider?.hasDeprecatedPlaceholderName) { + if (!provider) return + provider.start(signal) + provider.recognized.addListener((newValue, oldValue) => { + if (document.visibilityState === 'hidden') return + if (newValue.identifier.equals(oldValue.identifier)) return + if (newValue.identifier.isUnknown) return + + MaskMessages.events.Native_visibleSNS_currentDetectedProfileUpdated.sendToBackgroundPage( + newValue.identifier.toText(), + ) + }) + if (provider.hasDeprecatedPlaceholderName) { provider.recognized.addListener((id) => { if (signal.aborted) return if (id.identifier.isUnknown) return diff --git a/packages/mask/src/utils/native-rpc/Web.ts b/packages/mask/src/utils/native-rpc/Web.ts index 5415cd1e13cf..99de4f155aca 100644 --- a/packages/mask/src/utils/native-rpc/Web.ts +++ b/packages/mask/src/utils/native-rpc/Web.ts @@ -7,7 +7,7 @@ import type { AESJsonWebKey as Native_AESJsonWebKey, } from '@masknet/public-api' import { encodeArrayBuffer, encodeText } from '@dimensiondev/kit' -import { Environment, assertEnvironment, isEnvironment } from '@dimensiondev/holoflows-kit' +import { Environment, assertEnvironment } from '@dimensiondev/holoflows-kit' import { ECKeyIdentifier, Identifier, ProfileIdentifier } from '@masknet/shared-base' import { definedSocialNetworkWorkers } from '../../social-network/define' import { launchPageSettings } from '../../settings/settings' @@ -289,32 +289,6 @@ export const MaskNetworkAPI: MaskNetworkAPIs = { updatedAt: x.updatedAt.getTime(), })) }, - async SNSAdaptor_getCurrentDetectedProfile() { - const { activatedSocialNetworkUI } = await import('../../social-network') - return activatedSocialNetworkUI.collecting.identityProvider?.recognized.value.identifier.toText() - }, - async getCurrentDetectedProfile_delegate_to_SNSAdaptor() { - if (isEnvironment(Environment.ManifestBackground)) { - return new Promise((resolve) => { - MaskMessages.events.Native_delegate_getCurrentDetectedProfile.sendToVisiblePages(['request']) - const removeListener = MaskMessages.events.Native_delegate_getCurrentDetectedProfile.on( - ([type, data]) => { - if (type === 'request') return - resolve(data) - removeListener() - }, - ) - setTimeout(() => { - removeListener() - resolve(undefined) - }, 500) - }) - } else { - console.warn('This should not happen.') - const { activatedSocialNetworkUI } = await import('../../social-network') - return activatedSocialNetworkUI.collecting.identityProvider?.recognized.value.identifier.toText() - } - }, get_all_indexedDB_records: async () => { const personas = await Services.Identity.queryPersonaRecordsFromIndexedDB() const profiles = await Services.Identity.queryProfileRecordFromIndexedDB() diff --git a/packages/public-api/src/mobile.ts b/packages/public-api/src/mobile.ts index 4336502538c9..aa6f4804141e 100644 --- a/packages/public-api/src/mobile.ts +++ b/packages/public-api/src/mobile.ts @@ -8,6 +8,7 @@ import type { RelationRecord, PostRecord, } from './types' +import type { ProfileIdentifier_string } from './web' /** * APIs that both Android and iOS implements and have the same API signature @@ -112,6 +113,7 @@ export interface SharedNativeAPIs { pageOption?: PageOption }): Promise update_post(params: { post: Partial; options: { mode: 0 | 1 } }): Promise + notify_visible_detected_profile_changed(newID: ProfileIdentifier_string): Promise } /** * APIs that only implemented by iOS Mask Network diff --git a/packages/public-api/src/web.ts b/packages/public-api/src/web.ts index fe485cd5365f..fb4d55ad81ed 100644 --- a/packages/public-api/src/web.ts +++ b/packages/public-api/src/web.ts @@ -6,8 +6,8 @@ import type { PersonaRecord, ProfileRecord, RelationFavor, RelationRecord } from * Methods starts with "SNSAdaptor_" can only be called in SNS Adaptor. * Other methods can only be called in the background page. */ -type ProfileIdentifier_string = string -type PersonaIdentifier_string = string +export type ProfileIdentifier_string = string +export type PersonaIdentifier_string = string export interface MaskNetworkAPIs { app_suspended(): Promise app_resume(): Promise @@ -79,9 +79,6 @@ export interface MaskNetworkAPIs { wallet_updateEthereumAccount(params: { account: string }): Promise wallet_updateEthereumChainId(params: { chainId: number }): Promise wallet_getLegacyWalletInfo(): Promise - /** @deprecated */ - SNSAdaptor_getCurrentDetectedProfile(): Promise - getCurrentDetectedProfile_delegate_to_SNSAdaptor(): Promise get_all_indexedDB_records(): Promise<{ personas: PersonaRecord[] profiles: ProfileRecord[] diff --git a/packages/shared-base/src/Messages/Mask.ts b/packages/shared-base/src/Messages/Mask.ts index 4f67a572ea90..b3d5fc4b1237 100644 --- a/packages/shared-base/src/Messages/Mask.ts +++ b/packages/shared-base/src/Messages/Mask.ts @@ -43,7 +43,7 @@ export interface MaskSNSEvents { NFTAvatarUpdated: NFTAvatarEvent NFTAvatarTimelineUpdated: NFTAvatarEvent nftAvatarSettingDialogUpdated: NFTAvatarSettingDialogEvent - Native_delegate_getCurrentDetectedProfile: [type: 'request'] | [type: 'response', answer: string | undefined] + Native_visibleSNS_currentDetectedProfileUpdated: string } export interface MaskEvents extends MaskSettingsEvents, MaskMobileOnlyEvents, MaskSNSEvents {