@fluojs/passport 1.0.4 → 2.0.0
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/README.ko.md +114 -45
- package/README.md +114 -45
- package/dist/adapters/passport-js.d.ts +20 -5
- package/dist/adapters/passport-js.d.ts.map +1 -1
- package/dist/adapters/passport-js.js +32 -9
- package/dist/bearer/bearer-jwt.d.ts +90 -0
- package/dist/bearer/bearer-jwt.d.ts.map +1 -0
- package/dist/bearer/bearer-jwt.js +160 -0
- package/dist/cookie/cookie-auth-module.d.ts +7 -1
- package/dist/cookie/cookie-auth-module.d.ts.map +1 -1
- package/dist/cookie/cookie-auth-module.js +6 -0
- package/dist/cookie/cookie-auth.d.ts +6 -0
- package/dist/cookie/cookie-auth.d.ts.map +1 -1
- package/dist/cookie/cookie-auth.js +21 -3
- package/dist/cookie/cookie-manager.d.ts +15 -4
- package/dist/cookie/cookie-manager.d.ts.map +1 -1
- package/dist/cookie/cookie-manager.js +43 -44
- package/dist/guard.d.ts.map +1 -1
- package/dist/guard.js +3 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/refresh/jwt-refresh-token-adapter.d.ts.map +1 -1
- package/dist/refresh/jwt-refresh-token-adapter.js +22 -1
- package/dist/refresh/refresh-token.d.ts +53 -5
- package/dist/refresh/refresh-token.d.ts.map +1 -1
- package/dist/refresh/refresh-token.js +33 -3
- package/package.json +8 -8
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Token } from '@fluojs/core';
|
|
2
|
-
import type { GuardContext, Principal } from '@fluojs/http';
|
|
3
2
|
import type { Provider } from '@fluojs/di';
|
|
3
|
+
import type { GuardContext, Principal } from '@fluojs/http';
|
|
4
|
+
import type { OnApplicationShutdown } from '@fluojs/runtime';
|
|
4
5
|
import type { AuthHandledResult, AuthStrategy, AuthStrategyRegistration } from '../types.js';
|
|
5
6
|
/**
|
|
6
7
|
* Represents a Passport.js strategy-like object that implements
|
|
@@ -10,9 +11,14 @@ export interface PassportJsStrategyLike {
|
|
|
10
11
|
/**
|
|
11
12
|
* Performs authentication for the given request and options.
|
|
12
13
|
*
|
|
13
|
-
* @param request - The raw request
|
|
14
|
+
* @param request - The active platform adapter's raw host request when one exists,
|
|
15
|
+
* otherwise the normalized fluo request. The bridge never constructs a
|
|
16
|
+
* Passport-initialized host request.
|
|
14
17
|
* @param options - Strategy-specific authentication options.
|
|
15
|
-
* @returns
|
|
18
|
+
* @returns The bridge ignores the returned value. Strategy implementations must
|
|
19
|
+
* settle the request by calling one of the bound Passport actions (`success`,
|
|
20
|
+
* `fail`, `redirect`, `pass`, or `error`). A returned promise only propagates
|
|
21
|
+
* rejections; resolving it without calling an action fails authentication.
|
|
16
22
|
*/
|
|
17
23
|
authenticate(request: unknown, options?: unknown): unknown;
|
|
18
24
|
}
|
|
@@ -38,7 +44,10 @@ export type PassportJsPrincipalMapper = (input: PassportJsPrincipalMapperInput)
|
|
|
38
44
|
export interface PassportJsAuthStrategyOptions {
|
|
39
45
|
/** Optional options to pass to the Passport strategy's `authenticate` method. */
|
|
40
46
|
authenticateOptions?: Readonly<Record<string, unknown>>;
|
|
41
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Maximum time to wait for callback-style strategies to call a bound Passport action.
|
|
49
|
+
* Must be a non-negative finite number. A value of `0` schedules settlement on the next timer turn.
|
|
50
|
+
*/
|
|
42
51
|
actionTimeoutMs?: number;
|
|
43
52
|
/** Optional custom mapper for converting user data to a principal. */
|
|
44
53
|
mapPrincipal?: PassportJsPrincipalMapper;
|
|
@@ -55,13 +64,19 @@ export interface PassportJsStrategyBridge {
|
|
|
55
64
|
/**
|
|
56
65
|
* A bridge strategy that allows using Passport.js strategies within the fluo
|
|
57
66
|
* authentication framework.
|
|
67
|
+
*
|
|
68
|
+
* @throws {RangeError} When `actionTimeoutMs` is negative or non-finite.
|
|
58
69
|
*/
|
|
59
|
-
export declare class PassportJsAuthStrategy implements AuthStrategy {
|
|
70
|
+
export declare class PassportJsAuthStrategy implements AuthStrategy, OnApplicationShutdown {
|
|
60
71
|
private readonly strategyTemplate;
|
|
61
72
|
private readonly options;
|
|
73
|
+
private readonly actionTimeoutMs;
|
|
62
74
|
private readonly requestState;
|
|
75
|
+
private acceptingAuthentications;
|
|
63
76
|
constructor(strategyTemplate: PassportJsStrategyLike, options?: PassportJsAuthStrategyOptions);
|
|
64
77
|
authenticate(context: GuardContext): Promise<Principal | AuthHandledResult>;
|
|
78
|
+
/** Cancels every unsettled Passport.js execution when application shutdown starts. */
|
|
79
|
+
onApplicationShutdown(): void;
|
|
65
80
|
private createExecutableStrategy;
|
|
66
81
|
private settle;
|
|
67
82
|
private bindStrategyActions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"passport-js.d.ts","sourceRoot":"","sources":["../../src/adapters/passport-js.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"passport-js.d.ts","sourceRoot":"","sources":["../../src/adapters/passport-js.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAI7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAU7F;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;CAC5D;AAcD;;;GAGG;AACH,MAAM,WAAW,8BAA8B;IAC7C,iDAAiD;IACjD,OAAO,EAAE,YAAY,CAAC;IACtB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,yDAAyD;IACzD,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,8BAA8B,KAAK,SAAS,CAAC;AAE7F;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C,iFAAiF;IACjF,mBAAmB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sEAAsE;IACtE,YAAY,CAAC,EAAE,yBAAyB,CAAC;CAC1C;AAID;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,mEAAmE;IACnE,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,EAAE,wBAAwB,CAAC;CACpC;AAoGD;;;;;GAKG;AACH,qBAAa,sBAAuB,YAAW,YAAY,EAAE,qBAAqB;IAM9E,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAN1B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmE;IAChG,OAAO,CAAC,wBAAwB,CAAQ;gBAGrB,gBAAgB,EAAE,sBAAsB,EACxC,OAAO,GAAE,6BAAkC;IAW9D,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,GAAG,iBAAiB,CAAC;IAkE3E,sFAAsF;IACtF,qBAAqB,IAAI,IAAI;IAY7B,OAAO,CAAC,wBAAwB;IAmBhC,OAAO,CAAC,MAAM;IAiBd,OAAO,CAAC,mBAAmB;IAqC3B,OAAO,CAAC,kBAAkB;CAS3B;AAED;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,KAAK,CAAC,sBAAsB,CAAC,EAC5C,OAAO,GAAE,6BAAkC,GAC1C,wBAAwB,CAwB1B"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// allow: SIZE_OK — Keep the Passport.js action-binding state machine with its public bridge contracts for auditability.
|
|
2
|
+
|
|
1
3
|
import { AuthenticationFailedError, AuthenticationRequiredError } from '../errors.js';
|
|
2
4
|
import { normalizePrincipalScopes } from '../scope.js';
|
|
3
5
|
|
|
@@ -101,14 +103,26 @@ function isPromiseLike(value) {
|
|
|
101
103
|
/**
|
|
102
104
|
* A bridge strategy that allows using Passport.js strategies within the fluo
|
|
103
105
|
* authentication framework.
|
|
106
|
+
*
|
|
107
|
+
* @throws {RangeError} When `actionTimeoutMs` is negative or non-finite.
|
|
104
108
|
*/
|
|
105
109
|
export class PassportJsAuthStrategy {
|
|
106
|
-
|
|
110
|
+
actionTimeoutMs;
|
|
111
|
+
requestState = new Map();
|
|
112
|
+
acceptingAuthentications = true;
|
|
107
113
|
constructor(strategyTemplate, options = {}) {
|
|
108
114
|
this.strategyTemplate = strategyTemplate;
|
|
109
115
|
this.options = options;
|
|
116
|
+
const actionTimeoutMs = options.actionTimeoutMs ?? DEFAULT_ACTION_TIMEOUT_MS;
|
|
117
|
+
if (!Number.isFinite(actionTimeoutMs) || actionTimeoutMs < 0) {
|
|
118
|
+
throw new RangeError('Passport.js actionTimeoutMs must be a non-negative finite number.');
|
|
119
|
+
}
|
|
120
|
+
this.actionTimeoutMs = actionTimeoutMs;
|
|
110
121
|
}
|
|
111
122
|
authenticate(context) {
|
|
123
|
+
if (!this.acceptingAuthentications) {
|
|
124
|
+
return Promise.reject(new AuthenticationRequiredError('Passport strategy authentication was cancelled during application shutdown.'));
|
|
125
|
+
}
|
|
112
126
|
const response = context.requestContext.response;
|
|
113
127
|
const request = context.requestContext.request.raw ?? context.requestContext.request;
|
|
114
128
|
const strategy = this.createExecutableStrategy();
|
|
@@ -131,14 +145,11 @@ export class PassportJsAuthStrategy {
|
|
|
131
145
|
settled: false
|
|
132
146
|
});
|
|
133
147
|
this.bindStrategyActions(strategy);
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
});
|
|
140
|
-
}, actionTimeoutMs);
|
|
141
|
-
}
|
|
148
|
+
actionTimeout = setTimeout(() => {
|
|
149
|
+
this.settle(strategy, state => {
|
|
150
|
+
state.reject(new AuthenticationRequiredError('Passport strategy did not settle authentication.'));
|
|
151
|
+
});
|
|
152
|
+
}, this.actionTimeoutMs);
|
|
142
153
|
try {
|
|
143
154
|
const result = strategy.authenticate(request, this.options.authenticateOptions);
|
|
144
155
|
if (isPromiseLike(result)) {
|
|
@@ -155,11 +166,22 @@ export class PassportJsAuthStrategy {
|
|
|
155
166
|
});
|
|
156
167
|
}
|
|
157
168
|
} catch (error) {
|
|
169
|
+
// no-excuse-ok: catch — convert synchronous strategy throws to promise rejection.
|
|
158
170
|
clearActionTimeout();
|
|
159
171
|
this.settle(strategy, () => reject(error));
|
|
160
172
|
}
|
|
161
173
|
});
|
|
162
174
|
}
|
|
175
|
+
|
|
176
|
+
/** Cancels every unsettled Passport.js execution when application shutdown starts. */
|
|
177
|
+
onApplicationShutdown() {
|
|
178
|
+
this.acceptingAuthentications = false;
|
|
179
|
+
for (const strategy of this.requestState.keys()) {
|
|
180
|
+
this.settle(strategy, state => {
|
|
181
|
+
state.reject(new AuthenticationRequiredError('Passport strategy authentication was cancelled during application shutdown.'));
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
163
185
|
createExecutableStrategy() {
|
|
164
186
|
const template = this.strategyTemplate;
|
|
165
187
|
const strategy = Object.create(Object.getPrototypeOf(this.strategyTemplate));
|
|
@@ -196,6 +218,7 @@ export class PassportJsAuthStrategy {
|
|
|
196
218
|
user
|
|
197
219
|
}));
|
|
198
220
|
} catch (error) {
|
|
221
|
+
// no-excuse-ok: catch — convert mapper throws to authentication promise rejection.
|
|
199
222
|
state.reject(error);
|
|
200
223
|
}
|
|
201
224
|
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { type GuardContext } from '@fluojs/http';
|
|
2
|
+
import { DefaultJwtVerifier } from '@fluojs/jwt';
|
|
3
|
+
import type { AuthStrategy, AuthStrategyRegistration, AuthStrategyResult } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Identifies the built-in bearer JWT strategy in the `PassportModule` strategy registry.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* The name is intentionally `'jwt'` so existing routes stay on `@UseAuth('jwt')`
|
|
9
|
+
* when an application adopts the built-in preset instead of an application-owned
|
|
10
|
+
* bearer strategy.
|
|
11
|
+
*/
|
|
12
|
+
export declare const BEARER_JWT_STRATEGY_NAME = "jwt";
|
|
13
|
+
/**
|
|
14
|
+
* Authenticates requests by verifying `Authorization: Bearer <token>` credentials.
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* Credential extraction is strict and matches the documented preset contract:
|
|
18
|
+
* an absent or empty `Authorization` header (including an array-valued header
|
|
19
|
+
* whose first entry is empty) raises {@link AuthenticationRequiredError}; a
|
|
20
|
+
* wrong-scheme or malformed header raises {@link AuthenticationFailedError}.
|
|
21
|
+
* Credentials use the RFC 6750 `b64token` grammar: one or more ASCII letters,
|
|
22
|
+
* digits, `-`, `.`, `_`, `~`, `+`, or `/`, followed only by optional trailing
|
|
23
|
+
* `=` padding. Missing or malformed credentials set the bare
|
|
24
|
+
* `WWW-Authenticate: Bearer` challenge, while expired and invalid verifier
|
|
25
|
+
* failures set `WWW-Authenticate: Bearer error="invalid_token"`;
|
|
26
|
+
* an expired token raises {@link AuthenticationExpiredError} with the original
|
|
27
|
+
* `JwtExpiredTokenError` preserved as `cause`; an invalid token raises
|
|
28
|
+
* {@link AuthenticationFailedError} with the original `JwtInvalidTokenError`
|
|
29
|
+
* preserved as `cause`; JWT configuration and verifier-provider errors
|
|
30
|
+
* propagate unchanged. The Bearer scheme is matched case-insensitively per RFC
|
|
31
|
+
* 7235 and is separated from the token by one or more ASCII spaces. When an
|
|
32
|
+
* adapter surfaces an array-valued `Authorization` header, only the first entry
|
|
33
|
+
* is read.
|
|
34
|
+
*
|
|
35
|
+
* The strategy returns the normalized `JwtPrincipal` produced by
|
|
36
|
+
* `DefaultJwtVerifier.verifyAccessToken(...)` unchanged, so `subject`,
|
|
37
|
+
* `claims`, `issuer`, `audience`, `roles`, and `scopes` normalization stays
|
|
38
|
+
* owned by `@fluojs/jwt` and `AuthGuard` continues to write the principal to
|
|
39
|
+
* `requestContext.principal`.
|
|
40
|
+
*
|
|
41
|
+
* Register the class as a provider in the module that imports
|
|
42
|
+
* `PassportModule.forRoot(...)` (which also imports `JwtModule.forRoot(...)` so
|
|
43
|
+
* `DefaultJwtVerifier` resolves), and register its name with
|
|
44
|
+
* {@link createBearerJwtStrategyRegistration}.
|
|
45
|
+
*
|
|
46
|
+
* Use a custom `AuthStrategy` instead when the application needs token
|
|
47
|
+
* revocation, account-state checks, alternate extraction, or other
|
|
48
|
+
* application-owned policy beyond this contract.
|
|
49
|
+
*/
|
|
50
|
+
export declare class BearerJwtStrategy implements AuthStrategy {
|
|
51
|
+
private readonly verifier;
|
|
52
|
+
constructor(verifier: DefaultJwtVerifier);
|
|
53
|
+
authenticate(context: GuardContext): Promise<AuthStrategyResult>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Creates the passport strategy registration for the built-in bearer JWT preset.
|
|
57
|
+
*
|
|
58
|
+
* @returns The named strategy registration consumed by `PassportModule.forRoot(...)`.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* import { Module } from '@fluojs/core';
|
|
63
|
+
* import { JwtModule } from '@fluojs/jwt';
|
|
64
|
+
* import {
|
|
65
|
+
* BEARER_JWT_STRATEGY_NAME,
|
|
66
|
+
* BearerJwtStrategy,
|
|
67
|
+
* createBearerJwtStrategyRegistration,
|
|
68
|
+
* PassportModule,
|
|
69
|
+
* } from '@fluojs/passport';
|
|
70
|
+
*
|
|
71
|
+
* @Module({
|
|
72
|
+
* imports: [
|
|
73
|
+
* JwtModule.forRoot({
|
|
74
|
+
* algorithms: ['HS256'],
|
|
75
|
+
* audience: 'my-app',
|
|
76
|
+
* issuer: 'my-api',
|
|
77
|
+
* secret: 'your-secure-secret',
|
|
78
|
+
* }),
|
|
79
|
+
* PassportModule.forRoot(
|
|
80
|
+
* { defaultStrategy: BEARER_JWT_STRATEGY_NAME },
|
|
81
|
+
* [createBearerJwtStrategyRegistration()],
|
|
82
|
+
* ),
|
|
83
|
+
* ],
|
|
84
|
+
* providers: [BearerJwtStrategy],
|
|
85
|
+
* })
|
|
86
|
+
* export class AuthModule {}
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export declare function createBearerJwtStrategyRegistration(): AuthStrategyRegistration;
|
|
90
|
+
//# sourceMappingURL=bearer-jwt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bearer-jwt.d.ts","sourceRoot":"","sources":["../../src/bearer/bearer-jwt.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAA8C,MAAM,aAAa,CAAC;AAO7F,OAAO,KAAK,EAAE,YAAY,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAE9F;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,QAAQ,CAAC;AA8B9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,qBACa,iBAAkB,YAAW,YAAY;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,kBAAkB;IAEnD,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,kBAAkB,CAAC;CA+BvE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,mCAAmC,IAAI,wBAAwB,CAK9E"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
let _initClass;
|
|
2
|
+
function _applyDecs(e, t, n, r, o, i) { var a, c, u, s, f, l, p, d = Symbol.metadata || Symbol.for("Symbol.metadata"), m = Object.defineProperty, h = Object.create, y = [h(null), h(null)], v = t.length; function g(t, n, r) { return function (o, i) { n && (i = o, o = e); for (var a = 0; a < t.length; a++) i = t[a].apply(o, r ? [i] : []); return r ? i : o; }; } function b(e, t, n, r) { if ("function" != typeof e && (r || void 0 !== e)) throw new TypeError(t + " must " + (n || "be") + " a function" + (r ? "" : " or undefined")); return e; } function applyDec(e, t, n, r, o, i, u, s, f, l, p) { function d(e) { if (!p(e)) throw new TypeError("Attempted to access private element on non-instance"); } var h = [].concat(t[0]), v = t[3], w = !u, D = 1 === o, S = 3 === o, j = 4 === o, E = 2 === o; function I(t, n, r) { return function (o, i) { return n && (i = o, o = e), r && r(o), P[t].call(o, i); }; } if (!w) { var P = {}, k = [], F = S ? "get" : j || D ? "set" : "value"; if (f ? (l || D ? P = { get: _setFunctionName(function () { return v(this); }, r, "get"), set: function (e) { t[4](this, e); } } : P[F] = v, l || _setFunctionName(P[F], r, E ? "" : F)) : l || (P = Object.getOwnPropertyDescriptor(e, r)), !l && !f) { if ((c = y[+s][r]) && 7 !== (c ^ o)) throw Error("Decorating two elements with the same name (" + P[F].name + ") is not supported yet"); y[+s][r] = o < 3 ? 1 : o; } } for (var N = e, O = h.length - 1; O >= 0; O -= n ? 2 : 1) { var T = b(h[O], "A decorator", "be", !0), z = n ? h[O - 1] : void 0, A = {}, H = { kind: ["field", "accessor", "method", "getter", "setter", "class"][o], name: r, metadata: a, addInitializer: function (e, t) { if (e.v) throw new TypeError("attempted to call addInitializer after decoration was finished"); b(t, "An initializer", "be", !0), i.push(t); }.bind(null, A) }; if (w) c = T.call(z, N, H), A.v = 1, b(c, "class decorators", "return") && (N = c);else if (H.static = s, H.private = f, c = H.access = { has: f ? p.bind() : function (e) { return r in e; } }, j || (c.get = f ? E ? function (e) { return d(e), P.value; } : I("get", 0, d) : function (e) { return e[r]; }), E || S || (c.set = f ? I("set", 0, d) : function (e, t) { e[r] = t; }), N = T.call(z, D ? { get: P.get, set: P.set } : P[F], H), A.v = 1, D) { if ("object" == typeof N && N) (c = b(N.get, "accessor.get")) && (P.get = c), (c = b(N.set, "accessor.set")) && (P.set = c), (c = b(N.init, "accessor.init")) && k.unshift(c);else if (void 0 !== N) throw new TypeError("accessor decorators must return an object with get, set, or init properties or undefined"); } else b(N, (l ? "field" : "method") + " decorators", "return") && (l ? k.unshift(N) : P[F] = N); } return o < 2 && u.push(g(k, s, 1), g(i, s, 0)), l || w || (f ? D ? u.splice(-1, 0, I("get", s), I("set", s)) : u.push(E ? P[F] : b.call.bind(P[F])) : m(e, r, P)), N; } function w(e) { return m(e, d, { configurable: !0, enumerable: !0, value: a }); } return void 0 !== i && (a = i[d]), a = h(null == a ? null : a), f = [], l = function (e) { e && f.push(g(e)); }, p = function (t, r) { for (var i = 0; i < n.length; i++) { var a = n[i], c = a[1], l = 7 & c; if ((8 & c) == t && !l == r) { var p = a[2], d = !!a[3], m = 16 & c; applyDec(t ? e : e.prototype, a, m, d ? "#" + p : _toPropertyKey(p), l, l < 2 ? [] : t ? s = s || [] : u = u || [], f, !!t, d, r, t && d ? function (t) { return _checkInRHS(t) === e; } : o); } } }, p(8, 0), p(0, 0), p(8, 1), p(0, 1), l(u), l(s), c = f, v || w(e), { e: c, get c() { var n = []; return v && [w(e = applyDec(e, [t], r, e.name, 5, n)), g(n, 1)]; } }; }
|
|
3
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
4
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
5
|
+
function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
|
|
6
|
+
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
|
|
7
|
+
import { Inject } from '@fluojs/core';
|
|
8
|
+
import { getRequestHeader } from '@fluojs/http';
|
|
9
|
+
import { DefaultJwtVerifier, JwtExpiredTokenError, JwtInvalidTokenError } from '@fluojs/jwt';
|
|
10
|
+
import { AuthenticationExpiredError, AuthenticationFailedError, AuthenticationRequiredError } from '../errors.js';
|
|
11
|
+
/**
|
|
12
|
+
* Identifies the built-in bearer JWT strategy in the `PassportModule` strategy registry.
|
|
13
|
+
*
|
|
14
|
+
* @remarks
|
|
15
|
+
* The name is intentionally `'jwt'` so existing routes stay on `@UseAuth('jwt')`
|
|
16
|
+
* when an application adopts the built-in preset instead of an application-owned
|
|
17
|
+
* bearer strategy.
|
|
18
|
+
*/
|
|
19
|
+
export const BEARER_JWT_STRATEGY_NAME = 'jwt';
|
|
20
|
+
const BEARER_CREDENTIAL = /^Bearer +([A-Za-z0-9\-._~+/]+=*)$/i;
|
|
21
|
+
function isNonEmptyString(value) {
|
|
22
|
+
return typeof value === 'string' && value.length > 0;
|
|
23
|
+
}
|
|
24
|
+
function parseBearerCredential(authorization) {
|
|
25
|
+
return BEARER_CREDENTIAL.exec(authorization)?.[1];
|
|
26
|
+
}
|
|
27
|
+
function addBearerChallenge(context, value = 'Bearer') {
|
|
28
|
+
context.requestContext.response?.setHeader('WWW-Authenticate', value);
|
|
29
|
+
}
|
|
30
|
+
function readAuthorizationHeader(context) {
|
|
31
|
+
const value = getRequestHeader(context.requestContext.request, 'Authorization');
|
|
32
|
+
if (isNonEmptyString(value)) {
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
if (Array.isArray(value) && isNonEmptyString(value[0])) {
|
|
36
|
+
return value[0];
|
|
37
|
+
}
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Authenticates requests by verifying `Authorization: Bearer <token>` credentials.
|
|
43
|
+
*
|
|
44
|
+
* @remarks
|
|
45
|
+
* Credential extraction is strict and matches the documented preset contract:
|
|
46
|
+
* an absent or empty `Authorization` header (including an array-valued header
|
|
47
|
+
* whose first entry is empty) raises {@link AuthenticationRequiredError}; a
|
|
48
|
+
* wrong-scheme or malformed header raises {@link AuthenticationFailedError}.
|
|
49
|
+
* Credentials use the RFC 6750 `b64token` grammar: one or more ASCII letters,
|
|
50
|
+
* digits, `-`, `.`, `_`, `~`, `+`, or `/`, followed only by optional trailing
|
|
51
|
+
* `=` padding. Missing or malformed credentials set the bare
|
|
52
|
+
* `WWW-Authenticate: Bearer` challenge, while expired and invalid verifier
|
|
53
|
+
* failures set `WWW-Authenticate: Bearer error="invalid_token"`;
|
|
54
|
+
* an expired token raises {@link AuthenticationExpiredError} with the original
|
|
55
|
+
* `JwtExpiredTokenError` preserved as `cause`; an invalid token raises
|
|
56
|
+
* {@link AuthenticationFailedError} with the original `JwtInvalidTokenError`
|
|
57
|
+
* preserved as `cause`; JWT configuration and verifier-provider errors
|
|
58
|
+
* propagate unchanged. The Bearer scheme is matched case-insensitively per RFC
|
|
59
|
+
* 7235 and is separated from the token by one or more ASCII spaces. When an
|
|
60
|
+
* adapter surfaces an array-valued `Authorization` header, only the first entry
|
|
61
|
+
* is read.
|
|
62
|
+
*
|
|
63
|
+
* The strategy returns the normalized `JwtPrincipal` produced by
|
|
64
|
+
* `DefaultJwtVerifier.verifyAccessToken(...)` unchanged, so `subject`,
|
|
65
|
+
* `claims`, `issuer`, `audience`, `roles`, and `scopes` normalization stays
|
|
66
|
+
* owned by `@fluojs/jwt` and `AuthGuard` continues to write the principal to
|
|
67
|
+
* `requestContext.principal`.
|
|
68
|
+
*
|
|
69
|
+
* Register the class as a provider in the module that imports
|
|
70
|
+
* `PassportModule.forRoot(...)` (which also imports `JwtModule.forRoot(...)` so
|
|
71
|
+
* `DefaultJwtVerifier` resolves), and register its name with
|
|
72
|
+
* {@link createBearerJwtStrategyRegistration}.
|
|
73
|
+
*
|
|
74
|
+
* Use a custom `AuthStrategy` instead when the application needs token
|
|
75
|
+
* revocation, account-state checks, alternate extraction, or other
|
|
76
|
+
* application-owned policy beyond this contract.
|
|
77
|
+
*/
|
|
78
|
+
let _BearerJwtStrategy;
|
|
79
|
+
class BearerJwtStrategy {
|
|
80
|
+
static {
|
|
81
|
+
[_BearerJwtStrategy, _initClass] = _applyDecs(this, [Inject(DefaultJwtVerifier)], []).c;
|
|
82
|
+
}
|
|
83
|
+
constructor(verifier) {
|
|
84
|
+
this.verifier = verifier;
|
|
85
|
+
}
|
|
86
|
+
async authenticate(context) {
|
|
87
|
+
const authorization = readAuthorizationHeader(context);
|
|
88
|
+
if (!authorization) {
|
|
89
|
+
addBearerChallenge(context);
|
|
90
|
+
throw new AuthenticationRequiredError('Authorization header is required.');
|
|
91
|
+
}
|
|
92
|
+
const token = parseBearerCredential(authorization);
|
|
93
|
+
if (!token) {
|
|
94
|
+
addBearerChallenge(context);
|
|
95
|
+
throw new AuthenticationFailedError('Authorization header must use Bearer token format.');
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
return await this.verifier.verifyAccessToken(token);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
if (error instanceof JwtExpiredTokenError) {
|
|
101
|
+
addBearerChallenge(context, 'Bearer error="invalid_token"');
|
|
102
|
+
throw new AuthenticationExpiredError('Access token has expired.', {
|
|
103
|
+
cause: error
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
if (error instanceof JwtInvalidTokenError) {
|
|
107
|
+
addBearerChallenge(context, 'Bearer error="invalid_token"');
|
|
108
|
+
throw new AuthenticationFailedError('Access token verification failed.', {
|
|
109
|
+
cause: error
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
static {
|
|
116
|
+
_initClass();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Creates the passport strategy registration for the built-in bearer JWT preset.
|
|
122
|
+
*
|
|
123
|
+
* @returns The named strategy registration consumed by `PassportModule.forRoot(...)`.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* import { Module } from '@fluojs/core';
|
|
128
|
+
* import { JwtModule } from '@fluojs/jwt';
|
|
129
|
+
* import {
|
|
130
|
+
* BEARER_JWT_STRATEGY_NAME,
|
|
131
|
+
* BearerJwtStrategy,
|
|
132
|
+
* createBearerJwtStrategyRegistration,
|
|
133
|
+
* PassportModule,
|
|
134
|
+
* } from '@fluojs/passport';
|
|
135
|
+
*
|
|
136
|
+
* @Module({
|
|
137
|
+
* imports: [
|
|
138
|
+
* JwtModule.forRoot({
|
|
139
|
+
* algorithms: ['HS256'],
|
|
140
|
+
* audience: 'my-app',
|
|
141
|
+
* issuer: 'my-api',
|
|
142
|
+
* secret: 'your-secure-secret',
|
|
143
|
+
* }),
|
|
144
|
+
* PassportModule.forRoot(
|
|
145
|
+
* { defaultStrategy: BEARER_JWT_STRATEGY_NAME },
|
|
146
|
+
* [createBearerJwtStrategyRegistration()],
|
|
147
|
+
* ),
|
|
148
|
+
* ],
|
|
149
|
+
* providers: [BearerJwtStrategy],
|
|
150
|
+
* })
|
|
151
|
+
* export class AuthModule {}
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
export { _BearerJwtStrategy as BearerJwtStrategy };
|
|
155
|
+
export function createBearerJwtStrategyRegistration() {
|
|
156
|
+
return {
|
|
157
|
+
name: BEARER_JWT_STRATEGY_NAME,
|
|
158
|
+
token: _BearerJwtStrategy
|
|
159
|
+
};
|
|
160
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Provider } from '@fluojs/di';
|
|
2
2
|
import { type ModuleType } from '@fluojs/runtime';
|
|
3
|
+
import type { AuthStrategyRegistration } from '../types.js';
|
|
3
4
|
import { type CookieAuthOptions } from './cookie-auth.js';
|
|
4
5
|
import { type CookieManagerConfig } from './cookie-manager.js';
|
|
5
|
-
import type { AuthStrategyRegistration } from '../types.js';
|
|
6
6
|
type CookieAuthModuleType = ModuleType;
|
|
7
7
|
/**
|
|
8
8
|
* Configures the built-in cookie-auth strategy and cookie manager preset.
|
|
@@ -40,6 +40,7 @@ export declare class CookieAuthModule {
|
|
|
40
40
|
* @example
|
|
41
41
|
* ```ts
|
|
42
42
|
* import { Module } from '@fluojs/core';
|
|
43
|
+
* import { JwtModule } from '@fluojs/jwt';
|
|
43
44
|
* import {
|
|
44
45
|
* CookieAuthModule,
|
|
45
46
|
* CookieAuthStrategy,
|
|
@@ -50,6 +51,11 @@ export declare class CookieAuthModule {
|
|
|
50
51
|
* @Module({
|
|
51
52
|
* imports: [
|
|
52
53
|
* CookieAuthModule.forRoot(),
|
|
54
|
+
* JwtModule.forRoot({
|
|
55
|
+
* algorithms: ['HS256'],
|
|
56
|
+
* global: true,
|
|
57
|
+
* secret: 'your-secure-secret',
|
|
58
|
+
* }),
|
|
53
59
|
* PassportModule.forRoot(
|
|
54
60
|
* { defaultStrategy: COOKIE_AUTH_STRATEGY_NAME },
|
|
55
61
|
* [{ name: COOKIE_AUTH_STRATEGY_NAME, token: CookieAuthStrategy }],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cookie-auth-module.d.ts","sourceRoot":"","sources":["../../src/cookie/cookie-auth-module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"cookie-auth-module.d.ts","sourceRoot":"","sources":["../../src/cookie/cookie-auth-module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAGL,KAAK,iBAAiB,EAEvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAiB,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE9E,KAAK,oBAAoB,GAAG,UAAU,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,aAAa,CAAC,EAAE,mBAAmB,CAAC;CACrC;AAiBD;;;;GAIG;AACH,wBAAgB,oCAAoC,IAAI,wBAAwB,CAK/E;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,CAAC,EAAE,sBAAsB,GAAG;IACvE,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,EAAE,wBAAwB,CAAC;CACpC,CAKA;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,sBAAsB,GAAG,oBAAoB;CAQtE"}
|
|
@@ -55,6 +55,7 @@ export class CookieAuthModule {
|
|
|
55
55
|
* @example
|
|
56
56
|
* ```ts
|
|
57
57
|
* import { Module } from '@fluojs/core';
|
|
58
|
+
* import { JwtModule } from '@fluojs/jwt';
|
|
58
59
|
* import {
|
|
59
60
|
* CookieAuthModule,
|
|
60
61
|
* CookieAuthStrategy,
|
|
@@ -65,6 +66,11 @@ export class CookieAuthModule {
|
|
|
65
66
|
* @Module({
|
|
66
67
|
* imports: [
|
|
67
68
|
* CookieAuthModule.forRoot(),
|
|
69
|
+
* JwtModule.forRoot({
|
|
70
|
+
* algorithms: ['HS256'],
|
|
71
|
+
* global: true,
|
|
72
|
+
* secret: 'your-secure-secret',
|
|
73
|
+
* }),
|
|
68
74
|
* PassportModule.forRoot(
|
|
69
75
|
* { defaultStrategy: COOKIE_AUTH_STRATEGY_NAME },
|
|
70
76
|
* [{ name: COOKIE_AUTH_STRATEGY_NAME, token: CookieAuthStrategy }],
|
|
@@ -31,6 +31,12 @@ export declare function normalizeCookieAuthOptions(options?: CookieAuthOptions):
|
|
|
31
31
|
* When `requireAccessToken` is `false`, missing cookies now resolve to an explicit
|
|
32
32
|
* unauthenticated result. Protected routes still reject that result unless they opt in
|
|
33
33
|
* with `@UseOptionalAuth(...)`.
|
|
34
|
+
*
|
|
35
|
+
* Verifier failures keep the documented typed-error classification: expired access
|
|
36
|
+
* tokens raise {@link AuthenticationExpiredError}, invalid access tokens raise
|
|
37
|
+
* {@link AuthenticationFailedError}, and missing or malformed cookies raise
|
|
38
|
+
* {@link AuthenticationRequiredError}. `AuthGuard` still responds with HTTP 401 for
|
|
39
|
+
* every variant while preserving the typed error as the cause.
|
|
34
40
|
*/
|
|
35
41
|
export declare class CookieAuthStrategy implements AuthStrategy {
|
|
36
42
|
private readonly verifier;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cookie-auth.d.ts","sourceRoot":"","sources":["../../src/cookie/cookie-auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"cookie-auth.d.ts","sourceRoot":"","sources":["../../src/cookie/cookie-auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAA8C,MAAM,aAAa,CAAC;AAO7F,OAAO,KAAK,EAAsB,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAUxF;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAkD,CAAC;AAEnF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;GAEG;AACH,eAAO,MAAM,2BAA2B,EAAE,QAAQ,CAAC,iBAAiB,CAInE,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAMnG;AAED;;;;;;;;;;;;;GAaG;AACH,qBACa,kBAAmB,YAAW,YAAY;IAInD,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAH3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;gBAGnC,QAAQ,EAAE,kBAAkB,EAC7C,OAAO,CAAC,EAAE,iBAAiB;IAKvB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAqDvE;AAED;;GAEG;AACH,eAAO,MAAM,yBAAyB,WAAW,CAAC"}
|
|
@@ -5,8 +5,8 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
|
|
|
5
5
|
function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
|
|
6
6
|
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
|
|
7
7
|
import { Inject } from '@fluojs/core';
|
|
8
|
-
import { DefaultJwtVerifier } from '@fluojs/jwt';
|
|
9
|
-
import { AuthenticationRequiredError } from '../errors.js';
|
|
8
|
+
import { DefaultJwtVerifier, JwtExpiredTokenError, JwtInvalidTokenError } from '@fluojs/jwt';
|
|
9
|
+
import { AuthenticationExpiredError, AuthenticationFailedError, AuthenticationRequiredError } from '../errors.js';
|
|
10
10
|
const unauthenticatedCookieAuthResult = {
|
|
11
11
|
authenticated: false
|
|
12
12
|
};
|
|
@@ -53,6 +53,12 @@ export function normalizeCookieAuthOptions(options) {
|
|
|
53
53
|
* When `requireAccessToken` is `false`, missing cookies now resolve to an explicit
|
|
54
54
|
* unauthenticated result. Protected routes still reject that result unless they opt in
|
|
55
55
|
* with `@UseOptionalAuth(...)`.
|
|
56
|
+
*
|
|
57
|
+
* Verifier failures keep the documented typed-error classification: expired access
|
|
58
|
+
* tokens raise {@link AuthenticationExpiredError}, invalid access tokens raise
|
|
59
|
+
* {@link AuthenticationFailedError}, and missing or malformed cookies raise
|
|
60
|
+
* {@link AuthenticationRequiredError}. `AuthGuard` still responds with HTTP 401 for
|
|
61
|
+
* every variant while preserving the typed error as the cause.
|
|
56
62
|
*/
|
|
57
63
|
let _CookieAuthStrategy;
|
|
58
64
|
class CookieAuthStrategy {
|
|
@@ -94,8 +100,20 @@ class CookieAuthStrategy {
|
|
|
94
100
|
subject: principal.subject
|
|
95
101
|
};
|
|
96
102
|
} catch (error) {
|
|
103
|
+
if (error instanceof JwtExpiredTokenError) {
|
|
104
|
+
throw new AuthenticationExpiredError('Access token has expired.', {
|
|
105
|
+
cause: error
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (error instanceof JwtInvalidTokenError) {
|
|
109
|
+
throw new AuthenticationFailedError('Access token is invalid.', {
|
|
110
|
+
cause: error
|
|
111
|
+
});
|
|
112
|
+
}
|
|
97
113
|
if (error instanceof Error) {
|
|
98
|
-
throw new AuthenticationRequiredError(error.message
|
|
114
|
+
throw new AuthenticationRequiredError(error.message, {
|
|
115
|
+
cause: error
|
|
116
|
+
});
|
|
99
117
|
}
|
|
100
118
|
throw new AuthenticationRequiredError('Access token verification failed.');
|
|
101
119
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type FrameworkResponse } from '@fluojs/http';
|
|
2
2
|
import { type CookieAuthOptions } from './cookie-auth.js';
|
|
3
3
|
/**
|
|
4
4
|
* Describes the cookie options contract.
|
|
@@ -12,7 +12,13 @@ export interface CookieOptions {
|
|
|
12
12
|
maxAge?: number;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
* Describes the set cookie options contract.
|
|
15
|
+
* Describes the set cookie options contract accepted by {@link CookieManagerConfig}.
|
|
16
|
+
*
|
|
17
|
+
* @remarks
|
|
18
|
+
* `accessTokenTtlSeconds` and `refreshTokenTtlSeconds` become the default `Max-Age`
|
|
19
|
+
* for the matching token cookie when the positional TTL argument of
|
|
20
|
+
* `CookieManager.setAccessTokenCookie(...)` / `setRefreshTokenCookie(...)` is omitted.
|
|
21
|
+
* An explicit positional TTL always wins over these defaults.
|
|
16
22
|
*/
|
|
17
23
|
export interface SetCookieOptions extends CookieOptions {
|
|
18
24
|
accessTokenTtlSeconds?: number;
|
|
@@ -22,7 +28,10 @@ export interface SetCookieOptions extends CookieOptions {
|
|
|
22
28
|
* Describes the cookie manager config contract.
|
|
23
29
|
*/
|
|
24
30
|
export interface CookieManagerConfig extends CookieAuthOptions {
|
|
25
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Response-cookie defaults, including optional per-token TTL defaults.
|
|
33
|
+
*/
|
|
34
|
+
cookieOptions?: SetCookieOptions;
|
|
26
35
|
}
|
|
27
36
|
type NormalizedCookieOptions = Omit<Required<CookieOptions>, 'domain' | 'maxAge'> & Pick<CookieOptions, 'domain' | 'maxAge'>;
|
|
28
37
|
/**
|
|
@@ -35,6 +44,8 @@ export declare const DEFAULT_COOKIE_OPTIONS: NormalizedCookieOptions;
|
|
|
35
44
|
export declare class CookieManager {
|
|
36
45
|
private readonly options;
|
|
37
46
|
private readonly cookieOptions;
|
|
47
|
+
private readonly accessTokenTtlSeconds;
|
|
48
|
+
private readonly refreshTokenTtlSeconds;
|
|
38
49
|
constructor(config?: CookieManagerConfig);
|
|
39
50
|
setAccessTokenCookie(response: FrameworkResponse, token: string, ttlSeconds?: number): void;
|
|
40
51
|
setRefreshTokenCookie(response: FrameworkResponse, token: string, ttlSeconds?: number): void;
|
|
@@ -42,7 +53,7 @@ export declare class CookieManager {
|
|
|
42
53
|
clearRefreshTokenCookie(response: FrameworkResponse): void;
|
|
43
54
|
clearAllCookies(response: FrameworkResponse): void;
|
|
44
55
|
setAuthCookies(response: FrameworkResponse, accessToken: string, accessTokenTtlSeconds?: number, refreshToken?: string, refreshTokenTtlSeconds?: number): void;
|
|
45
|
-
private
|
|
56
|
+
private writeCookie;
|
|
46
57
|
}
|
|
47
58
|
/**
|
|
48
59
|
* Create cookie manager.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cookie-manager.d.ts","sourceRoot":"","sources":["../../src/cookie/cookie-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"cookie-manager.d.ts","sourceRoot":"","sources":["../../src/cookie/cookie-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAa,MAAM,cAAc,CAAC;AAEjE,OAAO,EAAE,KAAK,iBAAiB,EAA8B,MAAM,kBAAkB,CAAC;AAEtF;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC5D;;OAEG;IACH,aAAa,CAAC,EAAE,gBAAgB,CAAC;CAClC;AAED,KAAK,uBAAuB,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC,GAC/E,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,QAAQ,CAAC,CAAC;AAQ3C;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,uBAOpC,CAAC;AAuBF;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA0B;IACxD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAqB;IAC3D,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAqB;gBAEhD,MAAM,CAAC,EAAE,mBAAmB;IAcxC,oBAAoB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAQ3F,qBAAqB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAQ5F,sBAAsB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAQzD,uBAAuB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAQ1D,eAAe,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAKlD,cAAc,CACZ,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,MAAM,EACnB,qBAAqB,CAAC,EAAE,MAAM,EAC9B,YAAY,CAAC,EAAE,MAAM,EACrB,sBAAsB,CAAC,EAAE,MAAM,GAC9B,IAAI;IAQP,OAAO,CAAC,WAAW;CA2BpB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,mBAAmB,GAAG,aAAa,CAE/E"}
|