better-auth 1.6.9 → 1.6.11

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 (71) hide show
  1. package/dist/api/index.d.mts +0 -2
  2. package/dist/api/routes/callback.mjs +6 -5
  3. package/dist/api/routes/email-verification.mjs +2 -2
  4. package/dist/api/routes/error.mjs +1 -1
  5. package/dist/api/routes/sign-in.d.mts +0 -1
  6. package/dist/api/routes/sign-in.mjs +4 -11
  7. package/dist/api/routes/sign-up.mjs +1 -1
  8. package/dist/api/routes/update-user.mjs +1 -1
  9. package/dist/api/to-auth-endpoints.mjs +7 -1
  10. package/dist/client/index.d.mts +2 -2
  11. package/dist/client/plugins/index.d.mts +2 -1
  12. package/dist/cookies/cookie-utils.d.mts +10 -1
  13. package/dist/cookies/cookie-utils.mjs +19 -1
  14. package/dist/cookies/index.d.mts +2 -2
  15. package/dist/cookies/index.mjs +2 -2
  16. package/dist/db/internal-adapter.mjs +103 -7
  17. package/dist/db/with-hooks.d.mts +1 -0
  18. package/dist/db/with-hooks.mjs +58 -1
  19. package/dist/integrations/cookie-plugin-guard.mjs +18 -0
  20. package/dist/integrations/next-js.mjs +6 -0
  21. package/dist/integrations/svelte-kit.mjs +6 -0
  22. package/dist/integrations/tanstack-start-solid.mjs +6 -0
  23. package/dist/integrations/tanstack-start.mjs +6 -0
  24. package/dist/oauth2/link-account.mjs +3 -1
  25. package/dist/package.mjs +1 -1
  26. package/dist/plugins/access/access.d.mts +3 -15
  27. package/dist/plugins/access/index.d.mts +2 -2
  28. package/dist/plugins/access/types.d.mts +11 -4
  29. package/dist/plugins/admin/access/statement.d.mts +29 -93
  30. package/dist/plugins/admin/client.d.mts +5 -0
  31. package/dist/plugins/admin/client.mjs +5 -0
  32. package/dist/plugins/admin/routes.mjs +1 -0
  33. package/dist/plugins/anonymous/client.d.mts +1 -0
  34. package/dist/plugins/anonymous/error-codes.d.mts +1 -0
  35. package/dist/plugins/anonymous/error-codes.mjs +1 -0
  36. package/dist/plugins/anonymous/index.d.mts +1 -0
  37. package/dist/plugins/anonymous/index.mjs +16 -2
  38. package/dist/plugins/bearer/index.mjs +2 -4
  39. package/dist/plugins/captcha/index.mjs +14 -1
  40. package/dist/plugins/device-authorization/error-codes.mjs +1 -0
  41. package/dist/plugins/device-authorization/index.d.mts +1 -0
  42. package/dist/plugins/device-authorization/routes.mjs +34 -3
  43. package/dist/plugins/email-otp/routes.mjs +3 -3
  44. package/dist/plugins/generic-oauth/routes.mjs +3 -3
  45. package/dist/plugins/index.d.mts +2 -2
  46. package/dist/plugins/magic-link/index.d.mts +8 -1
  47. package/dist/plugins/magic-link/index.mjs +5 -17
  48. package/dist/plugins/mcp/authorize.mjs +8 -2
  49. package/dist/plugins/mcp/index.mjs +73 -30
  50. package/dist/plugins/oidc-provider/authorize.mjs +8 -2
  51. package/dist/plugins/oidc-provider/index.mjs +63 -33
  52. package/dist/plugins/one-tap/index.mjs +16 -10
  53. package/dist/plugins/organization/access/statement.d.mts +68 -201
  54. package/dist/plugins/organization/client.d.mts +1 -0
  55. package/dist/plugins/organization/client.mjs +1 -1
  56. package/dist/plugins/organization/error-codes.d.mts +1 -0
  57. package/dist/plugins/organization/error-codes.mjs +1 -0
  58. package/dist/plugins/organization/routes/crud-access-control.d.mts +2 -2
  59. package/dist/plugins/organization/routes/crud-invites.d.mts +8 -1
  60. package/dist/plugins/organization/routes/crud-invites.mjs +5 -3
  61. package/dist/plugins/organization/routes/crud-team.mjs +7 -2
  62. package/dist/plugins/organization/types.d.mts +12 -2
  63. package/dist/plugins/siwe/client.d.mts +4 -0
  64. package/dist/plugins/siwe/client.mjs +5 -1
  65. package/dist/plugins/siwe/index.d.mts +13 -2
  66. package/dist/plugins/siwe/index.mjs +179 -165
  67. package/dist/plugins/username/index.d.mts +11 -0
  68. package/dist/plugins/username/index.mjs +18 -2
  69. package/dist/test-utils/test-instance.d.mts +1 -6
  70. package/dist/test-utils/test-instance.mjs +11 -2
  71. package/package.json +10 -10
