From a11fc827c9acbcfb104583136dea4f8234551009 Mon Sep 17 00:00:00 2001 From: Nick Taras Date: Wed, 18 Oct 2023 12:21:27 +1100 Subject: [PATCH] fix for off chain attestations when authenticating a single token. --- CHANGELOG.md | 1 + src/client/index.ts | 37 +++++++++++++------------------------ src/client/interface.ts | 1 + src/outlet/index.ts | 6 +++--- 4 files changed, 18 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 009b373a..69937de4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ Feature release including multi-hook support, improved UX for off chain token ho ### Bug Fixes - TS interface custom view +- Single token off chain authentication incompatibility interface fix ### Performance / Quality Improvements diff --git a/src/client/index.ts b/src/client/index.ts index 8ad3650d..7f417f58 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -485,7 +485,7 @@ export class Client { private tokensSelectedCallBackHandler = () => { this.eventSender('tokens-selected', { selectedTokens: this.tokenStore.getSelectedTokens(), - selectedTokenKeys: Object.keys(this.tokenStore.getSelectedTokens()), + selectedIssuerKeys: Object.keys(this.tokenStore.getSelectedTokens()), }) } @@ -817,12 +817,13 @@ export class Client { async prepareToAuthenticateToken(authRequest: AuthenticateInterface) { await this.checkUserAgentSupport('authentication') - const { unsignedToken, tokenId } = authRequest - if (!authRequest.issuer) authRequest.issuer = unsignedToken?.collectionId - requiredParams(authRequest.issuer && (unsignedToken || tokenId), 'Issuer and unsigned token required.') - const config = this.tokenStore.getCurrentIssuers()[authRequest.issuer] + const unsignedToken = authRequest?.unsignedToken ?? authRequest + const issuer = authRequest?.issuer ?? unsignedToken?.collectionId ?? authRequest?.collectionId + const tokenId = authRequest?.tokenId + requiredParams(issuer && (unsignedToken || tokenId), 'Issuer and unsigned token required.') + const config = this.tokenStore.getCurrentIssuers()[issuer] if (!config) errorHandler('Provided issuer was not found.', 'error', null, null, true, true) - return authRequest + return { unsignedToken, issuer, tokenId } } async getMultiRequestBatch(authRequests: AuthenticateInterface[]) { @@ -830,41 +831,29 @@ export class Client { onChain: {}, offChain: {}, } - // build a list of the batches for each token origin. At this point when this loop is complete - // we will have a list of all the tokens that need to be authenticated and the origin they need to be authenticated against. await Promise.all( authRequests.map(async (authRequestItem) => { const reqItem = await this.prepareToAuthenticateToken(authRequestItem) - - if (!reqItem.tokenId && reqItem.unsignedToken?.tokenId) reqItem.tokenId = reqItem.unsignedToken?.tokenId - const issuerConfig = this.tokenStore.getCurrentIssuers()[reqItem.issuer] as OffChainTokenConfig - // Off Chain - // Setup for Token Collection. e.g. authRequestBatch.offChain['https://mywebsite.com']['devcon'] - /** - * Always generate a batch - */ if (issuerConfig.onChain === false) { if (!authRequestBatch.offChain[issuerConfig.tokenOrigin]) authRequestBatch.offChain[issuerConfig.tokenOrigin] = {} - if (!authRequestBatch.offChain[issuerConfig.tokenOrigin][reqItem.issuer]) { authRequestBatch.offChain[issuerConfig.tokenOrigin][reqItem.issuer] = { tokenIds: [], issuerConfig: issuerConfig, } } - // Push token into the request batch - authRequestBatch.offChain[issuerConfig.tokenOrigin][reqItem.issuer].tokenIds.push(reqItem.tokenId) + authRequestBatch.offChain[issuerConfig.tokenOrigin][reqItem.issuer].tokenIds.push( + reqItem.tokenId ?? reqItem.unsignedToken.tokenId, + ) return } - throw new Error('On-chain token are not supported by batch authentication at this time.') }), ) - - if (Object.keys(authRequestBatch.offChain).length > 1) + if (Object.keys(authRequestBatch.offChain).length > 1) { throw new Error('Only a single token origin is supported by batch authentication at this time.') - + } return authRequestBatch } @@ -890,7 +879,6 @@ export class Client { const authRequestBatch = await this.getMultiRequestBatch(authRequests) let issuerProofs = {} - // Send the request batches to each token origin: // Off Chain: // ['https://devcon.com']['issuer'][list of tokenIds] for (const tokenOrigin in authRequestBatch.offChain) { let AuthType = TicketZKProofMulti @@ -1137,6 +1125,7 @@ export class Client { if (issuerConfig) this.storeOutletTokenResponse(res.data.tokens) this.eventSender('tokens-selected', { selectedTokens: this.tokenStore.getSelectedTokens(), + selectedIssuerKeys: Object.keys(this.tokenStore.getSelectedTokens()), }) return res.data.tokens } diff --git a/src/client/interface.ts b/src/client/interface.ts index 5bb34a80..52d9a2ff 100644 --- a/src/client/interface.ts +++ b/src/client/interface.ts @@ -143,6 +143,7 @@ export interface MultiTokenInterface { } export interface AuthenticateInterface { + collectionId?: string issuer: string tokenId?: number | string unsignedToken: any diff --git a/src/outlet/index.ts b/src/outlet/index.ts index 9cefca4e..e97c0578 100644 --- a/src/outlet/index.ts +++ b/src/outlet/index.ts @@ -209,13 +209,13 @@ export class Outlet extends LocalOutlet { async sendTokenProof(evtid: string) { const collectionId: string = this.getDataFromQuery('issuer') - const tokenId: string = this.getDataFromQuery('tokenId') + const token: string = this.getDataFromQuery('tn-token') const wallet: string = this.getDataFromQuery('wallet') const address: string = this.getDataFromQuery('address') + const tokenParsed = JSON.parse(token) + const tokenId = tokenParsed.tokenId requiredParams(tokenId, 'tokenId is missing') - const redirect = this.getDataFromQuery('redirect') === 'true' ? window.location.href : false - try { const issuer = this.getIssuerConfigById(collectionId)