@90soft/parse-server-kit 2.8.2 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md CHANGED
@@ -594,6 +594,30 @@ a tree holding both compiled and source copies — every class registers twice.
594
594
 
595
595
  `getUsersRoles` costs one query per **role** (capped at 100), not per user.
596
596
 
597
+ ### Role cache (opt-in, off by default)
598
+
599
+ ```ts
600
+ function configureRoleCache(config: {ttlMs: number; maxUsers?: number} | false): void;
601
+ function invalidateRoles(userId?: string): void; // no arg = everyone
602
+ function roleCacheEnabled(): boolean;
603
+ function roleCacheStats(): {enabled: boolean; size: number; ttlMs: number | null};
604
+ ```
605
+
606
+ `@CloudFunction({requireRoles})` and `getUserRoles()` each cost a database
607
+ round-trip per call. Role membership rarely changes, so it caches well — but a
608
+ **revoked role keeps working until the entry expires**, which is why nothing
609
+ happens until you opt in:
610
+
611
+ ```ts
612
+ configureRoleCache({ttlMs: 30_000}); // global
613
+ @CloudFunction({requireRoles: [...], roleCacheMs: 0}) // this endpoint never caches
614
+ ```
615
+
616
+ Call `invalidateRoles(userId)` wherever you grant or revoke, and the TTL becomes
617
+ a backstop for changes made outside your code rather than the primary control.
618
+ `maxUsers` (default 10000) bounds memory; the oldest entry is evicted past it.
619
+ There is no timer — entries expire on read.
620
+
597
621
  ---
598
622
 
599
623
  ## Constants
package/README.md CHANGED
@@ -506,6 +506,33 @@ importFiles(join(__dirname, 'cloudCode/models'), {extensions: ['.js', '.ts']});
506
506
  Point it at one directory or the other, never a tree holding both a compiled and
507
507
  a source copy — that registers every class twice.
508
508
 
509
+ ### Role Cache (opt-in)
510
+
511
+ `@CloudFunction({requireRoles})` and `getUserRoles()` each cost a database
512
+ round-trip. Role membership rarely changes, so caching it removes that
513
+ round-trip — at the cost of a revoked role continuing to work until the entry
514
+ expires. That trade is yours to make, so the cache does nothing until you turn
515
+ it on:
516
+
517
+ ```ts
518
+ import {configureRoleCache, invalidateRoles} from '@90soft/parse-server-kit';
519
+
520
+ configureRoleCache({ttlMs: 30_000}); // global; omit entirely to stay off
521
+
522
+ // Opt a sensitive endpoint out, whatever the global policy says
523
+ @CloudFunction({requireRoles: [UserRoles.ADMIN], roleCacheMs: 0})
524
+ static async deleteEverything(req) { ... }
525
+
526
+ // Wherever you grant or revoke, drop the entry immediately
527
+ await role.getUsers().remove(user);
528
+ await role.save(null, {useMasterKey: true});
529
+ invalidateRoles(user.id);
530
+ ```
531
+
532
+ With `invalidateRoles` wired into your own grant/revoke paths, the TTL only
533
+ covers changes made outside your code (a dashboard edit, a direct database
534
+ write). `configureRoleCache(false)` disables it and clears everything held.
535
+
509
536
  ### Middleware
510
537
 
