@nextsparkjs/core 0.1.0-beta.194 → 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 (338) hide show
  1. package/dist/components/app/guards/DeveloperGuard.d.ts +8 -1
  2. package/dist/components/app/guards/DeveloperGuard.d.ts.map +1 -1
  3. package/dist/components/app/guards/DeveloperGuard.js +2 -1
  4. package/dist/components/app/guards/SuperAdminGuard.d.ts +8 -1
  5. package/dist/components/app/guards/SuperAdminGuard.d.ts.map +1 -1
  6. package/dist/components/app/guards/SuperAdminGuard.js +2 -1
  7. package/dist/components/dashboard/block-editor/block-picker.d.ts.map +1 -1
  8. package/dist/components/dashboard/block-editor/block-picker.js +2 -1
  9. package/dist/components/dashboard/block-editor/builder-editor-view.d.ts.map +1 -1
  10. package/dist/components/dashboard/block-editor/builder-editor-view.js +39 -23
  11. package/dist/components/dashboard/block-editor/pattern-reference-preview.d.ts.map +1 -1
  12. package/dist/components/dashboard/block-editor/pattern-reference-preview.js +2 -1
  13. package/dist/components/dashboard/layouts/AuthGuard.d.ts.map +1 -1
  14. package/dist/components/dashboard/layouts/AuthGuard.js +3 -4
  15. package/dist/components/dashboard/layouts/AuthenticatedDashboardLayout.d.ts.map +1 -1
  16. package/dist/components/dashboard/layouts/AuthenticatedDashboardLayout.js +9 -10
  17. package/dist/components/dashboard/layouts/DashboardAuthLayout.d.ts.map +1 -1
  18. package/dist/components/dashboard/layouts/DashboardAuthLayout.js +3 -4
  19. package/dist/components/dashboard/layouts/DashboardAuthSkeleton.d.ts +2 -2
  20. package/dist/components/entities/wrappers/EntityDetailWrapper.d.ts.map +1 -1
  21. package/dist/components/entities/wrappers/EntityDetailWrapper.js +5 -2
  22. package/dist/components/entities/wrappers/EntityFormWrapper.d.ts.map +1 -1
  23. package/dist/components/entities/wrappers/EntityFormWrapper.js +5 -2
  24. package/dist/components/entities/wrappers/EntityListWrapper.d.ts.map +1 -1
  25. package/dist/components/entities/wrappers/EntityListWrapper.js +5 -2
  26. package/dist/components/ui/relation-display.d.ts.map +1 -1
  27. package/dist/components/ui/relation-display.js +2 -1
  28. package/dist/components/ui/user-display.d.ts.map +1 -1
  29. package/dist/components/ui/user-display.js +2 -1
  30. package/dist/emails/otp-verification.d.ts.map +1 -1
  31. package/dist/emails/otp-verification.js +5 -3
  32. package/dist/emails/reset-password.d.ts.map +1 -1
  33. package/dist/emails/reset-password.js +5 -3
  34. package/dist/emails/team-invitation.d.ts.map +1 -1
  35. package/dist/emails/team-invitation.js +3 -2
  36. package/dist/emails/verify-email.d.ts.map +1 -1
  37. package/dist/emails/verify-email.js +5 -3
  38. package/dist/hooks/useAuth.d.ts.map +1 -1
  39. package/dist/hooks/useAuth.js +21 -4
  40. package/dist/hooks/usePatternUsages.d.ts.map +1 -1
  41. package/dist/hooks/usePatternUsages.js +3 -2
  42. package/dist/lib/api/auth.d.ts +2 -0
  43. package/dist/lib/api/auth.d.ts.map +1 -1
  44. package/dist/lib/api/auth.js +10 -10
  45. package/dist/lib/api/client-headers.d.ts +11 -0
  46. package/dist/lib/api/client-headers.d.ts.map +1 -0
  47. package/dist/lib/api/client-headers.js +12 -0
  48. package/dist/lib/api/client-ip.d.ts +59 -0
  49. package/dist/lib/api/client-ip.d.ts.map +1 -0
  50. package/dist/lib/api/client-ip.js +91 -0
  51. package/dist/lib/api/cors-response.d.ts +54 -0
  52. package/dist/lib/api/cors-response.d.ts.map +1 -0
  53. package/dist/lib/api/cors-response.js +88 -0
  54. package/dist/lib/api/entities.d.ts.map +1 -1
  55. package/dist/lib/api/entities.js +4 -3
  56. package/dist/lib/api/entity/audit-log.d.ts.map +1 -1
  57. package/dist/lib/api/entity/audit-log.js +2 -1
  58. package/dist/lib/api/entity/generic-handler.d.ts.map +1 -1
  59. package/dist/lib/api/entity/generic-handler.js +23 -5
  60. package/dist/lib/api/helpers.d.ts +8 -2
  61. package/dist/lib/api/helpers.d.ts.map +1 -1
  62. package/dist/lib/api/helpers.js +27 -81
  63. package/dist/lib/api/keys.d.ts +6 -0
  64. package/dist/lib/api/keys.d.ts.map +1 -1
  65. package/dist/lib/api/keys.js +7 -1
  66. package/dist/lib/api/rate-limit.d.ts +4 -0
  67. package/dist/lib/api/rate-limit.d.ts.map +1 -1
  68. package/dist/lib/api/rate-limit.js +16 -40
  69. package/dist/lib/api/request-origin.d.ts +16 -7
  70. package/dist/lib/api/request-origin.d.ts.map +1 -1
  71. package/dist/lib/api/request-origin.js +43 -20
  72. package/dist/lib/auth/load-login-page.d.ts +10 -0
  73. package/dist/lib/auth/load-login-page.d.ts.map +1 -0
  74. package/dist/lib/auth/load-login-page.js +7 -0
  75. package/dist/lib/auth/runtime-readiness.d.ts.map +1 -1
  76. package/dist/lib/auth/runtime-readiness.js +2 -0
  77. package/dist/lib/auth/security-notifications/device-fingerprint.d.ts +1 -8
  78. package/dist/lib/auth/security-notifications/device-fingerprint.d.ts.map +1 -1
  79. package/dist/lib/auth/security-notifications/device-fingerprint.js +2 -12
  80. package/dist/lib/auth-email-callbacks.js +3 -3
  81. package/dist/lib/auth.d.ts.map +1 -1
  82. package/dist/lib/auth.js +7 -2
  83. package/dist/lib/config/config-client.d.ts.map +1 -1
  84. package/dist/lib/config/config-client.js +1 -1
  85. package/dist/lib/config/config-sync.d.ts.map +1 -1
  86. package/dist/lib/config/config-sync.js +1 -1
  87. package/dist/lib/config/public-config-client.d.ts +1 -0
  88. package/dist/lib/config/public-config-client.d.ts.map +1 -1
  89. package/dist/lib/config/public-config-client.js +3 -1
  90. package/dist/lib/config/types.d.ts +2 -0
  91. package/dist/lib/config/types.d.ts.map +1 -1
  92. package/dist/lib/constants/reserved-slugs.d.ts +17 -8
  93. package/dist/lib/constants/reserved-slugs.d.ts.map +1 -1
  94. package/dist/lib/constants/reserved-slugs.js +16 -52
  95. package/dist/lib/db.d.ts.map +1 -1
  96. package/dist/lib/db.js +9 -3
  97. package/dist/lib/entities/external-api-generator.d.ts.map +1 -1
  98. package/dist/lib/entities/external-api-generator.js +2 -4
  99. package/dist/lib/entities/public-slug.d.ts +46 -0
  100. package/dist/lib/entities/public-slug.d.ts.map +1 -0
  101. package/dist/lib/entities/public-slug.js +39 -0
  102. package/dist/routes/(auth)/signup/page.cc.d.ts +3 -8
  103. package/dist/routes/(auth)/signup/page.cc.d.ts.map +1 -1
  104. package/dist/routes/(auth)/signup/page.cc.js +7 -1
  105. package/dist/routes/(auth)/verify-email/page.d.ts.map +1 -1
  106. package/dist/routes/(auth)/verify-email/page.js +2 -1
  107. package/dist/routes/(public)/page.cc.d.ts +3 -0
  108. package/dist/routes/(public)/page.cc.d.ts.map +1 -0
  109. package/dist/routes/(public)/page.cc.js +3 -0
  110. package/dist/routes/_internal/area-access.cc.d.ts +21 -0
  111. package/dist/routes/_internal/area-access.cc.d.ts.map +1 -0
  112. package/dist/routes/_internal/area-access.cc.js +19 -0
  113. package/dist/routes/_internal/auth-layout.d.ts.map +1 -1
  114. package/dist/routes/_internal/auth-layout.js +3 -2
  115. package/dist/routes/_internal/dashboard-main-shared.d.ts +7 -0
  116. package/dist/routes/_internal/dashboard-main-shared.d.ts.map +1 -0
  117. package/dist/routes/_internal/dashboard-main-shared.js +49 -0
  118. package/dist/routes/_internal/default-auth-layout.d.ts.map +1 -1
  119. package/dist/routes/_internal/default-auth-layout.js +3 -2
  120. package/dist/routes/_internal/devtools-layout.cc.d.ts +3 -2
  121. package/dist/routes/_internal/devtools-layout.cc.d.ts.map +1 -1
  122. package/dist/routes/_internal/devtools-layout.cc.js +1 -1
  123. package/dist/routes/_internal/devtools-layout.d.ts +7 -2
  124. package/dist/routes/_internal/devtools-layout.d.ts.map +1 -1
  125. package/dist/routes/_internal/devtools-layout.js +4 -4
  126. package/dist/routes/_internal/entity-detail-route.cc.d.ts +8 -0
  127. package/dist/routes/_internal/entity-detail-route.cc.d.ts.map +1 -0
  128. package/dist/routes/_internal/entity-detail-route.cc.js +5 -0
  129. package/dist/routes/_internal/entity-edit-route.cc.d.ts +8 -0
  130. package/dist/routes/_internal/entity-edit-route.cc.d.ts.map +1 -0
  131. package/dist/routes/_internal/entity-edit-route.cc.js +5 -0
  132. package/dist/routes/_internal/public-archive-route.d.ts +1 -1
  133. package/dist/routes/_internal/public-archive-route.d.ts.map +1 -1
  134. package/dist/routes/_internal/public-archive-route.js +8 -3
  135. package/dist/routes/_internal/public-item-route.cc.d.ts +5 -1
  136. package/dist/routes/_internal/public-item-route.cc.d.ts.map +1 -1
  137. package/dist/routes/_internal/public-item-route.cc.js +2 -1
  138. package/dist/routes/_internal/public-item-route.d.ts +7 -0
  139. package/dist/routes/_internal/public-item-route.d.ts.map +1 -1
  140. package/dist/routes/_internal/public-item-route.js +6 -1
  141. package/dist/routes/_internal/superadmin-layout.cc.d.ts +2 -1
  142. package/dist/routes/_internal/superadmin-layout.cc.d.ts.map +1 -1
  143. package/dist/routes/_internal/superadmin-layout.cc.js +1 -1
  144. package/dist/routes/_internal/superadmin-layout.d.ts +7 -2
  145. package/dist/routes/_internal/superadmin-layout.d.ts.map +1 -1
  146. package/dist/routes/_internal/superadmin-layout.js +6 -6
  147. package/dist/routes/_internal/suspended-route.d.ts +16 -0
  148. package/dist/routes/_internal/suspended-route.d.ts.map +1 -0
  149. package/dist/routes/_internal/suspended-route.js +7 -0
  150. package/dist/routes/api/auth/[...all]/route.d.ts.map +1 -1
  151. package/dist/routes/api/auth/[...all]/route.js +4 -12
  152. package/dist/routes/api/csp-report/route.d.ts.map +1 -1
  153. package/dist/routes/api/csp-report/route.js +2 -13
  154. package/dist/routes/api/devtools/config/entities/route.d.ts +2 -0
  155. package/dist/routes/api/devtools/config/entities/route.d.ts.map +1 -1
  156. package/dist/routes/api/devtools/config/entities/route.js +2 -0
  157. package/dist/routes/api/devtools/config/theme/route.d.ts +2 -0
  158. package/dist/routes/api/devtools/config/theme/route.d.ts.map +1 -1
  159. package/dist/routes/api/devtools/config/theme/route.js +2 -0
  160. package/dist/routes/api/devtools/tests/[...path]/route.d.ts +2 -0
  161. package/dist/routes/api/devtools/tests/[...path]/route.d.ts.map +1 -1
  162. package/dist/routes/api/devtools/tests/[...path]/route.js +2 -0
  163. package/dist/routes/api/devtools/tests/route.d.ts +2 -0
  164. package/dist/routes/api/devtools/tests/route.d.ts.map +1 -1
  165. package/dist/routes/api/devtools/tests/route.js +2 -0
  166. package/dist/routes/api/health/route.d.ts +2 -0
  167. package/dist/routes/api/health/route.d.ts.map +1 -1
  168. package/dist/routes/api/health/route.js +2 -0
  169. package/dist/routes/api/internal/user-metadata/route.d.ts +2 -0
  170. package/dist/routes/api/internal/user-metadata/route.d.ts.map +1 -1
  171. package/dist/routes/api/internal/user-metadata/route.js +2 -0
  172. package/dist/routes/api/mcp/route.d.ts +2 -0
  173. package/dist/routes/api/mcp/route.d.ts.map +1 -1
  174. package/dist/routes/api/mcp/route.js +2 -0
  175. package/dist/routes/api/superadmin/subscriptions/route.d.ts +2 -0
  176. package/dist/routes/api/superadmin/subscriptions/route.d.ts.map +1 -1
  177. package/dist/routes/api/superadmin/subscriptions/route.js +2 -0
  178. package/dist/routes/api/superadmin/teams/[teamId]/route.d.ts +2 -0
  179. package/dist/routes/api/superadmin/teams/[teamId]/route.d.ts.map +1 -1
  180. package/dist/routes/api/superadmin/teams/[teamId]/route.js +2 -0
  181. package/dist/routes/api/superadmin/teams/route.d.ts +2 -0
  182. package/dist/routes/api/superadmin/teams/route.d.ts.map +1 -1
  183. package/dist/routes/api/superadmin/teams/route.js +2 -0
  184. package/dist/routes/api/superadmin/users/[userId]/route.d.ts +2 -0
  185. package/dist/routes/api/superadmin/users/[userId]/route.d.ts.map +1 -1
  186. package/dist/routes/api/superadmin/users/[userId]/route.js +2 -0
  187. package/dist/routes/api/superadmin/users/route.d.ts +2 -0
  188. package/dist/routes/api/superadmin/users/route.d.ts.map +1 -1
  189. package/dist/routes/api/superadmin/users/route.js +2 -0
  190. package/dist/routes/api/user/delete-account/route.d.ts +2 -0
  191. package/dist/routes/api/user/delete-account/route.d.ts.map +1 -1
  192. package/dist/routes/api/user/delete-account/route.js +2 -0
  193. package/dist/routes/api/user/plan-flags/route.d.ts +2 -0
  194. package/dist/routes/api/user/plan-flags/route.d.ts.map +1 -1
  195. package/dist/routes/api/user/plan-flags/route.js +2 -0
  196. package/dist/routes/api/user/profile/route.d.ts +2 -0
  197. package/dist/routes/api/user/profile/route.d.ts.map +1 -1
  198. package/dist/routes/api/user/profile/route.js +4 -3
  199. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/[childId]/route.d.ts +2 -0
  200. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/[childId]/route.d.ts.map +1 -1
  201. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/[childId]/route.js +2 -0
  202. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/route.d.ts +2 -0
  203. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/route.d.ts.map +1 -1
  204. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/route.js +2 -0
  205. package/dist/routes/api/v1/billing/cancel/route.d.ts +2 -0
  206. package/dist/routes/api/v1/billing/cancel/route.d.ts.map +1 -1
  207. package/dist/routes/api/v1/billing/cancel/route.js +2 -0
  208. package/dist/routes/api/v1/billing/change-plan/route.d.ts +2 -0
  209. package/dist/routes/api/v1/billing/change-plan/route.d.ts.map +1 -1
  210. package/dist/routes/api/v1/billing/change-plan/route.js +2 -0
  211. package/dist/routes/api/v1/billing/check-action/route.d.ts +2 -0
  212. package/dist/routes/api/v1/billing/check-action/route.d.ts.map +1 -1
  213. package/dist/routes/api/v1/billing/check-action/route.js +2 -0
  214. package/dist/routes/api/v1/billing/checkout/route.d.ts +2 -0
  215. package/dist/routes/api/v1/billing/checkout/route.d.ts.map +1 -1
  216. package/dist/routes/api/v1/billing/checkout/route.js +2 -0
  217. package/dist/routes/api/v1/billing/plans/route.d.ts +2 -0
  218. package/dist/routes/api/v1/billing/plans/route.d.ts.map +1 -1
  219. package/dist/routes/api/v1/billing/plans/route.js +2 -0
  220. package/dist/routes/api/v1/billing/portal/route.d.ts +2 -0
  221. package/dist/routes/api/v1/billing/portal/route.d.ts.map +1 -1
  222. package/dist/routes/api/v1/billing/portal/route.js +2 -0
  223. package/dist/routes/api/v1/blocks/[slug]/route.d.ts +2 -0
  224. package/dist/routes/api/v1/blocks/[slug]/route.d.ts.map +1 -1
  225. package/dist/routes/api/v1/blocks/[slug]/route.js +2 -0
  226. package/dist/routes/api/v1/blocks/route.d.ts +2 -0
  227. package/dist/routes/api/v1/blocks/route.d.ts.map +1 -1
  228. package/dist/routes/api/v1/blocks/route.js +2 -0
  229. package/dist/routes/api/v1/blocks/validate/route.d.ts +2 -0
  230. package/dist/routes/api/v1/blocks/validate/route.d.ts.map +1 -1
  231. package/dist/routes/api/v1/blocks/validate/route.js +2 -0
  232. package/dist/routes/api/v1/devtools/blocks/route.d.ts +2 -1
  233. package/dist/routes/api/v1/devtools/blocks/route.d.ts.map +1 -1
  234. package/dist/routes/api/v1/devtools/blocks/route.js +2 -9
  235. package/dist/routes/api/v1/devtools/docs/route.d.ts +2 -0
  236. package/dist/routes/api/v1/devtools/docs/route.d.ts.map +1 -1
  237. package/dist/routes/api/v1/devtools/docs/route.js +2 -0
  238. package/dist/routes/api/v1/devtools/features/route.d.ts +2 -1
  239. package/dist/routes/api/v1/devtools/features/route.d.ts.map +1 -1
  240. package/dist/routes/api/v1/devtools/features/route.js +2 -9
  241. package/dist/routes/api/v1/devtools/flows/route.d.ts +2 -1
  242. package/dist/routes/api/v1/devtools/flows/route.d.ts.map +1 -1
  243. package/dist/routes/api/v1/devtools/flows/route.js +2 -9
  244. package/dist/routes/api/v1/devtools/scheduled-actions/route.d.ts +2 -1
  245. package/dist/routes/api/v1/devtools/scheduled-actions/route.d.ts.map +1 -1
  246. package/dist/routes/api/v1/devtools/scheduled-actions/route.js +2 -9
  247. package/dist/routes/api/v1/devtools/scheduled-actions/run/route.d.ts +2 -1
  248. package/dist/routes/api/v1/devtools/scheduled-actions/run/route.d.ts.map +1 -1
  249. package/dist/routes/api/v1/devtools/scheduled-actions/run/route.js +2 -9
  250. package/dist/routes/api/v1/devtools/testing/route.d.ts +2 -1
  251. package/dist/routes/api/v1/devtools/testing/route.d.ts.map +1 -1
  252. package/dist/routes/api/v1/devtools/testing/route.js +2 -9
  253. package/dist/routes/api/v1/media/[id]/route.d.ts +2 -0
  254. package/dist/routes/api/v1/media/[id]/route.d.ts.map +1 -1
  255. package/dist/routes/api/v1/media/[id]/route.js +2 -0
  256. package/dist/routes/api/v1/media/[id]/tags/route.d.ts +2 -0
  257. package/dist/routes/api/v1/media/[id]/tags/route.d.ts.map +1 -1
  258. package/dist/routes/api/v1/media/[id]/tags/route.js +2 -0
  259. package/dist/routes/api/v1/media/check-duplicates/route.d.ts +2 -0
  260. package/dist/routes/api/v1/media/check-duplicates/route.d.ts.map +1 -1
  261. package/dist/routes/api/v1/media/check-duplicates/route.js +2 -0
  262. package/dist/routes/api/v1/media/route.d.ts +2 -0
  263. package/dist/routes/api/v1/media/route.d.ts.map +1 -1
  264. package/dist/routes/api/v1/media/route.js +2 -0
  265. package/dist/routes/api/v1/media/upload/route.d.ts +2 -0
  266. package/dist/routes/api/v1/media/upload/route.d.ts.map +1 -1
  267. package/dist/routes/api/v1/media/upload/route.js +2 -0
  268. package/dist/routes/api/v1/media-tags/route.d.ts +2 -0
  269. package/dist/routes/api/v1/media-tags/route.d.ts.map +1 -1
  270. package/dist/routes/api/v1/media-tags/route.js +2 -0
  271. package/dist/routes/api/v1/post-categories/[id]/route.d.ts +2 -0
  272. package/dist/routes/api/v1/post-categories/[id]/route.d.ts.map +1 -1
  273. package/dist/routes/api/v1/post-categories/[id]/route.js +2 -0
  274. package/dist/routes/api/v1/post-categories/route.d.ts +2 -0
  275. package/dist/routes/api/v1/post-categories/route.d.ts.map +1 -1
  276. package/dist/routes/api/v1/post-categories/route.js +2 -0
  277. package/dist/routes/api/v1/teams/[teamId]/members/route.js +2 -2
  278. package/dist/routes/api/v1/teams/[teamId]/subscription/route.d.ts +2 -0
  279. package/dist/routes/api/v1/teams/[teamId]/subscription/route.d.ts.map +1 -1
  280. package/dist/routes/api/v1/teams/[teamId]/subscription/route.js +2 -0
  281. package/dist/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.d.ts +2 -0
  282. package/dist/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.d.ts.map +1 -1
  283. package/dist/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.js +2 -0
  284. package/dist/routes/api/v1/users/[id]/route.d.ts.map +1 -1
  285. package/dist/routes/api/v1/users/[id]/route.js +3 -2
  286. package/dist/routes/api/v1/users/docs.md +34 -19
  287. package/dist/routes/api/v1/users/me/route.d.ts +6 -0
  288. package/dist/routes/api/v1/users/me/route.d.ts.map +1 -0
  289. package/dist/routes/api/v1/users/me/route.js +5 -0
  290. package/dist/routes/api/v1/users/presets.ts +2 -2
  291. package/dist/routes/dashboard/(main)/layout.cc.d.ts +4 -0
  292. package/dist/routes/dashboard/(main)/layout.cc.d.ts.map +1 -0
  293. package/dist/routes/dashboard/(main)/layout.cc.js +10 -0
  294. package/dist/routes/dashboard/(main)/layout.d.ts.map +1 -1
  295. package/dist/routes/dashboard/(main)/layout.js +3 -44
  296. package/dist/routes/dashboard/permission-denied/page.d.ts +1 -1
  297. package/dist/routes/dashboard/permission-denied/page.d.ts.map +1 -1
  298. package/dist/routes/dashboard/permission-denied/page.js +5 -1
  299. package/dist/routes/devtools/layout.cc.d.ts.map +1 -1
  300. package/dist/routes/devtools/layout.cc.js +5 -1
  301. package/dist/routes/manifest.json +10 -0
  302. package/dist/routes/robots.d.ts +10 -0
  303. package/dist/routes/robots.d.ts.map +1 -0
  304. package/dist/routes/robots.js +10 -0
  305. package/dist/routes/superadmin/layout.cc.d.ts.map +1 -1
  306. package/dist/routes/superadmin/layout.cc.js +5 -1
  307. package/dist/routes/variants.json +12 -2
  308. package/dist/templates/next.config.mjs +2 -29
  309. package/dist/templates/projects/blog/api/authors/[username]/route.ts +3 -0
  310. package/dist/templates/projects/blog/api/authors/route.ts +3 -0
  311. package/dist/templates/projects/blog/api/posts/public/route.ts +3 -0
  312. package/dist/templates/proxy.ts +12 -1
  313. package/dist/templates/public/favicon.ico +0 -0
  314. package/package.json +2 -2
  315. package/scripts/build/registry/__tests__/api-docs-colocated.test.mjs +3 -0
  316. package/scripts/build/registry/__tests__/billing-registry.test.mjs +50 -1
  317. package/scripts/build/registry/__tests__/block-registry.test.mjs +3 -0
  318. package/scripts/build/registry/__tests__/icons-discovery.test.mjs +3 -0
  319. package/scripts/build/registry/__tests__/quiet-console.mjs +17 -0
  320. package/scripts/build/registry/__tests__/safe-fs.test.mjs +3 -0
  321. package/scripts/build/registry/__tests__/team-roles.test.mjs +3 -0
  322. package/scripts/build/registry/discovery/permissions.test.mjs +3 -0
  323. package/scripts/build/registry/discovery/plugin-capabilities.mjs +2 -2
  324. package/scripts/build/registry/generators/billing-registry.mjs +7 -3
  325. package/scripts/build/registry/host/README.md +25 -1
  326. package/scripts/build/registry/host/__tests__/host-area-access.test.mjs +32 -0
  327. package/scripts/build/registry/host/__tests__/host-entities.test.mjs +32 -1
  328. package/scripts/build/registry/host/__tests__/host-plan.test.mjs +12 -2
  329. package/scripts/build/registry/host/entity-routes.mjs +9 -3
  330. package/scripts/build/registry/host/static-imports.mjs +4 -0
  331. package/scripts/build/routes-manifest.mjs +13 -1
  332. package/scripts/db/ssl-config.mjs +12 -1
  333. package/templates/next.config.mjs +2 -29
  334. package/templates/projects/blog/api/authors/[username]/route.ts +3 -0
  335. package/templates/projects/blog/api/authors/route.ts +3 -0
  336. package/templates/projects/blog/api/posts/public/route.ts +3 -0
  337. package/templates/proxy.ts +12 -1
  338. package/templates/public/favicon.ico +0 -0