@@ -1,5 +1,4 @@
1
- import { Subset } from "../../access/types.mjs";
2
- import { AuthorizeResponse } from "../../access/access.mjs";
1
+ import { ExactRoleStatements, Role, RoleInput, Statements } from "../../access/types.mjs";
3
2
  //#region src/plugins/organization/access/statement.d.ts
4
3
  declare const defaultStatements: {
5
4
  readonly organization: readonly ["update", "delete"];
@@ -9,137 +8,100 @@ declare const defaultStatements: {
9
8
  readonly ac: readonly ["create", "read", "update", "delete"];
10
9
  };
11
10
  declare const defaultAc: {
12
- newRole<K extends "organization" | "member" | "team" | "ac" | "invitation">(statements: Subset<K, {
11
+ newRole<const TRoleStatements extends Statements>(statements: RoleInput<{
13
12
  readonly organization: readonly ["update", "delete"];
14
13
  readonly member: readonly ["create", "update", "delete"];
15
14
  readonly invitation: readonly ["create", "cancel"];
16
15
  readonly team: readonly ["create", "update", "delete"];
17
16
  readonly ac: readonly ["create", "read", "update", "delete"];
18
- }>): {
19
- authorize<K_1 extends K>(request: K_1 extends infer T extends keyof Subset<K, {
20
- readonly organization: readonly ["update", "delete"];
21
- readonly member: readonly ["create", "update", "delete"];
22
- readonly invitation: readonly ["create", "cancel"];
23
- readonly team: readonly ["create", "update", "delete"];
24
- readonly ac: readonly ["create", "read", "update", "delete"];
25
- }> ? { [key in T]?: Subset<K, {
26
- readonly organization: readonly ["update", "delete"];
27
- readonly member: readonly ["create", "update", "delete"];
28
- readonly invitation: readonly ["create", "cancel"];
29
- readonly team: readonly ["create", "update", "delete"];
30
- readonly ac: readonly ["create", "read", "update", "delete"];
31
- }>[key] | {
32
- actions: Subset<K, {
33
- readonly organization: readonly ["update", "delete"];
34
- readonly member: readonly ["create", "update", "delete"];
35
- readonly invitation: readonly ["create", "cancel"];
36
- readonly team: readonly ["create", "update", "delete"];
37
- readonly ac: readonly ["create", "read", "update", "delete"];
38
- }>[key];
39
- connector: "OR" | "AND";
40
- } | undefined } : never, connector?: "OR" | "AND"): AuthorizeResponse;
41
- statements: Subset<K, {
42
- readonly organization: readonly ["update", "delete"];
43
- readonly member: readonly ["create", "update", "delete"];
44
- readonly invitation: readonly ["create", "cancel"];
45
- readonly team: readonly ["create", "update", "delete"];
46
- readonly ac: readonly ["create", "read", "update", "delete"];
47
- }>;
48
- };
49
- statements: {
50
- readonly organization: readonly ["update", "delete"];
51
- readonly member: readonly ["create", "update", "delete"];
52
- readonly invitation: readonly ["create", "cancel"];
53
- readonly team: readonly ["create", "update", "delete"];
54
- readonly ac: readonly ["create", "read", "update", "delete"];
55
- };
56
- };
57
- declare const adminAc: {
58
- authorize<K extends "organization" | "member" | "team" | "ac" | "invitation">(request: K extends infer T extends keyof Subset<"organization" | "member" | "team" | "ac" | "invitation", {
59
- readonly organization: readonly ["update", "delete"];
60
- readonly member: readonly ["create", "update", "delete"];
61
- readonly invitation: readonly ["create", "cancel"];
62
- readonly team: readonly ["create", "update", "delete"];
63
- readonly ac: readonly ["create", "read", "update", "delete"];
64
- }> ? { [key in T]?: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
65
- readonly organization: readonly ["update", "delete"];
66
- readonly member: readonly ["create", "update", "delete"];
67
- readonly invitation: readonly ["create", "cancel"];
68
- readonly team: readonly ["create", "update", "delete"];
69
- readonly ac: readonly ["create", "read", "update", "delete"];
70
- }>[key] | {
71
- actions: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
72
- readonly organization: readonly ["update", "delete"];
73
- readonly member: readonly ["create", "update", "delete"];
74
- readonly invitation: readonly ["create", "cancel"];
75
- readonly team: readonly ["create", "update", "delete"];
76
- readonly ac: readonly ["create", "read", "update", "delete"];
77
- }>[key];
78
- connector: "OR" | "AND";
79
- } | undefined } : never, connector?: "OR" | "AND"): AuthorizeResponse;
80
- statements: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
17
+ }, TRoleStatements>): Role<ExactRoleStatements<TRoleStatements>, {
81
18
  readonly organization: readonly ["update", "delete"];
82
19
  readonly member: readonly ["create", "update", "delete"];
83
20
  readonly invitation: readonly ["create", "cancel"];
84
21
  readonly team: readonly ["create", "update", "delete"];
85
22
  readonly ac: readonly ["create", "read", "update", "delete"];
86
23
  }>;
