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

+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2020 Filip Skokan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+78
View File
@@ -0,0 +1,78 @@
# dpop
> OAuth 2.0 Demonstration of Proof-of-Possession at the Application Layer ([DPoP][RFC9449]) for JavaScript Runtimes
## [💗 Help the project](https://github.com/sponsors/panva)
## Dependencies: 0
## [API Reference](docs/README.md)
`dpop` is distributed via [npmjs.com](https://www.npmjs.com/package/dpop), [jsdelivr.com](https://www.jsdelivr.com/package/npm/dpop), and [github.com](https://github.com/panva/dpop).
## Example
### ESM import[^cjs]
```ts
import * as DPoP from 'dpop'
```
### DPoP Key Pair generation
```ts
const keypair = await DPoP.generateKeyPair('ES256', { extractable: false })
```
### AS proof generation
```ts
let nonce!: string | undefined
const proof = await DPoP.generateProof(keypair, 'https://as.example.com/token', 'POST', nonce)
```
### AS Authorization Code Binding via `dpop_jkt`
```ts
const dpop_jkt = await DPoP.calculateThumbprint(keyPair.publicKey)
```
### AS proof generation
```ts
let nonce!: string | undefined
let accessToken!: string
const proof = await DPoP.generateProof(
keypair,
'https://rs.example.com/api',
'GET',
nonce,
accessToken,
)
```
## Supported Runtimes
The supported JavaScript runtimes include those that support the utilized Web API globals and standard built-in objects. These are _(but are not limited to)_:
- Browsers
- Bun
- Cloudflare Workers
- Deno
- Electron
- Node.js[^nodejs]
- Vercel's Edge Runtime
## Supported Versions
| Version | Security Fixes 🔑 | Other Bug Fixes 🐞 | New Features ⭐ |
| ----------------------------------------------- | ----------------- | ------------------ | --------------- |
| [v2.x](https://github.com/panva/dpop/tree/v2.x) | [Security Policy] | ✅ | ✅ |
[rfc9449]: https://www.rfc-editor.org/rfc/rfc9449.html
[Security Policy]: https://github.com/panva/dpop/security/policy
[^cjs]: CJS style `let dpop = require('dpop')` is possible in Node.js versions where the `require(esm)` feature is enabled by default (^20.19.0 || ^22.12.0 || >= 23.0.0).
[^nodejs]: Node.js v20.x as baseline is required
+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
+48
View File
@@ -0,0 +1,48 @@
{
"name": "dpop",
"version": "2.1.1",
"description": "DPoP (RFC9449) for JavaScript Runtimes",
"keywords": [
"dpop",
"rfc9449"
],
"homepage": "https://github.com/panva/dpop",
"repository": "panva/dpop",
"funding": {
"url": "https://github.com/sponsors/panva"
},
"license": "MIT",
"author": "Filip Skokan <panva.ip@gmail.com>",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"types": "./build/index.d.ts",
"default": "./build/index.js"
},
"./package.json": "./package.json"
},
"main": "./build/index.js",
"types": "./build/index.d.ts",
"files": [
"build/index.js",
"build/index.js.map",
"build/index.d.ts"
],
"scripts": {
"_format": "find src -type f -name '*.ts' -o -name '*.mjs' | xargs prettier",
"build": "rm -rf build && tsc --sourceMap && tsc --declaration true --emitDeclarationOnly true --removeComments false",
"docs": "npx patch-package && typedoc",
"format": "npm run _format -- --write",
"format-check": "npm run _format -- --check"
},
"devDependencies": {
"patch-package": "^8.0.0",
"prettier": "^3.5.3",
"prettier-plugin-jsdoc": "^1.3.2",
"typedoc": "0.27.9",
"typedoc-plugin-markdown": "4.3.1",
"typedoc-plugin-mdn-links": "4.0.3",
"typescript": "5.8.3"
}
}