UNPKG

@microsoft/useragent-sdk

Version:

SDK for building decentralized identity wallets and enterprise agents.

205 lines (176 loc) 6.33 kB
/*--------------------------------------------------------------------------------------------- * 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 UserAgentError from "../UserAgentError"; import JwsToken from "../crypto/protocols/jose/jws/JwsToken"; /** * Type to describe a claim description. */ export type ClaimDescription = { header: string, body: string }; /** * Type to describe a claim key-value pair. */ export type Claim = {[key: string]: string}; /** * Class that represents a ClaimObject * @class */ export default class ClaimObject { /** * Pointer to the claimClass that is tied to this claimObject. */ public claimClass: string; /** * Context of the specific claim object */ public context: string; /** * Type of the Claim Object. */ public type: string; /** * Identifier of the entity that issued ClaimObject */ public issuer: string; /** * A list of claim descriptions that will define each claim. */ public claimDescriptions: ClaimDescription[]; /** * A list of claims that are contained in this claimObject. */ public claimDetails: Claim[]; /** * The Claim Details if they have been signed. */ public signedClaimDetails?: string; /** * Instantiates a new ClaimObject. * @param claimClass Pointer to the claimClass that is tied to this claimObject. * @param claimDescriptions A list of claim descriptions that will define each claim. * @param claimDetails A list of claims that are contained in this claimObject. */ constructor(claimClass: string, context: string, type: string, issuer: string, claimDescriptions: ClaimDescription[], claimDetails: Claim[], signedClaimDetails?: string) { this.claimClass = claimClass; this.issuer = issuer; this.claimDescriptions = claimDescriptions; this.claimDetails = claimDetails; this.signedClaimDetails = signedClaimDetails; this.context = context; this.type = type; } /** * Sign the claim details with signer. * @param signer Identifier that will sign the claim details. */ public async signClaimDetails(signer: Identifier, keyReference: string) { if (signer.id !== this.issuer) { throw new UserAgentError(`Signer ID: ${signer.id} does not match issuer ID: ${this.issuer}`); } this.signedClaimDetails = await signer.sign(this.claimDetails, keyReference); console.log(`${signer.id} signed claim details`); } /** * If details are signed, return signed claim details. * Else return unsigned claim details. */ public getClaimDetails() { if (this.signedClaimDetails) { return this.signedClaimDetails; } return this.claimDetails; } /** * Add a claim to the claim details. * @param {Claim} claim Claim to be added to claimDetails. * @param {ClaimDescription} claimDescription Optional parameter if want to also add a corresponding claim description. */ public async addClaim(claim: Claim, claimDescription?: ClaimDescription) { this.claimDetails.push(claim); if (claimDescription) { this.claimDescriptions.push(claimDescription); } } /** * Stringify ClaimObject. * @returns A Stringified ClaimObject in the correct format */ public serialize(): string { let claimDetails = {}; if (this.signedClaimDetails) { claimDetails = { type: 'jws', data: this.signedClaimDetails }; } else { claimDetails = { type: 'unsigned', data: this.claimDetails } } const claimObject = { claimClass: this.claimClass, '@context': this.context, '@type': this.type, claimDescriptions: this.claimDescriptions, claimIssuer: this.issuer, claimDetails }; return JSON.stringify(claimObject); } /** * Create new ClaimObject from stringified JSON. * @param object Stringifed JSON object * @returns a ClaimObject */ public static async deserialize(object: any): Promise<ClaimObject> { let claimObject; if (typeof(object) === 'string') { claimObject = JSON.parse(object); } else { claimObject = object; } if (!claimObject.claimDetails) { throw new UserAgentError(`Claim Object does not contain parameter claimDetails`); } if (!claimObject.claimClass) { throw new UserAgentError(`Claim Object does not contain parameter claimClass`); } if (!claimObject.claimDescriptions) { throw new UserAgentError(`Claim Object does not contain parameter claimDescriptions`); } if (!claimObject.claimIssuer) { throw new UserAgentError(`Claim Object does not contain parameter claimIssuer`); } if (!claimObject['@context'] || !claimObject['@type']) { throw new UserAgentError(`Claim Object is missing context`); } const claimDetails = claimObject.claimDetails; if (claimDetails.type === 'unsigned') { return new ClaimObject(claimObject.claimClass, claimObject['@context'], claimObject['@type'], claimObject.claimIssuer, claimObject.claimDescriptions, claimDetails.data); } else { const token : JwsToken = await JwsToken.deserialize(claimDetails.data); const parsedClaimDetails = JSON.parse(token.payload.toString()); return new ClaimObject(claimObject.claimClass, claimObject['@context'], claimObject['@type'], claimObject.claimIssuer, claimObject.claimDescriptions, parsedClaimDetails, claimDetails.data); } } }