@nebulr-group/bridge-auth-core 0.4.0-beta.0 → 0.4.0-beta.10

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.
Files changed (62) hide show
  1. package/dist/auth-service.d.ts +11 -0
  2. package/dist/auth-service.d.ts.map +1 -1
  3. package/dist/auth-service.js +20 -0
  4. package/dist/auth-service.js.map +1 -1
  5. package/dist/backend/index.d.ts +12 -0
  6. package/dist/backend/index.d.ts.map +1 -0
  7. package/dist/backend/index.js +12 -0
  8. package/dist/backend/index.js.map +1 -0
  9. package/dist/backend/jwks-service.d.ts +119 -0
  10. package/dist/backend/jwks-service.d.ts.map +1 -0
  11. package/dist/backend/jwks-service.js +216 -0
  12. package/dist/backend/jwks-service.js.map +1 -0
  13. package/dist/backend/types.d.ts +119 -0
  14. package/dist/backend/types.d.ts.map +1 -0
  15. package/dist/backend/types.js +37 -0
  16. package/dist/backend/types.js.map +1 -0
  17. package/dist/billing/quota-store.d.ts +20 -0
  18. package/dist/billing/quota-store.d.ts.map +1 -1
  19. package/dist/billing/quota-store.js +15 -0
  20. package/dist/billing/quota-store.js.map +1 -1
  21. package/dist/bridge-auth.d.ts +93 -2
  22. package/dist/bridge-auth.d.ts.map +1 -1
  23. package/dist/bridge-auth.js +178 -5
  24. package/dist/bridge-auth.js.map +1 -1
  25. package/dist/direct-auth.d.ts +5 -1
  26. package/dist/direct-auth.d.ts.map +1 -1
  27. package/dist/direct-auth.js +29 -19
  28. package/dist/direct-auth.js.map +1 -1
  29. package/dist/flags/realtime.d.ts +35 -0
  30. package/dist/flags/realtime.d.ts.map +1 -1
  31. package/dist/flags/realtime.js +285 -10
  32. package/dist/flags/realtime.js.map +1 -1
  33. package/dist/http.d.ts +4 -0
  34. package/dist/http.d.ts.map +1 -1
  35. package/dist/http.js +33 -11
  36. package/dist/http.js.map +1 -1
  37. package/dist/index.d.ts +1 -1
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/management-types.d.ts +17 -0
  41. package/dist/management-types.d.ts.map +1 -1
  42. package/dist/sso-popup.d.ts.map +1 -1
  43. package/dist/sso-popup.js +11 -4
  44. package/dist/sso-popup.js.map +1 -1
  45. package/dist/types.d.ts +52 -0
  46. package/dist/types.d.ts.map +1 -1
  47. package/dist/usage/index.d.ts +1 -1
  48. package/dist/usage/index.d.ts.map +1 -1
  49. package/dist/usage/index.js +1 -1
  50. package/dist/usage/index.js.map +1 -1
  51. package/dist/usage/storage/index.d.ts +0 -1
  52. package/dist/usage/storage/index.d.ts.map +1 -1
  53. package/dist/usage/storage/index.js +44 -9
  54. package/dist/usage/storage/index.js.map +1 -1
  55. package/dist/usage/storage/node-fs-storage.d.ts.map +1 -1
  56. package/dist/usage/storage/node-fs-storage.js +22 -7
  57. package/dist/usage/storage/node-fs-storage.js.map +1 -1
  58. package/dist/usage/usage-reporter.d.ts +1 -0
  59. package/dist/usage/usage-reporter.d.ts.map +1 -1
  60. package/dist/usage/usage-reporter.js +24 -3
  61. package/dist/usage/usage-reporter.js.map +1 -1
  62. package/package.json +16 -4