511
538
  ```ts
@@ -1 +1 @@
1
- {"version":3,"file":"cloudDecorator.d.ts","sourceRoot":"","sources":["../../src/decorators/cloudDecorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAMtE,KAAK,oBAAoB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;AAErF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,oBAAoB,QAE9D;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,IAE7C,QAAQ,GAAG,EACX,aAAa,MAAM,EACnB,aAAa,kBAAkB,GAAG,SAAS,wBAsC9C;AAoCD,wBAAgB,sBAAsB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,YA5E5D,GAAG,eACE,MAAM,eACN,kBAAkB,GAAG,SAAS,wBAgF9C"}
1
+ {"version":3,"file":"cloudDecorator.d.ts","sourceRoot":"","sources":["../../src/decorators/cloudDecorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAOtE,KAAK,oBAAoB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;AAErF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,oBAAoB,QAE9D;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,IAE7C,QAAQ,GAAG,EACX,aAAa,MAAM,EACnB,aAAa,kBAAkB,GAAG,SAAS,wBAsC9C;AAkED,wBAAgB,sBAAsB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,YA1G5D,GAAG,eACE,MAAM,eACN,kBAAkB,GAAG,SAAS,wBA8G9C"}
@@ -4,6 +4,7 @@ exports.onFunctionRegistered = onFunctionRegistered;
4
4
  exports.CloudFunction = CloudFunction;
5
5
  exports.ProtectedCloudFunction = ProtectedCloudFunction;
6
6
  const helper_1 = require("../utils/helper");
7
+ const roleCache_1 = require("../utils/roleCache");
7
8
  const cloudRegistry_1 = require("./cloudRegistry");
8
9
  const swaggerRegistry_1 = require("../swagger/swaggerRegistry");
9
10
  const functionHooks = [];
@@ -43,28 +44,51 @@ function CloudFunction(config) {
43
44
  return descriptor;
44
45
  };
45
46
  }
46
- async function checkUserRoles(request, config) {
47
- const user = request.user;
48
- if (!user) {
49
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Authentication required');
47
+ /**
48
+ * The roles this user holds, as far as this check needs to know.
49
+ *
50
+ * Two shapes, because the cache changes what is worth asking for. Uncached, the
51
+ * query is narrowed to the roles this function actually requires — the cheapest
52
+ * question, and exactly what this has always done. Cached, the full list is
53
+ * fetched instead: it answers every function's question, not just this one, so
54
+ * one round-trip serves the whole request and every later one until it expires.
55
+ */
56
+ async function resolveRoleNames(user, config) {
57
+ const useCache = (0, roleCache_1.roleCacheEnabled)() && config.roleCacheMs !== 0;
58
+ if (!useCache) {
59
+ const roleQuery = new Parse.Query('_Role');
60
+ roleQuery.containedIn('name', config.requireRoles);
61
+ roleQuery.equalTo('users', user);
62
+ const [error, roles] = await (0, helper_1.catchError)(roleQuery.find({ useMasterKey: true }));
63
+ if (error) {
64
+ throw new Parse.Error(Parse.Error.OTHER_CAUSE, 'Authorization check failed');
65
+ }
66
+ return roles.map(role => role.get('name'));
50
67
  }
51
- if (!config.requireRoles || config.requireRoles.length === 0)
52
- return;
68
+ const cached = (0, roleCache_1.readCachedRoles)(user.id, config.roleCacheMs);
69
+ if (cached)
70
+ return cached;
53
71
  const roleQuery = new Parse.Query('_Role');
54
- roleQuery.containedIn('name', config.requireRoles);
55
72
  roleQuery.equalTo('users', user);
56
- const [error, userRoles] = await (0, helper_1.catchError)(roleQuery.find({ useMasterKey: true }));
73
+ const [error, roles] = await (0, helper_1.catchError)(roleQuery.find({ useMasterKey: true }));
57
74
  if (error) {
58
75
  throw new Parse.Error(Parse.Error.OTHER_CAUSE, 'Authorization check failed');
59
76
  }
60
- let hasPermission = false;
61
- if (config.requireAllRoles) {
62
- const userRoleNames = userRoles.map(role => role.get('name'));
63
- hasPermission = config.requireRoles.every(role => userRoleNames.includes(role));
64
- }
65
- else {
66
- hasPermission = userRoles.length > 0;
77
+ const names = roles.map(role => role.get('name'));
78
+ (0, roleCache_1.writeCachedRoles)(user.id, names, config.roleCacheMs);
79
+ return names;
80
+ }
81
+ async function checkUserRoles(request, config) {
82
+ const user = request.user;
83
+ if (!user) {
84
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Authentication required');
67
85
  }
86
+ if (!config.requireRoles || config.requireRoles.length === 0)
87
+ return;
88
+ const userRoleNames = await resolveRoleNames(user, config);
89
+ const hasPermission = config.requireAllRoles
90
+ ? config.requireRoles.every(role => userRoleNames.includes(role))
91
+ : config.requireRoles.some(role => userRoleNames.includes(role));
68
92
  if (!hasPermission) {
69
93
  const msg = config.customErrorMessage ||
70
94
  `Access denied. Required ${config.requireAllRoles ? 'all' : 'one of'} these roles: ${config.requireRoles.join(', ')}`;
@@ -1 +1 @@
1
- {"version":3,"file":"cloudDecorator.js","sourceRoot":"","sources":["../../src/decorators/cloudDecorator.ts"],"names":[],"mappings":";;AAQA,oDAEC;AAED,sCA0CC;AAoCD,wDAMC;AA/FD,4CAA2C;AAC3C,mDAAsD;AACtD,gEAA2D;AAI3D,MAAM,aAAa,GAA2B,EAAE,CAAC;AACjD,SAAgB,oBAAoB,CAAC,IAA0B;IAC7D,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,SAAgB,aAAa,CAAC,MAAmB;IAC/C,OAAO,UACL,MAAW,EACX,WAAmB,EACnB,UAA2C;QAE3C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,UAAU,GAAG,MAAM,CAAC,wBAAwB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,qCAAqC,WAAW,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC;QAExC,0BAA0B;QAC1B,UAAU,CAAC,KAAK,GAAG,KAAK,WAAW,GAAG,IAAW;YAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAgC,CAAC;YACvD,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;gBACxB,MAAM,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACxC,CAAC;YACD,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1C,CAAC,CAAC;QAEF,MAAM,QAAQ,GAA0B;YACtC,IAAI,EAAE,WAAW;YACjB,MAAM;YACN,OAAO,EAAE,UAAU,CAAC,KAAK;SAC1B,CAAC;QACF,qCAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAEzC,wEAAwE;QACxE,2EAA2E;QAC3E,iCAAe,CAAC,yBAAyB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAE/D,+BAA+B;QAC/B,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YACjC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACpC,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,OAAoC,EACpC,MAAmB;IAEnB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,EAAE,yBAAyB,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAErE,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3C,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;IACnD,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAEjC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,MAAM,IAAA,mBAAU,EAAC,SAAS,CAAC,IAAI,CAAC,EAAC,YAAY,EAAE,IAAI,EAAC,CAAC,CAAC,CAAC;IAClF,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,4BAA4B,CAAC,CAAC;IAC/E,CAAC;IAED,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,MAAM,aAAa,GAAG,SAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/D,aAAa,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAClF,CAAC;SAAM,CAAC;QACN,aAAa,GAAG,SAAU,CAAC,MAAM,GAAG,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,MAAM,CAAC,kBAAkB;YACnC,2BAA2B,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,iBAAiB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACxH,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC;AAED,SAAgB,sBAAsB,CAAC,SAA+B,EAAE;IACtE,OAAO,aAAa,CAAC;QACnB,OAAO,EAAE,CAAC,MAAM,CAAC;QACjB,UAAU,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE;QACjC,GAAG,MAAM;KACV,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"cloudDecorator.js","sourceRoot":"","sources":["../../src/decorators/cloudDecorator.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,17 @@ export interface RouteConfig {
20
20
  description?: string;
21
21
  requireRoles?: string[];
22
22
  requireAllRoles?: boolean;
23
+ /**
24
+ * Overrides the global role cache for this function only.
25
+ *
26
+ * `0` opts out entirely — the role check always hits the database, whatever
27
+ * `configureRoleCache` says. Use it on the few endpoints where acting on a
28
+ * just-revoked role is unacceptable. A positive number sets a shorter or
29
+ * longer TTL than the global one. Omitted, the global policy applies.
30
+ *
31
+ * Has no effect unless `configureRoleCache()` has turned the cache on.
32
+ */
33
+ roleCacheMs?: number;
23
34
  customErrorMessage?: string;
24
35
  swagger?: SwaggerDocConfig;
25
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cloudTypes.d.ts","sourceRoot":"","sources":["../../../src/decorators/types/cloudTypes.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;AAErE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;CACnE;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,UAAU,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,eAAe,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACtE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
1
+ {"version":3,"file":"cloudTypes.d.ts","sourceRoot":"","sources":["../../../src/decorators/types/cloudTypes.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;AAErE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;CACnE;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,UAAU,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,eAAe,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACtE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
package/dist/index.d.ts CHANGED
@@ -20,6 +20,8 @@ export { UserRoles, roleKey, MAX_QUERY_LIMIT } from './utils/constants';
20
20
  export type { RoleString } from './utils/constants';
21
21
  export { catchError, getUserRoles, getUsersRoles, formatCount, generateRandomPassword, generateRandomInteger, generateRandomString, sleep } from './utils/helper';
22
22
  export { importFiles } from './utils/dynamicImport';
23
+ export { configureRoleCache, invalidateRoles, roleCacheEnabled, roleCacheStats } from './utils/roleCache';
24
+ export type { RoleCacheOptions } from './utils/roleCache';
23
25
  export { validateFunctionRoutes, validateEntityRoutes, restrictRoutes, removeResultMiddleware, conditionalJsonMiddleware } from './middleware/middleware';
24
26
  export { checkRateLimit } from './middleware/rateLimit';
25
27
  export { createSchemaConfig } from './database/schema';
@@ -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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"}
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // @90soft/parse-server-kit — complete toolkit for Parse Server
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.getUserRoles = exports.catchError = exports.MAX_QUERY_LIMIT = exports.roleKey = exports.UserRoles = exports.cloneAcl = exports.syncImageAcl = exports.implementACL = exports.BaseModel = exports.applyMongoValidators = exports.getValidators = exports.validateOrThrow = exports.validateObject = exports.classNames = exports.RouteRegistry = exports.Route = exports.CronRegistry = exports.CronSchedule = exports.Cron = exports.TriggerRegistry = exports.AfterEvent = exports.BeforeSubscribe = exports.BeforeConnect = exports.AfterSaveConfig = exports.BeforeSaveConfig = exports.AfterFindFile = exports.BeforeFindFile = exports.AfterDeleteFile = exports.BeforeDeleteFile = exports.AfterSaveFile = exports.BeforeSaveFile = exports.BeforePasswordResetRequest = exports.AfterLogout = exports.AfterLogin = exports.BeforeLogin = exports.AfterFind = exports.BeforeFind = exports.AfterDelete = exports.BeforeDelete = exports.AfterSave = exports.BeforeSave = exports.CloudFunctionRegistry = exports.onFunctionRegistered = exports.ProtectedCloudFunction = exports.CloudFunction = exports.onFieldRegistered = exports.onClassRegistered = exports.getSchemaDefinition = exports.ParseField = exports.ParseClass = void 0;
5
- exports.setupSwagger = exports.getSwaggerJson = exports.generateSwaggerSpec = exports.SwaggerRegistry = exports.NO_AMBIENT_TRANSACTION = exports.withAmbientSession = exports.CONFLICT_MESSAGE = exports.CONFLICT = exports.useTransactionAdapter = exports.currentSession = exports.inTransaction = exports.withTransaction = exports.Transactional = exports.VERSION_CONFLICT_MESSAGE = exports.VERSION_CONFLICT = exports.createVersionedMongoAdapter = exports.VersionRegistry = exports.ParseVersionField = exports.getFieldIndexes = exports.getCompoundIndexes = exports.getUniqueIndexes = exports.applyUniqueIndexes = exports.applyAllIndexes = exports.createSchemaConfig = exports.checkRateLimit = exports.conditionalJsonMiddleware = exports.removeResultMiddleware = exports.restrictRoutes = exports.validateEntityRoutes = exports.validateFunctionRoutes = exports.importFiles = exports.sleep = exports.generateRandomString = exports.generateRandomInteger = exports.generateRandomPassword = exports.formatCount = exports.getUsersRoles = void 0;
5
+ exports.setupSwagger = exports.getSwaggerJson = exports.generateSwaggerSpec = exports.SwaggerRegistry = exports.NO_AMBIENT_TRANSACTION = exports.withAmbientSession = exports.CONFLICT_MESSAGE = exports.CONFLICT = exports.useTransactionAdapter = exports.currentSession = exports.inTransaction = exports.withTransaction = exports.Transactional = exports.VERSION_CONFLICT_MESSAGE = exports.VERSION_CONFLICT = exports.createVersionedMongoAdapter = exports.VersionRegistry = exports.ParseVersionField = exports.getFieldIndexes = exports.getCompoundIndexes = exports.getUniqueIndexes = exports.applyUniqueIndexes = exports.applyAllIndexes = exports.createSchemaConfig = exports.checkRateLimit = exports.conditionalJsonMiddleware = exports.removeResultMiddleware = exports.restrictRoutes = exports.validateEntityRoutes = exports.validateFunctionRoutes = exports.roleCacheStats = exports.roleCacheEnabled = exports.invalidateRoles = exports.configureRoleCache = exports.importFiles = exports.sleep = exports.generateRandomString = exports.generateRandomInteger = exports.generateRandomPassword = exports.formatCount = exports.getUsersRoles = void 0;
6
6
  // ── Decorators ──
7
7
  var parseDecorators_1 = require("./decorators/parseDecorators");
8
8
  Object.defineProperty(exports, "ParseClass", { enumerable: true, get: function () { return parseDecorators_1.ParseClass; } });
@@ -81,6 +81,12 @@ Object.defineProperty(exports, "generateRandomString", { enumerable: true, get:
81
81
  Object.defineProperty(exports, "sleep", { enumerable: true, get: function () { return helper_1.sleep; } });
82
82
  var dynamicImport_1 = require("./utils/dynamicImport");
83
83
  Object.defineProperty(exports, "importFiles", { enumerable: true, get: function () { return dynamicImport_1.importFiles; } });
84
+ // ── Role cache (opt-in) ──
85
+ var roleCache_1 = require("./utils/roleCache");
86
+ Object.defineProperty(exports, "configureRoleCache", { enumerable: true, get: function () { return roleCache_1.configureRoleCache; } });
87
+ Object.defineProperty(exports, "invalidateRoles", { enumerable: true, get: function () { return roleCache_1.invalidateRoles; } });
88
+ Object.defineProperty(exports, "roleCacheEnabled", { enumerable: true, get: function () { return roleCache_1.roleCacheEnabled; } });
89
+ Object.defineProperty(exports, "roleCacheStats", { enumerable: true, get: function () { return roleCache_1.roleCacheStats; } });
84
90
  // ── Middleware ──
85
91
  var middleware_1 = require("./middleware/middleware");
86
92
  Object.defineProperty(exports, "validateFunctionRoutes", { enumerable: true, get: function () { return middleware_1.validateFunctionRoutes; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/swagger/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,SAAS,CAAC;AAChC,OAAO,EAAsB,aAAa,EAAC,MAAM,eAAe,CAAC;AAEjE,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,mBAAmB,EAAE,cAAc,EAAC,MAAM,eAAe,CAAC;AAqBlE;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,aAAa,EACrB,IAAI,GAAE,MAAoB,QAkC3B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/swagger/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,SAAS,CAAC;AAChC,OAAO,EAAsB,aAAa,EAAC,MAAM,eAAe,CAAC;AAGjE,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,mBAAmB,EAAE,cAAc,EAAC,MAAM,eAAe,CAAC;AAqBlE;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,aAAa,EACrB,IAAI,GAAE,MAAoB,QA8C3B"}
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getSwaggerJson = exports.generateSwaggerSpec = exports.SwaggerRegistry = void 0;
4
4
  exports.setupSwagger = setupSwagger;
5
5
  const swaggerSpec_1 = require("./swaggerSpec");
6
- var swaggerRegistry_1 = require("./swaggerRegistry");
7
- Object.defineProperty(exports, "SwaggerRegistry", { enumerable: true, get: function () { return swaggerRegistry_1.SwaggerRegistry; } });
6
+ const swaggerRegistry_1 = require("./swaggerRegistry");
7
+ var swaggerRegistry_2 = require("./swaggerRegistry");
8
+ Object.defineProperty(exports, "SwaggerRegistry", { enumerable: true, get: function () { return swaggerRegistry_2.SwaggerRegistry; } });
8
9
  var swaggerSpec_2 = require("./swaggerSpec");
9
10
  Object.defineProperty(exports, "generateSwaggerSpec", { enumerable: true, get: function () { return swaggerSpec_2.generateSwaggerSpec; } });
10
11
  Object.defineProperty(exports, "getSwaggerJson", { enumerable: true, get: function () { return swaggerSpec_2.getSwaggerJson; } });
@@ -35,8 +36,20 @@ function loadSwaggerUi() {
35
36
  * browser page, not the document.
36
37
  */
37
38
  function setupSwagger(app, config, path = '/api-docs') {
38
- // Generate spec dynamically (after all models and functions are loaded)
39
- const getSpec = () => (0, swaggerSpec_1.generateSwaggerSpec)(config);
39
+ // Generate once, then reuse until something registers.
40
+ //
41
+ // The spec was rebuilt from every model and every endpoint on each hit of
42
+ // `{path}/json` — walking the whole registry to produce a document that had
43
+ // not changed since boot. Keyed on the registry's revision rather than a flag,
44
+ // so late registration still invalidates it and nothing has to remember to.
45
+ let cached = null;
46
+ const getSpec = () => {
47
+ const revision = swaggerRegistry_1.SwaggerRegistry.getRevision();
48
+ if (!cached || cached.revision !== revision) {
49
+ cached = { revision, spec: (0, swaggerSpec_1.generateSwaggerSpec)(config) };
50
+ }
51
+ return cached.spec;
52
+ };
40
53
  // Serve Swagger JSON BEFORE the UI middleware (so it doesn't get caught)
41
54
  app.get(`${path}/json`, (req, res) => {
42
55
  res.json(getSpec());
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/swagger/index.ts"],"names":[],"mappings":";;;AAgCA,oCAqCC;AApED,+CAAiE;AAEjE,qDAAkD;AAA1C,kHAAA,eAAe,OAAA;AACvB,6CAAkE;AAA1D,kHAAA,mBAAmB,OAAA;AAAE,6GAAA,cAAc,OAAA;AAE3C;;;;;;;;;GASG;AACH,SAAS,aAAa;IACpB,IAAI,CAAC;QACH,8DAA8D;QAC9D,OAAO,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,YAAY,CAC1B,GAAY,EACZ,MAAqB,EACrB,OAAe,WAAW;IAE1B,wEAAwE;IACxE,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAA,iCAAmB,EAAC,MAAM,CAAC,CAAC;IAElD,yEAAyE;IACzE,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACnC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,mCAAmC,IAAI,OAAO,CAAC,CAAC;IAE5D,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;IAClC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CACV,oEAAoE,IAAI,cAAc;YACpF,mCAAmC,CACtC,CAAC;QACF,OAAO;IACT,CAAC;IAED,mBAAmB;IACnB,GAAG,CAAC,GAAG,CACL,IAAI,EACJ,SAAS,CAAC,KAAK,EACf,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE;QACpB,cAAc,EAAE;YACd,GAAG,EAAE,GAAG,IAAI,OAAO;YACnB,oBAAoB,EAAE,IAAI;SAC3B;QACD,eAAe,EAAE,MAAM,CAAC,KAAK,IAAI,mBAAmB;KACrD,CAAC,CACH,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,4CAA4C,IAAI,EAAE,CAAC,CAAC;AAClE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/swagger/index.ts"],"names":[],"mappings":";;;AAiCA,oCAiDC;AAjFD,+CAAiE;AACjE,uDAAkD;AAElD,qDAAkD;AAA1C,kHAAA,eAAe,OAAA;AACvB,6CAAkE;AAA1D,kHAAA,mBAAmB,OAAA;AAAE,6GAAA,cAAc,OAAA;AAE3C;;;;;;;;;GASG;AACH,SAAS,aAAa;IACpB,IAAI,CAAC;QACH,8DAA8D;QAC9D,OAAO,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,YAAY,CAC1B,GAAY,EACZ,MAAqB,EACrB,OAAe,WAAW;IAE1B,uDAAuD;IACvD,EAAE;IACF,0EAA0E;IAC1E,4EAA4E;IAC5E,+EAA+E;IAC/E,4EAA4E;IAC5E,IAAI,MAAM,GAA4C,IAAI,CAAC;IAC3D,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,MAAM,QAAQ,GAAG,iCAAe,CAAC,WAAW,EAAE,CAAC;QAC/C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC5C,MAAM,GAAG,EAAC,QAAQ,EAAE,IAAI,EAAE,IAAA,iCAAmB,EAAC,MAAM,CAAC,EAAC,CAAC;QACzD,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC,CAAC;IAEF,yEAAyE;IACzE,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACnC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,mCAAmC,IAAI,OAAO,CAAC,CAAC;IAE5D,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;IAClC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CACV,oEAAoE,IAAI,cAAc;YACpF,mCAAmC,CACtC,CAAC;QACF,OAAO;IACT,CAAC;IAED,mBAAmB;IACnB,GAAG,CAAC,GAAG,CACL,IAAI,EACJ,SAAS,CAAC,KAAK,EACf,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE;QACpB,cAAc,EAAE;YACd,GAAG,EAAE,GAAG,IAAI,OAAO;YACnB,oBAAoB,EAAE,IAAI;SAC3B;QACD,eAAe,EAAE,MAAM,CAAC,KAAK,IAAI,mBAAmB;KACrD,CAAC,CACH,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,4CAA4C,IAAI,EAAE,CAAC,CAAC;AAClE,CAAC"}
@@ -43,6 +43,17 @@ export interface SwaggerFunctionSchema {
43
43
  export declare class SwaggerRegistry {
44
44
  private static models;
45
45
  private static functions;
46
+ /**
47
+ * Bumped on every change to what the spec would contain.
48
+ *
49
+ * Lets `setupSwagger` cache the generated document and still be correct: it
50
+ * compares revisions rather than trusting that registration stopped at boot.
51
+ * Anything registered later invalidates the cache on its own, with no call to
52
+ * remember.
53
+ */
54
+ private static revision;
55
+ /** The current content revision. Changes whenever the spec would change. */
56
+ static getRevision(): number;
46
57
  /**
47
58
  * Register a model for Swagger documentation
48
59
  */
@@ -1 +1 @@
1
- {"version":3,"file":"swaggerRegistry.d.ts","sourceRoot":"","sources":["../../src/swagger/swaggerRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gCAAgC,CAAC;AAEhE,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAClD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE;QACZ,QAAQ,EAAE,OAAO,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;KACnD,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;CACnE;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,MAAM,CAA8C;IACnE,OAAO,CAAC,MAAM,CAAC,SAAS,CAAiD;IAEzE;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,kBAAkB;IAK/C;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,qBAAqB;IAKrD;;;;OAIG;IACH,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAKjD;;;;OAIG;IACH,MAAM,CAAC,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW;IAiDlE;;OAEG;IACH,MAAM,CAAC,SAAS;IAIhB;;OAEG;IACH,MAAM,CAAC,YAAY;IAInB;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM;IAI5B;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM;IAI/B;;;OAGG;IACH,MAAM,CAAC,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAWjE;;OAEG;IACH,MAAM,CAAC,kBAAkB,CACvB,SAAS,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,GACnB,qBAAqB;IAiCxB;;OAEG;IACH,MAAM,CAAC,uBAAuB,CAAC,IAAI,EAAE,GAAG,GAAG,qBAAqB;CAQjE"}
1
+ {"version":3,"file":"swaggerRegistry.d.ts","sourceRoot":"","sources":["../../src/swagger/swaggerRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gCAAgC,CAAC;AAEhE,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAClD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE;QACZ,QAAQ,EAAE,OAAO,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;KACnD,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;CACnE;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,MAAM,CAA8C;IACnE,OAAO,CAAC,MAAM,CAAC,SAAS,CAAiD;IAEzE;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAK;IAE5B,4EAA4E;IAC5E,MAAM,CAAC,WAAW,IAAI,MAAM;IAI5B;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,kBAAkB;IAM/C;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,qBAAqB;IAMrD;;;;OAIG;IACH,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAQjD;;;;OAIG;IACH,MAAM,CAAC,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW;IAiDlE;;OAEG;IACH,MAAM,CAAC,SAAS;IAIhB;;OAEG;IACH,MAAM,CAAC,YAAY;IAInB;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM;IAI5B;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM;IAI/B;;;OAGG;IACH,MAAM,CAAC,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAWjE;;OAEG;IACH,MAAM,CAAC,kBAAkB,CACvB,SAAS,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,GACnB,qBAAqB;IAiCxB;;OAEG;IACH,MAAM,CAAC,uBAAuB,CAAC,IAAI,EAAE,GAAG,GAAG,qBAAqB;CAQjE"}
@@ -6,11 +6,16 @@ require("reflect-metadata");
6
6
  * Registry for collecting Swagger/OpenAPI documentation metadata
7
7
  */
8
8
  class SwaggerRegistry {
9
+ /** The current content revision. Changes whenever the spec would change. */
10
+ static getRevision() {
11
+ return this.revision;
12
+ }
9
13
  /**
10
14
  * Register a model for Swagger documentation
11
15
  */
12
16
  static registerModel(schema) {
13
17
  this.models.set(schema.className, schema);
18
+ this.revision += 1;
14
19
  console.log(`[Swagger] Registered model: ${schema.className}`);
15
20
  }
16
21
  /**
@@ -18,6 +23,7 @@ class SwaggerRegistry {
18
23
  */
19
24
  static registerFunction(schema) {
20
25
  this.functions.set(schema.name, schema);
26
+ this.revision += 1;
21
27
  console.log(`[Swagger] Registered function: ${schema.name}`);
22
28
  }
23
29
  /**
@@ -27,8 +33,10 @@ class SwaggerRegistry {
27
33
  */
28
34
  static setFunctionPath(name, path) {
29
35
  const fn = this.functions.get(name);
30
- if (fn)
36
+ if (fn) {
31
37
  fn.path = path;
38
+ this.revision += 1;
39
+ }
32
40
  }
33
41
  /**
34
42
  * Build + register a cloud function's Swagger schema straight from its
@@ -166,4 +174,13 @@ class SwaggerRegistry {
166
174
  exports.SwaggerRegistry = SwaggerRegistry;
167
175
  SwaggerRegistry.models = new Map();
168
176
  SwaggerRegistry.functions = new Map();
177
+ /**
178
+ * Bumped on every change to what the spec would contain.
179
+ *
180
+ * Lets `setupSwagger` cache the generated document and still be correct: it
181
+ * compares revisions rather than trusting that registration stopped at boot.
182
+ * Anything registered later invalidates the cache on its own, with no call to
183
+ * remember.
184
+ */
185
+ SwaggerRegistry.revision = 0;
169
186
  //# sourceMappingURL=swaggerRegistry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"swaggerRegistry.js","sourceRoot":"","sources":["../../src/swagger/swaggerRegistry.ts"],"names":[],"mappings":";;;AAAA,4BAA0B;AAqC1B;;GAEG;AACH,MAAa,eAAe;IAI1B;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,MAA0B;QAC7C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,+BAA+B,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IACjE,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,MAA6B;QACnD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,kCAAkC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,eAAe,CAAC,IAAY,EAAE,IAAY;QAC/C,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,EAAE;YAAE,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,yBAAyB,CAAC,IAAY,EAAE,MAAmB;QAChE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAKjC,CAAC;QAEF,MAAM,YAAY,GAAG,OAAO,CAC1B,MAAM,CAAC,YAAY;YACjB,CAAC,CAAC,WAAW;YACb,CAAC,CAAC,aAAa;YACf,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC;YACtE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CACrE,CAAC;QAEF,uDAAuD;QACvD,MAAM,UAAU,GAA0C,EAAE,CAAC;QAC7D,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;QACxB,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,UAAU,CAAC,KAAK,CAAC,GAAG,EAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC;YACvD,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAChD,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClD,MAAM,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBACrD,IAAI,GAAG,EAAE,QAAQ;oBAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACxC,UAAU,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;YAC3B,CAAC;QACH,CAAC;QACD,MAAM,WAAW,GACf,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC;YAChC,CAAC,CAAC,EAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAC;YAC9B,CAAC,CAAC,SAAS,CAAC;QAEhB,IAAI,CAAC,gBAAgB,CAAC;YACpB,IAAI;YACJ,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM;YACrC,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO;YAChC,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,WAAW,IAAI,MAAM,CAAC,WAAW;YAC9D,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI;YAC1B,YAAY;YACZ,WAAW;YACX,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,SAAS,IAAI;gBACtC,KAAK,EAAE,EAAC,WAAW,EAAE,SAAS,EAAC;aAChC;SACF,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,SAAS;QACd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,YAAY;QACjB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAY;QAC1B,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,IAAY;QAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,kBAAkB,CAAC,SAAkB;QAC1C,IAAI,CAAC,SAAS;YAAE,OAAO,SAAS,CAAC;QAEjC,+CAA+C;QAC/C,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;QACnE,IAAI,cAAc,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,SAAS,EAAE,CAAC;QACzB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,kBAAkB,CACvB,SAAiB,EACjB,WAAoB;QAEpB,MAAM,eAAe,GAAG,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;QAC7D,MAAM,OAAO,GAA0C;YACrD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC1B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC1B,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;YAC5B,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE;YAC7C,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC1B,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;YACnD,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,sCAAsC;aACpD;YACD,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mBAAmB,EAAE;YAC1D,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE;YACzC,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qBAAqB,EAAE;YAC/D,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,cAAc,WAAW,IAAI,SAAS,EAAE;gBACrD,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,wBAAwB,eAAe,EAAE,CAAC,CAAC,CAAC,SAAS;aAC9E;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,OAAO;gBACb,WAAW,EAAE,eAAe,WAAW,IAAI,SAAS,EAAE;gBACtD,KAAK,EAAE;oBACL,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,wBAAwB,eAAe,EAAE,CAAC,CAAC,CAAC,SAAS;iBAC9E;aACF;SACF,CAAC;QAEF,OAAO,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,uBAAuB,CAAC,IAAS;QACtC,IAAI,IAAI,KAAK,MAAM;YAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC/C,IAAI,IAAI,KAAK,MAAM;YAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC/C,IAAI,IAAI,KAAK,OAAO;YAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACjD,IAAI,IAAI,KAAK,KAAK;YAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC;QACxE,IAAI,IAAI,KAAK,MAAM;YAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC/C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC5B,CAAC;;AAhLH,0CAiLC;AAhLgB,sBAAM,GAAoC,IAAI,GAAG,EAAE,CAAC;AACpD,yBAAS,GAAuC,IAAI,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"swaggerRegistry.js","sourceRoot":"","sources":["../../src/swagger/swaggerRegistry.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,11 @@ export declare function generateRandomString(length?: number): string;
5
5
  export declare function sleep(ms: number): Promise<unknown>;
6
6
  export declare function catchError<T>(promise: Promise<T>): Promise<[undefined, T] | [Error]>;
7
7
  /**
8
- * Get role names for a single user
8
+ * Get role names for a single user.
9
+ *
10
+ * Served from the role cache when one is configured; otherwise this is the same
11
+ * query it has always been. See `configureRoleCache` — the cache is off unless
12
+ * a deployment turns it on.
9
13
  */
10
14
  export declare function getUserRoles(user: Parse.User): Promise<string[]>;
11
15
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../src/utils/helper.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,SAAO,UAMlD;AAED,wBAAgB,sBAAsB,CACpC,MAAM,SAAI,EACV,cAAc,UAAO,EACrB,cAAc,UAAO,UAiBtB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,UAInD;AAED,wBAAgB,oBAAoB,CAAC,MAAM,SAAI,GAAG,MAAM,CAOvD;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,oBAE/B;AAED,wBAAsB,UAAU,CAAC,CAAC,EAChC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAClB,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAQnC;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAKtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAmBvF"}
1
+ {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../src/utils/helper.ts"],"names":[],"mappings":"AAEA,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,SAAO,UAMlD;AAED,wBAAgB,sBAAsB,CACpC,MAAM,SAAI,EACV,cAAc,UAAO,EACrB,cAAc,UAAO,UAiBtB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,UAInD;AAED,wBAAgB,oBAAoB,CAAC,MAAM,SAAI,GAAG,MAAM,CAOvD;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,oBAE/B;AAED,wBAAsB,UAAU,CAAC,CAAC,EAChC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAClB,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAQnC;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAWtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAgCvF"}
@@ -8,6 +8,7 @@ exports.sleep = sleep;
8
8
  exports.catchError = catchError;
9
9
  exports.getUserRoles = getUserRoles;
10
10
  exports.getUsersRoles = getUsersRoles;
11
+ const roleCache_1 = require("./roleCache");
11
12
  function formatCount(num, locale = 'en') {
12
13
  return new Intl.NumberFormat(locale, {
13
14
  notation: 'compact',
@@ -58,13 +59,22 @@ async function catchError(promise) {
58
59
  });
59
60
  }
60
61
  /**
61
- * Get role names for a single user
62
+ * Get role names for a single user.
63
+ *
64
+ * Served from the role cache when one is configured; otherwise this is the same
65
+ * query it has always been. See `configureRoleCache` — the cache is off unless
66
+ * a deployment turns it on.
62
67
  */
63
68
  async function getUserRoles(user) {
69
+ const cached = (0, roleCache_1.readCachedRoles)(user.id);
70
+ if (cached)
71
+ return cached;
64
72
  const roleQuery = new Parse.Query('_Role');
65
73
  roleQuery.equalTo('users', user);
66
74
  const roles = await roleQuery.find({ useMasterKey: true });
67
- return roles.map(r => r.get('name'));
75
+ const names = roles.map(r => r.get('name'));
76
+ (0, roleCache_1.writeCachedRoles)(user.id, names);
77
+ return names;
68
78
  }
69
79
  /**
70
80
  * Get role names for multiple users.
@@ -81,6 +91,17 @@ async function getUserRoles(user) {
81
91
  async function getUsersRoles(users) {
82
92
  if (users.length === 0)
83
93
  return new Map();
94
+ // Every user already cached means the whole batch — and its one-query-per-role
95
+ // cost — can be skipped outright.
96
+ const fromCache = new Map();
97
+ for (const user of users) {
98
+ const cached = (0, roleCache_1.readCachedRoles)(user.id);
99
+ if (!cached)
100
+ break;
101
+ fromCache.set(user.id, cached);
102
+ }
103
+ if (fromCache.size === users.length)
104
+ return fromCache;
84
105
  const allRoles = await new Parse.Query('_Role').limit(100).find({ useMasterKey: true });
85
106
  const userRolesMap = new Map();
86
107
  for (const user of users) {
@@ -97,6 +118,8 @@ async function getUsersRoles(users) {
97
118
  userRolesMap.set(u.id, existing);
98
119
  }
99
120
  }
121
+ for (const [userId, names] of userRolesMap)
122
+ (0, roleCache_1.writeCachedRoles)(userId, names);
100
123
  return userRolesMap;
101
124
  }
102
125
  //# sourceMappingURL=helper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"helper.js","sourceRoot":"","sources":["../../src/utils/helper.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"helper.js","sourceRoot":"","sources":["../../src/utils/helper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Role membership, remembered for a while.
3
+ *
4
+ * `@CloudFunction({requireRoles})` asks the database who a user is on every
5
+ * single call, and so does every `getUserRoles()`. That is a full round-trip —
6
+ * milliseconds, not microseconds — to answer a question whose answer almost
7
+ * never changes.
8
+ *
9
+ * **Off by default, and deliberately so.** Caching membership means a revoked
10
+ * role keeps working until the entry expires. That is a security trade, and it
11
+ * belongs to whoever runs the deployment, not to this library. Nothing here
12
+ * takes effect until `configureRoleCache()` is called.
13
+ *
14
+ * When it is on, `invalidateRoles(userId)` is the tool that keeps the window
15
+ * from mattering: call it wherever you grant or revoke, and the TTL becomes a
16
+ * backstop for changes made outside your code rather than the primary control.
17
+ *
18
+ * There is no timer. Entries expire when read and the map is capped on write,
19
+ * so importing this module costs nothing and holds nothing open.
20
+ */
21
+ export interface RoleCacheOptions {
22
+ /** How long a user's role list may be reused, in milliseconds. */
23
+ ttlMs: number;
24
+ /**
25
+ * Most users to remember at once. Oldest entries are dropped past this.
26
+ * Default 10000 — a bound against memory growth, not a tuning knob.
27
+ */
28
+ maxUsers?: number;
29
+ }
30
+ /**
31
+ * Turn the cache on, change its settings, or turn it off with `false`.
32
+ *
33
+ * Switching off clears whatever was held, so a deployment can disable it and be
34
+ * certain nothing stale survives.
35
+ */
36
+ export declare function configureRoleCache(config: RoleCacheOptions | false): void;
37
+ export declare function roleCacheEnabled(): boolean;
38
+ /**
39
+ * Forget a user's roles, or everyone's.
40
+ *
41
+ * Call this wherever a role is granted or revoked. Safe to call when the cache
42
+ * is off — it simply has nothing to do.
43
+ */
44
+ export declare function invalidateRoles(userId?: string): void;
45
+ /** For tests and for reporting. */
46
+ export declare function roleCacheStats(): {
47
+ enabled: boolean;
48
+ size: number;
49
+ ttlMs: number | null;
50
+ };
51
+ /**
52
+ * The cached roles for this user, or nothing if there is no live entry.
53
+ *
54
+ * `ttlOverrideMs` of 0 means "do not use the cache for this call" — how a
55
+ * single cloud function opts out of a global policy.
56
+ */
57
+ export declare function readCachedRoles(userId: string, ttlOverrideMs?: number): string[] | undefined;
58
+ /** Remember this user's roles. A no-op while the cache is off. */
59
+ export declare function writeCachedRoles(userId: string, roles: string[], ttlOverrideMs?: number): void;
60
+ //# sourceMappingURL=roleCache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roleCache.d.ts","sourceRoot":"","sources":["../../src/utils/roleCache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAOH,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAOD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,KAAK,GAAG,IAAI,CAkBzE;AAED,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAGrD;AAED,mCAAmC;AACnC,wBAAgB,cAAc,IAAI;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,CAMvF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,GACrB,MAAM,EAAE,GAAG,SAAS,CAWtB;AAED,kEAAkE;AAClE,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EAAE,EACf,aAAa,CAAC,EAAE,MAAM,GACrB,IAAI,CAaN"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ /**
3
+ * Role membership, remembered for a while.
4
+ *
5
+ * `@CloudFunction({requireRoles})` asks the database who a user is on every
6
+ * single call, and so does every `getUserRoles()`. That is a full round-trip —
7
+ * milliseconds, not microseconds — to answer a question whose answer almost
8
+ * never changes.
9
+ *
10
+ * **Off by default, and deliberately so.** Caching membership means a revoked
11
+ * role keeps working until the entry expires. That is a security trade, and it
12
+ * belongs to whoever runs the deployment, not to this library. Nothing here
13
+ * takes effect until `configureRoleCache()` is called.
14
+ *
15
+ * When it is on, `invalidateRoles(userId)` is the tool that keeps the window
16
+ * from mattering: call it wherever you grant or revoke, and the TTL becomes a
17
+ * backstop for changes made outside your code rather than the primary control.
18
+ *
19
+ * There is no timer. Entries expire when read and the map is capped on write,
20
+ * so importing this module costs nothing and holds nothing open.
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.configureRoleCache = configureRoleCache;
24
+ exports.roleCacheEnabled = roleCacheEnabled;
25
+ exports.invalidateRoles = invalidateRoles;
26
+ exports.roleCacheStats = roleCacheStats;
27
+ exports.readCachedRoles = readCachedRoles;
28
+ exports.writeCachedRoles = writeCachedRoles;
29
+ const DEFAULT_MAX_USERS = 10000;
30
+ let options = null;
31
+ const cache = new Map();
32
+ /**
33
+ * Turn the cache on, change its settings, or turn it off with `false`.
34
+ *
35
+ * Switching off clears whatever was held, so a deployment can disable it and be
36
+ * certain nothing stale survives.
37
+ */
38
+ function configureRoleCache(config) {
39
+ if (config === false) {
40
+ options = null;
41
+ cache.clear();
42
+ return;
43
+ }
44
+ if (!Number.isFinite(config.ttlMs) || config.ttlMs <= 0) {
45
+ throw new Error(`configureRoleCache: ttlMs must be a positive number, got ${config.ttlMs}. ` +
46
+ 'Pass `false` to disable the cache.');
47
+ }
48
+ options = {
49
+ ttlMs: config.ttlMs,
50
+ maxUsers: config.maxUsers ?? DEFAULT_MAX_USERS,
51
+ };
52
+ }
53
+ function roleCacheEnabled() {
54
+ return options !== null;
55
+ }
56
+ /**
57
+ * Forget a user's roles, or everyone's.
58
+ *
59
+ * Call this wherever a role is granted or revoked. Safe to call when the cache
60
+ * is off — it simply has nothing to do.
61
+ */
62
+ function invalidateRoles(userId) {
63
+ if (userId === undefined)
64
+ cache.clear();
65
+ else
66
+ cache.delete(userId);
67
+ }
68
+ /** For tests and for reporting. */
69
+ function roleCacheStats() {
70
+ return {
71
+ enabled: options !== null,
72
+ size: cache.size,
73
+ ttlMs: options?.ttlMs ?? null,
74
+ };
75
+ }
76
+ /**
77
+ * The cached roles for this user, or nothing if there is no live entry.
78
+ *
79
+ * `ttlOverrideMs` of 0 means "do not use the cache for this call" — how a
80
+ * single cloud function opts out of a global policy.
81
+ */
82
+ function readCachedRoles(userId, ttlOverrideMs) {
83
+ if (!options || ttlOverrideMs === 0)
84
+ return undefined;
85
+ const entry = cache.get(userId);
86
+ if (!entry)
87
+ return undefined;
88
+ if (Date.now() >= entry.expiresAt) {
89
+ cache.delete(userId);
90
+ return undefined;
91
+ }
92
+ return entry.roles;
93
+ }
94
+ /** Remember this user's roles. A no-op while the cache is off. */
95
+ function writeCachedRoles(userId, roles, ttlOverrideMs) {
96
+ if (!options || ttlOverrideMs === 0)
97
+ return;
98
+ // Map preserves insertion order, so the first key is the oldest write.
99
+ if (cache.size >= options.maxUsers && !cache.has(userId)) {
100
+ const oldest = cache.keys().next();
101
+ if (!oldest.done)
102
+ cache.delete(oldest.value);
103
+ }
104
+ cache.set(userId, {
105
+ roles,
106
+ expiresAt: Date.now() + (ttlOverrideMs ?? options.ttlMs),
107
+ });
108
+ }
109
+ //# sourceMappingURL=roleCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roleCache.js","sourceRoot":"","sources":["../../src/utils/roleCache.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;AA4BH,gDAkBC;AAED,4CAEC;AAQD,0CAGC;AAGD,wCAMC;AAQD,0CAcC;AAGD,4CAiBC;AA/FD,MAAM,iBAAiB,GAAG,KAAM,CAAC;AAEjC,IAAI,OAAO,GAAsC,IAAI,CAAC;AACtD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;AAE5C;;;;;GAKG;AACH,SAAgB,kBAAkB,CAAC,MAAgC;IACjE,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,OAAO,GAAG,IAAI,CAAC;QACf,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,OAAO;IACT,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CACb,4DAA4D,MAAM,CAAC,KAAK,IAAI;YAC1E,oCAAoC,CACvC,CAAC;IACJ,CAAC;IAED,OAAO,GAAG;QACR,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,iBAAiB;KAC/C,CAAC;AACJ,CAAC;AAED,SAAgB,gBAAgB;IAC9B,OAAO,OAAO,KAAK,IAAI,CAAC;AAC1B,CAAC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAAC,MAAe;IAC7C,IAAI,MAAM,KAAK,SAAS;QAAE,KAAK,CAAC,KAAK,EAAE,CAAC;;QACnC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED,mCAAmC;AACnC,SAAgB,cAAc;IAC5B,OAAO;QACL,OAAO,EAAE,OAAO,KAAK,IAAI;QACzB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,IAAI;KAC9B,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAC7B,MAAc,EACd,aAAsB;IAEtB,IAAI,CAAC,OAAO,IAAI,aAAa,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAEtD,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAE7B,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QAClC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACrB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC,KAAK,CAAC;AACrB,CAAC;AAED,kEAAkE;AAClE,SAAgB,gBAAgB,CAC9B,MAAc,EACd,KAAe,EACf,aAAsB;IAEtB,IAAI,CAAC,OAAO,IAAI,aAAa,KAAK,CAAC;QAAE,OAAO;IAE5C,uEAAuE;IACvE,IAAI,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACzD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,IAAI;YAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE;QAChB,KAAK;QACL,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC,KAAK,CAAC;KACzD,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@90soft/parse-server-kit",
3
- "version": "2.8.2",
3
+ "version": "2.9.0",
4
4
  "description": "Complete decorator-driven development kit for Parse Server — models, cloud functions, triggers, cron, routing, ACL, Swagger, and more.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",