UNPKG

@microsoft/useragent-sdk

Version:

SDK for building decentralized identity wallets and enterprise agents.

305 lines (304 loc) 15.1 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); const IdentifierDocument_1 = require("../src/IdentifierDocument"); const Identifier_1 = require("../src/Identifier"); const UserAgentOptions_1 = require("../src/UserAgentOptions"); const TestResolver_1 = require("./resolvers/TestResolver"); const UserAgentError_1 = require("../src/UserAgentError"); const CryptoOptions_1 = require("../src/CryptoOptions"); const TestRegistrar_1 = require("./registrars/TestRegistrar"); const KeyTypeFactory_1 = require("../src/crypto/keys/KeyTypeFactory"); const KeyUseFactory_1 = require("../src/crypto/keys/KeyUseFactory"); const KeyStoreInMemory_1 = require("../src/crypto/keyStore/KeyStoreInMemory"); const JwsToken_1 = require("../src/crypto/protocols/jose/jws/JwsToken"); const OctKey_1 = require("../src/crypto/keys/Oct/OctKey"); const CryptoFactory_1 = require("../src/crypto/plugin/CryptoFactory"); const SubtleCryptoNode_1 = require("../src/crypto/plugin/SubtleCryptoNode"); const KeyContainer_1 = require("../src/crypto/keys/KeyContainer"); describe('Identifier', () => { let testResolver; let options; beforeAll(() => { testResolver = new TestResolver_1.default(); // Configure the agent options for the tests options = new UserAgentOptions_1.default(); options.resolver = testResolver; options.timeoutInSeconds = 30; }); it('should construct a storage identfier for the key', () => { let identifier = Identifier_1.default.keyStorageIdentifier('did:ion:identifier', 'peer', KeyUseFactory_1.KeyUse.Encryption, KeyTypeFactory_1.KeyType.EC); expect(identifier).toEqual('did:ion:identifier-peer-enc-EC'); identifier = Identifier_1.default.keyStorageIdentifier('did:ion:identifier', 'peer', KeyUseFactory_1.KeyUse.Encryption, KeyTypeFactory_1.KeyType.RSA); expect(identifier).toEqual('did:ion:identifier-peer-enc-RSA'); identifier = Identifier_1.default.keyStorageIdentifier('did:ion:identifier', 'peer', KeyUseFactory_1.KeyUse.Signature, KeyTypeFactory_1.KeyType.EC); expect(identifier).toEqual('did:ion:identifier-peer-sig-EC'); identifier = Identifier_1.default.keyStorageIdentifier('did:ion:identifier', 'peer', KeyUseFactory_1.KeyUse.Signature, KeyTypeFactory_1.KeyType.RSA); expect(identifier).toEqual('did:ion:identifier-peer-sig-RSA'); }); it('should construct new instance when provided an identifier string', () => { const identifier = new Identifier_1.default('did:ion:identifier', options); expect(identifier).toBeDefined(); expect(identifier.id).toEqual('did:ion:identifier'); }); it('should construct new instance when provided an identifier document', () => { const identifierDocument = new IdentifierDocument_1.default({ id: 'did:ion:identifier', created: '2019-01-25T01:08:44.732Z' }); const identifier = new Identifier_1.default(identifierDocument, options); expect(identifier).toBeDefined(); expect(identifier.id).toEqual('did:ion:identifier'); }); it('should return document from local', () => { const identifierDocument = new IdentifierDocument_1.default({ id: 'did:ion:identifier', created: '2019-01-25T01:08:44.732Z' }); const identifier = new Identifier_1.default(identifierDocument, options); const resolver = spyOn(testResolver, 'resolve').and.callThrough(); const localDocument = identifier.getDocument(); expect(localDocument).toBeDefined(); expect(resolver).not.toHaveBeenCalled(); }); it('should throw when no resolver specified and document not cached', async (done) => { const options = { timeoutInSeconds: 30 }; const identifier = new Identifier_1.default('did:ion:identifier', options); await identifier .getDocument() .catch(error => { expect(error instanceof UserAgentError_1.default).toBeTruthy(); expect(error.message).toEqual('Resolver not specified in user agent options.'); }) .finally(done); }); it('should resolve identifier and return document', () => { const identifier = new Identifier_1.default('did:ion:identifier', options); const identifierDocument = new IdentifierDocument_1.default({ id: 'did:ion:identifier', created: '2019-01-25T01:08:44.732Z' }); options.resolver.prepareTest(identifier, identifierDocument); const resolver = spyOn(testResolver, 'resolve').and.callThrough(); const result = identifier.getDocument(); expect(result).toBeDefined(); expect(resolver).toHaveBeenCalled(); }); it('should call getDocument() when local document undefined', async () => { const identifier = new Identifier_1.default('did:ion:identifier', options); const identifierDocument = new IdentifierDocument_1.default({ id: 'did:ion:identifier', created: '2019-01-25T01:08:44.732Z', publicKeys: [ { id: '#master', type: 'RsaVerificationKey2018', publicKeyJwk: { kty: 'RSA', kid: '#master', keyOps: [ 'sign', 'verify' ], n: 'vdpHn7kNq42UMC1W8bwxgE7K...', e: 'AQAB' } } ] }); options.resolver.prepareTest(identifier, identifierDocument); const resolver = spyOn(testResolver, 'resolve').and.callThrough(); const result = await identifier.getPublicKey('#master'); expect(result).toBeDefined(); expect(resolver).toHaveBeenCalled(); }); it('should throw when document has no keys', async (done) => { const identifier = new Identifier_1.default('did:ion:identifier', options); const identifierDocument = new IdentifierDocument_1.default({ id: 'did:ion:identifier', created: '2019-01-25T01:08:44.732Z' }); options.resolver.prepareTest(identifier, identifierDocument); await identifier .getPublicKey('#master') .catch(error => { expect(error instanceof UserAgentError_1.default).toBeTruthy(); expect(error.message).toEqual('Document does not contain any public keys'); }) .finally(done); }); it('should throw when document does not contain specified key', async (done) => { const identifier = new Identifier_1.default('did:ion:identifier', options); const identifierDocument = new IdentifierDocument_1.default({ id: 'did:ion:identifier', created: '2019-01-25T01:08:44.732Z', publicKeys: [ { id: '#master', type: 'RsaVerificationKey2018', publicKeyJwk: { kty: 'RSA', kid: '#master', keyOps: [ 'sign', 'verify' ], n: 'vdpHn7kNq42UMC1W8bwxgE7K...', e: 'AQAB' } } ] }); options.resolver.prepareTest(identifier, identifierDocument); await identifier .getPublicKey('#notInDocument') .catch(error => { expect(error instanceof UserAgentError_1.default).toBeTruthy(); expect(error.message).toEqual(`No matching public key found for #notInDocument`); }) .finally(done); }); it('should return public key for specified key identifier', async () => { const identifier = new Identifier_1.default('did:ion:identifier', options); const identifierDocument = new IdentifierDocument_1.default({ id: 'did:ion:identifier', created: '2019-01-25T01:08:44.732Z', publicKeys: [ { id: '#master', type: 'RsaVerificationKey2018', publicKeyJwk: { kty: 'RSA', kid: '#master', keyOps: [ 'sign', 'verify' ], n: 'vdpHn7kNq42UMC1W8bwxgE7K...', e: 'AQAB' } } ] }); options.resolver.prepareTest(identifier, identifierDocument); const publicKey = await identifier.getPublicKey('#master'); expect(publicKey).toBeDefined(); expect(publicKey.id).toEqual('#master'); }); it('should return first public key when no key identifier specified', async () => { const identifier = new Identifier_1.default('did:ion:identifier', options); const identifierDocument = new IdentifierDocument_1.default({ id: 'did:ion:identifier', created: '2019-01-25T01:08:44.732Z', publicKeys: [ { id: '#first', type: 'RsaVerificationKey2018', publicKeyJwk: { kty: 'RSA', kid: '#master', keyOps: [ 'sign', 'verify' ], n: 'vdpHn7kNq42UMC1W8bwxgE7K...', e: 'AQAB' } }, { id: '#second', type: 'RsaVerificationKey2018', publicKeyJwk: { kty: 'RSA', kid: '#master', keyOps: [ 'sign', 'verify' ], n: 'vdpHn7kNq42UMC1W8bwxgE7K...', e: 'AQAB' } } ] }); options.resolver.prepareTest(identifier, identifierDocument); const publicKey = await identifier.getPublicKey(); expect(publicKey).toBeDefined(); expect(publicKey.id).toEqual('#first'); }); describe('sign', () => { let options; beforeEach(() => { options = new UserAgentOptions_1.default(); options.resolver = testResolver; options.timeoutInSeconds = 30; options.didPrefix = 'did:ion'; options.registrar = new TestRegistrar_1.default(); }); it('should sign a payload that is a string', async () => { options.cryptoOptions = new CryptoOptions_1.default(new CryptoFactory_1.default(new KeyStoreInMemory_1.default(), SubtleCryptoNode_1.default.getSubtleCrypto())); options.cryptoOptions.signingAlgorithm = 'ES256K'; const seed = new OctKey_1.default('ABDE'); await options.keyStore.save('masterSeed', new KeyContainer_1.default(seed)); const identifier = await Identifier_1.default.create(options); const keystore = await options.keyStore.list(); console.log(keystore); const signedPayload = await identifier.sign('examplePayload', 'did:ion-did:ion-ES256K-sig'); expect(signedPayload).toBeDefined(); expect(JwsToken_1.default.deserialize(signedPayload).getPayload()).toEqual('examplePayload'); }); it('should sign a payload that is an object', async () => { options.cryptoOptions = new CryptoOptions_1.default(new CryptoFactory_1.default(new KeyStoreInMemory_1.default(), SubtleCryptoNode_1.default.getSubtleCrypto())); options.cryptoOptions.signingAlgorithm = 'ES256K'; options.keyStore = new KeyStoreInMemory_1.default(); const seed = new OctKey_1.default('ABDE'); await options.keyStore.save('masterSeed', new KeyContainer_1.default(seed)); const identifier = await Identifier_1.default.create(options); const signedPayload = await identifier.sign({ payload: 'examplePayload' }, 'did:ion-did:ion-ES256K-sig'); expect(signedPayload).toBeDefined(); expect(JwsToken_1.default.deserialize(signedPayload).getPayload()).toEqual(`{"payload":"examplePayload"}`); }); }); describe('verify', () => { let identifier; let identifierDocument; beforeAll(() => { identifier = new Identifier_1.default('did:ion:identifier', options); identifierDocument = new IdentifierDocument_1.default({ id: 'did:ion:identifier', created: '2019-01-25T01:08:44.732Z', publicKeys: [ { id: '#master', type: 'RsaVerificationKey2018', publicKeyJwk: { kty: 'RSA', kid: '#master', keyOps: [ 'sign', 'verify' ], n: 'vdpHn7kNq42UMC1W8bwxgE7K...', e: 'AQAB' } } ] }); console.log(identifier); console.log(identifierDocument); }); /* const testJws = 'testJWS'; fit('should resolve identifier document and verify jws', async () => { (<TestResolver> options.resolver).prepareTest(identifier, identifierDocument); const verifiedPayload = await identifier.verify(testJws); expect(verifiedPayload).toBeDefined(); expect(verifiedPayload).toBe('verifiedPayload'); }); fit('should verify jws', async () => { console.log(identifier); const testIdentifier = new Identifier(identifierDocument, options); const verifiedPayload = await testIdentifier.verify(testJws); expect(verifiedPayload).toBeDefined(); expect(verifiedPayload).toBe('verifiedPayload'); }); */ }); }); //# sourceMappingURL=Identifier.spec.js.map