@@ -3,6 +3,7 @@ import { jsx } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { parseClientChildEntity as parseChildEntity, getClientEntityApiPath as getEntityApiPath } from "../../lib/entities/client-entity-meta.js";
5
5
  import { withBasePath } from "../../lib/base-path.js";
6
+ import { TEAM_ID_HEADER } from "../../lib/api/client-headers.js";
6
7
  function RelationDisplay({
7
8
  value,
8
9
  entityType,
@@ -76,7 +77,7 @@ function RelationDisplay({
76
77
  method: "GET",
77
78
  headers: {
78
79
  "Content-Type": "application/json",
79
- ...teamId && { "x-team-id": teamId }
80
+ ...teamId && { [TEAM_ID_HEADER]: teamId }
80
81
  },
81
82
  credentials: "include"
82
83
  });
@@ -1 +1 @@
1
- {"version":3,"file":"user-display.d.ts","sourceRoot":"","sources":["../../../src/components/ui/user-display.tsx"],"names":[],"mappings":"AASA,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IAChC,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAUD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,MAAM,EAAE,UAAU,EAClB,QAAgB,EAChB,SAAiB,EACjB,SAAS,GACV,EAAE,gBAAgB,2CA0IlB"}
1
+ {"version":3,"file":"user-display.d.ts","sourceRoot":"","sources":["../../../src/components/ui/user-display.tsx"],"names":[],"mappings":"AAUA,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IAChC,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAUD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,MAAM,EAAE,UAAU,EAClB,QAAgB,EAChB,SAAiB,EACjB,SAAS,GACV,EAAE,gBAAgB,2CA0IlB"}
@@ -6,6 +6,7 @@ import { Badge } from "./badge.js";
6
6
  import { cn } from "../../lib/utils/index.js";
7
7
  import { useTeam } from "../../hooks/useTeam.js";
8
8
  import { withBasePath } from "../../lib/base-path.js";
9
+ import { TEAM_ID_HEADER } from "../../lib/api/client-headers.js";
9
10
  function UserDisplay({
10
11
  value,
11
12
  teamId: propTeamId,
@@ -37,7 +38,7 @@ function UserDisplay({
37
38
  const response = await fetch(withBasePath(`/api/v1/teams/${effectiveTeamId}/members`), {
38
39
  headers: {
39
40
  "Content-Type": "application/json",
40
- "x-team-id": effectiveTeamId
41
+ [TEAM_ID_HEADER]: effectiveTeamId
41
42
  },
42
43
  credentials: "include"
43
44
  });
@@ -1 +1 @@
1
- {"version":3,"file":"otp-verification.d.ts","sourceRoot":"","sources":["../../src/emails/otp-verification.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAKjF,wBAA8B,eAAe,CAC3C,IAAI,EAAE,wBAAwB,EAC9B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CAuEvB"}
1
+ {"version":3,"file":"otp-verification.d.ts","sourceRoot":"","sources":["../../src/emails/otp-verification.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAKjF,wBAA8B,eAAe,CAC3C,IAAI,EAAE,wBAAwB,EAC9B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CAyEvB"}
@@ -1,9 +1,11 @@
1
1
  import { getTranslations } from "next-intl/server";
2
+ import { escapeHtml } from "../lib/auth/security-notifications/templates/shared.js";
2
3
  import { DEFAULT_OTP_CONFIG } from "../lib/auth/otp-config.js";
3
4
  const APP_NAME_FALLBACK = process.env.NEXT_PUBLIC_APP_NAME || "Your App";
4
5
  async function otpVerification(data, locale) {
5
6
  const t = locale ? await getTranslations({ locale, namespace: "email.otpVerification" }) : await getTranslations("email.otpVerification");
6
7
  const appName = data.appName || APP_NAME_FALLBACK;
8
+ const htmlAppName = escapeHtml(appName);
7
9
  const year = (/* @__PURE__ */ new Date()).getFullYear();
8
10
  const expiresInMinutes = Math.floor((data.expiresIn ?? DEFAULT_OTP_CONFIG.expiresIn) / 60);
9
11
  return {
@@ -23,7 +25,7 @@ async function otpVerification(data, locale) {
23
25
  <!-- Header -->
24
26
  <tr>
25
27
  <td style="padding: 40px 40px 20px 40px; text-align: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 8px 8px 0 0;">
26
- <h1 style="color: #ffffff; font-size: 28px; margin: 0; font-weight: 600;">${appName}</h1>
28
+ <h1 style="color: #ffffff; font-size: 28px; margin: 0; font-weight: 600;">${htmlAppName}</h1>
27
29
  <p style="color: #ffffff; font-size: 16px; margin: 10px 0 0 0; opacity: 0.95;">${t("headerSubtitle")}</p>
28
30
  </td>
29
31
  </tr>
@@ -52,10 +54,10 @@ async function otpVerification(data, locale) {
52
54
  <tr>
53
55
  <td style="padding: 30px 40px; background-color: #f8f8f8; border-radius: 0 0 8px 8px; text-align: center;">
54
56
  <p style="color: #999999; font-size: 14px; margin: 0 0 10px 0;">
55
- ${t("copyright", { year, appName })}
57
+ ${t("copyright", { year, appName: htmlAppName })}
56
58
  </p>
57
59
  <p style="color: #999999; font-size: 12px; margin: 0;">
58
- ${t("footerLine1", { appName })}
60
+ ${t("footerLine1", { appName: htmlAppName })}
59
61
  </p>
60
62
  </td>
61
63
  </tr>
@@ -1 +1 @@
1
- {"version":3,"file":"reset-password.d.ts","sourceRoot":"","sources":["../../src/emails/reset-password.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAI/E,wBAA8B,aAAa,CACzC,IAAI,EAAE,sBAAsB,EAC5B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CA4FvB"}
1
+ {"version":3,"file":"reset-password.d.ts","sourceRoot":"","sources":["../../src/emails/reset-password.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAI/E,wBAA8B,aAAa,CACzC,IAAI,EAAE,sBAAsB,EAC5B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CA8FvB"}
@@ -1,8 +1,10 @@
1
1
  import { getTranslations } from "next-intl/server";
2
+ import { escapeHtml } from "../lib/auth/security-notifications/templates/shared.js";
2
3
  const APP_NAME_FALLBACK = process.env.NEXT_PUBLIC_APP_NAME || "Your App";
3
4
  async function resetPassword(data, locale) {
4
5
  const t = locale ? await getTranslations({ locale, namespace: "email.resetPassword" }) : await getTranslations("email.resetPassword");
5
6
  const appName = data.appName || APP_NAME_FALLBACK;
7
+ const htmlAppName = escapeHtml(appName);
6
8
  const year = (/* @__PURE__ */ new Date()).getFullYear();
7
9
  const greeting = `${t("greetingPrefix")}${data.userName ? ` ${data.userName}` : ""},`;
8
10
  const expiresIn = data.expiresIn || t("defaultExpiresIn");
@@ -23,7 +25,7 @@ async function resetPassword(data, locale) {
23
25
  <!-- Header -->
24
26
  <tr>
25
27
  <td style="padding: 40px 40px 20px 40px; text-align: center; background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); border-radius: 8px 8px 0 0;">
26
- <h1 style="color: #ffffff; font-size: 28px; margin: 0; font-weight: 600;">${appName}</h1>
28
+ <h1 style="color: #ffffff; font-size: 28px; margin: 0; font-weight: 600;">${htmlAppName}</h1>
27
29
  <p style="color: #ffffff; font-size: 16px; margin: 10px 0 0 0; opacity: 0.95;">${t("headerSubtitle")}</p>
28
30
  </td>
29
31
  </tr>
@@ -73,10 +75,10 @@ async function resetPassword(data, locale) {
73
75
  <tr>
74
76
  <td style="padding: 30px 40px; background-color: #f8f8f8; border-radius: 0 0 8px 8px; text-align: center;">
75
77
  <p style="color: #999999; font-size: 14px; margin: 0 0 10px 0;">
76
- ${t("copyright", { year, appName })}
78
+ ${t("copyright", { year, appName: htmlAppName })}
77
79
  </p>
78
80
  <p style="color: #999999; font-size: 12px; margin: 0;">
79
- ${t("footerLine1", { appName })}
81
+ ${t("footerLine1", { appName: htmlAppName })}
80
82
  <br>${t("footerLine2")}
81
83
  </p>
82
84
  </td>
@@ -1 +1 @@
1
- {"version":3,"file":"team-invitation.d.ts","sourceRoot":"","sources":["../../src/emails/team-invitation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAKhF,wBAA8B,cAAc,CAC1C,IAAI,EAAE,uBAAuB,EAC7B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CA0FvB"}
1
+ {"version":3,"file":"team-invitation.d.ts","sourceRoot":"","sources":["../../src/emails/team-invitation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAKhF,wBAA8B,cAAc,CAC1C,IAAI,EAAE,uBAAuB,EAC7B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CA4FvB"}
@@ -4,6 +4,7 @@ const APP_NAME_FALLBACK = process.env.NEXT_PUBLIC_APP_NAME || "Your App";
4
4
  async function teamInvitation(data, locale) {
5
5
  const t = locale ? await getTranslations({ locale, namespace: "email.teamInvitation" }) : await getTranslations("email.teamInvitation");
6
6
  const appName = data.appName || APP_NAME_FALLBACK;
7
+ const htmlAppName = escapeHtml(appName);
7
8
  const year = (/* @__PURE__ */ new Date()).getFullYear();
8
9
  return {
9
10
  subject: t("subject", { teamName: data.teamName, appName }),
@@ -22,7 +23,7 @@ async function teamInvitation(data, locale) {
22
23
  <!-- Header -->
23
24
  <tr>
24
25
  <td style="padding: 40px 40px 20px 40px; text-align: center; background: linear-gradient(135deg, #4F46E5 0%, #7C3AED 100%); border-radius: 8px 8px 0 0;">
25
- <h1 style="color: #ffffff; font-size: 28px; margin: 0; font-weight: 600;">${appName}</h1>
26
+ <h1 style="color: #ffffff; font-size: 28px; margin: 0; font-weight: 600;">${htmlAppName}</h1>
26
27
  <p style="color: #ffffff; font-size: 16px; margin: 10px 0 0 0; opacity: 0.95;">${t("headerSubtitle")}</p>
27
28
  </td>
28
29
  </tr>
@@ -72,7 +73,7 @@ async function teamInvitation(data, locale) {
72
73
  <tr>
73
74
  <td style="padding: 30px 40px; background-color: #f8f8f8; border-radius: 0 0 8px 8px; text-align: center;">
74
75
  <p style="color: #999999; font-size: 14px; margin: 0 0 10px 0;">
75
- ${t("copyright", { year, appName })}
76
+ ${t("copyright", { year, appName: htmlAppName })}
76
77
  </p>
77
78
  <p style="color: #999999; font-size: 12px; margin: 0;">
78
79
  ${t("footerSentTo", { inviteeEmail: escapeHtml(data.inviteeEmail) })}<br>
@@ -1 +1 @@
1
- {"version":3,"file":"verify-email.d.ts","sourceRoot":"","sources":["../../src/emails/verify-email.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAI9E,wBAA8B,WAAW,CACvC,IAAI,EAAE,qBAAqB,EAC3B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CAiFvB"}
1
+ {"version":3,"file":"verify-email.d.ts","sourceRoot":"","sources":["../../src/emails/verify-email.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAI9E,wBAA8B,WAAW,CACvC,IAAI,EAAE,qBAAqB,EAC3B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CAmFvB"}
@@ -1,8 +1,10 @@
1
1
  import { getTranslations } from "next-intl/server";
2
+ import { escapeHtml } from "../lib/auth/security-notifications/templates/shared.js";
2
3
  const APP_NAME_FALLBACK = process.env.NEXT_PUBLIC_APP_NAME || "Your App";
3
4
  async function verifyEmail(data, locale) {
4
5
  const t = locale ? await getTranslations({ locale, namespace: "email.verifyEmail" }) : await getTranslations("email.verifyEmail");
5
6
  const appName = data.appName || APP_NAME_FALLBACK;
7
+ const htmlAppName = escapeHtml(appName);
6
8
  const year = (/* @__PURE__ */ new Date()).getFullYear();
7
9
  const greeting = `${t("greetingPrefix")}${data.userName ? ` ${data.userName}` : ""},`;
8
10
  return {
@@ -22,7 +24,7 @@ async function verifyEmail(data, locale) {
22
24
  <!-- Header -->
23
25
  <tr>
24
26
  <td style="padding: 40px 40px 20px 40px; text-align: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 8px 8px 0 0;">
25
- <h1 style="color: #ffffff; font-size: 28px; margin: 0; font-weight: 600;">${appName}</h1>
27
+ <h1 style="color: #ffffff; font-size: 28px; margin: 0; font-weight: 600;">${htmlAppName}</h1>
26
28
  <p style="color: #ffffff; font-size: 16px; margin: 10px 0 0 0; opacity: 0.95;">${t("headerSubtitle")}</p>
27
29
  </td>
28
30
  </tr>
@@ -62,10 +64,10 @@ async function verifyEmail(data, locale) {
62
64
  <tr>
63
65
  <td style="padding: 30px 40px; background-color: #f8f8f8; border-radius: 0 0 8px 8px; text-align: center;">
64
66
  <p style="color: #999999; font-size: 14px; margin: 0 0 10px 0;">
65
- ${t("copyright", { year, appName })}
67
+ ${t("copyright", { year, appName: htmlAppName })}
66
68
  </p>
67
69
  <p style="color: #999999; font-size: 12px; margin: 0;">
68
- ${t("footerLine1", { appName })}
70
+ ${t("footerLine1", { appName: htmlAppName })}
69
71
  <br>${t("footerLine2")}
70
72
  </p>
71
73
  </td>
@@ -1 +1 @@
1
- {"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../../src/hooks/useAuth.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AA4C9C;;;GAGG;AACH,wBAAgB,cAAc;8CAYiC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;+DAqBvC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCA2E1H,MAAM;qBAlCjB,MAAM;;;gDAgBiB;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;iBAwG1G,CADD;;;;;;;;;;;;;2BA5EuC,MAAM;;;;;;;;;;;;kCA6BC,MAAM,UAAU,MAAM;;;;;;;;;;;sCAwClB,MAAM,eAAe,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCA8B5B,MAAM;;;;;;;;;;;EAwC3D;AAED,8DAA8D;AAC9D,wBAAgB,OAAO;;;;;8CAvPwC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;+DAqBvC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCA2E1H,MAAM;qBAlCjB,MAAM;;;gDAgBiB;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;iBAwG1G,CADD;;;;;;;;;;;;;2BA5EuC,MAAM;;;;;;;;;;;;kCA6BC,MAAM,UAAU,MAAM;;;;;;;;;;;sCAwClB,MAAM,eAAe,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCA8B5B,MAAM;;;;;;;;;;;UAqD5B,WAAW,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;EASjD"}
1
+ {"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../../src/hooks/useAuth.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAwE9C;;;GAGG;AACH,wBAAgB,cAAc;8CAYiC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;+DAqBvC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAmF1H,MAAM;qBAlCjB,MAAM;;;gDAgBiB;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;iBAY9F,CAAC;;;;;;;;;;;;;2BAeyB,MAAM;;;;;;;;;;;;kCA6BC,MAAM,UAAU,MAAM;;;;;;;;;;;sCAwClB,MAAM,eAAe,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCA8B5B,MAAM;;;;;;;;;;;EAwC3D;AAED,8DAA8D;AAC9D,wBAAgB,OAAO;;;;;8CA/PwC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;+DAqBvC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAmF1H,MAAM;qBAlCjB,MAAM;;;gDAgBiB;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;iBAY9F,CAAC;;;;;;;;;;;;;2BAeyB,MAAM;;;;;;;;;;;;kCA6BC,MAAM,UAAU,MAAM;;;;;;;;;;;sCAwClB,MAAM,eAAe,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCA8B5B,MAAM;;;;;;;;;;;UAqD5B,WAAW,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;EASjD"}
@@ -7,9 +7,11 @@ import { useOrigin } from "./useOrigin.js";
7
7
  import { useLastAuthMethod } from "./useLastAuthMethod.js";
8
8
  import { safeCallbackPath } from "../lib/auth/callback-url.js";
9
9
  import { withBasePath } from "../lib/base-path.js";
10
+ import { loadLoginPage } from "../lib/auth/load-login-page.js";
10
11
  import { setSessionHint } from "../lib/auth/session-hint.js";
11
12
  import { setUserLocaleClient } from "../lib/locale-client.js";
12
13
  import { I18N_CONFIG } from "../lib/config/i18n-config-client.js";
14
+ import { SIGNUP_INTENT_HEADER } from "../lib/api/client-headers.js";
13
15
  function googleCallbackURL(redirectTo) {
14
16
  const url = new URL(safeCallbackPath(redirectTo) ?? "/dashboard", "http://callback.invalid");
15
17
  url.searchParams.set("auth_method", "google");
@@ -23,6 +25,20 @@ function rememberSignedIn(user) {
23
25
  setUserLocaleClient(language);
24
26
  }
25
27
  }
28
+ const SESSION_DROP_TIMEOUT_MS = 2e3;
29
+ async function waitForSessionToDrop() {
30
+ var _a, _b, _c, _d, _e, _f;
31
+ let timer;
32
+ try {
33
+ const refetch = (_f = (_e = (_d = (_c = (_b = (_a = authClient.$store) == null ? void 0 : _a.atoms) == null ? void 0 : _b.session) == null ? void 0 : _c.get) == null ? void 0 : _d.call(_c)) == null ? void 0 : _e.refetch) == null ? void 0 : _f.call(_e);
34
+ await Promise.race([refetch, new Promise((resolve) => {
35
+ timer = setTimeout(resolve, SESSION_DROP_TIMEOUT_MS);
36
+ })]);
37
+ } catch {
38
+ } finally {
39
+ clearTimeout(timer);
40
+ }
41
+ }
26
42
  function useAuthActions() {
27
43
  const router = useRouter();
28
44
  const origin = useOrigin();
@@ -57,7 +73,7 @@ function useAuthActions() {
57
73
  },
58
74
  // Optional signup intent, sent as the `x-signup-intent` header. The signup
59
75
  // route maps it to an initial team role (AUTH_CONFIG.signupIntent).
60
- intent ? { headers: { "x-signup-intent": intent } } : void 0
76
+ intent ? { headers: { [SIGNUP_INTENT_HEADER]: intent } } : void 0
61
77
  );
62
78
  if (error) {
63
79
  throw new Error(error.message || "Failed to create account");
@@ -68,10 +84,11 @@ function useAuthActions() {
68
84
  if (typeof window !== "undefined") {
69
85
  localStorage.removeItem("activeTeamId");
70
86
  }
71
- await authClient.signOut();
87
+ const { error } = await authClient.signOut();
88
+ if (error) throw new Error(error.message || "Failed to sign out");
72
89
  setSessionHint(false);
73
- forgetSignedInData();
74
- router.push("/login");
90
+ await waitForSessionToDrop();
91
+ loadLoginPage();
75
92
  };
76
93
  const handleSendOtp = async (email) => {
77
94
  const { data, error } = await authClient.emailOtp.sendVerificationOtp({
@@ -1 +1 @@
1
- {"version":3,"file":"usePatternUsages.d.ts","sourceRoot":"","sources":["../../src/hooks/usePatternUsages.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mDAAmD;IACnD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,YAAY,EAAE,CAAA;IACtB,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,uBAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4EtC;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,iEA8BxD"}
1
+ {"version":3,"file":"usePatternUsages.d.ts","sourceRoot":"","sources":["../../src/hooks/usePatternUsages.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mDAAmD;IACnD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,YAAY,EAAE,CAAA;IACtB,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,uBAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4EtC;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,iEA8BxD"}
@@ -3,6 +3,7 @@ import { useQuery } from "@tanstack/react-query";
3
3
  import { useAuth } from "./useAuth.js";
4
4
  import { useTeam } from "./useTeam.js";
5
5
  import { withBasePath } from "../lib/base-path.js";
6
+ import { TEAM_ID_HEADER } from "../lib/api/client-headers.js";
6
7
  function usePatternUsages(patternId, options = {}) {
7
8
  var _a, _b, _c, _d, _e;
8
9
  const {
@@ -37,7 +38,7 @@ function usePatternUsages(patternId, options = {}) {
37
38
  "Content-Type": "application/json"
38
39
  };
39
40
  if (teamId) {
40
- headers["x-team-id"] = teamId;
41
+ headers[TEAM_ID_HEADER] = teamId;
41
42
  }
42
43
  const response = await fetch(withBasePath(url), { headers });
43
44
  if (!response.ok) {
@@ -81,7 +82,7 @@ function usePatternUsageCount(patternId, options = {}) {
81
82
  "Content-Type": "application/json"
82
83
  };
83
84
  if (teamId) {
84
- headers["x-team-id"] = teamId;
85
+ headers[TEAM_ID_HEADER] = teamId;
85
86
  }
86
87
  const response = await fetch(withBasePath(`/api/v1/patterns/${patternId}/usages?limit=1`), { headers });
87
88
  if (!response.ok) {
@@ -21,6 +21,8 @@ export interface ApiKeyValidationResult {
21
21
  auth?: ApiKeyAuth;
22
22
  error?: string;
23
23
  }
24
+ /** The API key validateApiKey accepted for this request, or null when none was validated. */
25
+ export declare function getValidatedApiKey(request: Request): ApiKeyAuth | null;
24
26
  /**
25
27
  * Valida una API Key desde el header Authorization o x-api-key
26
28
  */
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/lib/api/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO1C;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAEnF;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAoHrF;AA8CD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3D;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ5E;AAID;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAM/E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAMhF;AAiBD;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,UAAU;QAG1C,MAAM;WACH,MAAM;eACF,MAAM,GAAG,IAAI;cACd,MAAM,GAAG,IAAI;UACjB,MAAM;GAWjB;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAwBvE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,eAAe,EAAE,MAAM,EAAE,GACxB,OAAO,CAAC;IACT,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC,CAyED"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/lib/api/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO1C;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAEnF;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAQD,6FAA6F;AAC7F,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAEtE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA0GrF;AA8CD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3D;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ5E;AAID;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAM/E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAMhF;AAiBD;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,UAAU;QAG1C,MAAM;WACH,MAAM;eACF,MAAM,GAAG,IAAI;cACd,MAAM,GAAG,IAAI;UACjB,MAAM;GAWjB;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAwBvE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,eAAe,EAAE,MAAM,EAAE,GACxB,OAAO,CAAC;IACT,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC,CAyED"}
@@ -1,22 +1,19 @@
1
1
  import { queryOne } from "../db.js";
2
- import { ApiKeyManager } from "./keys.js";
2
+ import { ApiKeyManager, presentedApiKey } from "./keys.js";
3
3
  import { apiKeyCache, getCacheKey } from "./cache.js";
4
4
  import { TeamMemberService } from "../services/team-member.service.js";
5
5
  import { ScopeService } from "../services/scope.service.js";
6
6
  function hasScope(auth, requiredScope) {
7
7
  return auth.scopes.includes(requiredScope);
8
8
  }
9
+ const validatedKeys = /* @__PURE__ */ new WeakMap();
10
+ function getValidatedApiKey(request) {
11
+ return validatedKeys.get(request) ?? null;
12
+ }
9
13
  async function validateApiKey(request) {
10
14
  const startTime = Date.now();
11
15
  try {
12
- const authHeader = request.headers.get("Authorization");
13
- const xApiKeyHeader = request.headers.get("x-api-key");
14
- let apiKey = null;
15
- if (authHeader == null ? void 0 : authHeader.startsWith("Bearer ")) {
16
- apiKey = authHeader.substring(7);
17
- } else if (xApiKeyHeader) {
18
- apiKey = xApiKeyHeader;
19
- }
16
+ const apiKey = presentedApiKey(request.headers);
20
17
  if (!apiKey) {
21
18
  await constantTimeDelay(startTime);
22
19
  return null;
@@ -72,11 +69,13 @@ async function validateApiKey(request) {
72
69
  updateLastUsed(keyData.id).catch((error) => {
73
70
  console.error("Error updating API key last used:", error);
74
71
  });
75
- return {
72
+ const validated = {
76
73
  userId: keyData.userId,
77
74
  keyId: keyData.id,
78
75
  scopes: keyData.scopes || []
79
76
  };
77
+ validatedKeys.set(request, validated);
78
+ return validated;
80
79
  } catch (error) {
81
80
  console.error("Error validating API key:", error);
82
81
  await constantTimeDelay(startTime);
@@ -245,6 +244,7 @@ async function validateScopesForUser(userId, teamId, requestedScopes) {
245
244
  export {
246
245
  canCreateApiKeys,
247
246
  getApiKeyUser,
247
+ getValidatedApiKey,
248
248
  hasAllScopes,
249
249
  hasAnyScope,
250
250
  hasScope,
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The custom request headers core's own clients send to /api. The clients set them by these names and
3
+ * CORS_ALLOW_HEADERS (cors-response.ts) is built from this list, so a listed origin's preflight allows
4
+ * every header core's clients send. Client-safe: no imports.
5
+ */
6
+ export declare const TEAM_ID_HEADER = "x-team-id";
7
+ export declare const BUILDER_SOURCE_HEADER = "x-builder-source";
8
+ export declare const SIGNUP_INTENT_HEADER = "x-signup-intent";
9
+ export declare const VERIFY_FROM_UI_HEADER = "x-verify-from-ui";
10
+ export declare const CLIENT_REQUEST_HEADERS: readonly ["x-team-id", "x-builder-source", "x-signup-intent", "x-verify-from-ui"];
11
+ //# sourceMappingURL=client-headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-headers.d.ts","sourceRoot":"","sources":["../../../src/lib/api/client-headers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,cAAc,cAAc,CAAA;AACzC,eAAO,MAAM,qBAAqB,qBAAqB,CAAA;AACvD,eAAO,MAAM,oBAAoB,oBAAoB,CAAA;AACrD,eAAO,MAAM,qBAAqB,qBAAqB,CAAA;AAEvD,eAAO,MAAM,sBAAsB,mFAAgG,CAAA"}
@@ -0,0 +1,12 @@
1
+ const TEAM_ID_HEADER = "x-team-id";
2
+ const BUILDER_SOURCE_HEADER = "x-builder-source";
3
+ const SIGNUP_INTENT_HEADER = "x-signup-intent";
4
+ const VERIFY_FROM_UI_HEADER = "x-verify-from-ui";
5
+ const CLIENT_REQUEST_HEADERS = [TEAM_ID_HEADER, BUILDER_SOURCE_HEADER, SIGNUP_INTENT_HEADER, VERIFY_FROM_UI_HEADER];
6
+ export {
7
+ BUILDER_SOURCE_HEADER,
8
+ CLIENT_REQUEST_HEADERS,
9
+ SIGNUP_INTENT_HEADER,
10
+ TEAM_ID_HEADER,
11
+ VERIFY_FROM_UI_HEADER
12
+ };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * The client address of a request: the one place that decides it, for rate limits, audit logs,
3
+ * security notifications and every other reader in core.
4
+ *
5
+ * Which header can be trusted depends on what sits in front of the app, so the deployment names it:
6
+ *
7
+ * NEXTSPARK_CLIENT_IP_SOURCE=vercel x-vercel-forwarded-for, then x-real-ip (set by Vercel)
8
+ * NEXTSPARK_CLIENT_IP_SOURCE=cloudflare cf-connecting-ip (set by Cloudflare)
9
+ * NEXTSPARK_CLIENT_IP_SOURCE=header:<name> one header that your proxy sets, e.g. header:x-real-ip
10
+ * NEXTSPARK_CLIENT_IP_SOURCE=xff X-Forwarded-For, counting NEXTSPARK_TRUSTED_PROXY_HOPS
11
+ * (default 1) trusted proxies from the right
12
+ * NEXTSPARK_CLIENT_IP_SOURCE=none no client address: every request shares one bucket
13
+ *
14
+ * Unset keeps the order core always used (cf-connecting-ip, rightmost X-Forwarded-For, x-real-ip,
15
+ * true-client-ip), and production logs one warning saying what to set. Next.js gives route handlers
16
+ * no socket address, so 'none' cannot fall back to one.
17
+ * What to set per deployment: the upgrade note in CHANGELOG.md, and https://nextspark.dev/docs.
18
+ */
19
+ export declare const UNKNOWN_CLIENT_IP = "unknown";
20
+ export type ClientIpSource = {
21
+ kind: 'default';
22
+ } | {
23
+ kind: 'vercel';
24
+ } | {
25
+ kind: 'cloudflare';
26
+ } | {
27
+ kind: 'header';
28
+ header: string;
29
+ } | {
30
+ kind: 'xff';
31
+ hops: number;
32
+ } | {
33
+ kind: 'none';
34
+ };
35
+ type Env = Record<string, string | undefined>;
36
+ /** Reads the setting. Throws on a value it does not understand: a typo must not silently trust a header. */
37
+ export declare function getClientIpSource(env?: Env): ClientIpSource;
38
+ /** The client address of a request, from the source the deployment configured (getClientIpSource). */
39
+ export declare function getClientIp(headers: Headers, env?: Env): string;
40
+ /**
41
+ * getClientIp for readers that only record the address (audit rows, the new-device fingerprint): an invalid
42
+ * setting records UNKNOWN_CLIENT_IP instead of throwing, so the row is still written. Rate limits use getClientIp,
43
+ * which throws.
44
+ */
45
+ export declare function getRecordedClientIp(headers: Headers, env?: Env): string;
46
+ /**
47
+ * The headers Better Auth's own rate limiter should read (advanced.ipAddress.ipAddressHeaders), or undefined
48
+ * to keep its default. Better Auth trusts only a single-valued header, so 'xff' keeps its default; 'none' names no
49
+ * header, so Better Auth counts every request to a path in one shared bucket.
50
+ */
51
+ export declare function getBetterAuthIpHeaders(env?: Env): string[] | undefined;
52
+ /**
53
+ * Logs once per process when the client address source is invalid (in every environment) or, in production
54
+ * only, not set. Called at server start (logAuthReadinessAtStartup) and again on first use, for projects whose
55
+ * instrumentation does not run it; the flag lives on globalThis so both bundles share it.
56
+ */
57
+ export declare function warnClientIpSourceAtStartup(env?: Env): void;
58
+ export {};
59
+ //# sourceMappingURL=client-ip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-ip.d.ts","sourceRoot":"","sources":["../../../src/lib/api/client-ip.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,eAAO,MAAM,iBAAiB,YAAY,CAAA;AAE1C,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpB,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;AAI7C,4GAA4G;AAC5G,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,GAAiB,GAAG,cAAc,CAiBxE;AAWD,sGAAsG;AACtG,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,GAAE,GAAiB,GAAG,MAAM,CA2B5E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,GAAE,GAAiB,GAAG,MAAM,CAMpF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,GAAE,GAAiB,GAAG,MAAM,EAAE,GAAG,SAAS,CAWnF;AAID;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,GAAE,GAAiB,GAAG,IAAI,CAkBxE"}
@@ -0,0 +1,91 @@
1
+ const UNKNOWN_CLIENT_IP = "unknown";
2
+ const HEADER_NAME = /^[a-z0-9!#$%&'*+.^_`|~-]+$/;
3
+ function getClientIpSource(env = process.env) {
4
+ var _a, _b;
5
+ const raw = (_a = env.NEXTSPARK_CLIENT_IP_SOURCE) == null ? void 0 : _a.trim().toLowerCase();
6
+ if (!raw) return { kind: "default" };
7
+ if (raw === "vercel" || raw === "cloudflare" || raw === "none") return { kind: raw };
8
+ if (raw === "xff") {
9
+ const hopsRaw = ((_b = env.NEXTSPARK_TRUSTED_PROXY_HOPS) == null ? void 0 : _b.trim()) || "1";
10
+ const hops = Number(hopsRaw);
11
+ if (!/^\d+$/.test(hopsRaw) || hops < 1) {
12
+ throw new Error("[client-ip] NEXTSPARK_TRUSTED_PROXY_HOPS must be a whole number of 1 or more");
13
+ }
14
+ return { kind: "xff", hops };
15
+ }
16
+ if (raw.startsWith("header:")) {
17
+ const header = raw.slice("header:".length).trim();
18
+ if (HEADER_NAME.test(header)) return { kind: "header", header };
19
+ }
20
+ throw new Error("[client-ip] NEXTSPARK_CLIENT_IP_SOURCE must be vercel, cloudflare, xff, none or header:<name>");
21
+ }
22
+ function entries(value) {
23
+ return value ? value.split(",").map((ip) => ip.trim()).filter(Boolean) : [];
24
+ }
25
+ function lastEntry(value) {
26
+ return entries(value).at(-1) ?? null;
27
+ }
28
+ function getClientIp(headers, env = process.env) {
29
+ warnClientIpSourceAtStartup(env);
30
+ const source = getClientIpSource(env);
31
+ switch (source.kind) {
32
+ case "vercel":
33
+ return lastEntry(headers.get("x-vercel-forwarded-for")) ?? lastEntry(headers.get("x-real-ip")) ?? UNKNOWN_CLIENT_IP;
34
+ case "cloudflare":
35
+ return lastEntry(headers.get("cf-connecting-ip")) ?? UNKNOWN_CLIENT_IP;
36
+ case "header":
37
+ return lastEntry(headers.get(source.header)) ?? UNKNOWN_CLIENT_IP;
38
+ case "xff": {
39
+ const ips = entries(headers.get("x-forwarded-for"));
40
+ return ips.length >= source.hops ? ips[ips.length - source.hops] : UNKNOWN_CLIENT_IP;
41
+ }
42
+ case "none":
43
+ return UNKNOWN_CLIENT_IP;
44
+ default:
45
+ return headers.get("cf-connecting-ip") || lastEntry(headers.get("x-forwarded-for")) || headers.get("x-real-ip") || headers.get("true-client-ip") || UNKNOWN_CLIENT_IP;
46
+ }
47
+ }
48
+ function getRecordedClientIp(headers, env = process.env) {
49
+ try {
50
+ return getClientIp(headers, env);
51
+ } catch {
52
+ return UNKNOWN_CLIENT_IP;
53
+ }
54
+ }
55
+ function getBetterAuthIpHeaders(env = process.env) {
56
+ try {
57
+ const source = getClientIpSource(env);
58
+ if (source.kind === "vercel") return ["x-vercel-forwarded-for", "x-real-ip"];
59
+ if (source.kind === "cloudflare") return ["cf-connecting-ip"];
60
+ if (source.kind === "header") return [source.header];
61
+ if (source.kind === "none") return [];
62
+ } catch {
63
+ }
64
+ return void 0;
65
+ }
66
+ const WARNED = /* @__PURE__ */ Symbol.for("nextspark.clientIpSourceWarned");
67
+ function warnClientIpSourceAtStartup(env = process.env) {
68
+ const state = globalThis;
69
+ if (state[WARNED]) return;
70
+ let source;
71
+ try {
72
+ source = getClientIpSource(env);
73
+ } catch (error) {
74
+ state[WARNED] = true;
75
+ console.error(error.message);
76
+ return;
77
+ }
78
+ if (source.kind !== "default" || env.NODE_ENV !== "production") return;
79
+ state[WARNED] = true;
80
+ console.warn(
81
+ "[client-ip] NEXTSPARK_CLIENT_IP_SOURCE is not set, so rate limits and audit logs read the client address from request headers in a fixed order. Set it for your deployment: vercel, cloudflare, xff (with NEXTSPARK_TRUSTED_PROXY_HOPS) or header:<name>; none if nothing in front sets a client address."
82
+ );
83
+ }
84
+ export {
85
+ UNKNOWN_CLIENT_IP,
86
+ getBetterAuthIpHeaders,
87
+ getClientIp,
88
+ getClientIpSource,
89
+ getRecordedClientIp,
90
+ warnClientIpSourceAtStartup
91
+ };
@@ -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"}