87
- };
88
- declare const ownerAc: {
89
- authorize<K extends "organization" | "member" | "team" | "ac" | "invitation">(request: K extends infer T extends keyof Subset<"organization" | "member" | "team" | "ac" | "invitation", {
90
- readonly organization: readonly ["update", "delete"];
91
- readonly member: readonly ["create", "update", "delete"];
92
- readonly invitation: readonly ["create", "cancel"];
93
- readonly team: readonly ["create", "update", "delete"];
94
- readonly ac: readonly ["create", "read", "update", "delete"];
95
- }> ? { [key in T]?: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
96
- readonly organization: readonly ["update", "delete"];
97
- readonly member: readonly ["create", "update", "delete"];
98
- readonly invitation: readonly ["create", "cancel"];
99
- readonly team: readonly ["create", "update", "delete"];
100
- readonly ac: readonly ["create", "read", "update", "delete"];
101
- }>[key] | {
102
- actions: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
103
- readonly organization: readonly ["update", "delete"];
104
- readonly member: readonly ["create", "update", "delete"];
105
- readonly invitation: readonly ["create", "cancel"];
106
- readonly team: readonly ["create", "update", "delete"];
107
- readonly ac: readonly ["create", "read", "update", "delete"];
108
- }>[key];
109
- connector: "OR" | "AND";
110
- } | undefined } : never, connector?: "OR" | "AND"): AuthorizeResponse;
111
- statements: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
24
+ statements: {
112
25
  readonly organization: readonly ["update", "delete"];
113
26
  readonly member: readonly ["create", "update", "delete"];
114
27
  readonly invitation: readonly ["create", "cancel"];
115
28
  readonly team: readonly ["create", "update", "delete"];
116
29
  readonly ac: readonly ["create", "read", "update", "delete"];
117
- }>;
30
+ };
118
31
  };
