@c9up/warden 0.1.6 → 0.1.7

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/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";
@@ -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
- findUser: (id: string) => Promise<UserPayload | null>;
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;AAwC3D,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,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACtD,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;IAgChD,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"}
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
- const user = await this.#findUser(payload.sub);
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":"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"}
1
+ {"version":3,"file":"JwtStrategy.js","sourceRoot":"","sources":["../../src/strategies/JwtStrategy.ts"],"names":[],"mappings":"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"}
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c9up/warden",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Warden — Authentication & authorization for the Ream framework",
5
5
  "license": "MIT",
6
6
  "type": "module",
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
- interface JwtPayloadData {
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: JwtPayloadData, secret: string): string {
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): JwtPayloadData | null {
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 JwtPayloadData;
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
- findUser: (id: string) => Promise<UserPayload | null>;
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): JwtPayloadData | null {
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
- const user = await this.#findUser(payload.sub);
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
  }