

import { CredoError } from "../../../error/CredoError.mjs";
import "../../../error/index.mjs";

//#region src/crypto/jose/jwt/JwtPayload.ts
/**
* The maximum allowed clock skew time in seconds. If an time based validation
* is performed against current time (`now`), the validation can be of by the skew
* time.
*
* See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5
*/
const DEFAULT_SKEW_TIME = 300;
var JwtPayload = class JwtPayload {
	constructor(options) {
		this.iss = options?.iss;
		this.sub = options?.sub;
		this.aud = options?.aud;
		this.exp = options?.exp;
		this.nbf = options?.nbf;
		this.iat = options?.iat;
		this.jti = options?.jti;
		this.additionalClaims = options?.additionalClaims ?? {};
	}
	/**
	* Validate the JWT payload. This does not verify the signature of the JWT itself.
	*
	* The following validations are performed:
	*  - if `nbf` is present, it must be greater than now
	*  - if `iat` is present, it must be less than now
	*  - if `exp` is present, it must be greater than now
	*/
	validate(options) {
		const { nowSkewedFuture, nowSkewedPast } = getNowSkewed(options?.now, options?.skewTime);
		if (typeof this.nbf !== "number" && typeof this.nbf !== "undefined") throw new CredoError(`JWT payload 'nbf' must be a number if provided. Actual type is ${typeof this.nbf}`);
		if (typeof this.nbf === "number" && this.nbf > nowSkewedFuture) throw new CredoError(`JWT not valid before ${this.nbf}`);
		if (typeof this.iat !== "number" && typeof this.iat !== "undefined") throw new CredoError(`JWT payload 'iat' must be a number if provided. Actual type is ${typeof this.iat}`);
		if (typeof this.iat === "number" && this.iat > nowSkewedFuture) throw new CredoError(`JWT issued in the future at ${this.iat}`);
		if (typeof this.exp !== "number" && typeof this.exp !== "undefined") throw new CredoError(`JWT payload 'exp' must be a number if provided. Actual type is ${typeof this.exp}`);
		if (typeof this.exp === "number" && this.exp < nowSkewedPast) throw new CredoError(`JWT expired at ${this.exp}`);
	}
	toJson() {
		return {
			...this.additionalClaims,
			iss: this.iss,
			sub: this.sub,
			aud: this.aud,
			exp: this.exp,
			nbf: this.nbf,
			iat: this.iat,
			jti: this.jti
		};
	}
	static fromJson(jwtPayloadJson) {
		const { iss, sub, aud, exp, nbf, iat, jti,...additionalClaims } = jwtPayloadJson;
		if (iss && typeof iss !== "string") throw new CredoError("JWT payload iss must be a string");
		if (sub && typeof sub !== "string") throw new CredoError("JWT payload sub must be a string");
		if (aud && typeof aud !== "string" && !(Array.isArray(aud) && aud.every((aud$1) => typeof aud$1 === "string"))) throw new CredoError("JWT payload aud must be a string or an array of strings");
		if (exp && (typeof exp !== "number" || exp < 0)) throw new CredoError("JWT payload exp must be a positive number");
		if (nbf && (typeof nbf !== "number" || nbf < 0)) throw new CredoError("JWT payload nbf must be a positive number");
		if (iat && (typeof iat !== "number" || iat < 0)) throw new CredoError("JWT payload iat must be a positive number");
		if (jti && typeof jti !== "string") throw new CredoError("JWT payload jti must be a string");
		return new JwtPayload({
			iss,
			sub,
			aud,
			exp,
			nbf,
			iat,
			jti,
			additionalClaims
		});
	}
};
function getNowSkewed(now, skewTime) {
	const _now = typeof now === "number" ? now : Math.floor(Date.now() / 1e3);
	const _skewTime = typeof skewTime !== "undefined" && skewTime >= 0 ? skewTime : DEFAULT_SKEW_TIME;
	return {
		nowSkewedPast: _now - _skewTime,
		nowSkewedFuture: _now + _skewTime
	};
}

//#endregion
export { JwtPayload };
//# sourceMappingURL=JwtPayload.mjs.map