Skip to content

Commit

Permalink
Merge branch 'main' into feat/session-engine
Browse files Browse the repository at this point in the history
  • Loading branch information
HunnySajid committed Sep 6, 2024
2 parents e0f3b96 + a70d470 commit 037364f
Show file tree
Hide file tree
Showing 9 changed files with 415 additions and 12 deletions.
1 change: 1 addition & 0 deletions example-web/my-app/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

# misc
.DS_Store
.env
.env.local
.env.development.local
.env.test.local
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/config/event-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ export const CS_EVENTS = {
fetch_resource_auto_signin_signature: `${CS}-${EVENT_TYPE.fetch_resource}-auto-signin-signature`,
fetch_resource_signed_headers: `${CS}-${EVENT_TYPE.fetch_resource}-signed-headers`,
fetch_resource_tab_signin: `${CS}-${EVENT_TYPE.fetch_resource}-tab-signin`,
fetch_resource_credential: `${CS}-${EVENT_TYPE.fetch_resource}-credential`,

create_resource_data_attestation_credential: `${CS}-${EVENT_TYPE.create_resource}-data-attestation-credential`,

vendor_info_get_vendor_data: `${CS}-${EVENT_TYPE.vendor_info}-get-vendor-data`,
vendor_info_provide_config_url: `${CS}-${EVENT_TYPE.vendor_info}-provide-config-url`,
Expand Down
5 changes: 5 additions & 0 deletions src/pages/background/handlers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
handleFetchSignins,
handleFetchTabSignin,
handleUpdateAutoSignin,
handleCreateAttestationCredential,
handleFetchCredential
} from "./resource";
import { handleGetVendorData, handleAttemptSetVendorData } from "./vendorInfo";
import {
Expand Down Expand Up @@ -77,6 +79,9 @@ export function initCSHandler() {
handleFetchSignifyHeaders
);
handler.set(CS_EVENTS.fetch_resource_tab_signin, handleFetchTabSignin);
handler.set(CS_EVENTS.fetch_resource_credential, handleFetchCredential);

handler.set(CS_EVENTS.create_resource_data_attestation_credential, handleCreateAttestationCredential);

handler.set(CS_EVENTS.vendor_info_get_vendor_data, handleGetVendorData);
handler.set(
Expand Down
30 changes: 30 additions & 0 deletions src/pages/background/handlers/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ export async function handleFetchCredentials({ sendResponse }: IHandler) {
}
}

export async function handleFetchCredential({ sendResponse, data }: IHandler) {
const cred = await signifyService.getCredential(data.id, data.includeCESR);
sendResponse({
data: { credential: cred ?? null },
});
}

export async function handleCreateIdentifier({ sendResponse, data }: IHandler) {
try {
const resp = await signifyService.createAID(data.name);
Expand Down Expand Up @@ -180,6 +187,29 @@ export async function handleCreateSignin({ sendResponse, data }: IHandler) {
}
}

export async function handleCreateAttestationCredential({
sendResponse,
url,
tabId,
data,
}: IHandler) {
try {
const resp = await signifyService.createAttestationCredential({
origin: getDomainFromUrl(url!),
credData: data.credData,
schemaSaid: data.schemaSaid,
tabId: tabId!
});
sendResponse({
data: { ...resp },
});
} catch (error: any) {
sendResponse({
error: { code: 503, message: error?.message },
});
}
}

export async function handleUpdateAutoSignin({ sendResponse, data }: IHandler) {
const resp = await signinResource.updateDomainAutoSignin(data?.signin);
sendResponse({
Expand Down
128 changes: 117 additions & 11 deletions src/pages/background/services/signify.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import browser from "webextension-polyfill";
import { SignifyClient, Tier, ready, randomPasscode } from "signify-ts";
import * as signinResource from "@pages/background/resource/signin";
import { SignifyClient, Tier, ready, randomPasscode, Saider, IssueCredentialResult, CredentialData } from "signify-ts";
import { sendMessage } from "@src/shared/browser/runtime-utils";
import { sendMessageTab, getCurrentTab } from "@src/shared/browser/tabs-utils";
import { userService } from "@pages/background/services/user";
import { configService } from "@pages/background/services/config";
import { sessionService } from "@pages/background/services/session";
import { IIdentifier, ISignin, ISessionConfig } from "@config/types";
import { SW_EVENTS } from "@config/event-types";
import { formatAsCredentialEdgeOrRuleObject, getSchemaFieldOfEdge, parseSchemaEdgeOrRuleSection, setNodeValueInEdge, waitOperation } from "@src/shared/signify-utils";

const PASSCODE_TIMEOUT = 5;

Expand Down Expand Up @@ -139,13 +140,9 @@ const Signify = () => {
};

// credential identifier => credential.sad.d
const getCredentialWithCESR = async (credentialIdentifier: string) => {
const getCredential = async (credentialIdentifier: string, includeCESR: boolean = false) => {
validateClient();
try {
return await _client?.credentials().get(credentialIdentifier, true);
} catch (error) {
console.error(error);
}
return await _client?.credentials().get(credentialIdentifier, includeCESR);
};

const disconnect = async () => {
Expand Down Expand Up @@ -178,7 +175,7 @@ const Signify = () => {
let credentialResp;
if (signin.credential) {
credentialResp = { raw: signin.credential, cesr: null };
const cesr = await getCredentialWithCESR(signin.credential?.sad?.d);
const cesr = await getCredential(signin.credential?.sad?.d, true);
credentialResp.cesr = cesr;
}

Expand Down Expand Up @@ -231,7 +228,7 @@ const Signify = () => {
let credentialResp;
if (signin?.credential) {
credentialResp = { raw: signin.credential, cesr: null };
const cesr = await getCredentialWithCESR(signin.credential?.sad?.d);
const cesr = await getCredential(signin.credential?.sad?.d, true);
credentialResp.cesr = cesr;
}
const resp = {
Expand Down Expand Up @@ -311,15 +308,106 @@ const Signify = () => {
resetTimeoutAlarm();
console.log("sreq", sreq);
let jsonHeaders: { [key: string]: string } = {};
for (const pair of sreq?.headers?.entries()) {
jsonHeaders[pair[0]] = pair[1];
if (sreq?.headers) {
for (const pair of sreq.headers.entries()) {
jsonHeaders[pair[0]] = pair[1];
}
}

return {
headers: jsonHeaders,
};
};

/**
* Create a data attestation credential, it is an untargeted ACDC credential i.e. there is no issuee.
*
* @param origin - origin url from where request is being made -- required
* @param credData - credential data object containing the credential attributes -- required
* @param schemaSaid - SAID of the schema -- required
* @param signin - signin object containing identifier or credential -- required
* @returns Promise<Request> - returns a signed headers request object
*/
const createAttestationCredential = async ({
origin,
credData,
schemaSaid,
tabId
}: {
origin: string;
credData: any,
schemaSaid: string,
tabId: number;
}): Promise<any> => {
// in case the client is not connected, try to connect
const connected = await isConnected();
// connected is false, it means the client session timed out or disconnected by user
if (!connected) {
validateClient();
}

const session = await sessionService.get({ tabId, origin });
let { aid, registry, rules, edge } = await getCreateCredentialPrerequisites(session.aidName, schemaSaid);
if (isGroupAid(aid) === true) {
throw new Error(`Attestation credential issuance by multisig identifier ${session.aidName} is not supported yet!`);
}

let credArgs: CredentialData = {
i: aid.prefix,
ri: registry.regk,
s: schemaSaid,
a: credData,
r: rules
? Object.keys(rules).length > 0
? Saider.saidify({ d: '', ...rules })[1]
: undefined
: undefined,
e: edge
? Object.keys(edge).length > 0
? Saider.saidify({ d: '', ...edge })[1]
: undefined
: undefined
}
console.log("create credential args: ", credArgs);
let credResult = await createCredential(session.aidName, credArgs)
if (credResult && _client) {
await waitOperation(_client, credResult.op)
}

return credResult;
};

const getCreateCredentialPrerequisites = async (aidName: string, schemaSaid: string):
Promise<{ aid: any | undefined; schema: any; registry: any, rules: any, edge: any }> => {
const aid = await _client?.identifiers().get(aidName);

let registries = await _client?.registries().list(aidName)
if (registries == undefined || registries.length === 0) {
throw new Error(`No credential registries found for the AID ${aidName}`);
}

let schema = await _client?.schemas().get(schemaSaid)
if (!schema || schema?.title == '404 Not Found') {
throw new Error(`Schema not found!`);
}

const edgeObject = parseSchemaEdgeOrRuleSection(schema.properties?.e)
let edge = formatAsCredentialEdgeOrRuleObject(edgeObject)
let edgeSchema = getSchemaFieldOfEdge(edge)
if (edge && edgeSchema) {
let filter = { '-s': edgeSchema, '-a-i': aid?.prefix }
let creds = await _client?.credentials().list({ filter: filter, limit: 50 })
if (creds && creds?.length > 0) {
edge = setNodeValueInEdge(edge, creds[0]?.sad.d)
}
}

let parsedRules = parseSchemaEdgeOrRuleSection(schema.properties?.r)
let rules = formatAsCredentialEdgeOrRuleObject(parsedRules)

return { aid, schema, registry: registries[0], rules, edge };
};

const getControllerID = async (): Promise<string> => {
validateClient();
const controllerId = await userService.getControllerId();
Expand All @@ -332,12 +420,29 @@ const Signify = () => {
return await res?.op();
};

const createCredential = async (
name: string,
args: CredentialData
): Promise<IssueCredentialResult | undefined> => {
const result = await _client?.credentials().issue(name, args)
return result
}

const isGroupAid = (aid: any): boolean => {
return (
aid.hasOwnProperty('group') &&
typeof aid.group === 'object' &&
aid.group !== null
)
}

return {
connect,
isConnected,
disconnect,
listIdentifiers,
listCredentials,
getCredential,
createAID,
generatePasscode,
bootAndConnect,
Expand All @@ -346,6 +451,7 @@ const Signify = () => {
authorizeSelectedSignin,
getSessionInfo,
removeSessionInfo,
createAttestationCredential
};
};

Expand Down
68 changes: 68 additions & 0 deletions src/pages/content/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,75 @@ window.addEventListener(
}

break;
case TAB_STATE.CREATE_DATA_ATTEST_CRED:
const { data: credData, error: attestCredError } =
await sendMessageWithExtId<{
rurl?: string;
}>(getExtId(), {
type: CS_EVENTS.create_resource_data_attestation_credential,
data: event.data.payload,
});
requestId = event?.data?.requestId ?? "";
rurl = event?.data?.rurl ?? rurl;

console.log("create attest credential resp data", credData);
if (attestCredError) {
window.postMessage(
{
type: "/signify/reply",
error: attestCredError?.message,
requestId,
rurl,
},
"*"
);
} else {
window.postMessage(
{
type: "/signify/reply",
payload: credData,
requestId,
rurl,
},
"*"
);
}

break;
case TAB_STATE.GET_CREDENTIAL:
const { data: cred, error: credError } = await sendMessageWithExtId<{
rurl?: string;
}>(getExtId(), {
type: CS_EVENTS.fetch_resource_credential,
data: event.data.payload,
});
requestId = event?.data?.requestId ?? "";
rurl = event?.data?.rurl ?? rurl;

console.log("get credential result", cred);
if (credError) {
window.postMessage(
{
type: "/signify/reply",
error: credError?.message,
requestId,
rurl,
},
"*"
);
} else {
window.postMessage(
{
type: "/signify/reply",
payload: cred,
requestId,
rurl,
},
"*"
);
}

break;
default:
break;
}
Expand Down
2 changes: 2 additions & 0 deletions src/pages/popup/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ export const TAB_STATE = {
SIGN_REQUEST: "/signify/sign-request",
CONFIGURE_VENDOR: "/signify/configure-vendor",
SELECT_AUTO_SIGNIN: "select-auto-signin",
CREATE_DATA_ATTEST_CRED: "/signify/credential/create/data-attestation",
GET_CREDENTIAL: "/signify/credential/get",
NONE: "none"
}
Loading

0 comments on commit 037364f

Please sign in to comment.