@dyrected/core 2.5.24 → 2.5.26

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 (169) hide show
  1. package/dist/__tests__/app.test.d.ts +2 -0
  2. package/dist/__tests__/app.test.d.ts.map +1 -0
  3. package/dist/__tests__/app.test.js +27 -0
  4. package/dist/__tests__/app.test.js.map +1 -0
  5. package/dist/__tests__/config.test.d.ts +2 -0
  6. package/dist/__tests__/config.test.d.ts.map +1 -0
  7. package/dist/__tests__/config.test.js +34 -0
  8. package/dist/__tests__/config.test.js.map +1 -0
  9. package/dist/__tests__/deleteMany.test.d.ts +2 -0
  10. package/dist/__tests__/deleteMany.test.d.ts.map +1 -0
  11. package/dist/__tests__/deleteMany.test.js +75 -0
  12. package/dist/__tests__/deleteMany.test.js.map +1 -0
  13. package/dist/__tests__/depth.test.d.ts +2 -0
  14. package/dist/__tests__/depth.test.d.ts.map +1 -0
  15. package/dist/__tests__/depth.test.js +81 -0
  16. package/dist/__tests__/depth.test.js.map +1 -0
  17. package/dist/__tests__/dynamic-options.test.d.ts +2 -0
  18. package/dist/__tests__/dynamic-options.test.d.ts.map +1 -0
  19. package/dist/__tests__/dynamic-options.test.js +132 -0
  20. package/dist/__tests__/dynamic-options.test.js.map +1 -0
  21. package/dist/__tests__/field-inference.test-types.d.ts +24 -0
  22. package/dist/__tests__/field-inference.test-types.d.ts.map +1 -0
  23. package/dist/__tests__/field-inference.test-types.js +87 -0
  24. package/dist/__tests__/field-inference.test-types.js.map +1 -0
  25. package/dist/__tests__/hooks.test.d.ts +2 -0
  26. package/dist/__tests__/hooks.test.d.ts.map +1 -0
  27. package/dist/__tests__/hooks.test.js +320 -0
  28. package/dist/__tests__/hooks.test.js.map +1 -0
  29. package/dist/__tests__/mocks.d.ts +68 -0
  30. package/dist/__tests__/mocks.d.ts.map +1 -0
  31. package/dist/__tests__/mocks.js +151 -0
  32. package/dist/__tests__/mocks.js.map +1 -0
  33. package/dist/__tests__/router.test.d.ts +2 -0
  34. package/dist/__tests__/router.test.d.ts.map +1 -0
  35. package/dist/__tests__/router.test.js +48 -0
  36. package/dist/__tests__/router.test.js.map +1 -0
  37. package/dist/__tests__/where.test.d.ts +2 -0
  38. package/dist/__tests__/where.test.d.ts.map +1 -0
  39. package/dist/__tests__/where.test.js +97 -0
  40. package/dist/__tests__/where.test.js.map +1 -0
  41. package/dist/app-BOrsS7Tz.d.cts +1771 -0
  42. package/dist/app-BOrsS7Tz.d.ts +1771 -0
  43. package/dist/app-BibuoHQG.d.cts +1764 -0
  44. package/dist/app-BibuoHQG.d.ts +1764 -0
  45. package/dist/app-aW2FMuYM.d.cts +1759 -0
  46. package/dist/app-aW2FMuYM.d.ts +1759 -0
  47. package/dist/app.d.ts +21 -0
  48. package/dist/app.d.ts.map +1 -0
  49. package/dist/app.js +56 -0
  50. package/dist/app.js.map +1 -0
  51. package/dist/auth/jexl.d.ts +10 -0
  52. package/dist/auth/jexl.d.ts.map +1 -0
  53. package/dist/auth/jexl.js +22 -0
  54. package/dist/auth/jexl.js.map +1 -0
  55. package/dist/auth/password.d.ts +10 -0
  56. package/dist/auth/password.d.ts.map +1 -0
  57. package/dist/auth/password.js +28 -0
  58. package/dist/auth/password.js.map +1 -0
  59. package/dist/auth/token.d.ts +20 -0
  60. package/dist/auth/token.d.ts.map +1 -0
  61. package/dist/auth/token.js +40 -0
  62. package/dist/auth/token.js.map +1 -0
  63. package/dist/chunk-4EDMZAM5.js +2692 -0
  64. package/dist/chunk-FDQYPPG3.js +2698 -0
  65. package/dist/chunk-NKDX67AW.js +2698 -0
  66. package/dist/chunk-SUGK7UYL.js +311 -0
  67. package/dist/chunk-ZFAOBRHT.js +2709 -0
  68. package/dist/controllers/auth.controller.d.ts +125 -0
  69. package/dist/controllers/auth.controller.d.ts.map +1 -0
  70. package/dist/controllers/auth.controller.js +323 -0
  71. package/dist/controllers/auth.controller.js.map +1 -0
  72. package/dist/controllers/collection.controller.d.ts +88 -0
  73. package/dist/controllers/collection.controller.d.ts.map +1 -0
  74. package/dist/controllers/collection.controller.js +554 -0
  75. package/dist/controllers/collection.controller.js.map +1 -0
  76. package/dist/controllers/global.controller.d.ts +17 -0
  77. package/dist/controllers/global.controller.d.ts.map +1 -0
  78. package/dist/controllers/global.controller.js +116 -0
  79. package/dist/controllers/global.controller.js.map +1 -0
  80. package/dist/controllers/media.controller.d.ts +36 -0
  81. package/dist/controllers/media.controller.d.ts.map +1 -0
  82. package/dist/controllers/media.controller.js +155 -0
  83. package/dist/controllers/media.controller.js.map +1 -0
  84. package/dist/controllers/preview.controller.d.ts +37 -0
  85. package/dist/controllers/preview.controller.d.ts.map +1 -0
  86. package/dist/controllers/preview.controller.js +48 -0
  87. package/dist/controllers/preview.controller.js.map +1 -0
  88. package/dist/index-Bp7PDOYG.d.cts +1750 -0
  89. package/dist/index-Bp7PDOYG.d.ts +1750 -0
  90. package/dist/index-DfAmTZXk.d.cts +1749 -0
  91. package/dist/index-DfAmTZXk.d.ts +1749 -0
  92. package/dist/index.cjs +19 -2324
  93. package/dist/index.d.cts +5 -6
  94. package/dist/index.d.ts +5 -6
  95. package/dist/index.d.ts.map +1 -0
  96. package/dist/index.js +3 -5
  97. package/dist/index.js.map +1 -0
  98. package/dist/middleware/auth.d.ts +18 -0
  99. package/dist/middleware/auth.d.ts.map +1 -0
  100. package/dist/middleware/auth.js +45 -0
  101. package/dist/middleware/auth.js.map +1 -0
  102. package/dist/router.d.ts +8 -0
  103. package/dist/router.d.ts.map +1 -0
  104. package/dist/router.js +463 -0
  105. package/dist/router.js.map +1 -0
  106. package/dist/server.cjs +237 -45
  107. package/dist/server.d.cts +22 -4
  108. package/dist/server.d.ts +22 -4
  109. package/dist/server.d.ts.map +1 -0
  110. package/dist/server.js +2429 -8
  111. package/dist/server.js.map +1 -0
  112. package/dist/services/audit.service.d.ts +23 -0
  113. package/dist/services/audit.service.d.ts.map +1 -0
  114. package/dist/services/audit.service.js +28 -0
  115. package/dist/services/audit.service.js.map +1 -0
  116. package/dist/services/defaults.service.d.ts +8 -0
  117. package/dist/services/defaults.service.d.ts.map +1 -0
  118. package/dist/services/defaults.service.js +55 -0
  119. package/dist/services/defaults.service.js.map +1 -0
  120. package/dist/services/email.service.d.ts +33 -0
  121. package/dist/services/email.service.d.ts.map +1 -0
  122. package/dist/services/email.service.js +219 -0
  123. package/dist/services/email.service.js.map +1 -0
  124. package/dist/services/media.service.d.ts +20 -0
  125. package/dist/services/media.service.d.ts.map +1 -0
  126. package/dist/services/media.service.js +49 -0
  127. package/dist/services/media.service.js.map +1 -0
  128. package/dist/services/population.service.d.ts +20 -0
  129. package/dist/services/population.service.d.ts.map +1 -0
  130. package/dist/services/population.service.js +168 -0
  131. package/dist/services/population.service.js.map +1 -0
  132. package/dist/types/index.d.ts +1749 -0
  133. package/dist/types/index.d.ts.map +1 -0
  134. package/dist/types/index.js +3 -0
  135. package/dist/types/index.js.map +1 -0
  136. package/dist/utils/config.d.ts +8 -0
  137. package/dist/utils/config.d.ts.map +1 -0
  138. package/dist/utils/config.js +153 -0
  139. package/dist/utils/config.js.map +1 -0
  140. package/dist/utils/hooks.d.ts +41 -0
  141. package/dist/utils/hooks.d.ts.map +1 -0
  142. package/dist/utils/hooks.js +169 -0
  143. package/dist/utils/hooks.js.map +1 -0
  144. package/dist/utils/openapi.d.ts +6 -0
  145. package/dist/utils/openapi.d.ts.map +1 -0
  146. package/dist/utils/openapi.js +331 -0
  147. package/dist/utils/openapi.js.map +1 -0
  148. package/dist/utils/parse-where.d.ts +63 -0
  149. package/dist/utils/parse-where.d.ts.map +1 -0
  150. package/dist/utils/parse-where.js +196 -0
  151. package/dist/utils/parse-where.js.map +1 -0
  152. package/dist/utils/readonly-db.d.ts +9 -0
  153. package/dist/utils/readonly-db.d.ts.map +1 -0
  154. package/dist/utils/readonly-db.js +21 -0
  155. package/dist/utils/readonly-db.js.map +1 -0
  156. package/dist/utils/setup-prompt.d.ts +11 -0
  157. package/dist/utils/setup-prompt.d.ts.map +1 -0
  158. package/dist/utils/setup-prompt.js +863 -0
  159. package/dist/utils/setup-prompt.js.map +1 -0
  160. package/dist/utils/swagger.d.ts +5 -0
  161. package/dist/utils/swagger.d.ts.map +1 -0
  162. package/dist/utils/swagger.js +51 -0
  163. package/dist/utils/swagger.js.map +1 -0
  164. package/dist/utils/where-sanitizer.d.ts +10 -0
  165. package/dist/utils/where-sanitizer.d.ts.map +1 -0
  166. package/dist/utils/where-sanitizer.js +63 -0
  167. package/dist/utils/where-sanitizer.js.map +1 -0
  168. package/dist/where-sanitizer-DQIWTQZW.js +50 -0
  169. package/package.json +1 -1
