@nextsparkjs/core 0.1.0-beta.196 → 0.1.0-beta.197

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 (136) hide show
  1. package/README.md +2 -0
  2. package/dist/components/auth/forms/SignupForm.d.ts.map +1 -1
  3. package/dist/components/auth/forms/SignupForm.js +55 -45
  4. package/dist/components/dashboard/block-editor/config-panel.d.ts.map +1 -1
  5. package/dist/components/dashboard/block-editor/config-panel.js +3 -2
  6. package/dist/components/dashboard/block-editor/entity-fields-sidebar.d.ts.map +1 -1
  7. package/dist/components/dashboard/block-editor/entity-fields-sidebar.js +3 -2
  8. package/dist/components/users/tables/UsersTable.d.ts.map +1 -1
  9. package/dist/components/users/tables/UsersTable.js +3 -4
  10. package/dist/hooks/useAuthReadiness.d.ts +1 -0
  11. package/dist/hooks/useAuthReadiness.d.ts.map +1 -1
  12. package/dist/hooks/useAuthReadiness.js +3 -1
  13. package/dist/lib/actions/entity.actions.js +2 -2
  14. package/dist/lib/actions/team.actions.js +2 -2
  15. package/dist/lib/actions/user.actions.js +4 -4
  16. package/dist/lib/api/auth/dual-auth.d.ts.map +1 -1
  17. package/dist/lib/api/auth/dual-auth.js +3 -2
  18. package/dist/lib/api/auth.d.ts.map +1 -1
  19. package/dist/lib/api/auth.js +7 -0
  20. package/dist/lib/api/entity/generic-handler.d.ts.map +1 -1
  21. package/dist/lib/api/entity/generic-handler.js +66 -12
  22. package/dist/lib/api/entity-handler.js +2 -2
  23. package/dist/lib/api/helpers.d.ts.map +1 -1
  24. package/dist/lib/api/helpers.js +4 -2
  25. package/dist/lib/api/post-categories.d.ts +29 -0
  26. package/dist/lib/api/post-categories.d.ts.map +1 -0
  27. package/dist/lib/api/post-categories.js +33 -0
  28. package/dist/lib/auth/auth-methods.d.ts +5 -2
  29. package/dist/lib/auth/auth-methods.d.ts.map +1 -1
  30. package/dist/lib/auth/auth-methods.js +4 -2
  31. package/dist/lib/auth/authorization-session.d.ts +14 -0
  32. package/dist/lib/auth/authorization-session.d.ts.map +1 -0
  33. package/dist/lib/auth/authorization-session.js +10 -0
  34. package/dist/lib/auth/request-session.d.ts +5 -0
  35. package/dist/lib/auth/request-session.d.ts.map +1 -1
  36. package/dist/lib/auth/request-session.js +3 -0
  37. package/dist/lib/auth/runtime-readiness.d.ts +7 -4
  38. package/dist/lib/auth/runtime-readiness.d.ts.map +1 -1
  39. package/dist/lib/auth/runtime-readiness.js +7 -6
  40. package/dist/lib/auth/sample-accounts.d.ts +2 -1
  41. package/dist/lib/auth/sample-accounts.d.ts.map +1 -1
  42. package/dist/lib/auth/sample-accounts.js +4 -1
  43. package/dist/lib/auth/suspension.d.ts +22 -0
  44. package/dist/lib/auth/suspension.d.ts.map +1 -0
  45. package/dist/lib/auth/suspension.js +43 -0
  46. package/dist/lib/auth.d.ts.map +1 -1
  47. package/dist/lib/auth.js +15 -15
  48. package/dist/lib/config/app.config.d.ts.map +1 -1
  49. package/dist/lib/config/app.config.js +6 -7
  50. package/dist/lib/config/types.d.ts +8 -6
  51. package/dist/lib/config/types.d.ts.map +1 -1
  52. package/dist/lib/db-pool.d.ts +31 -0
  53. package/dist/lib/db-pool.d.ts.map +1 -0
  54. package/dist/lib/db-pool.js +75 -0
  55. package/dist/lib/db.d.ts +1 -1
  56. package/dist/lib/db.d.ts.map +1 -1
  57. package/dist/lib/db.js +11 -14
  58. package/dist/lib/entities/api-generator.js +5 -5
  59. package/dist/lib/oauth/token-refresh.d.ts.map +1 -1
  60. package/dist/lib/oauth/token-refresh.js +3 -6
  61. package/dist/lib/permissions/check.d.ts +9 -0
  62. package/dist/lib/permissions/check.d.ts.map +1 -1
  63. package/dist/lib/permissions/check.js +11 -1
  64. package/dist/lib/services/generic-entity.service.d.ts.map +1 -1
  65. package/dist/lib/services/generic-entity.service.js +39 -7
  66. package/dist/lib/services/transactional-meta.service.d.ts.map +1 -1
  67. package/dist/lib/services/transactional-meta.service.js +7 -8
  68. package/dist/lib/validation.d.ts +5 -0
  69. package/dist/lib/validation.d.ts.map +1 -1
  70. package/dist/lib/validation.js +2 -0
  71. package/dist/migrations/030_taxonomies_team_writes.sql +29 -0
  72. package/dist/migrations/031_users_role_suspended.sql +41 -0
  73. package/dist/routes/(auth)/signup/page.cc.d.ts +3 -1
  74. package/dist/routes/(auth)/signup/page.cc.d.ts.map +1 -1
  75. package/dist/routes/(auth)/signup/page.cc.js +2 -2
  76. package/dist/routes/(auth)/signup/page.d.ts +3 -1
  77. package/dist/routes/(auth)/signup/page.d.ts.map +1 -1
  78. package/dist/routes/(auth)/signup/page.js +4 -3
  79. package/dist/routes/_internal/area-access.js +2 -2
  80. package/dist/routes/api/devtools/config/entities/route.js +2 -2
  81. package/dist/routes/api/devtools/config/theme/route.js +2 -2
  82. package/dist/routes/api/devtools/tests/[...path]/route.js +2 -2
  83. package/dist/routes/api/devtools/tests/route.js +2 -2
  84. package/dist/routes/api/superadmin/subscriptions/route.js +2 -2
  85. package/dist/routes/api/superadmin/teams/[teamId]/route.js +2 -2
  86. package/dist/routes/api/superadmin/teams/route.js +2 -2
  87. package/dist/routes/api/superadmin/users/[userId]/route.d.ts +5 -3
  88. package/dist/routes/api/superadmin/users/[userId]/route.d.ts.map +1 -1
  89. package/dist/routes/api/superadmin/users/[userId]/route.js +46 -23
  90. package/dist/routes/api/superadmin/users/route.js +2 -2
  91. package/dist/routes/api/user/delete-account/route.d.ts.map +1 -1
  92. package/dist/routes/api/user/delete-account/route.js +2 -3
  93. package/dist/routes/api/user/plan-flags/route.d.ts.map +1 -1
  94. package/dist/routes/api/user/plan-flags/route.js +5 -5
  95. package/dist/routes/api/user/profile/route.js +3 -3
  96. package/dist/routes/api/v1/auth/signup-with-invite/route.d.ts.map +1 -1
  97. package/dist/routes/api/v1/auth/signup-with-invite/route.js +80 -44
  98. package/dist/routes/api/v1/post-categories/[id]/route.d.ts.map +1 -1
  99. package/dist/routes/api/v1/post-categories/[id]/route.js +39 -34
  100. package/dist/routes/api/v1/post-categories/route.d.ts.map +1 -1
  101. package/dist/routes/api/v1/post-categories/route.js +18 -14
  102. package/dist/routes/api/v1/team-invitations/route.d.ts.map +1 -1
  103. package/dist/routes/api/v1/team-invitations/route.js +12 -5
  104. package/dist/routes/superadmin/users/page.js +2 -2
  105. package/dist/templates/next.config.mjs +11 -31
  106. package/dist/templates/projects/blog/package.json +1 -1
  107. package/dist/templates/projects/crm/package.json +1 -1
  108. package/dist/templates/projects/productivity/package.json +1 -1
  109. package/dist/templates/projects/starter/config/app.config.ts +8 -0
  110. package/dist/templates/proxy.ts +6 -3
  111. package/migrations/030_taxonomies_team_writes.sql +29 -0
  112. package/migrations/031_users_role_suspended.sql +41 -0
  113. package/package.json +3 -3
  114. package/scripts/build/registry/__tests__/build-output.test.mjs +1 -1
  115. package/scripts/build/registry/__tests__/project-mode-root-first.test.mjs +6 -6
  116. package/scripts/build/registry/__tests__/write-places.test.mjs +1 -1
  117. package/scripts/build/registry/contracts/__tests__/contracts-wire.test.mjs +1 -1
  118. package/scripts/build/registry/contracts/__tests__/contracts.test.mjs +1 -1
  119. package/scripts/build/registry/host/README.md +2 -2
  120. package/scripts/build/registry/host/__tests__/facade-emitter.test.mjs +14 -13
  121. package/scripts/build/registry/host/__tests__/host-mode.test.mjs +1 -1
  122. package/scripts/build/registry/host/__tests__/host-project-composition.test.mjs +1 -1
  123. package/scripts/build/registry/host/__tests__/host-project.test.mjs +2 -2
  124. package/scripts/build/registry/host/__tests__/host-proxy-areas.test.mjs +29 -2
  125. package/scripts/build/registry/host/__tests__/host-robustness.test.mjs +1 -1
  126. package/scripts/build/registry/host/facade-emitter.mjs +1 -1
  127. package/scripts/build/registry/host/next-route-exports.json +2 -2
  128. package/scripts/build/registry/host/proxy-areas.mjs +29 -2
  129. package/scripts/db/verify-theme-migrations.mjs +1 -1
  130. package/templates/next.config.mjs +11 -31
  131. package/templates/projects/blog/package.json +1 -1
  132. package/templates/projects/crm/package.json +1 -1
  133. package/templates/projects/productivity/package.json +1 -1
  134. package/templates/projects/starter/config/app.config.ts +8 -0
  135. package/templates/proxy.ts +6 -3
  136. package/tests/jest/__mocks__/@nextsparkjs/registries/permissions-registry.ts +5 -4
