@credo-ts/core
Version:
<p align="center"> <br /> <img alt="Credo Logo" src="https://github.com/openwallet-foundation/credo-ts/blob/c7886cb8377ceb8ee4efe8d264211e561a75072d/images/credo-logo.png" height="250px" /> </p> <h1 align="center"><b>Credo - Core</b></h1
88 lines (84 loc) • 4.88 kB
JavaScript
import { CredoError } from "../../../error/CredoError.mjs";
import "../../../error/index.mjs";
import { JsonTransformer } from "../../../utils/JsonTransformer.mjs";
import "../../../utils/index.mjs";
import { JwtPayload } from "../../../crypto/jose/jwt/JwtPayload.mjs";
import { isJsonObject } from "../../../types.mjs";
import "../../../crypto/jose/jwt/index.mjs";
import { W3cCredential } from "../models/credential/W3cCredential.mjs";
import { w3cDate } from "../util.mjs";
import { isObject } from "class-validator";
//#region src/modules/vc/jwt-vc/credentialTransformer.ts
function getJwtPayloadFromCredential(credential) {
const vc = JsonTransformer.toJSON(credential);
const payloadOptions = { additionalClaims: { vc } };
const issuanceDate = Date.parse(credential.issuanceDate);
if (Number.isNaN(issuanceDate)) throw new CredoError("JWT VCs must have a valid issuance date");
payloadOptions.nbf = Math.floor(issuanceDate / 1e3);
delete vc.issuanceDate;
if (credential.expirationDate) {
const expirationDate = Date.parse(credential.expirationDate);
if (!Number.isNaN(expirationDate)) {
payloadOptions.exp = Math.floor(expirationDate / 1e3);
delete vc.expirationDate;
}
}
payloadOptions.iss = credential.issuerId;
if (typeof vc.issuer === "string") delete vc.issuer;
else if (typeof vc.issuer === "object") {
delete vc.issuer.id;
if (Object.keys(vc.issuer).length === 0) delete vc.issuer;
}
if (credential.id) {
payloadOptions.jti = credential.id;
delete vc.id;
}
if (Array.isArray(credential.credentialSubject) && credential.credentialSubject.length !== 1) throw new CredoError("JWT VCs must have exactly one credential subject");
const [credentialSubjectId] = credential.credentialSubjectIds;
if (credentialSubjectId) {
payloadOptions.sub = credentialSubjectId;
if (Array.isArray(vc.credentialSubject)) delete vc.credentialSubject[0].id;
else delete vc.credentialSubject?.id;
}
return new JwtPayload(payloadOptions);
}
function getCredentialFromJwtPayload(jwtPayload) {
if (!("vc" in jwtPayload.additionalClaims) || !isJsonObject(jwtPayload.additionalClaims.vc)) throw new CredoError("JWT does not contain a valid 'vc' claim");
const jwtVc = jwtPayload.additionalClaims.vc;
if (!jwtPayload.nbf || !jwtPayload.iss) throw new CredoError("JWT does not contain valid 'nbf' and 'iss' claims");
if (Array.isArray(jwtVc.credentialSubject) && jwtVc.credentialSubject.length !== 1) throw new CredoError("JWT VCs must have exactly one credential subject");
if (Array.isArray(jwtVc.credentialSubject) && !isObject(jwtVc.credentialSubject[0])) throw new CredoError("JWT VCs must have a credential subject of type object");
const credentialSubject = Array.isArray(jwtVc.credentialSubject) ? jwtVc.credentialSubject[0] : jwtVc.credentialSubject;
if (!isJsonObject(credentialSubject)) throw new CredoError("JWT VC does not have a valid credential subject");
const subjectWithId = jwtPayload.sub ? {
...credentialSubject,
id: jwtPayload.sub
} : credentialSubject;
if (jwtVc.id && jwtPayload.jti !== jwtVc.id) throw new CredoError("JWT jti and vc.id do not match");
if (typeof jwtVc.issuer === "string" && jwtPayload.iss !== jwtVc.issuer || isJsonObject(jwtVc.issuer) && jwtVc.issuer.id && jwtPayload.iss !== jwtVc.issuer.id) throw new CredoError("JWT iss and vc.issuer(.id) do not match");
if (jwtVc.issuanceDate) {
if (typeof jwtVc.issuanceDate !== "string") throw new CredoError("JWT vc.issuanceDate must be a string");
const issuanceDate = Date.parse(jwtVc.issuanceDate) / 1e3;
if (jwtPayload.nbf !== issuanceDate) throw new CredoError("JWT nbf and vc.issuanceDate do not match");
}
if (jwtVc.expirationDate) {
if (typeof jwtVc.expirationDate !== "string") throw new CredoError("JWT vc.expirationDate must be a string");
if (Date.parse(jwtVc.expirationDate) / 1e3 !== jwtPayload.exp) throw new CredoError("JWT exp and vc.expirationDate do not match");
}
if (isJsonObject(jwtVc.credentialSubject) && jwtVc.credentialSubject.id && jwtPayload.sub !== jwtVc.credentialSubject.id || Array.isArray(jwtVc.credentialSubject) && isJsonObject(jwtVc.credentialSubject[0]) && jwtVc.credentialSubject[0].id && jwtPayload.sub !== jwtVc.credentialSubject[0].id) throw new CredoError("JWT sub and vc.credentialSubject.id do not match");
const dataModelVc = {
...jwtVc,
issuanceDate: w3cDate(jwtPayload.nbf * 1e3),
expirationDate: jwtPayload.exp ? w3cDate(jwtPayload.exp * 1e3) : void 0,
issuer: typeof jwtVc.issuer === "object" ? {
...jwtVc.issuer,
id: jwtPayload.iss
} : jwtPayload.iss,
id: jwtPayload.jti,
credentialSubject: Array.isArray(jwtVc.credentialSubject) ? [subjectWithId] : subjectWithId
};
return JsonTransformer.fromJSON(dataModelVc, W3cCredential);
}
//#endregion
export { getCredentialFromJwtPayload, getJwtPayloadFromCredential };
//# sourceMappingURL=credentialTransformer.mjs.map