From 8def57f55ae80ff0e465d5014921921c80789892 Mon Sep 17 00:00:00 2001 From: mohamedalichelbi Date: Fri, 12 Apr 2024 16:14:30 +0200 Subject: [PATCH] Add RP tabs --- src/pages/verifier/tabs/admin.tsx | 102 +++++++++++++++++++++++++++++ src/pages/verifier/tabs/holder.tsx | 70 ++++++++++++++++++++ src/pages/verifier/tabs/index.ts | 2 + src/pages/verifier/verifier.tsx | 38 ++++++++++- src/utils/api.ts | 26 ++++++++ 5 files changed, 236 insertions(+), 2 deletions(-) create mode 100644 src/pages/verifier/tabs/admin.tsx create mode 100644 src/pages/verifier/tabs/holder.tsx create mode 100644 src/pages/verifier/tabs/index.ts diff --git a/src/pages/verifier/tabs/admin.tsx b/src/pages/verifier/tabs/admin.tsx new file mode 100644 index 0000000..0e7056b --- /dev/null +++ b/src/pages/verifier/tabs/admin.tsx @@ -0,0 +1,102 @@ +import { useState, useEffect } from "react" +import { getPresentations, modifyPresentations} from "../../../utils" +import { DataGrid, GridColDef } from '@mui/x-data-grid'; +import { TextField, Button } from "@mui/material" + + +const columns: GridColDef[] = [ + { field: 'id', headerName: 'ID', width: 70 }, + { field: 'status', headerName: 'Status', width: 100 }, + { field: 'cred_hashes', headerName: 'Credential hashes', width: 140 }, + { field: 'cred_schemas', headerName: 'Credential schemas', width: 1000 }, + { field: 'lang', headerName: 'Language', width: 100 }, + { field: 'script', headerName: 'Script', width: 1000 }, + { field: 'result', headerName: 'Result', width: 70 }, +]; + + +export function AdminsTab() { + const [presentations, setPresentations] = useState([]); + const [toApprove, setToApprove] = useState(""); + const [toDeny, setToDeny] = useState(""); + + const fetchData = async () => { + const res = await getPresentations() + setPresentations(res.map((x, index) => { + x["id"] = index; + x["cred_schemas"] = x["cred_schemas"].map((y: string) => atob(y)); + return x; + })); + } + + const handleChange = (event: React.ChangeEvent) => { + switch(event.target.id) { + case "todeny": + setToDeny(event.target.value) + break + case "toapprove": + setToApprove(event.target.value) + break + } + } + + const handleApprove = () => { + const idx = toApprove.split(",").filter(x => x != "").map(x => parseInt(x)); + modifyPresentations(idx, []).then(() => { fetchData() }); + } + + const handleDeny = () => { + const idx = toDeny.split(",").filter(x => x != "").map(x => parseInt(x)); + modifyPresentations([], idx).then(() => { fetchData() }); + } + + useEffect(() => { fetchData() }, []) + + return ( + <> +
+ +
+
+

Manage presentation status

+ + +
+
+ + + + ); +} \ No newline at end of file diff --git a/src/pages/verifier/tabs/holder.tsx b/src/pages/verifier/tabs/holder.tsx new file mode 100644 index 0000000..c2ffea1 --- /dev/null +++ b/src/pages/verifier/tabs/holder.tsx @@ -0,0 +1,70 @@ +import { useState } from "react" +import { checkPresentation } from "../../../utils" +import { TextField, Button } from "@mui/material" + +export function HoldersTab() { + const [receipt, setReceipt] = useState(""); + const [issuers, setIssuers] = useState(""); + const [msg, setMsg] = useState(""); + + const handleChange = (event: React.ChangeEvent) => { + switch(event.target.id) { + case "receipt-field": + setReceipt(event.target.value) + break + case "issuers-field": + setIssuers(event.target.value) + break + } + } + + const handleSubmit = () => { + const issuersList = issuers.split(",").filter(x => x != ""); + checkPresentation(issuersList, receipt).then((result) => setMsg(JSON.stringify(result))) + } + + const msgToStatus = (): string => { + if (msg === "") { + return ""; + } + const parsedMsg = JSON.parse(msg); + if (parsedMsg["verdict"] === true) { + return "Success ✅"; + } + else { + return `Error: ${parsedMsg["error"]}` + } + } + + return ( + <> +
+ +
+
+ +
+
+ +
+
{msgToStatus()}
+ + ); +} \ No newline at end of file diff --git a/src/pages/verifier/tabs/index.ts b/src/pages/verifier/tabs/index.ts new file mode 100644 index 0000000..27fba60 --- /dev/null +++ b/src/pages/verifier/tabs/index.ts @@ -0,0 +1,2 @@ +export * from "./admin" +export * from "./holder" \ No newline at end of file diff --git a/src/pages/verifier/verifier.tsx b/src/pages/verifier/verifier.tsx index 2b56279..1c7ccc0 100644 --- a/src/pages/verifier/verifier.tsx +++ b/src/pages/verifier/verifier.tsx @@ -1,6 +1,40 @@ +import { useState } from 'react' +import { HoldersTab, AdminsTab } from './tabs' +import { Tabs, Tab, Box } from '@mui/material' + + export function Verifier() { - document.title = 'Verifier' + const [activeTab, setActiveTab] = useState("holders") + + const handleChange = (_event: React.SyntheticEvent, newValue: string) => { + setActiveTab(newValue); + }; + + const displayActiveTab = () => { + switch (activeTab) { + case "holders": + return + case "admins": + return + default: + return <> + } + } + + document.title = 'Verifer' return( - <>Verifier Page + <> + Relying Party Page + + + + + + + {displayActiveTab()} + ) } \ No newline at end of file diff --git a/src/utils/api.ts b/src/utils/api.ts index 7938527..da4e97a 100644 --- a/src/utils/api.ts +++ b/src/utils/api.ts @@ -92,4 +92,30 @@ export async function generateProof(credentials: string[], lang: string, script: export async function getProofStatus(taskId: number): Promise { return (await fetch(`${getBackendUrl()}/holder/proof/status/${taskId}`)).json() +} + +export async function getPresentations(): Promise { + return (await fetch(`${getBackendUrl()}/verifier/presentations`)).json() +} + +export async function modifyPresentations(approve: number[], deny: number[]): Promise { + return (await fetch(`${getBackendUrl()}/verifier/presentations`, { + method: "POST", + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ approve, deny }) + })).json() +} + +export async function checkPresentation(cred_issuers: string[], base64_receipt: string): Promise { + return (await fetch(`${getBackendUrl()}/verifier/check`, { + method: "POST", + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ cred_issuers, base64_receipt, }) + })).json() } \ No newline at end of file