@dyrected/core 2.6.2 → 2.6.4

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 (352) hide show
  1. package/dist/__tests__/access-features.test.d.ts +2 -0
  2. package/dist/__tests__/access-features.test.d.ts.map +1 -0
  3. package/dist/__tests__/access-features.test.js +159 -0
  4. package/dist/__tests__/access-features.test.js.map +1 -0
  5. package/dist/__tests__/access-parity.test.d.ts +2 -0
  6. package/dist/__tests__/access-parity.test.d.ts.map +1 -0
  7. package/dist/__tests__/access-parity.test.js +338 -0
  8. package/dist/__tests__/access-parity.test.js.map +1 -0
  9. package/dist/__tests__/access.test.d.ts +2 -0
  10. package/dist/__tests__/access.test.d.ts.map +1 -0
  11. package/dist/__tests__/access.test.js +137 -0
  12. package/dist/__tests__/access.test.js.map +1 -0
  13. package/dist/__tests__/admin-auth.test.d.ts +2 -0
  14. package/dist/__tests__/admin-auth.test.d.ts.map +1 -0
  15. package/dist/__tests__/admin-auth.test.js +440 -0
  16. package/dist/__tests__/admin-auth.test.js.map +1 -0
  17. package/dist/__tests__/app.test.d.ts +2 -0
  18. package/dist/__tests__/app.test.d.ts.map +1 -0
  19. package/dist/__tests__/app.test.js +112 -0
  20. package/dist/__tests__/app.test.js.map +1 -0
  21. package/dist/__tests__/audit.test.d.ts +2 -0
  22. package/dist/__tests__/audit.test.d.ts.map +1 -0
  23. package/dist/__tests__/audit.test.js +125 -0
  24. package/dist/__tests__/audit.test.js.map +1 -0
  25. package/dist/__tests__/auth-hydration.test.d.ts +2 -0
  26. package/dist/__tests__/auth-hydration.test.d.ts.map +1 -0
  27. package/dist/__tests__/auth-hydration.test.js +90 -0
  28. package/dist/__tests__/auth-hydration.test.js.map +1 -0
  29. package/dist/__tests__/auth-invite.test.d.ts +2 -0
  30. package/dist/__tests__/auth-invite.test.d.ts.map +1 -0
  31. package/dist/__tests__/auth-invite.test.js +152 -0
  32. package/dist/__tests__/auth-invite.test.js.map +1 -0
  33. package/dist/__tests__/auth-lockout.test.d.ts +2 -0
  34. package/dist/__tests__/auth-lockout.test.d.ts.map +1 -0
  35. package/dist/__tests__/auth-lockout.test.js +154 -0
  36. package/dist/__tests__/auth-lockout.test.js.map +1 -0
  37. package/dist/__tests__/auth-sessions.test.d.ts +2 -0
  38. package/dist/__tests__/auth-sessions.test.d.ts.map +1 -0
  39. package/dist/__tests__/auth-sessions.test.js +118 -0
  40. package/dist/__tests__/auth-sessions.test.js.map +1 -0
  41. package/dist/__tests__/config.test.d.ts +2 -0
  42. package/dist/__tests__/config.test.d.ts.map +1 -0
  43. package/dist/__tests__/config.test.js +402 -0
  44. package/dist/__tests__/config.test.js.map +1 -0
  45. package/dist/__tests__/define-field.test.d.ts +2 -0
  46. package/dist/__tests__/define-field.test.d.ts.map +1 -0
  47. package/dist/__tests__/define-field.test.js +121 -0
  48. package/dist/__tests__/define-field.test.js.map +1 -0
  49. package/dist/__tests__/deleteMany.test.d.ts +2 -0
  50. package/dist/__tests__/deleteMany.test.d.ts.map +1 -0
  51. package/dist/__tests__/deleteMany.test.js +75 -0
  52. package/dist/__tests__/deleteMany.test.js.map +1 -0
  53. package/dist/__tests__/depth.test.d.ts +2 -0
  54. package/dist/__tests__/depth.test.d.ts.map +1 -0
  55. package/dist/__tests__/depth.test.js +115 -0
  56. package/dist/__tests__/depth.test.js.map +1 -0
  57. package/dist/__tests__/dynamic-options.test.d.ts +2 -0
  58. package/dist/__tests__/dynamic-options.test.d.ts.map +1 -0
  59. package/dist/__tests__/dynamic-options.test.js +168 -0
  60. package/dist/__tests__/dynamic-options.test.js.map +1 -0
  61. package/dist/__tests__/email.service.test.d.ts +2 -0
  62. package/dist/__tests__/email.service.test.d.ts.map +1 -0
  63. package/dist/__tests__/email.service.test.js +52 -0
  64. package/dist/__tests__/email.service.test.js.map +1 -0
  65. package/dist/__tests__/field-inference.test-types.d.ts +161 -0
  66. package/dist/__tests__/field-inference.test-types.d.ts.map +1 -0
  67. package/dist/__tests__/field-inference.test-types.js +87 -0
  68. package/dist/__tests__/field-inference.test-types.js.map +1 -0
  69. package/dist/__tests__/fixtures/editorial-workflow.d.ts +14 -0
  70. package/dist/__tests__/fixtures/editorial-workflow.d.ts.map +1 -0
  71. package/dist/__tests__/fixtures/editorial-workflow.js +12 -0
  72. package/dist/__tests__/fixtures/editorial-workflow.js.map +1 -0
  73. package/dist/__tests__/hooks.test.d.ts +2 -0
  74. package/dist/__tests__/hooks.test.d.ts.map +1 -0
  75. package/dist/__tests__/hooks.test.js +320 -0
  76. package/dist/__tests__/hooks.test.js.map +1 -0
  77. package/dist/__tests__/mocks.d.ts +75 -0
  78. package/dist/__tests__/mocks.d.ts.map +1 -0
  79. package/dist/__tests__/mocks.js +170 -0
  80. package/dist/__tests__/mocks.js.map +1 -0
  81. package/dist/__tests__/observability.test.d.ts +2 -0
  82. package/dist/__tests__/observability.test.d.ts.map +1 -0
  83. package/dist/__tests__/observability.test.js +233 -0
  84. package/dist/__tests__/observability.test.js.map +1 -0
  85. package/dist/__tests__/openapi.test.d.ts +2 -0
  86. package/dist/__tests__/openapi.test.d.ts.map +1 -0
  87. package/dist/__tests__/openapi.test.js +105 -0
  88. package/dist/__tests__/openapi.test.js.map +1 -0
  89. package/dist/__tests__/parse-sort.test.d.ts +2 -0
  90. package/dist/__tests__/parse-sort.test.d.ts.map +1 -0
  91. package/dist/__tests__/parse-sort.test.js +24 -0
  92. package/dist/__tests__/parse-sort.test.js.map +1 -0
  93. package/dist/__tests__/preferences.test.d.ts +2 -0
  94. package/dist/__tests__/preferences.test.d.ts.map +1 -0
  95. package/dist/__tests__/preferences.test.js +168 -0
  96. package/dist/__tests__/preferences.test.js.map +1 -0
  97. package/dist/__tests__/router.test.d.ts +2 -0
  98. package/dist/__tests__/router.test.d.ts.map +1 -0
  99. package/dist/__tests__/router.test.js +70 -0
  100. package/dist/__tests__/router.test.js.map +1 -0
  101. package/dist/__tests__/search.test.d.ts +2 -0
  102. package/dist/__tests__/search.test.d.ts.map +1 -0
  103. package/dist/__tests__/search.test.js +174 -0
  104. package/dist/__tests__/search.test.js.map +1 -0
  105. package/dist/__tests__/upload-validation.test.d.ts +2 -0
  106. package/dist/__tests__/upload-validation.test.d.ts.map +1 -0
  107. package/dist/__tests__/upload-validation.test.js +41 -0
  108. package/dist/__tests__/upload-validation.test.js.map +1 -0
  109. package/dist/__tests__/where.test.d.ts +2 -0
  110. package/dist/__tests__/where.test.d.ts.map +1 -0
  111. package/dist/__tests__/where.test.js +105 -0
  112. package/dist/__tests__/where.test.js.map +1 -0
  113. package/dist/__tests__/workflow.test.d.ts +2 -0
  114. package/dist/__tests__/workflow.test.d.ts.map +1 -0
  115. package/dist/__tests__/workflow.test.js +684 -0
  116. package/dist/__tests__/workflow.test.js.map +1 -0
  117. package/dist/app-config-C9VJ6rTv.d.cts +2092 -0
  118. package/dist/app-config-C9VJ6rTv.d.ts +2092 -0
  119. package/dist/app-config-CYV70eoF.d.cts +2100 -0
  120. package/dist/app-config-CYV70eoF.d.ts +2100 -0
  121. package/dist/app.d.ts +35 -0
  122. package/dist/app.d.ts.map +1 -0
  123. package/dist/app.js +164 -0
  124. package/dist/app.js.map +1 -0
  125. package/dist/auth/access.d.ts +5 -0
  126. package/dist/auth/access.d.ts.map +1 -0
  127. package/dist/auth/access.js +59 -0
  128. package/dist/auth/access.js.map +1 -0
  129. package/dist/auth/jexl.d.ts +13 -0
  130. package/dist/auth/jexl.d.ts.map +1 -0
  131. package/dist/auth/jexl.js +30 -0
  132. package/dist/auth/jexl.js.map +1 -0
  133. package/dist/auth/lockout.d.ts +11 -0
  134. package/dist/auth/lockout.d.ts.map +1 -0
  135. package/dist/auth/lockout.js +37 -0
  136. package/dist/auth/lockout.js.map +1 -0
  137. package/dist/auth/password.d.ts +10 -0
  138. package/dist/auth/password.d.ts.map +1 -0
  139. package/dist/auth/password.js +28 -0
  140. package/dist/auth/password.js.map +1 -0
  141. package/dist/auth/sessions.d.ts +39 -0
  142. package/dist/auth/sessions.d.ts.map +1 -0
  143. package/dist/auth/sessions.js +126 -0
  144. package/dist/auth/sessions.js.map +1 -0
  145. package/dist/auth/token.d.ts +23 -0
  146. package/dist/auth/token.d.ts.map +1 -0
  147. package/dist/auth/token.js +40 -0
  148. package/dist/auth/token.js.map +1 -0
  149. package/dist/chunk-23NM4LDU.js +2883 -0
  150. package/dist/chunk-2TKDCCIR.js +2622 -0
  151. package/dist/chunk-3SFITPX4.js +2628 -0
  152. package/dist/chunk-CQVTQ67D.js +2632 -0
  153. package/dist/chunk-ELHRRPKX.js +2863 -0
  154. package/dist/chunk-HRLSFTLR.js +3061 -0
  155. package/dist/chunk-QTIAQBNH.js +3097 -0
  156. package/dist/chunk-T2DGC4MD.js +3008 -0
  157. package/dist/chunk-TLU77TLE.js +3203 -0
  158. package/dist/chunk-YEBCT77K.js +3269 -0
  159. package/dist/chunk-YXEKNN5X.js +3085 -0
  160. package/dist/controllers/admin-auth.controller.d.ts +71 -0
  161. package/dist/controllers/admin-auth.controller.d.ts.map +1 -0
  162. package/dist/controllers/admin-auth.controller.js +450 -0
  163. package/dist/controllers/admin-auth.controller.js.map +1 -0
  164. package/dist/controllers/audit.controller.d.ts +42 -0
  165. package/dist/controllers/audit.controller.d.ts.map +1 -0
  166. package/dist/controllers/audit.controller.js +149 -0
  167. package/dist/controllers/audit.controller.js.map +1 -0
  168. package/dist/controllers/auth.controller.d.ts +143 -0
  169. package/dist/controllers/auth.controller.d.ts.map +1 -0
  170. package/dist/controllers/auth.controller.js +572 -0
  171. package/dist/controllers/auth.controller.js.map +1 -0
  172. package/dist/controllers/collection.controller.d.ts +170 -0
  173. package/dist/controllers/collection.controller.d.ts.map +1 -0
  174. package/dist/controllers/collection.controller.js +1033 -0
  175. package/dist/controllers/collection.controller.js.map +1 -0
  176. package/dist/controllers/global.controller.d.ts +20 -0
  177. package/dist/controllers/global.controller.d.ts.map +1 -0
  178. package/dist/controllers/global.controller.js +182 -0
  179. package/dist/controllers/global.controller.js.map +1 -0
  180. package/dist/controllers/media.controller.d.ts +39 -0
  181. package/dist/controllers/media.controller.d.ts.map +1 -0
  182. package/dist/controllers/media.controller.js +178 -0
  183. package/dist/controllers/media.controller.js.map +1 -0
  184. package/dist/controllers/preview.controller.d.ts +37 -0
  185. package/dist/controllers/preview.controller.d.ts.map +1 -0
  186. package/dist/controllers/preview.controller.js +48 -0
  187. package/dist/controllers/preview.controller.js.map +1 -0
  188. package/dist/index.cjs +707 -27
  189. package/dist/index.d.cts +77 -5
  190. package/dist/index.d.ts +77 -5
  191. package/dist/index.d.ts.map +1 -0
  192. package/dist/index.js +37 -1
  193. package/dist/index.js.map +1 -0
  194. package/dist/middleware/auth.d.ts +19 -0
  195. package/dist/middleware/auth.d.ts.map +1 -0
  196. package/dist/middleware/auth.js +157 -0
  197. package/dist/middleware/auth.js.map +1 -0
  198. package/dist/middleware/rate-limit.d.ts +9 -0
  199. package/dist/middleware/rate-limit.d.ts.map +1 -0
  200. package/dist/middleware/rate-limit.js +75 -0
  201. package/dist/middleware/rate-limit.js.map +1 -0
  202. package/dist/network.d.ts +6 -0
  203. package/dist/network.d.ts.map +1 -0
  204. package/dist/network.js +70 -0
  205. package/dist/network.js.map +1 -0
  206. package/dist/observability.d.ts +113 -0
  207. package/dist/observability.d.ts.map +1 -0
  208. package/dist/observability.js +497 -0
  209. package/dist/observability.js.map +1 -0
  210. package/dist/router.d.ts +8 -0
  211. package/dist/router.d.ts.map +1 -0
  212. package/dist/router.js +704 -0
  213. package/dist/router.js.map +1 -0
  214. package/dist/server.cjs +861 -54
  215. package/dist/server.d.cts +9 -1
  216. package/dist/server.d.ts +9 -1
  217. package/dist/server.d.ts.map +1 -0
  218. package/dist/server.js +189 -26
  219. package/dist/server.js.map +1 -0
  220. package/dist/services/audit.service.d.ts +23 -0
  221. package/dist/services/audit.service.d.ts.map +1 -0
  222. package/dist/services/audit.service.js +39 -0
  223. package/dist/services/audit.service.js.map +1 -0
  224. package/dist/services/defaults.service.d.ts +8 -0
  225. package/dist/services/defaults.service.d.ts.map +1 -0
  226. package/dist/services/defaults.service.js +55 -0
  227. package/dist/services/defaults.service.js.map +1 -0
  228. package/dist/services/email-template.d.ts +46 -0
  229. package/dist/services/email-template.d.ts.map +1 -0
  230. package/dist/services/email-template.js +88 -0
  231. package/dist/services/email-template.js.map +1 -0
  232. package/dist/services/email.service.d.ts +34 -0
  233. package/dist/services/email.service.d.ts.map +1 -0
  234. package/dist/services/email.service.js +129 -0
  235. package/dist/services/email.service.js.map +1 -0
  236. package/dist/services/media.service.d.ts +20 -0
  237. package/dist/services/media.service.d.ts.map +1 -0
  238. package/dist/services/media.service.js +49 -0
  239. package/dist/services/media.service.js.map +1 -0
  240. package/dist/services/population.service.d.ts +20 -0
  241. package/dist/services/population.service.d.ts.map +1 -0
  242. package/dist/services/population.service.js +224 -0
  243. package/dist/services/population.service.js.map +1 -0
  244. package/dist/types/access.d.ts +48 -0
  245. package/dist/types/access.d.ts.map +1 -0
  246. package/dist/types/access.js +2 -0
  247. package/dist/types/access.js.map +1 -0
  248. package/dist/types/adapters.d.ts +152 -0
  249. package/dist/types/adapters.d.ts.map +1 -0
  250. package/dist/types/adapters.js +2 -0
  251. package/dist/types/adapters.js.map +1 -0
  252. package/dist/types/admin-auth.d.ts +132 -0
  253. package/dist/types/admin-auth.d.ts.map +1 -0
  254. package/dist/types/admin-auth.js +2 -0
  255. package/dist/types/admin-auth.js.map +1 -0
  256. package/dist/types/admin.d.ts +86 -0
  257. package/dist/types/admin.d.ts.map +1 -0
  258. package/dist/types/admin.js +2 -0
  259. package/dist/types/admin.js.map +1 -0
  260. package/dist/types/app-config.d.ts +279 -0
  261. package/dist/types/app-config.d.ts.map +1 -0
  262. package/dist/types/app-config.js +2 -0
  263. package/dist/types/app-config.js.map +1 -0
  264. package/dist/types/documents.d.ts +65 -0
  265. package/dist/types/documents.d.ts.map +1 -0
  266. package/dist/types/documents.js +2 -0
  267. package/dist/types/documents.js.map +1 -0
  268. package/dist/types/hooks.d.ts +122 -0
  269. package/dist/types/hooks.d.ts.map +1 -0
  270. package/dist/types/hooks.js +2 -0
  271. package/dist/types/hooks.js.map +1 -0
  272. package/dist/types/index.d.ts +13 -0
  273. package/dist/types/index.d.ts.map +1 -0
  274. package/dist/types/index.js +13 -0
  275. package/dist/types/index.js.map +1 -0
  276. package/dist/types/request.d.ts +42 -0
  277. package/dist/types/request.d.ts.map +1 -0
  278. package/dist/types/request.js +2 -0
  279. package/dist/types/request.js.map +1 -0
  280. package/dist/types/schema-config.d.ts +443 -0
  281. package/dist/types/schema-config.d.ts.map +1 -0
  282. package/dist/types/schema-config.js +2 -0
  283. package/dist/types/schema-config.js.map +1 -0
  284. package/dist/types/schema-core.d.ts +628 -0
  285. package/dist/types/schema-core.d.ts.map +1 -0
  286. package/dist/types/schema-core.js +2 -0
  287. package/dist/types/schema-core.js.map +1 -0
  288. package/dist/types/schema-inference.d.ts +73 -0
  289. package/dist/types/schema-inference.d.ts.map +1 -0
  290. package/dist/types/schema-inference.js +2 -0
  291. package/dist/types/schema-inference.js.map +1 -0
  292. package/dist/types/workflows.d.ts +121 -0
  293. package/dist/types/workflows.d.ts.map +1 -0
  294. package/dist/types/workflows.js +7 -0
  295. package/dist/types/workflows.js.map +1 -0
  296. package/dist/utils/access-control.d.ts +35 -0
  297. package/dist/utils/access-control.d.ts.map +1 -0
  298. package/dist/utils/access-control.js +161 -0
  299. package/dist/utils/access-control.js.map +1 -0
  300. package/dist/utils/admin-auth.d.ts +5 -0
  301. package/dist/utils/admin-auth.d.ts.map +1 -0
  302. package/dist/utils/admin-auth.js +39 -0
  303. package/dist/utils/admin-auth.js.map +1 -0
  304. package/dist/utils/block-references.d.ts +10 -0
  305. package/dist/utils/block-references.d.ts.map +1 -0
  306. package/dist/utils/block-references.js +100 -0
  307. package/dist/utils/block-references.js.map +1 -0
  308. package/dist/utils/collection-search.d.ts +11 -0
  309. package/dist/utils/collection-search.d.ts.map +1 -0
  310. package/dist/utils/collection-search.js +204 -0
  311. package/dist/utils/collection-search.js.map +1 -0
  312. package/dist/utils/config.d.ts +8 -0
  313. package/dist/utils/config.d.ts.map +1 -0
  314. package/dist/utils/config.js +336 -0
  315. package/dist/utils/config.js.map +1 -0
  316. package/dist/utils/hooks.d.ts +41 -0
  317. package/dist/utils/hooks.d.ts.map +1 -0
  318. package/dist/utils/hooks.js +177 -0
  319. package/dist/utils/hooks.js.map +1 -0
  320. package/dist/utils/openapi.d.ts +6 -0
  321. package/dist/utils/openapi.d.ts.map +1 -0
  322. package/dist/utils/openapi.js +981 -0
  323. package/dist/utils/openapi.js.map +1 -0
  324. package/dist/utils/parse-sort.d.ts +43 -0
  325. package/dist/utils/parse-sort.d.ts.map +1 -0
  326. package/dist/utils/parse-sort.js +70 -0
  327. package/dist/utils/parse-sort.js.map +1 -0
  328. package/dist/utils/parse-where.d.ts +69 -0
  329. package/dist/utils/parse-where.d.ts.map +1 -0
  330. package/dist/utils/parse-where.js +202 -0
  331. package/dist/utils/parse-where.js.map +1 -0
  332. package/dist/utils/readonly-db.d.ts +9 -0
  333. package/dist/utils/readonly-db.d.ts.map +1 -0
  334. package/dist/utils/readonly-db.js +21 -0
  335. package/dist/utils/readonly-db.js.map +1 -0
  336. package/dist/utils/swagger.d.ts +11 -0
  337. package/dist/utils/swagger.d.ts.map +1 -0
  338. package/dist/utils/swagger.js +62 -0
  339. package/dist/utils/swagger.js.map +1 -0
  340. package/dist/utils/upload-validation.d.ts +23 -0
  341. package/dist/utils/upload-validation.d.ts.map +1 -0
  342. package/dist/utils/upload-validation.js +46 -0
  343. package/dist/utils/upload-validation.js.map +1 -0
  344. package/dist/utils/where-sanitizer.d.ts +10 -0
  345. package/dist/utils/where-sanitizer.d.ts.map +1 -0
  346. package/dist/utils/where-sanitizer.js +67 -0
  347. package/dist/utils/where-sanitizer.js.map +1 -0
  348. package/dist/workflows.d.ts +86 -0
  349. package/dist/workflows.d.ts.map +1 -0
  350. package/dist/workflows.js +405 -0
  351. package/dist/workflows.js.map +1 -0
  352. package/package.json +1 -1
