UNPKG

@microsoft/useragent-sdk

Version:

SDK for building decentralized identity wallets and enterprise agents.

1,172 lines (1,157 loc) 3.29 MB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.useragentSdk = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const CryptoFactory_1 = require("./crypto/plugin/CryptoFactory"); const SubtleCryptoBrowserOperations_1 = require("./crypto/plugin/SubtleCryptoBrowser"); const KeyStoreInMemory_1 = require("./crypto/keyStore/KeyStoreInMemory"); const JoseProtocol_1 = require("./crypto/protocols/jose/JoseProtocol"); /** * Class used to model crypto options */ class CryptoOptions { constructor() { /** * Get or set the crypto api to be used. Initialize the default crypto plugin. */ this.cryptoFactory = new CryptoFactory_1.default(new KeyStoreInMemory_1.default(), new SubtleCryptoBrowserOperations_1.default()); /** * Get or set the payload protection protocol. */ this.payloadProtection = new JoseProtocol_1.default(); /** * Get or set the signing algorithm. */ this.signingAlgorithm = 'ES256K'; /** * Get or set the encryption algorithm. */ this.encryptionAlgorithm = 'RSA-OAEP'; } } exports.default = CryptoOptions; },{"./crypto/keyStore/KeyStoreInMemory":11,"./crypto/plugin/CryptoFactory":26,"./crypto/plugin/SubtleCryptoBrowser":28,"./crypto/protocols/jose/JoseProtocol":35}],2:[function(require,module,exports){ (function (Buffer){ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); const KeyStoreConstants_1 = require("./keystores/KeyStoreConstants"); const IdentifierDocument_1 = require("./IdentifierDocument"); const UserAgentError_1 = require("./UserAgentError"); const ProtectionFormat_1 = require("./crypto/keyStore/ProtectionFormat"); const SubtleCryptoExtension_1 = require("./crypto/plugin/SubtleCryptoExtension"); const JwsToken_1 = require("./crypto/protocols/jose/jws/JwsToken"); const CryptoHelpers_1 = require("./crypto/utilities/CryptoHelpers"); const KeyUseFactory_1 = require("./crypto/keys/KeyUseFactory"); const JweToken_1 = require("./crypto/protocols/jose/jwe/JweToken"); const JoseConstants_1 = require("./crypto/protocols/jose/JoseConstants"); const UserAgentConstants_1 = require("./UserAgentConstants"); /** * Class for creating and managing identifiers, * retrieving identifier documents. */ class Identifier { /** * Constructs an instance of the Identifier * class using the provided identifier or identifier document. * @param identifier either the string representation of an identifier or a identifier document. * @param [options] for configuring how to register and resolve identifiers. */ constructor(identifier, options) { this.identifier = identifier; // Check whether passed an identifier document // or an identifier string if (typeof identifier === 'object') { this.document = identifier; this.id = identifier.id; } else { this.id = identifier; } this.options = options; } /** * Creates a new decentralized identifier. * @param [options] for configuring how to register and resolve identifiers. */ static async create(options) { const id = options.didPrefix; return new Identifier(id, options).createLinkedIdentifier(id, true); } /** * Creates a new decentralized identifier, using the current identifier * and the specified target. If the registar flag is true, the newly created * identifier will be registered using the * @param target entity for which to create the linked identifier * @param register flag indicating whether the new identifier should be registered * with a ledger. */ async createLinkedIdentifier(target, register = false) { if (this.options && this.options.keyStore) { // Create DID key const cryptoFactory = this.options.cryptoFactory; const signingKeyStorageId = Identifier.keyStorageIdentifier(this.id, target, this.options.cryptoOptions.signingAlgorithm, KeyUseFactory_1.default.createViaJwa(this.options.cryptoOptions.signingAlgorithm)); const signingPublicKey = await this.generateAndSaveKey(new SubtleCryptoExtension_1.default(cryptoFactory), this.options.cryptoOptions.signingAlgorithm, target, `#${UserAgentConstants_1.default.keyTagSigning}1`, signingKeyStorageId || this.options.cryptoOptions.signingKeyReference); const encryptionKeyStorageId = Identifier.keyStorageIdentifier(this.id, target, this.options.cryptoOptions.encryptionAlgorithm, KeyUseFactory_1.default.createViaJwa(this.options.cryptoOptions.encryptionAlgorithm)); const encryptionPublicKey = await this.generateAndSaveKey(new SubtleCryptoExtension_1.default(cryptoFactory), this.options.cryptoOptions.encryptionAlgorithm, target, `#${UserAgentConstants_1.default.keyTagEncryption}1`, encryptionKeyStorageId || this.options.cryptoOptions.encryptionKeyReference); // Set key format // todo switch by leveraging pairwiseKey const signingDocumentKey = { id: signingPublicKey.kid, type: this.getDidDocumentKeyType(), publicKeyJwk: signingPublicKey }; const encryptionDocumentKey = { id: encryptionPublicKey.kid, // we need to add RsaEncryptionKey 2018 as type - todo type: 'RsaVerificationKey2018', publicKeyJwk: encryptionPublicKey }; let identifier; if (this.options.registrar) { // add encryptionDocumentKey to register the encryption key const document = await this.createIdentifierDocument(this.id, [signingDocumentKey, encryptionDocumentKey]); if (register) { // register did document identifier = await this.options.registrar.register(document, signingKeyStorageId); document.id = identifier.id; } identifier = new Identifier(document, this.options); // If we create a new identifier save the signing key if (target === this.id) { this.options.cryptoOptions.signingKeyReference = signingKeyStorageId; this.options.cryptoOptions.encryptionKeyReference = encryptionKeyStorageId; } return identifier; } else { throw new UserAgentError_1.default(`No registrar in options to register DID document`); } } throw new UserAgentError_1.default('No keyStore in options'); } /** * Generate a key and save it into the store * @param generator interface * @param algorithm for the key * @param target id of peer */ async generateAndSaveKey(generator, algorithm, target, kid, keyReference) { const alg = CryptoHelpers_1.default.jwaToWebCrypto(algorithm); const jwk = await generator.generatePairwiseKey(alg, KeyStoreConstants_1.default.masterSeed, this.id, target); jwk.kid = kid; jwk.use = KeyUseFactory_1.default.createViaJwa(algorithm); const pubJwk = jwk.getPublicKey(); pubJwk.kid = jwk.kid; const pairwiseKeyStorageId = keyReference || Identifier.keyStorageIdentifier(this.id, target, algorithm, KeyUseFactory_1.default.createViaJwa(algorithm)); await this.options.keyStore.save(pairwiseKeyStorageId, jwk); return pubJwk; } /** * Gets the IdentifierDocument for the identifier * instance, throwing if no identifier has been * created. */ async getDocument() { // If we already have not already // retrieved the document use the // resolver to get the document if (!this.document) { if (!this.options || !this.options.resolver) { throw new UserAgentError_1.default('Resolver not specified in user agent options.'); } // We need to resolve the document this.document = await this.options.resolver.resolve(this); } return this.document; } /** * Performs a public key lookup using the * specified key identifier, returning the * key defined in document. * @param keyIdentifier the identifier of the public key. */ async getPublicKey(keyIdentifier) { if (!this.document) { await this.getDocument(); } // If we have been provided a key identifier use // the identifier to look up a key in the document if (this.document && this.document.publicKeys && keyIdentifier) { const index = this.document.publicKeys.findIndex((key) => key.id === keyIdentifier); // trim down the key Identifier to the unique keyID const keyIdentifierComponents = keyIdentifier.split('#'); const keyId = keyIdentifierComponents[keyIdentifierComponents.length - 1]; const matchingPublicKeys = this.document.publicKeys.filter((PublicKey) => PublicKey.id.endsWith(keyId)); if (matchingPublicKeys.length === 0) { throw new UserAgentError_1.default(`No matching public key found for ${keyIdentifier}`); } return matchingPublicKeys[0]; } else if (this.document && this.document.publicKeys && this.document.publicKeys.length > 0) { // If only one key has been specified in the document // return that return this.document.publicKeys[0]; } throw new UserAgentError_1.default('Document does not contain any public keys'); } /** * Generate a storage identifier to store a key * @param personaId The identifier for the persona * @param target The identifier for the peer. Will be persona for non-pairwise keys * @param algorithm Key algorithm * @param keyType Key type */ static keyStorageIdentifier(personaId, target, algorithm, keyType) { console.log(`${personaId}-${target}-${algorithm}-${keyType}`); return `${personaId}-${target}-${algorithm}-${keyType}`; } // Create an identifier document. Included the public key. async createIdentifierDocument(id, publicKeys) { return IdentifierDocument_1.default.createAndGenerateId(id, publicKeys, this.options); } // Get the did document public key type getDidDocumentKeyType() { // Support other key types return 'Secp256k1VerificationKey2018'; } /** * Sign payload with key specified by keyStorageIdentifier in options.keyStore * @param payload object to be signed * @param keyReference the identifier for the key used to sign payload. */ async sign(payload, keyReference) { let body; if (this.options && this.options.cryptoOptions) { if (this.options.keyStore) { if (typeof (payload) !== 'string') { body = JSON.stringify(payload); } else { body = payload; } const signingOptions = { cryptoFactory: this.options.cryptoFactory }; const jws = new JwsToken_1.default(signingOptions); const signature = await jws.sign(keyReference, Buffer.from(body), ProtectionFormat_1.ProtectionFormat.JwsFlatJson); return signature.serialize(); ; } else { throw new UserAgentError_1.default('No KeyStore in Options'); } } else { throw new UserAgentError_1.default('No Crypto Options in User Agent Options'); } } /** * Verify the payload with public key from the Identifier Document. * @param jws the signed token to be verified. */ async verify(jws) { if (!this.document) { this.document = await this.getDocument(); } const signingOptions = { cryptoFactory: this.options.cryptoFactory }; const token = JwsToken_1.default.deserialize(jws, signingOptions); if (await token.verify(this.document.getPublicKeysFromDocument(), signingOptions)) { return token.getPayload(); } throw new UserAgentError_1.default(`The signature validation for '${this.id}' failed.`); } /** * Encrypt payload using Public Key registered on Identifier Document. * @param payload object that will be encrypted. * @param encryptionKeys used for the encryption. */ async encrypt(payload) { if (!this.options) { throw new UserAgentError_1.default('Options Undefined'); } // get document if undefined if (!this.document) { this.document = await this.getDocument(); } const keyStore = this.options.keyStore; const cryptoFactory = this.options.cryptoFactory; const options = { cryptoFactory: cryptoFactory, contentEncryptionAlgorithm: JoseConstants_1.default.AesGcm256 }; // create a jweToken with temp cryptoFactory and algorithm. const jweToken = new JweToken_1.default(options); // get any JWK key marked use as 'enc' const publicKey = this.document.getPublicKeysFromDocument().reduce((keyFound, currentKey) => { if (keyFound) { return keyFound; } if (currentKey.use === KeyUseFactory_1.KeyUse.Encryption) { return currentKey; } return undefined; }, undefined); if (!publicKey) { throw new UserAgentError_1.default(`No Public Key found with use equal to 'enc' for ${this.id}`); } // keyIDs retrieved from the DID Document may not be fully quantified if (publicKey.kid && publicKey.kid.indexOf('#') <= 0) { publicKey.kid = `${this.id}${publicKey.kid.indexOf('#') === -1 ? '#' : ''}${publicKey.kid}`; } // encrypt payload using public keys. const encryptedToken = await jweToken.encrypt([publicKey], payload, ProtectionFormat_1.ProtectionFormat.JweCompactJson); // return serialized token. return encryptedToken.serialize(ProtectionFormat_1.ProtectionFormat.JweCompactJson); } /** * Decrypt cipher using key referenced in keystore. * @param cipher cipher to be decrypted. * @param keyReference string that references what key to use from keystore. */ async decrypt(cipher, keyReference) { if (!this.options) { throw new UserAgentError_1.default('Options Undefined'); } const options = { cryptoFactory: this.options.cryptoFactory }; const jweToken = JweToken_1.default.deserialize(cipher.toString(), options); // create jweToken, feed in ciphertext, and decrypt. const payload = await jweToken.decrypt(keyReference); return payload.toString(); } } exports.default = Identifier; }).call(this,require("buffer").Buffer) },{"./IdentifierDocument":3,"./UserAgentConstants":4,"./UserAgentError":5,"./crypto/keyStore/ProtectionFormat":12,"./crypto/keys/KeyUseFactory":15,"./crypto/plugin/SubtleCryptoExtension":29,"./crypto/protocols/jose/JoseConstants":33,"./crypto/protocols/jose/jwe/JweToken":38,"./crypto/protocols/jose/jws/JwsToken":40,"./crypto/utilities/CryptoHelpers":44,"./keystores/KeyStoreConstants":68,"buffer":517}],3:[function(require,module,exports){ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); const UserAgentError_1 = require("./UserAgentError"); const HostServiceEndpoint_1 = require("./serviceEndpoints/HostServiceEndpoint"); const UserServiceEndpoint_1 = require("./serviceEndpoints/UserServiceEndpoint"); const cloneDeep = require('lodash/fp/cloneDeep'); /** * Class for creating and managing identifiers, * retrieving identifier documents. */ class IdentifierDocument { /** * Constructs an instance of the identifier * document. * @param document from which to create the identifier document. * @param options for configuring how to register and resolve identifiers. */ constructor(document) { /** * Array of service entries added to the document. */ this.publicKeys = []; /** * Array of authentication entries added to the document. */ this.authenticationReferences = []; /** * Array of service entries added to the document. */ this.serviceReferences = []; // Populate the base properties this.id = document.id; this.publicKeys = document.publicKeys; if (document.created) { this.created = new Date(document.created); } this.authenticationReferences = document.authentication || []; this.serviceReferences = document.service || []; if (document.service && document.service.length > 0) { document.service.forEach((serviceRef) => { if (serviceRef.serviceEndpoint['@type'] === 'HostServiceEndpoint') { serviceRef.serviceEndpoint = HostServiceEndpoint_1.default.fromJSON(serviceRef.serviceEndpoint); } else { serviceRef.serviceEndpoint = UserServiceEndpoint_1.default.fromJSON(serviceRef.serviceEndpoint); } }); } } /** * Creates a new instance of an identifier document using the * provided public keys. * @param publicKeys to include in the document. */ static create(id, publicKeys) { const createdDate = new Date(Date.now()).toISOString(); return new IdentifierDocument({ id: id, created: createdDate, publicKeys: publicKeys }); } /** * Creates a new instance of an identifier document using the * provided public keys. * The id is generated. * @param idBase The base id in format did:{method}:{id}. {id} will be filled in by this method * @param publicKeys to include in the document. * @param options User agent options containing the crypto Api */ static async createAndGenerateId(idBase, publicKeys, options) { const document = IdentifierDocument.create(idBase, publicKeys); const identifier = await options.registrar.generateIdentifier(document); document.id = identifier.id; return document; } /** * Adds an authentication reference to the document. * @param authenticationReference to add to the document. */ addAuthenticationReference(authenticationReference) { this.authenticationReferences.push(authenticationReference); } /** * Adds a service reference to the document. * @param serviceReference to add to the document. */ addServiceReference(serviceReference) { this.serviceReferences.push(serviceReference); } /** * Get Hub Instances from Identity Service Reference. */ getHubInstances() { const filteredServiceReferences = this.serviceReferences.filter(reference => reference.type === 'IdentityHub'); if (filteredServiceReferences.length === 0 || filteredServiceReferences[0].serviceEndpoint.type !== 'UserServiceEndpoint') { throw new UserAgentError_1.default(`No Hub Instances for ${this.id}`); } const serviceEndpoint = filteredServiceReferences[0].serviceEndpoint; return serviceEndpoint.instances; } /** * Get Hub Locations from Identity Service Reference. */ getHubLocations() { const filteredServiceReferences = this.serviceReferences.filter(reference => reference.type === 'IdentityHub'); if (filteredServiceReferences.length === 0 || filteredServiceReferences[0].serviceEndpoint.type !== 'HostServiceEndpoint') { throw new UserAgentError_1.default(`No Hub Locations for ${this.id}`); } const serviceEndpoint = filteredServiceReferences[0].serviceEndpoint; return serviceEndpoint.locations; } getPublicKeysFromDocument() { return this.publicKeys.map(key => key.publicKeyJwk); } /** * Used to control the the properties that are * output by JSON.parse. */ static fromJSON(obj) { const document = Object.create(IdentifierDocument.prototype); const result = Object.assign(document, obj, { publicKeys: obj.publicKey }); delete result.publicKey; return new IdentifierDocument(document); } /** * Used to control the the properties that are * output by JSON.stringify. */ toJSON() { // Clone the current instance. Note the use of // a deep clone to ensure immutability of // the instance being cloned for serialization const clonedDocument = cloneDeep(this); // Add the JSON-LD context clonedDocument['@context'] = 'https://w3id.org/did/v1'; // switch authentication references to authentication. if (this.authenticationReferences && this.authenticationReferences.length > 0) { clonedDocument.authentication = this.authenticationReferences; } clonedDocument.authenticationReferences = undefined; // switch service references to service. if (this.serviceReferences && this.serviceReferences.length > 0) { clonedDocument.service = this.serviceReferences; clonedDocument.service.forEach((serviceRef) => { if (serviceRef.serviceEndpoint['type'] === 'HostServiceEndpoint') { serviceRef.serviceEndpoint = serviceRef.serviceEndpoint.toJSON(); } else { serviceRef.serviceEndpoint = serviceRef.serviceEndpoint.toJSON(); } }); } clonedDocument.serviceReferences = undefined; if (!this.publicKeys || this.publicKeys.length === 0) { clonedDocument.publicKeys = undefined; } else { clonedDocument.publicKey = this.publicKeys; delete clonedDocument.publicKeys; } // Now return the cloned document for serialization return clonedDocument; } } exports.default = IdentifierDocument; },{"./UserAgentError":5,"./serviceEndpoints/HostServiceEndpoint":73,"./serviceEndpoints/UserServiceEndpoint":75,"lodash/fp/cloneDeep":319}],4:[function(require,module,exports){ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); /** * General constants used by user agent */ class UserAgentConstants { } /** * Define default key tag for signature key */ UserAgentConstants.keyTagSigning = 'sigKey'; /** * Define default key tag for encyption key */ UserAgentConstants.keyTagEncryption = 'encKey'; exports.default = UserAgentConstants; },{}],5:[function(require,module,exports){ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); /** * Base error class for the UserAgent. */ class UserAgentError extends Error { constructor(message) { super(message); // NOTE: Extending 'Error' breaks prototype chain since TypeScript 2.1. // The following line restores prototype chain. Object.setPrototypeOf(this, new.target.prototype); } } exports.default = UserAgentError; },{}],6:[function(require,module,exports){ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); const CryptoOptions_1 = require("./CryptoOptions"); /** * Interface defining options for the * User Agent, such as resolver and register. */ class UserAgentOptions { constructor() { /** * The timeout when making requests to * external services. */ this.timeoutInSeconds = 30; /** * The locale to be used by the * user agent. */ this.locale = 'en'; /** * The lifetime of any self-issued credentials. * Used to determine the expiry time of the * credential. */ this.selfIssuedCredentialLifetimeInSeconds = 300; // 5 mins /** * Crypto Options * contains algorithm and other data about crypto */ this.cryptoOptions = new CryptoOptions_1.default(); /** * Prefix for the generated did. */ this.didPrefix = 'did:ion'; } /** * Get the key store */ get keyStore() { return this.cryptoOptions.cryptoFactory.keyStore; } /** * Set the key store */ set keyStore(keyStore) { this.cryptoOptions.cryptoFactory.keyStore = keyStore; } /** * Get the crypto operations */ get cryptoFactory() { return this.cryptoOptions.cryptoFactory; } /** * Set the key store */ set cryptoFactory(cryptoFactory) { this.cryptoOptions.cryptoFactory = cryptoFactory; } } exports.default = UserAgentOptions; },{"./CryptoOptions":1}],7:[function(require,module,exports){ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); const UserAgentError_1 = require("../UserAgentError"); const CredentialManifest_1 = require("./CredentialManifest"); require("isomorphic-fetch"); /** * Class for obtaining * credentials from an issuer. */ class CredentialIssuer { /** * Constructs an instance of the credential issuer * based on the specified credential manifest. * @param identifier for the issuer. * @param manifest credential manifest for specific credential. */ constructor(identifier, manifest) { this.identifier = identifier; this.manifest = new CredentialManifest_1.default(manifest); } /** * Constructs an instance of the credential issuer * based on the specified credential manifest. * @param identifier for the issuer. * @param manifest credential manifest object or endpoint string of manifest. */ static async create(identifier, manifest) { let manifestJson; if (typeof (manifest) === 'string') { const response = await fetch(manifest); if (!response.ok) { let error; switch (response.status) { case 404: error = new UserAgentError_1.default(`Failed to request a credential manifest from the issuer \'${identifier.id}.\'`); break; default: error = new UserAgentError_1.default(`'${manifest}' returned an error with \'${response.statusText}\'`); } throw error; } manifestJson = await response.json(); } else { manifestJson = manifest; } return new CredentialIssuer(identifier, manifestJson); } /** * Gets the array of languages supported * by the manifest. */ // public get language (): Array<string> { // console.log(this.identifier); // return this.manifest.language || []; // } /** * Requests a new credential from the issuer, * providing a self-issued credential with the inputs * specified in the credential manifest. * @param inputCredential containing the inputs as specified * in the credential manifest. */ async requestCredential(inputCredential) { const serializedCredential = JSON.stringify(inputCredential); return new Promise(async (resolve, reject) => { const timer = setTimeout(() => reject(new UserAgentError_1.default(`Requesting a credential from '${this.manifest.endpoint}' timed out`)), 30000 // 30s ); const fetchOptions = { method: 'POST', body: serializedCredential, headers: { 'Content-Type': 'application/json', 'Content-Length': serializedCredential.length } }; // Now call the actual fetch with the updated options const response = await fetch(this.manifest.endpoint, fetchOptions); // Got a response so clear the timer clearTimeout(timer); if (!response.ok) { const error = new UserAgentError_1.default(`Failed to request a credential from the issuer '${this.identifier.id}.'`); reject(error); return; } const credential = await response.json(); resolve(credential); }); } /** * Validate inputCredential with manifest and process and exchange inputCredential wuth Data Handler * @param inputCredential The Self-Issued Credential that with required claims. * @param _dataHandler Data handler for process and exchanging credentials. */ async handleCredentialRequest(inputCredential, dataHandler) { // Validate that credential matched credential manifest. if (!this.validateCredential(inputCredential)) { throw new UserAgentError_1.default(`Credential issued by '${inputCredential.issuedBy.id}' does not match credential manifest '${this.manifest.credential}'`); } return dataHandler.process(inputCredential); } /** * Validate whether a credential is valid for the manifest. * @param _inputCredential the Credential to validate against the credential manifest */ validateCredential(_inputCredential) { return true; } } exports.default = CredentialIssuer; },{"../UserAgentError":5,"./CredentialManifest":8,"isomorphic-fetch":133}],8:[function(require,module,exports){ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); /** * context for credentialManifest */ const context = 'https://identity.foundation/schemas/credentials'; /** * type for credentialManifest */ const type = 'CredentialManifest'; /** * Class defining methods and properties for a ClaimManifest object. * based off of the CredentialManifest spec: {@link https://github.com/decentralized-identity/credential-manifest/blob/master/explainer.md} */ class CredentialManifest { /** * Constructs an instance of the CredentialManifest class from a well-formed credential manifest JSON object. */ constructor(credentialManifest) { this.endpoint = credentialManifest.endpoint; this.credential = credentialManifest.credential; this.language = credentialManifest.language; this.keeper = credentialManifest.keeper; this.version = credentialManifest.version; this.preconditions = credentialManifest.preconditions; this.inputs = credentialManifest.inputs; this.issuerOptions = credentialManifest.issuer_options; } /** * Creates a new instance of the CredentialManifest class. */ static create(credential, endpoint, language, keeper, version, preconditions, inputs, issuerOptions) { const manifest = { '@context': context, '@type': type, 'endpoint': endpoint, 'language': language, 'credential': credential, 'keeper': keeper, 'version': version, 'preconditions': preconditions, 'inputs': inputs, 'issuer_options': issuerOptions }; return new CredentialManifest(manifest); } /** * serializes the CredentialManifest to JSON. */ toJSON() { return { '@context': context, '@type': type, 'endpoint': this.endpoint, 'credential': this.credential, 'preconditions': this.preconditions, 'inputs': this.inputs, 'issuer_options': this.issuerOptions }; } /** * Get the keeper did of the CredentialManifest */ getKeeperDid() { return this.keeper; } /** * Get the input properties of the manifest */ getInputProperties() { return this.inputs; } } exports.default = CredentialManifest; },{}],9:[function(require,module,exports){ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); /** * Implementation of an OpenID Connect * self-issued id token. * @implements ICredential */ class SelfIssuedCredential { /** * Constructs a new instance of a self-issued * credential for the specified identifier. * @param issuer of the credential. * @param recipient either a string or identifier identifying the * intended recipient of the credential. */ constructor(issuer, recipient) { /** * Array to hold claims to be included in the credential */ this.claims = []; this.issuedBy = issuer; this.issuedTo = recipient; this.issuedAt = new Date(Date.now()); // Add the identifier as the did claim this.addClaim({ name: 'did', value: issuer.id }); } /** * Adds the specified claim to the credential. * @param claim claim to add to credential. */ addClaim(claim) { // Add the claim to the credential this.claims.push(claim); } } exports.default = SelfIssuedCredential; },{}],10:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ /** * Base error class for the crypto. */ class CryptoError extends Error { /** * Create instance of @class CryptoProtocolError * @param protocol name * @param message for the error */ constructor(algorithm, message) { super(message); // NOTE: Extending 'Error' breaks prototype chain since TypeScript 2.1. // The following line restores prototype chain. Object.setPrototypeOf(this, new.target.prototype); this.algorithm = algorithm; } } exports.default = CryptoError; },{}],11:[function(require,module,exports){ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); const SecretKey_1 = require("../keys/SecretKey"); /** * Class defining methods and properties for a light KeyStore */ class KeyStoreInMemory { constructor() { this.store = new Map(); } /** * Returns the key associated with the specified * key identifier. * @param keyReference for which to return the key. * @param [publicKeyOnly] True if only the public key is needed. */ get(keyReference, publicKeyOnly = true) { return new Promise((resolve, reject) => { if (this.store.has(keyReference)) { const key = this.store.get(keyReference); if (key instanceof SecretKey_1.default) { return resolve(key); } if (publicKeyOnly) { switch (key.kty.toLowerCase()) { case 'ec': case 'rsa': return resolve(key.getPublicKey()); default: throw new Error(`A secret does not has a public key`); } } else { resolve(key); } } else { reject(`${keyReference} not found`); } }); } /** * Lists all keys with their corresponding key ids */ list() { const dictionary = new Map(); for (let [key, value] of this.store) { if (value.kid) { dictionary.set(key, value.kid); } } return new Promise((resolve) => { resolve(dictionary); }); } /** * Saves the specified key to the key store using * the key identifier. * @param keyIdentifier for the key being saved. * @param key being saved to the key store. */ save(keyIdentifier, key) { console.log(this.store.toString() + keyIdentifier + key.toString()); this.store.set(keyIdentifier, key); return new Promise((resolve) => { resolve(); }); } } exports.default = KeyStoreInMemory; },{"../keys/SecretKey":19}],12:[function(require,module,exports){ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); /** * Enum to define different protection formats */ var ProtectionFormat; (function (ProtectionFormat) { /** * Format for a flat JSON signature */ ProtectionFormat["JwsFlatJson"] = "JwsFlatJson"; /** * Format for a compact JSON signature */ ProtectionFormat["JwsCompactJson"] = "JwsCompactJson"; /** * Format for a general JSON signature */ ProtectionFormat["JwsGeneralJson"] = "JwsGeneralJson"; /** * Format for a flat JSON encryption */ ProtectionFormat["JweFlatJson"] = "JweFlatJson"; /** * Format for a compact JSON encryption */ ProtectionFormat["JweCompactJson"] = "JweCompactJson"; /** * Format for a general JSON encryption */ ProtectionFormat["JweGeneralJson"] = "JweGeneralJson"; })(ProtectionFormat = exports.ProtectionFormat || (exports.ProtectionFormat = {})); },{}],13:[function(require,module,exports){ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); const jose = require('node-jose'); /** * JWK key operations */ var KeyOperation; (function (KeyOperation) { KeyOperation["Sign"] = "sign"; KeyOperation["Verify"] = "verify"; KeyOperation["Encrypt"] = "encrypt"; KeyOperation["Decrypt"] = "decrypt"; KeyOperation["WrapKey"] = "wrapKey"; KeyOperation["UnwrapKey"] = "unwrapKey"; KeyOperation["DeriveKey"] = "deriveKey"; KeyOperation["DeriveBits"] = "deriveBits"; })(KeyOperation = exports.KeyOperation || (exports.KeyOperation = {})); /** * Represents a Public Key in JWK format. * @class * @abstract * @hideconstructor */ class JsonWebKey { /** * Create instance of @class JsonWebKey */ constructor(key) { /** * Key ID */ this.kid = ''; this.kty = key.kty; this.kid = key.kid; this.use = key.use; this.key_ops = key.key_ops; this.alg = key.alg; } } exports.default = JsonWebKey; },{"node-jose":420}],14:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const CryptoHelpers_1 = require("../utilities/CryptoHelpers"); /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ /** * Enumeration to model key types. */ var KeyType; (function (KeyType) { KeyType["Oct"] = "oct"; KeyType["EC"] = "EC"; KeyType["RSA"] = "RSA"; })(KeyType = exports.KeyType || (exports.KeyType = {})); /** * Factory class to create @enum KeyType objects */ class KeyTypeFactory { /** * Create the key type according to the selected algorithm. * @param algorithm Web crypto compliant algorithm object */ static createViaWebCrypto(algorithm) { switch (algorithm.name.toLowerCase()) { case 'hmac': return KeyType.Oct; case 'ecdsa': return KeyType.EC; case 'ecdh': return KeyType.EC; case 'rsassa-pkcs1-v1_5': return KeyType.RSA; case 'rsa-oaep': case 'rsa-oaep-256': return KeyType.RSA; default: throw new Error(`The algorithm '${algorithm.name}' is not supported`); } } /** * Create the key use according to the selected algorithm. * @param algorithm JWA algorithm constant */ static createViaJwa(algorithm) { const alg = CryptoHelpers_1.default.jwaToWebCrypto(algorithm); return KeyTypeFactory.createViaWebCrypto(alg); } } exports.default = KeyTypeFactory; },{"../utilities/CryptoHelpers":44}],15:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const CryptoHelpers_1 = require("../utilities/CryptoHelpers"); /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ /** * Enumeration to model key use. */ var KeyUse; (function (KeyUse) { KeyUse["Encryption"] = "enc"; KeyUse["Signature"] = "sig"; })(KeyUse = exports.KeyUse || (exports.KeyUse = {})); /** * Factory class to create @enum KeyUse objects. */ class KeyUseFactory { /** * Create the key use according to the selected algorithm. * @param algorithm Web crypto compliant algorithm object */ static createViaWebCrypto(algorithm) { switch (algorithm.name.toLowerCase()) { case 'hmac': return KeyUse.Signature; case 'ecdsa': return KeyUse.Signature; case 'ecdh': return KeyUse.Encryption; case 'rsassa-pkcs1-v1_5': return KeyUse.Signature; case 'rsa-oaep': case 'rsa-oaep-256': return KeyUse.Encryption; default: throw new Error(`The algorithm '${algorithm.name}' is not supported`); } } /** * Create the key use according to the selected algorithm. * @param algorithm JWA algorithm constant */ static createViaJwa(algorithm) { const alg = CryptoHelpers_1.default.jwaToWebCrypto(algorithm); return KeyUseFactory.createViaWebCrypto(alg); } } exports.default = KeyUseFactory; },{"../utilities/CryptoHelpers":44}],16:[function(require,module,exports){ (function (Buffer){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const KeyTypeFactory_1 = require("./KeyTypeFactory"); const W3cCryptoApiConstants_1 = require("../utilities/W3cCryptoApiConstants"); const EcPairwiseKey_1 = require("./ec/EcPairwiseKey"); const CryptoError_1 = require("../CryptoError"); const RsaPairwiseKey_1 = require("./rsa/RsaPairwiseKey"); const JoseConstants_1 = require("../protocols/jose/JoseConstants"); /** * Class to model pairwise keys */ class PairwiseKey { /** * Create an instance of @class PairwiseKey. * @param cryptoFactory The crypto factory object. */ constructor(cryptoFactory) { // Set of master keys for the different persona's this.masterKeys = new Map(); this.cryptoFactory = cryptoFactory; } /** * Generate a pairwise key for the specified algorithms * @param algorithm for the key * @param seedReference Reference to the seed * @param personaId Id for th