119
- declare const memberAc: {
120
- authorize<K extends "organization" | "member" | "team" | "ac" | "invitation">(request: K extends infer T extends keyof Subset<"organization" | "member" | "team" | "ac" | "invitation", {
32
+ declare const adminAc: Role<ExactRoleStatements<{
33
+ readonly organization: ["update"];
34
+ readonly invitation: ["create", "cancel"];
35
+ readonly member: ["create", "update", "delete"];
36
+ readonly team: ["create", "update", "delete"];
37
+ readonly ac: ["create", "read", "update", "delete"];
38
+ }>, {
39
+ readonly organization: readonly ["update", "delete"];
40
+ readonly member: readonly ["create", "update", "delete"];
41
+ readonly invitation: readonly ["create", "cancel"];
42
+ readonly team: readonly ["create", "update", "delete"];
43
+ readonly ac: readonly ["create", "read", "update", "delete"];
44
+ }>;
45
+ declare const ownerAc: Role<ExactRoleStatements<{
46
+ readonly organization: ["update", "delete"];
47
+ readonly member: ["create", "update", "delete"];
48
+ readonly invitation: ["create", "cancel"];
49
+ readonly team: ["create", "update", "delete"];
50
+ readonly ac: ["create", "read", "update", "delete"];
51
+ }>, {
52
+ readonly organization: readonly ["update", "delete"];
53
+ readonly member: readonly ["create", "update", "delete"];
54
+ readonly invitation: readonly ["create", "cancel"];
55
+ readonly team: readonly ["create", "update", "delete"];
56
+ readonly ac: readonly ["create", "read", "update", "delete"];
57
+ }>;
58
+ declare const memberAc: Role<ExactRoleStatements<{
59
+ readonly organization: [];
60
+ readonly member: [];
61
+ readonly invitation: [];
62
+ readonly team: [];
63
+ readonly ac: ["read"];
64
+ }>, {
65
+ readonly organization: readonly ["update", "delete"];
66
+ readonly member: readonly ["create", "update", "delete"];
67
+ readonly invitation: readonly ["create", "cancel"];
68
+ readonly team: readonly ["create", "update", "delete"];
69
+ readonly ac: readonly ["create", "read", "update", "delete"];
70
+ }>;
71
+ declare const defaultRoles: {
72
+ admin: Role<ExactRoleStatements<{
73
+ readonly organization: ["update"];
74
+ readonly invitation: ["create", "cancel"];
75
+ readonly member: ["create", "update", "delete"];
76
+ readonly team: ["create", "update", "delete"];
77
+ readonly ac: ["create", "read", "update", "delete"];
78
+ }>, {
121
79
  readonly organization: readonly ["update", "delete"];
122
80
  readonly member: readonly ["create", "update", "delete"];
123
81
  readonly invitation: readonly ["create", "cancel"];
124
82
  readonly team: readonly ["create", "update", "delete"];
125
83
  readonly ac: readonly ["create", "read", "update", "delete"];
126
- }> ? { [key in T]?: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
84
+ }>;
85
+ owner: Role<ExactRoleStatements<{
86
+ readonly organization: ["update", "delete"];
87
+ readonly member: ["create", "update", "delete"];
88
+ readonly invitation: ["create", "cancel"];
89
+ readonly team: ["create", "update", "delete"];
90
+ readonly ac: ["create", "read", "update", "delete"];
91
+ }>, {
127
92
  readonly organization: readonly ["update", "delete"];
128
93
  readonly member: readonly ["create", "update", "delete"];
129
94
  readonly invitation: readonly ["create", "cancel"];
130
95
  readonly team: readonly ["create", "update", "delete"];
131
96
  readonly ac: readonly ["create", "read", "update", "delete"];
132
- }>[key] | {
133
- actions: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
134
- readonly organization: readonly ["update", "delete"];
135
- readonly member: readonly ["create", "update", "delete"];
136
- readonly invitation: readonly ["create", "cancel"];
137
- readonly team: readonly ["create", "update", "delete"];
138
- readonly ac: readonly ["create", "read", "update", "delete"];
139
- }>[key];
140
- connector: "OR" | "AND";
141
- } | undefined } : never, connector?: "OR" | "AND"): AuthorizeResponse;
142
- statements: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
97
+ }>;
98
+ member: Role<ExactRoleStatements<{
99
+ readonly organization: [];
100
+ readonly member: [];
101
+ readonly invitation: [];
102
+ readonly team: [];
103
+ readonly ac: ["read"];
104
+ }>, {
143
105
  readonly organization: readonly ["update", "delete"];
144
106
  readonly member: readonly ["create", "update", "delete"];
145
107
  readonly invitation: readonly ["create", "cancel"];
@@ -147,100 +109,5 @@ declare const memberAc: {
147
109
  readonly ac: readonly ["create", "read", "update", "delete"];
148
110
  }>;
149
111
  };
