@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
@@ -1,11 +1,15 @@
1
1
  import { NextResponse } from "next/server";
2
2
  import { unstable_rethrow } from "next/navigation";
3
- import { getRateLimitForScopes } from "./keys.js";
3
+ import { getRateLimitForScopes, presentedApiKey } from "./keys.js";
4
+ import { validateApiKey } from "./auth.js";
4
5
  import { rateLimitCache, getCacheKey } from "./cache.js";
6
+ import { getClientIp } from "./client-ip.js";
5
7
  import {
6
8
  checkRateLimit as checkRedisRateLimit,
7
9
  maybeRedisConfigured
8
10
  } from "../rate-limit-redis.js";
11
+ import { checkRequestOrigin } from "./request-origin.js";
12
+ import { withCors } from "./cors-response.js";
9
13
  function checkRateLimit(identifier, limit = 1e3, windowMs = 6e4) {
10
14
  const now = Date.now();
11
15
  const cacheKey = getCacheKey("rate_limit", identifier);
@@ -151,20 +155,11 @@ function addRateLimitHeaders(response, keyId, scopes) {
151
155
  function withRateLimit(handler) {
152
156
  return async (request, ...args) => {
153
157
  try {
154
- const keyId = request.headers.get("x-api-key-id");
155
- const scopesHeader = request.headers.get("x-api-scopes");
156
- if (!keyId || !scopesHeader) {
158
+ const auth = presentedApiKey(request.headers) ? await validateApiKey(request) : null;
159
+ if (!auth) {
157
160
  return handler(request, ...args);
158
161
  }
159
- let scopes = [];
160
- try {
161
- const parsed = JSON.parse(scopesHeader);
162
- if (Array.isArray(parsed)) {
163
- scopes = parsed.filter((s) => typeof s === "string");
164
- }
165
- } catch {
166
- console.warn("[RateLimit] Invalid scopes header format");
167
- }
162
+ const { keyId, scopes } = auth;
168
163
  const rateLimitResponse = applyRateLimit(request, keyId, scopes);
169
164
  if (rateLimitResponse) {
170
165
  return rateLimitResponse;
@@ -207,27 +202,6 @@ function getAllRateLimitStats() {
207
202
  function getRateLimitCacheStats() {
208
203
  return rateLimitCache.getStats();
209
204
  }
210
- function getClientIp(request) {
211
- const cfIp = request.headers.get("cf-connecting-ip");
212
- if (cfIp) return cfIp;
213
- const forwardedFor = request.headers.get("x-forwarded-for");
214
- if (forwardedFor) {
215
- const ips = forwardedFor.split(",").map((ip) => ip.trim()).filter(Boolean);
216
- if (ips.length > 0) return ips[ips.length - 1];
217
- }
218
- const realIp = request.headers.get("x-real-ip");
219
- if (realIp) return realIp;
220
- const trueClientIp = request.headers.get("true-client-ip");
221
- if (trueClientIp) return trueClientIp;
222
- return "unknown";
223
- }
224
- function getUserIdentifier(request) {
225
- const apiKey = request.headers.get("x-api-key");
226
- if (apiKey) {
227
- return `apikey:${apiKey.substring(0, 16)}`;
228
- }
229
- return null;
230
- }
231
205
  let rateLimitDisabledWarningLogged = false;
232
206
  function isRateLimitingDisabled() {
233
207
  const disabled = process.env.DISABLE_RATE_LIMITING === "true";
@@ -238,13 +212,14 @@ function isRateLimitingDisabled() {
238
212
  return disabled;
239
213
  }
240
214
  function withRateLimitTier(handler, tier = "api") {
241
- return async (request, ...args) => {
215
+ const limited = async (request, ...args) => {
216
+ const checked = checkRequestOrigin(request);
217
+ if (checked instanceof NextResponse) return checked;
218
+ request = checked;
242
219
  if (isRateLimitingDisabled()) {
243
220
  return handler(request, ...args);
244
221
  }
245
- const userIdentifier = getUserIdentifier(request);
246
- const clientIp = getClientIp(request);
247
- const identifier = userIdentifier ? `${tier}:${userIdentifier}` : `${tier}:ip:${clientIp}`;
222
+ const identifier = `${tier}:ip:${getClientIp(request.headers)}`;
248
223
  const rateLimitResult = await checkDistributedRateLimit(identifier, tier);
249
224
  if (!rateLimitResult.allowed) {
250
225
  return createRateLimitErrorResponse(rateLimitResult);
@@ -255,6 +230,10 @@ function withRateLimitTier(handler, tier = "api") {
255
230
  response.headers.set("X-RateLimit-Reset", rateLimitResult.resetTime.toString());
256
231
  return response;
257
232
  };
233
+ return async (request, ...args) => {
234
+ const response = await limited(request, ...args);
235
+ return tier === "webhook" ? response : withCors(response, request);
236
+ };
258
237
  }
259
238
  export {
260
239
  addRateLimitHeaders,
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Request origin check for cookie-authenticated writes.
3
+ *
4
+ * A POST/PUT/PATCH/DELETE that authenticates with the session cookie must come
5
+ * from an origin the app trusts: its own (NEXT_PUBLIC_APP_URL / BETTER_AUTH_URL)
6
+ * or one in the list Better Auth already trusts for sign-in (see
7
+ * getTrustedOrigins). withRateLimitTier runs it before every handler it wraps.
8
+ * Under the admin and developer areas (isAppOnlyCorsPath) only the app's own
9
+ * origin is trusted, plus, outside production, the request's own origin when it
10
+ * is a private-network address (#170); no other listed origin.
11
+ *
12
+ * What passes without a trusted origin, and why:
13
+ * - Reads (GET/HEAD/OPTIONS).
14
+ * - Requests without the session cookie: there is no session for them to use.
15
+ * - Requests that present an API key (`Authorization: Bearer sk_...` or
16
+ * x-api-key, in the API-key format). They are let through without their
17
+ * session cookie, so the handler can authenticate them only by the key: a key
18
+ * that does not validate gets 401, never the cookie's session. Any other
19
+ * Authorization value is not a credential here, and the check applies. Handlers
20
+ * should read the session from the request they are given, not from
21
+ * next/headers.
22
+ * - Requests with neither Origin nor Referer, unless their body is one an HTML
23
+ * form can send. Browsers send Origin on every write, so these come from
24
+ * native or server-side clients; requiring a non-form content type keeps
25
+ * a body without origin information from ever being read as a form post.
26
+ */
27
+ import { NextRequest, NextResponse } from 'next/server';
28
+ /**
29
+ * Checks a write's origin. Returns a 403 response when a cookie-authenticated
30
+ * write does not come from a trusted origin. Otherwise returns the request the
31
+ * handler should get: the same request, or, for a write that would be refused
32
+ * but presents an API key, a copy without its session cookie.
33
+ */
34
+ export declare function checkRequestOrigin(request: NextRequest): NextResponse | NextRequest;
35
+ //# sourceMappingURL=request-origin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-origin.d.ts","sourceRoot":"","sources":["../../../src/lib/api/request-origin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AA+DvD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,YAAY,GAAG,WAAW,CAoBnF"}
@@ -0,0 +1,69 @@
1
+ import { NextRequest, NextResponse } from "next/server";
2
+ import { APP_CONFIG_MERGED } from "../config/index.js";
3
+ import { hasSessionCookie } from "../auth/session-hint.js";
4
+ import { getTrustedOrigins, isOriginAllowed, isPrivateLanOrigin, normalizeCorsEnvironment, normalizeOrigin } from "../utils/cors.js";
5
+ import { ApiKeyManager, presentedApiKey } from "./keys.js";
6
+ import { appOrigins, isAppOnlyCorsPath, requestPathname } from "./cors-response.js";
7
+ const WRITE_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
8
+ const FORM_CONTENT_TYPES = /* @__PURE__ */ new Set(["text/plain", "application/x-www-form-urlencoded", "multipart/form-data"]);
9
+ function requestOrigin(headers) {
10
+ const origin = headers.get("origin");
11
+ if (origin) return origin;
12
+ const referer = headers.get("referer");
13
+ if (!referer) return null;
14
+ try {
15
+ return new URL(referer).origin;
16
+ } catch {
17
+ return "null";
18
+ }
19
+ }
20
+ const SESSION_COOKIE_NAME = /^(?:__Secure-)?better-auth[.-]/;
21
+ function withoutSessionCookies(request) {
22
+ const headers = {};
23
+ request.headers.forEach((value, key) => {
24
+ headers[key] = value;
25
+ });
26
+ const kept = (headers.cookie ?? "").split(";").map((part) => part.trim()).filter((part) => part && !SESSION_COOKIE_NAME.test(part));
27
+ if (kept.length) headers.cookie = kept.join("; ");
28
+ else delete headers.cookie;
29
+ return new NextRequest(request.url, {
30
+ method: request.method,
31
+ headers,
32
+ body: request.body,
33
+ signal: request.signal,
34
+ nextConfig: { basePath: request.nextUrl.basePath }
35
+ });
36
+ }
37
+ function isTrustedWriteOrigin(request, origin) {
38
+ const path = requestPathname(request);
39
+ if (path !== void 0 && isAppOnlyCorsPath(path)) {
40
+ const lan = normalizeCorsEnvironment(process.env.NODE_ENV || "development") !== "production" && isPrivateLanOrigin(origin);
41
+ return lan || appOrigins().includes(origin);
42
+ }
43
+ return isOriginAllowed(origin, getTrustedOrigins(APP_CONFIG_MERGED, origin)) !== null;
44
+ }
45
+ function refusal(error, code) {
46
+ return NextResponse.json({ success: false, error, code }, { status: 403 });
47
+ }
48
+ function checkRequestOrigin(request) {
49
+ if (!WRITE_METHODS.has(request.method.toUpperCase())) return request;
50
+ const headers = request.headers;
51
+ if (!hasSessionCookie(headers.get("cookie"))) return request;
52
+ let refused;
53
+ const origin = requestOrigin(headers);
54
+ if (origin === null) {
55
+ const contentType = (headers.get("content-type") ?? "").split(";")[0].trim().toLowerCase();
56
+ if (!FORM_CONTENT_TYPES.has(contentType)) return request;
57
+ refused = refusal("This request needs an Origin header", "ORIGIN_REQUIRED");
58
+ } else {
59
+ const normalized = normalizeOrigin(origin);
60
+ if (isTrustedWriteOrigin(request, normalized)) return request;
61
+ refused = refusal("Request origin not allowed", "ORIGIN_NOT_ALLOWED");
62
+ }
63
+ const apiKey = presentedApiKey(headers);
64
+ if (apiKey && ApiKeyManager.validateKeyFormat(apiKey)) return withoutSessionCookies(request);
65
+ return refused;
66
+ }
67
+ export {
68
+ checkRequestOrigin
69
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Leaves for the login page with a full page load, base path included. Sign-out and the dashboard guards use it.
3
+ *
4
+ * With Cache Components a client navigation out of the dashboard leaves it mounted, hidden, with its last render
5
+ * ("signed out"); shown again after the next sign-in, its effects act on that and send the user back to /login. The
6
+ * login page comes back as the form the last sign-in left. Loading the page drops the React tree, the session store
7
+ * and the query cache together, whichever way the session ended (this tab's sign-out, another tab's, an expiry).
8
+ */
9
+ export declare function loadLoginPage(): void;
10
+ //# sourceMappingURL=load-login-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-login-page.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/load-login-page.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAEpC"}
@@ -0,0 +1,7 @@
1
+ import { withBasePath } from "../base-path.js";
2
+ function loadLoginPage() {
3
+ window.location.assign(withBasePath("/login"));
4
+ }
5
+ export {
6
+ loadLoginPage
7
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-readiness.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/runtime-readiness.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAGpB,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAElE,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,aAAa,CAAA;AAEpB,KAAK,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;AAE5D,MAAM,WAAW,2BAA2B;IAC1C,UAAU,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,GAAG,WAAW,GAAG,kBAAkB,CAAC,GAAG,IAAI,CAAA;IAClF,GAAG,CAAC,EAAE,kBAAkB,CAAA;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,kFAAkF;IAClF,wBAAwB,EAAE,OAAO,CAAA;IACjC,mFAAmF;IACnF,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,GAAG,aAAa,CAAA;IAC/B,gBAAgB,EAAE,eAAe,EAAE,CAAA;IACnC,YAAY,EAAE,sBAAsB,CAAA;CACrC;AAaD,qEAAqE;AACrE,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,2BAAgC,GAAG,mBAAmB,CAEtG;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,2BAAgC,GAAG,IAAI,CAazF;AAED,sFAAsF;AACtF,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,2BAAgC,GAAG,mBAAmB,CAYrG;AAiBD,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,2BAAgC,GAAG,OAAO,CAE1F;AAED,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,2BAAgC,GAAG,OAAO,CAE3F;AAkDD;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CA4E1B;AAED,sFAAsF;AACtF,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,EAChC,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,QAAQ,CAAC,CAGnB"}
1
+ {"version":3,"file":"runtime-readiness.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/runtime-readiness.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAGpB,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAGlE,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,aAAa,CAAA;AAEpB,KAAK,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;AAE5D,MAAM,WAAW,2BAA2B;IAC1C,UAAU,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,GAAG,WAAW,GAAG,kBAAkB,CAAC,GAAG,IAAI,CAAA;IAClF,GAAG,CAAC,EAAE,kBAAkB,CAAA;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,kFAAkF;IAClF,wBAAwB,EAAE,OAAO,CAAA;IACjC,mFAAmF;IACnF,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,GAAG,aAAa,CAAA;IAC/B,gBAAgB,EAAE,eAAe,EAAE,CAAA;IACnC,YAAY,EAAE,sBAAsB,CAAA;CACrC;AAaD,qEAAqE;AACrE,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,2BAAgC,GAAG,mBAAmB,CAEtG;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,2BAAgC,GAAG,IAAI,CAezF;AAED,sFAAsF;AACtF,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,2BAAgC,GAAG,mBAAmB,CAYrG;AAiBD,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,2BAAgC,GAAG,OAAO,CAE1F;AAED,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,2BAAgC,GAAG,OAAO,CAE3F;AAkDD;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CA4E1B;AAED,sFAAsF;AACtF,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,EAChC,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,QAAQ,CAAC,CAGnB"}
@@ -1,6 +1,7 @@
1
1
  import "server-only";
2
2
  import { AUTH_CONFIG } from "../config/index.js";
3
3
  import { isPasswordLoginEnabled } from "./auth-methods.js";
4
+ import { warnClientIpSourceAtStartup } from "../api/client-ip.js";
4
5
  import {
5
6
  authReadinessConfigurationFromEnv,
6
7
  evaluateAuthReadiness
@@ -19,6 +20,7 @@ function getRuntimeAuthReadiness(options = {}) {
19
20
  return evaluateAuthReadiness(runtimeInput(options));
20
21
  }
21
22
  function logAuthReadinessAtStartup(options = {}) {
23
+ warnClientIpSourceAtStartup(options.env ?? process.env);
22
24
  try {
23
25
  const env = options.env ?? process.env;
24
26
  if (env.NODE_ENV !== "production") return;
@@ -40,13 +40,6 @@ export declare function ipToNetworkKey(ip: string | null | undefined): string;
40
40
  * @returns hex sha256 of `normalizedUA|ipNetworkKey`
41
41
  */
42
42
  export declare function computeDeviceFingerprint(ua: string | null, ip: string | null): string;
43
- /**
44
- * Extract the best-effort client IP from request headers.
45
- *
46
- * Strategy mirrors the rate-limiter (see lib/api/rate-limit.ts):
47
- * Cloudflare > rightmost x-forwarded-for > x-real-ip > true-client-ip > 'unknown'
48
- * The rightmost x-forwarded-for entry is the one appended by the last (trusted)
49
- * proxy, so it is the hardest for a client to spoof.
50
- */
43
+ /** The client address of a request (lib/api/client-ip, the same one rate limits and audit logs use); unknown on an invalid setting. */
51
44
  export declare function extractClientIp(headers: Headers): string;
52
45
  //# sourceMappingURL=device-fingerprint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"device-fingerprint.d.ts","sourceRoot":"","sources":["../../../../src/lib/auth/security-notifications/device-fingerprint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAQxE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAiBpE;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,MAAM,GAAG,IAAI,EACjB,EAAE,EAAE,MAAM,GAAG,IAAI,GAChB,MAAM,CAGR;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAoBxD"}
1
+ {"version":3,"file":"device-fingerprint.d.ts","sourceRoot":"","sources":["../../../../src/lib/auth/security-notifications/device-fingerprint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAQxE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAiBpE;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,MAAM,GAAG,IAAI,EACjB,EAAE,EAAE,MAAM,GAAG,IAAI,GAChB,MAAM,CAGR;AAED,uIAAuI;AACvI,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAExD"}
@@ -1,4 +1,5 @@
1
1
  import { createHash } from "crypto";
2
+ import { getRecordedClientIp } from "../../api/client-ip.js";
2
3
  function normalizeUserAgent(ua) {
3
4
  if (!ua) return "";
4
5
  return ua.toLowerCase().trim().replace(/\s+/g, " ").replace(/(\d+)\.(\d+)(?:\.\d+)+/g, "$1.$2");
@@ -21,18 +22,7 @@ function computeDeviceFingerprint(ua, ip) {
21
22
  return createHash("sha256").update(material).digest("hex");
22
23
  }
23
24
  function extractClientIp(headers) {
24
- const cfIp = headers.get("cf-connecting-ip");
25
- if (cfIp) return cfIp;
26
- const forwardedFor = headers.get("x-forwarded-for");
27
- if (forwardedFor) {
28
- const ips = forwardedFor.split(",").map((v) => v.trim()).filter(Boolean);
29
- if (ips.length > 0) return ips[ips.length - 1];
30
- }
31
- const realIp = headers.get("x-real-ip");
32
- if (realIp) return realIp;
33
- const trueClientIp = headers.get("true-client-ip");
34
- if (trueClientIp) return trueClientIp;
35
- return "unknown";
25
+ return getRecordedClientIp(headers);
36
26
  }
37
27
  export {
38
28
  computeDeviceFingerprint,
@@ -1,5 +1,5 @@
1
1
  import { sendResetPasswordEmail, sendVerifyEmail } from "./email/send.js";
2
- import { I18N_CONFIG } from "./config/index.js";
2
+ import { I18N_CONFIG, APP_NAME } from "./config/index.js";
3
3
  function requireEmail(user) {
4
4
  if (!user.email) throw new Error("Cannot send an auth email without an email address");
5
5
  return user.email;
@@ -10,7 +10,7 @@ async function sendResetPasswordCallback({ user, url, token: _token }, emailServ
10
10
  const template = await sendResetPasswordEmail({
11
11
  userName: user.firstName || "",
12
12
  resetUrl: url,
13
- appName: process.env.NEXT_PUBLIC_APP_NAME || "Your App",
13
+ appName: process.env.NEXT_PUBLIC_APP_NAME || APP_NAME,
14
14
  expiresIn: "1 hour"
15
15
  }, I18N_CONFIG.defaultLocale);
16
16
  const response = await emailService.send({
@@ -32,7 +32,7 @@ async function sendVerificationEmailCallback({ user, url, token: _token }, email
32
32
  const template = await sendVerifyEmail({
33
33
  userName: user.firstName || "",
34
34
  verificationUrl: url,
35
- appName: process.env.NEXT_PUBLIC_APP_NAME || "Your App"
35
+ appName: process.env.NEXT_PUBLIC_APP_NAME || APP_NAME
36
36
  }, I18N_CONFIG.defaultLocale);
37
37
  const response = await emailService.send({
38
38
  to: email,
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAUA,OAAO,EAAgF,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAkBvH;;;;;;;;;;;;;GAaG;AACH,wBAAsB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQlF;AAED;;;;;;;;;GASG;AACH,wBAAsB,6BAA6B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEnF;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsHD,eAAO,MAAM,IAAI,qEAkXf,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AACjD,MAAM,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,kBAAkB,EAAE,QAAQ,EAAE,CAAC;CAC/C,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5B,IAAI,EAAE,WAAW,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAO9B"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAUA,OAAO,EAA0F,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAmBjI;;;;;;;;;;;;;GAaG;AACH,wBAAsB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQlF;AAED;;;;;;;;;GASG;AACH,wBAAsB,6BAA6B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEnF;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAuHD,eAAO,MAAM,IAAI,qEAiXf,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AACjD,MAAM,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,kBAAkB,EAAE,QAAQ,EAAE,CAAC;CAC/C,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5B,IAAI,EAAE,WAAW,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAO9B"}
package/dist/lib/auth.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  sendOtpVerificationEmail
9
9
  } from "./email/send.js";
10
10
  import { sendResetPasswordCallback, sendVerificationEmailCallback } from "./auth-email-callbacks.js";
11
- import { I18N_CONFIG, USER_ROLES_CONFIG, TEAMS_CONFIG, AUTH_CONFIG, APP_CONFIG_MERGED } from "./config/index.js";
11
+ import { I18N_CONFIG, USER_ROLES_CONFIG, TEAMS_CONFIG, AUTH_CONFIG, APP_CONFIG_MERGED, APP_NAME } from "./config/index.js";
12
12
  import { getUserFlags } from "./services/user-flags.service.js";
13
13
  import { TeamService } from "./services/team.service.js";
14
14
  import { TeamMemberService } from "./services/team-member.service.js";
@@ -19,8 +19,9 @@ import { resolveSessionConfig } from "./auth/session-config.js";
19
19
  import { resolveOtpConfig } from "./auth/otp-config.js";
20
20
  import { isPasswordLoginEnabled } from "./auth/auth-methods.js";
21
21
  import { isRuntimeEmailAvailable, isRuntimeGoogleAvailable } from "./auth/runtime-readiness.js";
22
- import { getCorsOrigins, isPrivateLanOrigin, normalizeCorsEnvironment } from "./utils/cors.js";
22
+ import { getTrustedOrigins } from "./utils/cors.js";
23
23
  import { withBasePath } from "./base-path.js";
24
+ import { getBetterAuthIpHeaders } from "./api/client-ip.js";
24
25
  async function hasPendingInvitationForEmail(email) {
25
26
  const row = await queryOne(
26
27
  `SELECT id FROM "team_invitations"
@@ -34,6 +35,7 @@ async function shouldSkipTeamCreationForUser(email) {
34
35
  return shouldSkipTeamCreation() || await hasPendingInvitationForEmail(email);
35
36
  }
36
37
  const isProd = process.env.NODE_ENV === "production";
38
+ const betterAuthIpHeaders = getBetterAuthIpHeaders();
37
39
  const baseUrl = process.env.BETTER_AUTH_URL || process.env.NEXT_PUBLIC_APP_URL || "http://localhost:5173";
38
40
  const getEmailService = () => EmailFactory.create();
39
41
  const databaseUrl = process.env.DATABASE_SERVICE_URL || process.env.DATABASE_URL;
@@ -206,17 +208,7 @@ const auth = betterAuth({
206
208
  // adding a wildcard entry (e.g. "https://*.vercel.app") to
207
209
  // api.cors.additionalOrigins — better-auth's own trustedOrigins matching
208
210
  // already supports the same wildcard syntax as isOriginAllowed() above.
209
- trustedOrigins: async (request) => {
210
- const origins = getCorsOrigins(APP_CONFIG_MERGED);
211
- if (normalizeCorsEnvironment(process.env.NODE_ENV || "development") === "production") {
212
- return origins;
213
- }
214
- const requestOrigin = request == null ? void 0 : request.headers.get("origin");
215
- if (requestOrigin && isPrivateLanOrigin(requestOrigin)) {
216
- return [...origins, requestOrigin];
217
- }
218
- return origins;
219
- },
211
+ trustedOrigins: async (request) => getTrustedOrigins(APP_CONFIG_MERGED, request == null ? void 0 : request.headers.get("origin")),
220
212
  // Redirect auth errors to our custom error page instead of Better Auth's default.
221
213
  // Better Auth redirects to this path as-is, outside the Next.js router.
222
214
  onAPIError: {
@@ -235,7 +227,7 @@ const auth = betterAuth({
235
227
  email,
236
228
  otp,
237
229
  type,
238
- appName: process.env.NEXT_PUBLIC_APP_NAME || "Your App",
230
+ appName: process.env.NEXT_PUBLIC_APP_NAME || APP_NAME,
239
231
  expiresIn: otpConfig.expiresIn
240
232
  }, I18N_CONFIG.defaultLocale);
241
233
  await getEmailService().send({ to: email, ...template });
@@ -249,6 +241,12 @@ const auth = betterAuth({
249
241
  nextCookies()
250
242
  // MUST be the last plugin for Next.js cookie handling
251
243
  ],
244
+ // The proxy reads the session on every request; that lookup only reads the
245
+ // caller's own signed cookie, so it is kept out of the shared auth rate limit.
246
+ // The default limits (sign-in, sign-up, OTP, ...) stay.
247
+ rateLimit: {
248
+ customRules: { "/get-session": false }
249
+ },
252
250
  session: {
253
251
  // Configurable per theme via `auth.session` in app.config.ts (defaults:
254
252
  // 7 days / renewed daily / 5-minute cookie cache).
@@ -406,6 +404,9 @@ const auth = betterAuth({
406
404
  },
407
405
  // Removed additionalFields - will use standard name and image fields
408
406
  advanced: {
407
+ // Better Auth's own rate limiter reads the client address from the header NEXTSPARK_CLIENT_IP_SOURCE
408
+ // names (lib/api/client-ip); unset, 'xff' and 'none' keep Better Auth's default.
409
+ ...betterAuthIpHeaders ? { ipAddress: { ipAddressHeaders: betterAuthIpHeaders } } : {},
409
410
  // Cross-subdomain session cookies (opt-in via env).
410
411
  //
411
412
  // When an app serves tenants on subdomains (e.g. `<tenant>.example.com`)
@@ -1 +1 @@
1
- {"version":3,"file":"config-client.d.ts","sourceRoot":"","sources":["../../../src/lib/config/config-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAuCH,eAAO,MAAM,iBAAiB,qBAAe,CAAA;AAC7C,eAAO,MAAM,WAAW,KAAyB,CAAA;AACjD,eAAO,MAAM,QAAQ,KAA6B,CAAA;AAClD,eAAO,MAAM,WAAW,KAAgC,CAAA;AACxD,eAAO,MAAM,WAAW,KAAyB,CAAA;AACjD,eAAO,MAAM,UAAU,KAAwB,CAAA;AAC/C,eAAO,MAAM,YAAY,KAA0B,CAAA;AACnD,eAAO,MAAM,iBAAiB,KAA8B,CAAA;AAI5D,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAqE,CAAA;AAClG,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAA0B,CAAA;AACpD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAA4B,CAAA;AAExD,eAAO,MAAM,qBAAqB,GAAI,UAAU,MAAM,KAAG,OACP,CAAA;AAElD,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED,eAAO,MAAM,uBAAuB,QAAO,mBAAmB,EAClB,CAAA;AAE5C,eAAO,MAAM,sBAAsB,GAAI,SAAS,MAAM,KAAG,OACP,CAAA;AAElD,eAAO,MAAM,sBAAsB,GAAI,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,KAAG,CAAC,GAAG,SACV,CAAA;AAGhF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA"}
1
+ {"version":3,"file":"config-client.d.ts","sourceRoot":"","sources":["../../../src/lib/config/config-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAuCH,eAAO,MAAM,iBAAiB,qBAAe,CAAA;AAC7C,eAAO,MAAM,WAAW,KAAyB,CAAA;AACjD,eAAO,MAAM,QAAQ,KAAiE,CAAA;AACtF,eAAO,MAAM,WAAW,KAAgC,CAAA;AACxD,eAAO,MAAM,WAAW,KAAyB,CAAA;AACjD,eAAO,MAAM,UAAU,KAAwB,CAAA;AAC/C,eAAO,MAAM,YAAY,KAA0B,CAAA;AACnD,eAAO,MAAM,iBAAiB,KAA8B,CAAA;AAI5D,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAqE,CAAA;AAClG,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAA0B,CAAA;AACpD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAA4B,CAAA;AAExD,eAAO,MAAM,qBAAqB,GAAI,UAAU,MAAM,KAAG,OACP,CAAA;AAElD,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED,eAAO,MAAM,uBAAuB,QAAO,mBAAmB,EAClB,CAAA;AAE5C,eAAO,MAAM,sBAAsB,GAAI,SAAS,MAAM,KAAG,OACP,CAAA;AAElD,eAAO,MAAM,sBAAsB,GAAI,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,KAAG,CAAC,GAAG,SACV,CAAA;AAGhF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA"}
@@ -34,7 +34,7 @@ if ((_a = DEFAULT_APP_CONFIG.teams) == null ? void 0 : _a.roles) {
34
34
  }
35
35
  const APP_CONFIG_MERGED = mergedConfig;
36
36
  const I18N_CONFIG = APP_CONFIG_MERGED.i18n;
37
- const APP_NAME = APP_CONFIG_MERGED.app.name;
37
+ const APP_NAME = process.env.NEXT_PUBLIC_APP_NAME || APP_CONFIG_MERGED.app.name;
38
38
  const APP_VERSION = APP_CONFIG_MERGED.app.version;
39
39
  const AUTH_CONFIG = APP_CONFIG_MERGED.auth;
40
40
  const API_CONFIG = APP_CONFIG_MERGED.api;
@@ -1 +1 @@
1
- {"version":3,"file":"config-sync.d.ts","sourceRoot":"","sources":["../../../src/lib/config/config-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA0LH,eAAO,MAAM,iBAAiB,KAAkB,CAAA;AAChD,eAAO,MAAM,gBAAgB,KAAwB,CAAA;AACrD,eAAO,MAAM,UAAU,6BAAkB,CAAA;AAGzC,eAAO,MAAM,iBAAiB,KAA0C,CAAA;AACxE,eAAO,MAAM,cAAc,KAAuC,CAAA;AAClE,eAAO,MAAM,eAAe,KAA6C,CAAA;AACzE,eAAO,MAAM,YAAY,KAA0C,CAAA;AACnE,eAAO,MAAM,QAAQ,KAA6B,CAAA;AAClD,eAAO,MAAM,WAAW,KAAgC,CAAA;AAGxD,eAAO,MAAM,WAAW,KAAyB,CAAA;AACjD,eAAO,MAAM,UAAU,KAAwB,CAAA;AAC/C,eAAO,MAAM,iBAAiB,KAA8B,CAAA;AAC5D,eAAO,MAAM,UAAU,KAAwB,CAAA;AAC/C,eAAO,MAAM,iBAAiB,KAA8B,CAAA;AAC5D,eAAO,MAAM,YAAY,KAA0B,CAAA;AACnD,eAAO,MAAM,YAAY,KAA0B,CAAA;AACnD,eAAO,MAAM,WAAW,KAAyB,CAAA;AAcjD,eAAO,MAAM,kBAAkB;;cAEqC,OAAO,SAAS,EAAE,gBAAgB;;;;;;;;;CAaxD,CAAA;AAI9C,eAAO,MAAM,aAAa,KAA0B,CAAA;AACpD,eAAO,MAAM,cAAc,KAA2B,CAAA;AACtD,eAAO,MAAM,eAAe,KAA4B,CAAA;AACxD,eAAO,MAAM,eAAe,KAA4B,CAAA;AACxD,eAAO,MAAM,eAAe,KAA4B,CAAA;AACxD,eAAO,MAAM,kBAAkB,KAA+B,CAAA;AAC9D,eAAO,MAAM,oBAAoB,KAAiC,CAAA;AAIlE,eAAO,MAAM,qBAAqB,GAAI,UAAU,MAAM,KAAG,OAExD,CAAA;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED,eAAO,MAAM,uBAAuB,QAAO,mBAAmB,EAE7D,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAI,SAAS,MAAM,KAAG,OAExD,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAI,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,KAAG,CAAC,GAAG,SAGzF,CAAA;AAGD,MAAM,MAAM,eAAe,GAAG,OAAO,iBAAiB,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAA;AACpF,MAAM,MAAM,oBAAoB,GAAG,OAAO,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;AACnF,MAAM,MAAM,QAAQ,GAAG,OAAO,iBAAiB,CAAC,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA"}
1
+ {"version":3,"file":"config-sync.d.ts","sourceRoot":"","sources":["../../../src/lib/config/config-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA0LH,eAAO,MAAM,iBAAiB,KAAkB,CAAA;AAChD,eAAO,MAAM,gBAAgB,KAAwB,CAAA;AACrD,eAAO,MAAM,UAAU,6BAAkB,CAAA;AAGzC,eAAO,MAAM,iBAAiB,KAA0C,CAAA;AACxE,eAAO,MAAM,cAAc,KAAuC,CAAA;AAClE,eAAO,MAAM,eAAe,KAA6C,CAAA;AACzE,eAAO,MAAM,YAAY,KAA0C,CAAA;AACnE,eAAO,MAAM,QAAQ,KAAiE,CAAA;AACtF,eAAO,MAAM,WAAW,KAAgC,CAAA;AAGxD,eAAO,MAAM,WAAW,KAAyB,CAAA;AACjD,eAAO,MAAM,UAAU,KAAwB,CAAA;AAC/C,eAAO,MAAM,iBAAiB,KAA8B,CAAA;AAC5D,eAAO,MAAM,UAAU,KAAwB,CAAA;AAC/C,eAAO,MAAM,iBAAiB,KAA8B,CAAA;AAC5D,eAAO,MAAM,YAAY,KAA0B,CAAA;AACnD,eAAO,MAAM,YAAY,KAA0B,CAAA;AACnD,eAAO,MAAM,WAAW,KAAyB,CAAA;AAcjD,eAAO,MAAM,kBAAkB;;cAEqC,OAAO,SAAS,EAAE,gBAAgB;;;;;;;;;CAaxD,CAAA;AAI9C,eAAO,MAAM,aAAa,KAA0B,CAAA;AACpD,eAAO,MAAM,cAAc,KAA2B,CAAA;AACtD,eAAO,MAAM,eAAe,KAA4B,CAAA;AACxD,eAAO,MAAM,eAAe,KAA4B,CAAA;AACxD,eAAO,MAAM,eAAe,KAA4B,CAAA;AACxD,eAAO,MAAM,kBAAkB,KAA+B,CAAA;AAC9D,eAAO,MAAM,oBAAoB,KAAiC,CAAA;AAIlE,eAAO,MAAM,qBAAqB,GAAI,UAAU,MAAM,KAAG,OAExD,CAAA;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED,eAAO,MAAM,uBAAuB,QAAO,mBAAmB,EAE7D,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAI,SAAS,MAAM,KAAG,OAExD,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAI,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,KAAG,CAAC,GAAG,SAGzF,CAAA;AAGD,MAAM,MAAM,eAAe,GAAG,OAAO,iBAAiB,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAA;AACpF,MAAM,MAAM,oBAAoB,GAAG,OAAO,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;AACnF,MAAM,MAAM,QAAQ,GAAG,OAAO,iBAAiB,CAAC,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA"}
@@ -109,7 +109,7 @@ const SUPPORTED_LOCALES = APP_CONFIG_MERGED.i18n.supportedLocales;
109
109
  const DEFAULT_LOCALE = APP_CONFIG_MERGED.i18n.defaultLocale;
110
110
  const AVAILABLE_ROLES = APP_CONFIG_MERGED.userRoles.availableRoles;
111
111
  const DEFAULT_ROLE = APP_CONFIG_MERGED.userRoles.defaultRole;
112
- const APP_NAME = APP_CONFIG_MERGED.app.name;
112
+ const APP_NAME = process.env.NEXT_PUBLIC_APP_NAME || APP_CONFIG_MERGED.app.name;
113
113
  const APP_VERSION = APP_CONFIG_MERGED.app.version;
114
114
  const I18N_CONFIG = APP_CONFIG_MERGED.i18n;
115
115
  const APP_CONFIG = APP_CONFIG_MERGED.app;
@@ -6,6 +6,7 @@
6
6
  * component on a public or auth route imports this module instead, so those pages ship neither (#207).
7
7
  */
8
8
  export declare const APP_NAME: any;
9
+ export declare const APP_DESCRIPTION: any;
9
10
  export declare const DOCS_CONFIG: any;
10
11
  export declare const PUBLIC_AUTH_CONFIG: {
11
12
  registration: {
@@ -1 +1 @@
1
- {"version":3,"file":"public-config-client.d.ts","sourceRoot":"","sources":["../../../src/lib/config/public-config-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,eAAO,MAAM,QAAQ,KAAqB,CAAA;AAC1C,eAAO,MAAM,WAAW,KAAiB,CAAA;AAGzC,eAAO,MAAM,kBAAkB;;;;;;;;;;;CAS9B,CAAA"}
1
+ {"version":3,"file":"public-config-client.d.ts","sourceRoot":"","sources":["../../../src/lib/config/public-config-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,eAAO,MAAM,QAAQ,KAAyD,CAAA;AAC9E,eAAO,MAAM,eAAe,KAA4B,CAAA;AACxD,eAAO,MAAM,WAAW,KAAiB,CAAA;AAGzC,eAAO,MAAM,kBAAkB;;;;;;;;;;;CAS9B,CAAA"}
@@ -5,7 +5,8 @@ import { mergeConfigs } from "../utils/config-merge.js";
5
5
  import { resolveAuthMethods } from "../auth/auth-methods.js";
6
6
  import { resolveOtpConfig } from "../auth/otp-config.js";
7
7
  const appConfig = mergeConfigs(DEFAULT_APP_CONFIG, APP_CONFIG_OVERRIDES);
8
- const APP_NAME = appConfig.app.name;
8
+ const APP_NAME = process.env.NEXT_PUBLIC_APP_NAME || appConfig.app.name;
9
+ const APP_DESCRIPTION = appConfig.app.description;
9
10
  const DOCS_CONFIG = appConfig.docs;
10
11
  const methods = resolveAuthMethods(appConfig.auth);
11
12
  const PUBLIC_AUTH_CONFIG = {
@@ -19,6 +20,7 @@ const PUBLIC_AUTH_CONFIG = {
19
20
  otp: resolveOtpConfig(appConfig.auth)
20
21
  };
21
22
  export {
23
+ APP_DESCRIPTION,
22
24
  APP_NAME,
23
25
  DOCS_CONFIG,
24
26
  PUBLIC_AUTH_CONFIG
@@ -626,6 +626,8 @@ export interface AppConfig {
626
626
  app: {
627
627
  name: string;
628
628
  version: string;
629
+ /** One line shown under the name on the sign-in pages; the wizard writes the project's. */
630
+ description?: string;
629
631
  };
630
632
  i18n: {
631
633
  supportedLocales: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/config/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/config/types.ts"],"names":[],"mappings":"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"}
@@ -1,22 +1,31 @@
1
1
  /**
2
2
  * Reserved Slugs for Pages System
3
3
  *
4
- * This file contains all slugs that cannot be used for dynamic pages
5
- * to prevent conflicts with system routes, API endpoints, and existing entities.
6
- *
7
- * Auto-updated by build-registry.mjs to include entity slugs from ENTITY_REGISTRY
4
+ * The slugs a page at the site root cannot take because a route of the host already answers that URL: Next serves
5
+ * a static segment before the generated `(public)/[slug]` page. They are the first segments of core's route
6
+ * manifest (`src/routes/manifest.json`; a test fails when the two drift) plus `_next`. The base paths of the
7
+ * other registered entities are added where the check runs (`validatePublicSlug`); the routes a project adds
8
+ * under `templates/` are the project's to avoid.
8
9
  */
9
- export declare const RESERVED_SLUGS: readonly ["api", "auth", "admin", "login", "register", "dashboard", "signin", "signout", "signup", "verify", "reset-password", "forgot-password", "_next", "_vercel", "_error", "_document", "_app", "public", "static", "assets", "images", "theme", "favicon.ico", "robots.txt", "sitemap.xml", "manifest.json", "app", "core", "lib", "components", "utils", "styles", "fonts", "index", "home", "page", "post", "posts", "blog", "article", "articles", "v1", "v2", "v3"];
10
+ export declare const RESERVED_SLUGS: readonly ["_next", "403", "accept-invite", "api", "auth-error", "dashboard", "devtools", "docs", "forgot-password", "login", "public", "reset-password", "signup", "superadmin", "verify-email"];
10
11
  export type ReservedSlug = (typeof RESERVED_SLUGS)[number];
11
12
  /**
12
- * Check if a slug is reserved
13
+ * Check if a slug is reserved: one of core's routes, or one of `extra` (other entities' base path segments)
13
14
  */
14
- export declare function isReservedSlug(slug: string): boolean;
15
+ export declare function isReservedSlug(slug: string, extra?: readonly string[]): boolean;
15
16
  /**
16
17
  * Validate a slug for pages system
17
18
  * Returns error message if invalid, null if valid
19
+ *
20
+ * The format is the one the templates' `valid_slug` / `valid_post_slug` constraints enforce
21
+ * (`^[a-z0-9\-]+$`, no dot: a dotted last segment is read as a file request by the public item routes),
22
+ * plus the stricter rules below, which only apply to new writes. `checkReserved: false` skips the reserved
23
+ * list, `reserved` adds words to it, for an entity whose URLs are not at the site root (`/blog/v1` cannot shadow a root route).
18
24
  */
19
- export declare function validatePageSlug(slug: string): string | null;
25
+ export declare function validatePageSlug(slug: string, { checkReserved, reserved }?: {
26
+ checkReserved?: boolean;
27
+ reserved?: readonly string[];
28
+ }): string | null;
20
29
  /**
21
30
  * Generate a slug from a string (typically a title)
22
31
  */
@@ -1 +1 @@
1
- {"version":3,"file":"reserved-slugs.d.ts","sourceRoot":"","sources":["../../../src/lib/constants/reserved-slugs.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,cAAc,+cA2DjB,CAAA;AAEV,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAA;AAE1D;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqC5D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUlD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,GAAE,MAAM,EAAO,GAAG,MAAM,EAAE,CAsB3F"}
1
+ {"version":3,"file":"reserved-slugs.d.ts","sourceRoot":"","sources":["../../../src/lib/constants/reserved-slugs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,cAAc,kMAgBjB,CAAA;AAEV,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAA;AAE1D;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,SAAS,MAAM,EAAO,GAAG,OAAO,CAGnF;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,EAAE,aAAoB,EAAE,QAAa,EAAE,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAO,GACtG,MAAM,GAAG,IAAI,CAqCf;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUlD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,GAAE,MAAM,EAAO,GAAG,MAAM,EAAE,CAsB3F"}