@heavybit/pendoadmin-shared-lib 1.6.0 → 1.8.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.
Files changed (70) hide show
  1. package/dist/common/gateway-signature.d.ts +49 -0
  2. package/dist/common/gateway-signature.d.ts.map +1 -0
  3. package/dist/common/gateway-signature.js +99 -0
  4. package/dist/common/gateway-signature.js.map +1 -0
  5. package/dist/common/index.d.ts +1 -0
  6. package/dist/common/index.d.ts.map +1 -1
  7. package/dist/common/index.js +1 -0
  8. package/dist/common/index.js.map +1 -1
  9. package/dist/express/auth.middleware.d.ts +5 -4
  10. package/dist/express/auth.middleware.d.ts.map +1 -1
  11. package/dist/express/auth.middleware.js +49 -65
  12. package/dist/express/auth.middleware.js.map +1 -1
  13. package/dist/index.d.ts +1 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +2 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/logging/index.d.ts +1 -0
  18. package/dist/logging/index.d.ts.map +1 -1
  19. package/dist/logging/index.js +5 -2
  20. package/dist/logging/index.js.map +1 -1
  21. package/dist/logging/redact.d.ts +16 -0
  22. package/dist/logging/redact.d.ts.map +1 -0
  23. package/dist/logging/redact.js +83 -0
  24. package/dist/logging/redact.js.map +1 -0
  25. package/dist/nestjs/auth.guard.d.ts +2 -0
  26. package/dist/nestjs/auth.guard.d.ts.map +1 -1
  27. package/dist/nestjs/auth.guard.js +11 -3
  28. package/dist/nestjs/auth.guard.js.map +1 -1
  29. package/dist/nestjs/permission.guard.js +5 -4
  30. package/dist/nestjs/permission.guard.js.map +1 -1
  31. package/dist/rate-limit/create-rate-limiter.d.ts +21 -2
  32. package/dist/rate-limit/create-rate-limiter.d.ts.map +1 -1
  33. package/dist/rate-limit/create-rate-limiter.js +29 -3
  34. package/dist/rate-limit/create-rate-limiter.js.map +1 -1
  35. package/dist/rate-limit/index.d.ts +1 -1
  36. package/dist/rate-limit/index.d.ts.map +1 -1
  37. package/dist/rate-limit/index.js +1 -1
  38. package/dist/rate-limit/index.js.map +1 -1
  39. package/dist/redis/index.d.ts +3 -0
  40. package/dist/redis/index.d.ts.map +1 -0
  41. package/dist/redis/index.js +2 -0
  42. package/dist/redis/index.js.map +1 -0
  43. package/dist/redis/keyspace.d.ts +46 -0
  44. package/dist/redis/keyspace.d.ts.map +1 -0
  45. package/dist/redis/keyspace.js +82 -0
  46. package/dist/redis/keyspace.js.map +1 -0
  47. package/dist/types/index.d.ts +2 -0
  48. package/dist/types/index.d.ts.map +1 -1
  49. package/dist/types/index.js +2 -0
  50. package/dist/types/index.js.map +1 -1
  51. package/package.json +7 -3
  52. package/src/common/gateway-signature.ts +124 -0
  53. package/src/common/index.ts +1 -0
  54. package/src/express/auth.middleware.ts +46 -64
  55. package/src/index.ts +3 -0
  56. package/src/logging/index.ts +6 -2
  57. package/src/logging/redact.ts +84 -0
  58. package/src/nestjs/auth.guard.ts +12 -3
  59. package/src/nestjs/permission.guard.ts +5 -5
  60. package/src/rate-limit/create-rate-limiter.ts +44 -5
  61. package/src/rate-limit/index.ts +1 -1
  62. package/src/redis/index.ts +10 -0
  63. package/src/redis/keyspace.ts +127 -0
  64. package/src/types/index.ts +2 -0
  65. package/tests/auth-middleware.test.mjs +91 -0
  66. package/tests/gateway-signature.test.mjs +93 -0
  67. package/tests/nestjs-guards.test.mjs +45 -0
  68. package/tests/rate-limit-key.test.mjs +25 -0
  69. package/tests/redact.test.mjs +61 -0
  70. package/tests/redis-keyspace.test.mjs +149 -0
@@ -10,6 +10,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
10
10
  import { Injectable, UnauthorizedException, } from '@nestjs/common';
11
11
  import { Reflector } from '@nestjs/core';
12
12
  import { verifyToken } from '../common/jwt.utils.js';
13
+ import { isTrustedGatewayIdentity, isDirectJwtFallbackAllowed } from '../common/gateway-signature.js';
13
14
  import { GATEWAY_HEADERS } from '../types/index.js';
14
15
  /** Parse a header value that may be a JSON array string or comma-separated. */