package/README.md CHANGED
@@ -19,6 +19,8 @@ pnpm db:migrate
19
19
  pnpm dev
20
20
  ```
21
21
 
22
+ With lifecycle scripts disabled (`pnpm install --frozen-lockfile --ignore-scripts`) nothing else is needed: `nextspark dev`, `build` and `prepare` generate `src/app` and the registries. Only Cypress needs `pnpm exec cypress install` before `pnpm cy:run`.
23
+
22
24
  Or initialize in an existing project:
23
25
 
24
26
  ```bash
@@ -1 +1 @@
1
- {"version":3,"file":"SignupForm.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/forms/SignupForm.tsx"],"names":[],"mappings":"AA+BA,wBAAgB,UAAU,4CAsmBzB"}
1
+ {"version":3,"file":"SignupForm.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/forms/SignupForm.tsx"],"names":[],"mappings":"AA+BA,wBAAgB,UAAU,4CAqnBzB"}
@@ -18,7 +18,7 @@ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle }
18
18
  import { Separator } from "../../ui/separator.js";
19
19
  import { PasswordInput } from "../../ui/password-input.js";
20
20
  import { Mail, User, Loader2, AlertCircle, ArrowRight, MailCheck, CheckCircle2, Users } from "lucide-react";
21
- import { signupSchema } from "../../../lib/validation.js";
21
+ import { inviteSignupSchema, signupSchema } from "../../../lib/validation.js";
22
22
  import { sel } from "../../../lib/selectors/auth-sel.js";
23
23
  import { useTranslations } from "next-intl";
24
24
  import { AuthTranslationPreloader } from "../../../lib/i18n/AuthTranslationPreloader.js";
