Skip to content

Commit

Permalink
Merge pull request #65 from HunnySajid/feat/signin-actions
Browse files Browse the repository at this point in the history
feat: add remove dialog and delete signins functionality
  • Loading branch information
rodolfomiranda committed Jan 15, 2024
2 parents 792fb85 + 05af6a7 commit 92761d4
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 53 deletions.
23 changes: 17 additions & 6 deletions src/components/signinCard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export function SigninCard({ signin }): JSX.Element {
export function SigninCard({ signin, handleDelete }): JSX.Element {
return (
<div className="m-auto max-w-sm px-4 py-2 bg-white border border-gray-200 rounded-lg shadow text-gray-900">
<div className="flex flex-row justify-between">
Expand Down Expand Up @@ -30,11 +30,22 @@ export function SigninCard({ signin }): JSX.Element {
{signin?.identifier?.name}
</p>
</div>
<div className="">
<p className="font-bold text-gray-dark">Last Used</p>
<p className="font-normal text-md text-gray">
{new Date(signin?.updatedAt).toDateString()}
</p>
<div className="flex flex-row justify-between">
<div>
<p className="font-bold text-gray-dark">Last Used</p>
<p className="font-normal text-md text-gray">
{new Date(signin?.updatedAt).toDateString()}
</p>
</div>
<div className="flex items-end">
<button
type="button"
onClick={handleDelete}
className="text-white bg-green hover:bg-red font-medium rounded-full text-xs px-2 py-1 text-center"
>
{"Delete"}
</button>
</div>
</div>
</div>
);
Expand Down
25 changes: 24 additions & 1 deletion src/components/signinList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,26 @@ export function SigninList(): JSX.Element {
setIsLoading(false);
};

const deleteSignin = async (index: number) => {
const { data } = await chrome.runtime.sendMessage<IMessage<void>>({
type: "delete-resource",
subtype: "signins",
data: {
index,
},
});
if (data?.isDeleted) {
setSignins(data?.signins);
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
chrome.tabs.sendMessage(tabs[0].id!, {
type: "tab",
subtype: "reload-state",
eventType: "init-req-identifier",
});
});
}
};

useEffect(() => {
fetchSignins();
}, []);
Expand All @@ -30,7 +50,10 @@ export function SigninList(): JSX.Element {
) : null}
{signins.map((signin, index) => (
<div key={index} className="my-2 mx-4">
<SigninCard signin={signin} />
<SigninCard
signin={signin}
handleDelete={() => deleteSignin(index)}
/>
</div>
))}
{!isLoading && !signins?.length ? (
Expand Down
87 changes: 55 additions & 32 deletions src/pages/background/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ 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 { deleteSigninByIndex } from "@pages/background/signins-utils";

console.log("Background script loaded");

Expand All @@ -21,14 +22,14 @@ chrome.runtime.onMessage.addListener(function (
sendResponse
) {
(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 + ":" +
sender.tab.url +
" " +
message.type +
":" +
message.subtype
);

Expand All @@ -45,8 +46,11 @@ chrome.runtime.onMessage.addListener(function (
message.subtype === "get-signed-headers"
) {
const origin = sender.tab.url!;
const signedHeaders = await signifyService.signHeaders(message.data.signin.identifier.name, origin);
let jsonHeaders: { [key: string]: string; } = {};
const signedHeaders = await signifyService.signHeaders(
message.data.signin.identifier.name,
origin
);
let jsonHeaders: { [key: string]: string } = {};
for (const pair of signedHeaders.entries()) {
jsonHeaders[pair[0]] = pair[1];
}
Expand All @@ -60,10 +64,15 @@ chrome.runtime.onMessage.addListener(function (
const signins = await browserStorageService.getValue("signins");
sendResponse({ data: { signins: signins ?? [] } });
}
// Handle messages from Popup

// Handle messages from Popup
} else if (senderIsPopup(sender)) {
console.log("Message received from browser extension: " + message.type + "-" + message.subtype);
console.log(
"Message received from browser extension: " +
message.type +
"-" +
message.subtype
);

if (
message.type === "authentication" &&
Expand Down Expand Up @@ -98,7 +107,9 @@ chrome.runtime.onMessage.addListener(function (
}

if (message.type === "create-resource" && message.subtype === "signin") {
const signins = await browserStorageService.getValue("signins") as any[];
const signins = (await browserStorageService.getValue(
"signins"
)) as any[];
const currentDomain = await getCurrentDomain();

const { identifier, credential } = message.data;
Expand Down Expand Up @@ -137,39 +148,51 @@ chrome.runtime.onMessage.addListener(function (
});
}

if (message.type === "delete-resource" && message.subtype === "signins") {
const resp = await deleteSigninByIndex(message?.data?.index);
sendResponse({
data: {
...resp,
},
});
}

if (
message.type === "fetch-resource" &&
message.subtype === "credentials"
) {
const credentials = await signifyService.listCredentials();
sendResponse({ data: { credentials: credentials ?? [] } });
}

})();

// return true to indicate chrome api to send a response asynchronously
return true;
});

chrome.runtime.onMessageExternal.addListener(
async function(request, 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];
}
sendResponse({ data: { headers: jsonHeaders } });

chrome.runtime.onMessageExternal.addListener(async function (
request,
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];
}

});
sendResponse({ data: { headers: jsonHeaders } });
}
});
14 changes: 14 additions & 0 deletions src/pages/background/signins-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { browserStorageService } from "@pages/background/services/browser-storage";