15
16
  function parseArrayHeader(value) {
@@ -25,6 +26,8 @@ function parseArrayHeader(value) {
25
26
  return trimmed.split(',').filter(Boolean);
26
27
  }
27
28
  export const IS_PUBLIC_KEY = 'isPublic';
29
+ /** Request property AuthGuard sets when the caller came from signed gateway headers. */
30
+ export const GATEWAY_VERIFIED_FLAG = 'gatewayVerified';
28
31
  /**
29
32
  * NestJS Guard: validates JWT or trusts gateway-injected headers.
30
33
  */
@@ -41,9 +44,10 @@ let AuthGuard = class AuthGuard {
41
44
  if (isPublic)
42
45
  return true;
43
46
  const request = context.switchToHttp().getRequest();
44
- // Trust gateway-injected headers first
47
+ // Trust gateway-injected headers only with a valid gateway signature
45
48
  const gatewayUserId = request.headers[GATEWAY_HEADERS.USER_ID];
46
- if (gatewayUserId) {
49
+ if (gatewayUserId && isTrustedGatewayIdentity(request.headers)) {
50
+ request[GATEWAY_VERIFIED_FLAG] = true;
47
51
  request.user = {
48
52
  id: gatewayUserId,
49
53
  companyId: request.headers[GATEWAY_HEADERS.COMPANY_ID] || undefined,
@@ -54,7 +58,11 @@ let AuthGuard = class AuthGuard {
54
58
  };
55
59
  return true;
56
60
  }
57
- // Fallback to direct JWT validation
61
+ // Fallback to direct JWT validation — development only; production
62
+ // requests must arrive through the gateway.
63
+ if (!isDirectJwtFallbackAllowed()) {
64
+ throw new UnauthorizedException('Authentication required');
65
+ }
58
66
  const authHeader = request.headers.authorization;
59
67
  if (!authHeader?.startsWith('Bearer ')) {
60
68
  throw new UnauthorizedException('Missing authentication token');
@@ -1 +1 @@
1
- {"version":3,"file":"auth.guard.js","sourceRoot":"","sources":["../../src/nestjs/auth.guard.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EACL,UAAU,EAGV,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAkB,MAAM,mBAAmB,CAAC;AAEpE,+EAA+E;AAC/E,SAAS,gBAAgB,CAAC,KAAyB;IACjD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC;YAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC;AAExC;;GAEG;AAEI,IAAM,SAAS,GAAf,MAAM,SAAS;IACA;IAApB,YAAoB,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IAAG,CAAC;IAE5C,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAU,aAAa,EAAE;YACxE,OAAO,CAAC,UAAU,EAAE;YACpB,OAAO,CAAC,QAAQ,EAAE;SACnB,CAAC,CAAC;QACH,IAAI,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE1B,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QAEpD,uCAAuC;QACvC,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAC/D,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,GAAG;gBACb,EAAE,EAAE,aAAa;gBACjB,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,IAAI,SAAS;gBACnE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,IAAI,SAAS;gBAC/D,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,UAAU,CAAW,CAAC;gBAC9E,WAAW,EAAE,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,gBAAgB,CAAW,CAAC;gBAC1F,YAAY,EACV,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,KAAK,MAAM;aAC/C,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;QAED,oCAAoC;QACpC,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;QACjD,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACvC,MAAM,IAAI,qBAAqB,CAAC,8BAA8B,CAAC,CAAC;QAClE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAClC,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,UAAW,CAAC,CAAC;YAC5D,OAAO,CAAC,IAAI,GAAG;gBACb,EAAE,EAAE,OAAO,CAAC,GAAG;gBACf,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;gBAC1B,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE;gBACtC,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,KAAK;aAC/B,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,qBAAqB,CAAC,0BAA0B,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;CACF,CAAA;AAjDY,SAAS;IADrB,UAAU,EAAE;qCAEoB,SAAS;GAD7B,SAAS,CAiDrB"}
1
+ {"version":3,"file":"auth.guard.js","sourceRoot":"","sources":["../../src/nestjs/auth.guard.ts"],"names":[],"mappings":"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"}
@@ -10,7 +10,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
10
10
  import { Injectable, ForbiddenException, } from '@nestjs/common';
11
11
  import { Reflector } from '@nestjs/core';
12
12
  import { PERMISSIONS_KEY, REQUIRE_ALL_KEY, ROLES_KEY, } from './permission.decorator.js';
13
- import { IS_PUBLIC_KEY } from './auth.guard.js';
13
+ import { IS_PUBLIC_KEY, GATEWAY_VERIFIED_FLAG } from './auth.guard.js';
14
14
  /**
15
15
  * NestJS Guard: checks permissions/roles from decorators.
16
16
  * Must be used after AuthGuard so that request.user is populated.
@@ -37,9 +37,10 @@ let PermissionGuard = class PermissionGuard {
37
37
  if (user.isSuperAdmin)
38
38
  return true;
39
39
  // M2M / gateway-authenticated clients: the gateway already verified the JWT
40
- // and injected headers. Requiring human roles on top of scoped permissions
41
- // is overly restrictive for API access.
42
- const isGatewayAuth = request.headers?.['x-gateway-auth'] === 'verified';
40
+ // and signed the injected headers (AuthGuard checked the signature).
41
+ // Requiring human roles on top of scoped permissions is overly restrictive
42
+ // for API access.
43
+ const isGatewayAuth = request[GATEWAY_VERIFIED_FLAG] === true;
43
44
  // Check permissions first — they are the primary authorization mechanism
44
45
  const requiredPermissions = this.reflector.getAllAndOverride(PERMISSIONS_KEY, [context.getHandler(), context.getClass()]);
45
46
  const requireAll = this.reflector.getAllAndOverride(REQUIRE_ALL_KEY, [context.getHandler(), context.getClass()]);
@@ -1 +1 @@
1
- {"version":3,"file":"permission.guard.js","sourceRoot":"","sources":["../../src/nestjs/permission.guard.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EACL,UAAU,EAGV,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EACL,eAAe,EACf,eAAe,EACf,SAAS,GACV,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD;;;GAGG;AAEI,IAAM,eAAe,GAArB,MAAM,eAAe;IACN;IAApB,YAAoB,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IAAG,CAAC;IAE5C,WAAW,CAAC,OAAyB;QACnC,0CAA0C;QAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAU,aAAa,EAAE;YACxE,OAAO,CAAC,UAAU,EAAE;YACpB,OAAO,CAAC,QAAQ,EAAE;SACnB,CAAC,CAAC;QACH,IAAI,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE1B,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QACpD,MAAM,IAAI,GAA0B,OAAO,CAAC,IAAI,CAAC;QAEjD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,kBAAkB,CAAC,wBAAwB,CAAC,CAAC;QACzD,CAAC;QAED,4CAA4C;QAC5C,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO,IAAI,CAAC;QAEnC,4EAA4E;QAC5E,2EAA2E;QAC3E,wCAAwC;QACxC,MAAM,aAAa,GACjB,OAAO,CAAC,OAAO,EAAE,CAAC,gBAAgB,CAAC,KAAK,UAAU,CAAC;QAErD,yEAAyE;QACzE,MAAM,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAC1D,eAAe,EACf,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAC3C,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CACjD,eAAe,EACf,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAC3C,CAAC;QAEF,IAAI,sBAAsB,GAAG,IAAI,CAAC;QAClC,IAAI,mBAAmB,EAAE,MAAM,EAAE,CAAC;YAChC,sBAAsB,GAAG,UAAU;gBACjC,CAAC,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACxE,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5E,CAAC;QAED,oEAAoE;QACpE,mEAAmE;QACnE,uEAAuE;QACvE,wEAAwE;QACxE,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CACpD,SAAS,EACT,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAC3C,CAAC;QACF,IAAI,aAAa,EAAE,MAAM,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YAChF,gEAAgE;YAChE,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,aAAa,IAAI,sBAAsB,CAAC,EAAE,CAAC;gBAC3D,MAAM,IAAI,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QAED,IAAI,mBAAmB,EAAE,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAC3D,MAAM,IAAI,kBAAkB,CAAC,0BAA0B,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AAnEY,eAAe;IAD3B,UAAU,EAAE;qCAEoB,SAAS;GAD7B,eAAe,CAmE3B"}
1
+ {"version":3,"file":"permission.guard.js","sourceRoot":"","sources":["../../src/nestjs/permission.guard.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,23 @@
1
1
  import { Request, Response, NextFunction } from "express";
2
2
  import { RateLimiterAbstract } from "rate-limiter-flexible";
3
3
  import type Redis from "ioredis";
4
+ import type { RedisKeyspace } from "../redis/keyspace.js";
4
5
  export interface RateLimitConfig {
5
6
  /** Max requests per window (default: 100) */
6
7
  maxRequests?: number;
7
8
  /** Window duration in milliseconds (default: 60 000) */
8
9
  windowMs?: number;
9
- /** Redis key prefix — use unique per service to avoid collisions (default: "rl:service") */
10
+ /**
11
+ * Service keyspace (G5). With it, keys are `{app}:{env}:{service}:rl:{keyPrefix}:…`
12
+ * and `keyPrefix` is only the limiter name. Required with a Redis client
13
+ * in NODE_ENV production/staging.
14
+ */
15
+ keyspace?: RedisKeyspace;
16
+ /** Limiter name with a keyspace; the raw Redis key prefix without one (default: "rl:service") */
10
17
  keyPrefix?: string;
11
18
  /** Optional Redis client — falls back to in-memory if omitted */
12
19
  redisClient?: Redis | null;
13
- /** Extract the rate-limit key from the request. Default: X-User-Id header → IP → "unknown" */
20
+ /** Extract the rate-limit key from the request. Default: signed gateway user id → IP → "unknown" */
14
21
  keyExtractor?: (req: Request) => string;
15
22
  }
16
23
  export interface RateLimitResult {
@@ -20,4 +27,16 @@ export interface RateLimitResult {
20
27
  middleware: (req: Request, res: Response, next: NextFunction) => Promise<void>;
21
28
  }
22
29
  export declare function createRateLimiter(cfg?: RateLimitConfig): RateLimitResult;
30
+ /**
31
+ * With a keyspace: `{prefix}rl:{name}`. Without one the legacy raw prefix is
32
+ * kept for in-memory or local use only — staging and production share Redis
33
+ * with each other and with other apps, so unscoped Redis keys are refused there.
34
+ */
35
+ export declare function resolveLimiterKeyPrefix(keyPrefix: string | undefined, keyspace: RedisKeyspace | undefined, usesRedis: boolean): string;
36
+ /**
37
+ * The gateway user id only when its signature verifies — an unsigned
38
+ * x-user-id is caller-controlled, and a fresh value per request would get a
39
+ * fresh budget. Otherwise the client IP.
40
+ */
41
+ export declare function defaultKeyExtractor(req: Request): string;
23
42
  //# sourceMappingURL=create-rate-limiter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-rate-limiter.d.ts","sourceRoot":"","sources":["../../src/rate-limit/create-rate-limiter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAuC,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACjG,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AAIjC,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,WAAW,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IAC3B,8FAA8F;IAC9F,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;CACzC;AAED,MAAM,WAAW,eAAe;IAC9B,mDAAmD;IACnD,OAAO,EAAE,mBAAmB,CAAC;IAC7B,yBAAyB;IACzB,UAAU,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChF;AAID,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,eAAoB,GAAG,eAAe,CAmE5E"}
1
+ {"version":3,"file":"create-rate-limiter.d.ts","sourceRoot":"","sources":["../../src/rate-limit/create-rate-limiter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAuC,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACjG,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AAEjC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI1D,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,iGAAiG;IACjG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,WAAW,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IAC3B,oGAAoG;IACpG,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;CACzC;AAED,MAAM,WAAW,eAAe;IAC9B,mDAAmD;IACnD,OAAO,EAAE,mBAAmB,CAAC;IAC7B,yBAAyB;IACzB,UAAU,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChF;AAID,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,eAAoB,GAAG,eAAe,CAoE5E;AAMD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,QAAQ,EAAE,aAAa,GAAG,SAAS,EACnC,SAAS,EAAE,OAAO,GACjB,MAAM,CAMR;AAID;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAMxD"}
@@ -3,9 +3,11 @@
3
3
  // Factory that creates a dual-layer (Redis + memory fallback) rate limiter.
4
4
  // Available for any Express-based service.
5
5
  import { RateLimiterRedis, RateLimiterMemory } from "rate-limiter-flexible";
6
+ import { isTrustedGatewayIdentity } from "../common/gateway-signature.js";
6
7
  // ─── Factory ────────────────────────────────────────────
7
8
  export function createRateLimiter(cfg = {}) {
8
- const { maxRequests = 100, windowMs = 60_000, keyPrefix = "rl:service", redisClient = null, keyExtractor = defaultKeyExtractor, } = cfg;
9
+ const { maxRequests = 100, windowMs = 60_000, keyspace, redisClient = null, keyExtractor = defaultKeyExtractor, } = cfg;
10
+ const keyPrefix = resolveLimiterKeyPrefix(cfg.keyPrefix, keyspace, Boolean(redisClient));
9
11
  const durationSecs = Math.max(1, Math.round(windowMs / 1000));
10
12
  const memoryLimiter = new RateLimiterMemory({
11
13
  keyPrefix,
@@ -53,8 +55,32 @@ export function createRateLimiter(cfg = {}) {
53
55
  }
54
56
  return { limiter, middleware };
55
57
  }
58
+ // ─── Key prefix ─────────────────────────────────────────
59
+ const DEPLOYED_NODE_ENVS = new Set(["production", "staging"]);
60
+ /**
61
+ * With a keyspace: `{prefix}rl:{name}`. Without one the legacy raw prefix is
62
+ * kept for in-memory or local use only — staging and production share Redis
63
+ * with each other and with other apps, so unscoped Redis keys are refused there.
64
+ */
65
+ export function resolveLimiterKeyPrefix(keyPrefix, keyspace, usesRedis) {
66
+ if (keyspace)
67
+ return keyspace.key("rl", keyPrefix || "default");
68
+ if (usesRedis && DEPLOYED_NODE_ENVS.has(process.env.NODE_ENV ?? "")) {
69
+ throw new Error("createRateLimiter: a keyspace is required for Redis-backed limiters in production/staging");
70
+ }
71
+ return keyPrefix || "rl:service";
72
+ }
56
73
  // ─── Defaults ───────────────────────────────────────────
57
- function defaultKeyExtractor(req) {
58
- return req.headers["x-user-id"] || req.ip || "unknown";
74
+ /**
75
+ * The gateway user id only when its signature verifies — an unsigned
76
+ * x-user-id is caller-controlled, and a fresh value per request would get a
77
+ * fresh budget. Otherwise the client IP.
78
+ */
79
+ export function defaultKeyExtractor(req) {
80
+ const userId = req.headers["x-user-id"];
81
+ if (typeof userId === "string" && userId && isTrustedGatewayIdentity(req.headers)) {
82
+ return `user:${userId}`;
83
+ }
84
+ return `ip:${req.ip || "unknown"}`;
59
85
  }
60
86
  //# sourceMappingURL=create-rate-limiter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-rate-limiter.js","sourceRoot":"","sources":["../../src/rate-limit/create-rate-limiter.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,4EAA4E;AAC5E,2CAA2C;AAG3C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAuB,MAAM,uBAAuB,CAAC;AAyBjG,2DAA2D;AAE3D,MAAM,UAAU,iBAAiB,CAAC,MAAuB,EAAE;IACzD,MAAM,EACJ,WAAW,GAAG,GAAG,EACjB,QAAQ,GAAG,MAAM,EACjB,SAAS,GAAG,YAAY,EACxB,WAAW,GAAG,IAAI,EAClB,YAAY,GAAG,mBAAmB,GACnC,GAAG,GAAG,CAAC;IAER,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC;IAE9D,MAAM,aAAa,GAAG,IAAI,iBAAiB,CAAC;QAC1C,SAAS;QACT,MAAM,EAAE,WAAW;QACnB,QAAQ,EAAE,YAAY;KACvB,CAAC,CAAC;IAEH,IAAI,OAA4B,CAAC;IAEjC,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,GAAG,IAAI,gBAAgB,CAAC;YAC7B,WAAW,EAAE,WAAW;YACxB,SAAS;YACT,MAAM,EAAE,WAAW;YACnB,QAAQ,EAAE,YAAY;YACtB,aAAa,EAAE,CAAC;YAChB,gBAAgB,EAAE,aAAa;SAChC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,aAAa,CAAC;IAC1B,CAAC;IAED,wDAAwD;IAExD,KAAK,UAAU,UAAU,CACvB,GAAY,EACZ,GAAa,EACb,IAAkB;QAElB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAE1C,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;YAChD,GAAG,CAAC,SAAS,CAAC,uBAAuB,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;YAC/D,GAAG,CAAC,SAAS,CACX,mBAAmB,EACnB,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CACzD,CAAC;YACF,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,MAAW,EAAE,CAAC;YACrB,iDAAiD;YACjD,IAAI,OAAO,MAAM,EAAE,YAAY,KAAK,QAAQ,EAAE,CAAC;gBAC7C,OAAO,CAAC,KAAK,CAAC,cAAc,SAAS,qBAAqB,EAAE,MAAM,EAAE,OAAO,IAAI,MAAM,CAAC,CAAC;gBACvF,OAAO,IAAI,EAAE,CAAC;YAChB,CAAC;YACD,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;YAChD,GAAG,CAAC,SAAS,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAAC;YAC1C,GAAG,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC;YACpE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,4CAA4C;aACtD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;AACjC,CAAC;AAED,2DAA2D;AAE3D,SAAS,mBAAmB,CAAC,GAAY;IACvC,OAAQ,GAAG,CAAC,OAAO,CAAC,WAAW,CAAY,IAAI,GAAG,CAAC,EAAE,IAAI,SAAS,CAAC;AACrE,CAAC"}
1
+ {"version":3,"file":"create-rate-limiter.js","sourceRoot":"","sources":["../../src/rate-limit/create-rate-limiter.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- export { createRateLimiter } from "./create-rate-limiter.js";
1
+ export { createRateLimiter, defaultKeyExtractor, resolveLimiterKeyPrefix } from "./create-rate-limiter.js";
2
2
  export type { RateLimitConfig, RateLimitResult } from "./create-rate-limiter.js";
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rate-limit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rate-limit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAC3G,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC"}
@@ -1,2 +1,2 @@
1
- export { createRateLimiter } from "./create-rate-limiter.js";
1
+ export { createRateLimiter, defaultKeyExtractor, resolveLimiterKeyPrefix } from "./create-rate-limiter.js";
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rate-limit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rate-limit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { createRedisKeyspace, resolveRedisKeyApp, resolveRedisKeyEnv, encodeRedisKeyPart, hashRedisKeyPart, DEFAULT_REDIS_KEY_APP, DEFAULT_REDIS_KEY_ENV, } from "./keyspace.js";
2
+ export type { RedisKeyspace, RedisKeyspaceOptions, RedisKeyPart } from "./keyspace.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createRedisKeyspace, resolveRedisKeyApp, resolveRedisKeyEnv, encodeRedisKeyPart, hashRedisKeyPart, DEFAULT_REDIS_KEY_APP, DEFAULT_REDIS_KEY_ENV, } from "./keyspace.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,46 @@
1
+ export type RedisKeyPart = string | number;
2
+ export interface RedisKeyspaceOptions {
3
+ /** Canonical owning service name (the service that writes the key), e.g. "api-gateway", "sms". */
4
+ service: string;
5
+ /** Defaults to REDIS_KEY_APP, then "pendoadmin". */
6
+ app?: string;
7
+ /** Defaults to resolveRedisKeyEnv(). */
8
+ env?: string;
9
+ }
10
+ export interface RedisKeyspace {
11
+ readonly app: string;
12
+ readonly env: string;
13
+ readonly service: string;
14
+ /** `{app}:{env}:{service}:` — every key and pattern starts with this. */
15
+ readonly prefix: string;
16
+ /**
17
+ * The prefix without its trailing ':' — pass as `environment` to
18
+ * @heavybit/cache-package so its `${environment}|k:v` keys are anchored too.
19
+ */
20
+ readonly cacheEnvironment: string;
21
+ /** `{prefix}{purpose}[:{part}...]`, each part encoded so it can't fake extra segments. */
22
+ key(purpose: string, ...parts: RedisKeyPart[]): string;
23
+ /** SCAN pattern anchored on the prefix: `{prefix}{purpose}:{suffix}` (suffix defaults to "*"). */
24
+ pattern(purpose: string, suffix?: string): string;
25
+ }
26
+ type EnvSource = Record<string, string | undefined>;
27
+ export declare const DEFAULT_REDIS_KEY_APP = "pendoadmin";
28
+ export declare const DEFAULT_REDIS_KEY_ENV = "dev";
29
+ export declare function resolveRedisKeyApp(source?: EnvSource): string;
30
+ /**
31
+ * REDIS_KEY_ENV, else CACHE_KEY_PREFIX ("prod" / "staging" in compose), else
32
+ * "dev". Throws in NODE_ENV production/staging when neither is set, so a
33
+ * deployed service can never write unscoped or "dev" keys.
34
+ */
35
+ export declare function resolveRedisKeyEnv(source?: EnvSource): string;
36
+ /**
37
+ * Percent-encodes a variable key part. Beyond encodeURIComponent this also
38
+ * encodes the glob characters SCAN patterns interpret, so a part can never
39
+ * add segments or widen a pattern.
40
+ */
41
+ export declare function encodeRedisKeyPart(part: RedisKeyPart): string;
42
+ /** sha256 hex of a long or sensitive part (URLs, tokens). Never put a raw token in a key. */
43
+ export declare function hashRedisKeyPart(value: string): string;
44
+ export declare function createRedisKeyspace(options: RedisKeyspaceOptions): RedisKeyspace;
45
+ export {};
46
+ //# sourceMappingURL=keyspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyspace.d.ts","sourceRoot":"","sources":["../../src/redis/keyspace.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,oBAAoB;IACnC,kGAAkG;IAClG,OAAO,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,0FAA0F;IAC1F,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IACvD,kGAAkG;IAClG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACnD;AAED,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAIpD,eAAO,MAAM,qBAAqB,eAAe,CAAC;AAClD,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAgB3C,wBAAgB,kBAAkB,CAAC,MAAM,GAAE,SAAuB,GAAG,MAAM,CAE1E;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,GAAE,SAAuB,GAAG,MAAM,CAS1E;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAI7D;AAED,6FAA6F;AAC7F,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtD;AAID,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAqBhF"}
@@ -0,0 +1,82 @@
1
+ // pendoadmin-shared-lib/src/redis/keyspace.ts
2
+ //
3
+ // One Redis installation is shared by other applications and by PendoAdmin
4
+ // staging and production, so every PendoAdmin key is namespaced by app,
5
+ // environment and owning service:
6
+ //
7
+ // {app}:{env}:{service}:{purpose}[:{part}...]
8
+ // e.g. pendoadmin:prod:api-gateway:authz:018ea4b0-…
9
+ //
10
+ // Build every key and SCAN pattern through createRedisKeyspace(); never
11
+ // hand-write prefixes (tracker decisions G5 / D39).
12
+ import { createHash } from "node:crypto";
13
+ // ─── Constants ──────────────────────────────────────────
14
+ export const DEFAULT_REDIS_KEY_APP = "pendoadmin";
15
+ export const DEFAULT_REDIS_KEY_ENV = "dev";
16
+ /** NODE_ENV values that must name their key environment explicitly. */
17
+ const DEPLOYED_NODE_ENVS = new Set(["production", "staging"]);
18
+ const SEGMENT_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
19
+ // ─── Segment resolution ─────────────────────────────────
20
+ function assertSegment(kind, value) {
21
+ if (!SEGMENT_RE.test(value)) {
22
+ throw new Error(`Redis keyspace: invalid ${kind} "${value}" (lower-case kebab-case [a-z0-9-] only)`);
23
+ }
24
+ return value;
25
+ }
26
+ export function resolveRedisKeyApp(source = process.env) {
27
+ return assertSegment("app", source.REDIS_KEY_APP?.trim() || DEFAULT_REDIS_KEY_APP);
28
+ }
29
+ /**
30
+ * REDIS_KEY_ENV, else CACHE_KEY_PREFIX ("prod" / "staging" in compose), else
31
+ * "dev". Throws in NODE_ENV production/staging when neither is set, so a
32
+ * deployed service can never write unscoped or "dev" keys.
33
+ */
34
+ export function resolveRedisKeyEnv(source = process.env) {
35
+ const explicit = source.REDIS_KEY_ENV?.trim() || source.CACHE_KEY_PREFIX?.trim();
36
+ if (explicit)
37
+ return assertSegment("env", explicit);
38
+ const nodeEnv = source.NODE_ENV?.trim() ?? "";
39
+ if (DEPLOYED_NODE_ENVS.has(nodeEnv)) {
40
+ throw new Error(`Redis keyspace: REDIS_KEY_ENV or CACHE_KEY_PREFIX must be set when NODE_ENV=${nodeEnv}`);
41
+ }
42
+ return DEFAULT_REDIS_KEY_ENV;
43
+ }
44
+ // ─── Part encoding ──────────────────────────────────────
45
+ /**
46
+ * Percent-encodes a variable key part. Beyond encodeURIComponent this also
47
+ * encodes the glob characters SCAN patterns interpret, so a part can never
48
+ * add segments or widen a pattern.
49
+ */
50
+ export function encodeRedisKeyPart(part) {
51
+ const value = String(part);
52
+ if (!value)
53
+ throw new Error("Redis keyspace: key parts must not be empty");
54
+ return encodeURIComponent(value).replace(/[*?[\]!'()]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
55
+ }
56
+ /** sha256 hex of a long or sensitive part (URLs, tokens). Never put a raw token in a key. */
57
+ export function hashRedisKeyPart(value) {
58
+ return createHash("sha256").update(value).digest("hex");
59
+ }
60
+ // ─── Factory ────────────────────────────────────────────
61
+ export function createRedisKeyspace(options) {
62
+ const app = options.app !== undefined ? assertSegment("app", options.app) : resolveRedisKeyApp();
63
+ const env = options.env !== undefined ? assertSegment("env", options.env) : resolveRedisKeyEnv();
64
+ const service = assertSegment("service", options.service);
65
+ const cacheEnvironment = `${app}:${env}:${service}`;
66
+ const prefix = `${cacheEnvironment}:`;
67
+ return {
68
+ app,
69
+ env,
70
+ service,
71
+ prefix,
72
+ cacheEnvironment,
73
+ key(purpose, ...parts) {
74
+ const head = `${prefix}${assertSegment("purpose", purpose)}`;
75
+ return parts.length ? `${head}:${parts.map(encodeRedisKeyPart).join(":")}` : head;
76
+ },
77
+ pattern(purpose, suffix = "*") {
78
+ return `${prefix}${assertSegment("purpose", purpose)}:${suffix}`;
79
+ },
80
+ };
81
+ }
82
+ //# sourceMappingURL=keyspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyspace.js","sourceRoot":"","sources":["../../src/redis/keyspace.ts"],"names":[],"mappings":"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"}
@@ -213,5 +213,7 @@ export declare const GATEWAY_HEADERS: {
213
213
  readonly IS_SUPERADMIN: "x-is-superadmin";
214
214
  readonly CORRELATION_ID: "x-correlation-id";
215
215
  readonly SERVICE_NAME: "x-service-name";
216
+ readonly GATEWAY_SIGNATURE: "x-gateway-signature";
217
+ readonly GATEWAY_TIMESTAMP: "x-gateway-ts";
216
218
  };
217
219
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -48,5 +48,7 @@ export const GATEWAY_HEADERS = {
48
48
  IS_SUPERADMIN: 'x-is-superadmin',
49
49
  CORRELATION_ID: 'x-correlation-id',
50
50
  SERVICE_NAME: 'x-service-name',
51
+ GATEWAY_SIGNATURE: 'x-gateway-signature',
52
+ GATEWAY_TIMESTAMP: 'x-gateway-ts',
51
53
  };
52
54
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,oBAAoB;AACpB,iDAAiD;AA2EjD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAe,EACf,kBAAkC;IAElC,IAAI,IAAI,CAAC,YAAY,IAAI,kBAAkB,EAAE,CAAC;QAC5C,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC;AACxB,CAAC;AAED,oDAAoD;AACpD,MAAM,CAAC,MAAM,qBAAqB,GAAG,sCAAsC,CAAC;AAE5E,8FAA8F;AAC9F,MAAM,UAAU,qBAAqB,CACnC,IAA2D;IAE3D,OAAO,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,qBAAqB,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;AACnF,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAmD,EACnD,kBAAkC;IAElC,IAAI,qBAAqB,CAAC,IAAI,CAAC;QAAE,OAAO,kBAAkB,IAAI,SAAS,CAAC;IACxE,IAAI,CAAC,IAAI,CAAC,SAAS;QAAE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;IACtG,OAAO,IAAI,CAAC,SAAS,CAAC;AACxB,CAAC;AAwJD,iDAAiD;AACjD,uBAAuB;AACvB,iDAAiD;AAEjD,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,OAAO,EAAE,WAAW;IACpB,UAAU,EAAE,cAAc;IAC1B,UAAU,EAAE,cAAc;IAC1B,UAAU,EAAE,cAAc;IAC1B,gBAAgB,EAAE,oBAAoB;IACtC,aAAa,EAAE,iBAAiB;IAChC,cAAc,EAAE,kBAAkB;IAClC,YAAY,EAAE,gBAAgB;CACtB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,oBAAoB;AACpB,iDAAiD;AA2EjD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAe,EACf,kBAAkC;IAElC,IAAI,IAAI,CAAC,YAAY,IAAI,kBAAkB,EAAE,CAAC;QAC5C,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC;AACxB,CAAC;AAED,oDAAoD;AACpD,MAAM,CAAC,MAAM,qBAAqB,GAAG,sCAAsC,CAAC;AAE5E,8FAA8F;AAC9F,MAAM,UAAU,qBAAqB,CACnC,IAA2D;IAE3D,OAAO,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,qBAAqB,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;AACnF,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAmD,EACnD,kBAAkC;IAElC,IAAI,qBAAqB,CAAC,IAAI,CAAC;QAAE,OAAO,kBAAkB,IAAI,SAAS,CAAC;IACxE,IAAI,CAAC,IAAI,CAAC,SAAS;QAAE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;IACtG,OAAO,IAAI,CAAC,SAAS,CAAC;AACxB,CAAC;AAwJD,iDAAiD;AACjD,uBAAuB;AACvB,iDAAiD;AAEjD,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,OAAO,EAAE,WAAW;IACpB,UAAU,EAAE,cAAc;IAC1B,UAAU,EAAE,cAAc;IAC1B,UAAU,EAAE,cAAc;IAC1B,gBAAgB,EAAE,oBAAoB;IACtC,aAAa,EAAE,iBAAiB;IAChC,cAAc,EAAE,kBAAkB;IAClC,YAAY,EAAE,gBAAgB;IAC9B,iBAAiB,EAAE,qBAAqB;IACxC,iBAAiB,EAAE,cAAc;CACzB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heavybit/pendoadmin-shared-lib",
3
- "version": "1.6.0",
3
+ "version": "1.8.0",
4
4
  "description": "Shared library for PendoAdmin microservices",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -29,7 +29,7 @@
29
29
  "build": "tsc",
30
30
  "dev": "tsc --watch",
31
31
  "clean": "rm -rf dist",
32
- "test": "npm run build && node --test tests/"
32
+ "test": "npm run build && node --test tests/*.test.mjs"
33
33
  },
34
34
  "exports": {
35
35
  ".": "./dist/index.js",
@@ -45,7 +45,8 @@
45
45
  "./rate-limit": "./dist/rate-limit/index.js",
46
46
  "./socket": "./dist/socket/index.js",
47
47
  "./tenant": "./dist/tenant/index.js",
48
- "./scheduling": "./dist/scheduling/index.js"
48
+ "./scheduling": "./dist/scheduling/index.js",
49
+ "./redis": "./dist/redis/index.js"
49
50
  },
50
51
  "typesVersions": {
51
52
  "*": {
@@ -87,6 +88,9 @@
87
88
  ],
88
89
  "scheduling": [
89
90
  "dist/scheduling/index.d.ts"
91
+ ],
92
+ "redis": [
93
+ "dist/redis/index.d.ts"
90
94
  ]
91
95
  }
92
96
  },
@@ -0,0 +1,124 @@
1
+ import crypto from 'node:crypto';
2
+
3
+ /**
4
+ * Signed gateway identity.
5
+ *
6
+ * The api-gateway (and any internal service forwarding a caller's identity)
7
+ * signs the identity headers it injects with GATEWAY_SIGNING_SECRET. Downstream
8
+ * services verify the signature before trusting x-user-id / x-is-superadmin /
9
+ * x-user-permissions, so a request that reaches a service port directly, or
10
+ * slips past the gateway with its own headers, cannot impersonate anyone.
11
+ *
12
+ * The api-gateway keeps its own copy of the signer
13
+ * (api-gateway/src/utils/gateway-signature.ts). Any change to the canonical
14
+ * string below must be made in both places — the shared test vector in both
15
+ * test suites pins the format.
16
+ */
17
+
18
+ export const GATEWAY_SIGNATURE_HEADER = 'x-gateway-signature';
19
+ export const GATEWAY_TIMESTAMP_HEADER = 'x-gateway-ts';
20
+ const SIGNATURE_VERSION = 'v1';
21
+
22
+ /** Identity headers covered by the signature, in canonical order. */
23
+ export const GATEWAY_IDENTITY_HEADERS = [
24
+ 'x-user-id',
25
+ 'x-user-email',
26
+ 'x-company-id',
27
+ 'x-company-slug',
28
+ 'x-user-roles',
29
+ 'x-user-permissions',
30
+ 'x-is-superadmin',
31
+ 'x-otp-verified',
32
+ ] as const;
33
+
34
+ /** Default allowed clock skew between signer and verifier. */
35
+ export const GATEWAY_SIGNATURE_MAX_SKEW_SECONDS = 60;
36
+
37
+ type HeaderBag = Record<string, string | string[] | undefined>;
38
+
39
+ function headerValue(headers: HeaderBag, name: string): string {
40
+ const value = headers[name];
41
+ return (Array.isArray(value) ? value[0] : value) ?? '';
42
+ }
43
+
44
+ function canonicalString(headers: HeaderBag, timestamp: string): string {
45
+ return [
46
+ SIGNATURE_VERSION,
47
+ timestamp,
48
+ headerValue(headers, 'x-correlation-id'),
49
+ ...GATEWAY_IDENTITY_HEADERS.map((name) => headerValue(headers, name)),
50
+ ].join('\n');
51
+ }
52
+
53
+ function hmac(secret: string, payload: string): string {
54
+ return crypto.createHmac('sha256', secret).update(payload).digest('hex');
55
+ }
56
+
57
+ /**
58
+ * Signature headers for the identity headers already present in `headers`
59
+ * (lower-case names). Merge the result into the outgoing request headers.
60
+ */
61
+ export function signGatewayIdentity(
62
+ headers: HeaderBag,
63
+ secret: string,
64
+ nowMs: number = Date.now(),
65
+ ): Record<typeof GATEWAY_SIGNATURE_HEADER | typeof GATEWAY_TIMESTAMP_HEADER, string> {
66
+ const timestamp = String(Math.floor(nowMs / 1000));
67
+ return {
68
+ [GATEWAY_SIGNATURE_HEADER]: hmac(secret, canonicalString(headers, timestamp)),
69
+ [GATEWAY_TIMESTAMP_HEADER]: timestamp,
70
+ };
71
+ }
72
+
73
+ export interface VerifyGatewayIdentityOptions {
74
+ maxSkewSeconds?: number;
75
+ nowMs?: number;
76
+ }
77
+
78
+ /** True when the identity headers carry a valid, fresh signature from `secret`. */
79
+ export function verifyGatewayIdentity(
80
+ headers: HeaderBag,
81
+ secret: string,
82
+ options: VerifyGatewayIdentityOptions = {},
83
+ ): boolean {
84
+ if (!secret) return false;
85
+ const { maxSkewSeconds = GATEWAY_SIGNATURE_MAX_SKEW_SECONDS, nowMs = Date.now() } = options;
86
+
87
+ const timestamp = headerValue(headers, GATEWAY_TIMESTAMP_HEADER);
88
+ const signature = headerValue(headers, GATEWAY_SIGNATURE_HEADER);
89
+ if (!/^\d+$/.test(timestamp) || !/^[0-9a-f]{64}$/.test(signature)) return false;
90
+ if (Math.abs(nowMs / 1000 - Number(timestamp)) > maxSkewSeconds) return false;
91
+
92
+ const expected = Buffer.from(hmac(secret, canonicalString(headers, timestamp)), 'hex');
93
+ const provided = Buffer.from(signature, 'hex');
94
+ return expected.length === provided.length && crypto.timingSafeEqual(expected, provided);
95
+ }
96
+
97
+ /**
98
+ * The secret services sign and verify gateway identity with. Unset means
99
+ * unsigned identity is accepted only outside production (see
100
+ * isUnsignedGatewayIdentityAllowed).
101
+ */
102
+ export function gatewaySigningSecret(): string {
103
+ return process.env.GATEWAY_SIGNING_SECRET || '';
104
+ }
105
+
106
+ /** Local development may run services without a signing secret; production never trusts unsigned identity. */
107
+ export function isUnsignedGatewayIdentityAllowed(): boolean {
108
+ return !gatewaySigningSecret() && process.env.NODE_ENV !== 'production';
109
+ }
110
+
111
+ /**
112
+ * Whether a request's gateway identity headers can be trusted: a valid
113
+ * signature when a secret is configured, otherwise only outside production.
114
+ */
115
+ export function isTrustedGatewayIdentity(headers: HeaderBag): boolean {
116
+ const secret = gatewaySigningSecret();
117
+ if (secret) return verifyGatewayIdentity(headers, secret);
118
+ return isUnsignedGatewayIdentityAllowed();
119
+ }
120
+
121
+ /** Direct JWT validation is a development convenience only; production requests must come through the gateway. */
122
+ export function isDirectJwtFallbackAllowed(): boolean {
123
+ return process.env.NODE_ENV !== 'production';
124
+ }
@@ -5,3 +5,4 @@ export * from './uuid.utils.js';
5
5
  export * from './response.utils.js';
6
6
  export * from './timezone.utils.js';
7
7
  export * from './permission.utils.js';
8
+ export * from './gateway-signature.js';