forked from jsnbuchanan/crowd-funder-for-time-pwa
add expiration inside JWANT & refactor getHeaders to move toward supporting did:peer
This commit is contained in:
@@ -2,7 +2,6 @@ import {
|
||||
Axios,
|
||||
AxiosRequestConfig,
|
||||
AxiosResponse,
|
||||
RawAxiosRequestHeaders,
|
||||
} from "axios";
|
||||
import * as didJwt from "did-jwt";
|
||||
import { LRUCache } from "lru-cache";
|
||||
@@ -13,7 +12,8 @@ import { DEFAULT_IMAGE_API_SERVER } from "@/constants/app";
|
||||
import { Contact } from "@/db/tables/contacts";
|
||||
import { accessToken, SimpleSigner } from "@/libs/crypto";
|
||||
import { NonsensitiveDexie } from "@/db/index";
|
||||
import { getIdentity } from "@/libs/util";
|
||||
import { createDidPeerJwt } from "@/libs/didPeer";
|
||||
import { getAccount, getIdentity } from "@/libs/util";
|
||||
|
||||
export const SCHEMA_ORG_CONTEXT = "https://schema.org";
|
||||
// the object in RegisterAction claims
|
||||
@@ -160,7 +160,7 @@ export interface OfferVerifiableCredential {
|
||||
// Note that previous VCs may have additional fields.
|
||||
// https://endorser.ch/doc/html/transactions.html#id7
|
||||
export interface PlanVerifiableCredential {
|
||||
"@context": SCHEMA_ORG_CONTEXT;
|
||||
"@context": "https://schema.org";
|
||||
"@type": "PlanAction";
|
||||
name: string;
|
||||
agent?: { identifier: string };
|
||||
@@ -453,28 +453,30 @@ export function didInfo(
|
||||
return didInfoForContact(did, activeDid, contact, allMyDids).displayName;
|
||||
}
|
||||
|
||||
async function getHeaders(identity: IIdentifier | null) {
|
||||
const headers: RawAxiosRequestHeaders = {
|
||||
export async function getHeaders(did?: string) {
|
||||
const headers: { "Content-Type": string; Authorization?: string } = {
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
if (identity) {
|
||||
const token = await accessToken(identity);
|
||||
if (did) {
|
||||
const token = await accessToken(undefined, did);
|
||||
headers["Authorization"] = "Bearer " + token;
|
||||
} else {
|
||||
// it's often OK to request without auth; we assume necessary checks are done earlier
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param handleId nullable, in which case "undefined" will be returned
|
||||
* @param identity nullable, in which case no private info will be returned
|
||||
* @param requesterDid optional, in which case no private info will be returned
|
||||
* @param axios
|
||||
* @param apiServer
|
||||
*/
|
||||
export async function getPlanFromCache(
|
||||
handleId: string | null,
|
||||
identity: IIdentifier | null,
|
||||
axios: Axios,
|
||||
apiServer: string,
|
||||
requesterDid?: string,
|
||||
): Promise<PlanSummaryRecord | undefined> {
|
||||
if (!handleId) {
|
||||
return undefined;
|
||||
@@ -485,7 +487,7 @@ export async function getPlanFromCache(
|
||||
apiServer +
|
||||
"/api/v2/report/plans?handleId=" +
|
||||
encodeURIComponent(handleId);
|
||||
const headers = await getHeaders(identity);
|
||||
const headers = await getHeaders(requesterDid);
|
||||
try {
|
||||
const resp = await axios.get(url, { headers });
|
||||
if (resp.status === 200 && resp.data?.data?.length > 0) {
|
||||
@@ -944,18 +946,34 @@ export const bvcMeetingJoinClaim = (did: string, startTime: string) => {
|
||||
};
|
||||
};
|
||||
|
||||
export async function createEndorserJwt(did: string, payload: object) {
|
||||
const account = await getAccount(did);
|
||||
if (account.identity) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const identity = JSON.parse(account.identity!);
|
||||
const privateKeyHex = identity.keys[0].privateKeyHex;
|
||||
const signer = await SimpleSigner(privateKeyHex);
|
||||
return didJwt.createJWT(payload, {
|
||||
issuer: did,
|
||||
signer: signer,
|
||||
});
|
||||
} else if (account.passkeyCredIdHex) {
|
||||
return createDidPeerJwt(did, account.passkeyCredIdHex, payload);
|
||||
} else {
|
||||
throw new Error("No identity data found to sign for DID " + did);
|
||||
}
|
||||
}
|
||||
|
||||
export async function register(
|
||||
activeDid: string,
|
||||
apiServer: string,
|
||||
axios: Axios,
|
||||
contact: Contact,
|
||||
) {
|
||||
const identity = await getIdentity(activeDid);
|
||||
|
||||
const vcClaim: RegisterVerifiableCredential = {
|
||||
"@context": SCHEMA_ORG_CONTEXT,
|
||||
"@type": "RegisterAction",
|
||||
agent: { identifier: identity.did },
|
||||
agent: { identifier: activeDid },
|
||||
object: SERVICE_ID,
|
||||
participant: { identifier: contact.did },
|
||||
};
|
||||
@@ -968,26 +986,10 @@ export async function register(
|
||||
},
|
||||
};
|
||||
// Create a signature using private key of identity
|
||||
if (identity.keys[0].privateKeyHex == null) {
|
||||
return { error: "Private key not found." };
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const privateKeyHex: string = identity.keys[0].privateKeyHex!;
|
||||
const signer = await SimpleSigner(privateKeyHex);
|
||||
const alg = undefined;
|
||||
// Create a JWT for the request
|
||||
const vcJwt: string = await didJwt.createJWT(vcPayload, {
|
||||
alg: alg,
|
||||
issuer: identity.did,
|
||||
signer: signer,
|
||||
});
|
||||
const vcJwt = await createEndorserJwt(activeDid, vcPayload);
|
||||
|
||||
// Make the xhr request payload
|
||||
const payload = JSON.stringify({ jwtEncoded: vcJwt });
|
||||
const url = apiServer + "/api/v2/claim";
|
||||
const headers = await getHeaders(identity);
|
||||
|
||||
const resp = await axios.post(url, payload, { headers });
|
||||
const resp = await axios.post(url, { jwtEncoded: vcJwt });
|
||||
if (resp.data?.success?.handleId) {
|
||||
return { success: true };
|
||||
} else if (resp.data?.success?.embeddedRecordError) {
|
||||
@@ -1017,7 +1019,7 @@ export async function setVisibilityUtil(
|
||||
const url =
|
||||
apiServer + "/api/report/" + (visibility ? "canSeeMe" : "cannotSeeMe");
|
||||
const identity = await getIdentity(activeDid);
|
||||
const headers = await getHeaders(identity);
|
||||
const headers = await getHeaders(identity.did);
|
||||
const payload = JSON.stringify({ did: contact.did });
|
||||
|
||||
try {
|
||||
@@ -1052,10 +1054,10 @@ export async function setVisibilityUtil(
|
||||
export async function fetchEndorserRateLimits(
|
||||
apiServer: string,
|
||||
axios: Axios,
|
||||
identity: IIdentifier,
|
||||
did: string,
|
||||
) {
|
||||
const url = `${apiServer}/api/report/rateLimits`;
|
||||
const headers = await getHeaders(identity);
|
||||
const headers = await getHeaders(did);
|
||||
return await axios.get(url, { headers } as AxiosRequestConfig);
|
||||
}
|
||||
|
||||
@@ -1070,9 +1072,9 @@ export async function fetchEndorserRateLimits(
|
||||
export async function fetchImageRateLimits(
|
||||
apiServer: string,
|
||||
axios: Axios,
|
||||
identity: IIdentifier,
|
||||
did: string,
|
||||
) {
|
||||
const url = DEFAULT_IMAGE_API_SERVER + "/image-limits";
|
||||
const headers = await getHeaders(identity);
|
||||
const headers = await getHeaders(did);
|
||||
return await axios.get(url, { headers } as AxiosRequestConfig);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user