UNPKG

@iden3/js-iden3-auth

Version:

iden3-auth implementation in JavaScript

148 lines (147 loc) 7.06 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AtomicQueryV3PubSignalsVerifier = void 0; const ownershipVerifier_1 = require("../circuits/ownershipVerifier"); const common_1 = require("../circuits/common"); const js_iden3_core_1 = require("@iden3/js-iden3-core"); const js_jsonld_merklization_1 = require("@iden3/js-jsonld-merklization"); const js_sdk_1 = require("@0xpolygonid/js-sdk"); const constants_1 = require("../constants"); /** * Verifies the public signals for the AtomicQueryV3 circuit. * @beta */ class AtomicQueryV3PubSignalsVerifier extends ownershipVerifier_1.IDOwnershipPubSignals { constructor(pubSignals) { super(); this.pubSignals = new js_sdk_1.AtomicQueryV3PubSignals(); this.pubSignals = this.pubSignals.pubSignalsUnmarshal(js_sdk_1.byteEncoder.encode(JSON.stringify(pubSignals))); this.userId = this.pubSignals.userID; this.challenge = this.pubSignals.requestID; } async verifyQuery(query, schemaLoader, verifiablePresentation, opts, params) { const outs = { issuerId: this.pubSignals.issuerID, schemaHash: this.pubSignals.claimSchema, slotIndex: this.pubSignals.slotIndex, operator: this.pubSignals.operator, value: this.pubSignals.value, timestamp: this.pubSignals.timestamp, merklized: this.pubSignals.merklized, claimPathKey: this.pubSignals.claimPathKey, valueArraySize: constants_1.CONSTANTS.CIRCUITS_ARRAY_VALUE_SIZE, isRevocationChecked: this.pubSignals.isRevocationChecked, operatorOutput: this.pubSignals.operatorOutput }; if (!query.type) { throw new Error(`proof query type is undefined`); } const loader = schemaLoader ?? (0, js_jsonld_merklization_1.getDocumentLoader)(); // validate schema let context; try { context = (await loader(query.context ?? '')).document; } catch (e) { throw new Error(`can't load schema for request query`); } const queriesMetadata = await (0, js_sdk_1.parseQueriesMetadata)(query.type, JSON.stringify(context), query.credentialSubject, { documentLoader: loader }); const circuitId = js_sdk_1.CircuitId.AtomicQueryV3; await (0, js_sdk_1.checkQueryRequest)(query, queriesMetadata, context, outs, js_sdk_1.CircuitId.AtomicQueryV3, loader, opts); const queryMetadata = queriesMetadata[0]; // only one query is supported (0, js_sdk_1.checkCircuitOperator)(circuitId, outs.operator); // validate selective disclosure if (queryMetadata.operator === js_sdk_1.Operators.SD) { try { await (0, js_sdk_1.validateDisclosureNativeSDSupport)(queryMetadata, outs, verifiablePresentation, loader); } catch (e) { throw new Error(`failed to validate selective disclosure: ${e.message}`); } } else if (!queryMetadata.fieldName && queryMetadata.operator == js_sdk_1.Operators.NOOP) { try { await (0, js_sdk_1.validateEmptyCredentialSubjectNoopNativeSupport)(outs); } catch (e) { throw new Error(`failed to validate operators: ${e.message}`); } } else { try { await (0, js_sdk_1.validateOperators)(queryMetadata, outs); } catch (e) { throw new Error(`failed to validate operators: ${e.message}`); } } // verify field inclusion / non-inclusion (0, js_sdk_1.verifyFieldValueInclusionNativeExistsSupport)(outs, queryMetadata); const { proofType, verifierID, nullifier, nullifierSessionID, linkID } = this.pubSignals; switch (query.proofType) { case js_sdk_1.ProofType.BJJSignature: if (proofType !== 1) { throw new Error('wrong proof type for BJJSignature'); } break; case js_sdk_1.ProofType.Iden3SparseMerkleTreeProof: if (proofType !== 2) { throw new Error('wrong proof type for Iden3SparseMerkleTreeProof'); } break; default: // if proof type is not specified in query any proof type in signals is OK. } const nSessionId = BigInt(params?.nullifierSessionId ?? 0); if (nSessionId !== 0n) { if (BigInt(nullifier ?? 0) === 0n) { throw new Error('nullifier should be provided for nullification and should not be 0'); } // verify nullifier information const verifierDIDParam = params?.verifierDid; if (!verifierDIDParam) { throw new Error('verifierDid is required'); } const id = js_iden3_core_1.DID.idFromDID(verifierDIDParam); if (verifierID.bigInt() != id.bigInt()) { throw new Error('wrong verifier is used for nullification'); } if (nullifierSessionID !== nSessionId) { throw new Error(`wrong verifier session id is used for nullification, expected ${nSessionId}, got ${nullifierSessionID}`); } } else if (nullifierSessionID !== 0n) { throw new Error(`Nullifier id is generated but wasn't requested`); } if (!query.groupId && linkID !== 0n) { throw new Error(`proof contains link id, but group id is not provided`); } if (query.groupId && linkID === 0n) { throw new Error("proof doesn't contain link id, but group id is provided"); } return this.pubSignals; } async verifyStates(resolvers, opts) { const resolver = (0, common_1.getResolverByID)(resolvers, this.pubSignals.issuerID); if (!resolver) { throw new Error(`resolver not found for issuerID ${this.pubSignals.issuerID.string()}`); } await (0, common_1.checkUserState)(resolver, this.pubSignals.issuerID, this.pubSignals.issuerState); if (this.pubSignals.isRevocationChecked === 0) { return; } const issuerNonRevStateResolved = await (0, common_1.checkIssuerNonRevState)(resolver, this.pubSignals.issuerID, this.pubSignals.issuerClaimNonRevState); const acceptedStateTransitionDelay = opts?.acceptedStateTransitionDelay ?? constants_1.CONSTANTS.ACCEPTED_STATE_TRANSITION_DELAY; if (issuerNonRevStateResolved.latest) { return; } const timeDiff = Date.now() - (0, js_iden3_core_1.getDateFromUnixTimestamp)(Number(issuerNonRevStateResolved.transitionTimestamp)).getTime(); if (timeDiff > acceptedStateTransitionDelay) { throw new Error('issuer state is outdated'); } } } exports.AtomicQueryV3PubSignalsVerifier = AtomicQueryV3PubSignalsVerifier;