@nextsparkjs/core 0.1.0-beta.183 → 0.1.0-beta.185

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 (80) hide show
  1. package/dist/components/auth/forms/LoginForm.d.ts.map +1 -1
  2. package/dist/components/auth/forms/LoginForm.js +8 -5
  3. package/dist/hooks/useAuth.d.ts +74 -25
  4. package/dist/hooks/useAuth.d.ts.map +1 -1
  5. package/dist/hooks/useValidationSchemas.d.ts +7 -7
  6. package/dist/lib/api/auth/dual-auth.d.ts +7 -0
  7. package/dist/lib/api/auth/dual-auth.d.ts.map +1 -1
  8. package/dist/lib/api/auth/dual-auth.js +1 -1
  9. package/dist/lib/api/auth.d.ts +20 -3
  10. package/dist/lib/api/auth.d.ts.map +1 -1
  11. package/dist/lib/api/auth.js +37 -19
  12. package/dist/lib/api/entity/generic-handler.d.ts.map +1 -1
  13. package/dist/lib/api/entity/generic-handler.js +19 -22
  14. package/dist/lib/auth.d.ts +1 -3057
  15. package/dist/lib/auth.d.ts.map +1 -1
  16. package/dist/lib/billing/schema.d.ts +1 -1
  17. package/dist/lib/mcp/audit.d.ts +17 -0
  18. package/dist/lib/mcp/audit.d.ts.map +1 -0
  19. package/dist/lib/mcp/audit.js +48 -0
  20. package/dist/lib/mcp/engine.d.ts +28 -0
  21. package/dist/lib/mcp/engine.d.ts.map +1 -0
  22. package/dist/lib/mcp/engine.js +158 -0
  23. package/dist/lib/mcp/errors.d.ts +16 -0
  24. package/dist/lib/mcp/errors.d.ts.map +1 -0
  25. package/dist/lib/mcp/errors.js +66 -0
  26. package/dist/lib/mcp/executor.d.ts +15 -0
  27. package/dist/lib/mcp/executor.d.ts.map +1 -0
  28. package/dist/lib/mcp/executor.js +63 -0
  29. package/dist/lib/mcp/index.d.ts +9 -0
  30. package/dist/lib/mcp/index.d.ts.map +1 -0
  31. package/dist/lib/mcp/index.js +32 -0
  32. package/dist/lib/mcp/schema-builder.d.ts +45 -0
  33. package/dist/lib/mcp/schema-builder.d.ts.map +1 -0
  34. package/dist/lib/mcp/schema-builder.js +212 -0
  35. package/dist/lib/mcp/tool-generator.d.ts +31 -0
  36. package/dist/lib/mcp/tool-generator.d.ts.map +1 -0
  37. package/dist/lib/mcp/tool-generator.js +271 -0
  38. package/dist/lib/mcp/transport.d.ts +31 -0
  39. package/dist/lib/mcp/transport.d.ts.map +1 -0
  40. package/dist/lib/mcp/transport.js +58 -0
  41. package/dist/lib/mcp/types.d.ts +184 -0
  42. package/dist/lib/mcp/types.d.ts.map +1 -0
  43. package/dist/lib/mcp/types.js +11 -0
  44. package/dist/messages/de/auth.json +2 -0
  45. package/dist/messages/de/index.d.ts +2 -0
  46. package/dist/messages/de/index.d.ts.map +1 -1
  47. package/dist/messages/en/auth.json +3 -1
  48. package/dist/messages/en/index.d.ts +2 -0
  49. package/dist/messages/en/index.d.ts.map +1 -1
  50. package/dist/messages/es/auth.json +2 -0
  51. package/dist/messages/es/index.d.ts +2 -0
  52. package/dist/messages/es/index.d.ts.map +1 -1
  53. package/dist/messages/fr/auth.json +2 -0
  54. package/dist/messages/fr/index.d.ts +2 -0
  55. package/dist/messages/fr/index.d.ts.map +1 -1
  56. package/dist/messages/it/auth.json +2 -0
  57. package/dist/messages/it/index.d.ts +2 -0
  58. package/dist/messages/it/index.d.ts.map +1 -1
  59. package/dist/messages/pt/auth.json +2 -0
  60. package/dist/messages/pt/index.d.ts +2 -0
  61. package/dist/messages/pt/index.d.ts.map +1 -1
  62. package/dist/styles/classes.json +1 -1
  63. package/dist/styles/ui.css +1 -1
  64. package/dist/templates/app/api/mcp/route.ts +173 -0
  65. package/dist/templates/app/api/v1/api-keys/route.ts +15 -3
  66. package/dist/templates/app/layout.tsx +3 -0
  67. package/package.json +8 -3
  68. package/scripts/build/registry/__tests__/mcp-registry.test.mjs +64 -0
  69. package/scripts/build/registry/__tests__/scope-registry.test.mjs +88 -0
  70. package/scripts/build/registry/discovery/mcp-overrides.mjs +72 -0
  71. package/scripts/build/registry/discovery/mcp-overrides.test.mjs +86 -0
  72. package/scripts/build/registry/generators/mcp-registry.mjs +61 -0
  73. package/scripts/build/registry/generators/scope-registry.mjs +133 -88
  74. package/scripts/build/registry.mjs +8 -4
  75. package/templates/app/api/mcp/route.ts +173 -0
  76. package/templates/app/api/v1/api-keys/route.ts +15 -3
  77. package/templates/app/layout.tsx +3 -0
  78. package/tests/jest/__mocks__/@nextsparkjs/registries/scope-registry.ts +56 -6
  79. package/dist/lib/auth-client.d.ts +0 -3595
  80. package/dist/lib/auth-client.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"LoginForm.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/forms/LoginForm.tsx"],"names":[],"mappings":"AAmGA,wBAAgB,SAAS,4CA4YxB"}