package/dist/app.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ import { Hono } from 'hono';
2
+ import type { DyrectedConfig } from './types/index.js';
3
+ export interface DyrectedContext {
4
+ Variables: {
5
+ config: DyrectedConfig;
6
+ siteId?: string;
7
+ workspaceId?: string;
8
+ /** Decoded JWT payload set by requireAuth() or optionalAuth() middleware. */
9
+ user?: {
10
+ sub: string;
11
+ email: string;
12
+ collection: string;
13
+ [key: string]: any;
14
+ };
15
+ };
16
+ }
17
+ /**
18
+ * Create the main Dyrected Hono application.
19
+ */
20
+ export declare function createDyrectedApp(rawConfig: DyrectedConfig): Promise<Hono<DyrectedContext, import("hono/types").BlankSchema, "/">>;
21
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAKvD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE;QACT,MAAM,EAAE,cAAc,CAAC;QACvB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,6EAA6E;QAC7E,IAAI,CAAC,EAAE;YACL,GAAG,EAAE,MAAM,CAAC;YACZ,KAAK,EAAE,MAAM,CAAC;YACd,UAAU,EAAE,MAAM,CAAC;YACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;SACpB,CAAC;KACH,CAAC;CACH;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,cAAc,yEAoDhE"}
package/dist/app.js ADDED
@@ -0,0 +1,56 @@
1
+ import { Hono } from 'hono';
2
+ import { cors } from 'hono/cors';
3
+ import { requestId } from 'hono/request-id';
4
+ import { registerRoutes } from './router.js';
5
+ import { normalizeConfig } from './utils/config.js';
6
+ import { optionalAuth } from './middleware/auth.js';
7
+ /**
8
+ * Create the main Dyrected Hono application.
9
+ */
10
+ export async function createDyrectedApp(rawConfig) {
11
+ const config = normalizeConfig(rawConfig);
12
+ const app = new Hono();
13
+ // 0. Sync Database Schema if adapter supports it
14
+ if (config.db?.sync) {
15
+ await config.db.sync(config.collections, config.globals);
16
+ }
17
+ // 1. Standard Middleware
18
+ app.use('*', requestId());
19
+ // Decode bearer token if present so user is available in CRUD hooks and audit logging.
20
+ app.use('*', optionalAuth());
21
+ app.use('*', async (c, next) => {
22
+ const start = Date.now();
23
+ await next();
24
+ const ms = Date.now() - start;
25
+ console.log(`[dyrected/api] ${c.req.method} ${c.req.path} ${c.res.status} - ${ms}ms`);
26
+ });
27
+ app.use('*', cors());
28
+ // 2. Site Resolution Middleware
29
+ app.use('*', async (c, next) => {
30
+ c.set('config', config);
31
+ // If an upstream middleware (e.g. cloud app) hasn't already set the siteId,
32
+ // fallback to 'default' for self-hosted/singleton mode.
33
+ if (!c.get('siteId')) {
34
+ c.set('siteId', 'default');
35
+ }
36
+ await next();
37
+ });
38
+ // 3. Health Check & Debug
39
+ app.get('/health', (c) => c.json({ status: 'ok', version: '0.0.1' }));
40
+ app.get('/routes', (c) => {
41
+ const routes = app.routes.map(r => ({ method: r.method, path: r.path }));
42
+ return c.json({ routes });
43
+ });
44
+ // 4. Global Error Handler
45
+ app.onError((err, c) => {
46
+ console.error(`[dyrected/core] Uncaught Error:`, err);
47
+ return c.json({
48
+ message: err.message || 'Internal Server Error',
49
+ stack: process.env.NODE_ENV === 'development' ? err.stack : undefined
50
+ }, 500);
51
+ });
52
+ // 5. Dynamic Routing
53
+ registerRoutes(app, config);
54
+ return app;
55
+ }
56
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Jexl evaluator for Dyrected access control.
3
+ * Allows for serializable, dynamic permissions based on user state, request, and document.
4
+ */
5
+ export declare function evaluateAccess(expression: string | boolean | undefined | null, context: {
6
+ user?: any;
7
+ req?: any;
8
+ doc?: any;
9
+ }): Promise<boolean>;
10
+ //# sourceMappingURL=jexl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jexl.d.ts","sourceRoot":"","sources":["../../src/auth/jexl.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,EAC/C,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,GAAG,CAAC;IAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IAAC,GAAG,CAAC,EAAE,GAAG,CAAA;CAAE,GAC5C,OAAO,CAAC,OAAO,CAAC,CAalB"}
@@ -0,0 +1,22 @@
1
+ import jexl from 'jexl';
2
+ /**
3
+ * Jexl evaluator for Dyrected access control.
4
+ * Allows for serializable, dynamic permissions based on user state, request, and document.
5
+ */
6
+ export async function evaluateAccess(expression, context) {
7
+ // If no expression is provided, default to closed (false) for security
8
+ // unless explicitly specified otherwise in the core router logic.
9
+ if (expression === undefined || expression === null)
10
+ return false;
11
+ if (typeof expression === 'boolean')
12
+ return expression;
13
+ try {
14
+ const result = await jexl.eval(expression, context);
15
+ return !!result;
16
+ }
17
+ catch (err) {
18
+ console.error('[dyrected/core] Jexl evaluation failed:', err);
19
+ return false;
20
+ }
21
+ }
22
+ //# sourceMappingURL=jexl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jexl.js","sourceRoot":"","sources":["../../src/auth/jexl.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,UAA+C,EAC/C,OAA6C;IAE7C,uEAAuE;IACvE,kEAAkE;IAClE,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAClE,IAAI,OAAO,UAAU,KAAK,SAAS;QAAE,OAAO,UAAU,CAAC;IAEvD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACpD,OAAO,CAAC,CAAC,MAAM,CAAC;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,yCAAyC,EAAE,GAAG,CAAC,CAAC;QAC9D,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Hash a plain-text password using scrypt.
3
+ * Returns a `salt:hash` string safe to store in the database.
4
+ */
5
+ export declare function hashPassword(plain: string): Promise<string>;
6
+ /**
7
+ * Verify a plain-text password against a stored `salt:hash` string.
8
+ */
9
+ export declare function verifyPassword(plain: string, stored: string): Promise<boolean>;
10
+ //# sourceMappingURL=password.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/auth/password.ts"],"names":[],"mappings":"AAQA;;;GAGG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIjE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASpF"}
@@ -0,0 +1,28 @@
1
+ import { promisify } from 'node:util';
2
+ import { scrypt, randomBytes, timingSafeEqual } from 'node:crypto';
3
+ const scryptAsync = promisify(scrypt);
4
+ const SALT_LEN = 16;
5
+ const KEY_LEN = 64;
6
+ /**
7
+ * Hash a plain-text password using scrypt.
8
+ * Returns a `salt:hash` string safe to store in the database.
9
+ */
10
+ export async function hashPassword(plain) {
11
+ const salt = randomBytes(SALT_LEN).toString('hex');
12
+ const derivedKey = (await scryptAsync(plain, salt, KEY_LEN));
13
+ return `${salt}:${derivedKey.toString('hex')}`;
14
+ }
15
+ /**
16
+ * Verify a plain-text password against a stored `salt:hash` string.
17
+ */
18
+ export async function verifyPassword(plain, stored) {
19
+ const [salt, storedHash] = stored.split(':');
20
+ if (!salt || !storedHash)
21
+ return false;
22
+ const derivedKey = (await scryptAsync(plain, salt, KEY_LEN));
23
+ const storedBuffer = Buffer.from(storedHash, 'hex');
24
+ if (derivedKey.length !== storedBuffer.length)
25
+ return false;
26
+ return timingSafeEqual(derivedKey, storedBuffer);
27
+ }
28
+ //# sourceMappingURL=password.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password.js","sourceRoot":"","sources":["../../src/auth/password.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnE,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAEtC,MAAM,QAAQ,GAAG,EAAE,CAAC;AACpB,MAAM,OAAO,GAAG,EAAE,CAAC;AAEnB;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAa;IAC9C,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,CAAC,MAAM,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAW,CAAC;IACvE,OAAO,GAAG,IAAI,IAAI,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAa,EAAE,MAAc;IAChE,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAEvC,MAAM,UAAU,GAAG,CAAC,MAAM,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAW,CAAC;IACvE,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAEpD,IAAI,UAAU,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC5D,OAAO,eAAe,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;AACnD,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { type JWTPayload } from 'jose';
2
+ export interface CollectionTokenPayload extends JWTPayload {
3
+ sub: string;
4
+ email: string;
5
+ collection: string;
6
+ purpose?: 'invite' | 'reset';
7
+ }
8
+ /**
9
+ * Issue a signed JWT for a user document in an auth collection.
10
+ */
11
+ export declare function signCollectionToken(payload: Omit<CollectionTokenPayload, 'iat' | 'exp'>, expiresIn?: string): Promise<string>;
12
+ /**
13
+ * Verify and decode a collection JWT. Throws if invalid or expired.
14
+ */
15
+ export declare function verifyCollectionToken(token: string): Promise<CollectionTokenPayload>;
16
+ /**
17
+ * Decode a token without verification (read-only, for middleware that wants to be non-blocking).
18
+ */
19
+ export declare function decodeCollectionToken(token: string): CollectionTokenPayload | null;
20
+ //# sourceMappingURL=token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/auth/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAGtE,MAAM,WAAW,sBAAuB,SAAQ,UAAU;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC9B;AAeD;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,IAAI,CAAC,sBAAsB,EAAE,KAAK,GAAG,KAAK,CAAC,EACpD,SAAS,GAAE,MAAuB,GACjC,OAAO,CAAC,MAAM,CAAC,CAMjB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAG1F;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI,CAMlF"}
@@ -0,0 +1,40 @@
1
+ import { SignJWT, jwtVerify, decodeJwt } from 'jose';
2
+ import { TextEncoder } from 'node:util';
3
+ function getSecret() {
4
+ const secret = process.env.DYRECTED_JWT_SECRET || process.env.JWT_SECRET;
5
+ if (!secret) {
6
+ throw new Error('[dyrected/core] DYRECTED_JWT_SECRET is not set. ' +
7
+ 'Add it to your environment variables to enable auth collections.');
8
+ }
9
+ return new TextEncoder().encode(secret);
10
+ }
11
+ const DEFAULT_EXPIRY = '7d';
12
+ /**
13
+ * Issue a signed JWT for a user document in an auth collection.
14
+ */
15
+ export async function signCollectionToken(payload, expiresIn = DEFAULT_EXPIRY) {
16
+ return new SignJWT({ ...payload })
17
+ .setProtectedHeader({ alg: 'HS256' })
18
+ .setIssuedAt()
19
+ .setExpirationTime(expiresIn)
20
+ .sign(getSecret());
21
+ }
22
+ /**
23
+ * Verify and decode a collection JWT. Throws if invalid or expired.
24
+ */
25
+ export async function verifyCollectionToken(token) {
26
+ const { payload } = await jwtVerify(token, getSecret());
27
+ return payload;
28
+ }
29
+ /**
30
+ * Decode a token without verification (read-only, for middleware that wants to be non-blocking).
31
+ */
32
+ export function decodeCollectionToken(token) {
33
+ try {
34
+ return decodeJwt(token);
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ //# sourceMappingURL=token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/auth/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAmB,MAAM,MAAM,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AASxC,SAAS,SAAS;IAChB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;IACzE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,kDAAkD;YAClD,kEAAkE,CACnE,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,cAAc,GAAG,IAAI,CAAC;AAE5B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAAoD,EACpD,YAAoB,cAAc;IAElC,OAAO,IAAI,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;SAC/B,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;SACpC,WAAW,EAAE;SACb,iBAAiB,CAAC,SAAS,CAAC;SAC5B,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAAa;IACvD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACxD,OAAO,OAAiC,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAa;IACjD,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,KAAK,CAA2B,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}