export const deleteSigninByIndex = async (index: number) => {
let signins = await browserStorageService.getValue("signins");
let deleted = false;
if (signins?.length) {
const newSignins = signins.filter((_ele, idx) => idx !== index);
await browserStorageService.setValue("signins", newSignins);
deleted = newSignins.length !== signins?.length;
}
signins = await browserStorageService.getValue("signins");

return { isDeleted: deleted, signins };
};
26 changes: 15 additions & 11 deletions src/pages/content/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ window.addEventListener(
switch (event.data.type) {
case "init-req-identifier":
case "init-req-credential":
setTabState(TAB_STATE.DEFAULT)
setTabState(TAB_STATE.DEFAULT);
const { data } = await chrome.runtime.sendMessage<IMessage<void>>({
type: "authentication",
subtype: "check-agent-connection",
Expand Down Expand Up @@ -73,24 +73,27 @@ chrome.runtime.onMessage.addListener(async function (
data.isConnected,
data.tabUrl,
tabSigninResp?.data?.signins,
""
message.eventType ?? ""
);
}

}

if (message.type === "tab" && message.subtype === "get-tab-state") {
sendResponse({data: {appState:getTabState()}});
}
sendResponse({ data: { appState: getTabState() } });
}

if (message.type === "tab" && message.subtype === "set-tab-state") {
setTabState(message.data.appState);
}
}
}

});

function insertDialog(isConnected: boolean, tabUrl: string, signins: any, eventType: string) {
function insertDialog(
isConnected: boolean,
tabUrl: string,
signins: any,
eventType: string
) {
const div = document.createElement("div");
div.id = "__root";
document.body.appendChild(div);
Expand All @@ -103,6 +106,7 @@ function insertDialog(isConnected: boolean, tabUrl: string, signins: any, eventT
tabUrl={tabUrl}
signins={signins}
eventType={eventType}
removeDialog={removeDialog}
/>
);
}
Expand All @@ -113,11 +117,11 @@ function removeDialog() {
}

export function setTabState(state: string) {
console.log("setTabState: " + state)
console.log("setTabState: " + state);
tabState = state;
}

export function getTabState() {
console.log("getTabState: " + tabState)
console.log("getTabState: " + tabState);
return tabState;
}
}
16 changes: 13 additions & 3 deletions src/pages/dialog/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default function Dialog({
tabUrl = "",
signins = [],
eventType = "",
removeDialog,
}): JSX.Element {
const logo = chrome.runtime.getURL("src/assets/img/128_keri_logo.png");
const [showPopupPrompt, setShowPopupPrompt] = useState(false);
Expand Down Expand Up @@ -36,6 +37,10 @@ export default function Dialog({
}
}, []);

const handleRemove = () => {
removeDialog();
};

return (
<div className="absolute top-10 right-10 w-[320px] max-h-[540px] overflow-auto pt-7 ">
{showPopupPrompt ? (
Expand All @@ -51,6 +56,13 @@ export default function Dialog({
}
/>
) : null}
<button
type="button"
onClick={handleRemove}
className=" absolute opacity-90 hover:opacity-100 top-4 left-0 hover:bg-red hover:text-white text-gray-dark bg-white font-medium rounded-full text-xs px-2 py-1 text-center"
>
{"x"}
</button>
<div className="items-center justify-center rounded text-center p-3 bg-white">
<div className="flex flex-row gap-x-2 mb-2">
<img src={logo} className="h-8" alt="logo" />
Expand All @@ -77,9 +89,7 @@ export default function Dialog({
<img src={logo} className="h-4" alt="logo" />
</span>{" "}
to select other{" "}
{eventType === "init-req-identifier"
? "identifier"
: "credential"}{" "}
{eventType === "init-req-identifier" ? "AID" : "credential"}{" "}
</button>
</>
) : null}
Expand Down

0 comments on commit 92761d4

Please sign in to comment.