package/dist/server.d.cts CHANGED
@@ -2,7 +2,7 @@ import * as hono_types from 'hono/types';
2
2
  import * as hono from 'hono';
3
3
  import { Hono, Context } from 'hono';
4
4
  import { Logger } from 'pino';
5
- import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-DCWinlNK.cjs';
5
+ import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-CYV70eoF.cjs';
6
6
  import { JWTPayload } from 'jose';
7
7
  import { Tracer, Counter, Attributes, Histogram, Span } from '@opentelemetry/api';
8
8
  import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
@@ -153,6 +153,9 @@ declare class AuthController {
153
153
  private collection;
154
154
  constructor(collection: CollectionConfig);
155
155
  private sanitizeUser;
156
+ private hasField;
157
+ private buildPendingInviteData;
158
+ private buildAcceptedInviteData;
156
159
  private clearLockoutState;
157
160
  private recordFailedLogin;
158
161
  init(c: Context<DyrectedContext>): Promise<(Response & hono.TypedResponse<{
@@ -185,6 +188,9 @@ declare class AuthController {
185
188
  }, 401, "json">) | (Response & hono.TypedResponse<{
186
189
  error: true;
187
190
  message: string;
191
+ }, 403, "json">) | (Response & hono.TypedResponse<{
192
+ error: true;
193
+ message: string;
188
194
  retryAfterSeconds: number;
189
195
  }, 429, "json">) | (Response & hono.TypedResponse<{
190
196
  token: string;
@@ -251,6 +257,8 @@ declare class AuthController {
251
257
  }, 409, "json">) | (Response & hono.TypedResponse<{
252
258
  success: true;
253
259
  message: string;
260
+ token: string;
261
+ inviteUrl: string | undefined;
254
262
  }, hono_utils_http_status.ContentfulStatusCode, "json">)>;
255
263
  acceptInvite(c: Context<DyrectedContext>): Promise<(Response & hono.TypedResponse<{
256
264
  message: string;
package/dist/server.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as hono_types from 'hono/types';
2
2
  import * as hono from 'hono';
3
3
  import { Hono, Context } from 'hono';
4
4
  import { Logger } from 'pino';
5
- import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-DCWinlNK.js';
5
+ import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-CYV70eoF.js';
6
6
  import { JWTPayload } from 'jose';
7
7
  import { Tracer, Counter, Attributes, Histogram, Span } from '@opentelemetry/api';
8
8
  import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
@@ -153,6 +153,9 @@ declare class AuthController {
153
153
  private collection;
154
154
  constructor(collection: CollectionConfig);
155
155
  private sanitizeUser;
156
+ private hasField;
157
+ private buildPendingInviteData;
158
+ private buildAcceptedInviteData;
156
159
  private clearLockoutState;
157
160
  private recordFailedLogin;
158
161
  init(c: Context<DyrectedContext>): Promise<(Response & hono.TypedResponse<{
@@ -185,6 +188,9 @@ declare class AuthController {
185
188
  }, 401, "json">) | (Response & hono.TypedResponse<{
186
189
  error: true;
187
190
  message: string;
191
+ }, 403, "json">) | (Response & hono.TypedResponse<{
192
+ error: true;
193
+ message: string;
188
194
  retryAfterSeconds: number;
189
195
  }, 429, "json">) | (Response & hono.TypedResponse<{
190
196
  token: string;
@@ -251,6 +257,8 @@ declare class AuthController {
251
257
  }, 409, "json">) | (Response & hono.TypedResponse<{
252
258
  success: true;
253
259
  message: string;
260
+ token: string;
261
+ inviteUrl: string | undefined;
254
262
  }, hono_utils_http_status.ContentfulStatusCode, "json">)>;
255
263
  acceptInvite(c: Context<DyrectedContext>): Promise<(Response & hono.TypedResponse<{
256
264
  message: string;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,kCAAkC,CAAC;AACjD,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC"}
package/dist/server.js CHANGED
@@ -1,10 +1,15 @@
1
1
  import {
2
2
  WORKFLOW_HISTORY_COLLECTION,
3
+ assertValidAdminConditionsInConfig,
4
+ assertValidDeclarativeAccessInConfig,
5
+ assertValidDeclarativeHooksInConfig,
6
+ assertValidPreviewUrlsInConfig,
3
7
  attachRequestMetrics,
4
8
  bindObservabilityRuntime,
5
9
  buildRequestLogger,
6
10
  canViewWorkflowDraft,
7
11
  captureRequestBody,
12
+ collectConfigDiagnostics,
8
13
  createObservabilityRuntime,
9
14
  createRequestSpan,
10
15
  createWorkflowDocument,
@@ -36,7 +41,7 @@ import {
36
41
  touchAuthSession,
37
42
  transitionWorkflow,
38
43
  verifyCollectionToken
39
- } from "./chunk-K3ASMUKV.js";
44
+ } from "./chunk-YEBCT77K.js";
40
45
 
41
46
  // src/app.ts
42
47
  import { Hono } from "hono";
@@ -985,6 +990,10 @@ var CollectionController = class {
985
990
  query: where,
986
991
  user,
987
992
  db: readonlyDb
993
+ },
994
+ {
995
+ surface: "collection.beforeRead",
996
+ path: `collection:${this.collection.slug}.hooks.beforeRead`
988
997
  }
989
998
  );
990
999
  if (beforeReadResult !== void 0) {
@@ -1267,6 +1276,9 @@ var CollectionController = class {
1267
1276
  user,
1268
1277
  operation: "create",
1269
1278
  db: readonlyDb
1279
+ }, {
1280
+ surface: "collection.beforeChange",
1281
+ path: `collection:${this.collection.slug}.hooks.beforeChange`
1270
1282
  });
1271
1283
  const doc = this.collection.workflow ? (await createWorkflowDocument({
1272
1284
  config,
@@ -1301,6 +1313,9 @@ var CollectionController = class {
1301
1313
  req: c.req,
1302
1314
  user,
1303
1315
  db: readonlyDb
1316
+ }, {
1317
+ surface: "collection.afterRead",
1318
+ path: `collection:${this.collection.slug}.hooks.afterRead`
1304
1319
  });
1305
1320
  const finalDoc = await executeFieldAfterRead(
1306
1321
  this.collection.fields,
@@ -1398,6 +1413,9 @@ var CollectionController = class {
1398
1413
  user,
1399
1414
  operation: "create",
1400
1415
  db: readonlyDb
1416
+ }, {
1417
+ surface: "collection.beforeChange",
1418
+ path: `collection:${this.collection.slug}.hooks.beforeChange`
1401
1419
  });
1402
1420
  const doc = await db.create({
1403
1421
  collection: this.collection.slug,
@@ -1420,6 +1438,9 @@ var CollectionController = class {
1420
1438
  req: c.req,
1421
1439
  user,
1422
1440
  db: readonlyDb
1441
+ }, {
1442
+ surface: "collection.afterRead",
1443
+ path: `collection:${this.collection.slug}.hooks.afterRead`
1423
1444
  });
1424
1445
  const finalDoc = await executeFieldAfterRead(
1425
1446
  this.collection.fields,
@@ -1528,6 +1549,9 @@ var CollectionController = class {
1528
1549
  user,
1529
1550
  operation: "update",
1530
1551
  db: readonlyDb
1552
+ }, {
1553
+ surface: "collection.beforeChange",
1554
+ path: `collection:${this.collection.slug}.hooks.beforeChange`
1531
1555
  });
1532
1556
  const doc = this.collection.workflow ? (await saveWorkflowDraft({
1533
1557
  config,
@@ -1565,6 +1589,9 @@ var CollectionController = class {
1565
1589
  req: c.req,
1566
1590
  user,
1567
1591
  db: readonlyDb
1592
+ }, {
1593
+ surface: "collection.afterRead",
1594
+ path: `collection:${this.collection.slug}.hooks.afterRead`
1568
1595
  });
1569
1596
  const finalDoc = await executeFieldAfterRead(
1570
1597
  this.collection.fields,
@@ -1959,6 +1986,9 @@ var GlobalController = class {
1959
1986
  query: void 0,
1960
1987
  user,
1961
1988
  db: readonlyDb
1989
+ }, {
1990
+ surface: "global.beforeRead",
1991
+ path: `global:${this.global.slug}.hooks.beforeRead`
1962
1992
  });
1963
1993
  let data = await db.getGlobal({ slug: this.global.slug });
1964
1994
  const isEmpty = !data || isFunctionallyEmpty(data);
@@ -1996,6 +2026,10 @@ var GlobalController = class {
1996
2026
  req: c.req,
1997
2027
  user,
1998
2028
  db: readonlyDb
2029
+ },
2030
+ {
2031
+ surface: "global.afterRead",
2032
+ path: `global:${this.global.slug}.hooks.afterRead`
1999
2033
  }
2000
2034
  );
2001
2035
  const docWithFieldHooks = await executeFieldAfterRead(
@@ -2078,6 +2112,9 @@ var GlobalController = class {
2078
2112
  user,
2079
2113
  operation: "update",
2080
2114
  db: readonlyDb
2115
+ }, {
2116
+ surface: "global.beforeChange",
2117
+ path: `global:${this.global.slug}.hooks.beforeChange`
2081
2118
  });
2082
2119
  const updated = await db.updateGlobal({ slug: this.global.slug, data });
2083
2120
  await runCollectionHooks(
@@ -2097,6 +2134,9 @@ var GlobalController = class {
2097
2134
  req: c.req,
2098
2135
  user,
2099
2136
  db: readonlyDb
2137
+ }, {
2138
+ surface: "global.afterRead",
2139
+ path: `global:${this.global.slug}.hooks.afterRead`
2100
2140
  });
2101
2141
  const finalDoc = await executeFieldAfterRead(
2102
2142
  this.global.fields,
@@ -2317,6 +2357,9 @@ var MediaController = class {
2317
2357
  }
2318
2358
  };
2319
2359
 
2360
+ // src/controllers/auth.controller.ts
2361
+ import { randomBytes as randomBytes2 } from "crypto";
2362
+
2320
2363
  // src/auth/lockout.ts
2321
2364
  var DEFAULT_MAX_LOGIN_ATTEMPTS = 5;
2322
2365
  var DEFAULT_LOCK_TIME_MS = 10 * 60 * 1e3;
@@ -2361,6 +2404,7 @@ var emailTokens = {
2361
2404
  border: "#dde0d7",
2362
2405
  accent: "#b6ff2e",
2363
2406
  code: "#f1f3ec",
2407
+ codeBorder: "#e2e5dc",
2364
2408
  dangerSurface: "#fff2f0",
2365
2409
  dangerBorder: "#ffc9c2",
2366
2410
  dangerText: "#9f251b"
@@ -2410,7 +2454,13 @@ function table(content, style = "width:100%") {
2410
2454
  }
2411
2455
  function detailBox(content, monospace = false) {
2412
2456
  const font = monospace ? emailTokens.mono : emailTokens.font;
2413
- return table(row(escapeHtml(content), `padding:14px 16px;font-family:${font};font-size:13px;line-height:1.5;font-weight:${monospace ? "400" : "700"};color:${emailTokens.colors.text};word-break:break-all`), `width:100%;background:${emailTokens.colors.code};border-radius:${emailTokens.radius.control}`);
2457
+ return table(
2458
+ row(
2459
+ escapeHtml(content),
2460
+ `padding:14px 16px;font-family:${font};font-size:13px;line-height:1.5;font-weight:${monospace ? "400" : "700"};color:${emailTokens.colors.text};word-break:break-all`
2461
+ ),
2462
+ `width:100%;background:${emailTokens.colors.code};border:1px solid ${emailTokens.colors.codeBorder};border-radius:${emailTokens.radius.control}`
2463
+ );
2414
2464
  }
2415
2465
  function ctaButton(label, href) {
2416
2466
  const safeHref = safeHttpUrl(href);
@@ -2420,22 +2470,46 @@ function ctaButton(label, href) {
2420
2470
  "padding:8px 0 24px"
2421
2471
  ), "width:auto");
2422
2472
  }
2473
+ function safeLinkDetailBox(href) {
2474
+ const safeHref = safeHttpUrl(href);
2475
+ if (!safeHref) return "";
2476
+ return detailBox(safeHref, true);
2477
+ }
2423
2478
  function alertBox(content) {
2424
2479
  return table(row(escapeHtml(content), `padding:13px 16px;font-family:${emailTokens.font};font-size:13px;line-height:1.5;color:${emailTokens.colors.dangerText}`), `width:100%;background:${emailTokens.colors.dangerSurface};border:1px solid ${emailTokens.colors.dangerBorder};border-radius:${emailTokens.radius.control}`);
2425
2480
  }
2426
2481
  function layout({ preheader, title, content, footer }) {
2427
2482
  return `<!doctype html>
2428
- <html lang="en">
2429
- <head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"></head>
2430
- <body style="margin:0;padding:0;background:${emailTokens.colors.canvas}">
2431
- <div style="display:none;max-height:0;overflow:hidden;opacity:0;color:transparent">${escapeHtml(preheader)}</div>
2432
- ${table(row(
2433
- table(
2434
- row("&nbsp;", `height:5px;background:${emailTokens.colors.accent};font-size:0;line-height:0`) + row(`${sectionLabel("Dyrected")}${heading(title)}`, "padding:30px 32px 24px") + row(content, "padding:0 32px 32px") + row(`${divider()}${paragraph(footer, "20px 0 6px")}${paragraph("Privacy: this message contains account-related information; please avoid forwarding it.", "0")}`, "padding:0 32px 28px"),
2435
- `width:100%;max-width:${emailTokens.width};background:${emailTokens.colors.surface};border:1px solid ${emailTokens.colors.border};border-radius:${emailTokens.radius.card};overflow:hidden`
2483
+ <html lang="en" dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
2484
+ <head>
2485
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
2486
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
2487
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
2488
+ <meta name="x-apple-disable-message-reformatting">
2489
+ <meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no">
2490
+ <meta name="color-scheme" content="light">
2491
+ <meta name="supported-color-schemes" content="light">
2492
+ <title>${escapeHtml(title)}</title>
2493
+ </head>
2494
+ <body style="margin:0;padding:0;background-color:${emailTokens.colors.canvas};word-spacing:normal;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%">
2495
+ <div style="display:none;max-height:0;max-width:0;overflow:hidden;opacity:0;mso-hide:all;color:transparent;font-size:1px;line-height:1px">
2496
+ ${escapeHtml(preheader)}&#8203;&#847;&zwnj;&nbsp;&#8199;&#8199;&#847;&zwnj;&nbsp;
2497
+ </div>
2498
+ <center lang="en" style="width:100%;background-color:${emailTokens.colors.canvas}">
2499
+ ${table(
2500
+ row(
2501
+ table(
2502
+ row("&nbsp;", `height:5px;background:${emailTokens.colors.accent};font-size:0;line-height:0`) + row(`${sectionLabel("Dyrected")}${heading(title)}`, "padding:30px 32px 24px") + row(content, "padding:0 32px 32px") + row(
2503
+ `${divider()}${paragraph(footer, "20px 0 6px")}${paragraph("Privacy: this message contains account-related information; please avoid forwarding it.", "0")}`,
2504
+ "padding:0 32px 28px"
2505
+ ),
2506
+ `width:100%;max-width:${emailTokens.width};background:${emailTokens.colors.surface};border:1px solid ${emailTokens.colors.border};border-radius:${emailTokens.radius.card};overflow:hidden`
2507
+ ),
2508
+ "padding:32px 12px"
2436
2509
  ),
2437
- "padding:32px 12px"
2438
- ), `width:100%;background:${emailTokens.colors.canvas}`)}
2510
+ `width:100%;background:${emailTokens.colors.canvas}`
2511
+ )}
2512
+ </center>
2439
2513
  </body>
2440
2514
  </html>`;
2441
2515
  }
@@ -2521,12 +2595,14 @@ function buildWelcomeEmail(config, args) {
2521
2595
  }
2522
2596
  function buildInviteEmail(config, args) {
2523
2597
  const custom = config.email?.templates?.invite?.(args);
2598
+ const inviteLink = args.url;
2599
+ const inviteLinkBlock = inviteLink ? safeLinkDetailBox(inviteLink) : "";
2524
2600
  return {
2525
2601
  subject: custom?.subject ?? "You've been invited",
2526
2602
  html: custom?.html ?? layout({
2527
- preheader: "You've been invited to join a Dyrected account.",
2603
+ preheader: "You've been invited to join a Dyrected admin area.",
2528
2604
  title: "You've been invited",
2529
- content: `${args.invitedByEmail ? paragraph(`You were invited by ${args.invitedByEmail}.`) : ""}${paragraph("Use the token below to accept your invitation. It expires in 7 days.")}${sectionLabel("Invitation token")}${detailBox(args.token, true)}`,
2605
+ content: inviteLink ? `${args.invitedByEmail ? paragraph(`You were invited by ${args.invitedByEmail}.`) : ""}${paragraph("Use the invitation link below to create your account. The link expires in 7 days.")}${ctaButton("Accept invitation", inviteLink)}${sectionLabel("Invitation link")}${inviteLinkBlock}${paragraph("If the button does not work, copy and paste the link above into your browser.", "12px 0 0")}` : `${args.invitedByEmail ? paragraph(`You were invited by ${args.invitedByEmail}.`) : ""}${paragraph("Use the invitation token below to accept your invitation. It expires in 7 days.")}${sectionLabel("Invitation token")}${detailBox(args.token, true)}`,
2530
2606
  footer: "If you weren't expecting this invitation, you can safely ignore this email."
2531
2607
  })
2532
2608
  };
@@ -2534,12 +2610,13 @@ function buildInviteEmail(config, args) {
2534
2610
  function buildResetPasswordEmail(config, args) {
2535
2611
  const custom = config.email?.templates?.resetPassword?.(args);
2536
2612
  const resetLink = args.url;
2613
+ const resetLinkBlock = resetLink ? safeLinkDetailBox(resetLink) : "";
2537
2614
  return {
2538
2615
  subject: custom?.subject ?? "Reset your password",
2539
2616
  html: custom?.html ?? layout({
2540
2617
  preheader: "Reset your Dyrected password.",
2541
2618
  title: "Reset your password",
2542
- content: `${paragraph("We received a request to reset your password. The reset link and token expire in 1 hour.")}${resetLink ? ctaButton("Reset password", resetLink) : ""}${sectionLabel(resetLink ? "Or use this token" : "Reset token")}${detailBox(args.token, true)}`,
2619
+ content: resetLink ? `${paragraph("We received a request to reset your password. The reset link expires in 1 hour.")}${ctaButton("Reset password", resetLink)}${sectionLabel("Reset link")}${resetLinkBlock}${paragraph("If the button does not work, copy and paste the link above into your browser.", "12px 0 0")}` : `${paragraph("We received a request to reset your password. The reset token expires in 1 hour.")}${sectionLabel("Reset token")}${detailBox(args.token, true)}`,
2543
2620
  footer: "If you didn't request a password reset, you can safely ignore this email."
2544
2621
  })
2545
2622
  };
@@ -2572,6 +2649,36 @@ var AuthController = class {
2572
2649
  } = user;
2573
2650
  return safeUser;
2574
2651
  }
2652
+ hasField(name) {
2653
+ return (this.collection.fields || []).some((field) => field.name === name);
2654
+ }
2655
+ async buildPendingInviteData(email, extraFields = {}) {
2656
+ const {
2657
+ id: _id,
2658
+ password: _password,
2659
+ email: _email,
2660
+ ...safeExtraFields
2661
+ } = extraFields;
2662
+ const data = {
2663
+ ...safeExtraFields,
2664
+ email,
2665
+ password: await hashPassword(randomBytes2(32).toString("hex"))
2666
+ };
2667
+ if (this.hasField("status")) {
2668
+ data.status = "pending";
2669
+ }
2670
+ return data;
2671
+ }
2672
+ buildAcceptedInviteData(hashedPassword, extraFields) {
2673
+ const data = {
2674
+ ...extraFields,
2675
+ password: hashedPassword
2676
+ };
2677
+ if (this.hasField("status")) {
2678
+ data.status = "active";
2679
+ }
2680
+ return data;
2681
+ }
2575
2682
  clearLockoutState(c, userId) {
2576
2683
  const db = c.get("config").db;
2577
2684
  if (!db) return Promise.resolve(null);
@@ -2706,6 +2813,12 @@ var AuthController = class {
2706
2813
  401
2707
2814
  );
2708
2815
  }
2816
+ if (user.status === "pending") {
2817
+ return c.json(
2818
+ { error: true, message: "This invitation has not been accepted yet." },
2819
+ 403
2820
+ );
2821
+ }
2709
2822
  const lockedUntilMs = getLockedUntilMs(user.lockedUntil);
2710
2823
  if (lockedUntilMs !== null && lockedUntilMs > Date.now()) {
2711
2824
  const retryAfterSeconds = Math.max(
@@ -2970,6 +3083,7 @@ var AuthController = class {
2970
3083
  // ---------------------------------------------------------------------------
2971
3084
  // POST /invite
2972
3085
  // Requires auth. Issues a signed invite token and emails it to the invitee.
3086
+ // If inviteUrl is provided, the email uses a clickable acceptance URL.
2973
3087
  // ---------------------------------------------------------------------------
2974
3088
  async invite(c) {
2975
3089
  const config = c.get("config");
@@ -2983,17 +3097,32 @@ var AuthController = class {
2983
3097
  if (!body?.email) {
2984
3098
  return c.json({ error: true, message: "email is required." }, 400);
2985
3099
  }
3100
+ const inviteData = body?.data && typeof body.data === "object" && !Array.isArray(body.data) ? body.data : {};
2986
3101
  const existing = await db.find({
2987
3102
  collection: this.collection.slug,
2988
3103
  where: { email: body.email },
2989
3104
  limit: 1
2990
3105
  });
2991
- if (existing.total > 0) {
3106
+ const existingUser = existing.docs[0];
3107
+ const existingIsPending = existingUser?.status === "pending";
3108
+ if (existingUser && !existingIsPending) {
2992
3109
  return c.json(
2993
3110
  { error: true, message: "An account with that email already exists." },
2994
3111
  409
2995
3112
  );
2996
3113
  }
3114
+ if (!existingUser) {
3115
+ await db.create({
3116
+ collection: this.collection.slug,
3117
+ data: await this.buildPendingInviteData(body.email, inviteData)
3118
+ });
3119
+ } else if (Object.keys(inviteData).length > 0) {
3120
+ await db.update({
3121
+ collection: this.collection.slug,
3122
+ id: String(existingUser.id),
3123
+ data: await this.buildPendingInviteData(body.email, inviteData)
3124
+ });
3125
+ }
2997
3126
  const inviteToken = await signCollectionToken(
2998
3127
  {
2999
3128
  sub: body.email,
@@ -3003,10 +3132,13 @@ var AuthController = class {
3003
3132
  },
3004
3133
  "7d"
3005
3134
  );
3135
+ const inviteUrl = body?.inviteUrl;
3136
+ const url = inviteUrl ? `${inviteUrl}${inviteUrl.includes("?") ? "&" : "?"}inviteToken=${encodeURIComponent(inviteToken)}` : void 0;
3006
3137
  try {
3007
3138
  const { subject, html } = buildInviteEmail(config, {
3008
3139
  token: inviteToken,
3009
- invitedByEmail: requestUser.email
3140
+ invitedByEmail: requestUser.email,
3141
+ url
3010
3142
  });
3011
3143
  await sendEmail(config, { to: body.email, subject, html });
3012
3144
  } catch (err) {
@@ -3016,7 +3148,12 @@ var AuthController = class {
3016
3148
  email: body.email
3017
3149
  });
3018
3150
  }
3019
- return c.json({ success: true, message: `Invite sent to ${body.email}.` });
3151
+ return c.json({
3152
+ success: true,
3153
+ message: `Invite sent to ${body.email}.`,
3154
+ token: inviteToken,
3155
+ inviteUrl: url
3156
+ });
3020
3157
  }
3021
3158
  // ---------------------------------------------------------------------------
3022
3159
  // POST /accept-invite
@@ -3055,7 +3192,9 @@ var AuthController = class {
3055
3192
  where: { email: inviteeEmail },
3056
3193
  limit: 1
3057
3194
  });
3058
- if (existing.total > 0) {
3195
+ const existingUser = existing.docs[0];
3196
+ const existingIsPending = existingUser?.status === "pending";
3197
+ if (existingUser && !existingIsPending) {
3059
3198
  return c.json(
3060
3199
  { error: true, message: "An account with that email already exists." },
3061
3200
  409
@@ -3063,9 +3202,17 @@ var AuthController = class {
3063
3202
  }
3064
3203
  const { token: _t, password: _p, ...extraFields } = body;
3065
3204
  const hashedPassword = await hashPassword(body.password);
3066
- const user = await db.create({
3205
+ const user = existingUser ? await db.update({
3206
+ collection: this.collection.slug,
3207
+ id: String(existingUser.id),
3208
+ data: this.buildAcceptedInviteData(hashedPassword, extraFields)
3209
+ }) : await db.create({
3067
3210
  collection: this.collection.slug,
3068
- data: { ...extraFields, email: inviteeEmail, password: hashedPassword }
3211
+ data: {
3212
+ ...extraFields,
3213
+ email: inviteeEmail,
3214
+ ...this.buildAcceptedInviteData(hashedPassword, {})
3215
+ }
3069
3216
  });
3070
3217
  const sessionToken = await issueAuthSessionToken({
3071
3218
  config,
@@ -3091,7 +3238,7 @@ var AuthController = class {
3091
3238
  };
3092
3239
 
3093
3240
  // src/controllers/admin-auth.controller.ts
3094
- import { randomBytes as randomBytes2 } from "crypto";
3241
+ import { randomBytes as randomBytes3 } from "crypto";
3095
3242
  import { TextEncoder } from "util";
3096
3243
  import {
3097
3244
  SignJWT,
@@ -3305,7 +3452,7 @@ var AdminAuthController = class {
3305
3452
  access.roles,
3306
3453
  access.data
3307
3454
  ),
3308
- password: await hashPassword(randomBytes2(32).toString("hex"))
3455
+ password: await hashPassword(randomBytes3(32).toString("hex"))
3309
3456
  }
3310
3457
  });
3311
3458
  } else if (user) {
@@ -3391,7 +3538,7 @@ var AdminAuthController = class {
3391
3538
  }
3392
3539
  async buildOidcStartUrl(provider, returnTo, siteId, origin) {
3393
3540
  const discovery = await this.getOidcDiscovery(provider);
3394
- const nonce = randomBytes2(16).toString("hex");
3541
+ const nonce = randomBytes3(16).toString("hex");
3395
3542
  const state = await this.signState({
3396
3543
  providerId: provider.id,
3397
3544
  returnTo,
@@ -3994,6 +4141,7 @@ function getSwaggerHtml(specUrl) {
3994
4141
  }
3995
4142
 
3996
4143
  // src/router.ts
4144
+ var SERIALIZED_ADMIN_HOOK_PREFIX = "__dyrected_fn__:";
3997
4145
  function accessGate(config, target, action) {
3998
4146
  return async (c, next) => {
3999
4147
  const user = c.get("user");
@@ -4020,7 +4168,7 @@ function serializeFieldForApi(f) {
4020
4168
  if (serialized.admin?.hooks) {
4021
4169
  const hooks = { ...serialized.admin.hooks };
4022
4170
  if (typeof hooks.onChange === "function") {
4023
- hooks.onChange = hooks.onChange.toString();
4171
+ hooks.onChange = `${SERIALIZED_ADMIN_HOOK_PREFIX}${hooks.onChange.toString()}`;
4024
4172
  }
4025
4173
  if (typeof hooks.options === "function") {
4026
4174
  hooks.options = hooks.options.toString();
@@ -4054,6 +4202,10 @@ function registerRoutes(app, config) {
4054
4202
  app.get("/api/schemas", optionalAuth(config), async (c) => {
4055
4203
  const siteId = c.req.header("X-Site-Id");
4056
4204
  const requestConfig = siteId && config.onSchemaFetch ? mergeDynamicConfig(config, await config.onSchemaFetch(siteId)) : config;
4205
+ assertValidDeclarativeHooksInConfig(requestConfig, "/api/schemas");
4206
+ assertValidDeclarativeAccessInConfig(requestConfig, "/api/schemas");
4207
+ assertValidAdminConditionsInConfig(requestConfig, "/api/schemas");
4208
+ assertValidPreviewUrlsInConfig(requestConfig, "/api/schemas");
4057
4209
  const collections = [...requestConfig.collections];
4058
4210
  const globals = [...requestConfig.globals];
4059
4211
  const user = c.get("user");
@@ -4168,7 +4320,18 @@ function registerRoutes(app, config) {
4168
4320
  globals: filteredGlobals,
4169
4321
  admin: requestConfig.admin || {},
4170
4322
  adminAuth: getPublicAdminAuthConfig(requestConfig.adminAuth, collections),
4171
- hasStorage: !!requestConfig.storage
4323
+ hasStorage: !!requestConfig.storage,
4324
+ configDiagnostics: collectConfigDiagnostics(requestConfig),
4325
+ adminHealth: {
4326
+ emailConfigured: !!requestConfig.email,
4327
+ secureAuthSecretConfigured: !!process.env.DYRECTED_JWT_SECRET,
4328
+ authCollectionConfigured: requestConfig.collections.some(
4329
+ (collection) => !!collection.auth
4330
+ ),
4331
+ uploadCollectionConfigured: requestConfig.collections.some(
4332
+ (collection) => !!collection.upload
4333
+ )
4334
+ }
4172
4335
  });
4173
4336
  });
4174
4337
  app.get(
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,kCAAkC,CAAC;AACjD,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { DatabaseAdapter, DyrectedConfig } from '../types/index.js';
2
+ export interface AuditLogArgs {
3
+ operation: 'create' | 'update' | 'delete';
4
+ collection: string;
5
+ documentId?: string;
6
+ user?: {
7
+ id: string;
8
+ collection: string;
9
+ email?: string;
10
+ };
11
+ /** Full state before the operation (null for create). */
12
+ before?: any;
13
+ /** Full state after the operation (null for delete). */
14
+ after?: any;
15
+ }
16
+ export declare class AuditService {
17
+ /**
18
+ * Writes a single entry to the __audit collection.
19
+ * Called without await — runs asynchronously and never blocks the primary operation.
20
+ */
21
+ static log(db: DatabaseAdapter, args: AuditLogArgs, config?: DyrectedConfig): Promise<void>;
22
+ }
23
+ //# sourceMappingURL=audit.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.service.d.ts","sourceRoot":"","sources":["../../src/services/audit.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGzE,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,yDAAyD;IACzD,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,wDAAwD;IACxD,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAED,qBAAa,YAAY;IACvB;;;OAGG;WACU,GAAG,CACd,EAAE,EAAE,eAAe,EACnB,IAAI,EAAE,YAAY,EAClB,MAAM,CAAC,EAAE,cAAc,GACtB,OAAO,CAAC,IAAI,CAAC;CA8BjB"}
@@ -0,0 +1,39 @@
1
+ import { getConfigLogger, getObservabilityRuntime } from '../observability.js';
2
+ export class AuditService {
3
+ /**
4
+ * Writes a single entry to the __audit collection.
5
+ * Called without await — runs asynchronously and never blocks the primary operation.
6
+ */
7
+ static async log(db, args, config) {
8
+ try {
9
+ await db.create({
10
+ collection: '__audit',
11
+ data: {
12
+ collection: args.collection,
13
+ documentId: args.documentId ?? null,
14
+ operation: args.operation,
15
+ user: args.user?.id ?? null,
16
+ timestamp: new Date().toISOString(),
17
+ changes: JSON.stringify({
18
+ before: args.before ?? null,
19
+ after: args.after ?? null,
20
+ }),
21
+ },
22
+ });
23
+ }
24
+ catch (err) {
25
+ getObservabilityRuntime(config)?.recordAuditWriteFailure({
26
+ collection: args.collection,
27
+ operation: args.operation,
28
+ });
29
+ getConfigLogger(config, 'audit').error({
30
+ err,
31
+ msg: 'Failed to write audit log',
32
+ collection: args.collection,
33
+ operation: args.operation,
34
+ documentId: args.documentId,
35
+ });
36
+ }
37
+ }
38
+ }
39
+ //# sourceMappingURL=audit.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.service.js","sourceRoot":"","sources":["../../src/services/audit.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAa/E,MAAM,OAAO,YAAY;IACvB;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,GAAG,CACd,EAAmB,EACnB,IAAkB,EAClB,MAAuB;QAEvB,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC;gBACd,UAAU,EAAE,SAAS;gBACrB,IAAI,EAAE;oBACJ,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI;oBACnC,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,IAAI;oBAC3B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACnC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC;wBACtB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI;wBAC3B,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI;qBAC1B,CAAC;iBACH;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,uBAAuB,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC;gBACvD,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,CAAC,CAAC;YACH,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC;gBACrC,GAAG;gBACH,GAAG,EAAE,2BAA2B;gBAChC,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,UAAU,EAAE,IAAI,CAAC,UAAU;aAC5B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import type { Field } from '../types/index.js';
2
+ export declare class DefaultsService {
3
+ /**
4
+ * Recursively apply default values to a data object based on field definitions.
5
+ */
6
+ static apply(fields: Field[], data?: any): any;
7
+ }
8
+ //# sourceMappingURL=defaults.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.service.d.ts","sourceRoot":"","sources":["../../src/services/defaults.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,qBAAa,eAAe;IAC1B;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,GAAE,GAAQ,GAAG,GAAG;CA6CnD"}