150
- declare const defaultRoles: {
151
- admin: {
152
- authorize<K extends "organization" | "member" | "team" | "ac" | "invitation">(request: K extends infer T extends keyof Subset<"organization" | "member" | "team" | "ac" | "invitation", {
153
- readonly organization: readonly ["update", "delete"];
154
- readonly member: readonly ["create", "update", "delete"];
155
- readonly invitation: readonly ["create", "cancel"];
156
- readonly team: readonly ["create", "update", "delete"];
157
- readonly ac: readonly ["create", "read", "update", "delete"];
158
- }> ? { [key in T]?: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
159
- readonly organization: readonly ["update", "delete"];
160
- readonly member: readonly ["create", "update", "delete"];
161
- readonly invitation: readonly ["create", "cancel"];
162
- readonly team: readonly ["create", "update", "delete"];
163
- readonly ac: readonly ["create", "read", "update", "delete"];
164
- }>[key] | {
165
- actions: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
166
- readonly organization: readonly ["update", "delete"];
167
- readonly member: readonly ["create", "update", "delete"];
168
- readonly invitation: readonly ["create", "cancel"];
169
- readonly team: readonly ["create", "update", "delete"];
170
- readonly ac: readonly ["create", "read", "update", "delete"];
171
- }>[key];
172
- connector: "OR" | "AND";
173
- } | undefined } : never, connector?: "OR" | "AND"): AuthorizeResponse;
174
- statements: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
175
- readonly organization: readonly ["update", "delete"];
176
- readonly member: readonly ["create", "update", "delete"];
177
- readonly invitation: readonly ["create", "cancel"];
178
- readonly team: readonly ["create", "update", "delete"];
179
- readonly ac: readonly ["create", "read", "update", "delete"];
180
- }>;
181
- };
182
- owner: {
183
- authorize<K extends "organization" | "member" | "team" | "ac" | "invitation">(request: K extends infer T extends keyof Subset<"organization" | "member" | "team" | "ac" | "invitation", {
184
- readonly organization: readonly ["update", "delete"];
185
- readonly member: readonly ["create", "update", "delete"];
186
- readonly invitation: readonly ["create", "cancel"];
187
- readonly team: readonly ["create", "update", "delete"];
188
- readonly ac: readonly ["create", "read", "update", "delete"];
189
- }> ? { [key in T]?: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
190
- readonly organization: readonly ["update", "delete"];
191
- readonly member: readonly ["create", "update", "delete"];
192
- readonly invitation: readonly ["create", "cancel"];
193
- readonly team: readonly ["create", "update", "delete"];
194
- readonly ac: readonly ["create", "read", "update", "delete"];
195
- }>[key] | {
196
- actions: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
197
- readonly organization: readonly ["update", "delete"];
198
- readonly member: readonly ["create", "update", "delete"];
199
- readonly invitation: readonly ["create", "cancel"];
200
- readonly team: readonly ["create", "update", "delete"];
201
- readonly ac: readonly ["create", "read", "update", "delete"];
202
- }>[key];
203
- connector: "OR" | "AND";
204
- } | undefined } : never, connector?: "OR" | "AND"): AuthorizeResponse;
205
- statements: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
206
- readonly organization: readonly ["update", "delete"];
207
- readonly member: readonly ["create", "update", "delete"];
208
- readonly invitation: readonly ["create", "cancel"];
209
- readonly team: readonly ["create", "update", "delete"];
210
- readonly ac: readonly ["create", "read", "update", "delete"];
211
- }>;
212
- };
213
- member: {
214
- authorize<K extends "organization" | "member" | "team" | "ac" | "invitation">(request: K extends infer T extends keyof Subset<"organization" | "member" | "team" | "ac" | "invitation", {
215
- readonly organization: readonly ["update", "delete"];
216
- readonly member: readonly ["create", "update", "delete"];
217
- readonly invitation: readonly ["create", "cancel"];
218
- readonly team: readonly ["create", "update", "delete"];
219
- readonly ac: readonly ["create", "read", "update", "delete"];
220
- }> ? { [key in T]?: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
221
- readonly organization: readonly ["update", "delete"];
222
- readonly member: readonly ["create", "update", "delete"];
223
- readonly invitation: readonly ["create", "cancel"];
224
- readonly team: readonly ["create", "update", "delete"];
225
- readonly ac: readonly ["create", "read", "update", "delete"];
226
- }>[key] | {
227
- actions: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
228
- readonly organization: readonly ["update", "delete"];
229
- readonly member: readonly ["create", "update", "delete"];
230
- readonly invitation: readonly ["create", "cancel"];
231
- readonly team: readonly ["create", "update", "delete"];
232
- readonly ac: readonly ["create", "read", "update", "delete"];
233
- }>[key];
234
- connector: "OR" | "AND";
235
- } | undefined } : never, connector?: "OR" | "AND"): AuthorizeResponse;
236
- statements: Subset<"organization" | "member" | "team" | "ac" | "invitation", {
237
- readonly organization: readonly ["update", "delete"];
238
- readonly member: readonly ["create", "update", "delete"];
239
- readonly invitation: readonly ["create", "cancel"];
240
- readonly team: readonly ["create", "update", "delete"];
241
- readonly ac: readonly ["create", "read", "update", "delete"];
242
- }>;
243
- };
244
- };
245
112
  //#endregion
246
113
  export { adminAc, defaultAc, defaultRoles, defaultStatements, memberAc, ownerAc };
