|  |  | @ -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, | 
			
		
	
		
			
				
					|  |  |  |   }); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   // Make the xhr request payload
 | 
			
		
	
		
			
				
					|  |  |  |   const payload = JSON.stringify({ jwtEncoded: vcJwt }); | 
			
		
	
		
			
				
					|  |  |  |   const url = apiServer + "/api/v2/claim"; | 
			
		
	
		
			
				
					|  |  |  |   const headers = await getHeaders(identity); | 
			
		
	
		
			
				
					|  |  |  |   const vcJwt = await createEndorserJwt(activeDid, vcPayload); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   const resp = await axios.post(url, payload, { headers }); | 
			
		
	
		
			
				
					|  |  |  |   const url = apiServer + "/api/v2/claim"; | 
			
		
	
		
			
				
					|  |  |  |   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); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
	
		
			
				
					|  |  | 
 |