@nextsparkjs/core 0.1.0-beta.193 → 0.1.0-beta.195

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 (374) hide show
  1. package/README.md +2 -2
  2. package/dist/components/app/guards/DeveloperGuard.d.ts +8 -1
  3. package/dist/components/app/guards/DeveloperGuard.d.ts.map +1 -1
  4. package/dist/components/app/guards/DeveloperGuard.js +2 -1
  5. package/dist/components/app/guards/SuperAdminGuard.d.ts +8 -1
  6. package/dist/components/app/guards/SuperAdminGuard.d.ts.map +1 -1
  7. package/dist/components/app/guards/SuperAdminGuard.js +2 -1
  8. package/dist/components/dashboard/block-editor/block-picker.d.ts.map +1 -1
  9. package/dist/components/dashboard/block-editor/block-picker.js +2 -1
  10. package/dist/components/dashboard/block-editor/builder-editor-view.d.ts.map +1 -1
  11. package/dist/components/dashboard/block-editor/builder-editor-view.js +39 -23
  12. package/dist/components/dashboard/block-editor/pattern-reference-preview.d.ts.map +1 -1
  13. package/dist/components/dashboard/block-editor/pattern-reference-preview.js +2 -1
  14. package/dist/components/dashboard/layouts/AuthGuard.d.ts.map +1 -1
  15. package/dist/components/dashboard/layouts/AuthGuard.js +3 -4
  16. package/dist/components/dashboard/layouts/AuthenticatedDashboardLayout.d.ts.map +1 -1
  17. package/dist/components/dashboard/layouts/AuthenticatedDashboardLayout.js +9 -10
  18. package/dist/components/dashboard/layouts/DashboardAuthLayout.d.ts.map +1 -1
  19. package/dist/components/dashboard/layouts/DashboardAuthLayout.js +3 -4
  20. package/dist/components/dashboard/layouts/DashboardAuthSkeleton.d.ts +2 -2
  21. package/dist/components/entities/wrappers/EntityDetailWrapper.d.ts.map +1 -1
  22. package/dist/components/entities/wrappers/EntityDetailWrapper.js +5 -2
  23. package/dist/components/entities/wrappers/EntityFormWrapper.d.ts.map +1 -1
  24. package/dist/components/entities/wrappers/EntityFormWrapper.js +5 -2
  25. package/dist/components/entities/wrappers/EntityListWrapper.d.ts.map +1 -1
  26. package/dist/components/entities/wrappers/EntityListWrapper.js +5 -2
  27. package/dist/components/ui/relation-display.d.ts.map +1 -1
  28. package/dist/components/ui/relation-display.js +2 -1
  29. package/dist/components/ui/user-display.d.ts.map +1 -1
  30. package/dist/components/ui/user-display.js +2 -1
  31. package/dist/emails/otp-verification.d.ts.map +1 -1
  32. package/dist/emails/otp-verification.js +5 -3
  33. package/dist/emails/reset-password.d.ts.map +1 -1
  34. package/dist/emails/reset-password.js +5 -3
  35. package/dist/emails/team-invitation.d.ts.map +1 -1
  36. package/dist/emails/team-invitation.js +3 -2
  37. package/dist/emails/verify-email.d.ts.map +1 -1
  38. package/dist/emails/verify-email.js +5 -3
  39. package/dist/hooks/useAuth.d.ts.map +1 -1
  40. package/dist/hooks/useAuth.js +21 -4
  41. package/dist/hooks/usePatternUsages.d.ts.map +1 -1
  42. package/dist/hooks/usePatternUsages.js +3 -2
  43. package/dist/lib/api/auth/permissions.d.ts +10 -0
  44. package/dist/lib/api/auth/permissions.d.ts.map +1 -1
  45. package/dist/lib/api/auth/permissions.js +7 -0
  46. package/dist/lib/api/auth.d.ts +2 -0
  47. package/dist/lib/api/auth.d.ts.map +1 -1
  48. package/dist/lib/api/auth.js +10 -10
  49. package/dist/lib/api/client-headers.d.ts +11 -0
  50. package/dist/lib/api/client-headers.d.ts.map +1 -0
  51. package/dist/lib/api/client-headers.js +12 -0
  52. package/dist/lib/api/client-ip.d.ts +59 -0
  53. package/dist/lib/api/client-ip.d.ts.map +1 -0
  54. package/dist/lib/api/client-ip.js +91 -0
  55. package/dist/lib/api/cors-response.d.ts +54 -0
  56. package/dist/lib/api/cors-response.d.ts.map +1 -0
  57. package/dist/lib/api/cors-response.js +88 -0
  58. package/dist/lib/api/entities.d.ts.map +1 -1
  59. package/dist/lib/api/entities.js +4 -3
  60. package/dist/lib/api/entity/audit-log.d.ts.map +1 -1
  61. package/dist/lib/api/entity/audit-log.js +2 -1
  62. package/dist/lib/api/entity/generic-handler.d.ts.map +1 -1
  63. package/dist/lib/api/entity/generic-handler.js +23 -5
  64. package/dist/lib/api/helpers.d.ts +8 -2
  65. package/dist/lib/api/helpers.d.ts.map +1 -1
  66. package/dist/lib/api/helpers.js +27 -81
  67. package/dist/lib/api/keys.d.ts +6 -0
  68. package/dist/lib/api/keys.d.ts.map +1 -1
  69. package/dist/lib/api/keys.js +7 -1
  70. package/dist/lib/api/rate-limit.d.ts +4 -0
  71. package/dist/lib/api/rate-limit.d.ts.map +1 -1
  72. package/dist/lib/api/rate-limit.js +17 -38
  73. package/dist/lib/api/request-origin.d.ts +35 -0
  74. package/dist/lib/api/request-origin.d.ts.map +1 -0
  75. package/dist/lib/api/request-origin.js +69 -0
  76. package/dist/lib/auth/load-login-page.d.ts +10 -0
  77. package/dist/lib/auth/load-login-page.d.ts.map +1 -0
  78. package/dist/lib/auth/load-login-page.js +7 -0
  79. package/dist/lib/auth/runtime-readiness.d.ts.map +1 -1
  80. package/dist/lib/auth/runtime-readiness.js +2 -0
  81. package/dist/lib/auth/security-notifications/device-fingerprint.d.ts +1 -8
  82. package/dist/lib/auth/security-notifications/device-fingerprint.d.ts.map +1 -1
  83. package/dist/lib/auth/security-notifications/device-fingerprint.js +2 -12
  84. package/dist/lib/auth-email-callbacks.js +3 -3
  85. package/dist/lib/auth.d.ts.map +1 -1
  86. package/dist/lib/auth.js +15 -14
  87. package/dist/lib/config/config-client.d.ts.map +1 -1
  88. package/dist/lib/config/config-client.js +1 -1
  89. package/dist/lib/config/config-sync.d.ts.map +1 -1
  90. package/dist/lib/config/config-sync.js +1 -1
  91. package/dist/lib/config/public-config-client.d.ts +1 -0
  92. package/dist/lib/config/public-config-client.d.ts.map +1 -1
  93. package/dist/lib/config/public-config-client.js +3 -1
  94. package/dist/lib/config/types.d.ts +2 -0
  95. package/dist/lib/config/types.d.ts.map +1 -1
  96. package/dist/lib/constants/reserved-slugs.d.ts +17 -8
  97. package/dist/lib/constants/reserved-slugs.d.ts.map +1 -1
  98. package/dist/lib/constants/reserved-slugs.js +16 -52
  99. package/dist/lib/db.d.ts.map +1 -1
  100. package/dist/lib/db.js +9 -3
  101. package/dist/lib/entities/external-api-generator.d.ts.map +1 -1
  102. package/dist/lib/entities/external-api-generator.js +5 -5
  103. package/dist/lib/entities/public-slug.d.ts +46 -0
  104. package/dist/lib/entities/public-slug.d.ts.map +1 -0
  105. package/dist/lib/entities/public-slug.js +39 -0
  106. package/dist/lib/services/subscription.service.d.ts.map +1 -1
  107. package/dist/lib/services/subscription.service.js +3 -0
  108. package/dist/lib/utils/cors.d.ts +7 -0
  109. package/dist/lib/utils/cors.d.ts.map +1 -1
  110. package/dist/lib/utils/cors.js +8 -0
  111. package/dist/routes/(auth)/signup/page.cc.d.ts +3 -8
  112. package/dist/routes/(auth)/signup/page.cc.d.ts.map +1 -1
  113. package/dist/routes/(auth)/signup/page.cc.js +7 -1
  114. package/dist/routes/(auth)/verify-email/page.d.ts.map +1 -1
  115. package/dist/routes/(auth)/verify-email/page.js +2 -1
  116. package/dist/routes/(public)/page.cc.d.ts +3 -0
  117. package/dist/routes/(public)/page.cc.d.ts.map +1 -0
  118. package/dist/routes/(public)/page.cc.js +3 -0
  119. package/dist/routes/_internal/area-access.cc.d.ts +21 -0
  120. package/dist/routes/_internal/area-access.cc.d.ts.map +1 -0
  121. package/dist/routes/_internal/area-access.cc.js +19 -0
  122. package/dist/routes/_internal/auth-layout.d.ts.map +1 -1
  123. package/dist/routes/_internal/auth-layout.js +3 -2
  124. package/dist/routes/_internal/dashboard-main-shared.d.ts +7 -0
  125. package/dist/routes/_internal/dashboard-main-shared.d.ts.map +1 -0
  126. package/dist/routes/_internal/dashboard-main-shared.js +49 -0
  127. package/dist/routes/_internal/default-auth-layout.d.ts.map +1 -1
  128. package/dist/routes/_internal/default-auth-layout.js +3 -2
  129. package/dist/routes/_internal/devtools-layout.cc.d.ts +3 -2
  130. package/dist/routes/_internal/devtools-layout.cc.d.ts.map +1 -1
  131. package/dist/routes/_internal/devtools-layout.cc.js +1 -1
  132. package/dist/routes/_internal/devtools-layout.d.ts +7 -2
  133. package/dist/routes/_internal/devtools-layout.d.ts.map +1 -1
  134. package/dist/routes/_internal/devtools-layout.js +4 -4
  135. package/dist/routes/_internal/entity-detail-route.cc.d.ts +8 -0
  136. package/dist/routes/_internal/entity-detail-route.cc.d.ts.map +1 -0
  137. package/dist/routes/_internal/entity-detail-route.cc.js +5 -0
  138. package/dist/routes/_internal/entity-edit-route.cc.d.ts +8 -0
  139. package/dist/routes/_internal/entity-edit-route.cc.d.ts.map +1 -0
  140. package/dist/routes/_internal/entity-edit-route.cc.js +5 -0
  141. package/dist/routes/_internal/public-archive-route.d.ts +1 -1
  142. package/dist/routes/_internal/public-archive-route.d.ts.map +1 -1
  143. package/dist/routes/_internal/public-archive-route.js +8 -3
  144. package/dist/routes/_internal/public-item-route.cc.d.ts +5 -1
  145. package/dist/routes/_internal/public-item-route.cc.d.ts.map +1 -1
  146. package/dist/routes/_internal/public-item-route.cc.js +2 -1
  147. package/dist/routes/_internal/public-item-route.d.ts +7 -0
  148. package/dist/routes/_internal/public-item-route.d.ts.map +1 -1
  149. package/dist/routes/_internal/public-item-route.js +6 -1
  150. package/dist/routes/_internal/superadmin-layout.cc.d.ts +2 -1
  151. package/dist/routes/_internal/superadmin-layout.cc.d.ts.map +1 -1
  152. package/dist/routes/_internal/superadmin-layout.cc.js +1 -1
  153. package/dist/routes/_internal/superadmin-layout.d.ts +7 -2
  154. package/dist/routes/_internal/superadmin-layout.d.ts.map +1 -1
  155. package/dist/routes/_internal/superadmin-layout.js +6 -6
  156. package/dist/routes/_internal/suspended-route.d.ts +16 -0
  157. package/dist/routes/_internal/suspended-route.d.ts.map +1 -0
  158. package/dist/routes/_internal/suspended-route.js +7 -0
  159. package/dist/routes/api/auth/[...all]/route.d.ts.map +1 -1
  160. package/dist/routes/api/auth/[...all]/route.js +4 -12
  161. package/dist/routes/api/csp-report/route.d.ts.map +1 -1
  162. package/dist/routes/api/csp-report/route.js +2 -13
  163. package/dist/routes/api/devtools/config/entities/route.d.ts +2 -0
  164. package/dist/routes/api/devtools/config/entities/route.d.ts.map +1 -1
  165. package/dist/routes/api/devtools/config/entities/route.js +2 -0
  166. package/dist/routes/api/devtools/config/theme/route.d.ts +2 -0
  167. package/dist/routes/api/devtools/config/theme/route.d.ts.map +1 -1
  168. package/dist/routes/api/devtools/config/theme/route.js +2 -0
  169. package/dist/routes/api/devtools/tests/[...path]/route.d.ts +2 -0
  170. package/dist/routes/api/devtools/tests/[...path]/route.d.ts.map +1 -1
  171. package/dist/routes/api/devtools/tests/[...path]/route.js +2 -0
  172. package/dist/routes/api/devtools/tests/route.d.ts +2 -0
  173. package/dist/routes/api/devtools/tests/route.d.ts.map +1 -1
  174. package/dist/routes/api/devtools/tests/route.js +2 -0
  175. package/dist/routes/api/health/route.d.ts +2 -0
  176. package/dist/routes/api/health/route.d.ts.map +1 -1
  177. package/dist/routes/api/health/route.js +2 -0
  178. package/dist/routes/api/internal/user-metadata/route.d.ts +2 -0
  179. package/dist/routes/api/internal/user-metadata/route.d.ts.map +1 -1
  180. package/dist/routes/api/internal/user-metadata/route.js +2 -0
  181. package/dist/routes/api/mcp/route.d.ts +2 -0
  182. package/dist/routes/api/mcp/route.d.ts.map +1 -1
  183. package/dist/routes/api/mcp/route.js +2 -0
  184. package/dist/routes/api/superadmin/subscriptions/route.d.ts +2 -0
  185. package/dist/routes/api/superadmin/subscriptions/route.d.ts.map +1 -1
  186. package/dist/routes/api/superadmin/subscriptions/route.js +2 -0
  187. package/dist/routes/api/superadmin/teams/[teamId]/route.d.ts +2 -0
  188. package/dist/routes/api/superadmin/teams/[teamId]/route.d.ts.map +1 -1
  189. package/dist/routes/api/superadmin/teams/[teamId]/route.js +2 -0
  190. package/dist/routes/api/superadmin/teams/route.d.ts +2 -0
  191. package/dist/routes/api/superadmin/teams/route.d.ts.map +1 -1
  192. package/dist/routes/api/superadmin/teams/route.js +2 -0
  193. package/dist/routes/api/superadmin/users/[userId]/route.d.ts +2 -0
  194. package/dist/routes/api/superadmin/users/[userId]/route.d.ts.map +1 -1
  195. package/dist/routes/api/superadmin/users/[userId]/route.js +2 -0
  196. package/dist/routes/api/superadmin/users/route.d.ts +2 -0
  197. package/dist/routes/api/superadmin/users/route.d.ts.map +1 -1
  198. package/dist/routes/api/superadmin/users/route.js +2 -0
  199. package/dist/routes/api/user/delete-account/route.d.ts +2 -0
  200. package/dist/routes/api/user/delete-account/route.d.ts.map +1 -1
  201. package/dist/routes/api/user/delete-account/route.js +2 -0
  202. package/dist/routes/api/user/plan-flags/route.d.ts +2 -0
  203. package/dist/routes/api/user/plan-flags/route.d.ts.map +1 -1
  204. package/dist/routes/api/user/plan-flags/route.js +2 -0
  205. package/dist/routes/api/user/profile/route.d.ts +2 -0
  206. package/dist/routes/api/user/profile/route.d.ts.map +1 -1
  207. package/dist/routes/api/user/profile/route.js +4 -3
  208. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/[childId]/route.d.ts +2 -0
  209. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/[childId]/route.d.ts.map +1 -1
  210. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/[childId]/route.js +2 -0
  211. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/route.d.ts +2 -0
  212. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/route.d.ts.map +1 -1
  213. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/route.js +2 -0
  214. package/dist/routes/api/v1/billing/cancel/route.d.ts +2 -0
  215. package/dist/routes/api/v1/billing/cancel/route.d.ts.map +1 -1
  216. package/dist/routes/api/v1/billing/cancel/route.js +2 -0
  217. package/dist/routes/api/v1/billing/change-plan/route.d.ts +2 -0
  218. package/dist/routes/api/v1/billing/change-plan/route.d.ts.map +1 -1
  219. package/dist/routes/api/v1/billing/change-plan/route.js +2 -0
  220. package/dist/routes/api/v1/billing/check-action/route.d.ts +2 -0
  221. package/dist/routes/api/v1/billing/check-action/route.d.ts.map +1 -1
  222. package/dist/routes/api/v1/billing/check-action/route.js +2 -0
  223. package/dist/routes/api/v1/billing/checkout/route.d.ts +2 -0
  224. package/dist/routes/api/v1/billing/checkout/route.d.ts.map +1 -1
  225. package/dist/routes/api/v1/billing/checkout/route.js +2 -0
  226. package/dist/routes/api/v1/billing/plans/route.d.ts +2 -0
  227. package/dist/routes/api/v1/billing/plans/route.d.ts.map +1 -1
  228. package/dist/routes/api/v1/billing/plans/route.js +2 -0
  229. package/dist/routes/api/v1/billing/portal/route.d.ts +2 -0
  230. package/dist/routes/api/v1/billing/portal/route.d.ts.map +1 -1
  231. package/dist/routes/api/v1/billing/portal/route.js +2 -0
  232. package/dist/routes/api/v1/blocks/[slug]/route.d.ts +2 -0
  233. package/dist/routes/api/v1/blocks/[slug]/route.d.ts.map +1 -1
  234. package/dist/routes/api/v1/blocks/[slug]/route.js +2 -0
  235. package/dist/routes/api/v1/blocks/route.d.ts +2 -0
  236. package/dist/routes/api/v1/blocks/route.d.ts.map +1 -1
  237. package/dist/routes/api/v1/blocks/route.js +2 -0
  238. package/dist/routes/api/v1/blocks/validate/route.d.ts +2 -0
  239. package/dist/routes/api/v1/blocks/validate/route.d.ts.map +1 -1
  240. package/dist/routes/api/v1/blocks/validate/route.js +2 -0
  241. package/dist/routes/api/v1/devtools/blocks/route.d.ts +2 -1
  242. package/dist/routes/api/v1/devtools/blocks/route.d.ts.map +1 -1
  243. package/dist/routes/api/v1/devtools/blocks/route.js +2 -9
  244. package/dist/routes/api/v1/devtools/docs/route.d.ts +2 -0
  245. package/dist/routes/api/v1/devtools/docs/route.d.ts.map +1 -1
  246. package/dist/routes/api/v1/devtools/docs/route.js +2 -0
  247. package/dist/routes/api/v1/devtools/features/route.d.ts +2 -1
  248. package/dist/routes/api/v1/devtools/features/route.d.ts.map +1 -1
  249. package/dist/routes/api/v1/devtools/features/route.js +2 -9
  250. package/dist/routes/api/v1/devtools/flows/route.d.ts +2 -1
  251. package/dist/routes/api/v1/devtools/flows/route.d.ts.map +1 -1
  252. package/dist/routes/api/v1/devtools/flows/route.js +2 -9
  253. package/dist/routes/api/v1/devtools/scheduled-actions/route.d.ts +2 -1
  254. package/dist/routes/api/v1/devtools/scheduled-actions/route.d.ts.map +1 -1
  255. package/dist/routes/api/v1/devtools/scheduled-actions/route.js +2 -9
  256. package/dist/routes/api/v1/devtools/scheduled-actions/run/route.d.ts +2 -1
  257. package/dist/routes/api/v1/devtools/scheduled-actions/run/route.d.ts.map +1 -1
  258. package/dist/routes/api/v1/devtools/scheduled-actions/run/route.js +2 -9
  259. package/dist/routes/api/v1/devtools/testing/route.d.ts +2 -1
  260. package/dist/routes/api/v1/devtools/testing/route.d.ts.map +1 -1
  261. package/dist/routes/api/v1/devtools/testing/route.js +2 -9
  262. package/dist/routes/api/v1/media/[id]/route.d.ts +2 -0
  263. package/dist/routes/api/v1/media/[id]/route.d.ts.map +1 -1
  264. package/dist/routes/api/v1/media/[id]/route.js +2 -0
  265. package/dist/routes/api/v1/media/[id]/tags/route.d.ts +2 -0
  266. package/dist/routes/api/v1/media/[id]/tags/route.d.ts.map +1 -1
  267. package/dist/routes/api/v1/media/[id]/tags/route.js +2 -0
  268. package/dist/routes/api/v1/media/check-duplicates/route.d.ts +2 -0
  269. package/dist/routes/api/v1/media/check-duplicates/route.d.ts.map +1 -1
  270. package/dist/routes/api/v1/media/check-duplicates/route.js +2 -0
  271. package/dist/routes/api/v1/media/route.d.ts +2 -0
  272. package/dist/routes/api/v1/media/route.d.ts.map +1 -1
  273. package/dist/routes/api/v1/media/route.js +2 -0
  274. package/dist/routes/api/v1/media/upload/route.d.ts +2 -0
  275. package/dist/routes/api/v1/media/upload/route.d.ts.map +1 -1
  276. package/dist/routes/api/v1/media/upload/route.js +2 -0
  277. package/dist/routes/api/v1/media-tags/route.d.ts +2 -0
  278. package/dist/routes/api/v1/media-tags/route.d.ts.map +1 -1
  279. package/dist/routes/api/v1/media-tags/route.js +2 -0
  280. package/dist/routes/api/v1/post-categories/[id]/route.d.ts +2 -0
  281. package/dist/routes/api/v1/post-categories/[id]/route.d.ts.map +1 -1
  282. package/dist/routes/api/v1/post-categories/[id]/route.js +2 -0
  283. package/dist/routes/api/v1/post-categories/route.d.ts +2 -0
  284. package/dist/routes/api/v1/post-categories/route.d.ts.map +1 -1
  285. package/dist/routes/api/v1/post-categories/route.js +2 -0
  286. package/dist/routes/api/v1/teams/[teamId]/members/route.js +2 -2
  287. package/dist/routes/api/v1/teams/[teamId]/subscription/route.d.ts +2 -0
  288. package/dist/routes/api/v1/teams/[teamId]/subscription/route.d.ts.map +1 -1
  289. package/dist/routes/api/v1/teams/[teamId]/subscription/route.js +2 -0
  290. package/dist/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.d.ts +2 -0
  291. package/dist/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.d.ts.map +1 -1
  292. package/dist/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.js +2 -0
  293. package/dist/routes/api/v1/users/[id]/meta/[key]/route.d.ts.map +1 -1
  294. package/dist/routes/api/v1/users/[id]/meta/[key]/route.js +13 -0
  295. package/dist/routes/api/v1/users/[id]/route.d.ts.map +1 -1
  296. package/dist/routes/api/v1/users/[id]/route.js +20 -2
  297. package/dist/routes/api/v1/users/docs.md +34 -19
  298. package/dist/routes/api/v1/users/me/route.d.ts +6 -0
  299. package/dist/routes/api/v1/users/me/route.d.ts.map +1 -0
  300. package/dist/routes/api/v1/users/me/route.js +5 -0
  301. package/dist/routes/api/v1/users/presets.ts +2 -2
  302. package/dist/routes/dashboard/(main)/layout.cc.d.ts +4 -0
  303. package/dist/routes/dashboard/(main)/layout.cc.d.ts.map +1 -0
  304. package/dist/routes/dashboard/(main)/layout.cc.js +10 -0
  305. package/dist/routes/dashboard/(main)/layout.d.ts.map +1 -1
  306. package/dist/routes/dashboard/(main)/layout.js +3 -44
  307. package/dist/routes/dashboard/permission-denied/page.d.ts +1 -1
  308. package/dist/routes/dashboard/permission-denied/page.d.ts.map +1 -1
  309. package/dist/routes/dashboard/permission-denied/page.js +5 -1
  310. package/dist/routes/devtools/layout.cc.d.ts.map +1 -1
  311. package/dist/routes/devtools/layout.cc.js +5 -1
  312. package/dist/routes/manifest.json +10 -0
  313. package/dist/routes/robots.d.ts +10 -0
  314. package/dist/routes/robots.d.ts.map +1 -0
  315. package/dist/routes/robots.js +10 -0
  316. package/dist/routes/superadmin/layout.cc.d.ts.map +1 -1
  317. package/dist/routes/superadmin/layout.cc.js +5 -1
  318. package/dist/routes/variants.json +12 -2
  319. package/dist/templates/next.config.mjs +2 -29
  320. package/dist/templates/projects/blog/api/authors/[username]/route.ts +3 -0
  321. package/dist/templates/projects/blog/api/authors/route.ts +3 -0
  322. package/dist/templates/projects/blog/api/posts/public/route.ts +3 -0
  323. package/dist/templates/projects/blog/package.json +3 -3
  324. package/dist/templates/projects/crm/package.json +3 -3
  325. package/dist/templates/projects/productivity/package.json +3 -3
  326. package/dist/templates/proxy.ts +12 -1
  327. package/dist/templates/public/favicon.ico +0 -0
  328. package/package.json +8 -5
  329. package/scripts/build/auth-readiness.mjs +4 -0
  330. package/scripts/build/registry/__tests__/api-docs-colocated.test.mjs +3 -0
  331. package/scripts/build/registry/__tests__/billing-registry.test.mjs +50 -1
  332. package/scripts/build/registry/__tests__/block-registry.test.mjs +3 -0
  333. package/scripts/build/registry/__tests__/build-output.test.mjs +1 -1
  334. package/scripts/build/registry/__tests__/icons-discovery.test.mjs +3 -0
  335. package/scripts/build/registry/__tests__/project-mode-root-first.test.mjs +6 -6
  336. package/scripts/build/registry/__tests__/quiet-console.mjs +17 -0
  337. package/scripts/build/registry/__tests__/safe-fs.test.mjs +3 -0
  338. package/scripts/build/registry/__tests__/team-roles.test.mjs +3 -0
  339. package/scripts/build/registry/__tests__/write-places.test.mjs +1 -1
  340. package/scripts/build/registry/contracts/__tests__/contracts-wire.test.mjs +1 -1
  341. package/scripts/build/registry/contracts/__tests__/contracts.test.mjs +1 -1
  342. package/scripts/build/registry/contracts/render.mjs +3 -3
  343. package/scripts/build/registry/discovery/permissions.test.mjs +3 -0
  344. package/scripts/build/registry/discovery/plugin-capabilities.mjs +2 -2
  345. package/scripts/build/registry/generators/billing-registry.mjs +7 -3
  346. package/scripts/build/registry/host/README.md +27 -3
  347. package/scripts/build/registry/host/__tests__/facade-emitter.test.mjs +9 -9
  348. package/scripts/build/registry/host/__tests__/host-area-access.test.mjs +32 -0
  349. package/scripts/build/registry/host/__tests__/host-entities.test.mjs +32 -1
  350. package/scripts/build/registry/host/__tests__/host-mode.test.mjs +1 -1
  351. package/scripts/build/registry/host/__tests__/host-plan.test.mjs +12 -2
  352. package/scripts/build/registry/host/__tests__/host-project-composition.test.mjs +1 -1
  353. package/scripts/build/registry/host/__tests__/host-project.test.mjs +2 -2
  354. package/scripts/build/registry/host/__tests__/host-robustness.test.mjs +65 -2
  355. package/scripts/build/registry/host/entity-routes.mjs +9 -3
  356. package/scripts/build/registry/host/facade-emitter.mjs +2 -2
  357. package/scripts/build/registry/host/generation.mjs +54 -0
  358. package/scripts/build/registry/host/next-route-exports.json +2 -2
  359. package/scripts/build/registry/host/prepare.mjs +3 -0
  360. package/scripts/build/registry/host/static-imports.mjs +4 -0
  361. package/scripts/build/routes-manifest.mjs +13 -1
  362. package/scripts/db/migration-time-limit.mjs +216 -34
  363. package/scripts/db/run-migrations.mjs +11 -179
  364. package/scripts/db/ssl-config.mjs +12 -1
  365. package/scripts/db/verify-theme-migrations.mjs +1 -1
  366. package/templates/next.config.mjs +2 -29
  367. package/templates/projects/blog/api/authors/[username]/route.ts +3 -0
  368. package/templates/projects/blog/api/authors/route.ts +3 -0
  369. package/templates/projects/blog/api/posts/public/route.ts +3 -0
  370. package/templates/projects/blog/package.json +3 -3
  371. package/templates/projects/crm/package.json +3 -3
  372. package/templates/projects/productivity/package.json +3 -3
  373. package/templates/proxy.ts +12 -1
  374. package/templates/public/favicon.ico +0 -0
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Core's CORS answer for /api responses, in one place: addCorsHeaders and wrapAuthHandlerWithCors (helpers.ts)
3
+ * and the common route wrapper (withRateLimitTier) all use it, so every response and preflight a route gives
4
+ * names the same origin, with or without credentials, for the same request.
5
+ */
6
+ import { NextResponse } from 'next/server';
7
+ import type { ApplicationConfig } from '../config/config-types';
8
+ type CorsConfig = Pick<ApplicationConfig, 'api'>;
9
+ export declare const CORS_ALLOW_METHODS = "GET, POST, PUT, PATCH, DELETE, OPTIONS";
10
+ export declare const CORS_ALLOW_HEADERS: string;
11
+ /**
12
+ * True for a path under the admin or developer areas, which answer CORS only to the app's own origin and accept
13
+ * cookie-authenticated writes only from it (checkRequestOrigin).
14
+ */
15
+ export declare function isAppOnlyCorsPath(pathname: string): boolean;
16
+ /** A request's path, for corsGrant (undefined when its URL does not parse). */
17
+ export declare function requestPathname(request: Request): string | undefined;
18
+ /** The app's own origins: NEXT_PUBLIC_APP_URL and BETTER_AUTH_URL. */
19
+ export declare function appOrigins(): string[];
20
+ /**
21
+ * Which origin a CORS response may name, and whether credentials go with it.
22
+ * A listed origin (getCorsOrigins, wildcard entries allowed) is echoed with
23
+ * credentials. In development with allowAllOrigins.development, any other
24
+ * origin is echoed too, but with credentials only when the cookie-write origin
25
+ * check trusts it (getTrustedOrigins). Any other origin gets no grant: the
26
+ * response names no origin and sends no credentials header.
27
+ * Under the admin and developer areas (isAppOnlyCorsPath, given the request's
28
+ * `pathname`), only the app's own origin is granted, with credentials; no
29
+ * other origin, listed or not.
30
+ */
31
+ export declare function corsGrant(origin: string, config: CorsConfig, env: string, pathname?: string): {
32
+ origin: string;
33
+ credentials: boolean;
34
+ } | null;
35
+ /** `Vary: Origin` once, however many times CORS is applied to the same response. */
36
+ export declare function varyOnOrigin(headers: Headers): void;
37
+ /** Core's CORS headers for a request's grant (corsGrant; null for none), written onto `headers`. */
38
+ export declare function setCorsHeaders(headers: Headers, grant: {
39
+ origin: string;
40
+ credentials: boolean;
41
+ } | null): void;
42
+ /**
43
+ * `response` with core's CORS for `request`. A response that already names an origin was answered by its
44
+ * route (addCorsHeaders, or a CORS policy of its own) and is returned as it is. A response with read-only
45
+ * headers is copied first.
46
+ */
47
+ export declare function withCors<R extends Response>(response: R, request: Request): R;
48
+ /**
49
+ * A CORS preflight answered with the same grant the route's responses get. Routes export it as their
50
+ * `OPTIONS`: without one, Next.js answers OPTIONS itself, with no CORS headers.
51
+ */
52
+ export declare function corsPreflight(request: Request): NextResponse;
53
+ export {};
54
+ //# sourceMappingURL=cors-response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors-response.d.ts","sourceRoot":"","sources":["../../../src/lib/api/cors-response.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAG/D,KAAK,UAAU,GAAG,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAA;AAEhD,eAAO,MAAM,kBAAkB,2CAA2C,CAAA;AAC1E,eAAO,MAAM,kBAAkB,QAAuF,CAAA;AAKtH;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAI3D;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAEpE;AAED,sEAAsE;AACtE,wBAAgB,UAAU,IAAI,MAAM,EAAE,CAKrC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,MAAM,GAChB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAYjD;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAGnD;AAED,oGAAoG;AACpG,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,GACrD,IAAI,CAWN;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,CAAC,CAa7E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,YAAY,CAE5D"}
@@ -0,0 +1,88 @@
1
+ import { NextResponse } from "next/server";
2
+ import { APP_CONFIG_MERGED } from "../config/index.js";
3
+ import { getCorsOrigins, getTrustedOrigins, isOriginAllowed, normalizeOrigin } from "../utils/cors.js";
4
+ import { CLIENT_REQUEST_HEADERS } from "./client-headers.js";
5
+ const CORS_ALLOW_METHODS = "GET, POST, PUT, PATCH, DELETE, OPTIONS";
6
+ const CORS_ALLOW_HEADERS = ["Content-Type", "Authorization", "X-API-Key", ...CLIENT_REQUEST_HEADERS].join(", ");
7
+ const APP_ONLY_PATH = /(^|\/)api\/(v1\/)?(superadmin|devtools)(\/|$)/;
8
+ function isAppOnlyCorsPath(pathname) {
9
+ let path = pathname;
10
+ try {
11
+ path = decodeURIComponent(pathname);
12
+ } catch {
13
+ }
14
+ return APP_ONLY_PATH.test(path.toLowerCase().replace(/\/{2,}/g, "/"));
15
+ }
16
+ function requestPathname(request) {
17
+ try {
18
+ return new URL(request.url).pathname;
19
+ } catch {
20
+ return void 0;
21
+ }
22
+ }
23
+ function appOrigins() {
24
+ return [process.env.NEXT_PUBLIC_APP_URL, process.env.BETTER_AUTH_URL].flatMap((url) => {
25
+ if (!url) return [];
26
+ try {
27
+ return [new URL(url).origin];
28
+ } catch {
29
+ return [];
30
+ }
31
+ });
32
+ }
33
+ function corsGrant(origin, config, env, pathname) {
34
+ const normalizedOrigin = normalizeOrigin(origin);
35
+ if (pathname !== void 0 && isAppOnlyCorsPath(pathname)) {
36
+ return appOrigins().includes(normalizedOrigin) ? { origin: normalizedOrigin, credentials: true } : null;
37
+ }
38
+ const listed = isOriginAllowed(normalizedOrigin, getCorsOrigins(config, env));
39
+ if (listed) return { origin: listed, credentials: true };
40
+ if (env === "development" && config.api.cors.allowAllOrigins.development) {
41
+ const trusted = isOriginAllowed(normalizedOrigin, getTrustedOrigins(config, normalizedOrigin, env));
42
+ return { origin: normalizedOrigin, credentials: trusted !== null };
43
+ }
44
+ return null;
45
+ }
46
+ function varyOnOrigin(headers) {
47
+ const vary = headers.get("vary") ?? "";
48
+ if (!vary.split(",").some((value) => value.trim().toLowerCase() === "origin")) headers.set("Vary", vary ? `${vary}, Origin` : "Origin");
49
+ }
50
+ function setCorsHeaders(headers, grant) {
51
+ if (grant) {
52
+ headers.set("Access-Control-Allow-Origin", grant.origin);
53
+ if (grant.credentials) headers.set("Access-Control-Allow-Credentials", "true");
54
+ }
55
+ varyOnOrigin(headers);
56
+ headers.set("Access-Control-Allow-Methods", CORS_ALLOW_METHODS);
57
+ headers.set("Access-Control-Allow-Headers", CORS_ALLOW_HEADERS);
58
+ headers.set("Access-Control-Max-Age", "86400");
59
+ }
60
+ function withCors(response, request) {
61
+ if (response.headers.has("access-control-allow-origin")) return response;
62
+ const origin = request.headers.get("origin");
63
+ const env = process.env.NODE_ENV || "development";
64
+ const grant = origin ? corsGrant(origin, APP_CONFIG_MERGED, env, requestPathname(request)) : null;
65
+ try {
66
+ setCorsHeaders(response.headers, grant);
67
+ return response;
68
+ } catch {
69
+ const copy = new Response(response.body, { status: response.status, statusText: response.statusText, headers: new Headers(response.headers) });
70
+ setCorsHeaders(copy.headers, grant);
71
+ return copy;
72
+ }
73
+ }
74
+ function corsPreflight(request) {
75
+ return withCors(new NextResponse(null, { status: 204 }), request);
76
+ }
77
+ export {
78
+ CORS_ALLOW_HEADERS,
79
+ CORS_ALLOW_METHODS,
80
+ appOrigins,
81
+ corsGrant,
82
+ corsPreflight,
83
+ isAppOnlyCorsPath,
84
+ requestPathname,
85
+ setCorsHeaders,
86
+ varyOnOrigin,
87
+ withCors
88
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../../src/lib/api/entities.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../../src/lib/api/entities.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { getClientEntityApiPath, getClientEntityConfigs } from "../entities/client-entity-meta.js";
2
2
  import { withBasePath, withBasePathIfInApp } from "../base-path.js";
3
+ import { BUILDER_SOURCE_HEADER, TEAM_ID_HEADER } from "./client-headers.js";
3
4
  function getApiBaseUrl() {
4
5
  if (typeof window !== "undefined") {
5
6
  return window.location.origin;
@@ -20,7 +21,7 @@ function buildHeaders(additionalHeaders = {}) {
20
21
  };
21
22
  const teamId = getCurrentTeamId();
22
23
  if (teamId) {
23
- headers["x-team-id"] = teamId;
24
+ headers[TEAM_ID_HEADER] = teamId;
24
25
  }
25
26
  return headers;
26
27
  }
@@ -418,7 +419,7 @@ class EntityApiClient {
418
419
  delete copyData.createdAt;
419
420
  delete copyData.updatedAt;
420
421
  const hasBlocks = "blocks" in copyData && Array.isArray(copyData.blocks);
421
- return this.create(entityType, copyData, hasBlocks ? { "x-builder-source": "true" } : {});
422
+ return this.create(entityType, copyData, hasBlocks ? { [BUILDER_SOURCE_HEADER]: "true" } : {});
422
423
  }
423
424
  /**
424
425
  * Detect if entity has custom override (client-side detection)
@@ -474,7 +475,7 @@ async function fetchWithTeam(url, options = {}) {
474
475
  headers.set("Content-Type", "application/json");
475
476
  }
476
477
  if (activeTeamId) {
477
- headers.set("x-team-id", activeTeamId);
478
+ headers.set(TEAM_ID_HEADER, activeTeamId);
478
479
  }
479
480
  return fetch(withBasePathIfInApp(url), {
480
481
  ...options,
@@ -1 +1 @@
1
- {"version":3,"file":"audit-log.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/entity/audit-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEvD;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,cAAc,GAAG,IAAI,CAAA;CAC5B;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,cAAc,GAAG,IAAI,EAC3B,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAqDf"}
1
+ {"version":3,"file":"audit-log.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/entity/audit-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAG9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEvD;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,cAAc,GAAG,IAAI,CAAA;CAC5B;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,cAAc,GAAG,IAAI,EAC3B,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAqDf"}
@@ -1,4 +1,5 @@
1
1
  import { mutateWithRLS } from "../../db.js";
2
+ import { getRecordedClientIp } from "../client-ip.js";
2
3
  async function logGenericHandlerUsage(auth, request, statusCode, responseTime) {
3
4
  var _a;
4
5
  const userId = (_a = auth == null ? void 0 : auth.user) == null ? void 0 : _a.id;
@@ -9,7 +10,7 @@ async function logGenericHandlerUsage(auth, request, statusCode, responseTime) {
9
10
  try {
10
11
  endpoint = request.nextUrl.pathname;
11
12
  method = request.method;
12
- const ipAddress = request.headers.get("x-forwarded-for") || request.headers.get("x-real-ip") || "unknown";
13
+ const ipAddress = getRecordedClientIp(request.headers);
13
14
  const userAgent = request.headers.get("user-agent");
14
15
  await mutateWithRLS(
15
16
  `INSERT INTO "api_audit_log"
@@ -1 +1 @@
1
- {"version":3,"file":"generic-handler.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/entity/generic-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AA6wBvD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAEnF;AA8lBD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAErF;AAoaD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAEpJ;AAoND;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAEtJ;AA+YD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAEtJ;AAwKD;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAEtF"}
1
+ {"version":3,"file":"generic-handler.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/entity/generic-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AA+wBvD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAEnF;AA8lBD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAErF;AAyaD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAEpJ;AAoND;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAEtJ;AA6ZD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAEtJ;AAwKD;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAEtF"}
@@ -2,6 +2,8 @@ import { NextResponse } from "next/server";
2
2
  import { authenticateRequest, createAuthFailureResponse, canBypassTeamContext } from "../auth/dual-auth.js";
3
3
  import { resolveEntityFromUrl, validateEntityOperation } from "./resolver.js";
4
4
  import { generateEntitySchemas } from "../../entities/schema-generator.js";
5
+ import { publicSlugIssue, otherBasePathSegments } from "../../entities/public-slug.js";
6
+ import { getAllEntityConfigs } from "../../entities/registry.js";
5
7
  import { entityResponseSystemColumns, taxonomyResponseFields } from "../../entities/portable/response-shape.js";
6
8
  import { queryWithRLS, mutateWithRLS, queryOneWithRLS } from "../../db.js";
7
9
  import {
@@ -832,6 +834,10 @@ async function handleGenericCreateImpl(request, audit) {
832
834
  return addCorsHeaders(response2, request);
833
835
  }
834
836
  let validatedData = validation.data;
837
+ const slugIssue = publicSlugIssue(entityConfig, validatedData, otherBasePathSegments(entityConfig, getAllEntityConfigs()));
838
+ if (slugIssue) {
839
+ return addCorsHeaders(createApiError(slugIssue.message, 400, [slugIssue], "VALIDATION_ERROR"), request);
840
+ }
835
841
  const xssField = checkNameFieldXss(entityConfig, validatedData);
836
842
  if (xssField) {
837
843
  const xssResponse = createApiError(
@@ -1204,7 +1210,7 @@ async function handleGenericUpdate(request, { params }) {
1204
1210
  return runWithAuditLog(request, (audit) => handleGenericUpdateImpl(request, audit, { params }));
1205
1211
  }
1206
1212
  async function handleGenericUpdateImpl(request, audit, { params }) {
1207
- var _a, _b, _c, _d, _e, _f, _g;
1213
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1208
1214
  try {
1209
1215
  const { id } = await params;
1210
1216
  const resolution = await resolveEntityFromUrl(request.nextUrl.pathname);
@@ -1285,6 +1291,18 @@ async function handleGenericUpdateImpl(request, audit, { params }) {
1285
1291
  return addCorsHeaders(response2, request);
1286
1292
  }
1287
1293
  let validatedData = validation.data;
1294
+ let slugIssue = publicSlugIssue(entityConfig, validatedData, otherBasePathSegments(entityConfig, getAllEntityConfigs()));
1295
+ if (slugIssue) {
1296
+ const current = await queryWithRLS(
1297
+ `SELECT "slug" FROM "${tableName}" WHERE id = $1 AND "teamId" = $2`,
1298
+ [id, teamId],
1299
+ authResult.user.id
1300
+ );
1301
+ if (((_d = current[0]) == null ? void 0 : _d.slug) === validatedData.slug) slugIssue = null;
1302
+ }
1303
+ if (slugIssue) {
1304
+ return addCorsHeaders(createApiError(slugIssue.message, 400, [slugIssue], "VALIDATION_ERROR"), request);
1305
+ }
1288
1306
  const updateXssField = checkNameFieldXss(entityConfig, validatedData);
1289
1307
  if (updateXssField) {
1290
1308
  const updateXssResponse = createApiError(
@@ -1316,7 +1334,7 @@ async function handleGenericUpdateImpl(request, audit, { params }) {
1316
1334
  const values = [];
1317
1335
  let paramCount = 1;
1318
1336
  const builderRequest = isBuilderRequest(request);
1319
- const entityHasBuilder = ((_d = entityConfig.builder) == null ? void 0 : _d.enabled) === true;
1337
+ const entityHasBuilder = ((_e = entityConfig.builder) == null ? void 0 : _e.enabled) === true;
1320
1338
  if (builderRequest && entityHasBuilder && "blocks" in entityData) {
1321
1339
  let blocksData = entityData.blocks;
1322
1340
  blocksData = await filterOrphanedPatternReferences(blocksData, authResult.user.id);
@@ -1392,7 +1410,7 @@ async function handleGenericUpdateImpl(request, audit, { params }) {
1392
1410
  whereConditions.push(`"teamId" = $${paramCount++}`);
1393
1411
  values.push(teamId);
1394
1412
  }
1395
- if (!((_e = entityConfig.access) == null ? void 0 : _e.shared)) {
1413
+ if (!((_f = entityConfig.access) == null ? void 0 : _f.shared)) {
1396
1414
  whereConditions.push(`"userId" = $${paramCount++}`);
1397
1415
  values.push(authResult.user.id);
1398
1416
  }
@@ -1436,7 +1454,7 @@ async function handleGenericUpdateImpl(request, audit, { params }) {
1436
1454
  }
1437
1455
  updatedItem = result[0];
1438
1456
  }
1439
- if ((_f = entityConfig.taxonomies) == null ? void 0 : _f.enabled) {
1457
+ if ((_g = entityConfig.taxonomies) == null ? void 0 : _g.enabled) {
1440
1458
  await processTaxonomyRelations(entityConfig, id, body, authResult.user.id, true);
1441
1459
  }
1442
1460
  if (metadataWasProvided) {
@@ -1448,7 +1466,7 @@ async function handleGenericUpdateImpl(request, audit, { params }) {
1448
1466
  );
1449
1467
  }
1450
1468
  let responseItem = updatedItem;
1451
- if ((_g = entityConfig.taxonomies) == null ? void 0 : _g.enabled) {
1469
+ if ((_h = entityConfig.taxonomies) == null ? void 0 : _h.enabled) {
1452
1470
  const itemsWithTaxonomies = await includeTaxonomiesInData(
1453
1471
  entityConfig,
1454
1472
  [updatedItem],
@@ -46,7 +46,9 @@ export declare function validateAndAuthenticateApiRequest(request: NextRequest):
46
46
  rateLimitResponse?: NextResponse;
47
47
  }>;
48
48
  /**
49
- * Extrae la información de autenticación API de los headers de la request
49
+ * The API key this request was authenticated with: the one validateApiKey accepted for it (directly, or through
50
+ * authenticateRequest / validateAndAuthenticateRequest). Throws when no key was validated for the request.
51
+ * Identity never comes from request headers.
50
52
  * @deprecated Use validateAndAuthenticateApiRequest instead
51
53
  */
52
54
  export declare function getApiAuth(request: NextRequest): ApiKeyAuth;
@@ -106,6 +108,10 @@ export declare function createPaginationMeta(page: number, limit: number, total:
106
108
  export declare function logApiUsage(auth: ApiKeyAuth, request: NextRequest, statusCode: number, responseTime?: number, requestBody?: unknown): Promise<void>;
107
109
  /**
108
110
  * Wrapper para endpoints que agrega logging automático
111
+ *
112
+ * Writes an api_audit_log row for a request authenticated with an API key, attributed to the key the handler
113
+ * validated (getValidatedApiKey), never to identity headers in the request. Requests without a validated key
114
+ * are not logged here. The request body is not stored, as in entity/audit-log.ts: payloads carry personal data.
109
115
  */
110
116
  export declare function withApiLogging<T extends unknown[]>(handler: (request: NextRequest, ...args: T) => Promise<NextResponse>): (request: NextRequest, ...args: T) => Promise<NextResponse>;
111
117
  /**
@@ -125,7 +131,7 @@ export declare function sanitizeSearchQuery(query: string): string;
125
131
  export declare function parseFilters(request: NextRequest): Record<string, string>;
126
132
  /**
127
133
  * Agrega headers de CORS para API externa
128
- * Uses unified getCorsOrigins() for single source of truth
134
+ * Uses unified getCorsOrigins() for single source of truth (see corsGrant)
129
135
  */
130
136
  export declare function addCorsHeaders(response: NextResponse, request?: NextRequest): Promise<NextResponse>;
131
137
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/lib/api/helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/lib/api/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,UAAU,EAAsC,MAAM,QAAQ,CAAC;AAaxE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EACL,KAAK,mBAAmB,EAKzB,MAAM,qBAAqB,CAAC;AAG7B,UAAU,WAAW;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,OAAO,mBAAmB,EAAE,QAAQ,EAAE,CAAC;IAC9C,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,KAAK,IAAI,GAAG,UAAU,GAAG,WAAW,CAAC;AAErC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,WAAW,EACpB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC;IACT,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,iBAAiB,CAAC,EAAE,YAAY,CAAC;IACjC,wEAAwE;IACxE,aAAa,CAAC,EAAE,YAAY,CAAC;CAC9B,CAAC,CAwDD;AAgFD;;;;;;;;GAQG;AACH,wBAAsB,iCAAiC,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC;IACrF,IAAI,EAAE,UAAU,CAAC;IACjB,iBAAiB,CAAC,EAAE,YAAY,CAAC;CAClC,CAAC,CASD;AA+BD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CAM3D;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,YAAY,GAAG,IAAI,CAiB5F;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAE,MAAY;;;;;;GASzG;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAY,EACpB,OAAO,CAAC,EAAE,OAAO,EACjB,IAAI,CAAC,EAAE,MAAM;;;;;;;;GAWd;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAQA;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM;;;;;;;EAUd;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,OAAO,GACpB,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,OAAO,EAAE,EAChD,OAAO,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,IAEtD,SAAS,WAAW,EAAE,GAAG,MAAM,CAAC,KAAG,OAAO,CAAC,YAAY,CAAC,CAkBvE;AAED;;GAEG;AACH,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUzD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAezE;AAUD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAkBzG;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAG7F;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,EAChC,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,QAAQ,CAAC,CAuBnB;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CA0BhE;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,eAAe,EAAE,OAAO,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,WAAW,CA0BlE;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAClE,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,CAAC,EAAE,EACb,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,CAAC,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,EAAE,CAAC,CA6BtD;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAClE,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,CAAC,EAAE,EACb,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,OAAO,GACrB,OAAO,CAAC,CAAC,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;CAAE,CAAC,EAAE,CAAC,CAgExD;AAED;;;GAGG;AACH,wBAAsB,8BAA8B,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAC3E,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,CAAC,EACT,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CA2BlD;AAED;;;GAGG;AACH,wBAAsB,8BAA8B,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAC3E,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,CAAC,EACT,eAAe,EAAE,OAAO,EACxB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CAiBlD;AAoBD;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA+DjD"}
@@ -1,13 +1,15 @@
1
1
  import { NextResponse } from "next/server";
2
- import { validateApiKey } from "./auth.js";
2
+ import { getValidatedApiKey, validateApiKey } from "./auth.js";
3
3
  import { mutateWithRLS, queryWithRLS } from "../db.js";
4
4
  import { checkRateLimit, addRateLimitHeaders } from "./rate-limit.js";
5
+ import { getRecordedClientIp } from "./client-ip.js";
5
6
  import { getApplicationConfig } from "../config/index.js";
6
7
  import { auth } from "../auth.js";
7
8
  import { MetaService } from "../services/meta.service.js";
8
9
  import { ScopeService } from "../services/scope.service.js";
9
10
  import { getChildEntities } from "../entities/queries.js";
10
- import { getCorsOrigins, normalizeOrigin, isOriginAllowed } from "../utils/cors.js";
11
+ import { getCorsOrigins } from "../utils/cors.js";
12
+ import { corsGrant, requestPathname, setCorsHeaders, varyOnOrigin } from "./cors-response.js";
11
13
  import { isValidUUID } from "../utils/uuid.js";
12
14
  import {
13
15
  describeRoute,
@@ -122,26 +124,11 @@ function applyApiKeyRateLimit(auth2) {
122
124
  return { auth: auth2 };
123
125
  }
124
126
  function getApiAuth(request) {
125
- const userId = request.headers.get("x-api-user-id");
126
- const keyId = request.headers.get("x-api-key-id");
127
- const scopesHeader = request.headers.get("x-api-scopes");
128
- if (!userId || !keyId || !scopesHeader) {
129
- throw new Error("Missing API authentication headers");
130
- }
131
- let scopes = [];
132
- try {
133
- const parsed = JSON.parse(scopesHeader);
134
- if (Array.isArray(parsed)) {
135
- scopes = parsed.filter((s) => typeof s === "string");
136
- }
137
- } catch {
138
- console.warn("[API] Invalid scopes header format");
127
+ const auth2 = getValidatedApiKey(request);
128
+ if (!auth2) {
129
+ throw new Error("No validated API key for this request");
139
130
  }
140
- return {
141
- userId,
142
- keyId,
143
- scopes
144
- };
131
+ return auth2;
145
132
  }
146
133
  function checkScope(auth2, requiredScope) {
147
134
  if (!scopesSatisfy(auth2.scopes, requiredScope)) {
@@ -203,7 +190,7 @@ async function logApiUsage(auth2, request, statusCode, responseTime, requestBody
203
190
  try {
204
191
  const endpoint = request.nextUrl.pathname;
205
192
  const method = request.method;
206
- const ipAddress = request.headers.get("x-forwarded-for") || request.headers.get("x-real-ip") || "unknown";
193
+ const ipAddress = getRecordedClientIp(request.headers);
207
194
  const userAgent = request.headers.get("user-agent");
208
195
  await mutateWithRLS(
209
196
  `INSERT INTO "api_audit_log"
@@ -229,31 +216,18 @@ async function logApiUsage(auth2, request, statusCode, responseTime, requestBody
229
216
  function withApiLogging(handler) {
230
217
  return async (request, ...args) => {
231
218
  const startTime = Date.now();
232
- let auth2 = null;
233
- let requestBody = null;
234
- try {
235
- try {
236
- auth2 = getApiAuth(request);
237
- } catch {
238
- }
239
- if (["POST", "PUT", "PATCH"].includes(request.method)) {
240
- try {
241
- const clonedRequest = request.clone();
242
- requestBody = await clonedRequest.json();
243
- } catch {
244
- }
245
- }
246
- const response = await handler(request, ...args);
247
- const responseTime = Date.now() - startTime;
219
+ const log = (status) => {
220
+ const auth2 = getValidatedApiKey(request);
248
221
  if (auth2) {
249
- logApiUsage(auth2, request, response.status, responseTime, requestBody).catch(console.error);
222
+ logApiUsage(auth2, request, status, Date.now() - startTime).catch(console.error);
250
223
  }
224
+ };
225
+ try {
226
+ const response = await handler(request, ...args);
227
+ log(response.status);
251
228
  return response;
252
229
  } catch (error) {
253
- const responseTime = Date.now() - startTime;
254
- if (auth2) {
255
- logApiUsage(auth2, request, 500, responseTime, requestBody).catch(console.error);
256
- }
230
+ log(500);
257
231
  throw error;
258
232
  }
259
233
  };
@@ -282,32 +256,15 @@ function getAllowedFiltersFromRegistry() {
282
256
  async function addCorsHeaders(response, request) {
283
257
  const env = process.env.NODE_ENV || "development";
284
258
  const config = await getApplicationConfig();
285
- const corsConfig = config.api.cors;
286
- let allowedOrigin = "null";
259
+ let grant = null;
287
260
  if (request) {
288
261
  const origin = request.headers.get("origin");
289
- if (origin) {
290
- const normalizedOrigin = normalizeOrigin(origin);
291
- if (env === "development" && corsConfig.allowAllOrigins.development) {
292
- allowedOrigin = normalizedOrigin;
293
- } else {
294
- const allowedOrigins = getCorsOrigins(config, env);
295
- const matched = isOriginAllowed(normalizedOrigin, allowedOrigins);
296
- if (matched) {
297
- allowedOrigin = matched;
298
- }
299
- }
300
- }
301
- } else if (env === "development" && corsConfig.allowAllOrigins.development) {
262
+ if (origin) grant = corsGrant(origin, config, env, requestPathname(request));
263
+ } else if (env === "development" && config.api.cors.allowAllOrigins.development) {
302
264
  const allowedOrigins = getCorsOrigins(config, env);
303
- allowedOrigin = allowedOrigins[0] || "http://localhost:3000";
265
+ grant = { origin: allowedOrigins[0] || "http://localhost:3000", credentials: true };
304
266
  }
305
- response.headers.set("Access-Control-Allow-Origin", allowedOrigin);
306
- response.headers.append("Vary", "Origin");
307
- response.headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS");
308
- response.headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-API-Key, x-team-id, x-builder-source");
309
- response.headers.set("Access-Control-Allow-Credentials", "true");
310
- response.headers.set("Access-Control-Max-Age", "86400");
267
+ setCorsHeaders(response.headers, grant);
311
268
  return response;
312
269
  }
313
270
  async function handleCorsPreflightRequest(request) {
@@ -321,25 +278,14 @@ async function wrapAuthHandlerWithCors(handler, request) {
321
278
  statusText: response.statusText,
322
279
  headers: new Headers(response.headers)
323
280
  });
324
- const env = process.env.NODE_ENV || "development";
325
- const config = await getApplicationConfig();
326
- const corsConfig = config.api.cors;
327
281
  const origin = request.headers.get("origin");
328
282
  if (origin) {
329
- const normalizedOrigin = normalizeOrigin(origin);
330
- let allowedOrigin = "null";
331
- if (env === "development" && corsConfig.allowAllOrigins.development) {
332
- allowedOrigin = normalizedOrigin;
333
- } else {
334
- const allowedOrigins = getCorsOrigins(config, env);
335
- const matched = isOriginAllowed(normalizedOrigin, allowedOrigins);
336
- if (matched) {
337
- allowedOrigin = matched;
338
- }
283
+ const grant = corsGrant(origin, await getApplicationConfig(), process.env.NODE_ENV || "development", requestPathname(request));
284
+ if (grant) {
285
+ newResponse.headers.set("Access-Control-Allow-Origin", grant.origin);
286
+ if (grant.credentials) newResponse.headers.set("Access-Control-Allow-Credentials", "true");
339
287
  }
340
- newResponse.headers.set("Access-Control-Allow-Origin", allowedOrigin);
341
- newResponse.headers.set("Access-Control-Allow-Credentials", "true");
342
- newResponse.headers.append("Vary", "Origin");
288
+ varyOnOrigin(newResponse.headers);
343
289
  }
344
290
  return newResponse;
345
291
  }
@@ -35,6 +35,12 @@ export declare class ApiKeyManager {
35
35
  */
36
36
  static suggestKeyName(scopes: string[]): string;
37
37
  }
38
+ /**
39
+ * The API key a request presents: the token of `Authorization: Bearer <token>`,
40
+ * else the `x-api-key` header. validateApiKey checks this value, and the
41
+ * cookie-write origin check (lib/api/request-origin) reads it too.
42
+ */
43
+ export declare function presentedApiKey(headers: Headers): string | null;
38
44
  /**
39
45
  * Definición de scopes disponibles para API keys
40
46
  */
@@ -1 +1 @@
1
- {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../src/lib/api/keys.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,aAAa;IACxB;;;OAGG;WACU,cAAc,IAAI,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAyBrF;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAM9C;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAKzC;;OAEG;WACU,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQlD;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,aAAa,EAAE,MAAM,EAAE,CAAA;KAAE;IAUpF;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM;CAchD;AAED;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;CAgCb,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,UAAU,CAAC;AAE/C;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGrD;AAED,oFAAoF;AACpF,wBAAgB,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIxD;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;yBAIgC,QAAQ,EAAE;;;;;yBAKV,QAAQ,EAAE;;;;;yBAKV,QAAQ,EAAE;;;;;yBAKtB,QAAQ,EAAE;;;;;yBAKQ,QAAQ,EAAE;;;;;yBAKxD,QAAQ,EAAE;;CAErB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,cAAc;;;;CAIjB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CASd,CAAC;AAEX;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAmB9F"}
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../src/lib/api/keys.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,aAAa;IACxB;;;OAGG;WACU,cAAc,IAAI,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAyBrF;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAM9C;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAKzC;;OAEG;WACU,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQlD;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,aAAa,EAAE,MAAM,EAAE,CAAA;KAAE;IAUpF;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM;CAchD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAI/D;AAED;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;CAgCb,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,UAAU,CAAC;AAE/C;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGrD;AAED,oFAAoF;AACpF,wBAAgB,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIxD;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;yBAIgC,QAAQ,EAAE;;;;;yBAKV,QAAQ,EAAE;;;;;yBAKV,QAAQ,EAAE;;;;;yBAKtB,QAAQ,EAAE;;;;;yBAKQ,QAAQ,EAAE;;;;;yBAKxD,QAAQ,EAAE;;CAErB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,cAAc;;;;CAIjB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CASd,CAAC;AAEX;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAmB9F"}
@@ -68,6 +68,11 @@ class ApiKeyManager {
68
68
  return `${categoryNames} Access Key`;
69
69
  }
70
70
  }
71
+ function presentedApiKey(headers) {
72
+ const authorization = headers.get("authorization");
73
+ if (authorization == null ? void 0 : authorization.startsWith("Bearer ")) return authorization.substring(7);
74
+ return headers.get("x-api-key") || null;
75
+ }
71
76
  const API_SCOPES = {
72
77
  // Usuarios
73
78
  "users:read": "Read user information",
@@ -183,5 +188,6 @@ export {
183
188
  SCOPE_CATEGORIES,
184
189
  getApiScopes,
185
190
  getAppApiScopes,
186
- getRateLimitForScopes
191
+ getRateLimitForScopes,
192
+ presentedApiKey
187
193
  };
@@ -47,6 +47,10 @@ export declare function applyRateLimit(request: NextRequest, keyId: string, scop
47
47
  export declare function addRateLimitHeaders(response: NextResponse, keyId: string, scopes: string[]): NextResponse;
48
48
  /**
49
49
  * Middleware helper para aplicar rate limiting automáticamente
50
+ *
51
+ * Limits per API key, with the limits of the key's scopes, when the request presents a key that validates.
52
+ * The key id and scopes come from that validation, never from request headers; any other request runs the
53
+ * handler without this limit.
50
54
  */
51
55
  export declare function withRateLimit<T extends unknown[]>(handler: (request: NextRequest, ...args: T) => Promise<NextResponse>): (request: NextRequest, ...args: T) => Promise<NextResponse>;
52
56
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../../src/lib/api/rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIxD,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,KAAK,GAAE,MAAa,EACpB,QAAQ,GAAE,MAAc,GACvB,eAAe,CAyCjB;AAED;;;GAGG;AACH,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,aAAqB,GAC1B,OAAO,CAAC,eAAe,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6CpD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,eAAe,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,CAwB5G;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,IAAI,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EAAE,GACf,YAAY,GAAG,IAAI,CAkCrB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,EACtB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EAAE,GACf,YAAY,CASd;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,OAAO,EAAE,EAC/C,OAAO,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,IAEtD,SAAS,WAAW,EAAE,GAAG,MAAM,CAAC,KAAG,OAAO,CAAC,YAAY,CAAC,CAwCvE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;CACtB,GAAG,IAAI,CAaP;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAGlD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,KAAK,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CASD;AAED;;GAEG;AACH,wBAAgB,sBAAsB;;;;;EAErC;AAoGD,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,OAAO,EAAE,EACnD,OAAO,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,EACpE,IAAI,GAAE,aAAqB,IAEb,SAAS,WAAW,EAAE,GAAG,MAAM,CAAC,KAAG,OAAO,CAAC,YAAY,CAAC,CAkCvE"}
1
+ {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../../src/lib/api/rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMxD,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAI7B,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,KAAK,GAAE,MAAa,EACpB,QAAQ,GAAE,MAAc,GACvB,eAAe,CAyCjB;AAED;;;GAGG;AACH,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,aAAqB,GAC1B,OAAO,CAAC,eAAe,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6CpD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,eAAe,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,CAwB5G;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,IAAI,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EAAE,GACf,YAAY,GAAG,IAAI,CAkCrB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,EACtB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EAAE,GACf,YAAY,CASd;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,OAAO,EAAE,EAC/C,OAAO,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,IAEtD,SAAS,WAAW,EAAE,GAAG,MAAM,CAAC,KAAG,OAAO,CAAC,YAAY,CAAC,CA2BvE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;CACtB,GAAG,IAAI,CAaP;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAGlD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,KAAK,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CASD;AAED;;GAEG;AACH,wBAAgB,sBAAsB;;;;;EAErC;AA4DD,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,OAAO,EAAE,EACnD,OAAO,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,EACpE,IAAI,GAAE,aAAqB,IAkCb,SAAS,WAAW,EAAE,GAAG,MAAM,CAAC,KAAG,OAAO,CAAC,YAAY,CAAC,CAIvE"}