@@ -238,6 +238,7 @@ declare const organizationClient: <CO extends OrganizationClientOptions>(options
238
238
  INVITATION_NOT_FOUND: _better_auth_core_utils_error_codes0.RawError<"INVITATION_NOT_FOUND">;
239
239
  YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION: _better_auth_core_utils_error_codes0.RawError<"YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION">;
240
240
  EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION: _better_auth_core_utils_error_codes0.RawError<"EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION">;
241
+ EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION: _better_auth_core_utils_error_codes0.RawError<"EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION">;
241
242
  YOU_ARE_NOT_ALLOWED_TO_CANCEL_THIS_INVITATION: _better_auth_core_utils_error_codes0.RawError<"YOU_ARE_NOT_ALLOWED_TO_CANCEL_THIS_INVITATION">;
242
243
  INVITER_IS_NO_LONGER_A_MEMBER_OF_THE_ORGANIZATION: _better_auth_core_utils_error_codes0.RawError<"INVITER_IS_NO_LONGER_A_MEMBER_OF_THE_ORGANIZATION">;
243
244
  YOU_ARE_NOT_ALLOWED_TO_INVITE_USER_WITH_THIS_ROLE: _better_auth_core_utils_error_codes0.RawError<"YOU_ARE_NOT_ALLOWED_TO_INVITE_USER_WITH_THIS_ROLE">;
@@ -71,7 +71,7 @@ const organizationClient = (options) => {
71
71
  },
72
72
  {
73
73
  matcher(path) {
74
- return path.startsWith("/organization");
74
+ return path === "/sign-out" || path.startsWith("/organization");
75
75
  },
76
76
  signal: "$activeOrgSignal"
77
77
  },
@@ -25,6 +25,7 @@ declare const ORGANIZATION_ERROR_CODES: {
25
25
  INVITATION_NOT_FOUND: _better_auth_core_utils_error_codes0.RawError<"INVITATION_NOT_FOUND">;
26
26
  YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION: _better_auth_core_utils_error_codes0.RawError<"YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION">;
27
27
  EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION: _better_auth_core_utils_error_codes0.RawError<"EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION">;
28
+ EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION: _better_auth_core_utils_error_codes0.RawError<"EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION">;
28
29
  YOU_ARE_NOT_ALLOWED_TO_CANCEL_THIS_INVITATION: _better_auth_core_utils_error_codes0.RawError<"YOU_ARE_NOT_ALLOWED_TO_CANCEL_THIS_INVITATION">;
29
30
  INVITER_IS_NO_LONGER_A_MEMBER_OF_THE_ORGANIZATION: _better_auth_core_utils_error_codes0.RawError<"INVITER_IS_NO_LONGER_A_MEMBER_OF_THE_ORGANIZATION">;
30
31
  YOU_ARE_NOT_ALLOWED_TO_INVITE_USER_WITH_THIS_ROLE: _better_auth_core_utils_error_codes0.RawError<"YOU_ARE_NOT_ALLOWED_TO_INVITE_USER_WITH_THIS_ROLE">;
@@ -24,6 +24,7 @@ const ORGANIZATION_ERROR_CODES = defineErrorCodes({
24
24
  INVITATION_NOT_FOUND: "Invitation not found",
25
25
  YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION: "You are not the recipient of the invitation",
26
26
  EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION: "Email verification required before accepting or rejecting invitation",
27
+ EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION: "Email verification required to view or list invitations for the session email",
27
28
  YOU_ARE_NOT_ALLOWED_TO_CANCEL_THIS_INVITATION: "You are not allowed to cancel this invitation",
28
29
  INVITER_IS_NO_LONGER_A_MEMBER_OF_THE_ORGANIZATION: "Inviter is no longer a member of the organization",
29
30
  YOU_ARE_NOT_ALLOWED_TO_INVITE_USER_WITH_THIS_ROLE: "You are not allowed to invite a user with this role",
@@ -1,5 +1,5 @@
1
1
  import { InferAdditionalFieldsFromPluginOptions } from "../../../db/field.mjs";
2
- import { Statements, Subset } from "../../access/types.mjs";
2
+ import { ExactRoleStatements } from "../../access/types.mjs";
3
3
  import { OrganizationOptions } from "../types.mjs";
4
4
  import { OrganizationRole } from "../schema.mjs";
5
5
  import * as better_call0 from "better-call";
@@ -91,7 +91,7 @@ declare const createOrgRole: <O extends OrganizationOptions>(options: O) => bett
91
91
  createdAt: Date;
92
92
  updatedAt?: Date | undefined;
93
93
  } & InferAdditionalFieldsFromPluginOptions<"organizationRole", O, false>;
94
- statements: Subset<string, Statements>;
94
+ statements: ExactRoleStatements<Record<string, string[]>>;
95
95
  }>;
96
96
  declare const deleteOrgRole: <O extends OrganizationOptions>(options: O) => better_call0.StrictEndpoint<"/organization/delete-role", {
97
97
  method: "POST";
@@ -4,11 +4,18 @@ import { OrganizationOptions } from "../types.mjs";
4
4
  import { InferOrganizationRolesFromOption, InvitationStatus } from "../schema.mjs";
5
5
  import { defaultRoles } from "../access/statement.mjs";
6
6
  import * as _better_auth_core0 from "@better-auth/core";
7
+ import { LiteralString } from "@better-auth/core";
7
8
  import * as _better_auth_core_db0 from "@better-auth/core/db";
8
9
  import * as better_call0 from "better-call";
9
10
  import * as z from "zod";
10
11
 
11
12
  //#region src/plugins/organization/routes/crud-invites.d.ts
13
+ type DynamicOrganizationRole<O extends OrganizationOptions> = O extends {
14
+ dynamicAccessControl: {
15
+ enabled: true;
16
+ };
17
+ } ? LiteralString : never;
18
+ type OrganizationInvitationRole<O extends OrganizationOptions> = InferOrganizationRolesFromOption<O> | DynamicOrganizationRole<O>;
12
19
  declare const createInvitation: <O extends OrganizationOptions>(option: O) => better_call0.StrictEndpoint<"/organization/invite-member", {
13
20
  method: "POST";
14
21
  requireHeaders: true;
@@ -109,7 +116,7 @@ declare const createInvitation: <O extends OrganizationOptions>(option: O) => be
109
116
  /**
110
117
  * The role to assign to the user
111
118
  */
112
- role: InferOrganizationRolesFromOption<O> | InferOrganizationRolesFromOption<O>[];
119
+ role: OrganizationInvitationRole<O> | OrganizationInvitationRole<O>[];
113
120
  /**
114
121
  * The organization ID to invite
115
122
  * the user to
@@ -114,7 +114,7 @@ const createInvitation = (option) => {
114
114
  email,
115
115
  organizationId
116
116
  });
117
- if (alreadyInvited.length && !ctx.body.resend) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_ALREADY_INVITED_TO_THIS_ORGANIZATION);
117
+ if (alreadyInvited.length && !ctx.body.resend && !ctx.context.orgOptions.cancelPendingInvitationsOnReInvite) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_ALREADY_INVITED_TO_THIS_ORGANIZATION);
118
118
  const organization = await adapter.findOrganizationById(organizationId);
119
119
  if (!organization) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND);
120
120
  if (alreadyInvited.length && ctx.body.resend) {
@@ -244,7 +244,7 @@ const acceptInvitation = (options) => createAuthEndpoint("/organization/accept-i
244
244
  const invitation = await adapter.findInvitationById(ctx.body.invitationId);
245
245
  if (!invitation || invitation.expiresAt < /* @__PURE__ */ new Date() || invitation.status !== "pending") throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.INVITATION_NOT_FOUND);
246
246
  if (invitation.email.toLowerCase() !== session.user.email.toLowerCase()) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION);
247
- if (ctx.context.orgOptions.requireEmailVerificationOnInvitation && !session.user.emailVerified) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION);
247
+ if ((ctx.context.orgOptions.requireEmailVerificationOnInvitation ?? true) && !session.user.emailVerified) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION);
248
248
  const membershipLimit = ctx.context.orgOptions?.membershipLimit || 100;
