UNPKG

@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

1 lines • 10.4 kB
{"version":3,"file":"JwtPayload.mjs","names":[],"sources":["../../../../src/crypto/jose/jwt/JwtPayload.ts"],"sourcesContent":["import { CredoError } from '../../../error'\nimport { dateToSeconds } from '../../../utils'\n\n/**\n * The maximum allowed clock skew time in seconds. If an time based validation\n * is performed against current time (`now`), the validation can be of by the skew\n * time.\n *\n * See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5\n */\nexport const DEFAULT_SKEW_TIME = 30\n\nexport interface JwtPayloadJson {\n iss?: string\n sub?: string\n aud?: string | string[]\n exp?: number\n nbf?: number\n iat?: number\n jti?: string\n [key: string]: unknown\n}\n\nexport interface JwtPayloadOptions {\n iss?: string\n sub?: string\n aud?: string | string[]\n exp?: number\n nbf?: number\n iat?: number\n jti?: string\n additionalClaims?: Record<string, unknown>\n}\n\nexport class JwtPayload {\n public constructor(options?: JwtPayloadOptions) {\n this.iss = options?.iss\n this.sub = options?.sub\n this.aud = options?.aud\n this.exp = options?.exp\n this.nbf = options?.nbf\n this.iat = options?.iat\n this.jti = options?.jti\n this.additionalClaims = options?.additionalClaims ?? {}\n }\n\n /**\n * identifies the principal that issued the JWT.\n * The processing of this claim is generally application specific.\n * The \"iss\" value is a case-sensitive string containing a StringOrURI\n * value.\n */\n public iss?: string\n\n /**\n * identifies the principal that is the\n * subject of the JWT. The Claims in a JWT are normally statements\n * about the subject. The subject value MUST either be scoped to be\n * locally unique in the context of the issuer or be globally unique.\n * The processing of this claim is generally application specific. The\n * \"sub\" value is a case-sensitive string containing a StringOrURI\n * value.\n */\n public sub?: string\n\n /**\n * identifies the recipients that the JWT is\n * intended for. Each principal intended to process the JWT MUST\n * identify itself with a value in the audience claim. If the principal\n * processing the claim does not identify itself with a value in the\n * \"aud\" claim when this claim is present, then the JWT MUST be\n * rejected.In the general case, the \"aud\" value is an array of case-\n * sensitive strings, each containing a StringOrURI value. In the\n * special case when the JWT has one audience, the \"aud\" value MAY be a\n * single case-sensitive string containing a StringOrURI value. The\n * interpretation of audience values is generally application specific.\n */\n public aud?: string | string[]\n\n /**\n * identifies the expiration time on\n * or after which the JWT MUST NOT be accepted for processing. The\n * processing of the \"exp\" claim requires that the current date/time\n * MUST be before the expiration date/time listed in the \"exp\" claim.\n * Implementers MAY provide for some small leeway, usually no more than\n * a few minutes, to account for clock skew. Its value MUST be a number\n * containing a NumericDate value.\n */\n public exp?: number\n\n /**\n * identifies the time at which the JWT was\n * issued. This claim can be used to determine the age of the JWT. Its\n * value MUST be a number containing a NumericDate value.\n */\n public nbf?: number\n\n /**\n * identifies the time at which the JWT was\n * issued. This claim can be used to determine the age of the JWT. Its\n * value MUST be a number containing a NumericDate value.\n */\n public iat?: number\n\n /**\n * provides a unique identifier for the JWT.\n * The identifier value MUST be assigned in a manner that ensures that\n * there is a negligible probability that the same value will be\n * accidentally assigned to a different data object; if the application\n * uses multiple issuers, collisions MUST be prevented among values\n * produced by different issuers as well. The \"jti\" claim can be used\n * to prevent the JWT from being replayed. The \"jti\" value is a case-\n * sensitive string.\n */\n public jti?: string\n\n public additionalClaims: Record<string, unknown>\n\n /**\n * Validate the JWT payload. This does not verify the signature of the JWT itself.\n *\n * The following validations are performed:\n * - if `nbf` is present, it must be greater than now\n * - if `iat` is present, it must be less than now\n * - if `exp` is present, it must be greater than now\n */\n public validate(options?: {\n /**\n * @deprecated use `skewSeconds` instead\n */\n skewTime?: number\n skewSeconds?: number\n now?: number\n }) {\n const { nowSkewedFuture, nowSkewedPast } = getNowSkewed(options?.now, options?.skewSeconds ?? options?.skewTime)\n\n // Validate nbf\n if (typeof this.nbf !== 'number' && typeof this.nbf !== 'undefined') {\n throw new CredoError(`JWT payload 'nbf' must be a number if provided. Actual type is ${typeof this.nbf}`)\n }\n if (typeof this.nbf === 'number' && this.nbf > nowSkewedFuture) {\n throw new CredoError(`JWT not valid before ${this.nbf}`)\n }\n\n // Validate iat\n if (typeof this.iat !== 'number' && typeof this.iat !== 'undefined') {\n throw new CredoError(`JWT payload 'iat' must be a number if provided. Actual type is ${typeof this.iat}`)\n }\n if (typeof this.iat === 'number' && this.iat > nowSkewedFuture) {\n throw new CredoError(`JWT issued in the future at ${this.iat}`)\n }\n\n // Validate exp\n if (typeof this.exp !== 'number' && typeof this.exp !== 'undefined') {\n throw new CredoError(`JWT payload 'exp' must be a number if provided. Actual type is ${typeof this.exp}`)\n }\n if (typeof this.exp === 'number' && this.exp < nowSkewedPast) {\n throw new CredoError(`JWT expired at ${this.exp}`)\n }\n\n // NOTE: nonce and aud are not validated in here. We could maybe add\n // the values as input, so you can provide the expected nonce and aud values\n }\n\n public toJson(): JwtPayloadJson {\n return {\n ...this.additionalClaims,\n ...(this.iss !== undefined && { iss: this.iss }),\n ...(this.sub !== undefined && { sub: this.sub }),\n ...(this.aud !== undefined && { aud: this.aud }),\n ...(this.exp !== undefined && { exp: this.exp }),\n ...(this.nbf !== undefined && { nbf: this.nbf }),\n ...(this.jti !== undefined && { jti: this.jti }),\n ...(this.iat !== undefined && { iat: this.iat }),\n }\n }\n\n public static fromJson(jwtPayloadJson: JwtPayloadJson) {\n const { iss, sub, aud, exp, nbf, iat, jti, ...additionalClaims } = jwtPayloadJson\n\n // Validate iss\n if (iss && typeof iss !== 'string') {\n throw new CredoError('JWT payload iss must be a string')\n }\n\n // Validate sub\n if (sub && typeof sub !== 'string') {\n throw new CredoError('JWT payload sub must be a string')\n }\n\n // Validate aud\n if (aud && typeof aud !== 'string' && !(Array.isArray(aud) && aud.every((aud) => typeof aud === 'string'))) {\n throw new CredoError('JWT payload aud must be a string or an array of strings')\n }\n\n // Validate exp\n if (exp && (typeof exp !== 'number' || exp < 0)) {\n throw new CredoError('JWT payload exp must be a positive number')\n }\n\n // Validate nbf\n if (nbf && (typeof nbf !== 'number' || nbf < 0)) {\n throw new CredoError('JWT payload nbf must be a positive number')\n }\n\n // Validate iat\n if (iat && (typeof iat !== 'number' || iat < 0)) {\n throw new CredoError('JWT payload iat must be a positive number')\n }\n\n // Validate jti\n if (jti && typeof jti !== 'string') {\n throw new CredoError('JWT payload jti must be a string')\n }\n\n const jwtPayload = new JwtPayload({\n iss,\n sub,\n aud,\n exp,\n nbf,\n iat,\n jti,\n additionalClaims,\n })\n\n return jwtPayload\n }\n}\n\nfunction getNowSkewed(now?: number, skewSeconds?: number) {\n const _now = now ?? dateToSeconds(new Date())\n const _skewSeconds = skewSeconds ?? DEFAULT_SKEW_TIME\n\n return {\n nowSkewedPast: _now - _skewSeconds,\n nowSkewedFuture: _now + _skewSeconds,\n }\n}\n"],"mappings":"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"}