{"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      iss: this.iss,\n      sub: this.sub,\n      aud: this.aud,\n      exp: this.exp,\n      nbf: this.nbf,\n      iat: this.iat,\n      jti: this.jti,\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":";;;;;;;;;;;;;;;AAUA,MAAa,oBAAoB;AAwBjC,IAAa,aAAb,MAAa,WAAW;CACtB,AAAO,YAAY,SAA6B;AAC9C,OAAK,MAAM,SAAS;AACpB,OAAK,MAAM,SAAS;AACpB,OAAK,MAAM,SAAS;AACpB,OAAK,MAAM,SAAS;AACpB,OAAK,MAAM,SAAS;AACpB,OAAK,MAAM,SAAS;AACpB,OAAK,MAAM,SAAS;AACpB,OAAK,mBAAmB,SAAS,oBAAoB,EAAE;;;;;;;;;;CAmFzD,AAAO,SAAS,SAOb;EACD,MAAM,EAAE,iBAAiB,kBAAkB,aAAa,SAAS,KAAK,SAAS,eAAe,SAAS,SAAS;AAGhH,MAAI,OAAO,KAAK,QAAQ,YAAY,OAAO,KAAK,QAAQ,YACtD,OAAM,IAAI,WAAW,kEAAkE,OAAO,KAAK,MAAM;AAE3G,MAAI,OAAO,KAAK,QAAQ,YAAY,KAAK,MAAM,gBAC7C,OAAM,IAAI,WAAW,wBAAwB,KAAK,MAAM;AAI1D,MAAI,OAAO,KAAK,QAAQ,YAAY,OAAO,KAAK,QAAQ,YACtD,OAAM,IAAI,WAAW,kEAAkE,OAAO,KAAK,MAAM;AAE3G,MAAI,OAAO,KAAK,QAAQ,YAAY,KAAK,MAAM,gBAC7C,OAAM,IAAI,WAAW,+BAA+B,KAAK,MAAM;AAIjE,MAAI,OAAO,KAAK,QAAQ,YAAY,OAAO,KAAK,QAAQ,YACtD,OAAM,IAAI,WAAW,kEAAkE,OAAO,KAAK,MAAM;AAE3G,MAAI,OAAO,KAAK,QAAQ,YAAY,KAAK,MAAM,cAC7C,OAAM,IAAI,WAAW,kBAAkB,KAAK,MAAM;;CAOtD,AAAO,SAAyB;AAC9B,SAAO;GACL,GAAG,KAAK;GACR,KAAK,KAAK;GACV,KAAK,KAAK;GACV,KAAK,KAAK;GACV,KAAK,KAAK;GACV,KAAK,KAAK;GACV,KAAK,KAAK;GACV,KAAK,KAAK;GACX;;CAGH,OAAc,SAAS,gBAAgC;EACrD,MAAM,EAAE,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,qBAAqB;AAGnE,MAAI,OAAO,OAAO,QAAQ,SACxB,OAAM,IAAI,WAAW,mCAAmC;AAI1D,MAAI,OAAO,OAAO,QAAQ,SACxB,OAAM,IAAI,WAAW,mCAAmC;AAI1D,MAAI,OAAO,OAAO,QAAQ,YAAY,EAAE,MAAM,QAAQ,IAAI,IAAI,IAAI,OAAO,QAAQ,OAAO,QAAQ,SAAS,EACvG,OAAM,IAAI,WAAW,0DAA0D;AAIjF,MAAI,QAAQ,OAAO,QAAQ,YAAY,MAAM,GAC3C,OAAM,IAAI,WAAW,4CAA4C;AAInE,MAAI,QAAQ,OAAO,QAAQ,YAAY,MAAM,GAC3C,OAAM,IAAI,WAAW,4CAA4C;AAInE,MAAI,QAAQ,OAAO,QAAQ,YAAY,MAAM,GAC3C,OAAM,IAAI,WAAW,4CAA4C;AAInE,MAAI,OAAO,OAAO,QAAQ,SACxB,OAAM,IAAI,WAAW,mCAAmC;AAc1D,SAXmB,IAAI,WAAW;GAChC;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;;;AAMN,SAAS,aAAa,KAAc,aAAsB;CACxD,MAAM,OAAO,OAAO,8BAAc,IAAI,MAAM,CAAC;CAC7C,MAAM,eAAe,eAAe;AAEpC,QAAO;EACL,eAAe,OAAO;EACtB,iBAAiB,OAAO;EACzB"}