249
249
  const membersCount = await adapter.countMembers({ organizationId: invitation.organizationId });
250
250
  const organization = await adapter.findOrganizationById(invitation.organizationId);
@@ -333,7 +333,7 @@ const rejectInvitation = (options) => createAuthEndpoint("/organization/reject-i
333
333
  code: "INVITATION_NOT_FOUND"
334
334
  });
335
335
  if (invitation.email.toLowerCase() !== session.user.email.toLowerCase()) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION);
336
- if (ctx.context.orgOptions.requireEmailVerificationOnInvitation && !session.user.emailVerified) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION);
336
+ if ((ctx.context.orgOptions.requireEmailVerificationOnInvitation ?? true) && !session.user.emailVerified) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION);
337
337
  const organization = await adapter.findOrganizationById(invitation.organizationId);
338
338
  if (!organization) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND);
339
339
  if (options?.organizationHooks?.beforeRejectInvitation) await options?.organizationHooks.beforeRejectInvitation({
@@ -452,6 +452,7 @@ const getInvitation = (options) => createAuthEndpoint("/organization/get-invitat
452
452
  const invitation = await adapter.findInvitationById(ctx.query.id);
453
453
  if (!invitation || invitation.status !== "pending" || invitation.expiresAt < /* @__PURE__ */ new Date()) throw APIError.fromStatus("BAD_REQUEST", { message: "Invitation not found!" });
454
454
  if (invitation.email.toLowerCase() !== session.user.email.toLowerCase()) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION);
455
+ if ((ctx.context.orgOptions.requireEmailVerificationOnInvitation ?? true) && !session.user.emailVerified) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION);
455
456
  const organization = await adapter.findOrganizationById(invitation.organizationId);
456
457
  if (!organization) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND);
