@c9up/warden 0.1.6 → 0.1.8
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/AuthManager.d.ts +13 -0
- package/dist/AuthManager.d.ts.map +1 -1
- package/dist/AuthManager.js +29 -0
- package/dist/AuthManager.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/strategies/JwtStrategy.d.ts +25 -1
- package/dist/strategies/JwtStrategy.d.ts.map +1 -1
- package/dist/strategies/JwtStrategy.js +4 -1
- package/dist/strategies/JwtStrategy.js.map +1 -1
- package/index.darwin-arm64.node +0 -0
- package/index.darwin-x64.node +0 -0
- package/index.linux-arm64-gnu.node +0 -0
- package/index.linux-x64-gnu.node +0 -0
- package/index.win32-x64-msvc.node +0 -0
- package/package.json +1 -1
- package/src/AuthManager.ts +42 -0
- package/src/index.ts +1 -1
- package/src/strategies/JwtStrategy.ts +24 -7
package/dist/AuthManager.d.ts
CHANGED
|
@@ -53,6 +53,19 @@ export declare class AuthManager {
|
|
|
53
53
|
authenticate(credentials: Record<string, unknown>, strategyName?: string): Promise<AuthResult>;
|
|
54
54
|
/** Verify a token (JWT, session, API key). */
|
|
55
55
|
verify(token: string, strategyName?: string, context?: Record<string, unknown>): Promise<AuthResult>;
|
|
56
|
+
/**
|
|
57
|
+
* Mint a token for an ALREADY-resolved user — the "login-as-known-user"
|
|
58
|
+
* path (e.g. straight after signup created the row in the app's own
|
|
59
|
+
* transaction). Skips the credential check `authenticate()` performs, so no
|
|
60
|
+
* redundant bcrypt / DB lookup, and the app never has to reach into the
|
|
61
|
+
* strategy internals.
|
|
62
|
+
*
|
|
63
|
+
* The token is byte-for-byte what `authenticate()` would emit for the same
|
|
64
|
+
* `user` (it delegates to the same `signToken`), so the claims — sub / roles
|
|
65
|
+
* / permissions / iat / exp / jti — are identical. Throws if the resolved
|
|
66
|
+
* strategy can't issue tokens (e.g. session / API-key strategies).
|
|
67
|
+
*/
|
|
68
|
+
issueFor(user: UserPayload, strategyName?: string): string;
|
|
56
69
|
/**
|
|
57
70
|
* Resolve a user's effective permissions for a scope (Epic 56). The single
|
|
58
71
|
* resolution entry the coarse helpers wrap — `hasRole`/`hasPermission`/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthManager.d.ts","sourceRoot":"","sources":["../src/AuthManager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAErE,MAAM,WAAW,WAAW;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACxE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC9E;AAED,MAAM,WAAW,UAAU;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACzC;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;CACxB;
|
|
1
|
+
{"version":3,"file":"AuthManager.d.ts","sourceRoot":"","sources":["../src/AuthManager.ts"],"names":[],"mappings":"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"}
|
package/dist/AuthManager.js
CHANGED
|
@@ -6,6 +6,14 @@
|
|
|
6
6
|
import { WardenError } from "./errors.js";
|
|
7
7
|
import { MemoryRightsStore } from "./rights/MemoryRightsStore.js";
|
|
8
8
|
import { RightsResolver } from "./rights/RightsResolver.js";
|
|
9
|
+
/**
|
|
10
|
+
* Capability check for {@link AuthManager.issueFor}. `signToken` is not on the
|
|
11
|
+
* `AuthStrategy` interface (only token-minting strategies have it), so narrow
|
|
12
|
+
* via `in` + `typeof` — no cast.
|
|
13
|
+
*/
|
|
14
|
+
function isTokenIssuer(strategy) {
|
|
15
|
+
return "signToken" in strategy && typeof strategy.signToken === "function";
|
|
16
|
+
}
|
|
9
17
|
/**
|
|
10
18
|
* Manages authentication strategies and provides guard/permission checks.
|
|
11
19
|
*/
|
|
@@ -75,6 +83,27 @@ export class AuthManager {
|
|
|
75
83
|
};
|
|
76
84
|
}
|
|
77
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Mint a token for an ALREADY-resolved user — the "login-as-known-user"
|
|
88
|
+
* path (e.g. straight after signup created the row in the app's own
|
|
89
|
+
* transaction). Skips the credential check `authenticate()` performs, so no
|
|
90
|
+
* redundant bcrypt / DB lookup, and the app never has to reach into the
|
|
91
|
+
* strategy internals.
|
|
92
|
+
*
|
|
93
|
+
* The token is byte-for-byte what `authenticate()` would emit for the same
|
|
94
|
+
* `user` (it delegates to the same `signToken`), so the claims — sub / roles
|
|
95
|
+
* / permissions / iat / exp / jti — are identical. Throws if the resolved
|
|
96
|
+
* strategy can't issue tokens (e.g. session / API-key strategies).
|
|
97
|
+
*/
|
|
98
|
+
issueFor(user, strategyName) {
|
|
99
|
+
const strategy = this.getStrategy(strategyName);
|
|
100
|
+
if (!isTokenIssuer(strategy)) {
|
|
101
|
+
throw new WardenError("STRATEGY_CANNOT_ISSUE", `Auth strategy '${strategyName ?? this.defaultStrategy}' cannot issue tokens.`, {
|
|
102
|
+
hint: "issueFor() needs a token-minting strategy (e.g. JwtStrategy with signToken). Session / API-key strategies don't mint tokens.",
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return strategy.signToken(user);
|
|
106
|
+
}
|
|
78
107
|
/**
|
|
79
108
|
* Resolve a user's effective permissions for a scope (Epic 56). The single
|
|
80
109
|
* resolution entry the coarse helpers wrap — `hasRole`/`hasPermission`/
|
package/dist/AuthManager.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthManager.js","sourceRoot":"","sources":["../src/AuthManager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthManager.js","sourceRoot":"","sources":["../src/AuthManager.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ export type { EffectivePermissions, RightsStore, Scope, } from "./rights/types.j
|
|
|
43
43
|
export { scopeKey } from "./rights/types.js";
|
|
44
44
|
export type { ApiKeyConfig } from "./strategies/ApiKeyStrategy.js";
|
|
45
45
|
export { ApiKeyStrategy } from "./strategies/ApiKeyStrategy.js";
|
|
46
|
-
export type { JwtStrategyConfig } from "./strategies/JwtStrategy.js";
|
|
46
|
+
export type { JwtClaims, JwtStrategyConfig } from "./strategies/JwtStrategy.js";
|
|
47
47
|
export { generateJwtSecret, JwtStrategy } from "./strategies/JwtStrategy.js";
|
|
48
48
|
export type { SessionStore, SessionStrategyConfig, } from "./strategies/SessionStrategy.js";
|
|
49
49
|
export { SessionStrategy } from "./strategies/SessionStrategy.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,22 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { AuthResult, AuthStrategy, UserPayload } from "../AuthManager.js";
|
|
6
6
|
import type { TokenBlacklist } from "../TokenBlacklist.js";
|
|
7
|
+
/**
|
|
8
|
+
* The verified JWT claims. Passed to `findUser` as the second argument so an app
|
|
9
|
+
* can reject a token on more than `sub` — e.g. compare `iat` to a stored
|
|
10
|
+
* `passwordChangedAt` (kill sessions on reset), check a `tokenVersion` custom
|
|
11
|
+
* claim, or honour the `jti` directly. Return `null` from `findUser` to reject.
|
|
12
|
+
*/
|
|
13
|
+
export interface JwtClaims {
|
|
14
|
+
sub: string;
|
|
15
|
+
roles?: string[];
|
|
16
|
+
permissions?: string[];
|
|
17
|
+
iat: number;
|
|
18
|
+
exp: number;
|
|
19
|
+
/** RFC 7519 JWT ID — populated at sign time so revocation can target a single token. */
|
|
20
|
+
jti: string;
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}
|
|
7
23
|
export interface JwtStrategyConfig {
|
|
8
24
|
/**
|
|
9
25
|
* Active signing secret. New tokens are always signed with this key.
|
|
@@ -19,7 +35,15 @@ export interface JwtStrategyConfig {
|
|
|
19
35
|
*/
|
|
20
36
|
previousSecrets?: readonly string[];
|
|
21
37
|
expiresInSeconds?: number;
|
|
22
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Resolve the user for a verified token. Receives the token `sub` AND the
|
|
40
|
+
* full verified `claims` — use the claims to enforce session invalidation
|
|
41
|
+
* the strategy can't know about (e.g. reject when `claims.iat` predates the
|
|
42
|
+
* user's `passwordChangedAt`, or a `claims.tokenVersion` is stale) by
|
|
43
|
+
* returning `null`. The second arg is optional for callers that only need
|
|
44
|
+
* the id (existing one-arg `findUser` functions stay valid).
|
|
45
|
+
*/
|
|
46
|
+
findUser: (id: string, claims: JwtClaims) => Promise<UserPayload | null>;
|
|
23
47
|
verifyCredentials: (email: string, password: string) => Promise<UserPayload | null>;
|
|
24
48
|
/**
|
|
25
49
|
* Optional blacklist for revocation. When supplied, `verify` rejects
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JwtStrategy.d.ts","sourceRoot":"","sources":["../../src/strategies/JwtStrategy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE/E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"JwtStrategy.d.ts","sourceRoot":"","sources":["../../src/strategies/JwtStrategy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE/E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,wFAAwF;IACxF,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AA6BD,MAAM,WAAW,iBAAiB;IACjC;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;OAOG;IACH,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACzE,iBAAiB,EAAE,CAClB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,KACZ,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACjC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,qBAAa,WAAY,YAAW,YAAY;;IAC/C,IAAI,SAAS;gBAaD,MAAM,EAAE,iBAAiB;IAgC/B,YAAY,CACjB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,OAAO,CAAC,UAAU,CAAC;IAkBhB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAmChD,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM;IAepC;;;;;;;;OAQG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAa7C;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
|
|
@@ -104,7 +104,10 @@ export class JwtStrategy {
|
|
|
104
104
|
return { authenticated: false, error: "Token revoked" };
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
|
-
|
|
107
|
+
// Pass the FULL verified claims (not just `sub`) so the app can reject
|
|
108
|
+
// stale tokens it alone can judge — iat vs passwordChangedAt, tokenVersion,
|
|
109
|
+
// etc. — by returning null. This is the session-invalidation seam.
|
|
110
|
+
const user = await this.#findUser(payload.sub, payload);
|
|
108
111
|
if (!user) {
|
|
109
112
|
return { authenticated: false, error: "User not found" };
|
|
110
113
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JwtStrategy.js","sourceRoot":"","sources":["../../src/strategies/JwtStrategy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"JwtStrategy.js","sourceRoot":"","sources":["../../src/strategies/JwtStrategy.ts"],"names":[],"mappings":"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"}
|
package/index.darwin-arm64.node
CHANGED
|
Binary file
|
package/index.darwin-x64.node
CHANGED
|
Binary file
|
|
Binary file
|
package/index.linux-x64-gnu.node
CHANGED
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
package/src/AuthManager.ts
CHANGED
|
@@ -49,6 +49,22 @@ export interface AuthConfig {
|
|
|
49
49
|
rights?: RightsResolver;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
/** A strategy that can mint a token for a resolved user (e.g. JwtStrategy). */
|
|
53
|
+
interface TokenIssuer {
|
|
54
|
+
signToken(user: UserPayload): string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Capability check for {@link AuthManager.issueFor}. `signToken` is not on the
|
|
59
|
+
* `AuthStrategy` interface (only token-minting strategies have it), so narrow
|
|
60
|
+
* via `in` + `typeof` — no cast.
|
|
61
|
+
*/
|
|
62
|
+
function isTokenIssuer(
|
|
63
|
+
strategy: AuthStrategy,
|
|
64
|
+
): strategy is AuthStrategy & TokenIssuer {
|
|
65
|
+
return "signToken" in strategy && typeof strategy.signToken === "function";
|
|
66
|
+
}
|
|
67
|
+
|
|
52
68
|
/**
|
|
53
69
|
* Manages authentication strategies and provides guard/permission checks.
|
|
54
70
|
*/
|
|
@@ -131,6 +147,32 @@ export class AuthManager {
|
|
|
131
147
|
}
|
|
132
148
|
}
|
|
133
149
|
|
|
150
|
+
/**
|
|
151
|
+
* Mint a token for an ALREADY-resolved user — the "login-as-known-user"
|
|
152
|
+
* path (e.g. straight after signup created the row in the app's own
|
|
153
|
+
* transaction). Skips the credential check `authenticate()` performs, so no
|
|
154
|
+
* redundant bcrypt / DB lookup, and the app never has to reach into the
|
|
155
|
+
* strategy internals.
|
|
156
|
+
*
|
|
157
|
+
* The token is byte-for-byte what `authenticate()` would emit for the same
|
|
158
|
+
* `user` (it delegates to the same `signToken`), so the claims — sub / roles
|
|
159
|
+
* / permissions / iat / exp / jti — are identical. Throws if the resolved
|
|
160
|
+
* strategy can't issue tokens (e.g. session / API-key strategies).
|
|
161
|
+
*/
|
|
162
|
+
issueFor(user: UserPayload, strategyName?: string): string {
|
|
163
|
+
const strategy = this.getStrategy(strategyName);
|
|
164
|
+
if (!isTokenIssuer(strategy)) {
|
|
165
|
+
throw new WardenError(
|
|
166
|
+
"STRATEGY_CANNOT_ISSUE",
|
|
167
|
+
`Auth strategy '${strategyName ?? this.defaultStrategy}' cannot issue tokens.`,
|
|
168
|
+
{
|
|
169
|
+
hint: "issueFor() needs a token-minting strategy (e.g. JwtStrategy with signToken). Session / API-key strategies don't mint tokens.",
|
|
170
|
+
},
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
return strategy.signToken(user);
|
|
174
|
+
}
|
|
175
|
+
|
|
134
176
|
/**
|
|
135
177
|
* Resolve a user's effective permissions for a scope (Epic 56). The single
|
|
136
178
|
* resolution entry the coarse helpers wrap — `hasRole`/`hasPermission`/
|
package/src/index.ts
CHANGED
|
@@ -124,7 +124,7 @@ export type {
|
|
|
124
124
|
export { scopeKey } from "./rights/types.js";
|
|
125
125
|
export type { ApiKeyConfig } from "./strategies/ApiKeyStrategy.js";
|
|
126
126
|
export { ApiKeyStrategy } from "./strategies/ApiKeyStrategy.js";
|
|
127
|
-
export type { JwtStrategyConfig } from "./strategies/JwtStrategy.js";
|
|
127
|
+
export type { JwtClaims, JwtStrategyConfig } from "./strategies/JwtStrategy.js";
|
|
128
128
|
export { generateJwtSecret, JwtStrategy } from "./strategies/JwtStrategy.js";
|
|
129
129
|
export type {
|
|
130
130
|
SessionStore,
|
|
@@ -8,7 +8,13 @@ import type { AuthResult, AuthStrategy, UserPayload } from "../AuthManager.js";
|
|
|
8
8
|
import { nativeWarden } from "../native.js";
|
|
9
9
|
import type { TokenBlacklist } from "../TokenBlacklist.js";
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* The verified JWT claims. Passed to `findUser` as the second argument so an app
|
|
13
|
+
* can reject a token on more than `sub` — e.g. compare `iat` to a stored
|
|
14
|
+
* `passwordChangedAt` (kill sessions on reset), check a `tokenVersion` custom
|
|
15
|
+
* claim, or honour the `jti` directly. Return `null` from `findUser` to reject.
|
|
16
|
+
*/
|
|
17
|
+
export interface JwtClaims {
|
|
12
18
|
sub: string;
|
|
13
19
|
roles?: string[];
|
|
14
20
|
permissions?: string[];
|
|
@@ -19,7 +25,7 @@ interface JwtPayloadData {
|
|
|
19
25
|
[key: string]: unknown;
|
|
20
26
|
}
|
|
21
27
|
|
|
22
|
-
function sign(payload:
|
|
28
|
+
function sign(payload: JwtClaims, secret: string): string {
|
|
23
29
|
const rust = nativeWarden();
|
|
24
30
|
if (!rust) {
|
|
25
31
|
throw new Error(
|
|
@@ -29,7 +35,7 @@ function sign(payload: JwtPayloadData, secret: string): string {
|
|
|
29
35
|
return rust.jwtSign(JSON.stringify(payload), secret);
|
|
30
36
|
}
|
|
31
37
|
|
|
32
|
-
function verify(token: string, secret: string):
|
|
38
|
+
function verify(token: string, secret: string): JwtClaims | null {
|
|
33
39
|
const rust = nativeWarden();
|
|
34
40
|
if (!rust) {
|
|
35
41
|
throw new Error(
|
|
@@ -38,7 +44,7 @@ function verify(token: string, secret: string): JwtPayloadData | null {
|
|
|
38
44
|
}
|
|
39
45
|
try {
|
|
40
46
|
const payloadJson = rust.jwtVerify(token, secret);
|
|
41
|
-
const payload = JSON.parse(payloadJson) as
|
|
47
|
+
const payload = JSON.parse(payloadJson) as JwtClaims;
|
|
42
48
|
if (typeof payload.sub !== "string" || !payload.sub) return null;
|
|
43
49
|
return payload;
|
|
44
50
|
} catch {
|
|
@@ -61,7 +67,15 @@ export interface JwtStrategyConfig {
|
|
|
61
67
|
*/
|
|
62
68
|
previousSecrets?: readonly string[];
|
|
63
69
|
expiresInSeconds?: number;
|
|
64
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Resolve the user for a verified token. Receives the token `sub` AND the
|
|
72
|
+
* full verified `claims` — use the claims to enforce session invalidation
|
|
73
|
+
* the strategy can't know about (e.g. reject when `claims.iat` predates the
|
|
74
|
+
* user's `passwordChangedAt`, or a `claims.tokenVersion` is stale) by
|
|
75
|
+
* returning `null`. The second arg is optional for callers that only need
|
|
76
|
+
* the id (existing one-arg `findUser` functions stay valid).
|
|
77
|
+
*/
|
|
78
|
+
findUser: (id: string, claims: JwtClaims) => Promise<UserPayload | null>;
|
|
65
79
|
verifyCredentials: (
|
|
66
80
|
email: string,
|
|
67
81
|
password: string,
|
|
@@ -113,7 +127,7 @@ export class JwtStrategy implements AuthStrategy {
|
|
|
113
127
|
* Returns `null` when no secret accepts the token — same semantics as
|
|
114
128
|
* the single-secret path so callers see "invalid or expired token".
|
|
115
129
|
*/
|
|
116
|
-
#verifyWithRotation(token: string):
|
|
130
|
+
#verifyWithRotation(token: string): JwtClaims | null {
|
|
117
131
|
for (const secret of this.#verifySecrets) {
|
|
118
132
|
const payload = verify(token, secret);
|
|
119
133
|
if (payload) return payload;
|
|
@@ -165,7 +179,10 @@ export class JwtStrategy implements AuthStrategy {
|
|
|
165
179
|
}
|
|
166
180
|
}
|
|
167
181
|
|
|
168
|
-
|
|
182
|
+
// Pass the FULL verified claims (not just `sub`) so the app can reject
|
|
183
|
+
// stale tokens it alone can judge — iat vs passwordChangedAt, tokenVersion,
|
|
184
|
+
// etc. — by returning null. This is the session-invalidation seam.
|
|
185
|
+
const user = await this.#findUser(payload.sub, payload);
|
|
169
186
|
if (!user) {
|
|
170
187
|
return { authenticated: false, error: "User not found" };
|
|
171
188
|
}
|