@@ -43,6 +43,8 @@ function SignupForm() {
43
43
  const callbackUrl = safeCallbackPath(searchParams.get("callbackUrl"));
44
44
  const inviteToken = searchParams.get("inviteToken");
45
45
  const passwordAvailable = inviteToken ? readiness.capabilities.invitationPasswordSignup : readiness.availableMethods.includes("email-password");
46
+ const invitePasswordless = Boolean(inviteToken) && !passwordAvailable && readiness.capabilities.invitationSignup;
47
+ const formAvailable = passwordAvailable || invitePasswordless;
46
48
  const loginHref = callbackUrl ? `/login?callbackUrl=${encodeURIComponent(callbackUrl)}` : "/login";
47
49
  const {
48
50
  register,
@@ -50,7 +52,8 @@ function SignupForm() {
50
52
  watch,
51
53
  formState: { errors }
52
54
  } = useForm({
53
- resolver: zodResolver(signupSchema),
55
+ // Without a password field the form validates the rest only
56
+ resolver: zodResolver(invitePasswordless ? inviteSignupSchema : signupSchema),
54
57
  defaultValues: {
55
58
  email: inviteEmail || ""
56
59
  }
@@ -75,7 +78,7 @@ function SignupForm() {
75
78
  },
76
79
  body: JSON.stringify({
77
80
  email: data.email,
78
- password: data.password,
81
+ ...invitePasswordless ? {} : { password: data.password },
79
82
  firstName: data.firstName,
80
83
  lastName: data.lastName,
81
84
  inviteToken
@@ -100,7 +103,12 @@ function SignupForm() {
100
103
  toast.success(t("signup.messages.inviteSuccess"), {
101
104
  description: t("signup.messages.inviteJoinedTeam")
102
105
  });
103
- router.push(((_a = result.data) == null ? void 0 : _a.redirectTo) || "/dashboard/settings/teams");
106
+ const redirectTo = ((_a = result.data) == null ? void 0 : _a.redirectTo) || "/dashboard/settings/teams";
107
+ if (invitePasswordless) {
108
+ router.push(`/login?${new URLSearchParams({ email: data.email, fromInvite: "true", callbackUrl: redirectTo })}`);
109
+ return;
110
+ }
111
+ router.push(redirectTo);
104
112
  return;
105
113
  }
106
114
  await signUp({
@@ -119,7 +127,7 @@ function SignupForm() {
119
127
  } finally {
120
128
  setLoadingProvider(null);
121
129
  }
122
- }, [agreedToTerms, signUp, t, inviteToken, router]);
130
+ }, [agreedToTerms, signUp, t, inviteToken, invitePasswordless, router]);
123
131
  const handleGoogleSignUp = async () => {
124
132
  setLoadingProvider("google");
125
133
  setError(null);
@@ -147,7 +155,7 @@ function SignupForm() {
147
155
  setResendingEmail(false);
148
156
  }
149
157
  };
150
- if (readiness.state === "loading" || readiness.state === "error" || readiness.state === "unavailable" && !(inviteToken && passwordAvailable)) {
158
+ if (readiness.state === "loading" || readiness.state === "error" || readiness.state === "unavailable" && !(inviteToken && formAvailable)) {
151
159
  const isLoading = readiness.state === "loading";
152
160
  const isError = readiness.state === "error";
153
161
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -341,7 +349,7 @@ function SignupForm() {
341
349
  /* @__PURE__ */ jsx(Users, { className: "h-4 w-4" }),
342
350
  /* @__PURE__ */ jsx(AlertDescription, { children: t("signup.inviteBanner") })
343
351
  ] }),
344
- passwordAvailable && /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit(onSubmit), className: "space-y-4", children: [
352
+ formAvailable && /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit(onSubmit), className: "space-y-4", children: [
345
353
  /* @__PURE__ */ jsxs("div", { className: "grid gap-4 sm:grid-cols-2", children: [
346
354
  /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
347
355
  /* @__PURE__ */ jsx(Label, { htmlFor: "firstName", children: t("signup.form.firstName") }),
@@ -402,41 +410,43 @@ function SignupForm() {
402
410
  ] }),
403
411
  errors.email && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: errors.email.message })
404
412
  ] }),
405
- /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
406
- /* @__PURE__ */ jsx(Label, { htmlFor: "password", children: t("signup.form.password") }),
407
- /* @__PURE__ */ jsx(
408
- PasswordInput,
409
- {
410
- ...register("password"),
411
- id: "password",
412
- autoComplete: "new-password",
413
- placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
414
- showRequirements: true,
415
- password,
416
- requirementLabels: {
417
- minChars: t("signup.form.passwordRequirements.minChars"),
418
- uppercase: t("signup.form.passwordRequirements.uppercase"),
419
- lowercase: t("signup.form.passwordRequirements.lowercase"),
420
- number: t("signup.form.passwordRequirements.number")
421
- },
422
- "data-cy": sel("auth.signup.password")
423
- }
424
- ),
425
- errors.password && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: errors.password.message })
426
- ] }),
427
- /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
428
- /* @__PURE__ */ jsx(Label, { htmlFor: "confirmPassword", children: t("signup.form.confirmPassword") }),
429
- /* @__PURE__ */ jsx(
430
- PasswordInput,
431
- {
432
- ...register("confirmPassword"),
433
- id: "confirmPassword",
434
- autoComplete: "new-password",
435
- placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
436
- "data-cy": sel("auth.signup.confirmPassword")
437
- }
438
- ),
439
- errors.confirmPassword && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: errors.confirmPassword.message })
413
+ !invitePasswordless && /* @__PURE__ */ jsxs(Fragment, { children: [
414
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
415
+ /* @__PURE__ */ jsx(Label, { htmlFor: "password", children: t("signup.form.password") }),
416
+ /* @__PURE__ */ jsx(
417
+ PasswordInput,
418
+ {
419
+ ...register("password"),
420
+ id: "password",
421
+ autoComplete: "new-password",
422
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
423
+ showRequirements: true,
424
+ password,
425
+ requirementLabels: {
426
+ minChars: t("signup.form.passwordRequirements.minChars"),
427
+ uppercase: t("signup.form.passwordRequirements.uppercase"),
428
+ lowercase: t("signup.form.passwordRequirements.lowercase"),
429
+ number: t("signup.form.passwordRequirements.number")
430
+ },
431
+ "data-cy": sel("auth.signup.password")
432
+ }
433
+ ),
434
+ errors.password && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: errors.password.message })
435
+ ] }),
436
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
437
+ /* @__PURE__ */ jsx(Label, { htmlFor: "confirmPassword", children: t("signup.form.confirmPassword") }),
438
+ /* @__PURE__ */ jsx(
439
+ PasswordInput,
440
+ {
441
+ ...register("confirmPassword"),
442
+ id: "confirmPassword",
443
+ autoComplete: "new-password",
444
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
445
+ "data-cy": sel("auth.signup.confirmPassword")
446
+ }
447
+ ),
448
+ errors.confirmPassword && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: errors.confirmPassword.message })
449
+ ] })
440
450
  ] }),
