@microsoft/useragent-sdk
Version:
SDK for building decentralized identity wallets and enterprise agents.
171 lines (140 loc) • 7.01 kB
text/typescript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import Identifier from '../Identifier';
import Commit from '../hubSession/Commit';
import UserAgentError from '../UserAgentError';
import CommitProtector, { CommitProtectorOptions } from '../hubSession/crypto/CommitProtector';
import HubCommitWriteRequest from '../hubSession/requests/HubCommitWriteRequest';
import HubObjectQueryRequest from '../hubSession/requests/HubObjectQueryRequest';
import HubSession, { HubSessionOptions } from '../hubSession/HubSession';
import IHubClient, {HubClientOptions } from './IHubClient';
import HubObject from './HubObject';
import HubCommitQueryRequest from '../hubSession/requests/HubCommitQueryRequest';
import CryptoFactory from '../crypto/plugin/CryptoFactory';
import { IPayloadProtection } from '../crypto/protocols/IPayloadProtection';
import ProtectionStrategy from '../crypto/strategies/ProtectionStrategy';
import { PublicKey, UserAgentOptions } from '..';
import JoseConstants from '../crypto/protocols/jose/JoseConstants';
import IPayloadProtectionOptions from '../crypto/protocols/IPayloadProtectionOptions';
import JoseProtocol from '../crypto/protocols/jose/JoseProtocol';
import { TSMap } from 'typescript-map';
/**
* Class for doing CRUD operations to Actions, Collections, Permissions, and Profile
* In a Hub.
*/
export default class HubClient implements IHubClient {
public hubOwner: Identifier;
public clientIdentifier: Identifier;
private readonly signingKeyReference: string | undefined;
private readonly encryptionKeyReference: string | undefined;
private readonly recipientsPublicKeys: PublicKey[] | undefined;
private readonly cryptoFactory: CryptoFactory;
private readonly payloadProtection: IPayloadProtection;
private readonly hubProtectionStrategy: ProtectionStrategy | undefined;
/**
* Constructs an instance of the Hub Client Class for hub operations
* @param hubClientOptions hub client options used to create instance.
*/
constructor (hubClientOptions: HubClientOptions) {
if (!hubClientOptions.hubOwner || !hubClientOptions.clientIdentifier) {
throw new UserAgentError(`HubClientOptions does not contain all properties`);
}
this.hubOwner = hubClientOptions.hubOwner;
this.clientIdentifier = hubClientOptions.clientIdentifier;
this.signingKeyReference = (<UserAgentOptions>hubClientOptions.clientIdentifier.options).cryptoOptions.signingKeyReference;
this.encryptionKeyReference = (<UserAgentOptions>hubClientOptions.clientIdentifier.options).cryptoOptions.encryptionKeyReference;
this.recipientsPublicKeys = hubClientOptions.recipientsPublicKeys;
this.cryptoFactory = hubClientOptions.cryptoOptions.cryptoFactory;
this.payloadProtection = hubClientOptions.cryptoOptions.payloadProtection;
this.hubProtectionStrategy = hubClientOptions.hubProtectionStrategy;
}
/**
* Protect and sends a commit to the hub owner's hub.
* @param commit commit to be sent to hub owner's hub.
*/
public async commit (commit: Commit) {
if (commit.getCommitFields().iss !== this.clientIdentifier.id) {
throw new UserAgentError(`Issuer, '${commit.getCommitFields().iss},' is not valid for this HubClient Instance.`);
}
if (commit.getCommitFields().sub !== this.hubOwner.id) {
throw new UserAgentError(`Subject, '${commit.getCommitFields().sub},' is not valid for this HubClient Instance.`);
}
if (!this.clientIdentifier.options || !this.clientIdentifier.options.keyStore) {
throw new UserAgentError(`No KeyStore defined for '${this.clientIdentifier}`);
}
const fields = commit.getCommitFields();
fields.kid = '';
const map = Object.keys(fields).map((field) => {
return [field, fields[field]];
});
const options: IPayloadProtectionOptions = {
cryptoFactory: this.cryptoFactory,
options: new TSMap<string, any>([
[JoseConstants.optionProtectedHeader, new TSMap(map) ]
]),
payloadProtection: new JoseProtocol()
};
const commitProtectOptions: CommitProtectorOptions = {
did: this.clientIdentifier.id,
signingKeyReference: this.signingKeyReference,
recipientsPublicKeys: this.recipientsPublicKeys,
payloadProtection: this.payloadProtection,
payloadProtectionOptions: options,
hubProtectionStrategy: this.hubProtectionStrategy
};
// protect the commit
const commitProtector = new CommitProtector(commitProtectOptions);
const protectedCommit = await commitProtector.protect(commit);
const commitRequest = new HubCommitWriteRequest(protectedCommit);
const session = await this.createHubSession();
return session.send(commitRequest);
}
/**
* Query Objects of certain type in Hub.
* @param queryRequest object that tells the hub what object to get.
*/
public async queryObjects (queryRequest: HubObjectQueryRequest): Promise<HubObject[]> {
const session = await this.createHubSession();
const queryResponse = await session.send(queryRequest);
const objects = queryResponse.getObjects();
let hubObjects: HubObject[] = [];
objects.forEach(object => {
hubObjects.push(new HubObject(object));
});
return hubObjects;
}
/**
* Query Object specified by certain id
* @param commitQueryRequest HubCommitQueryRequest object to request object of specific id.
* @param hubObject a HubObject containing metadata such as object id.
*/
public async queryObject (commitQueryRequest: HubCommitQueryRequest, hubObject: HubObject): Promise<HubObject> {
const session = await this.createHubSession();
await hubObject.hydrate(session, commitQueryRequest);
return hubObject;
}
/**
* Get all Hub Instances from hub owner's identifier document.
*/
public async getHubInstances () {
const identifierDocument = await this.hubOwner.getDocument();
return identifierDocument.getHubInstances();
}
/**
* Implement createHubSession method once HubSession is refactored.
* creates a hubSession for hub instance that is available/online.
*/
private async createHubSession () {
const options: HubSessionOptions = {
client: this.clientIdentifier,
hubOwner: this.hubOwner,
hubId: 'did:ion:test:EiANVcAJKiAdVQRId8IYrQHxJE4nU4-_pW041qh-z5tVZQ',
hubEndpoint: 'http://localhost:8080/',
signingKeyReference: this.signingKeyReference,
encryptionKeyReference: this.encryptionKeyReference
};
return new HubSession(options);
}
}