diff --git a/example-web/my-app/src/App.js b/example-web/my-app/src/App.js index ca3d2877..106b3a3b 100644 --- a/example-web/my-app/src/App.js +++ b/example-web/my-app/src/App.js @@ -2,6 +2,8 @@ import logo from "./ACME_Corporation.png"; import Button from "@mui/material/Button"; import "./App.css"; +const extensionId = "dfhkgnnnbadadbljpjnpifpbaemcgpfa"; + function App() { const handleRequestIdentifier = () => { window.postMessage({ type: "select-identifier" }, "*"); @@ -11,34 +13,59 @@ function App() { window.postMessage({ type: "select-credential" }, "*"); }; - const handleSyncRequest = () => { + const handleRequestIdORCred = () => { + window.postMessage({ type: "select-aid-or-credential" }, "*"); + }; + + const handleSyncRequest = async () => { // TODO extension Id harcoded just for testing, need to find a way to get it dynamically - chrome.runtime.sendMessage( - "fklmfbmpaimbgjplbambkdjphdadbmed", - { data: "test" }, - function (response) { - if (!response.success) console.log(response.data); - alert( - "Signed headers received\n" + - JSON.stringify(response.data.headers, null, 2) - ); - } - ); + const { data, error } = await chrome.runtime.sendMessage(extensionId, { + type: "fetch-resource", + subtype: "auto-signin-signature", + }); + + if (error) { + alert(error?.message); + } else { + alert( + "Signed headers received\n" + JSON.stringify(data.headers, null, 2) + ); + } }; return (
logo -
- + - -
diff --git a/src/components/main.tsx b/src/components/main.tsx index 0531e5ed..c75f6e84 100644 --- a/src/components/main.tsx +++ b/src/components/main.tsx @@ -16,28 +16,32 @@ export function Main(props: IMain): JSX.Element { const [tabState, setTabState] = useState(TAB_STATE.DEFAULT); const fetchTabState = async () => { + chrome.tabs.query( + { active: true, currentWindow: true }, + async function (tabs) { + const { data } = await chrome.tabs.sendMessage(tabs[0].id!, { + type: "tab", + subtype: "get-tab-state", + }); + if (!data) return; - chrome.tabs.query({ active: true, currentWindow: true }, async function (tabs) { - const { data } = await chrome.tabs.sendMessage( - tabs[0].id!, - { type: "tab", subtype: "get-tab-state" } - ); - if (!data) return; - - if (data?.appState) { - setTabState(data?.appState); - if ( - data?.appState === TAB_STATE.SELECT_IDENTIFIER || - data?.appState === TAB_STATE.SELECT_CREDENTIAL - ) { - setActiveSidebar( - data?.appState === TAB_STATE.SELECT_IDENTIFIER - ? "Identifiers" - : "Credentials" - ); + if (data?.appState) { + setTabState(data?.appState); + if ( + data?.appState === TAB_STATE.SELECT_IDENTIFIER || + data?.appState === TAB_STATE.SELECT_CREDENTIAL || + data?.appState === TAB_STATE.SELECT_ID_CRED + ) { + setActiveSidebar( + data?.appState === TAB_STATE.SELECT_IDENTIFIER || + data?.appState === TAB_STATE.SELECT_ID_CRED + ? "Identifiers" + : "Credentials" + ); + } + } } - } - }); + ); }; useEffect(() => { @@ -45,17 +49,25 @@ export function Main(props: IMain): JSX.Element { }, []); const renderItems = () => { - if (tabState === TAB_STATE.SELECT_IDENTIFIER) return ; - - if (tabState === TAB_STATE.SELECT_CREDENTIAL) return ; - switch (activeSidebar) { case "Credentials": + if ( + tabState === TAB_STATE.SELECT_CREDENTIAL || + tabState === TAB_STATE.SELECT_ID_CRED + ) + return ; + return ; case "Sign Ins": return ; default: + if ( + tabState === TAB_STATE.SELECT_IDENTIFIER || + tabState === TAB_STATE.SELECT_ID_CRED + ) + return ; + return ; } }; @@ -73,7 +85,7 @@ export function Main(props: IMain): JSX.Element { active={activeSidebar} onClickLink={setActiveSidebar} onSignout={props.handleDisconnect} - disabled={isSidebarDisabled()} + // disabled={isSidebarDisabled()} />
diff --git a/src/pages/background/index.ts b/src/pages/background/index.ts index f7db19be..1e50d2c6 100644 --- a/src/pages/background/index.ts +++ b/src/pages/background/index.ts @@ -4,8 +4,12 @@ import { userService } from "@pages/background/services/user"; import { signifyService } from "@pages/background/services/signify"; import { IMessage } from "@pages/background/types"; import { senderIsPopup } from "@pages/background/utils"; -import { getCurrentDomain } from "@pages/background/utils"; -import { updateDomainAutoSigninByIndex, deleteSigninByIndex } from "@pages/background/signins-utils"; +import { removeSlash, getCurrentDomain } from "@pages/background/utils"; +import { + updateDomainAutoSigninByIndex, + getSigninsByDomain, + deleteSigninByIndex, +} from "@pages/background/signins-utils"; console.log("Background script loaded"); @@ -148,8 +152,14 @@ chrome.runtime.onMessage.addListener(function ( }); } - if (message.type === "update-resource" && message.subtype === "auto-signin") { - const resp = await updateDomainAutoSigninByIndex(message?.data?.index, message?.data?.signin); + if ( + message.type === "update-resource" && + message.subtype === "auto-signin" + ) { + const resp = await updateDomainAutoSigninByIndex( + message?.data?.index, + message?.data?.signin + ); sendResponse({ data: { ...resp, @@ -179,29 +189,50 @@ chrome.runtime.onMessage.addListener(function ( return true; }); -chrome.runtime.onMessageExternal.addListener(async function ( - request, +chrome.runtime.onMessageExternal.addListener(function ( + message, sender, sendResponse ) { - console.log("Message received from external source: " + sender.url); - // if (sender.url === blocklistedWebsite) - // return; // don't allow this web page access - // if (request.openUrlInEditor) - // openUrl(request.openUrlInEditor); - // sendResponse({data: "received"}) - const origin = sender.url!; - const signins = (await browserStorageService.getValue("signins")) as any; - // Validate that message comes from a page that has a signin - if (origin.startsWith(signins[0].domain)) { - const signedHeaders = await signifyService.signHeaders( - signins[0].identifier.name, - origin - ); - let jsonHeaders: { [key: string]: string } = {}; - for (const pair of signedHeaders.entries()) { - jsonHeaders[pair[0]] = pair[1]; + (async () => { + console.log("Message received from external source: ", sender); + console.log("Message received from external request: ", message); + // if (sender.url === blocklistedWebsite) + // return; // don't allow this web page access + // if (request.openUrlInEditor) + // openUrl(request.openUrlInEditor); + // sendResponse({data: "received"}) + + if ( + message.type === "fetch-resource" && + message.subtype === "auto-signin-signature" + ) { + // Validate that message comes from a page that has a signin + + const origin = removeSlash(sender.url); + const signins = await getSigninsByDomain(origin); + 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.name ?? autoSignin?.credential?.schema?.title, + origin + ); + let jsonHeaders: { [key: string]: string } = {}; + for (const pair of signedHeaders.entries()) { + jsonHeaders[pair[0]] = pair[1]; + } + sendResponse({ data: { headers: jsonHeaders } }); } - sendResponse({ data: { headers: jsonHeaders } }); - } + })(); + + // return true to indicate chrome api to send a response asynchronously + return true; }); diff --git a/src/pages/background/signins-utils.ts b/src/pages/background/signins-utils.ts index 36557603..bdbf2fdf 100644 --- a/src/pages/background/signins-utils.ts +++ b/src/pages/background/signins-utils.ts @@ -1,5 +1,10 @@ import { browserStorageService } from "@pages/background/services/browser-storage"; +export const getSigninsByDomain = async (domain: string) => { + const signins = await browserStorageService.getValue("signins"); + return signins?.filter(signin => signin.domain === domain) ?? []; +}; + export const updateDomainAutoSigninByIndex = async (index: number, signin) => { let signins = await browserStorageService.getValue("signins"); if (signins?.length) { diff --git a/src/pages/background/utils.ts b/src/pages/background/utils.ts index 8e678042..2469d938 100644 --- a/src/pages/background/utils.ts +++ b/src/pages/background/utils.ts @@ -23,7 +23,7 @@ export const getCurrentTab = (): Promise => { export const getCurrentDomain = async () => { const currentTab = await getCurrentTab(); - console.log("Current tab: ", currentTab) + console.log("Current tab: ", currentTab); return currentTab ? new URL(currentTab.url!) : null; }; @@ -39,4 +39,8 @@ export const obfuscateString = (inputString: string) => { const suffix = inputString.slice(-suffixLength); return `${prefix}...${suffix}`; -} \ No newline at end of file +}; + +export const removeSlash = (site:string) => { + return site.replace(/\/$/, ""); +}; diff --git a/src/pages/content/index.tsx b/src/pages/content/index.tsx index 37548d9e..45ddf4e2 100644 --- a/src/pages/content/index.tsx +++ b/src/pages/content/index.tsx @@ -19,6 +19,7 @@ window.addEventListener( switch (event.data.type) { case TAB_STATE.SELECT_IDENTIFIER: case TAB_STATE.SELECT_CREDENTIAL: + case TAB_STATE.SELECT_ID_CRED: setTabState(TAB_STATE.DEFAULT); const { data } = await chrome.runtime.sendMessage>({ type: "authentication", diff --git a/src/pages/dialog/Dialog.tsx b/src/pages/dialog/Dialog.tsx index 61503666..cee5ad1d 100644 --- a/src/pages/dialog/Dialog.tsx +++ b/src/pages/dialog/Dialog.tsx @@ -67,7 +67,11 @@ export default function Dialog({ {!signins.length || !isConnected ? (

{tabUrl} requests authentication with{" "} - {eventType === TAB_STATE.SELECT_IDENTIFIER ? "AID" : "credential"} + {eventType === TAB_STATE.SELECT_IDENTIFIER + ? "AID" + : eventType === TAB_STATE.SELECT_ID_CRED + ? "AID or Credential" + : "Credential"}

) : null} diff --git a/src/pages/popup/constants.ts b/src/pages/popup/constants.ts index 7d2fa88d..2858097f 100644 --- a/src/pages/popup/constants.ts +++ b/src/pages/popup/constants.ts @@ -2,5 +2,6 @@ export const TAB_STATE = { DEFAULT: "default", SELECT_IDENTIFIER: "select-identifier", SELECT_CREDENTIAL: "select-credential", + SELECT_ID_CRED: "select-aid-or-credential", NONE: "none" } \ No newline at end of file