1
+ {"version":3,"file":"LoginForm.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/forms/LoginForm.tsx"],"names":[],"mappings":"AAqGA,wBAAgB,SAAS,4CA6YxB"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { useState, useCallback, useRef, useEffect } from "react";
3
+ import { useState, useCallback, useRef, useEffect, useMemo } from "react";
4
4
  import Link from "next/link";
5
5
  import { useSearchParams } from "next/navigation";
6
6
  import { useForm } from "react-hook-form";
@@ -76,10 +76,12 @@ function getErrorCodeFromMessage(message) {
76
76
  }
77
77
  return "UNKNOWN_ERROR";
78
78
  }
79
- const loginSchema = z.object({
80
- email: z.string().email({ message: "Invalid email" }),
81
- password: z.string().min(6, "Password must be at least 6 characters")
82
- });
79
+ function buildLoginSchema(t) {
80
+ return z.object({
81
+ email: z.string().email({ message: t("login.errors.invalidEmail", { defaultValue: "Invalid email" }) }),
82
+ password: z.string().min(6, t("login.errors.passwordTooShort", { defaultValue: "Password must be at least 6 characters" }))
83
+ });
84
+ }
83
85
  function LoginForm() {
84
86
  var _a, _b, _c;
85
87
  const registrationMode = PUBLIC_AUTH_CONFIG.registration.mode;
@@ -95,6 +97,7 @@ function LoginForm() {
95
97
  const { signIn, googleSignIn } = useAuth();
96
98
  const { lastMethod, isReady } = useLastAuthMethod();
97
99
  const t = useTranslations("auth");
100
+ const loginSchema = useMemo(() => buildLoginSchema(t), [t]);
98
101
  const searchParams = useSearchParams();
99
102
  const inviteEmail = searchParams.get("email");
100
103
  const fromInvite = searchParams.get("fromInvite") === "true";
@@ -2,44 +2,54 @@ import type { SessionUser } from '../lib/auth';
2
2
  export declare function useAuth(): {
3
3
  user: SessionUser | null;
4
4
  session: {
5
- user: {
5
+ user: import("better-auth").StripEmptyObjects<{
6
6
  id: string;
7
- emailVerified: boolean;
8
- name: string;
9
7
  createdAt: Date;
10
8
  updatedAt: Date;
9
+ emailVerified: boolean;
10
+ name: string;
11
11
  email?: string;
12
12
  image?: string;
13
- };
14
- session: {
13
+ } & {} & {}>;
14
+ session: import("better-auth").StripEmptyObjects<{
15
15
  id: string;
16
- userId: string;
17
- expiresAt: Date;
18
16
  createdAt: Date;
19
17
  updatedAt: Date;
18
+ userId: string;
19
+ expiresAt: Date;
20
20
  token: string;
21
21
  ipAddress?: string;
22
22
  userAgent?: string;
23
- };
23
+ } & {} & {}>;
24
24
  };
25
25
  isLoading: boolean;
26
26
  signIn: ({ email, password, redirectTo }: {
27
27
  email: string;
28
28
  password: string;
29
29
  redirectTo?: string;
30
- }) => Promise<{
30
+ }) => Promise<Omit<{
31
31
  redirect: boolean;
32
32
  token: string;
33
- url: string | undefined;
33
+ url?: string | undefined;
34
34
  user: {
35
35
  id: string;
36
+ createdAt: Date;
37
+ updatedAt: Date;
36
38
  email: string;
37
- name: string;
38
- image: string | null | undefined;
39
39
  emailVerified: boolean;
40
+ name: string;
41
+ image?: string | null | undefined;
42
+ };
43
+ }, "user"> & {
44
+ user: import("better-auth").StripEmptyObjects<{
45
+ id: string;
40
46
  createdAt: Date;
41
47
  updatedAt: Date;
42
- };
48
+ emailVerified: boolean;
49
+ name: string;
50
+ email?: string;
51
+ image?: string;
52
+ } & {} & {}>;
43
53
  }>;
44
54
  signUp: ({ email, password, firstName, lastName, intent }: {
45
55
  email: string;
@@ -47,29 +57,49 @@ export declare function useAuth(): {
47
57
  firstName?: string;
48
58
  lastName?: string;
49
59
  intent?: string;
50
- }) => Promise<NonNullable<{
60
+ }) => Promise<(Omit<{
51
61
  token: null;
52
62
  user: {
53
63
  id: string;
64
+ createdAt: Date;
65
+ updatedAt: Date;
54
66
  email: string;
55
- name: string;
56
- image: string | null | undefined;
57
67
  emailVerified: boolean;
68
+ name: string;
69
+ image?: string | null | undefined;
70
+ };
71
+ }, "user"> & {
72
+ user: import("better-auth").StripEmptyObjects<{
73
+ id: string;
58
74
  createdAt: Date;
59
75
  updatedAt: Date;
60
- };
61
- } | {
76
+ emailVerified: boolean;
77
+ name: string;
78
+ email?: string;
79
+ image?: string;
80
+ } & {} & {}>;
81
+ }) | (Omit<{
62
82
  token: string;
63
83
  user: {
64
84
  id: string;
85
+ createdAt: Date;
86
+ updatedAt: Date;
65
87
  email: string;
66
- name: string;
67
- image: string | null | undefined;
68
88
  emailVerified: boolean;
89
+ name: string;
90
+ image?: string | null | undefined;
91
+ };
92
+ }, "user"> & {
93
+ user: import("better-auth").StripEmptyObjects<{
94
+ id: string;
69
95
  createdAt: Date;
70
96
  updatedAt: Date;
71
- };
72
- }>>;
97
+ emailVerified: boolean;
98
+ name: string;
99
+ email?: string;
100
+ image?: string;
101
+ } & {} & {}>;
102
+ })>;
73
103
  signOut: () => Promise<void>;
