From fbc5862df13c10e305e6761ffa09a9994f68f940 Mon Sep 17 00:00:00 2001 From: Hunain Bin Sajid Date: Thu, 4 Apr 2024 21:10:52 +0500 Subject: [PATCH 1/4] feat: refactor background js and delegate events --- src/components/credentialList.tsx | 4 +- src/components/identifierList.tsx | 7 +- src/components/selectCredential.tsx | 7 +- src/components/selectIdentifier.tsx | 10 +- src/components/signinList.tsx | 18 +- src/config/event-types.ts | 52 +++ src/config/types.ts | 8 +- src/pages/background/handlers/actionIcon.ts | 25 ++ .../background/handlers/authentication.ts | 88 +++++ src/pages/background/handlers/index.ts | 103 +++++ src/pages/background/handlers/resource.ts | 141 +++++++ src/pages/background/handlers/vendorInfo.ts | 23 ++ src/pages/background/index.ts | 369 ++---------------- src/pages/{ => content}/dialog/Dialog.tsx | 1 - .../{ => content}/dialog/popupPrompt.tsx | 2 +- src/pages/{ => content}/dialog/signin.tsx | 8 +- src/pages/content/index.tsx | 36 +- src/pages/dialog/index.css | 12 - src/pages/dialog/index.html | 12 - src/pages/dialog/index.tsx | 12 - src/pages/popup/Popup.tsx | 18 +- src/screens/permission/permission.tsx | 8 +- src/screens/signup/signup.tsx | 4 +- 23 files changed, 514 insertions(+), 454 deletions(-) create mode 100644 src/config/event-types.ts create mode 100644 src/pages/background/handlers/actionIcon.ts create mode 100644 src/pages/background/handlers/authentication.ts create mode 100644 src/pages/background/handlers/index.ts create mode 100644 src/pages/background/handlers/resource.ts create mode 100644 src/pages/background/handlers/vendorInfo.ts rename src/pages/{ => content}/dialog/Dialog.tsx (98%) rename src/pages/{ => content}/dialog/popupPrompt.tsx (91%) rename src/pages/{ => content}/dialog/signin.tsx (94%) delete mode 100644 src/pages/dialog/index.css delete mode 100644 src/pages/dialog/index.html delete mode 100644 src/pages/dialog/index.tsx diff --git a/src/components/credentialList.tsx b/src/components/credentialList.tsx index dd446b4a..8f42d44b 100644 --- a/src/components/credentialList.tsx +++ b/src/components/credentialList.tsx @@ -1,5 +1,6 @@ import { useState, useEffect } from "react"; import { useIntl } from "react-intl"; +import { UI_EVENTS } from "@config/event-types"; import { CredentialCard } from "@components/credentialCard"; import { Loader, Flex, Box, Text } from "@components/ui"; import { IMessage } from "@config/types"; @@ -11,8 +12,7 @@ export function CredentialList(): JSX.Element { const fetchCredentials = async () => { setIsLoading(true); const { data } = await chrome.runtime.sendMessage>({ - type: "fetch-resource", - subtype: "credentials", + type: UI_EVENTS.fetch_resource_credentials, }); setCredentials(data.credentials); setIsLoading(false); diff --git a/src/components/identifierList.tsx b/src/components/identifierList.tsx index 2261442f..422cfb75 100644 --- a/src/components/identifierList.tsx +++ b/src/components/identifierList.tsx @@ -1,5 +1,6 @@ import { useState, useEffect } from "react"; import { useIntl } from "react-intl"; +import { UI_EVENTS } from "@config/event-types"; import { IdentifierCard } from "@components/identifierCard"; import { Button, Box, Drawer, Flex, Text, Loader } from "@components/ui"; import { IMessage } from "@config/types"; @@ -19,8 +20,7 @@ export function IdentifierList(): JSX.Element { const fetchIdentifiers = async () => { const { data } = await chrome.runtime.sendMessage>({ - type: "fetch-resource", - subtype: "identifiers", + type: UI_EVENTS.fetch_resource_identifiers }); setAids(data.aids); }; @@ -45,8 +45,7 @@ export function IdentifierList(): JSX.Element { const { data, error } = await chrome.runtime.sendMessage< IMessage >({ - type: "create-resource", - subtype: "identifier", + type: UI_EVENTS.create_resource_identifier, data: { name }, }); if (error) { diff --git a/src/components/selectCredential.tsx b/src/components/selectCredential.tsx index 8f54f159..9392c9fa 100644 --- a/src/components/selectCredential.tsx +++ b/src/components/selectCredential.tsx @@ -1,5 +1,6 @@ import { useState, useEffect } from "react"; import { useIntl } from "react-intl"; +import { UI_EVENTS } from "@config/event-types"; import { CredentialCard } from "@components/credentialCard"; import { Button, Loader, Flex, Box } from "@components/ui"; import { IMessage } from "@config/types"; @@ -11,8 +12,7 @@ export function SelectCredential(): JSX.Element { const fetchCredentials = async () => { setIsLoading(true); const { data } = await chrome.runtime.sendMessage>({ - type: "fetch-resource", - subtype: "credentials", + type: UI_EVENTS.fetch_resource_credentials }); setCredentials(data.credentials); setIsLoading(false); @@ -20,8 +20,7 @@ export function SelectCredential(): JSX.Element { const createSigninWithCredential = async (credential: any) => { await chrome.runtime.sendMessage>({ - type: "create-resource", - subtype: "signin", + type: UI_EVENTS.create_resource_signin, data: { credential, }, diff --git a/src/components/selectIdentifier.tsx b/src/components/selectIdentifier.tsx index 594983ea..c6bd52ef 100644 --- a/src/components/selectIdentifier.tsx +++ b/src/components/selectIdentifier.tsx @@ -1,5 +1,6 @@ import { useState, useEffect } from "react"; import { useIntl } from "react-intl"; +import { UI_EVENTS } from "@config/event-types"; import { IdentifierCard } from "@components/identifierCard"; import { Box, Button, Drawer, Flex, Text, Loader } from "@components/ui"; import { IMessage } from "@config/types"; @@ -20,8 +21,7 @@ export function SelectIdentifier(): JSX.Element { const fetchIdentifiers = async () => { setIsLoading(true); const { data } = await chrome.runtime.sendMessage>({ - type: "fetch-resource", - subtype: "identifiers", + type: UI_EVENTS.fetch_resource_identifiers }); console.log("data", data); setIsLoading(false); @@ -30,8 +30,7 @@ export function SelectIdentifier(): JSX.Element { const createSigninWithIdentifiers = async (aid: any) => { await chrome.runtime.sendMessage>({ - type: "create-resource", - subtype: "signin", + type: UI_EVENTS.create_resource_signin, data: { identifier: aid, }, @@ -64,8 +63,7 @@ export function SelectIdentifier(): JSX.Element { const { data, error } = await chrome.runtime.sendMessage< IMessage >({ - type: "create-resource", - subtype: "identifier", + type: UI_EVENTS.create_resource_identifier, data: { name }, }); if (error) { diff --git a/src/components/signinList.tsx b/src/components/signinList.tsx index 706bf8ff..5824569c 100644 --- a/src/components/signinList.tsx +++ b/src/components/signinList.tsx @@ -1,5 +1,6 @@ import { useState, useEffect } from "react"; import { useIntl } from "react-intl"; +import { UI_EVENTS } from "@config/event-types"; import { SigninCard } from "@components/signinCard"; import { Loader, Flex, Box, Text } from "@components/ui"; import { IMessage, ISignin } from "@config/types"; @@ -19,19 +20,15 @@ export function SigninList(): JSX.Element { const fetchSignins = async () => { setIsLoading(true); const { data } = await chrome.runtime.sendMessage>({ - type: "fetch-resource", - subtype: "signins", + type: UI_EVENTS.fetch_resource_signins, }); setSignins(data?.signins); setIsLoading(false); }; const deleteSignin = async (id: string) => { - const { data } = await chrome.runtime.sendMessage< - IMessage - >({ - type: "delete-resource", - subtype: "signins", + const { data } = await chrome.runtime.sendMessage>({ + type: UI_EVENTS.delete_resource_signins, data: { id, }, @@ -56,11 +53,8 @@ export function SigninList(): JSX.Element { }; const updateAutoSignin = async (signin: ISignin) => { - const { data } = await chrome.runtime.sendMessage< - IMessage - >({ - type: "update-resource", - subtype: "auto-signin", + const { data } = await chrome.runtime.sendMessage>({ + type: UI_EVENTS.update_resource_auto_signin, data: { signin, }, diff --git a/src/config/event-types.ts b/src/config/event-types.ts new file mode 100644 index 00000000..b101f0a6 --- /dev/null +++ b/src/config/event-types.ts @@ -0,0 +1,52 @@ +const CS = "cs-"; // content-script +const UI = "ui-"; // pages like popup, new tab etc +const EXTERNAL = "external-"; // onExternalMessage + +const EVENT_TYPE = { + action_icon: "action-icon", + authentication: "authentication", + create_resource: "create-resource", + delete_resource: "delete-resource", + fetch_resource: "fetch-resource", + update_resource: "update-resource", + vendor_info: "vendor-info", +}; + +export const CS_EVENTS = { + action_icon_set: `${CS}-${EVENT_TYPE.action_icon}-set`, + action_icon_unset: `${CS}-${EVENT_TYPE.action_icon}-unset`, + action_icon_set_tab: `${CS}-${EVENT_TYPE.action_icon}-set-tab`, + action_icon_unset_tab: `${CS}-${EVENT_TYPE.action_icon}-unset-tab`, + + fetch_resource_auto_signin_signature: `${CS}-${EVENT_TYPE.fetch_resource}-auto-signin-signature`, + fetch_resource_tab_signin: `${CS}-${EVENT_TYPE.fetch_resource}-tab-signin`, + + vendor_info_get_vendor_data: `${CS}-${EVENT_TYPE.vendor_info}-get-vendor-data`, + vendor_info_attempt_set_vendor_url: `${CS}-${EVENT_TYPE.vendor_info}-attempt-set-vendor-url`, + + authentication_check_agent_connection: `${CS}-${EVENT_TYPE.authentication}-check-agent-connection`, + authentication_get_signed_headers: `${CS}-${EVENT_TYPE.authentication}-get-signed-headers`, +}; + +export const UI_EVENTS = { + action_icon_unset: `${UI}-${EVENT_TYPE.action_icon}-unset`, + authentication_check_agent_connection: `${UI}-${EVENT_TYPE.authentication}-check-agent-connection`, + authentication_disconnect_agent: `${UI}-${EVENT_TYPE.authentication}-disconnect-agent`, + authentication_connect_agent: `${UI}-${EVENT_TYPE.authentication}-connect-agent`, + authentication_boot_connect_agent: `${UI}-${EVENT_TYPE.authentication}-boot-connect-agent`, + authentication_generate_passcode: `${UI}-${EVENT_TYPE.authentication}-generate-passcode`, + + create_resource_signin: `${UI}-${EVENT_TYPE.create_resource}-signin`, + create_resource_identifier: `${UI}-${EVENT_TYPE.create_resource}-identifier`, + + fetch_resource_identifiers: `${UI}-${EVENT_TYPE.fetch_resource}-identifiers`, + fetch_resource_signins: `${UI}-${EVENT_TYPE.fetch_resource}-signins`, + fetch_resource_credentials: `${UI}-${EVENT_TYPE.fetch_resource}-credentials`, + + update_resource_auto_signin: `${UI}-${EVENT_TYPE.update_resource}-auto-signin`, + delete_resource_signins: `${UI}-${EVENT_TYPE.delete_resource}-signins`, +}; + +export const EXTERNAL_EVENTS = { + fetch_resource_auto_signin_signature: `${EXTERNAL}-${EVENT_TYPE.fetch_resource}-auto-signin-signature`, +}; diff --git a/src/config/types.ts b/src/config/types.ts index 3f5c27fc..f1c480ae 100644 --- a/src/config/types.ts +++ b/src/config/types.ts @@ -2,9 +2,15 @@ export interface ObjectOfArrays { [key: string]: T[]; } +export interface IHandler { + sendResponse: (response?: any) => void; + tabId?: number; + url?: string; + data?: any; + +} export interface IMessage { type: string; - subtype?: string; data?: T; } diff --git a/src/pages/background/handlers/actionIcon.ts b/src/pages/background/handlers/actionIcon.ts new file mode 100644 index 00000000..405e68fe --- /dev/null +++ b/src/pages/background/handlers/actionIcon.ts @@ -0,0 +1,25 @@ +import { IHandler } from "@config/types"; + +export function handleSetActionIcon({ sendResponse }: IHandler) { + chrome.action.setBadgeBackgroundColor({ color: "#008000" }, () => { + chrome.action.setBadgeText({ text: "1" }); + sendResponse({ data: { success: true } }); + }); +} + +export function handleUnsetActionIcon({ sendResponse }: IHandler) { + chrome.action.setBadgeText({ text: "" }); + sendResponse({ data: { success: true } }); +} + +export function handleSetTabActionIcon({ sendResponse, tabId }: IHandler) { + chrome.action.setBadgeBackgroundColor({ color: "#008000" }, () => { + chrome.action.setBadgeText({ tabId: tabId, text: "1" }); + sendResponse({ data: { success: true } }); + }); +} + +export function handleUnsetTabActionIcon({ sendResponse, tabId }: IHandler) { + chrome.action.setBadgeText({ tabId: tabId, text: "" }); + sendResponse({ data: { success: true } }); +} diff --git a/src/pages/background/handlers/authentication.ts b/src/pages/background/handlers/authentication.ts new file mode 100644 index 00000000..b4f09894 --- /dev/null +++ b/src/pages/background/handlers/authentication.ts @@ -0,0 +1,88 @@ +import { signifyService } from "@pages/background/services/signify"; +import { userService } from "@pages/background/services/user"; +import { IHandler } from "@config/types"; + +export async function handleCheckAgentConnection({ + sendResponse, + url, +}: IHandler) { + const isConnected = await signifyService.isConnected(); + sendResponse({ data: { isConnected, tabUrl: url } }); +} + +export async function handleDisconnectAgent({ sendResponse }: IHandler) { + await signifyService.disconnect(); + sendResponse({ data: { isConnected: false } }); +} + +export async function handleConnectAgent({ sendResponse, data }: IHandler) { + const resp = (await signifyService.connect( + data.agentUrl, + data.passcode + )) as any; + if (resp?.error) { + // TODO: improve error messages + // Current messages are not descrptive enough e.g + // bran must be 21 characters + // agent does not exist for controller + // using custom error message for now instead of resp?.error?.message + + sendResponse({ + error: { + code: 404, + message: resp?.error?.message, + }, + }); + } else { + await userService.setPasscode(data.passcode); + sendResponse({ data: { success: true } }); + } +} + +export async function handleBootConnectAgent({ sendResponse, data }: IHandler) { + const resp = (await signifyService.bootAndConnect( + data.agentUrl, + data.bootUrl, + data.passcode + )) as any; + if (resp?.error) { + sendResponse({ + error: { + code: 404, + message: resp?.error?.message, + }, + }); + } else { + await userService.setPasscode(data.passcode); + sendResponse({ data: { success: true } }); + } +} + +export async function handleGeneratePasscode({ sendResponse, data }: IHandler) { + const passcode = signifyService.generatePasscode(); + sendResponse({ data: { passcode } }); +} + +export async function handleGetSignedHeaders({ + sendResponse, + url, + data, +}: IHandler) { + const origin = url!; + const signedHeaders = await signifyService.signHeaders( + data.signin.identifier + ? data.signin.identifier.name + : data.signin.credential.issueeName, + origin + ); + let jsonHeaders: { [key: string]: string } = {}; + for (const pair of signedHeaders.entries()) { + jsonHeaders[pair[0]] = pair[1]; + } + sendResponse({ + data: { + headers: jsonHeaders, + credential: data.signin.credential ? data.signin.credential : null, + }, + }); +} diff --git a/src/pages/background/handlers/index.ts b/src/pages/background/handlers/index.ts new file mode 100644 index 00000000..a8afba1e --- /dev/null +++ b/src/pages/background/handlers/index.ts @@ -0,0 +1,103 @@ +import { IHandler } from "@src/config/types"; +import { CS_EVENTS, UI_EVENTS, EXTERNAL_EVENTS } from "@config/event-types"; +import { + handleSetActionIcon, + handleUnsetActionIcon, + handleSetTabActionIcon, + handleUnsetTabActionIcon, +} from "./actionIcon"; +import { + handleCreateIdentifier, + handleCreateSignin, + handleDeleteSignin, + handleFetchAutoSigninSignature, + handleFetchCredentials, + handleFetchIdentifiers, + handleFetchSignins, + handleFetchTabSignin, + handleUpdateAutoSignin, +} from "./resource"; +import { handleGetVendorData, handleAttemptSetVendorData } from "./vendorInfo"; +import { + handleBootConnectAgent, + handleCheckAgentConnection, + handleConnectAgent, + handleDisconnectAgent, + handleGeneratePasscode, + handleGetSignedHeaders, +} from "./authentication"; + +export function initUIHandler() { + const handler = new Map void>(); + handler.set(UI_EVENTS.action_icon_unset, handleUnsetActionIcon); + + handler.set( + UI_EVENTS.authentication_check_agent_connection, + handleCheckAgentConnection + ); + handler.set(UI_EVENTS.authentication_disconnect_agent, handleDisconnectAgent); + handler.set(UI_EVENTS.authentication_connect_agent, handleConnectAgent); + handler.set( + UI_EVENTS.authentication_boot_connect_agent, + handleBootConnectAgent + ); + handler.set( + UI_EVENTS.authentication_generate_passcode, + handleGeneratePasscode + ); + + handler.set(UI_EVENTS.create_resource_signin, handleCreateSignin); + handler.set(UI_EVENTS.create_resource_identifier, handleCreateIdentifier); + + handler.set(UI_EVENTS.fetch_resource_identifiers, handleFetchIdentifiers); + handler.set(UI_EVENTS.fetch_resource_signins, handleFetchSignins); + handler.set(UI_EVENTS.fetch_resource_credentials, handleFetchCredentials); + + handler.set(UI_EVENTS.update_resource_auto_signin, handleUpdateAutoSignin); + handler.set(UI_EVENTS.delete_resource_signins, handleDeleteSignin); + + return handler; +} + +export function initCSHandler() { + const handler = new Map void>(); + handler.set(CS_EVENTS.action_icon_set, handleSetActionIcon); + handler.set(CS_EVENTS.action_icon_unset, handleUnsetActionIcon); + handler.set(CS_EVENTS.action_icon_set_tab, handleSetTabActionIcon); + handler.set(CS_EVENTS.action_icon_unset_tab, handleUnsetTabActionIcon); + + handler.set( + CS_EVENTS.fetch_resource_auto_signin_signature, + handleFetchAutoSigninSignature + ); + handler.set(CS_EVENTS.fetch_resource_tab_signin, handleFetchTabSignin); + + handler.set(CS_EVENTS.vendor_info_get_vendor_data, handleGetVendorData); + handler.set( + CS_EVENTS.vendor_info_attempt_set_vendor_url, + handleAttemptSetVendorData + ); + + handler.set( + CS_EVENTS.authentication_check_agent_connection, + handleCheckAgentConnection + ); + handler.set( + CS_EVENTS.authentication_get_signed_headers, + handleGetSignedHeaders + ); + + return handler; +} + +export function initExternalHandler() { + const handler = new Map void>(); + // handler.set("action-icon", handleActionIcon); + // handler.set("vendor-info", handleVendorInfo); + + return handler; + // const processor = messageProcessors.get(message.type); + // if (processor) { + // processor(message, sender, sendResponse); + // } +} diff --git a/src/pages/background/handlers/resource.ts b/src/pages/background/handlers/resource.ts new file mode 100644 index 00000000..aceabef1 --- /dev/null +++ b/src/pages/background/handlers/resource.ts @@ -0,0 +1,141 @@ +import * as signinResource from "@pages/background/resource/signin"; +import { signifyService } from "@pages/background/services/signify"; +import { IHandler, IIdentifier, ICredential } from "@config/types"; +import { getCurrentUrl } from "@pages/background/utils"; + +export async function handleFetchAutoSigninSignature({ + sendResponse, + url, +}: IHandler) { + // Validate that message comes from a page that has a signin + const signins = await signinResource.getSigninsByDomain(url); + const autoSignin = signins?.find((signin) => signin.autoSignin); + if (!signins?.length || !autoSignin) { + sendResponse({ + error: { code: 404, message: "auto signin not found" }, + }); + return; + } + + const signedHeaders = await signifyService.signHeaders( + // sigin can either have identifier or credential + autoSignin?.identifier + ? autoSignin?.identifier?.name + : autoSignin?.credential?.issueeName, + url! + ); + let jsonHeaders: { [key: string]: string } = {}; + for (const pair of signedHeaders.entries()) { + jsonHeaders[pair[0]] = pair[1]; + } + sendResponse({ data: { headers: jsonHeaders } }); +} + +export async function handleFetchTabSignin({ sendResponse, url }: IHandler) { + const signins = await signinResource.getSigninsByDomain(url); + const autoSigninObj = signins?.find((signin) => signin.autoSignin); + sendResponse({ data: { signins: signins ?? [], autoSigninObj } }); +} + +export async function handleFetchIdentifiers({ sendResponse }: IHandler) { + const identifiers = await signifyService.listIdentifiers(); + sendResponse({ data: { aids: identifiers ?? [] } }); +} + +export async function handleFetchSignins({ sendResponse, url }: IHandler) { + const signins = await signinResource.getSignins(); + sendResponse({ + data: { + signins, + }, + }); +} + +export async function handleFetchCredentials({ sendResponse }: IHandler) { + var credentials = await signifyService.listCredentials(); + const indentifiers = await signifyService.listIdentifiers(); + console.log(indentifiers); + // Add holder name to credential + credentials?.forEach((credential: ICredential) => { + const issueePrefix = credential.sad.a.i; + const aidIssuee = indentifiers.find((aid: IIdentifier) => { + return aid.prefix === issueePrefix; + }); + credential.issueeName = aidIssuee?.name!; + }); + + sendResponse({ data: { credentials: credentials ?? [] } }); +} + +export async function handleCreateIdentifier({ sendResponse, data }: IHandler) { + try { + const resp = await signifyService.createAID(data.name); + sendResponse({ data: { ...(resp ?? {}) } }); + } catch (error: any) { + const errorMsg = JSON.parse(error?.message ?? ""); + sendResponse({ + error: { code: 404, message: errorMsg?.title }, + }); + } +} + +export async function handleCreateSignin({ sendResponse, data }: IHandler) { + const signins = await signinResource.getSignins(); + const currentUrl = await getCurrentUrl(); + const { identifier, credential } = data; + let signinExists = false; + if (identifier && identifier.prefix) { + signinExists = Boolean( + signins?.find( + (signin) => + signin.domain === currentUrl?.origin && + signin?.identifier?.prefix === identifier.prefix + ) + ); + } + + if (credential && credential.sad.d) { + signinExists = Boolean( + signins?.find( + (signin) => + signin.domain === currentUrl?.origin && + signin?.credential?.sad?.d === credential.sad.d + ) + ); + } + + if (signinExists) { + sendResponse({ data: { signins: signins } }); + } else { + const signinObj = signinResource.newSigninObject({ + identifier, + credential, + domain: currentUrl!.origin, + }); + if (signins && signins?.length) { + await signinResource.updateSignins([...signins, signinObj]); + } else { + await signinResource.updateSignins([signinObj]); + } + const storageSignins = await signinResource.getSignins(); + sendResponse({ data: { signins: storageSignins } }); + } +} + +export async function handleUpdateAutoSignin({ sendResponse, data }: IHandler) { + const resp = await signinResource.updateAutoSigninByDomain(data?.signin); + sendResponse({ + data: { + ...resp, + }, + }); +} + +export async function handleDeleteSignin({ sendResponse, data }: IHandler) { + const resp = await signinResource.deleteSigninById(data?.id); + sendResponse({ + data: { + ...resp, + }, + }); +} diff --git a/src/pages/background/handlers/vendorInfo.ts b/src/pages/background/handlers/vendorInfo.ts new file mode 100644 index 00000000..33b1a692 --- /dev/null +++ b/src/pages/background/handlers/vendorInfo.ts @@ -0,0 +1,23 @@ +import { + WEB_APP_PERMS, + configService, +} from "@pages/background/services/config"; +import { IHandler } from "@config/types"; + +export async function handleGetVendorData({ sendResponse }: IHandler) { + const vendorData = await configService.getVendorData(); + sendResponse({ data: { vendorData } }); +} + +export async function handleAttemptSetVendorData({ + sendResponse, + data, + url, +}: IHandler) { + const { vendorUrl } = data ?? {}; + await configService.setWebRequestedPermission(WEB_APP_PERMS.SET_VENDOR_URL, { + origin: url, + vendorUrl, + }); + sendResponse({ data: { success: true } }); +} diff --git a/src/pages/background/index.ts b/src/pages/background/index.ts index f0154cc7..7e2f53e2 100644 --- a/src/pages/background/index.ts +++ b/src/pages/background/index.ts @@ -1,20 +1,16 @@ -import { - WEB_APP_PERMS, - configService, -} from "@pages/background/services/config"; -import { userService } from "@pages/background/services/user"; +import { configService } from "@pages/background/services/config"; import { signifyService } from "@pages/background/services/signify"; import * as signinResource from "@pages/background/resource/signin"; -import { IMessage, IIdentifier, ICredential } from "@config/types"; +import { IMessage } from "@config/types"; import { senderIsPopup } from "@pages/background/utils"; -import { - removeSlash, - getCurrentUrl, - setActionIcon, -} from "@pages/background/utils"; +import { removeSlash, setActionIcon } from "@pages/background/utils"; +import { initCSHandler, initUIHandler } from "@pages/background/handlers"; console.log("Background script loaded"); +const csHandler = initCSHandler(); +const uiHandler = initUIHandler(); + chrome.runtime.onStartup.addListener(function () { (async () => { const vendorData = await configService.getVendorData(); @@ -41,346 +37,33 @@ chrome.runtime.onMessage.addListener(function ( (async () => { // Handle mesages from content script on active tab if (sender.tab && sender.tab.active) { - console.log( - "Message received from content script at " + - sender.tab.url + - " " + - message.type + - ":" + - message.subtype - ); - - if ( - message.type === "action-icon" && - message.subtype === "set-action-icon" - ) { - chrome.action.setBadgeBackgroundColor({ color: "#008000" }, () => { - chrome.action.setBadgeText({ text: "1" }); - sendResponse({ data: { success: true } }); - }); - } - - if ( - message.type === "action-icon" && - message.subtype === "set-tab-action-icon" - ) { - chrome.action.setBadgeBackgroundColor({ color: "#008000" }, () => { - chrome.action.setBadgeText({ tabId: sender.tab?.id, text: "1" }); - sendResponse({ data: { success: true } }); - }); - } - - if ( - message.type === "action-icon" && - message.subtype === "unset-tab-action-icon" - ) { - chrome.action.setBadgeText({ tabId: sender.tab?.id, text: "" }); - sendResponse({ data: { success: true } }); - } - - if ( - message.type === "action-icon" && - message.subtype === "unset-action-icon" - ) { - chrome.action.setBadgeText({ text: "" }); - sendResponse({ data: { success: true } }); - } - - if ( - message.type === "vendor-info" && - message.subtype === "get-vendor-data" - ) { - const vendorData = await configService.getVendorData(); - sendResponse({ data: { vendorData } }); - } - - if ( - message.type === "vendor-info" && - message.subtype === "attempt-set-vendor-url" - ) { - const { vendorUrl } = message?.data ?? {}; - await configService.setWebRequestedPermission( - WEB_APP_PERMS.SET_VENDOR_URL, - { origin: sender.tab.url, vendorUrl } - ); - sendResponse({ data: { success: true } }); - } - - if ( - message.type === "fetch-resource" && - message.subtype === "auto-signin-signature" - ) { - // Validate that message comes from a page that has a signin - const signins = await signinResource.getSigninsByDomain(sender.url!); - const autoSignin = signins?.find((signin) => signin.autoSignin); - if (!signins?.length || !autoSignin) { - sendResponse({ - error: { code: 404, message: "auto signin not found" }, - }); - return; - } - - const signedHeaders = await signifyService.signHeaders( - // sigin can either have identifier or credential - autoSignin?.identifier - ? autoSignin?.identifier?.name - : autoSignin?.credential?.issueeName, - origin - ); - let jsonHeaders: { [key: string]: string } = {}; - for (const pair of signedHeaders.entries()) { - jsonHeaders[pair[0]] = pair[1]; - } - sendResponse({ data: { headers: jsonHeaders } }); - } - - if ( - message.type === "authentication" && - message.subtype === "check-agent-connection" - ) { - const isConnected = await signifyService.isConnected(); - sendResponse({ data: { isConnected, tabUrl: sender?.tab.url } }); - } - - if ( - message.type === "authentication" && - message.subtype === "get-signed-headers" - ) { - const origin = sender.tab.url!; - console.log(message.data.signin); - - const signedHeaders = await signifyService.signHeaders( - message.data.signin.identifier - ? message.data.signin.identifier.name - : message.data.signin.credential.issueeName, - origin - ); - let jsonHeaders: { [key: string]: string } = {}; - for (const pair of signedHeaders.entries()) { - jsonHeaders[pair[0]] = pair[1]; - } - sendResponse({ - data: { - headers: jsonHeaders, - credential: message.data.signin.credential - ? message.data.signin.credential - : null, - }, + console.log("Message received from content script at ", sender.tab.url); + console.log("Message Type", message.type); + + const processor = csHandler.get(message.type); + if (processor) { + processor({ + sendResponse, + tabId: sender?.tab?.id, + url: sender?.url, + data: message?.data, }); } - if ( - message.type === "fetch-resource" && - message.subtype === "tab-signin" - ) { - const signins = await signinResource.getSigninsByDomain(sender.url); - const autoSigninObj = signins?.find((signin) => signin.autoSignin); - sendResponse({ data: { signins: signins ?? [], autoSigninObj } }); - } - // Handle messages from Popup } else if (senderIsPopup(sender)) { - console.log( - "Message received from browser extension: " + - message.type + - "-" + - message.subtype - ); - - if ( - message.type === "action-icon" && - message.subtype === "unset-action-icon" - ) { - chrome.action.setBadgeText({ text: "" }); - sendResponse({ data: { success: true } }); - } - - if ( - message.type === "authentication" && - message.subtype === "check-agent-connection" - ) { - const isConnected = await signifyService.isConnected(); - sendResponse({ data: { isConnected } }); - } - - if ( - message.type === "authentication" && - message.subtype === "disconnect-agent" - ) { - await signifyService.disconnect(); - sendResponse({ data: { isConnected: false } }); - } - - if ( - message.type === "authentication" && - message.subtype === "connect-agent" - ) { - const resp = (await signifyService.connect( - message.data.agentUrl, - message.data.passcode - )) as any; - if (resp?.error) { - // TODO: improve error messages - // Current messages are not descrptive enough e.g - // bran must be 21 characters - // agent does not exist for controller - // using custom error message for now instead of resp?.error?.message - - sendResponse({ - error: { - code: 404, - message: resp?.error?.message, - }, - }); - } else { - await userService.setPasscode(message.data.passcode); - sendResponse({ data: { success: true } }); - } - } - - if ( - message.type === "authentication" && - message.subtype === "boot-and-connect-agent" - ) { - const resp = (await signifyService.bootAndConnect( - message.data.agentUrl, - message.data.bootUrl, - message.data.passcode - )) as any; - if (resp?.error) { - sendResponse({ - error: { - code: 404, - message: resp?.error?.message, - }, - }); - } else { - await userService.setPasscode(message.data.passcode); - sendResponse({ data: { success: true } }); - } - } - - if ( - message.type === "authentication" && - message.subtype === "generate-passcode" - ) { - const passcode = signifyService.generatePasscode(); - sendResponse({ data: { passcode } }); - } - } - - if (message.type === "create-resource" && message.subtype === "signin") { - const signins = await signinResource.getSignins(); - const currentUrl = await getCurrentUrl(); - const { identifier, credential } = message.data; - let signinExists = false; - if (identifier && identifier.prefix) { - signinExists = Boolean( - signins?.find( - (signin) => - signin.domain === currentUrl?.origin && - signin?.identifier?.prefix === identifier.prefix - ) - ); - } - - if (credential && credential.sad.d) { - signinExists = Boolean( - signins?.find( - (signin) => - signin.domain === currentUrl?.origin && - signin?.credential?.sad?.d === credential.sad.d - ) - ); - } - - if (signinExists) { - sendResponse({ data: { signins: signins } }); - } else { - const signinObj = signinResource.newSigninObject({ - identifier, - credential, - domain: currentUrl!.origin, + console.log("Message received from browser extension: ", message.type); + + const processor = uiHandler.get(message.type); + if (processor) { + processor({ + sendResponse, + tabId: sender?.tab?.id, + url: sender?.url, + data: message?.data, }); - if (signins && signins?.length) { - await signinResource.updateSignins([...signins, signinObj]); - } else { - await signinResource.updateSignins([signinObj]); - } - const storageSignins = await signinResource.getSignins(); - sendResponse({ data: { signins: storageSignins } }); } } - if ( - message.type === "create-resource" && - message.subtype === "identifier" - ) { - try { - const resp = await signifyService.createAID(message.data.name); - sendResponse({ data: { ...(resp ?? {}) } }); - } catch (error: any) { - const errorMsg = JSON.parse(error?.message ?? ""); - sendResponse({ - error: { code: 404, message: errorMsg?.title }, - }); - } - } - if ( - message.type === "fetch-resource" && - message.subtype === "identifiers" - ) { - const identifiers = await signifyService.listIdentifiers(); - sendResponse({ data: { aids: identifiers ?? [] } }); - } - - if (message.type === "fetch-resource" && message.subtype === "signins") { - const signins = await signinResource.getSignins(); - sendResponse({ - data: { - signins, - }, - }); - } - - if ( - message.type === "update-resource" && - message.subtype === "auto-signin" - ) { - const resp = await signinResource.updateAutoSigninByDomain(message?.data?.signin); - sendResponse({ - data: { - ...resp, - }, - }); - } - - if (message.type === "delete-resource" && message.subtype === "signins") { - const resp = await signinResource.deleteSigninById(message?.data?.id); - sendResponse({ - data: { - ...resp, - }, - }); - } - - if ( - message.type === "fetch-resource" && - message.subtype === "credentials" - ) { - var credentials = await signifyService.listCredentials(); - const indentifiers = await signifyService.listIdentifiers(); - console.log(indentifiers); - // Add holder name to credential - credentials?.forEach((credential: ICredential) => { - const issueePrefix = credential.sad.a.i; - const aidIssuee = indentifiers.find((aid: IIdentifier) => { - return aid.prefix === issueePrefix; - }); - credential.issueeName = aidIssuee?.name!; - }); - - sendResponse({ data: { credentials: credentials ?? [] } }); - } })(); // return true to indicate chrome api to send a response asynchronously diff --git a/src/pages/dialog/Dialog.tsx b/src/pages/content/dialog/Dialog.tsx similarity index 98% rename from src/pages/dialog/Dialog.tsx rename to src/pages/content/dialog/Dialog.tsx index 3d046ae8..aee528fe 100644 --- a/src/pages/dialog/Dialog.tsx +++ b/src/pages/content/dialog/Dialog.tsx @@ -2,7 +2,6 @@ import { useState, useEffect } from "react"; import { ThemeProvider, styled } from "styled-components"; import { useIntl } from "react-intl"; import { Text, Subtext, Box, Flex, IconButton } from "@components/ui"; -import CloseIcon from "@components/shared/icons/close"; import { IVendorData, ISignin } from "@config/types"; import { TAB_STATE } from "@pages/popup/constants"; import { setTabState } from "@pages/content"; diff --git a/src/pages/dialog/popupPrompt.tsx b/src/pages/content/dialog/popupPrompt.tsx similarity index 91% rename from src/pages/dialog/popupPrompt.tsx rename to src/pages/content/dialog/popupPrompt.tsx index 7799c746..b5a8079a 100644 --- a/src/pages/dialog/popupPrompt.tsx +++ b/src/pages/content/dialog/popupPrompt.tsx @@ -1,6 +1,6 @@ import { styled } from "styled-components"; import { Flex, Box } from "@components/ui"; -import PopupArrowIcon from "@src/components/shared/icons/popup-arrow"; +import PopupArrowIcon from "@components/shared/icons/popup-arrow"; interface IPopupPrompt { message: JSX.Element; diff --git a/src/pages/dialog/signin.tsx b/src/pages/content/dialog/signin.tsx similarity index 94% rename from src/pages/dialog/signin.tsx rename to src/pages/content/dialog/signin.tsx index 88f557a0..6a791ac4 100644 --- a/src/pages/dialog/signin.tsx +++ b/src/pages/content/dialog/signin.tsx @@ -1,8 +1,9 @@ import { styled } from "styled-components"; +import { CS_EVENTS } from "@config/event-types"; +import { ISignin } from "@config/types"; import { Box, Button, Text, Subtext, Flex } from "@components/ui"; -import SigninIcon from "@src/components/shared/icons/signin"; +import SigninIcon from "@components/shared/icons/signin"; import { resetTabState } from "@pages/content"; -import { ISignin } from "@config/types"; const StyledSigninItem = styled(Flex)` border: 1px solid; @@ -18,8 +19,7 @@ const AutoSigninTag = styled(Box)<{ visible?: boolean }>` export const SigninItem = ({ signin }: { signin: ISignin }): JSX.Element => { const handleClick = async () => { const headers = await chrome.runtime.sendMessage({ - type: "authentication", - subtype: "get-signed-headers", + type: CS_EVENTS.authentication_get_signed_headers, data: { signin: signin, }, diff --git a/src/pages/content/index.tsx b/src/pages/content/index.tsx index 74ce136a..6d9070b7 100644 --- a/src/pages/content/index.tsx +++ b/src/pages/content/index.tsx @@ -1,8 +1,9 @@ import { createRoot } from "react-dom/client"; import { LocaleProvider } from "@src/_locales"; +import { CS_EVENTS } from "@config/event-types"; import { IMessage } from "@config/types"; import { TAB_STATE } from "@pages/popup/constants"; -import { Dialog } from "../dialog/Dialog"; +import { Dialog } from "./dialog/Dialog"; // import "./style.css"; var tabState = TAB_STATE.NONE; @@ -34,24 +35,20 @@ window.addEventListener( case TAB_STATE.SELECT_ID_CRED: case TAB_STATE.SELECT_AUTO_SIGNIN: await chrome.runtime.sendMessage>({ - type: "action-icon", - subtype: "set-tab-action-icon", + type: CS_EVENTS.action_icon_set_tab, }); const respVendorData = await chrome.runtime.sendMessage< IMessage >({ - type: "vendor-info", - subtype: "get-vendor-data", + type: CS_EVENTS.vendor_info_get_vendor_data, }); const { data } = await chrome.runtime.sendMessage>({ - type: "authentication", - subtype: "check-agent-connection", + type: CS_EVENTS.authentication_check_agent_connection, }); const tabSigninResp = await chrome.runtime.sendMessage< IMessage >({ - type: "fetch-resource", - subtype: "tab-signin", + type: CS_EVENTS.fetch_resource_tab_signin, }); const filteredSignins = getFilteredSignins( @@ -72,12 +69,10 @@ window.addEventListener( case "vendor-info": if (event.data.subtype === "attempt-set-vendor-url") { await chrome.runtime.sendMessage>({ - type: "action-icon", - subtype: "set-action-icon", + type: CS_EVENTS.action_icon_set, }); await chrome.runtime.sendMessage(chrome.runtime.id, { - type: "vendor-info", - subtype: "attempt-set-vendor-url", + type: CS_EVENTS.vendor_info_attempt_set_vendor_url, data: { vendorUrl: event.data.data.vendorUrl, }, @@ -89,8 +84,7 @@ window.addEventListener( const { data, error } = await chrome.runtime.sendMessage( chrome.runtime.id, { - type: "fetch-resource", - subtype: "auto-signin-signature", + type: CS_EVENTS.fetch_resource_auto_signin_signature, } ); if (error) { @@ -134,18 +128,15 @@ chrome.runtime.onMessage.addListener(async function ( removeDialog(); const respVendorData = await chrome.runtime.sendMessage>( { - type: "vendor-info", - subtype: "get-vendor-data", + type: CS_EVENTS.vendor_info_get_vendor_data, } ); const { data } = await chrome.runtime.sendMessage>({ - type: "authentication", - subtype: "check-agent-connection", + type: CS_EVENTS.authentication_check_agent_connection, }); const tabSigninResp = await chrome.runtime.sendMessage>({ - type: "fetch-resource", - subtype: "tab-signin", + type: CS_EVENTS.fetch_resource_tab_signin, }); const filteredSignins = getFilteredSignins( tabSigninResp?.data?.signins, @@ -211,8 +202,7 @@ function removeDialog() { if (element) element.remove(); chrome.runtime.sendMessage>({ - type: "action-icon", - subtype: "unset-tab-action-icon", + type: CS_EVENTS.action_icon_unset_tab, }); } diff --git a/src/pages/dialog/index.css b/src/pages/dialog/index.css deleted file mode 100644 index 6aa8c2bf..00000000 --- a/src/pages/dialog/index.css +++ /dev/null @@ -1,12 +0,0 @@ -body { - width: 300px; - height: 260px; - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", - "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - - position: relative; -} diff --git a/src/pages/dialog/index.html b/src/pages/dialog/index.html deleted file mode 100644 index 37397769..00000000 --- a/src/pages/dialog/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - Dialog - - - -
- - - diff --git a/src/pages/dialog/index.tsx b/src/pages/dialog/index.tsx deleted file mode 100644 index 3fdb2fa1..00000000 --- a/src/pages/dialog/index.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { createRoot } from "react-dom/client"; -import "@pages/popup/index.css"; -import Popup from "@pages/popup/Popup"; - -function init() { - const rootContainer = document.querySelector("#__root"); - if (!rootContainer) throw new Error("Can't find Popup root element"); - const root = createRoot(rootContainer); - root.render(); -} - -init(); diff --git a/src/pages/popup/Popup.tsx b/src/pages/popup/Popup.tsx index 47dae36e..e18b416c 100644 --- a/src/pages/popup/Popup.tsx +++ b/src/pages/popup/Popup.tsx @@ -1,5 +1,6 @@ import { useState, useEffect } from "react"; import { createGlobalStyle } from "styled-components"; +import { UI_EVENTS } from "@config/event-types"; import { WEB_APP_PERMS, configService, @@ -89,8 +90,7 @@ export default function Popup(): JSX.Element { const checkConnection = async () => { const { data } = await chrome.runtime.sendMessage>({ - type: "authentication", - subtype: "check-agent-connection", + type: UI_EVENTS.authentication_check_agent_connection, }); setIsConnected(!!data.isConnected); @@ -126,12 +126,11 @@ export default function Popup(): JSX.Element { if (!urlObject || !urlObject?.origin) return; setIsLoading(true); - + const { data, error } = await chrome.runtime.sendMessage< IMessage >({ - type: "authentication", - subtype: "boot-and-connect-agent", + type: UI_EVENTS.authentication_boot_connect_agent, data: { passcode, agentUrl, @@ -157,8 +156,7 @@ export default function Popup(): JSX.Element { const { data, error } = await chrome.runtime.sendMessage< IMessage >({ - type: "authentication", - subtype: "connect-agent", + type: UI_EVENTS.authentication_connect_agent, data: { passcode, agentUrl, @@ -178,16 +176,14 @@ export default function Popup(): JSX.Element { const handleDisconnect = async () => { await chrome.runtime.sendMessage>({ - type: "authentication", - subtype: "disconnect-agent", + type: UI_EVENTS.authentication_disconnect_agent, }); checkConnection(); }; const handleDisconnectPermission = async () => { await chrome.runtime.sendMessage>({ - type: "authentication", - subtype: "disconnect-agent", + type: UI_EVENTS.authentication_disconnect_agent }); await checkConnection(); checkIfVendorDataExists(); diff --git a/src/screens/permission/permission.tsx b/src/screens/permission/permission.tsx index 4ef4ce61..400fa8b3 100644 --- a/src/screens/permission/permission.tsx +++ b/src/screens/permission/permission.tsx @@ -1,10 +1,11 @@ import { useState } from "react"; import { useIntl } from "react-intl"; +import { UI_EVENTS } from "@config/event-types"; import { WEB_APP_PERMS, configService, } from "@pages/background/services/config"; -import { isValidUrl, getBootUrl, setActionIcon } from "@pages/background/utils"; +import { isValidUrl, setActionIcon } from "@pages/background/utils"; import { Box, Card, Button, Text, Flex } from "@components/ui"; import { IMessage } from "@config/types"; @@ -48,8 +49,7 @@ export function Permission({ "delete" ); await chrome.runtime.sendMessage>({ - type: "action-icon", - subtype: "unset-action-icon", + type: UI_EVENTS.action_icon_unset, }); }; @@ -82,7 +82,7 @@ export function Permission({ await handleSetAgentUrl(resp?.agentUrl); } - if(resp?.bootUrl) { + if (resp?.bootUrl) { await handleSetBootUrl(resp?.bootUrl); } diff --git a/src/screens/signup/signup.tsx b/src/screens/signup/signup.tsx index d50e0052..6eb2316a 100644 --- a/src/screens/signup/signup.tsx +++ b/src/screens/signup/signup.tsx @@ -1,6 +1,7 @@ import { useState, useEffect } from "react"; import styled, { css } from "styled-components"; import { useIntl } from "react-intl"; +import { UI_EVENTS } from "@config/event-types"; import { Box, Card, @@ -60,8 +61,7 @@ export function Signup({ const handleGeneratePasscode = async () => { const { data } = await chrome.runtime.sendMessage>({ - type: "authentication", - subtype: "generate-passcode", + type: UI_EVENTS.authentication_generate_passcode, }); if (data?.passcode) { setGeneratedPasscode(data.passcode); From a8783932111aeac54e85073183c801d556dd89f1 Mon Sep 17 00:00:00 2001 From: Hunain Bin Sajid Date: Thu, 4 Apr 2024 22:57:28 +0500 Subject: [PATCH 2/4] fix: update message in background --- src/pages/background/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/background/index.ts b/src/pages/background/index.ts index 7e2f53e2..41a34fb3 100644 --- a/src/pages/background/index.ts +++ b/src/pages/background/index.ts @@ -37,7 +37,7 @@ chrome.runtime.onMessage.addListener(function ( (async () => { // Handle mesages from content script on active tab if (sender.tab && sender.tab.active) { - console.log("Message received from content script at ", sender.tab.url); + console.log("Message received from content script at ", sender?.tab?.url); console.log("Message Type", message.type); const processor = csHandler.get(message.type); From afa1b5cdce941a0e0e4f045a3f24345d55ea591b Mon Sep 17 00:00:00 2001 From: Hunain Bin Sajid Date: Fri, 5 Apr 2024 21:00:18 +0500 Subject: [PATCH 3/4] refactor: add getSignedheaders in signify service --- .../background/handlers/authentication.ts | 21 ++----- src/pages/background/handlers/resource.ts | 19 +++--- src/pages/background/index.ts | 30 ++------- src/pages/background/services/signify.ts | 62 ++++++++++++++----- 4 files changed, 64 insertions(+), 68 deletions(-) diff --git a/src/pages/background/handlers/authentication.ts b/src/pages/background/handlers/authentication.ts index b4f09894..5335161e 100644 --- a/src/pages/background/handlers/authentication.ts +++ b/src/pages/background/handlers/authentication.ts @@ -68,21 +68,12 @@ export async function handleGetSignedHeaders({ url, data, }: IHandler) { - const origin = url!; - const signedHeaders = await signifyService.signHeaders( - data.signin.identifier - ? data.signin.identifier.name - : data.signin.credential.issueeName, - origin - ); - let jsonHeaders: { [key: string]: string } = {}; - for (const pair of signedHeaders.entries()) { - jsonHeaders[pair[0]] = pair[1]; - } + const resp = await signifyService.getSignedHeaders({ + url: url!, + signin: data.signin, + }); + sendResponse({ - data: { - headers: jsonHeaders, - credential: data.signin.credential ? data.signin.credential : null, - }, + data: resp, }); } diff --git a/src/pages/background/handlers/resource.ts b/src/pages/background/handlers/resource.ts index aceabef1..db7909f8 100644 --- a/src/pages/background/handlers/resource.ts +++ b/src/pages/background/handlers/resource.ts @@ -16,19 +16,14 @@ export async function handleFetchAutoSigninSignature({ }); return; } + const resp = await signifyService.getSignedHeaders({ + url: url!, + signin: autoSignin, + }); - const signedHeaders = await signifyService.signHeaders( - // sigin can either have identifier or credential - autoSignin?.identifier - ? autoSignin?.identifier?.name - : autoSignin?.credential?.issueeName, - url! - ); - let jsonHeaders: { [key: string]: string } = {}; - for (const pair of signedHeaders.entries()) { - jsonHeaders[pair[0]] = pair[1]; - } - sendResponse({ data: { headers: jsonHeaders } }); + sendResponse({ + data: resp, + }); } export async function handleFetchTabSignin({ sendResponse, url }: IHandler) { diff --git a/src/pages/background/index.ts b/src/pages/background/index.ts index 41a34fb3..8c24a814 100644 --- a/src/pages/background/index.ts +++ b/src/pages/background/index.ts @@ -1,10 +1,9 @@ import { configService } from "@pages/background/services/config"; -import { signifyService } from "@pages/background/services/signify"; -import * as signinResource from "@pages/background/resource/signin"; import { IMessage } from "@config/types"; import { senderIsPopup } from "@pages/background/utils"; -import { removeSlash, setActionIcon } from "@pages/background/utils"; +import { setActionIcon } from "@pages/background/utils"; import { initCSHandler, initUIHandler } from "@pages/background/handlers"; +import { handleFetchAutoSigninSignature } from "@pages/background/handlers/resource"; console.log("Background script loaded"); @@ -80,33 +79,12 @@ chrome.runtime.onMessageExternal.addListener(function ( console.log("Message received from external source: ", sender); console.log("Message received from external request: ", message); + // TODO: replace with External Handler like we did for uiHandler and csHandler if ( message.type === "fetch-resource" && message.subtype === "auto-signin-signature" ) { - // Validate that message comes from a page that has a signin - const signins = await signinResource.getSigninsByDomain(sender.url); - console.log("signins", signins); - const autoSignin = signins?.find((signin) => signin.autoSignin); - if (!signins?.length || !autoSignin) { - sendResponse({ - error: { code: 404, message: "auto signin not found" }, - }); - return; - } - - const signedHeaders = await signifyService.signHeaders( - // sigin can either have identifier or credential - autoSignin?.identifier - ? autoSignin?.identifier?.name - : autoSignin?.credential?.issueeName, - removeSlash(sender.url) - ); - let jsonHeaders: { [key: string]: string } = {}; - for (const pair of signedHeaders.entries()) { - jsonHeaders[pair[0]] = pair[1]; - } - sendResponse({ data: { headers: jsonHeaders } }); + handleFetchAutoSigninSignature({ sendResponse, url: sender.url }); } })(); diff --git a/src/pages/background/services/signify.ts b/src/pages/background/services/signify.ts index 2ae23a1e..7cc406da 100644 --- a/src/pages/background/services/signify.ts +++ b/src/pages/background/services/signify.ts @@ -1,7 +1,13 @@ -import { SignifyClient, Tier, ready, Authenticater, randomPasscode, b } from "signify-ts"; +import { + SignifyClient, + Tier, + ready, + Authenticater, + randomPasscode, +} from "signify-ts"; import { userService } from "@pages/background/services/user"; import { configService } from "@pages/background/services/config"; -import { IIdentifier } from "@config/types"; +import { IIdentifier, ISignin } from "@config/types"; const PASSCODE_TIMEOUT = 5; @@ -10,20 +16,21 @@ const Signify = () => { chrome.alarms.onAlarm.addListener(async (alarm) => { if (alarm.name == "passcode-timeout") { - try { - const response = await chrome.runtime.sendMessage({type: "popup", subtype: "isOpened"}); + const response = await chrome.runtime.sendMessage({ + type: "popup", + subtype: "isOpened", + }); if (response.data.isOpened) { console.log("Timer expired, but extsenion is open. Resetting timer."); resetTimeoutAlarm(); } } catch (error) { - console.log("Timer expired, client and passcode zeroed out"); - _client = null; - await userService.removeControllerId(); - await userService.removePasscode(); + console.log("Timer expired, client and passcode zeroed out"); + _client = null; + await userService.removeControllerId(); + await userService.removePasscode(); } - } }); @@ -38,11 +45,15 @@ const Signify = () => { setTimeoutAlarm(); }; - const generatePasscode = () => { + const generatePasscode = () => { return randomPasscode(); }; - const bootAndConnect = async (agentUrl: string, bootUrl: string, passcode: string) => { + const bootAndConnect = async ( + agentUrl: string, + bootUrl: string, + passcode: string + ) => { try { await ready(); _client = new SignifyClient(agentUrl, passcode, Tier.low, bootUrl); @@ -84,7 +95,8 @@ const Signify = () => { console.log( _client ? "Signify client is connected" - : "Signify client is not connected", _client + : "Signify client is not connected", + _client ); return _client ? true : false; }; @@ -101,16 +113,16 @@ const Signify = () => { const listIdentifiers = async () => { validateClient(); - let aids: IIdentifier[] = [] + let aids: IIdentifier[] = []; let start = 0; let total = 0; do { const res = await _client?.identifiers().list(start); - if(res.aids?.length){ + if (res.aids?.length) { aids.push(...res.aids); } total = res.total; - start = aids.length; + start = aids.length; } while (aids.length < total); return aids; }; @@ -156,6 +168,25 @@ const Signify = () => { return signed_headers; }; + const getSignedHeaders = async ({ url, signin } : { url: string, signin: ISignin }) => { + const origin = url!; + const signedHeaders = await signHeaders( + signin.identifier + ? signin.identifier?.name + : signin.credential?.issueeName, + origin + ); + let jsonHeaders: { [key: string]: string } = {}; + for (const pair of signedHeaders.entries()) { + jsonHeaders[pair[0]] = pair[1]; + } + + return { + headers: jsonHeaders, + credential: signin?.credential ?? null, + }; + }; + const getControllerID = async (): Promise => { const controllerId = await userService.getControllerId(); return controllerId; @@ -178,6 +209,7 @@ const Signify = () => { generatePasscode, bootAndConnect, getControllerID, + getSignedHeaders }; }; From ad344e18f87e336c7873de3d2d36b7ebf5aa473f Mon Sep 17 00:00:00 2001 From: Hunain Bin Sajid Date: Fri, 5 Apr 2024 21:20:56 +0500 Subject: [PATCH 4/4] fix: removeSlash from origin in signed headers --- src/pages/background/services/signify.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/background/services/signify.ts b/src/pages/background/services/signify.ts index 7cc406da..7cc937b5 100644 --- a/src/pages/background/services/signify.ts +++ b/src/pages/background/services/signify.ts @@ -7,6 +7,7 @@ import { } from "signify-ts"; import { userService } from "@pages/background/services/user"; import { configService } from "@pages/background/services/config"; +import { removeSlash } from "@pages/background/utils"; import { IIdentifier, ISignin } from "@config/types"; const PASSCODE_TIMEOUT = 5; @@ -169,7 +170,7 @@ const Signify = () => { }; const getSignedHeaders = async ({ url, signin } : { url: string, signin: ISignin }) => { - const origin = url!; + const origin = removeSlash(url!); const signedHeaders = await signHeaders( signin.identifier ? signin.identifier?.name