457
458
  const member = await adapter.findMemberByOrgId({
@@ -537,6 +538,7 @@ const listUserInvitations = (options) => createAuthEndpoint("/organization/list-
537
538
  }, async (ctx) => {
538
539
  const session = await getSessionFromCtx(ctx);
539
540
  if (ctx.request && ctx.query?.email) throw APIError.fromStatus("BAD_REQUEST", { message: "User email cannot be passed for client side API calls." });
541
+ if (session && (ctx.context.orgOptions.requireEmailVerificationOnInvitation ?? true) && !session.user.emailVerified) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION);
540
542
  const userEmail = session?.user.email || ctx.query?.email;
541
543
  if (!userEmail) throw APIError.fromStatus("BAD_REQUEST", { message: "Missing session headers, or email query parameter." });
542
544
  const pendingInvitations = (await getOrgAdapter(ctx.context, options).listUserInvitations(userEmail)).filter((inv) => inv.status === "pending");
@@ -376,7 +376,7 @@ const setActiveTeam = (options) => createAuthEndpoint("/organization/set-active-
376
376
  requireHeaders: true,
377
377
  use: [orgSessionMiddleware, orgMiddleware],
378
378
  metadata: { openapi: {
379
- description: "Set the active team",
379
+ description: "Set the active team for the current active organization",
380
380
  responses: { "200": {
381
381
  description: "Success",
382
382
  content: { "application/json": { schema: {
@@ -403,7 +403,12 @@ const setActiveTeam = (options) => createAuthEndpoint("/organization/set-active-
403
403
  if (!sessionTeamId) return ctx.json(null);
404
404
  else teamId = sessionTeamId;
405
405
  } else teamId = ctx.body.teamId;
406
- const team = await adapter.findTeamById({ teamId });
406
+ const activeOrganizationId = session.session.activeOrganizationId;
407
+ if (!activeOrganizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
408
+ const team = await adapter.findTeamById({
409
+ teamId,
410
+ organizationId: activeOrganizationId
411
+ });
407
412
  if (!team) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.TEAM_NOT_FOUND);
408
413
  if (!await adapter.findTeamMember({
409
414
  teamId,
@@ -165,9 +165,19 @@ interface OrganizationOptions {
165
165
  */
166
166
  cancelPendingInvitationsOnReInvite?: boolean | undefined;
167
167
  /**
168
- * Require email verification on accepting or rejecting an invitation
168
+ * Require email verification on session-authenticated recipient invitation
169
+ * calls (accept, reject, get, list). Defaults to `true` so unverified
170
+ * accounts registered against a victim's email cannot accept, read, or
171
+ * enumerate invitations targeted at that email. Server-side
172
+ * `listUserInvitations` calls without a session (caller passes
173
+ * `ctx.query.email`) continue to bypass the gate because the caller is
174
+ * trusted. Set to `false` for backward compatibility on apps that do not
175
+ * require email verification; understand the takeover risk before doing so.
169
176
  *
170
- * @default false
177
+ * @default true
178
+ *
179
+ * @deprecated The option will be removed on the next minor; the gate will
180
+ * become unconditional. Plan to verify emails before invitation acceptance.
171
181
  */
172
182
  requireEmailVerificationOnInvitation?: boolean | undefined;
173
183
  /**
@@ -5,6 +5,10 @@ declare const siweClient: () => {
5
5
  id: "siwe";
6
6
  version: string;
7
7
  $InferServerPlugin: ReturnType<typeof siwe>;
8
+ pathMethods: {
9
+ "/siwe/nonce": "POST";
10
+ "/siwe/get-nonce": "POST";
11
+ };
8
12
  };
9
13
  //#endregion
10
14
  export { siweClient };
@@ -4,7 +4,11 @@ const siweClient = () => {
4
4
  return {
5
5
  id: "siwe",
6
6
  version: PACKAGE_VERSION,
7
- $InferServerPlugin: {}
7
+ $InferServerPlugin: {},
8
+ pathMethods: {
9
+ "/siwe/nonce": "POST",
10
+ "/siwe/get-nonce": "POST"
11
+ }
8
12
  };
9
13
  };
10
14
  //#endregion
@@ -26,10 +26,21 @@ declare const siwe: (options: SIWEPluginOptions) => {
26
26
  version: string;
27
27
  schema: WalletAddressSchema;
28
28
  endpoints: {
29
- getSiweNonce: better_call0.StrictEndpoint<"/siwe/nonce", {
29
+ getSiweNonce: better_call0.StrictEndpoint<"/siwe/nonce" | "/siwe/get-nonce", {
30
30
  method: "POST";
31
31
  body: z.ZodObject<{
32
- walletAddress: z.ZodString;
32
+ walletAddress: z.ZodOptional<z.ZodString>;
33
+ address: z.ZodOptional<z.ZodString>;
34
+ chainId: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
35
+ }, z.core.$strip>;
36
+ }, {
37
+ nonce: string;
38
+ }>;
39
+ getNonce: better_call0.StrictEndpoint<"/siwe/nonce" | "/siwe/get-nonce", {
40
+ method: "POST";
41
+ body: z.ZodObject<{
42
+ walletAddress: z.ZodOptional<z.ZodString>;
43
+ address: z.ZodOptional<z.ZodString>;
33
44
  chainId: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
34
45
  }, z.core.$strip>;
35
46
  }, {