@@ -7,6 +7,17 @@ export declare class AuthService {
7
7
  createLoginUrl(options?: {
8
8
  redirectUri?: string;
9
9
  }): string;
10
+ /**
11
+ * TBP-36 — hosted signup URL, mirroring {@link createLoginUrl}. Optional
12
+ * plan preselection (`signupPlan` + currency/interval) is carried as URL
13
+ * params that the hosted signup page applies at tenant creation.
14
+ */
15
+ createSignupUrl(options?: {
16
+ redirectUri?: string;
17
+ signupPlan?: string;
18
+ signupCurrency?: string;
19
+ signupRecurrenceInterval?: string;
20
+ }): string;
10
21
  createLogoutUrl(): string;
11
22
  exchangeCode(code: string): Promise<TokenSet>;
12
23
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"auth-service.d.ts","sourceRoot":"","sources":["../src/auth-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAQ3D,qBAAa,WAAW;IAEpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM;IAGjC,cAAc,CAAC,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,MAAM;IAQ9D,eAAe,IAAI,MAAM;IAInB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAqBnD;;;;;;;OAOG;IACG,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAc5D,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAa5E,YAAY,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;CAuBxE"}
1
+ {"version":3,"file":"auth-service.d.ts","sourceRoot":"","sources":["../src/auth-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAQ3D,qBAAa,WAAW;IAEpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM;IAGjC,cAAc,CAAC,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,MAAM;IAQ9D;;;;OAIG;IACH,eAAe,CAAC,OAAO,GAAE;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,wBAAwB,CAAC,EAAE,MAAM,CAAC;KAC9B,GAAG,MAAM;IAYf,eAAe,IAAI,MAAM;IAInB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAqBnD;;;;;;;OAOG;IACG,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAc5D,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAa5E,YAAY,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;CAuBxE"}
@@ -13,6 +13,26 @@ export class AuthService {
13
13
  ? `${base}?redirectUri=${encodeURIComponent(redirectUri)}`
14
14
  : base;
15
15
  }
16
+ /**
17
+ * TBP-36 — hosted signup URL, mirroring {@link createLoginUrl}. Optional
18
+ * plan preselection (`signupPlan` + currency/interval) is carried as URL
19
+ * params that the hosted signup page applies at tenant creation.
20
+ */
21
+ createSignupUrl(options = {}) {
22
+ const redirectUri = options.redirectUri ?? this.config.callbackUrl;
23
+ const base = `${this.config.hostedUrl}/auth/signup/${this.config.appId}`;
24
+ const params = new URLSearchParams();
25
+ if (redirectUri)
26
+ params.set('redirectUri', redirectUri);
27
+ if (options.signupPlan)
28
+ params.set('signupPlan', options.signupPlan);
29
+ if (options.signupCurrency)
30
+ params.set('signupCurrency', options.signupCurrency);
31
+ if (options.signupRecurrenceInterval)
32
+ params.set('signupRecurrenceInterval', options.signupRecurrenceInterval);
33
+ const qs = params.toString();
34
+ return qs ? `${base}?${qs}` : base;
35
+ }
16
36
  createLogoutUrl() {
17
37
  return `${this.config.hostedUrl}/auth/login/${this.config.appId}`;
18
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"auth-service.js","sourceRoot":"","sources":["../src/auth-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth-service.js","sourceRoot":"","sources":["../src/auth-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @nebulr-group/bridge-auth-core/backend
3
+ *
4
+ * Framework-agnostic, Node-only auth surface for server-side Bridge plugins.
5
+ * No NestJS, no browser/storage APIs. Safe to import from any Node backend.
6
+ */
7
+ export { JwksService, TokenVerificationError } from './jwks-service.js';
8
+ export type { JwksServiceConfig, JwksLogger } from './jwks-service.js';
9
+ export type { JwtClaims, BridgeUser, ApiTokenClaims } from './types.js';
10
+ export { transformJwtToBridgeUser } from './types.js';
11
+ export { decodeJwtPayload, getTokenExpiry, isTokenExpired, getTenantId, getTenantUserId, } from '../token-utils.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACxE,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGvE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAGtD,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,WAAW,EACX,eAAe,GAChB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @nebulr-group/bridge-auth-core/backend
3
+ *
4
+ * Framework-agnostic, Node-only auth surface for server-side Bridge plugins.
5
+ * No NestJS, no browser/storage APIs. Safe to import from any Node backend.
6
+ */
7
+ // JWKS-based verification (plain class, not a DI provider)
8
+ export { JwksService, TokenVerificationError } from './jwks-service.js';
9
+ export { transformJwtToBridgeUser } from './types.js';
10
+ // Token utilities (reused from the shared token-utils — no duplication)
11
+ export { decodeJwtPayload, getTokenExpiry, isTokenExpired, getTenantId, getTenantUserId, } from '../token-utils.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,2DAA2D;AAC3D,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAKxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAEtD,wEAAwE;AACxE,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,WAAW,EACX,eAAe,GAChB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,119 @@
1
+ import type { JwtClaims, ApiTokenClaims } from './types.js';
2
+ /**
3
+ * Optional logger. Defaults to a no-op so the service is silent unless a
4
+ * consumer wires one in (e.g. NestJS forwards `BridgeConfigService.log`).
5
+ */
6
+ export type JwksLogger = (message: string, ...args: unknown[]) => void;
7
+ /**
8
+ * Construction config for the framework-agnostic JwksService.
9
+ *
10
+ * Everything the verification logic needs is injected — there is no hardcoded
11
+ * URL, issuer, audience, or TTL. Framework wrappers (NestJS, etc.) construct
12
+ * this from their own config service.
13
+ */
14
+ export interface JwksServiceConfig {
15
+ /** JWKS endpoint for user-token verification. */
16
+ jwksUrl: string;
17
+ /**
18
+ * Token-introspection endpoint for API-token verification.
19
+ *
20
+ * API tokens are signed with the per-app HS256 secret, which a plugin never
21
+ * holds — so the plugin cannot verify them locally. Instead it POSTs the
22
+ * token here (`{ token }`) and the Bridge returns `{ active, sub, appId,
23
+ * tenantId, type, privileges, exp }`. This also gives instant revocation:
24
+ * the Bridge re-checks the backing record on every (uncached) call.
25
+ */
26
+ introspectionUrl: string;
27
+ /** Expected `iss` for user tokens. */
28
+ issuer: string;
29
+ /** Expected `aud` for user tokens (typically the appId). */
30
+ audience: string;
31
+ /** How long a remote JWKS client is reused before it is re-created. @default 3600000 (1h) */
32
+ cacheTtlMs?: number;
33
+ /**
34
+ * How long a successful introspection result is cached, keyed by token.
35
+ * Trades revocation latency for fewer network calls. `0` disables caching
36
+ * (every request introspects → instant revocation). @default 0
37
+ */
38
+ introspectionCacheTtlMs?: number;
39
+ /** Optional debug logger. @default no-op */
40
+ log?: JwksLogger;
41
+ }
42
+ /**
43
+ * Error thrown on token verification failure.
44
+ *
45
+ * `code` is a stable, framework-agnostic discriminator:
46
+ * `TOKEN_EXPIRED` | `TOKEN_INVALID` | `JWKS_NO_MATCH` | `CLAIM_VALIDATION_FAILED`
47
+ * | `APP_MISMATCH` | `UNKNOWN_ERROR`.
48
+ */
49
+ export declare class TokenVerificationError extends Error {
50
+ readonly code: string;
51
+ constructor(message: string, code: string);
52
+ }
53
+ /**
54
+ * Framework-agnostic, Node-only Bridge token verification.
55
+ *
56
+ * Covers two paths:
57
+ * - **User tokens** — verified locally via remote JWKS (asymmetric PS256;
58
+ * issuer/audience validated). The verifier needs no secret, so offline
59
+ * JWKS verification is the right tool.
60
+ * - **API tokens** — verified via remote *introspection* (a POST to the
61
+ * Bridge). API tokens are signed with the per-app HS256 secret which the
62
+ * plugin never holds, so the secret-holder (the Bridge) is asked. This also
63
+ * gives instant revocation. Successful results may be cached (off by
64
+ * default; see `introspectionCacheTtlMs`).
65
+ *
66
+ * This is a plain class — NOT a DI provider. Framework plugins wrap it.
67
+ */
68
+ export declare class JwksService {
69
+ private readonly config;
70
+ private jwks;
71
+ private jwksInitTime;
72
+ /** token → { result, expiresAt(ms) }. Only successful introspections are cached. */
73
+ private readonly introspectionCache;
74
+ private readonly cacheTtlMs;
75
+ private readonly introspectionCacheTtlMs;
76
+ private readonly log;
77
+ constructor(config: JwksServiceConfig);
78
+ /**
79
+ * Initialize or refresh the user-token JWKS client.
80
+ */
81
+ private ensureJwks;
82
+ /**
83
+ * Verify a user JWT and return its claims.
84
+ *
85
+ * @throws {TokenVerificationError} if the token is invalid or expired.
86
+ */
87
+ verifyToken(token: string): Promise<JwtClaims>;
88
+ /**
89
+ * Verify a Bridge API token by introspecting it against the Bridge.
90
+ *
91
+ * Unlike user tokens, API tokens are signed with the per-app HS256 secret
92
+ * which this verifier does not hold — so it asks the secret-holder. The
93
+ * Bridge returns whether the token is active (signature valid AND backing
94
+ * record live: not revoked, not expired) plus its claims.
95
+ *
96
+ * The returned `{ active: false }` covers every rejection (forged, tampered,
97
+ * wrong type, revoked, expired) without distinguishing them — no information
98
+ * leak. App-scoping is then enforced here: the introspected `appId` must
99
+ * equal `expectedAppId`.
100
+ *
101
+ * @throws {TokenVerificationError}
102
+ * - `TOKEN_INVALID` if the token is inactive or not an API token
103
+ * - `APP_MISMATCH` if the token belongs to a different app
104
+ * - `UNKNOWN_ERROR` if the introspection request itself fails
105
+ */
106
+ verifyApiToken(token: string, expectedAppId: string): Promise<ApiTokenClaims>;
107
+ /**
108
+ * POST the token to the introspection endpoint, with optional short-lived
109
+ * caching of successful results (see `introspectionCacheTtlMs`).
110
+ */
111
+ private introspect;
112
+ private getCachedIntrospection;
113
+ private cacheIntrospection;
114
+ /**
115
+ * Map a jose verification error to a stable TokenVerificationError.
116
+ */
117
+ private mapVerificationError;
118
+ }
119
+ //# sourceMappingURL=jwks-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwks-service.d.ts","sourceRoot":"","sources":["../../src/backend/jwks-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5D;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAEvE;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;;;OAQG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,6FAA6F;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,4CAA4C;IAC5C,GAAG,CAAC,EAAE,UAAU,CAAC;CAClB;AAeD;;;;;;GAMG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;aAG7B,IAAI,EAAE,MAAM;gBAD5B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM;CAK/B;AAKD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,WAAW;IAcV,OAAO,CAAC,QAAQ,CAAC,MAAM;IAbnC,OAAO,CAAC,IAAI,CAAsD;IAClE,OAAO,CAAC,YAAY,CAAK;IAEzB,oFAAoF;IACpF,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAG/B;IAEJ,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAS;IACjD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;gBAEJ,MAAM,EAAE,iBAAiB;IAOtD;;OAEG;IACH,OAAO,CAAC,UAAU;IAYlB;;;;OAIG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAqBpD;;;;;;;;;;;;;;;;;OAiBG;IACG,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IA+BnF;;;OAGG;YACW,UAAU;IAwCxB,OAAO,CAAC,sBAAsB;IAe9B,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAqB7B"}
@@ -0,0 +1,216 @@
1
+ import { createRemoteJWKSet, jwtVerify, errors as joseErrors } from 'jose';
2
+ /**
3
+ * Error thrown on token verification failure.
4
+ *
5
+ * `code` is a stable, framework-agnostic discriminator:
6
+ * `TOKEN_EXPIRED` | `TOKEN_INVALID` | `JWKS_NO_MATCH` | `CLAIM_VALIDATION_FAILED`
7
+ * | `APP_MISMATCH` | `UNKNOWN_ERROR`.
8
+ */
9
+ export class TokenVerificationError extends Error {
10
+ code;
11
+ constructor(message, code) {
12
+ super(message);
13
+ this.code = code;
14
+ this.name = 'TokenVerificationError';
15
+ }
16
+ }
17
+ const DEFAULT_CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
18
+ const DEFAULT_INTROSPECTION_CACHE_TTL_MS = 0; // disabled → instant revocation
19
+ /**
20
+ * Framework-agnostic, Node-only Bridge token verification.
21
+ *
22
+ * Covers two paths:
23
+ * - **User tokens** — verified locally via remote JWKS (asymmetric PS256;
24
+ * issuer/audience validated). The verifier needs no secret, so offline
25
+ * JWKS verification is the right tool.
26
+ * - **API tokens** — verified via remote *introspection* (a POST to the
27
+ * Bridge). API tokens are signed with the per-app HS256 secret which the
28
+ * plugin never holds, so the secret-holder (the Bridge) is asked. This also
29
+ * gives instant revocation. Successful results may be cached (off by
30
+ * default; see `introspectionCacheTtlMs`).
31
+ *
32
+ * This is a plain class — NOT a DI provider. Framework plugins wrap it.
33
+ */
34
+ export class JwksService {
35
+ config;
36
+ jwks = null;
37
+ jwksInitTime = 0;
38
+ /** token → { result, expiresAt(ms) }. Only successful introspections are cached. */
39
+ introspectionCache = new Map();
40
+ cacheTtlMs;
41
+ introspectionCacheTtlMs;
42
+ log;
43
+ constructor(config) {
44
+ this.config = config;
45
+ this.cacheTtlMs = config.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;
46
+ this.introspectionCacheTtlMs =
47
+ config.introspectionCacheTtlMs ?? DEFAULT_INTROSPECTION_CACHE_TTL_MS;
48
+ this.log = config.log ?? (() => { });
49
+ }
50
+ /**
51
+ * Initialize or refresh the user-token JWKS client.
52
+ */
53
+ ensureJwks() {
54
+ const now = Date.now();
55
+ if (!this.jwks || now - this.jwksInitTime > this.cacheTtlMs) {
56
+ this.log('Initializing JWKS client', { url: this.config.jwksUrl });
57
+ this.jwks = createRemoteJWKSet(new URL(this.config.jwksUrl));
58
+ this.jwksInitTime = now;
59
+ }
60
+ return this.jwks;
61
+ }
62
+ /**
63
+ * Verify a user JWT and return its claims.
64
+ *
65
+ * @throws {TokenVerificationError} if the token is invalid or expired.
66
+ */
67
+ async verifyToken(token) {
68
+ const jwks = this.ensureJwks();
69
+ try {
70
+ const { payload } = await jwtVerify(token, jwks, {
71
+ issuer: this.config.issuer,
72
+ audience: this.config.audience,
73
+ });
74
+ this.log('Token verified successfully', {
75
+ sub: payload.sub,
76
+ iss: payload.iss,
77
+ aud: payload.aud,
78
+ });
79
+ return payload;
80
+ }
81
+ catch (error) {
82
+ throw this.mapVerificationError(error, 'Token');
83
+ }
84
+ }
85
+ /**
86
+ * Verify a Bridge API token by introspecting it against the Bridge.
87
+ *
88
+ * Unlike user tokens, API tokens are signed with the per-app HS256 secret
89
+ * which this verifier does not hold — so it asks the secret-holder. The
90
+ * Bridge returns whether the token is active (signature valid AND backing
91
+ * record live: not revoked, not expired) plus its claims.
92
+ *
93
+ * The returned `{ active: false }` covers every rejection (forged, tampered,
94
+ * wrong type, revoked, expired) without distinguishing them — no information
95
+ * leak. App-scoping is then enforced here: the introspected `appId` must
96
+ * equal `expectedAppId`.
97
+ *
98
+ * @throws {TokenVerificationError}
99
+ * - `TOKEN_INVALID` if the token is inactive or not an API token
100
+ * - `APP_MISMATCH` if the token belongs to a different app
101
+ * - `UNKNOWN_ERROR` if the introspection request itself fails
102
+ */
103
+ async verifyApiToken(token, expectedAppId) {
104
+ const introspection = await this.introspect(token);
105
+ if (!introspection.active) {
106
+ // Bridge already collapsed forged/tampered/revoked/expired → inactive.
107
+ throw new TokenVerificationError('Invalid token', 'TOKEN_INVALID');
108
+ }
109
+ if (introspection.type !== 'api') {
110
+ throw new TokenVerificationError('Wrong token type', 'TOKEN_INVALID');
111
+ }
112
+ if (introspection.appId !== expectedAppId) {
113
+ throw new TokenVerificationError('Token issued for a different app', 'APP_MISMATCH');
114
+ }
115
+ this.log('API token verified via introspection', {
116
+ sub: introspection.sub,
117
+ appId: introspection.appId,
118
+ });
119
+ return {
120
+ sub: introspection.sub,
121
+ appId: introspection.appId,
122
+ tenantId: introspection.tenantId ?? null,
123
+ type: 'api',
124
+ privileges: introspection.privileges ?? [],
125
+ ...(introspection.exp != null ? { exp: introspection.exp } : {}),
126
+ };
127
+ }
128
+ /**
129
+ * POST the token to the introspection endpoint, with optional short-lived
130
+ * caching of successful results (see `introspectionCacheTtlMs`).
131
+ */
132
+ async introspect(token) {
133
+ const cached = this.getCachedIntrospection(token);
134
+ if (cached) {
135
+ this.log('API token introspection cache hit');
136
+ return cached;
137
+ }
138
+ let response;
139
+ try {
140
+ response = await fetch(this.config.introspectionUrl, {
141
+ method: 'POST',
142
+ headers: { 'Content-Type': 'application/json' },
143
+ body: JSON.stringify({ token }),
144
+ });
145
+ }
146
+ catch (error) {
147
+ this.log('API token introspection request failed', error);
148
+ throw new TokenVerificationError('Introspection request failed', 'UNKNOWN_ERROR');
149
+ }
150
+ if (!response.ok) {
151
+ this.log('API token introspection returned a non-OK status', {
152
+ status: response.status,
153
+ });
154
+ throw new TokenVerificationError('Introspection endpoint error', 'UNKNOWN_ERROR');
155
+ }
156
+ let body;
157
+ try {
158
+ body = (await response.json());
159
+ }
160
+ catch (error) {
161
+ this.log('API token introspection returned invalid JSON', error);
162
+ throw new TokenVerificationError('Introspection response invalid', 'UNKNOWN_ERROR');
163
+ }
164
+ if (body.active) {
165
+ this.cacheIntrospection(token, body);
166
+ }
167
+ return body;
168
+ }
169
+ getCachedIntrospection(token) {
170
+ if (this.introspectionCacheTtlMs <= 0) {
171
+ return null;
172
+ }
173
+ const entry = this.introspectionCache.get(token);
174
+ if (!entry) {
175
+ return null;
176
+ }
177
+ if (Date.now() >= entry.expiresAt) {
178
+ this.introspectionCache.delete(token);
179
+ return null;
180
+ }
181
+ return entry.result;
182
+ }
183
+ cacheIntrospection(token, result) {
184
+ if (this.introspectionCacheTtlMs <= 0) {
185
+ return;
186
+ }
187
+ this.introspectionCache.set(token, {
188
+ result,
189
+ expiresAt: Date.now() + this.introspectionCacheTtlMs,
190
+ });
191
+ }
192
+ /**
193
+ * Map a jose verification error to a stable TokenVerificationError.
194
+ */
195
+ mapVerificationError(error, label) {
196
+ if (error instanceof joseErrors.JWTExpired) {
197
+ this.log(`${label} verification failed: Token expired`);
198
+ return new TokenVerificationError('Token expired', 'TOKEN_EXPIRED');
199
+ }
200
+ if (error instanceof joseErrors.JWTInvalid) {
201
+ this.log(`${label} verification failed: Invalid token`);
202
+ return new TokenVerificationError('Invalid token', 'TOKEN_INVALID');
203
+ }
204
+ if (error instanceof joseErrors.JWKSNoMatchingKey) {
205
+ this.log(`${label} verification failed: No matching key in JWKS`);
206
+ return new TokenVerificationError('Invalid token signature', 'JWKS_NO_MATCH');
207
+ }
208
+ if (error instanceof joseErrors.JWTClaimValidationFailed) {
209
+ this.log(`${label} verification failed: Claim validation failed`, error.message);
210
+ return new TokenVerificationError('Token claim validation failed', 'CLAIM_VALIDATION_FAILED');
211
+ }
212
+ this.log(`${label} verification failed: Unknown error`, error);
213
+ return new TokenVerificationError('Token verification failed', 'UNKNOWN_ERROR');
214
+ }
215
+ }
216
+ //# sourceMappingURL=jwks-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwks-service.js","sourceRoot":"","sources":["../../src/backend/jwks-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Backend (Node-only) auth types.
3
+ *
4
+ * Framework-agnostic. No NestJS, no browser/storage APIs. These are the shapes
5
+ * shared by every server-side Bridge plugin (bridge-nestjs today; others later)
6
+ * for JWT verification and user extraction.
7
+ *
8
+ * NOTE on `JwtClaims` vs `IDToken` (in ../types.ts): `IDToken` is the strict
9
+ * OIDC id_token payload used by the browser SDK to build a `Profile`. `JwtClaims`
10
+ * here is the permissive *access-token* claim set the server verifies via JWKS —
11
+ * it carries short-form tenant/app claims (`tid`/`aid`), `privileges`, `role`,
12
+ * and the registered JWT claims (`iss`/`aud`/`exp`/...). They intentionally stay
13
+ * separate: different tokens, different consumers.
14
+ */
15
+ /**
16
+ * Raw JWT claims from a Bridge access/ID token (the verified payload).
17
+ */
18
+ export interface JwtClaims {
19
+ /** Subject (user ID) */
20
+ sub: string;
21
+ /** Preferred username */
22
+ preferred_username?: string;
23
+ /** Email address */
24
+ email?: string;
25
+ /** Email verified flag */
26
+ email_verified?: boolean;
27
+ /** Full name */
28
+ name?: string;
29
+ /** Given name */
30
+ given_name?: string;
31
+ /** Family name */
32
+ family_name?: string;
33
+ /** Locale */
34
+ locale?: string;
35
+ /** User onboarded flag */
36
+ onboarded?: boolean;
37
+ /** Multi-tenant flag */
38
+ multi_tenant?: boolean;
39
+ /** Tenant ID (long form) */
40
+ tenant_id?: string;
41
+ /** Tenant ID (short form) */
42
+ tid?: string;
43
+ /** App ID (short form) */
44
+ aid?: string;
45
+ /** Scope */
46
+ scope?: string;
47
+ /** Tenant name */
48
+ tenant_name?: string;
49
+ /** Tenant locale */
50
+ tenant_locale?: string;
51
+ /** Tenant logo URL */
52
+ tenant_logo?: string;
53
+ /** Tenant onboarded flag */
54
+ tenant_onboarded?: boolean;
55
+ /** User's role */
56
+ role?: string;
57
+ /** User privilege strings (custom claim) */
58
+ privileges?: string[];
59
+ /** Token issuer */
60
+ iss?: string;
61
+ /** Token audience */
62
+ aud?: string | string[];
63
+ /** Expiration time */
64
+ exp?: number;
65
+ /** Not before time */
66
+ nbf?: number;
67
+ /** Issued at time */
68
+ iat?: number;
69
+ }
70
+ /**
71
+ * Authenticated user extracted from a verified JWT access token.
72
+ */
73
+ export interface BridgeUser {
74
+ /** User ID (sub claim) */
75
+ id: string;
76
+ /** User's email address */
77
+ email: string;
78
+ /** Whether email is verified */
79
+ emailVerified: boolean;
80
+ /** Username (preferred_username claim) */
81
+ username: string;
82
+ /** Full display name */
83
+ fullName: string;
84
+ /** Given/first name */
85
+ givenName?: string;
86
+ /** Family/last name */
87
+ familyName?: string;
88
+ /** User's locale preference */
89
+ locale?: string;
90
+ /** Whether user has completed onboarding */
91
+ onboarded?: boolean;
92
+ /** Tenant/workspace ID the user is authenticated for */
93
+ tenantId: string;
94
+ /** App ID from the token (aid claim) */
95
+ appId?: string;
96
+ /** OAuth scopes granted to the token */
97
+ scope?: string;
98
+ /** User's role within the tenant */
99
+ role?: string;
100
+ /** Whether user has multi-tenant access */
101
+ multiTenantAccess?: boolean;
102
+ /** Privilege strings from the JWT `privileges` claim (e.g. ['AUTHENTICATED', 'USER_READ']) */
103
+ privileges?: string[];
104
+ }
105
+ /**
106
+ * Claims present in a Bridge API token JWT (the `x-api-key` machine credential).
107
+ */
108
+ export interface ApiTokenClaims extends JwtClaims {
109
+ sub: string;
110
+ appId: string;
111
+ tenantId: string | null;
112
+ type: 'api';
113
+ privileges: string[];
114
+ }
115
+ /**
116
+ * Transform raw JWT claims into a BridgeUser.
117
+ */
118
+ export declare function transformJwtToBridgeUser(claims: JwtClaims): BridgeUser;
119
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/backend/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Backend (Node-only) auth types.
3
+ *
4
+ * Framework-agnostic. No NestJS, no browser/storage APIs. These are the shapes
5
+ * shared by every server-side Bridge plugin (bridge-nestjs today; others later)
6
+ * for JWT verification and user extraction.
7
+ *
8
+ * NOTE on `JwtClaims` vs `IDToken` (in ../types.ts): `IDToken` is the strict
9
+ * OIDC id_token payload used by the browser SDK to build a `Profile`. `JwtClaims`
10
+ * here is the permissive *access-token* claim set the server verifies via JWKS —
11
+ * it carries short-form tenant/app claims (`tid`/`aid`), `privileges`, `role`,
12
+ * and the registered JWT claims (`iss`/`aud`/`exp`/...). They intentionally stay
13
+ * separate: different tokens, different consumers.
14
+ */
15
+ /**
16
+ * Transform raw JWT claims into a BridgeUser.
17
+ */
18
+ export function transformJwtToBridgeUser(claims) {
19
+ return {
20
+ id: claims.sub,
21
+ email: claims.email || '',
22
+ emailVerified: claims.email_verified || false,
23
+ username: claims.preferred_username || claims.email || '',
24
+ fullName: claims.name || '',
25
+ givenName: claims.given_name,
26
+ familyName: claims.family_name,
27
+ locale: claims.locale,
28
+ onboarded: claims.onboarded,
29
+ tenantId: claims.tid || claims.tenant_id || '',
30
+ appId: claims.aid,
31
+ scope: claims.scope,
32
+ role: claims.role,
33
+ multiTenantAccess: claims.multi_tenant,
34
+ privileges: claims.privileges,
35
+ };
36
+ }
37
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/backend/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAyGH;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAiB;IACxD,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,GAAG;QACd,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;QACzB,aAAa,EAAE,MAAM,CAAC,cAAc,IAAI,KAAK;QAC7C,QAAQ,EAAE,MAAM,CAAC,kBAAkB,IAAI,MAAM,CAAC,KAAK,IAAI,EAAE;QACzD,QAAQ,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;QAC3B,SAAS,EAAE,MAAM,CAAC,UAAU;QAC5B,UAAU,EAAE,MAAM,CAAC,WAAW;QAC9B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,QAAQ,EAAE,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,SAAS,IAAI,EAAE;QAC9C,KAAK,EAAE,MAAM,CAAC,GAAG;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,iBAAiB,EAAE,MAAM,CAAC,YAAY;QACtC,UAAU,EAAE,MAAM,CAAC,UAAU;KAC9B,CAAC;AACJ,CAAC"}
@@ -22,6 +22,26 @@ export interface QuotaSnapshot {
22
22
  warningLevel: null | 'approaching' | 'critical';
23
23
  /** Display label. US-11 uses the raw metric key; framework wrappers can override. */
24
24
  label: string;
25
+ /**
26
+ * TBP-275 — per-unit price for a metered quota (whole currency units, e.g.
27
+ * 0.002). Absent for `hard` quotas and for metered quotas with no price yet.
28
+ */
29
+ unitAmount?: number;
30
+ /** TBP-275 — currency of `unitAmount` / `overageEstimate` (ISO code). */
31
+ currency?: string;
32
+ /**
33
+ * TBP-275 — estimated overage cost accrued this period, in `currency` units.
34
+ * Server-computed: `max(0, used - limit) * unitAmount` (or `used * unitAmount`
35
+ * when `limit === 0`). Lets the UI show "~$1.00 estimated" without waiting for
36
+ * a Stripe invoice.
37
+ */
38
+ overageEstimate?: number;
39
+ /**
40
+ * TBP-275 — true once usage has passed the included allotment (metered billing
41
+ * engaged). Prefer this over a UI-derived `used > limit` so the server stays
42
+ * authoritative (handles `limit === 0` pure-per-unit correctly).
43
+ */
44
+ overcap?: boolean;
25
45
  }
26
46
  type Listener = (metric: string, snap: QuotaSnapshot | undefined) => void;
27
47
  interface MountOptions {