@atproto/jwk
Version:
A library for working with JSON Web Keys (JWKs) in TypeScript. This is meant to be extended by environment-specific libraries like @atproto/jwk-jose.
150 lines • 6.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.jwtPayloadSchema = exports.jwtHeaderSchema = exports.isUnsignedJwt = exports.unsignedJwtSchema = exports.isSignedJwt = exports.signedJwtSchema = void 0;
const zod_1 = require("zod");
const jwk_js_1 = require("./jwk.js");
const util_js_1 = require("./util.js");
exports.signedJwtSchema = zod_1.z
.string()
.superRefine(util_js_1.jwtCharsRefinement)
.superRefine((0, util_js_1.segmentedStringRefinementFactory)(3));
const isSignedJwt = (data) => exports.signedJwtSchema.safeParse(data).success;
exports.isSignedJwt = isSignedJwt;
exports.unsignedJwtSchema = zod_1.z
.string()
.superRefine(util_js_1.jwtCharsRefinement)
.superRefine((0, util_js_1.segmentedStringRefinementFactory)(2));
const isUnsignedJwt = (data) => exports.unsignedJwtSchema.safeParse(data).success;
exports.isUnsignedJwt = isUnsignedJwt;
/**
* @see {@link https://www.rfc-editor.org/rfc/rfc7515.html#section-4}
*/
exports.jwtHeaderSchema = zod_1.z.object({
/** "alg" (Algorithm) Header Parameter */
alg: zod_1.z.string(),
/** "jku" (JWK Set URL) Header Parameter */
jku: zod_1.z.string().url().optional(),
/** "jwk" (JSON Web Key) Header Parameter */
jwk: zod_1.z
.object({
kty: zod_1.z.string(),
crv: zod_1.z.string().optional(),
x: zod_1.z.string().optional(),
y: zod_1.z.string().optional(),
e: zod_1.z.string().optional(),
n: zod_1.z.string().optional(),
})
.optional(),
/** "kid" (Key ID) Header Parameter */
kid: zod_1.z.string().optional(),
/** "x5u" (X.509 URL) Header Parameter */
x5u: zod_1.z.string().optional(),
/** "x5c" (X.509 Certificate Chain) Header Parameter */
x5c: zod_1.z.array(zod_1.z.string()).optional(),
/** "x5t" (X.509 Certificate SHA-1 Thumbprint) Header Parameter */
x5t: zod_1.z.string().optional(),
/** "x5t#S256" (X.509 Certificate SHA-256 Thumbprint) Header Parameter */
'x5t#S256': zod_1.z.string().optional(),
/** "typ" (Type) Header Parameter */
typ: zod_1.z.string().optional(),
/** "cty" (Content Type) Header Parameter */
cty: zod_1.z.string().optional(),
/** "crit" (Critical) Header Parameter */
crit: zod_1.z.array(zod_1.z.string()).optional(),
});
// https://www.iana.org/assignments/jwt/jwt.xhtml
exports.jwtPayloadSchema = zod_1.z.object({
iss: zod_1.z.string().optional(),
aud: zod_1.z.union([zod_1.z.string(), zod_1.z.array(zod_1.z.string()).nonempty()]).optional(),
sub: zod_1.z.string().optional(),
exp: zod_1.z.number().int().optional(),
nbf: zod_1.z.number().int().optional(),
iat: zod_1.z.number().int().optional(),
jti: zod_1.z.string().optional(),
htm: zod_1.z.string().optional(),
htu: zod_1.z.string().optional(),
ath: zod_1.z.string().optional(),
acr: zod_1.z.string().optional(),
azp: zod_1.z.string().optional(),
amr: zod_1.z.array(zod_1.z.string()).optional(),
// https://datatracker.ietf.org/doc/html/rfc7800
cnf: zod_1.z
.object({
kid: zod_1.z.string().optional(), // Key ID
jwk: jwk_js_1.jwkPubSchema.optional(), // JWK
jwe: zod_1.z.string().optional(), // Encrypted key
jku: zod_1.z.string().url().optional(), // JWK Set URI ("kid" should also be provided)
// https://datatracker.ietf.org/doc/html/rfc9449#section-6.1
jkt: zod_1.z.string().optional(),
// https://datatracker.ietf.org/doc/html/rfc8705
'x5t#S256': zod_1.z.string().optional(), // X.509 Certificate SHA-256 Thumbprint
// https://datatracker.ietf.org/doc/html/rfc9203
osc: zod_1.z.string().optional(), // OSCORE_Input_Material carrying the parameters for using OSCORE per-message security with implicit key confirmation
})
.optional(),
client_id: zod_1.z.string().optional(),
scope: zod_1.z.string().optional(),
nonce: zod_1.z.string().optional(),
at_hash: zod_1.z.string().optional(),
c_hash: zod_1.z.string().optional(),
s_hash: zod_1.z.string().optional(),
auth_time: zod_1.z.number().int().optional(),
// https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
// OpenID: "profile" scope
name: zod_1.z.string().optional(),
family_name: zod_1.z.string().optional(),
given_name: zod_1.z.string().optional(),
middle_name: zod_1.z.string().optional(),
nickname: zod_1.z.string().optional(),
preferred_username: zod_1.z.string().optional(),
gender: zod_1.z.string().optional(), // OpenID only defines "male" and "female" without forbidding other values
picture: zod_1.z.string().url().optional(),
profile: zod_1.z.string().url().optional(),
website: zod_1.z.string().url().optional(),
birthdate: zod_1.z
.string()
.regex(/\d{4}-\d{2}-\d{2}/) // YYYY-MM-DD
.optional(),
zoneinfo: zod_1.z
.string()
.regex(/^[A-Za-z0-9_/]+$/)
.optional(),
locale: zod_1.z
.string()
.regex(/^[a-z]{2}(-[A-Z]{2})?$/)
.optional(),
updated_at: zod_1.z.number().int().optional(),
// OpenID: "email" scope
email: zod_1.z.string().optional(),
email_verified: zod_1.z.boolean().optional(),
// OpenID: "phone" scope
phone_number: zod_1.z.string().optional(),
phone_number_verified: zod_1.z.boolean().optional(),
// OpenID: "address" scope
// https://openid.net/specs/openid-connect-core-1_0.html#AddressClaim
address: zod_1.z
.object({
formatted: zod_1.z.string().optional(),
street_address: zod_1.z.string().optional(),
locality: zod_1.z.string().optional(),
region: zod_1.z.string().optional(),
postal_code: zod_1.z.string().optional(),
country: zod_1.z.string().optional(),
})
.optional(),
// https://datatracker.ietf.org/doc/html/rfc9396#section-14.2
authorization_details: zod_1.z
.array(zod_1.z
.object({
type: zod_1.z.string(),
// https://datatracker.ietf.org/doc/html/rfc9396#section-2.2
locations: zod_1.z.array(zod_1.z.string()).optional(),
actions: zod_1.z.array(zod_1.z.string()).optional(),
datatypes: zod_1.z.array(zod_1.z.string()).optional(),
identifier: zod_1.z.string().optional(),
privileges: zod_1.z.array(zod_1.z.string()).optional(),
})
.passthrough())
.optional(),
});
//# sourceMappingURL=jwt.js.map