diff --git a/src/components/GiftedDialog.vue b/src/components/GiftedDialog.vue index 183ac97e2..30274bedc 100644 --- a/src/components/GiftedDialog.vue +++ b/src/components/GiftedDialog.vue @@ -287,11 +287,10 @@ export default class GiftedDialog extends Vue { unitCode: string = "HUR", ) { try { - const identity = await libsUtil.getIdentity(this.activeDid); const result = await createAndSubmitGive( this.axios, this.apiServer, - identity, + this.activeDid, giverDid, this.receiver?.did as string, description, diff --git a/src/components/OfferDialog.vue b/src/components/OfferDialog.vue index e04888894..1498c065e 100644 --- a/src/components/OfferDialog.vue +++ b/src/components/OfferDialog.vue @@ -223,11 +223,10 @@ export default class OfferDialog extends Vue { } try { - const identity = await libsUtil.getIdentity(this.activeDid); const result = await createAndSubmitOffer( this.axios, this.apiServer, - identity, + this.activeDid, description, amount, unitCode, diff --git a/src/libs/crypto/index.ts b/src/libs/crypto/index.ts index f7eefdc95..169f271f5 100644 --- a/src/libs/crypto/index.ts +++ b/src/libs/crypto/index.ts @@ -101,11 +101,6 @@ export const accessToken = async (did?: string) => { } }; -export const sign = async (privateKeyHex: string) => { - const signer = SimpleSigner(privateKeyHex); - return signer; -}; - /** * Copied out of did-jwt since it's deprecated in that library. * diff --git a/src/libs/endorserServer.ts b/src/libs/endorserServer.ts index b124ca550..f05e6de2d 100644 --- a/src/libs/endorserServer.ts +++ b/src/libs/endorserServer.ts @@ -2,7 +2,6 @@ import { Axios, AxiosRequestConfig, AxiosResponse } from "axios"; import * as didJwt from "did-jwt"; import { LRUCache } from "lru-cache"; import * as R from "ramda"; -import { IIdentifier } from "@veramo/core"; import { DEFAULT_IMAGE_API_SERVER } from "@/constants/app"; import { Contact } from "@/db/tables/contacts"; @@ -516,6 +515,9 @@ export async function setPlanInCache( planCache.set(handleId, planSummary); } +/** + * Construct GiveAction VC for submission to server + */ export function constructGive( fromDid?: string | null, toDid?: string, @@ -570,7 +572,7 @@ export function constructGive( export async function createAndSubmitGive( axios: Axios, apiServer: string, - identity: IIdentifier, + issuerDid: string, fromDid?: string | null, toDid?: string, description?: string, @@ -594,7 +596,7 @@ export async function createAndSubmitGive( ); return createAndSubmitClaim( vcClaim as GenericCredWrapper, - identity, + issuerDid, apiServer, axios, ); @@ -612,7 +614,7 @@ export async function createAndSubmitGive( export async function createAndSubmitOffer( axios: Axios, apiServer: string, - identity: IIdentifier, + issuerDid: string, description?: string, amount?: number, unitCode?: string, @@ -623,7 +625,7 @@ export async function createAndSubmitOffer( const vcClaim: OfferVerifiableCredential = { "@context": SCHEMA_ORG_CONTEXT, "@type": "Offer", - offeredBy: { identifier: identity.did }, + offeredBy: { identifier: issuerDid }, validThrough: expirationDate || undefined, }; if (amount) { @@ -647,7 +649,7 @@ export async function createAndSubmitOffer( } return createAndSubmitClaim( vcClaim as GenericCredWrapper, - identity, + issuerDid, apiServer, axios, ); @@ -655,7 +657,7 @@ export async function createAndSubmitOffer( // similar logic is found in endorser-mobile export const createAndSubmitConfirmation = async ( - identifier: IIdentifier, + issuerDid: string, claim: GenericVerifiableCredential, lastClaimId: string, // used to set the lastClaimId handleId: string | undefined, @@ -672,12 +674,12 @@ export const createAndSubmitConfirmation = async ( "@type": "AgreeAction", object: goodClaim, }; - return createAndSubmitClaim(confirmationClaim, identifier, apiServer, axios); + return createAndSubmitClaim(confirmationClaim, issuerDid, apiServer, axios); }; export async function createAndSubmitClaim( vcClaim: GenericVerifiableCredential, - identity: IIdentifier, + issuerDid: string, apiServer: string, axios: Axios, ): Promise { @@ -690,34 +692,15 @@ export async function createAndSubmitClaim( }, }; - // Create a signature using private key of identity - const firstKey = identity.keys[0]; - const privateKeyHex = firstKey?.privateKeyHex; - - if (!privateKeyHex) { - throw { - error: "No private key", - message: `Your identifier ${identity.did} is not configured correctly. Use a different identifier.`, - }; - } - - const signer = await SimpleSigner(privateKeyHex); - - // Create a JWT for the request - const vcJwt: string = await didJwt.createJWT(vcPayload, { - issuer: identity.did, - signer, - }); + const vcJwt: string = await createEndorserJwt(issuerDid, vcPayload); // Make the xhr request payload const payload = JSON.stringify({ jwtEncoded: vcJwt }); const url = `${apiServer}/api/v2/claim`; - const token = await accessToken(identity.did); const response = await axios.post(url, payload, { headers: { "Content-Type": "application/json", - Authorization: `Bearer ${token}`, }, }); @@ -942,21 +925,36 @@ export const bvcMeetingJoinClaim = (did: string, startTime: string) => { }; }; -export async function createEndorserJwt(did: string, payload: object) { - const account = await getAccount(did); +export async function createEndorserJwtVcFromClaim( + issuerDid: string, + claim: object, +) { + // Make a payload for the claim + const vcPayload = { + vc: { + "@context": ["https://www.w3.org/2018/credentials/v1"], + type: ["VerifiableCredential"], + credentialSubject: claim, + }, + }; + return createEndorserJwt(issuerDid, vcPayload); +} + +export async function createEndorserJwt(issuerDid: string, payload: object) { + const account = await getAccount(issuerDid); 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, + issuer: issuerDid, signer: signer, }); } else if (account?.passkeyCredIdHex) { - return createDidPeerJwt(did, account.passkeyCredIdHex, payload); + return createDidPeerJwt(issuerDid, account.passkeyCredIdHex, payload); } else { - throw new Error("No identity data found to sign for DID " + did); + throw new Error("No identity data found to sign for DID " + issuerDid); } } @@ -1044,16 +1042,16 @@ export async function setVisibilityUtil( * * @param apiServer endorser server URL string * @param axios Axios instance - * @param {IIdentifier} identity - The identity object to check rate limits for. + * @param {string} issuerDid - The DID for which to check rate limits. * @returns {Promise} The Axios response object. */ export async function fetchEndorserRateLimits( apiServer: string, axios: Axios, - did: string, + issuerDid: string, ) { const url = `${apiServer}/api/report/rateLimits`; - const headers = await getHeaders(did); + const headers = await getHeaders(issuerDid); return await axios.get(url, { headers } as AxiosRequestConfig); } @@ -1062,15 +1060,11 @@ export async function fetchEndorserRateLimits( * * @param apiServer image server URL string * @param axios Axios instance - * @param {IIdentifier} identity - The identity object to check rate limits for. + * @param {string} issuerDid - The DID for which to check rate limits. * @returns {Promise} The Axios response object. */ -export async function fetchImageRateLimits( - apiServer: string, - axios: Axios, - did: string, -) { +export async function fetchImageRateLimits(axios: Axios, issuerDid: string) { const url = DEFAULT_IMAGE_API_SERVER + "/image-limits"; - const headers = await getHeaders(did); + const headers = await getHeaders(issuerDid); return await axios.get(url, { headers } as AxiosRequestConfig); } diff --git a/src/libs/util.ts b/src/libs/util.ts index 2e9c9803a..b92f6c7b6 100644 --- a/src/libs/util.ts +++ b/src/libs/util.ts @@ -16,7 +16,7 @@ import { createPeerDid, registerCredential } from "@/libs/didPeer"; import { Buffer } from "buffer"; export const PRIVACY_MESSAGE = - "The data you send be visible to the world -- except: your IDs and the IDs of anyone you tag will stay private, only visible to those you allow."; + "The data you send will be visible to the world -- except: your IDs and the IDs of anyone you tag will stay private, only visible to them and others you explicitly allow."; /* eslint-disable prettier/prettier */ export const UNIT_SHORT: Record = { diff --git a/src/test/index.ts b/src/test/index.ts index 1c2f5f45c..5b9d37699 100644 --- a/src/test/index.ts +++ b/src/test/index.ts @@ -6,6 +6,9 @@ import { SERVICE_ID } from "../libs/endorserServer"; import { deriveAddress, newIdentifier } from "../libs/crypto"; import { MASTER_SETTINGS_KEY } from "@/db/tables/settings"; +/** + * Get User #0 to sign & submit a RegisterAction for the user's activeDid. + */ export async function testServerRegisterUser() { const testUser0Mnem = "seminar accuse mystery assist delay law thing deal image undo guard initial shallow wrestle list fragile borrow velvet tomorrow awake explain test offer control"; diff --git a/src/views/AccountViewView.vue b/src/views/AccountViewView.vue index 0e4034b08..d32267eae 100644 --- a/src/views/AccountViewView.vue +++ b/src/views/AccountViewView.vue @@ -359,6 +359,7 @@
Derivation Path
{{ derivationPath }} @@ -375,6 +376,12 @@ Copied
+
+ (none) +
@@ -646,13 +653,16 @@