This commit is contained in:
nucther committed 2025-12-01 23:23:05 +07:00
commit d282e2bcae
3481 files changed
+568488

No files matched your search

+98
View File
@@ -0,0 +1,98 @@
export type JsonObject = {
[Key in string]?: JsonValue;
};
export type JsonArray = JsonValue[];
export type JsonPrimitive = string | number | boolean | null;
export type JsonValue = JsonPrimitive | JsonObject | JsonArray;
/**
* @ignore
*/
export type CryptoKey = Extract<Awaited<ReturnType<typeof crypto.subtle.generateKey>>, {
type: string;
}>;
/**
* Supported JWS `alg` Algorithm identifiers.
*
* @example CryptoKey algorithm for the ES256 JWS Algorithm Identifier
*
* ```ts
* interface ES256Algorithm extends EcKeyAlgorithm {
* name: 'ECDSA'
* namedCurve: 'P-256'
* }
* ```
*
* @example CryptoKey algorithm for the Ed25519 JWS Algorithm Identifier
*
* ```ts
* interface Ed25519Algorithm extends Algorithm {
* name: 'Ed25519'
* }
* ```
*
* @example CryptoKey algorithm for the PS256 JWS Algorithm Identifier
*
* ```ts
* interface PS256Algorithm extends RsaHashedKeyAlgorithm {
* name: 'RSA-PSS'
* hash: { name: 'SHA-256' }
* }
* ```
*
* @example CryptoKey algorithm for the RS256 JWS Algorithm Identifier
*
* ```ts
* interface RS56Algorithm extends RsaHashedKeyAlgorithm {
* name: 'RSASSA-PKCS1-v1_5'
* hash: { name: 'SHA-256' }
* }
* ```
*/
export type JWSAlgorithm = 'ES256' | 'Ed25519' | 'RS256' | 'PS256';
/**
* @ignore
*/
export interface CryptoKeyPair {
privateKey: CryptoKey;
publicKey: CryptoKey;
}
export interface KeyPair extends CryptoKeyPair {
/**
* Private CryptoKey instance to sign the DPoP Proof JWT with.
*
* Its algorithm must be compatible with a supported {@link JWSAlgorithm JWS `alg` Algorithm}.
*/
privateKey: CryptoKey;
/**
* The public CryptoKey instance corresponding to {@link KeyPair.privateKey}
*/
publicKey: CryptoKey;
}
/**
* Generates a unique DPoP Proof JWT.
*
* @param keypair
* @param htu The HTTP URI (without query and fragment parts) of the request
* @param htm The HTTP method of the request
* @param nonce Server-provided nonce.
* @param accessToken Access token's value (When making protected resource requests).
* @param additional Any additional claims.
*/
export declare function generateProof(keypair: KeyPair, htu: string, htm: string, nonce?: string, accessToken?: string, additional?: Record<string, JsonValue>): Promise<string>;
export interface GenerateKeyPairOptions {
/**
* Indicates whether or not the private key may be exported. Default is `false`.
*/
extractable?: boolean;
}
/**
* Generates a {@link KeyPair} for a given JWS `alg` Algorithm identifier.
*
* @param alg Supported JWS `alg` Algorithm identifier.
*/
export declare function generateKeyPair(alg: JWSAlgorithm, options?: GenerateKeyPairOptions): Promise<KeyPair>;
/**
* Calculates the JWK Thumbprint of the DPoP public key using the SHA-256 hash function for use as
* the optional `dpop_jkt` authorization request parameter.
*/
export declare function calculateThumbprint(publicKey: CryptoKey): Promise<string>;
+229
View File
@@ -0,0 +1,229 @@
const encoder = new TextEncoder();
const decoder = new TextDecoder();
function buf(input) {
if (typeof input === 'string') {
return encoder.encode(input);
}
return decoder.decode(input);
}
function checkRsaKeyAlgorithm(algorithm) {
if (typeof algorithm.modulusLength !== 'number' || algorithm.modulusLength < 2048) {
throw new OperationProcessingError(`${algorithm.name} modulusLength must be at least 2048 bits`);
}
}
function subtleAlgorithm(key) {
switch (key.algorithm.name) {
case 'ECDSA':
return { name: key.algorithm.name, hash: 'SHA-256' };
case 'RSA-PSS':
checkRsaKeyAlgorithm(key.algorithm);
return {
name: key.algorithm.name,
saltLength: 256 >> 3,
};
case 'RSASSA-PKCS1-v1_5':
checkRsaKeyAlgorithm(key.algorithm);
return { name: key.algorithm.name };
case 'Ed25519':
return { name: key.algorithm.name };
}
throw new UnsupportedOperationError();
}
async function jwt(header, claimsSet, key) {
if (key.usages.includes('sign') === false) {
throw new TypeError('private CryptoKey instances used for signing assertions must include "sign" in their "usages"');
}
const input = `${b64u(buf(JSON.stringify(header)))}.${b64u(buf(JSON.stringify(claimsSet)))}`;
const signature = b64u(await crypto.subtle.sign(subtleAlgorithm(key), key, buf(input)));
return `${input}.${signature}`;
}
let encodeBase64Url;
if (Uint8Array.prototype.toBase64) {
encodeBase64Url = (input) => {
if (input instanceof ArrayBuffer) {
input = new Uint8Array(input);
}
return input.toBase64({ alphabet: 'base64url', omitPadding: true });
};
}
else {
const CHUNK_SIZE = 0x8000;
encodeBase64Url = (input) => {
if (input instanceof ArrayBuffer) {
input = new Uint8Array(input);
}
const arr = [];
for (let i = 0; i < input.byteLength; i += CHUNK_SIZE) {
arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE)));
}
return btoa(arr.join('')).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
};
}
function b64u(input) {
return encodeBase64Url(input);
}
class UnsupportedOperationError extends Error {
constructor(message) {
var _a;
super(message !== null && message !== void 0 ? message : 'operation not supported');
this.name = this.constructor.name;
(_a = Error.captureStackTrace) === null || _a === void 0 ? void 0 : _a.call(Error, this, this.constructor);
}
}
class OperationProcessingError extends Error {
constructor(message) {
var _a;
super(message);
this.name = this.constructor.name;
(_a = Error.captureStackTrace) === null || _a === void 0 ? void 0 : _a.call(Error, this, this.constructor);
}
}
function psAlg(key) {
switch (key.algorithm.hash.name) {
case 'SHA-256':
return 'PS256';
default:
throw new UnsupportedOperationError('unsupported RsaHashedKeyAlgorithm hash name');
}
}
function rsAlg(key) {
switch (key.algorithm.hash.name) {
case 'SHA-256':
return 'RS256';
default:
throw new UnsupportedOperationError('unsupported RsaHashedKeyAlgorithm hash name');
}
}
function esAlg(key) {
switch (key.algorithm.namedCurve) {
case 'P-256':
return 'ES256';
default:
throw new UnsupportedOperationError('unsupported EcKeyAlgorithm namedCurve');
}
}
function determineJWSAlgorithm(key) {
switch (key.algorithm.name) {
case 'RSA-PSS':
return psAlg(key);
case 'RSASSA-PKCS1-v1_5':
return rsAlg(key);
case 'ECDSA':
return esAlg(key);
case 'Ed25519':
return 'Ed25519';
default:
throw new UnsupportedOperationError('unsupported CryptoKey algorithm name');
}
}
function isCryptoKey(key) {
return key instanceof CryptoKey;
}
function isPrivateKey(key) {
return isCryptoKey(key) && key.type === 'private';
}
function isPublicKey(key) {
return isCryptoKey(key) && key.type === 'public';
}
function epochTime() {
return Math.floor(Date.now() / 1000);
}
export async function generateProof(keypair, htu, htm, nonce, accessToken, additional) {
const privateKey = keypair === null || keypair === void 0 ? void 0 : keypair.privateKey;
const publicKey = keypair === null || keypair === void 0 ? void 0 : keypair.publicKey;
if (!isPrivateKey(privateKey)) {
throw new TypeError('"keypair.privateKey" must be a private CryptoKey');
}
if (!isPublicKey(publicKey)) {
throw new TypeError('"keypair.publicKey" must be a public CryptoKey');
}
if (publicKey.extractable !== true) {
throw new TypeError('"keypair.publicKey.extractable" must be true');
}
if (typeof htu !== 'string') {
throw new TypeError('"htu" must be a string');
}
if (typeof htm !== 'string') {
throw new TypeError('"htm" must be a string');
}
if (nonce !== undefined && typeof nonce !== 'string') {
throw new TypeError('"nonce" must be a string or undefined');
}
if (accessToken !== undefined && typeof accessToken !== 'string') {
throw new TypeError('"accessToken" must be a string or undefined');
}
if (additional !== undefined &&
(typeof additional !== 'object' || additional === null || Array.isArray(additional))) {
throw new TypeError('"additional" must be an object');
}
return jwt({
alg: determineJWSAlgorithm(privateKey),
typ: 'dpop+jwt',
jwk: await publicJwk(publicKey),
}, Object.assign(Object.assign({}, additional), { iat: epochTime(), jti: crypto.randomUUID(), htm,
nonce,
htu, ath: accessToken ? b64u(await crypto.subtle.digest('SHA-256', buf(accessToken))) : undefined }), privateKey);
}
async function publicJwk(key) {
const { kty, e, n, x, y, crv } = await crypto.subtle.exportKey('jwk', key);
return { kty, crv, e, n, x, y };
}
export async function generateKeyPair(alg, options) {
var _a;
let algorithm;
if (typeof alg !== 'string' || alg.length === 0) {
throw new TypeError('"alg" must be a non-empty string');
}
switch (alg) {
case 'PS256':
algorithm = {
name: 'RSA-PSS',
hash: 'SHA-256',
modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
};
break;
case 'RS256':
algorithm = {
name: 'RSASSA-PKCS1-v1_5',
hash: 'SHA-256',
modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
};
break;
case 'ES256':
algorithm = { name: 'ECDSA', namedCurve: 'P-256' };
break;
case 'Ed25519':
algorithm = { name: 'Ed25519' };
break;
default:
throw new UnsupportedOperationError();
}
return (crypto.subtle.generateKey(algorithm, (_a = options === null || options === void 0 ? void 0 : options.extractable) !== null && _a !== void 0 ? _a : false, ['sign', 'verify']));
}
export async function calculateThumbprint(publicKey) {
if (!isPublicKey(publicKey)) {
throw new TypeError('"publicKey" must be a public CryptoKey');
}
if (publicKey.extractable !== true) {
throw new TypeError('"publicKey.extractable" must be true');
}
const jwk = await publicJwk(publicKey);
let components;
switch (jwk.kty) {
case 'EC':
components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y };
break;
case 'OKP':
components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x };
break;
case 'RSA':
components = { e: jwk.e, kty: jwk.kty, n: jwk.n };
break;
default:
throw new UnsupportedOperationError('unsupported JWK kty');
}
return b64u(await crypto.subtle.digest({ name: 'SHA-256' }, buf(JSON.stringify(components))));
}
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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 truncated