441
451
  error && /* @__PURE__ */ jsxs(Alert, { variant: "destructive", "data-cy": sel("auth.signup.error"), children: [
442
452
  /* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }),
@@ -479,7 +489,7 @@ function SignupForm() {
479
489
  }
480
490
  )
481
491
  ] }),
482
- !passwordAvailable && !googleAvailable && /* @__PURE__ */ jsxs(
492
+ !formAvailable && !googleAvailable && /* @__PURE__ */ jsxs(
483
493
  Alert,
484
494
  {
485
495
  role: "alert",
@@ -495,12 +505,12 @@ function SignupForm() {
495
505
  ]
496
506
  }
497
507
  ),
498
- inviteToken && !passwordAvailable && googleAvailable && /* @__PURE__ */ jsxs(Alert, { role: "alert", className: "mb-4", "data-cy": sel("auth.signup.inviteUnavailable"), children: [
508
+ inviteToken && !formAvailable && googleAvailable && /* @__PURE__ */ jsxs(Alert, { role: "alert", className: "mb-4", "data-cy": sel("auth.signup.inviteUnavailable"), children: [
499
509
  /* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4", "aria-hidden": "true" }),
500
510
  /* @__PURE__ */ jsx(AlertDescription, { children: t("signup.inviteUnavailable") })
501
511
  ] }),
502
512
  googleAvailable && /* @__PURE__ */ jsxs(Fragment, { children: [
503
- passwordAvailable && /* @__PURE__ */ jsxs("div", { className: "relative my-4", children: [
513
+ formAvailable && /* @__PURE__ */ jsxs("div", { className: "relative my-4", children: [
504
514
  /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsx(Separator, { className: "w-full" }) }),
505
515
  /* @__PURE__ */ jsx("div", { className: "relative flex justify-center text-xs uppercase", children: /* @__PURE__ */ jsx("span", { className: "bg-background px-2 text-muted-foreground", children: t("signup.form.orContinueWith") }) })
506
516
  ] }),
@@ -1 +1 @@
1
- {"version":3,"file":"config-panel.d.ts","sourceRoot":"","sources":["../../../../src/components/dashboard/block-editor/config-panel.tsx"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAA;AACxF,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,uBAAuB,CAAA;AAkB1E,UAAU,gBAAgB;IACxB,YAAY,EAAE,kBAAkB,CAAA;IAChC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACrC,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAC5D,YAAY,EAAE,YAAY,CAAA;IAC1B,oBAAoB,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAA;CACvD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAC1B,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,EACrB,EAAE,gBAAgB,2CA6elB"}
1
+ {"version":3,"file":"config-panel.d.ts","sourceRoot":"","sources":["../../../../src/components/dashboard/block-editor/config-panel.tsx"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAA;AACxF,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,uBAAuB,CAAA;AAmB1E,UAAU,gBAAgB;IACxB,YAAY,EAAE,kBAAkB,CAAA;IAChC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACrC,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAC5D,YAAY,EAAE,YAAY,CAAA;IAC1B,oBAAoB,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAA;CACvD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAC1B,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,EACrB,EAAE,gBAAgB,2CA6elB"}
@@ -36,7 +36,8 @@ import {
36
36
  SelectTrigger,
37
37
  SelectValue
38
38
  } from "../../ui/select.js";
39
- import { withBasePath, withBasePathIfInApp } from "../../../lib/base-path.js";
39
+ import { withBasePathIfInApp } from "../../../lib/base-path.js";
40
+ import { fetchWithTeam } from "../../../lib/api/entities.js";
40
41
  function ConfigPanel({
41
42
  entityConfig,
42
43
  entityFields,
@@ -59,7 +60,7 @@ function ConfigPanel({
59
60
  queryKey: ["taxonomies", taxonomyApiPath],
60
61
  queryFn: async () => {
61
62
  if (!taxonomyApiPath) return { data: [] };
62
- const response = await fetch(withBasePath(`/api/v1/${taxonomyApiPath}`));
63
+ const response = await fetchWithTeam(`/api/v1/${taxonomyApiPath}`);
63
64
  if (!response.ok) return { data: [] };
64
65
  return response.json();
65
66
  },
@@ -1 +1 @@
1
- {"version":3,"file":"entity-fields-sidebar.d.ts","sourceRoot":"","sources":["../../../../src/components/dashboard/block-editor/entity-fields-sidebar.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAA;AAkBxF,UAAU,wBAAwB;IAChC,YAAY,EAAE,kBAAkB,CAAA;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IACjD,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC7B,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;CAChD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,YAAY,EACZ,MAAM,EACN,QAAQ,EACR,kBAAuB,EACvB,gBAAgB,EACjB,EAAE,wBAAwB,2CAmS1B"}
1
+ {"version":3,"file":"entity-fields-sidebar.d.ts","sourceRoot":"","sources":["../../../../src/components/dashboard/block-editor/entity-fields-sidebar.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAA;AAmBxF,UAAU,wBAAwB;IAChC,YAAY,EAAE,kBAAkB,CAAA;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IACjD,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC7B,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;CAChD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,YAAY,EACZ,MAAM,EACN,QAAQ,EACR,kBAAuB,EACvB,gBAAgB,EACjB,EAAE,wBAAwB,2CAmS1B"}
@@ -18,7 +18,8 @@ import {
18
18
  SelectTrigger,
19
19
  SelectValue
20
20
  } from "../../ui/select.js";
21
- import { withBasePath, withBasePathIfInApp } from "../../../lib/base-path.js";
21
+ import { withBasePathIfInApp } from "../../../lib/base-path.js";
22
+ import { fetchWithTeam } from "../../../lib/api/entities.js";
22
23
  function EntityFieldsSidebar({
23
24
  entityConfig,
24
25
  fields,
@@ -37,7 +38,7 @@ function EntityFieldsSidebar({
37
38
  queryKey: ["taxonomies", taxonomyApiPath],
38
39
  queryFn: async () => {
39
40
  if (!taxonomyApiPath) return { data: [] };
40
- const response = await fetch(withBasePath(`/api/v1/${taxonomyApiPath}`));
41
+ const response = await fetchWithTeam(`/api/v1/${taxonomyApiPath}`);
41
42
  if (!response.ok) return { data: [] };
42
43
  return response.json();
43
44
  },
@@ -1 +1 @@
1
- {"version":3,"file":"UsersTable.d.ts","sourceRoot":"","sources":["../../../../src/components/users/tables/UsersTable.tsx"],"names":[],"mappings":"AAsCA,OAAO,EAEL,IAAI,EAUL,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAM1D,UAAU,IAAI;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,eAAe;IACvB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AASD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,eAAe,2CA2Y1E"}
1
+ {"version":3,"file":"UsersTable.d.ts","sourceRoot":"","sources":["../../../../src/components/users/tables/UsersTable.tsx"],"names":[],"mappings":"AAsCA,OAAO,EAEL,IAAI,EAUL,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAM1D,UAAU,IAAI;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,eAAe;IACvB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AASD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,eAAe,2CAwY1E"}
@@ -183,9 +183,9 @@ function UsersTable({ users, isLoading, onRefresh }) {
183
183
  };
184
184
  const getRoleBadgeVariant = (role) => {
185
185
  switch (role) {
186
- case "admin":
186
+ case "suspended":
187
187
  return "destructive";
188
- case "colaborator":
188
+ case "developer":
189
189
  return "default";
190
190
  case "member":
191
191
  return "secondary";
@@ -284,8 +284,7 @@ function UsersTable({ users, isLoading, onRefresh }) {
284
284
  onValueChange: (value) => handleRoleChange(user, value),
285
285
  children: [
286
286
  /* @__PURE__ */ jsx(DropdownMenuRadioItem, { value: "member", children: "Member" }),
287
- /* @__PURE__ */ jsx(DropdownMenuRadioItem, { value: "colaborator", children: "Colaborator" }),
288
- /* @__PURE__ */ jsx(DropdownMenuRadioItem, { value: "admin", children: "Admin" })
287
+ /* @__PURE__ */ jsx(DropdownMenuRadioItem, { value: "developer", children: "Developer" })
289
288
  ]
290
289
  }
291
290
  ) })
@@ -2,6 +2,7 @@ import type { AuthLoginMethod } from '../lib/config/types';
2
2
  export type AuthReadinessState = 'loading' | 'ready' | 'unavailable' | 'error';
3
3
  /** Server-derived flows independent of the login UI methods; see runtime-readiness. */
4
4
  export interface ClientAuthCapabilities {
5
+ invitationSignup: boolean;
5
6
  invitationPasswordSignup: boolean;
6
7
  passwordRecovery: boolean;
7
8
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useAuthReadiness.d.ts","sourceRoot":"","sources":["../../src/hooks/useAuthReadiness.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAE1D,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,OAAO,GAAG,aAAa,GAAG,OAAO,CAAA;AAE9E,uFAAuF;AACvF,MAAM,WAAW,sBAAsB;IACrC,wBAAwB,EAAE,OAAO,CAAA;IACjC,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,kBAAkB,CAAA;IACzB,gBAAgB,EAAE,eAAe,EAAE,CAAA;IACnC,YAAY,EAAE,sBAAsB,CAAA;CACrC;AAsCD,qFAAqF;AACrF,wBAAgB,gBAAgB,IAAI,mBAAmB,CA8BtD"}
1
+ {"version":3,"file":"useAuthReadiness.d.ts","sourceRoot":"","sources":["../../src/hooks/useAuthReadiness.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAE1D,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,OAAO,GAAG,aAAa,GAAG,OAAO,CAAA;AAE9E,uFAAuF;AACvF,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,EAAE,OAAO,CAAA;IACzB,wBAAwB,EAAE,OAAO,CAAA;IACjC,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,kBAAkB,CAAA;IACzB,gBAAgB,EAAE,eAAe,EAAE,CAAA;IACnC,YAAY,EAAE,sBAAsB,CAAA;CACrC;AAyCD,qFAAqF;AACrF,wBAAgB,gBAAgB,IAAI,mBAAmB,CA8BtD"}
@@ -3,6 +3,7 @@ import { useEffect, useState } from "react";
3
3
  import { withBasePath } from "../lib/base-path.js";
4
4
  import { isAuthLoginMethod } from "../lib/auth/auth-methods.js";
5
5
  const NO_CAPABILITIES = {
6
+ invitationSignup: false,
6
7
  invitationPasswordSignup: false,
7
8
  passwordRecovery: false
8
9
  };
@@ -19,13 +20,14 @@ function parseReadiness(value) {
19
20
  throw new Error("Ready auth response has no available method");
20
21
  }
21
22
  const capabilities = candidate.capabilities;
22
- if (!capabilities || typeof capabilities !== "object" || typeof capabilities.invitationPasswordSignup !== "boolean" || typeof capabilities.passwordRecovery !== "boolean") {
23
+ if (!capabilities || typeof capabilities !== "object" || typeof capabilities.invitationSignup !== "boolean" || typeof capabilities.invitationPasswordSignup !== "boolean" || typeof capabilities.passwordRecovery !== "boolean") {
23
24
  throw new Error("Invalid auth readiness capabilities");
24
25
  }
25
26
  return {
26
27
  state: candidate.status,
27
28
  availableMethods: [...new Set(candidate.availableMethods)],
28
29
  capabilities: {
30
+ invitationSignup: capabilities.invitationSignup,
29
31
  invitationPasswordSignup: capabilities.invitationPasswordSignup,
30
32
  passwordRecovery: capabilities.passwordRecovery
31
33
  }
@@ -6,12 +6,12 @@ import { ACTIVE_TEAM_COOKIE, activeTeamIdForSession } from "../teams/active-team
6
6
  import { redirect } from "next/navigation";
7
7
  import { GenericEntityService } from "../services/generic-entity.service.js";
8
8
  import { entityRegistry } from "../entities/registry.js";
9
- import { getTypedSession } from "../auth.js";
9
+ import { getAuthorizationSession } from "../auth/authorization-session.js";
10
10
  import { checkPermission } from "../permissions/check.js";
11
11
  async function getAuthContext() {
12
12
  var _a, _b, _c;
13
13
  const headersList = await headers();
14
- const session = await getTypedSession(headersList);
14
+ const session = await getAuthorizationSession(headersList);
15
15
  if (!((_a = session == null ? void 0 : session.user) == null ? void 0 : _a.id)) {
16
16
  return { success: false, error: "Authentication required" };
17
17
  }
@@ -1,7 +1,7 @@
1
1
  "use server";
2
2
  import { revalidatePath } from "next/cache";
3
3
  import { headers } from "next/headers";
4
- import { getTypedSession } from "../auth.js";
4
+ import { getAuthorizationSession } from "../auth/authorization-session.js";
5
5
  import { TeamService } from "../services/team.service.js";
6
6
  import { TeamMemberService } from "../services/team-member.service.js";
7
7
  import { getInvitableRoles } from "../teams/permissions.js";
@@ -9,7 +9,7 @@ import { APP_CONFIG_MERGED } from "../config/config-sync.js";
9
9
  async function getAuthUser() {
10
10
  var _a;
11
11
  const headersList = await headers();
12
- const session = await getTypedSession(headersList);
12
+ const session = await getAuthorizationSession(headersList);
13
13
  if (!((_a = session == null ? void 0 : session.user) == null ? void 0 : _a.id)) {
14
14
  return { success: false, error: "Authentication required" };
15
15
  }
@@ -1,13 +1,13 @@
1
1
  "use server";
2
2
  import { revalidatePath } from "next/cache";
3
3
  import { headers } from "next/headers";
4
- import { getTypedSession } from "../auth.js";
4
+ import { getAuthorizationSession } from "../auth/authorization-session.js";
5
5
  import { UserService } from "../services/user.service.js";
6
6
  async function updateProfile(data) {
7
7
  var _a;
8
8
  try {
9
9
  const headersList = await headers();
10
- const session = await getTypedSession(headersList);
10
+ const session = await getAuthorizationSession(headersList);
11
11
  if (!((_a = session == null ? void 0 : session.user) == null ? void 0 : _a.id)) {
12
12
  return { success: false, error: "Authentication required" };
13
13
  }
@@ -54,7 +54,7 @@ async function updateAvatar(formData) {
54
54
  var _a;
55
55
  try {
56
56
  const headersList = await headers();
57
- const session = await getTypedSession(headersList);
57
+ const session = await getAuthorizationSession(headersList);
58
58
  if (!((_a = session == null ? void 0 : session.user) == null ? void 0 : _a.id)) {
59
59
  return { success: false, error: "Authentication required" };
60
60
  }
@@ -109,7 +109,7 @@ async function deleteAccount() {
109
109
  var _a;
110
110
  try {
111
111
  const headersList = await headers();
112
- const session = await getTypedSession(headersList);
112
+ const session = await getAuthorizationSession(headersList);
113
113
  if (!((_a = session == null ? void 0 : session.user) == null ? void 0 : _a.id)) {
114
114
  return { success: false, error: "Authentication required" };
115
115
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dual-auth.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/auth/dual-auth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAOvD,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,eAAe,EAKrB,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAK/F;;;GAGG;AACH,eAAO,MAAM,oBAAoB,uBAAuB,CAAA;AAExD;;GAEG;AACH,eAAO,MAAM,mBAAmB,mBAAmB,CAAA;AACnD,eAAO,MAAM,kBAAkB,8BAA8B,CAAA;AAE7D;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,kBAAkB,CAAA;AAOjD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAA;IAChB;;;;OAIG;IACH,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAA;IACpC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,mHAAmH;IACnH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,yFAAyF;IACzF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+GAA+G;IAC/G,iBAAiB,CAAC,EAAE,QAAQ,CAAA;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAA;IAC3D,0EAA0E;IAC1E,KAAK,CAAC,EAAE,eAAe,CAAA;CACxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,WAAW,EACpB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,cAAc,CAAC,CA2DzB;AAmKD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAUtG;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,cAAc,GACzB,OAAO,CAAC,MAAM,GAAG,YAAY,CAAC,CAsChC;AAMD;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,cAAc,EAC1B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,OAAO,CAAC,CAkBlB;AA2BD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,MAAkC,EAAE,MAAM,GAAE,MAAY;;;;GAShG;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,cAAc,GAAG,YAAY,CAWlF"}
1
+ {"version":3,"file":"dual-auth.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/auth/dual-auth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAQvD,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,eAAe,EAKrB,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAK/F;;;GAGG;AACH,eAAO,MAAM,oBAAoB,uBAAuB,CAAA;AAExD;;GAEG;AACH,eAAO,MAAM,mBAAmB,mBAAmB,CAAA;AACnD,eAAO,MAAM,kBAAkB,8BAA8B,CAAA;AAE7D;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,kBAAkB,CAAA;AAOjD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAA;IAChB;;;;OAIG;IACH,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAA;IACpC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,mHAAmH;IACnH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,yFAAyF;IACzF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+GAA+G;IAC/G,iBAAiB,CAAC,EAAE,QAAQ,CAAA;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAA;IAC3D,0EAA0E;IAC1E,KAAK,CAAC,EAAE,eAAe,CAAA;CACxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,WAAW,EACpB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,cAAc,CAAC,CA2DzB;AAsKD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAUtG;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,cAAc,GACzB,OAAO,CAAC,MAAM,GAAG,YAAY,CAAC,CAsChC;AAMD;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,cAAc,EAC1B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,OAAO,CAAC,CAkBlB;AA2BD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,MAAkC,EAAE,MAAM,GAAE,MAAY;;;;GAShG;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,cAAc,GAAG,YAAY,CAWlF"}
@@ -3,6 +3,7 @@ import { getUserDefaultTeamId } from "../../teams/dashboard-team.js";
3
3
  import { NextResponse } from "next/server";
4
4
  import { auth } from "../../auth.js";
5
5
  import { validateApiKey } from "../auth.js";
6
+ import { isSuspendedRole } from "../../auth/suspension.js";
6
7
  import { apiKeyRateLimitResponse } from "../rate-limit.js";
7
8
  import { queryOne } from "../../db.js";
8
9
  import { TeamMemberService } from "../../services/team-member.service.js";
@@ -141,8 +142,8 @@ async function tryApiKeyAuth(request) {
141
142
  async function trySessionAuth(request) {
142
143
  var _a;
143
144
  try {
144
- const session = await auth.api.getSession({ headers: request.headers });
145
- if (!(session == null ? void 0 : session.user)) {
145
+ const session = await auth.api.getSession({ headers: request.headers, query: { disableCookieCache: true } });
146
+ if (!(session == null ? void 0 : session.user) || isSuspendedRole(session.user.role)) {
146
147
  return { success: false, type: "none", user: null };
147
148
  }
148
149
  const defaultTeamId = await getUserDefaultTeamId(session.user.id);
@@ -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;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
+ {"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,CAsHrF;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"}
@@ -11,6 +11,8 @@ function getValidatedApiKey(request) {
11
11
  return validatedKeys.get(request) ?? null;
12
12
  }
13
13
  async function validateApiKey(request) {
14
+ const validatedBefore = validatedKeys.get(request);
15
+ if (validatedBefore) return validatedBefore;
14
16
  const startTime = Date.now();
15
17
  try {
16
18
  const apiKey = presentedApiKey(request.headers);
@@ -63,6 +65,11 @@ async function validateApiKey(request) {
63
65
  await constantTimeDelay(startTime);
64
66
  return null;
65
67
  }
68
+ const owner = await queryOne('SELECT role FROM "users" WHERE id = $1', [keyData.userId]);
69
+ if ((owner == null ? void 0 : owner.role) === "suspended") {
70
+ await constantTimeDelay(startTime);
71
+ return null;
72
+ }
66
73
  if (keyData.failedAttempts && keyData.failedAttempts > 0) {
67
74
  resetFailedAttempts(keyData.id).catch(console.error);
68
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"generic-handler.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/entity/generic-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AA4wBvD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAEnF;AA8lBD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAErF;AAyaD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAEpJ;AAoND;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAEtJ;AA6ZD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAEtJ;AAwKD;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAEtF"}
1
+ {"version":3,"file":"generic-handler.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/entity/generic-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AA+wBvD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAEnF;AA8lBD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAErF;AAwcD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAEpJ;AAoND;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAEtJ;AA4bD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAEtJ;AAwKD;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAEtF"}
@@ -5,7 +5,7 @@ import { generateEntitySchemas } from "../../entities/schema-generator.js";
5
5
  import { publicSlugIssue, otherBasePathSegments } from "../../entities/public-slug.js";
6
6
  import { getAllEntityConfigs } from "../../entities/registry.js";
7
7
  import { entityResponseSystemColumns, taxonomyResponseFields } from "../../entities/portable/response-shape.js";
8
- import { queryWithRLS, mutateWithRLS, queryOneWithRLS } from "../../db.js";
8
+ import { queryWithRLS, mutateWithRLS, queryOneWithRLS, getTransactionClient } from "../../db.js";
9
9
  import {
10
10
  createApiResponse,
11
11
  createApiError,
@@ -22,7 +22,7 @@ import {
22
22
  } from "../helpers.js";
23
23
  import { beforeEntityCreate, afterEntityCreate, beforeEntityUpdate, afterEntityUpdate, beforeEntityDelete, afterEntityDelete, beforeEntityRead, afterEntityRead } from "../../entities/entity-hooks.js";
24
24
  import { logGenericHandlerUsage } from "./audit-log.js";
25
- import { checkPermission } from "../../permissions/check.js";
25
+ import { checkPermission, declaredPublishPermission, publishPermissionFor } from "../../permissions/check.js";
26
26
  import { extractPatternIds } from "../../blocks/pattern-resolver.js";
27
27
  import { isPatternReference } from "../../../types/pattern-reference.js";
28
28
  import { PatternUsageService } from "../../services/pattern-usage.service.js";
@@ -122,7 +122,7 @@ async function includeTaxonomiesInData(entityConfig, items, userId) {
122
122
  };
123
123
  });
124
124
  }
125
- async function processTaxonomyRelations(entityConfig, entityId, data, userId, isUpdate = false) {
125
+ async function processTaxonomyRelations(entityConfig, entityId, data, userId, teamId, isUpdate = false) {
126
126
  var _a, _b, _c;
127
127
  if (!((_a = entityConfig.taxonomies) == null ? void 0 : _a.enabled) || !((_c = (_b = entityConfig.taxonomies) == null ? void 0 : _b.types) == null ? void 0 : _c.length)) {
128
128
  return;
@@ -146,8 +146,9 @@ async function processTaxonomyRelations(entityConfig, entityId, data, userId, is
146
146
  const taxonomyId = typeof taxonomyIds[i] === "object" && taxonomyIds[i] !== null ? taxonomyIds[i].id : taxonomyIds[i];
147
147
  await mutateWithRLS(
148
148
  `INSERT INTO entity_taxonomy_relations ("entityType", "entityId", "taxonomyId", "order")
149
- VALUES ($1, $2, $3, $4)`,
150
- [entityType, entityId, taxonomyId, i + 1],
149
+ SELECT $1, $2, id, $4 FROM taxonomies
150
+ WHERE id = $3 AND type = $5 AND ("teamId" IS NULL OR "teamId" = $6)`,
151
+ [entityType, entityId, taxonomyId, i + 1, taxonomyType.type, teamId],
151
152
  userId
152
153
  );
153
154
  }
@@ -785,7 +786,7 @@ async function handleGenericCreate(request) {
785
786
  return runWithAuditLog(request, (audit) => handleGenericCreateImpl(request, audit));
786
787
  }
787
788
  async function handleGenericCreateImpl(request, audit) {
788
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
789
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
789
790
  try {
790
791
  const resolution = await resolveEntityFromUrl(request.nextUrl.pathname);
791
792
  if (!resolution.isValidEntity || !resolution.entityConfig) {
@@ -886,6 +887,13 @@ async function handleGenericCreateImpl(request, audit) {
886
887
  );
887
888
  return addCorsHeaders(response2, request);
888
889
  }
890
+ const createStatusField = entityConfig.fields.find((f) => f.name === "status");
891
+ const createStatus = validatedData.status ?? (createStatusField == null ? void 0 : createStatusField.defaultValue);
892
+ if (publishPermissionFor(entityConfig.slug, createStatus)) {
893
+ const publishDenied = await checkAuthPermission(authResult, entityConfig.slug, "publish", teamId, request);
894
+ if (publishDenied) return publishDenied;
895
+ }
896
+ const checkStoredStatus = createStatus === void 0 && !!createStatusField && !!declaredPublishPermission(entityConfig.slug);
889
897
  if (idStrategy === "serial") {
890
898
  insertFields = ['"userId"', '"teamId"'];
891
899
  placeholders = ["$1", "$2"];
@@ -984,8 +992,28 @@ async function handleGenericCreateImpl(request, audit) {
984
992
  INSERT INTO "${tableName}" (${insertFields.join(", ")})
985
993
  VALUES (${placeholders.join(", ")}) RETURNING *
986
994
  `;
987
- const insertResult = await mutateWithRLS(insertQuery, values, authResult.user.id);
988
- const createdEntityId = String((_g = insertResult.rows[0]) == null ? void 0 : _g.id);
995
+ let insertResult;
996
+ if (checkStoredStatus) {
997
+ const tx = await getTransactionClient(authResult.user.id);
998
+ try {
999
+ insertResult = await tx.mutate(insertQuery, values);
1000
+ if (((_g = insertResult.rows[0]) == null ? void 0 : _g.status) === "published") {
1001
+ const publishDenied = await checkAuthPermission(authResult, entityConfig.slug, "publish", teamId, request);
1002
+ if (publishDenied) {
1003
+ await tx.rollback();
1004
+ return publishDenied;
1005
+ }
1006
+ }
1007
+ await tx.commit();
1008
+ } catch (error) {
1009
+ await tx.rollback().catch(() => {
1010
+ });
1011
+ throw error;
1012
+ }
1013
+ } else {
1014
+ insertResult = await mutateWithRLS(insertQuery, values, authResult.user.id);
1015
+ }
1016
+ const createdEntityId = String((_h = insertResult.rows[0]) == null ? void 0 : _h.id);
989
1017
  if (limitSlug) {
990
1018
  UsageService.track({
991
1019
  teamId,
@@ -1015,8 +1043,8 @@ async function handleGenericCreateImpl(request, audit) {
1015
1043
  `;
1016
1044
  const createdItems = await queryWithRLS(selectQuery, [createdEntityId], authResult.user.id);
1017
1045
  const createdItem = createdItems[0];
1018
- if ((_h = entityConfig.taxonomies) == null ? void 0 : _h.enabled) {
1019
- await processTaxonomyRelations(entityConfig, createdEntityId, body, authResult.user.id, false);
1046
+ if ((_i = entityConfig.taxonomies) == null ? void 0 : _i.enabled) {
1047
+ await processTaxonomyRelations(entityConfig, createdEntityId, body, authResult.user.id, teamId, false);
1020
1048
  }
1021
1049
  const metadataWasProvided = metas && typeof metas === "object" && Object.keys(metas).length > 0;
1022
1050
  if (metadataWasProvided) {
@@ -1028,7 +1056,7 @@ async function handleGenericCreateImpl(request, audit) {
1028
1056
  );
1029
1057
  }
1030
1058
  let responseItem = createdItem;
1031
- if ((_i = entityConfig.taxonomies) == null ? void 0 : _i.enabled) {
1059
+ if ((_j = entityConfig.taxonomies) == null ? void 0 : _j.enabled) {
1032
1060
  const itemsWithTaxonomies = await includeTaxonomiesInData(
1033
1061
  entityConfig,
1034
1062
  [createdItem],
@@ -1327,6 +1355,18 @@ async function handleGenericUpdateImpl(request, audit, { params }) {
1327
1355
  );
1328
1356
  return addCorsHeaders(response2, request);
1329
1357
  }
1358
+ let statusRead;
1359
+ if ("status" in entityData && entityConfig.fields.some((f) => f.name === "status") && declaredPublishPermission(entityConfig.slug)) {
1360
+ statusRead = (await queryWithRLS(
1361
+ `SELECT "status" FROM "${tableName}" WHERE id = $1 AND "teamId" = $2`,
1362
+ [id, teamId],
1363
+ authResult.user.id
1364
+ ))[0];
1365
+ if (statusRead && publishPermissionFor(entityConfig.slug, validatedData.status, statusRead.status)) {
1366
+ const publishDenied = await checkAuthPermission(authResult, entityConfig.slug, "publish", teamId, request);
1367
+ if (publishDenied) return publishDenied;
1368
+ }
1369
+ }
1330
1370
  const updates = [];
1331
1371
  const values = [];
1332
1372
  let paramCount = 1;
@@ -1425,6 +1465,10 @@ async function handleGenericUpdateImpl(request, audit, { params }) {
1425
1465
  whereConditions.push(`"${updateOwnershipFilter.field}" = $${paramCount++}`);
1426
1466
  values.push(updateOwnershipFilter.value);
1427
1467
  }
1468
+ if (statusRead) {
1469
+ whereConditions.push(`"status" IS NOT DISTINCT FROM $${paramCount++}`);
1470
+ values.push(statusRead.status);
1471
+ }
1428
1472
  const updateQuery = `
1429
1473
  UPDATE "${tableName}"
1430
1474
  SET ${updates.join(", ")}
@@ -1433,6 +1477,16 @@ async function handleGenericUpdateImpl(request, audit, { params }) {
1433
1477
  `;
1434
1478
  const result = await mutateWithRLS(updateQuery, values, authResult.user.id);
1435
1479
  if (!result.rows || result.rows.length === 0) {
1480
+ if (statusRead) {
1481
+ const [now] = await queryWithRLS(
1482
+ `SELECT "status" FROM "${tableName}" WHERE id = $1 AND "teamId" = $2`,
1483
+ [id, teamId],
1484
+ authResult.user.id
1485
+ );
1486
+ if (now && now.status !== statusRead.status) {
1487
+ return addCorsHeaders(createApiError("The record changed while it was being saved. Reload it and try again.", 409, void 0, "STATUS_CHANGED"), request);
1488
+ }
1489
+ }
1436
1490
  const response2 = createApiError("Item not found", 404);
1437
1491
  return addCorsHeaders(response2, request);
1438
1492
  }
@@ -1452,7 +1506,7 @@ async function handleGenericUpdateImpl(request, audit, { params }) {
1452
1506
  updatedItem = result[0];
1453
1507
  }
1454
1508
  if ((_g = entityConfig.taxonomies) == null ? void 0 : _g.enabled) {
1455
- await processTaxonomyRelations(entityConfig, id, body, authResult.user.id, true);
1509
+ await processTaxonomyRelations(entityConfig, id, body, authResult.user.id, teamId, true);
1456
1510
  }
1457
1511
  if (metadataWasProvided) {
1458
1512
  await processEntityMetadata(