74
104
  googleSignIn: (redirectTo?: string) => Promise<void>;
75
105
  resetPassword: (email: string) => Promise<{
@@ -80,6 +110,7 @@ export declare function useAuth(): {
80
110
  success: boolean;
81
111
  data: {
82
112
  status: boolean;
113
+ message: string;
83
114
  };
84
115
  error: any;
85
116
  }>;
@@ -100,17 +131,35 @@ export declare function useAuth(): {
100
131
  error: string;
101
132
  } | {
102
133
  success: boolean;
103
- data: {
134
+ data: Omit<{
104
135
  token: string | null;
105
136
  user: {
106
137
  id: string;
138
+ createdAt: Date;
139
+ updatedAt: Date;
107
140
  email: string;
108
- name: string;
109
- image: string | null | undefined;
110
141
  emailVerified: boolean;
142
+ name: string;
143
+ image?: string | null | undefined;
144
+ } & Record<string, any> & {
145
+ id: string;
111
146
  createdAt: Date;
112
147
  updatedAt: Date;
148
+ email: string;
149
+ emailVerified: boolean;
150
+ name: string;
151
+ image?: string | null | undefined;
113
152
  };
153
+ }, "user"> & {
154
+ user: import("better-auth").StripEmptyObjects<{
155
+ id: string;
156
+ createdAt: Date;
157
+ updatedAt: Date;
158
+ emailVerified: boolean;
159
+ name: string;
160
+ email?: string;
161
+ image?: string;
162
+ } & {} & {}>;
114
163
  };
115
164
  error: any;
116
165
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../../src/hooks/useAuth.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAS9C,wBAAgB,OAAO;UAuMS,WAAW,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;8CAjMa;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;+DAmBvC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;gCAkC1H,MAAM;2BAYX,MAAM;;;;;;;;;;;kCA6BC,MAAM,UAAU,MAAM;;;;;;;;;;;sCAwClB,MAAM,eAAe,MAAM;;;;;;;;;;;;;;;;;;;;qCA8B5B,MAAM;;;;;;;;;;;;;;;EA6C3D"}
1
+ {"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../../src/hooks/useAuth.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAS9C,wBAAgB,OAAO;UAuMS,WAAW,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;8CAjMa;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;+DAmBvC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAkC1H,MAAM;2BAYX,MAAM;;;;;;;;;;;;kCA6BC,MAAM,UAAU,MAAM;;;;;;;;;;;sCAwClB,MAAM,eAAe,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCA8B5B,MAAM;;;;;;;;;;;;;;;EA6C3D"}
@@ -6,37 +6,37 @@ export declare function useValidationSchemas(): {
6
6
  login: import("zod").ZodObject<{
7
7
  email: import("zod").ZodString;
8
8
  password: import("zod").ZodString;
9
- }, import("better-auth").$strip>;
9
+ }, import("zod/v4/core").$strip>;
10
10
  signup: import("zod").ZodObject<{
11
11
  firstName: import("zod").ZodString;
12
12
  lastName: import("zod").ZodString;
13
13
  email: import("zod").ZodString;
14
14
  password: import("zod").ZodString;
15
15
  confirmPassword: import("zod").ZodString;
16
- }, import("better-auth").$strip>;
16
+ }, import("zod/v4/core").$strip>;
17
17
  resetPassword: import("zod").ZodObject<{
18
18
  email: import("zod").ZodString;
19
- }, import("better-auth").$strip>;
19
+ }, import("zod/v4/core").$strip>;
20
20
  newPassword: import("zod").ZodObject<{
21
21
  password: import("zod").ZodString;
22
22
  confirmPassword: import("zod").ZodString;
23
- }, import("better-auth").$strip>;
23
+ }, import("zod/v4/core").$strip>;
24
24
  changePassword: import("zod").ZodObject<{
25
25
  currentPassword: import("zod").ZodString;
26
26
  newPassword: import("zod").ZodString;
27
27
  confirmPassword: import("zod").ZodString;
28
28
  revokeOtherSessions: import("zod").ZodOptional<import("zod").ZodBoolean>;
29
- }, import("better-auth").$strip>;
29
+ }, import("zod/v4/core").$strip>;
30
30
  profile: import("zod").ZodObject<{
31
31
  firstName: import("zod").ZodString;
32
32
  lastName: import("zod").ZodString;
33
33
  country: import("zod").ZodString;
34
34
  timezone: import("zod").ZodString;
35
35
  language: import("zod").ZodString;
36
- }, import("better-auth").$strip>;
36
+ }, import("zod/v4/core").$strip>;
37
37
  task: import("zod").ZodObject<{
38
38
  title: import("zod").ZodString;
39
39
  description: import("zod").ZodOptional<import("zod").ZodString>;
40
- }, import("better-auth").$strip>;
40
+ }, import("zod/v4/core").$strip>;
41
41
  };
