@fluixi/oauth2 1.0.0-alpha.2 → 1.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{browser-WDGFIB5Z.mjs → browser-ZDO2EHPH.mjs} +2 -2
- package/dist/browser.cjs +4 -2
- package/dist/browser.mjs +4 -2
- package/dist/{chunk-ZVQNMEAR.mjs → chunk-5NSLG6E3.mjs} +1 -1
- package/dist/{chunk-C6SXP47D.mjs → chunk-UEAYG4TW.mjs} +1 -1
- package/dist/{dpop-DLCJBCQN.mjs → dpop-CU42DUAJ.mjs} +26 -6
- package/dist/{dpop-NS7NKOWM.mjs → dpop-YPGCGL7S.mjs} +22 -2
- package/dist/dpop-store.cjs +4 -2
- package/dist/dpop-store.mjs +4 -2
- package/dist/dpop.cjs +22 -2
- package/dist/dpop.d.ts +18 -1
- package/dist/dpop.d.ts.map +1 -1
- package/dist/dpop.js +23 -2
- package/dist/dpop.mjs +22 -2
- package/dist/index.cjs +20 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.mjs +23 -6
- package/dist/module.cjs +44 -0
- package/dist/module.d.ts +13 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +22 -0
- package/dist/module.mjs +23 -0
- package/dist/server.cjs +138 -25
- package/dist/server.d.ts +20 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +79 -17
- package/dist/server.mjs +140 -27
- package/dist/service-client.cjs +1 -1
- package/dist/service-client.mjs +3 -3
- package/dist/service.cjs +4 -2
- package/dist/service.mjs +4 -2
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/verify.cjs +24 -3
- package/dist/verify.mjs +6 -6
- package/package.json +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/*! @fluixi/oauth2 v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/oauth2 v1.0.0-alpha.4 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
import {
|
|
3
3
|
__export
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-5NSLG6E3.mjs";
|
|
5
5
|
|
|
6
6
|
// ../../node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/browser/runtime/webcrypto.js
|
|
7
7
|
var webcrypto_default = crypto;
|
package/dist/browser.cjs
CHANGED
|
@@ -165,9 +165,11 @@ async function loadJose2() {
|
|
|
165
165
|
);
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
|
-
async function createDpopKey(alg = "ES256") {
|
|
168
|
+
async function createDpopKey(alg = "ES256", options = {}) {
|
|
169
169
|
const jose = await loadJose2();
|
|
170
|
-
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
170
|
+
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
171
|
+
extractable: options.extractable ?? false
|
|
172
|
+
});
|
|
171
173
|
const publicJwk = { ...await jose.exportJWK(publicKey) };
|
|
172
174
|
return {
|
|
173
175
|
privateKey,
|
package/dist/browser.mjs
CHANGED
|
@@ -131,9 +131,11 @@ async function loadJose2() {
|
|
|
131
131
|
);
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
-
async function createDpopKey(alg = "ES256") {
|
|
134
|
+
async function createDpopKey(alg = "ES256", options = {}) {
|
|
135
135
|
const jose = await loadJose2();
|
|
136
|
-
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
136
|
+
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
137
|
+
extractable: options.extractable ?? false
|
|
138
|
+
});
|
|
137
139
|
const publicJwk = { ...await jose.exportJWK(publicKey) };
|
|
138
140
|
return {
|
|
139
141
|
privateKey,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/oauth2 v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/oauth2 v1.0.0-alpha.4 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __export = (target, all) => {
|
|
4
4
|
for (var name in all)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
/*! @fluixi/oauth2 v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/oauth2 v1.0.0-alpha.4 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
import {
|
|
3
3
|
OAuthError
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-UEAYG4TW.mjs";
|
|
5
|
+
import "./chunk-5NSLG6E3.mjs";
|
|
6
6
|
|
|
7
7
|
// src/dpop.ts
|
|
8
8
|
async function loadJose() {
|
|
9
9
|
try {
|
|
10
|
-
return await import("./browser-
|
|
10
|
+
return await import("./browser-ZDO2EHPH.mjs");
|
|
11
11
|
} catch {
|
|
12
12
|
throw new OAuthError(
|
|
13
13
|
"DPoP needs `jose`. Install it: npm i jose. It is an optional peer, so a client not using DPoP does not carry it.",
|
|
@@ -15,9 +15,11 @@ async function loadJose() {
|
|
|
15
15
|
);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
async function createDpopKey(alg = "ES256") {
|
|
18
|
+
async function createDpopKey(alg = "ES256", options = {}) {
|
|
19
19
|
const jose = await loadJose();
|
|
20
|
-
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
20
|
+
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
21
|
+
extractable: options.extractable ?? false
|
|
22
|
+
});
|
|
21
23
|
const publicJwk = { ...await jose.exportJWK(publicKey) };
|
|
22
24
|
return {
|
|
23
25
|
privateKey,
|
|
@@ -26,6 +28,22 @@ async function createDpopKey(alg = "ES256") {
|
|
|
26
28
|
alg
|
|
27
29
|
};
|
|
28
30
|
}
|
|
31
|
+
async function exportDpopKey(key) {
|
|
32
|
+
const jose = await loadJose();
|
|
33
|
+
return { jwk: { ...await jose.exportJWK(key.privateKey) }, alg: key.alg };
|
|
34
|
+
}
|
|
35
|
+
var PRIVATE_MEMBERS = /* @__PURE__ */ new Set(["d", "p", "q", "dp", "dq", "qi", "oth"]);
|
|
36
|
+
async function importDpopKey(stored) {
|
|
37
|
+
const jose = await loadJose();
|
|
38
|
+
const privateKey = await jose.importJWK(stored.jwk, stored.alg);
|
|
39
|
+
const publicJwk = Object.fromEntries(Object.entries(stored.jwk).filter(([k]) => !PRIVATE_MEMBERS.has(k)));
|
|
40
|
+
return {
|
|
41
|
+
privateKey,
|
|
42
|
+
publicJwk,
|
|
43
|
+
thumbprint: await jose.calculateJwkThumbprint(publicJwk, "sha256"),
|
|
44
|
+
alg: stored.alg
|
|
45
|
+
};
|
|
46
|
+
}
|
|
29
47
|
async function thumbprintOf(jwk) {
|
|
30
48
|
const jose = await loadJose();
|
|
31
49
|
return jose.calculateJwkThumbprint(jwk, "sha256");
|
|
@@ -73,6 +91,8 @@ function boundKeyOf(claims) {
|
|
|
73
91
|
export {
|
|
74
92
|
boundKeyOf,
|
|
75
93
|
createDpopKey,
|
|
94
|
+
exportDpopKey,
|
|
95
|
+
importDpopKey,
|
|
76
96
|
nonceFrom,
|
|
77
97
|
proofFor,
|
|
78
98
|
thumbprintOf,
|
|
@@ -14,9 +14,11 @@ async function loadJose() {
|
|
|
14
14
|
);
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
async function createDpopKey(alg = "ES256") {
|
|
17
|
+
async function createDpopKey(alg = "ES256", options = {}) {
|
|
18
18
|
const jose = await loadJose();
|
|
19
|
-
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
19
|
+
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
20
|
+
extractable: options.extractable ?? false
|
|
21
|
+
});
|
|
20
22
|
const publicJwk = { ...await jose.exportJWK(publicKey) };
|
|
21
23
|
return {
|
|
22
24
|
privateKey,
|
|
@@ -25,6 +27,22 @@ async function createDpopKey(alg = "ES256") {
|
|
|
25
27
|
alg
|
|
26
28
|
};
|
|
27
29
|
}
|
|
30
|
+
async function exportDpopKey(key) {
|
|
31
|
+
const jose = await loadJose();
|
|
32
|
+
return { jwk: { ...await jose.exportJWK(key.privateKey) }, alg: key.alg };
|
|
33
|
+
}
|
|
34
|
+
var PRIVATE_MEMBERS = /* @__PURE__ */ new Set(["d", "p", "q", "dp", "dq", "qi", "oth"]);
|
|
35
|
+
async function importDpopKey(stored) {
|
|
36
|
+
const jose = await loadJose();
|
|
37
|
+
const privateKey = await jose.importJWK(stored.jwk, stored.alg);
|
|
38
|
+
const publicJwk = Object.fromEntries(Object.entries(stored.jwk).filter(([k]) => !PRIVATE_MEMBERS.has(k)));
|
|
39
|
+
return {
|
|
40
|
+
privateKey,
|
|
41
|
+
publicJwk,
|
|
42
|
+
thumbprint: await jose.calculateJwkThumbprint(publicJwk, "sha256"),
|
|
43
|
+
alg: stored.alg
|
|
44
|
+
};
|
|
45
|
+
}
|
|
28
46
|
async function thumbprintOf(jwk) {
|
|
29
47
|
const jose = await loadJose();
|
|
30
48
|
return jose.calculateJwkThumbprint(jwk, "sha256");
|
|
@@ -72,6 +90,8 @@ function boundKeyOf(claims) {
|
|
|
72
90
|
export {
|
|
73
91
|
boundKeyOf,
|
|
74
92
|
createDpopKey,
|
|
93
|
+
exportDpopKey,
|
|
94
|
+
importDpopKey,
|
|
75
95
|
nonceFrom,
|
|
76
96
|
proofFor,
|
|
77
97
|
thumbprintOf,
|
package/dist/dpop-store.cjs
CHANGED
|
@@ -56,9 +56,11 @@ async function loadJose() {
|
|
|
56
56
|
);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
-
async function createDpopKey(alg = "ES256") {
|
|
59
|
+
async function createDpopKey(alg = "ES256", options = {}) {
|
|
60
60
|
const jose = await loadJose();
|
|
61
|
-
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
61
|
+
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
62
|
+
extractable: options.extractable ?? false
|
|
63
|
+
});
|
|
62
64
|
const publicJwk = { ...await jose.exportJWK(publicKey) };
|
|
63
65
|
return {
|
|
64
66
|
privateKey,
|
package/dist/dpop-store.mjs
CHANGED
|
@@ -21,9 +21,11 @@ async function loadJose() {
|
|
|
21
21
|
);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
async function createDpopKey(alg = "ES256") {
|
|
24
|
+
async function createDpopKey(alg = "ES256", options = {}) {
|
|
25
25
|
const jose = await loadJose();
|
|
26
|
-
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
26
|
+
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
27
|
+
extractable: options.extractable ?? false
|
|
28
|
+
});
|
|
27
29
|
const publicJwk = { ...await jose.exportJWK(publicKey) };
|
|
28
30
|
return {
|
|
29
31
|
privateKey,
|
package/dist/dpop.cjs
CHANGED
|
@@ -32,6 +32,8 @@ var dpop_exports = {};
|
|
|
32
32
|
__export(dpop_exports, {
|
|
33
33
|
boundKeyOf: () => boundKeyOf,
|
|
34
34
|
createDpopKey: () => createDpopKey,
|
|
35
|
+
exportDpopKey: () => exportDpopKey,
|
|
36
|
+
importDpopKey: () => importDpopKey,
|
|
35
37
|
nonceFrom: () => nonceFrom,
|
|
36
38
|
proofFor: () => proofFor,
|
|
37
39
|
thumbprintOf: () => thumbprintOf,
|
|
@@ -60,9 +62,11 @@ async function loadJose() {
|
|
|
60
62
|
);
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
|
-
async function createDpopKey(alg = "ES256") {
|
|
65
|
+
async function createDpopKey(alg = "ES256", options = {}) {
|
|
64
66
|
const jose = await loadJose();
|
|
65
|
-
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
67
|
+
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
68
|
+
extractable: options.extractable ?? false
|
|
69
|
+
});
|
|
66
70
|
const publicJwk = { ...await jose.exportJWK(publicKey) };
|
|
67
71
|
return {
|
|
68
72
|
privateKey,
|
|
@@ -71,6 +75,22 @@ async function createDpopKey(alg = "ES256") {
|
|
|
71
75
|
alg
|
|
72
76
|
};
|
|
73
77
|
}
|
|
78
|
+
async function exportDpopKey(key) {
|
|
79
|
+
const jose = await loadJose();
|
|
80
|
+
return { jwk: { ...await jose.exportJWK(key.privateKey) }, alg: key.alg };
|
|
81
|
+
}
|
|
82
|
+
var PRIVATE_MEMBERS = /* @__PURE__ */ new Set(["d", "p", "q", "dp", "dq", "qi", "oth"]);
|
|
83
|
+
async function importDpopKey(stored) {
|
|
84
|
+
const jose = await loadJose();
|
|
85
|
+
const privateKey = await jose.importJWK(stored.jwk, stored.alg);
|
|
86
|
+
const publicJwk = Object.fromEntries(Object.entries(stored.jwk).filter(([k]) => !PRIVATE_MEMBERS.has(k)));
|
|
87
|
+
return {
|
|
88
|
+
privateKey,
|
|
89
|
+
publicJwk,
|
|
90
|
+
thumbprint: await jose.calculateJwkThumbprint(publicJwk, "sha256"),
|
|
91
|
+
alg: stored.alg
|
|
92
|
+
};
|
|
93
|
+
}
|
|
74
94
|
async function thumbprintOf(jwk) {
|
|
75
95
|
const jose = await loadJose();
|
|
76
96
|
return jose.calculateJwkThumbprint(jwk, "sha256");
|
package/dist/dpop.d.ts
CHANGED
|
@@ -25,7 +25,24 @@ export interface DpopKey {
|
|
|
25
25
|
* attacker who can run script can use the key while they are there, and cannot take it
|
|
26
26
|
* away to use later.
|
|
27
27
|
*/
|
|
28
|
-
export declare function createDpopKey(alg?: string
|
|
28
|
+
export declare function createDpopKey(alg?: string, options?: {
|
|
29
|
+
extractable?: boolean;
|
|
30
|
+
}): Promise<DpopKey>;
|
|
31
|
+
/**
|
|
32
|
+
* A key as a server session stores it: the private JWK and its algorithm.
|
|
33
|
+
*
|
|
34
|
+
* Only for a key held by a server, inside an encrypted httpOnly cookie. There it is bytes
|
|
35
|
+
* no page can read, and the session has nowhere else to keep it between requests. A
|
|
36
|
+
* browser key stays non-extractable in IndexedDB instead.
|
|
37
|
+
*/
|
|
38
|
+
export interface StoredDpopKey {
|
|
39
|
+
jwk: Record<string, unknown>;
|
|
40
|
+
alg: string;
|
|
41
|
+
}
|
|
42
|
+
/** Export a key made with `extractable: true`, for a server session to store. */
|
|
43
|
+
export declare function exportDpopKey(key: DpopKey): Promise<StoredDpopKey>;
|
|
44
|
+
/** Rebuild a key a server session stored. The thumbprint comes out the same, which is the point. */
|
|
45
|
+
export declare function importDpopKey(stored: StoredDpopKey): Promise<DpopKey>;
|
|
29
46
|
/** The thumbprint of a public JWK, for comparing against a token's `cnf.jkt`. */
|
|
30
47
|
export declare function thumbprintOf(jwk: Record<string, unknown>): Promise<string>;
|
|
31
48
|
export interface ProofOptions {
|
package/dist/dpop.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dpop.d.ts","sourceRoot":"","sources":["../src/dpop.ts"],"names":[],"mappings":"AAkBA,6EAA6E;AAC7E,MAAM,WAAW,OAAO;IACtB,iEAAiE;IACjE,UAAU,EAAE,SAAS,CAAC;IACtB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,GAAG,EAAE,MAAM,CAAC;CACb;AAcD;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,
|
|
1
|
+
{"version":3,"file":"dpop.d.ts","sourceRoot":"","sources":["../src/dpop.ts"],"names":[],"mappings":"AAkBA,6EAA6E;AAC7E,MAAM,WAAW,OAAO;IACtB,iEAAiE;IACjE,UAAU,EAAE,SAAS,CAAC;IACtB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,GAAG,EAAE,MAAM,CAAC;CACb;AAcD;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,GAAG,SAAU,EACb,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACtC,OAAO,CAAC,OAAO,CAAC,CAalB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,iFAAiF;AACjF,wBAAsB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAGxE;AAID,oGAAoG;AACpG,wBAAsB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAW3E;AAED,iFAAiF;AACjF,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAGhF;AAED,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAsCnF;AAED,mFAAmF;AACnF,wBAAgB,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAE3D;AAED,0FAA0F;AAC1F,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAGvE;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CAGzE"}
|
package/dist/dpop.js
CHANGED
|
@@ -35,9 +35,11 @@ async function loadJose() {
|
|
|
35
35
|
* attacker who can run script can use the key while they are there, and cannot take it
|
|
36
36
|
* away to use later.
|
|
37
37
|
*/
|
|
38
|
-
export async function createDpopKey(alg = 'ES256') {
|
|
38
|
+
export async function createDpopKey(alg = 'ES256', options = {}) {
|
|
39
39
|
const jose = await loadJose();
|
|
40
|
-
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
40
|
+
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
41
|
+
extractable: options.extractable ?? false,
|
|
42
|
+
});
|
|
41
43
|
const publicJwk = { ...(await jose.exportJWK(publicKey)) };
|
|
42
44
|
return {
|
|
43
45
|
privateKey: privateKey,
|
|
@@ -46,6 +48,25 @@ export async function createDpopKey(alg = 'ES256') {
|
|
|
46
48
|
alg,
|
|
47
49
|
};
|
|
48
50
|
}
|
|
51
|
+
/** Export a key made with `extractable: true`, for a server session to store. */
|
|
52
|
+
export async function exportDpopKey(key) {
|
|
53
|
+
const jose = await loadJose();
|
|
54
|
+
return { jwk: { ...(await jose.exportJWK(key.privateKey)) }, alg: key.alg };
|
|
55
|
+
}
|
|
56
|
+
const PRIVATE_MEMBERS = new Set(['d', 'p', 'q', 'dp', 'dq', 'qi', 'oth']);
|
|
57
|
+
/** Rebuild a key a server session stored. The thumbprint comes out the same, which is the point. */
|
|
58
|
+
export async function importDpopKey(stored) {
|
|
59
|
+
const jose = await loadJose();
|
|
60
|
+
const privateKey = (await jose.importJWK(stored.jwk, stored.alg));
|
|
61
|
+
// The public half is the private JWK without its private members (RFC 7518 §6.2.2, §6.3.2).
|
|
62
|
+
const publicJwk = Object.fromEntries(Object.entries(stored.jwk).filter(([k]) => !PRIVATE_MEMBERS.has(k)));
|
|
63
|
+
return {
|
|
64
|
+
privateKey,
|
|
65
|
+
publicJwk,
|
|
66
|
+
thumbprint: await jose.calculateJwkThumbprint(publicJwk, 'sha256'),
|
|
67
|
+
alg: stored.alg,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
49
70
|
/** The thumbprint of a public JWK, for comparing against a token's `cnf.jkt`. */
|
|
50
71
|
export async function thumbprintOf(jwk) {
|
|
51
72
|
const jose = await loadJose();
|
package/dist/dpop.mjs
CHANGED
|
@@ -21,9 +21,11 @@ async function loadJose() {
|
|
|
21
21
|
);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
async function createDpopKey(alg = "ES256") {
|
|
24
|
+
async function createDpopKey(alg = "ES256", options = {}) {
|
|
25
25
|
const jose = await loadJose();
|
|
26
|
-
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
26
|
+
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
27
|
+
extractable: options.extractable ?? false
|
|
28
|
+
});
|
|
27
29
|
const publicJwk = { ...await jose.exportJWK(publicKey) };
|
|
28
30
|
return {
|
|
29
31
|
privateKey,
|
|
@@ -32,6 +34,22 @@ async function createDpopKey(alg = "ES256") {
|
|
|
32
34
|
alg
|
|
33
35
|
};
|
|
34
36
|
}
|
|
37
|
+
async function exportDpopKey(key) {
|
|
38
|
+
const jose = await loadJose();
|
|
39
|
+
return { jwk: { ...await jose.exportJWK(key.privateKey) }, alg: key.alg };
|
|
40
|
+
}
|
|
41
|
+
var PRIVATE_MEMBERS = /* @__PURE__ */ new Set(["d", "p", "q", "dp", "dq", "qi", "oth"]);
|
|
42
|
+
async function importDpopKey(stored) {
|
|
43
|
+
const jose = await loadJose();
|
|
44
|
+
const privateKey = await jose.importJWK(stored.jwk, stored.alg);
|
|
45
|
+
const publicJwk = Object.fromEntries(Object.entries(stored.jwk).filter(([k]) => !PRIVATE_MEMBERS.has(k)));
|
|
46
|
+
return {
|
|
47
|
+
privateKey,
|
|
48
|
+
publicJwk,
|
|
49
|
+
thumbprint: await jose.calculateJwkThumbprint(publicJwk, "sha256"),
|
|
50
|
+
alg: stored.alg
|
|
51
|
+
};
|
|
52
|
+
}
|
|
35
53
|
async function thumbprintOf(jwk) {
|
|
36
54
|
const jose = await loadJose();
|
|
37
55
|
return jose.calculateJwkThumbprint(jwk, "sha256");
|
|
@@ -79,6 +97,8 @@ function boundKeyOf(claims) {
|
|
|
79
97
|
export {
|
|
80
98
|
boundKeyOf,
|
|
81
99
|
createDpopKey,
|
|
100
|
+
exportDpopKey,
|
|
101
|
+
importDpopKey,
|
|
82
102
|
nonceFrom,
|
|
83
103
|
proofFor,
|
|
84
104
|
thumbprintOf,
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/oauth2 v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/oauth2 v1.0.0-alpha.4 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
"use strict";
|
|
3
3
|
var __create = Object.create;
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -35,6 +35,7 @@ __export(index_exports, {
|
|
|
35
35
|
AuthServiceToken: () => AuthServiceToken,
|
|
36
36
|
COOKIE_SESSION: () => COOKIE_SESSION,
|
|
37
37
|
OAuthError: () => OAuthError,
|
|
38
|
+
authModule: () => authModule,
|
|
38
39
|
boundKeyOf: () => boundKeyOf,
|
|
39
40
|
clearDiscoveryCache: () => clearDiscoveryCache,
|
|
40
41
|
createAuthService: () => createAuthService,
|
|
@@ -212,9 +213,11 @@ async function loadJose2() {
|
|
|
212
213
|
);
|
|
213
214
|
}
|
|
214
215
|
}
|
|
215
|
-
async function createDpopKey(alg = "ES256") {
|
|
216
|
+
async function createDpopKey(alg = "ES256", options = {}) {
|
|
216
217
|
const jose = await loadJose2();
|
|
217
|
-
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
218
|
+
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
219
|
+
extractable: options.extractable ?? false
|
|
220
|
+
});
|
|
218
221
|
const publicJwk = { ...await jose.exportJWK(publicKey) };
|
|
219
222
|
return {
|
|
220
223
|
privateKey,
|
|
@@ -938,3 +941,17 @@ function createAuthService(options) {
|
|
|
938
941
|
var import_di = require("@fluixi/start/di");
|
|
939
942
|
var AuthServiceToken = (0, import_di.injectionToken)("AuthService");
|
|
940
943
|
var AuthClientToken = (0, import_di.injectionToken)("AuthClient");
|
|
944
|
+
|
|
945
|
+
// src/module.ts
|
|
946
|
+
var import_app = require("@fluixi/start/app");
|
|
947
|
+
function authModule(auth) {
|
|
948
|
+
return (0, import_app.defineModule)({
|
|
949
|
+
name: "oauth2",
|
|
950
|
+
providers: [
|
|
951
|
+
// One instance for every request on the server. It holds no per-visitor state there:
|
|
952
|
+
// the signed-in user comes from request locals, which `sessionLocals` fills per request.
|
|
953
|
+
{ provide: AuthServiceToken, useValue: auth },
|
|
954
|
+
{ provide: AuthClientToken, useValue: auth.client }
|
|
955
|
+
]
|
|
956
|
+
});
|
|
957
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -101,4 +101,5 @@ export type { ReturnToOptions } from './return-to.js';
|
|
|
101
101
|
export { OAuthError } from './types.js';
|
|
102
102
|
export type { AuthClient, AuthConfig, BaseConfig, BrowserConfig, CallbackParams, Endpoints, LoginOptions, ServerConfig, Tokens, } from './types.js';
|
|
103
103
|
export { AuthServiceToken, AuthClientToken } from './tokens.js';
|
|
104
|
+
export { authModule } from './module.js';
|
|
104
105
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyFG;AACH,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAChE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAErF,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAExE,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EACL,cAAc,EACd,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,aAAa,GACd,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC9E,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACb,cAAc,EACd,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,MAAM,GACP,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyFG;AACH,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAChE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAErF,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAExE,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EACL,cAAc,EACd,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,aAAa,GACd,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC9E,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACb,cAAc,EACd,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,MAAM,GACP,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -97,5 +97,6 @@ export { createDpopKey, proofFor, thumbprintOf, boundKeyOf } from './dpop.js';
|
|
|
97
97
|
export { safeReturnTo } from './return-to.js';
|
|
98
98
|
export { OAuthError } from './types.js';
|
|
99
99
|
export { AuthServiceToken, AuthClientToken } from './tokens.js';
|
|
100
|
+
export { authModule } from './module.js';
|
|
100
101
|
// Token verification lives on `@fluixi/oauth2/verify`, so a browser bundle never pulls in
|
|
101
102
|
// `jose` just because the package was imported.
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! @fluixi/oauth2 v1.0.0-alpha.
|
|
2
|
-
import "./chunk-
|
|
1
|
+
/*! @fluixi/oauth2 v1.0.0-alpha.4 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
|
+
import "./chunk-5NSLG6E3.mjs";
|
|
3
3
|
|
|
4
4
|
// src/service.ts
|
|
5
5
|
import { createSession } from "@fluixi/session";
|
|
@@ -111,7 +111,7 @@ function resolveMethod(auth) {
|
|
|
111
111
|
}
|
|
112
112
|
async function loadJose() {
|
|
113
113
|
try {
|
|
114
|
-
return await import("./browser-
|
|
114
|
+
return await import("./browser-ZDO2EHPH.mjs");
|
|
115
115
|
} catch {
|
|
116
116
|
throw new OAuthError(
|
|
117
117
|
"private_key_jwt needs `jose`. Install it: npm i jose. It is an optional peer, so a client using a secret does not carry it.",
|
|
@@ -151,7 +151,7 @@ async function applyClientAuth(auth, endpoint, headers, form) {
|
|
|
151
151
|
// src/dpop.ts
|
|
152
152
|
async function loadJose2() {
|
|
153
153
|
try {
|
|
154
|
-
return await import("./browser-
|
|
154
|
+
return await import("./browser-ZDO2EHPH.mjs");
|
|
155
155
|
} catch {
|
|
156
156
|
throw new OAuthError(
|
|
157
157
|
"DPoP needs `jose`. Install it: npm i jose. It is an optional peer, so a client not using DPoP does not carry it.",
|
|
@@ -159,9 +159,11 @@ async function loadJose2() {
|
|
|
159
159
|
);
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
|
-
async function createDpopKey(alg = "ES256") {
|
|
162
|
+
async function createDpopKey(alg = "ES256", options = {}) {
|
|
163
163
|
const jose = await loadJose2();
|
|
164
|
-
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
164
|
+
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
165
|
+
extractable: options.extractable ?? false
|
|
166
|
+
});
|
|
165
167
|
const publicJwk = { ...await jose.exportJWK(publicKey) };
|
|
166
168
|
return {
|
|
167
169
|
privateKey,
|
|
@@ -885,11 +887,26 @@ function createAuthService(options) {
|
|
|
885
887
|
import { injectionToken } from "@fluixi/start/di";
|
|
886
888
|
var AuthServiceToken = injectionToken("AuthService");
|
|
887
889
|
var AuthClientToken = injectionToken("AuthClient");
|
|
890
|
+
|
|
891
|
+
// src/module.ts
|
|
892
|
+
import { defineModule } from "@fluixi/start/app";
|
|
893
|
+
function authModule(auth) {
|
|
894
|
+
return defineModule({
|
|
895
|
+
name: "oauth2",
|
|
896
|
+
providers: [
|
|
897
|
+
// One instance for every request on the server. It holds no per-visitor state there:
|
|
898
|
+
// the signed-in user comes from request locals, which `sessionLocals` fills per request.
|
|
899
|
+
{ provide: AuthServiceToken, useValue: auth },
|
|
900
|
+
{ provide: AuthClientToken, useValue: auth.client }
|
|
901
|
+
]
|
|
902
|
+
});
|
|
903
|
+
}
|
|
888
904
|
export {
|
|
889
905
|
AuthClientToken,
|
|
890
906
|
AuthServiceToken,
|
|
891
907
|
COOKIE_SESSION,
|
|
892
908
|
OAuthError,
|
|
909
|
+
authModule,
|
|
893
910
|
boundKeyOf,
|
|
894
911
|
clearDiscoveryCache,
|
|
895
912
|
createAuthService,
|
package/dist/module.cjs
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/module.ts
|
|
21
|
+
var module_exports = {};
|
|
22
|
+
__export(module_exports, {
|
|
23
|
+
authModule: () => authModule
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(module_exports);
|
|
26
|
+
var import_app = require("@fluixi/start/app");
|
|
27
|
+
|
|
28
|
+
// src/tokens.ts
|
|
29
|
+
var import_di = require("@fluixi/start/di");
|
|
30
|
+
var AuthServiceToken = (0, import_di.injectionToken)("AuthService");
|
|
31
|
+
var AuthClientToken = (0, import_di.injectionToken)("AuthClient");
|
|
32
|
+
|
|
33
|
+
// src/module.ts
|
|
34
|
+
function authModule(auth) {
|
|
35
|
+
return (0, import_app.defineModule)({
|
|
36
|
+
name: "oauth2",
|
|
37
|
+
providers: [
|
|
38
|
+
// One instance for every request on the server. It holds no per-visitor state there:
|
|
39
|
+
// the signed-in user comes from request locals, which `sessionLocals` fills per request.
|
|
40
|
+
{ provide: AuthServiceToken, useValue: auth },
|
|
41
|
+
{ provide: AuthClientToken, useValue: auth.client }
|
|
42
|
+
]
|
|
43
|
+
});
|
|
44
|
+
}
|
package/dist/module.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The app-module half of this package, listed in `src/app.config.ts`.
|
|
3
|
+
*
|
|
4
|
+
* Registers the app's service under `AuthServiceToken` and its client under
|
|
5
|
+
* `AuthClientToken` on both sides. Package code reaches the service through those tokens,
|
|
6
|
+
* `OAuthCallback` among it, because a package cannot import the app. The server half, the
|
|
7
|
+
* routes and session middleware of `tokens: 'server'`, is `authServerModule` in
|
|
8
|
+
* `@fluixi/oauth2/server`, for `app.config.server.ts`.
|
|
9
|
+
*/
|
|
10
|
+
import { type AppModule } from '@fluixi/start/app';
|
|
11
|
+
import type { AuthService } from './service.js';
|
|
12
|
+
export declare function authModule<U, P, Q>(auth: AuthService<U, P, Q>): AppModule;
|
|
13
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAUzE"}
|
package/dist/module.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The app-module half of this package, listed in `src/app.config.ts`.
|
|
3
|
+
*
|
|
4
|
+
* Registers the app's service under `AuthServiceToken` and its client under
|
|
5
|
+
* `AuthClientToken` on both sides. Package code reaches the service through those tokens,
|
|
6
|
+
* `OAuthCallback` among it, because a package cannot import the app. The server half, the
|
|
7
|
+
* routes and session middleware of `tokens: 'server'`, is `authServerModule` in
|
|
8
|
+
* `@fluixi/oauth2/server`, for `app.config.server.ts`.
|
|
9
|
+
*/
|
|
10
|
+
import { defineModule } from '@fluixi/start/app';
|
|
11
|
+
import { AuthServiceToken, AuthClientToken } from './tokens.js';
|
|
12
|
+
export function authModule(auth) {
|
|
13
|
+
return defineModule({
|
|
14
|
+
name: 'oauth2',
|
|
15
|
+
providers: [
|
|
16
|
+
// One instance for every request on the server. It holds no per-visitor state there:
|
|
17
|
+
// the signed-in user comes from request locals, which `sessionLocals` fills per request.
|
|
18
|
+
{ provide: AuthServiceToken, useValue: auth },
|
|
19
|
+
{ provide: AuthClientToken, useValue: auth.client },
|
|
20
|
+
],
|
|
21
|
+
});
|
|
22
|
+
}
|
package/dist/module.mjs
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// src/module.ts
|
|
2
|
+
import { defineModule } from "@fluixi/start/app";
|
|
3
|
+
|
|
4
|
+
// src/tokens.ts
|
|
5
|
+
import { injectionToken } from "@fluixi/start/di";
|
|
6
|
+
var AuthServiceToken = injectionToken("AuthService");
|
|
7
|
+
var AuthClientToken = injectionToken("AuthClient");
|
|
8
|
+
|
|
9
|
+
// src/module.ts
|
|
10
|
+
function authModule(auth) {
|
|
11
|
+
return defineModule({
|
|
12
|
+
name: "oauth2",
|
|
13
|
+
providers: [
|
|
14
|
+
// One instance for every request on the server. It holds no per-visitor state there:
|
|
15
|
+
// the signed-in user comes from request locals, which `sessionLocals` fills per request.
|
|
16
|
+
{ provide: AuthServiceToken, useValue: auth },
|
|
17
|
+
{ provide: AuthClientToken, useValue: auth.client }
|
|
18
|
+
]
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
authModule
|
|
23
|
+
};
|