42
42
  //# sourceMappingURL=useValidationSchemas.d.ts.map
@@ -49,6 +49,13 @@ export interface DualAuthResult {
49
49
  export declare function authenticateRequest(request: NextRequest): Promise<DualAuthResult>;
50
50
  /**
51
51
  * Check if user has required scope (for API Key auth)
52
+ *
53
+ * `admin:all` was previously accepted as an implicit full-access scope here,
54
+ * but it was never in `API_SCOPES`, never mintable via `validateScopesForUser`,
55
+ * and undocumented — a full-access string nothing legitimately produced.
56
+ * Removed rather than formalized: the wildcard `*` (mintable only by a real
57
+ * superadmin, see `validateScopesForUser`) already covers the "this key has
58
+ * full access" case in a documented, auditable way.
52
59
  */
53
60
  export declare function hasRequiredScope(authResult: DualAuthResult, requiredScope: string): boolean;
54
61
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"dual-auth.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/auth/dual-auth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAUvD;;;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,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAA;IACpC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,iBAAiB,CAAC,EAAE,QAAQ,CAAA;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5D;AAqBD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CAkBvF;AAqKD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAY3F;AAMD;;;;;;;;;;;;;GAaG;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;AAkBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,MAAkC,EAAE,MAAM,GAAE,MAAY;;;;GAShG"}
1
+ {"version":3,"file":"dual-auth.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/auth/dual-auth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAUvD;;;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,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAA;IACpC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,iBAAiB,CAAC,EAAE,QAAQ,CAAA;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5D;AAqBD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CAkBvF;AAqKD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAW3F;AAMD;;;;;;;;;;;;;GAaG;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;AAkBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,MAAkC,EAAE,MAAM,GAAE,MAAY;;;;GAShG"}
@@ -145,7 +145,7 @@ function hasRequiredScope(authResult, requiredScope) {
145
145
  return true;
146
146
  }
147
147
  if (authResult.type === "api-key" && authResult.scopes) {
148
- return authResult.scopes.includes(requiredScope) || authResult.scopes.includes("admin:all") || authResult.scopes.includes("*");
148
+ return authResult.scopes.includes(requiredScope) || authResult.scopes.includes("*");
149
149
  }
150
150
  return false;
151
151
  }
@@ -44,13 +44,30 @@ export declare function getApiKeyUser(auth: ApiKeyAuth): Promise<{
44
44
  role: string;
45
45
  }>;
46
46
  /**
47
- * Verifica si un usuario puede crear API keys
47
+ * Verifica si un usuario puede crear API keys.
48
+ *
49
+ * Superadmin is a GLOBAL role (`users.role`) and is always allowed. Any
50
+ * other user is allowed only if they hold a team role that itself grants
51
+ * `admin:api-keys`/`admin:users`-equivalent scopes for at least one team —
52
+ * i.e. the same source of truth `validateScopesForUser` uses, checked
53
+ * without a specific team in mind (any qualifying membership is enough).
48
54
  */
49
55
  export declare function canCreateApiKeys(userId: string): Promise<boolean>;
50
56
  /**
51
- * Valida que los scopes solicitados sean permitidos para el usuario
57
+ * Valida que los scopes solicitados sean permitidos para el usuario, en el
58
+ * contexto de un team específico.
59
+ *
60
+ * Superadmin is a GLOBAL role (`users.role`) — it never appears in
61
+ * `AVAILABLE_ROLES` (team roles), so it's special-cased here rather than
62
+ * inside the scope registry. Every other user is resolved through their
63
+ * TEAM role for `teamId` (not their global `users.role` — NextSpark's
64
+ * entity authorization model is team-scoped, see `app.config.ts`), and the
65
+ * allowed-scope set comes from the same registry-backed
66
+ * `ScopeService.getRoleScopes()` that session auth's implicit scopes
67
+ * (`generateScopesForRole` in `helpers.ts`) and `checkPermission()` both
68
+ * ultimately derive from — so minting and enforcement can't diverge again.
52
69
  */
53
- export declare function validateScopesForUser(userId: string, requestedScopes: string[]): Promise<{
70
+ export declare function validateScopesForUser(userId: string, teamId: string | null, requestedScopes: string[]): Promise<{
54
71
  valid: boolean;
55
72
  allowedScopes: string[];
56
73
  deniedScopes: string[];
@@ -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;AAK1C;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAEnF;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAoHrF;AAiDD;;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;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBvE;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC9F,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC,CAuDD"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/lib/api/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO1C;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAEnF;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAoHrF;AAiDD;;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,6 +1,8 @@
1
1
  import { queryOne } from "../db.js";
2
2
  import { ApiKeyManager } from "./keys.js";
3
3
  import { apiKeyCache, getCacheKey } from "./cache.js";
4
+ import { TeamMemberService } from "../services/team-member.service.js";
5
+ import { ScopeService } from "../services/scope.service.js";
4
6
  function hasScope(auth, requiredScope) {
5
7
  return auth.scopes.includes(requiredScope);
6
8
  }
@@ -154,13 +156,20 @@ async function canCreateApiKeys(userId) {
154
156
  if (!user) {
155
157
  return false;
156
158
  }
157
- return ["admin", "superadmin"].includes(user.role);
159
+ if (user.role === "superadmin") {
160
+ return true;
161
+ }
162
+ const memberships = await TeamMemberService.listByUser(userId);
163
+ return memberships.some(({ role }) => {
164
+ const scopes = ScopeService.getRoleScopes(role);
165
+ return scopes.includes("*") || scopes.includes("admin:api-keys");
166
+ });
158
167
  } catch (error) {
159
168
  console.error("Error checking API key creation permissions:", error);
160
169
  return false;
161
170
  }
162
171
  }
163
- async function validateScopesForUser(userId, requestedScopes) {
172
+ async function validateScopesForUser(userId, teamId, requestedScopes) {
164
173
  try {
165
174
  const user = await queryOne(
166
175
  'SELECT role FROM "users" WHERE id = $1',
@@ -173,23 +182,32 @@ async function validateScopesForUser(userId, requestedScopes) {
173
182
  deniedScopes: requestedScopes
174
183
  };
175
184
  }
176
- const scopesByRole = {
177
- member: ["tasks:read", "tasks:write"],
178
- colaborator: ["tasks:read", "tasks:write", "tasks:delete", "users:read"],
179
- admin: [
180
- "users:read",
181
- "users:write",
182
- "users:delete",
183
- "tasks:read",
184
- "tasks:write",
185
- "tasks:delete",
186
- "admin:api-keys",
187
- "admin:users"
188
- ],
189
- superadmin: ["*"]
190
- // Acceso completo
191
- };
192
- const allowedScopes = scopesByRole[user.role] || [];
185
+ if (user.role === "superadmin") {
186
+ return {
187
+ valid: true,
188
+ allowedScopes: requestedScopes,
189
+ deniedScopes: []
190
+ };
191
+ }
192
+ if (!teamId) {
193
+ return {
194
+ valid: false,
195
+ allowedScopes: [],
196
+ deniedScopes: requestedScopes
197
+ };
198
+ }
199
+ const teamRole = await TeamMemberService.getRole(teamId, userId);
200
+ if (!teamRole) {
201
+ return {
202
+ valid: false,
203
+ allowedScopes: [],
204
+ deniedScopes: requestedScopes
205
+ };
206
+ }
207
+ const allowedScopes = [
208
+ ...ScopeService.getBaseScopes(),
209
+ ...ScopeService.getRoleScopes(teamRole)
210
+ ];
193
211
  if (allowedScopes.includes("*")) {
194
212
  return {
195
213
  valid: true,
@@ -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;AA8iBvD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAugBnF;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAmZrF;AAED;;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,CA0MpJ;AAED;;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,CAyXtJ;AAED;;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,CAoJtJ;AAED;;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;AAmjBvD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAwgBnF;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAoZrF;AAED;;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,CA0MpJ;AAED;;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,CA2XtJ;AAED;;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,CAyJtJ;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAEtF"}
@@ -193,11 +193,11 @@ function getTeamIdFromRequest(request) {
193
193
  function isBuilderRequest(request) {
194
194
  return request.headers.get("x-builder-source") === "true";
195
195
  }
196
- async function resolveOwnershipFilter(entityConfig, userId, teamId, isBypass, authType) {
196
+ async function resolveOwnershipFilter(entityConfig, userId, teamId, isBypass) {
197
197
  var _a;
198
198
  const ownershipFilter = (_a = entityConfig.access) == null ? void 0 : _a.ownershipFilter;
199
199
  if (!ownershipFilter) return { applies: false };
200
- if (isBypass || authType === "api-key") return { applies: false };
200
+ if (isBypass) return { applies: false };
201
201
  const memberRow = await queryOneWithRLS(
202
202
  'SELECT role FROM "team_members" WHERE "teamId" = $1 AND "userId" = $2',
203
203
  [teamId, userId],
@@ -221,9 +221,9 @@ async function resolveOwnershipFilter(entityConfig, userId, teamId, isBypass, au
221
221
  const filterValue = linkedRow ? linkedRow[valueField] ?? null : null;
222
222
  return { applies: true, field: ownershipFilter.field, value: filterValue };
223
223
  }
224
- async function checkSessionPermission(authResult, entitySlug, action, teamId, request) {
224
+ async function checkAuthPermission(authResult, entitySlug, action, teamId, request) {
225
225
  var _a;
226
- if (authResult.type !== "session" || !((_a = authResult.user) == null ? void 0 : _a.id)) return null;
226
+ if (!((_a = authResult.user) == null ? void 0 : _a.id)) return null;
227
227
  const permission = `${entitySlug}.${action}`;
228
228
  try {
229
229
  const allowed = await checkPermission(authResult.user.id, teamId, permission);
@@ -330,7 +330,7 @@ async function handleGenericList(request) {
330
330
  teamId = teamValidation.teamId;
331
331
  isBypass = teamValidation.isBypass;
332
332
  if (!isBypass && teamId) {
333
- const permDenied = await checkSessionPermission(authResult, resolution.entityConfig.slug, "list", teamId, request);
333
+ const permDenied = await checkAuthPermission(authResult, resolution.entityConfig.slug, "list", teamId, request);
334
334
  if (permDenied) return permDenied;
335
335
  }
336
336
  }
@@ -413,8 +413,7 @@ async function handleGenericList(request) {
413
413
  entityConfig,
414
414
  userId,
415
415
  teamId,
416
- isBypass,
417
- authResult.type
416
+ isBypass
418
417
  );
419
418
  }
420
419
  if (ownershipFilter.applies && ownershipFilter.value === null) {
@@ -714,7 +713,7 @@ async function handleGenericCreate(request) {
714
713
  const response2 = createApiError("Team context required for create operations. Include x-team-id header.", 400, void 0, "TEAM_CONTEXT_REQUIRED");
715
714
  return addCorsHeaders(response2, request);
716
715
  }
717
- const permDenied = await checkSessionPermission(authResult, entityConfig.slug, "create", teamId, request);
716
+ const permDenied = await checkAuthPermission(authResult, entityConfig.slug, "create", teamId, request);
718
717
  if (permDenied) return permDenied;
719
718
  if (idStrategy === "serial") {
720
719
  insertFields = ['"userId"', '"teamId"'];
@@ -938,7 +937,7 @@ async function handleGenericRead(request, { params }) {
938
937
  teamId = teamValidation.teamId;
939
938
  isBypass = teamValidation.isBypass;
940
939
  if (!isBypass && teamId) {
941
- const permDenied = await checkSessionPermission(authResult, resolution.entityConfig.slug, "read", teamId, request);
940
+ const permDenied = await checkAuthPermission(authResult, resolution.entityConfig.slug, "read", teamId, request);
942
941
  if (permDenied) return permDenied;
943
942
  }
944
943
  }
@@ -982,8 +981,7 @@ async function handleGenericRead(request, { params }) {
982
981
  entityConfig,
983
982
  userId,
984
983
  teamId,
985
- isBypass,
986
- authResult.type
984
+ isBypass
987
985
  );
988
986
  if (readOwnershipFilter.applies) {
989
987
  if (readOwnershipFilter.value === null) {
@@ -1045,7 +1043,7 @@ async function handleGenericRead(request, { params }) {
1045
1043
  }
1046
1044
  }
1047
1045
  async function handleGenericUpdate(request, { params }) {
1048
- var _a, _b, _c, _d, _e, _f;
1046
+ var _a, _b, _c, _d, _e, _f, _g;
1049
1047
  try {
1050
1048
  const { id } = await params;
1051
1049
  const resolution = await resolveEntityFromUrl(request.nextUrl.pathname);
@@ -1080,7 +1078,7 @@ async function handleGenericUpdate(request, { params }) {
1080
1078
  const response2 = createApiError("Team context required for update operations. Include x-team-id header.", 400, void 0, "TEAM_CONTEXT_REQUIRED");
1081
1079
  return addCorsHeaders(response2, request);
1082
1080
  }
1083
- const permDenied = await checkSessionPermission(authResult, resolution.entityConfig.slug, "update", teamId, request);
1081
+ const permDenied = await checkAuthPermission(authResult, resolution.entityConfig.slug, "update", teamId, request);
1084
1082
  if (permDenied) return permDenied;
1085
1083
  let body;
1086
1084
  try {
@@ -1092,7 +1090,7 @@ async function handleGenericUpdate(request, { params }) {
1092
1090
  const { metas, ...entityData } = body;
1093
1091
  const entityConfig = resolution.entityConfig;
1094
1092
  const fieldGuards = (_b = (_a = entityConfig.access) == null ? void 0 : _a.ownershipFilter) == null ? void 0 : _b.fieldGuards;
1095
- if (fieldGuards && fieldGuards.length > 0 && authResult.type === "session") {
1093
+ if (fieldGuards && fieldGuards.length > 0 && ((_c = authResult.user) == null ? void 0 : _c.id)) {
1096
1094
  const guardMemberRow = await queryOneWithRLS(
1097
1095
  'SELECT role FROM "team_members" WHERE "teamId" = $1 AND "userId" = $2',
1098
1096
  [teamId, authResult.user.id],
@@ -1141,7 +1139,7 @@ async function handleGenericUpdate(request, { params }) {
1141
1139
  const values = [];
1142
1140
  let paramCount = 1;
1143
1141
  const builderRequest = isBuilderRequest(request);
1144
- const entityHasBuilder = ((_c = entityConfig.builder) == null ? void 0 : _c.enabled) === true;
1142
+ const entityHasBuilder = ((_d = entityConfig.builder) == null ? void 0 : _d.enabled) === true;
1145
1143
  if (builderRequest && entityHasBuilder && "blocks" in entityData) {
1146
1144
  let blocksData = entityData.blocks;
1147
1145
  blocksData = await filterOrphanedPatternReferences(blocksData, authResult.user.id);
@@ -1217,7 +1215,7 @@ async function handleGenericUpdate(request, { params }) {
1217
1215
  whereConditions.push(`"teamId" = $${paramCount++}`);
1218
1216
  values.push(teamId);
1219
1217
  }
1220
- if (!((_d = entityConfig.access) == null ? void 0 : _d.shared)) {
1218
+ if (!((_e = entityConfig.access) == null ? void 0 : _e.shared)) {
1221
1219
  whereConditions.push(`"userId" = $${paramCount++}`);
1222
1220
  values.push(authResult.user.id);
1223
1221
  }
@@ -1225,8 +1223,7 @@ async function handleGenericUpdate(request, { params }) {
1225
1223
  entityConfig,
1226
1224
  authResult.user.id,
1227
1225
  teamId,
1228
- teamValidation.isBypass,
1229
- authResult.type
1226
+ teamValidation.isBypass
1230
1227
  );
1231
1228
  if (updateOwnershipFilter.applies) {
1232
1229
  if (updateOwnershipFilter.value === null) {
@@ -1262,7 +1259,7 @@ async function handleGenericUpdate(request, { params }) {
1262
1259
  }
1263
1260
  updatedItem = result[0];
1264
1261
  }
1265
- if ((_e = entityConfig.taxonomies) == null ? void 0 : _e.enabled) {
1262
+ if ((_f = entityConfig.taxonomies) == null ? void 0 : _f.enabled) {
1266
1263
  await processTaxonomyRelations(entityConfig, id, body, authResult.user.id, true);
1267
1264
  }
1268
1265
  if (metadataWasProvided) {
@@ -1274,7 +1271,7 @@ async function handleGenericUpdate(request, { params }) {
1274
1271
  );
1275
1272
  }
1276
1273
  let responseItem = updatedItem;
1277
- if ((_f = entityConfig.taxonomies) == null ? void 0 : _f.enabled) {
1274
+ if ((_g = entityConfig.taxonomies) == null ? void 0 : _g.enabled) {
1278
1275
  const itemsWithTaxonomies = await includeTaxonomiesInData(
1279
1276
  entityConfig,
1280
1277
  [updatedItem],
@@ -1335,7 +1332,7 @@ async function handleGenericDelete(request, { params }) {
1335
1332
  if (authResult.rateLimitResponse) {
1336
1333
  return authResult.rateLimitResponse;
1337
1334
  }
1338
- if (!hasRequiredScope(authResult, `${resolution.entityConfig.slug}:write`)) {
1335
+ if (!hasRequiredScope(authResult, `${resolution.entityConfig.slug}:delete`)) {
1339
1336
  const response2 = createApiError("Insufficient permissions", 403);
1340
1337
  return addCorsHeaders(response2, request);
1341
1338
  }
@@ -1348,7 +1345,7 @@ async function handleGenericDelete(request, { params }) {
1348
1345
  const response2 = createApiError("Team context required for delete operations. Include x-team-id header.", 400, void 0, "TEAM_CONTEXT_REQUIRED");
1349
1346
  return addCorsHeaders(response2, request);
1350
1347
  }
1351
- const permDenied = await checkSessionPermission(authResult, resolution.entityConfig.slug, "delete", teamId, request);
1348
+ const permDenied = await checkAuthPermission(authResult, resolution.entityConfig.slug, "delete", teamId, request);
1352
1349
  if (permDenied) return permDenied;
1353
1350
  const entityConfig = resolution.entityConfig;
1354
1351
  const tableName = getTableName(entityConfig);