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.
- package/dist/api/index.d.mts +0 -2
- package/dist/api/routes/callback.mjs +6 -5
- package/dist/api/routes/email-verification.mjs +2 -2
- package/dist/api/routes/error.mjs +1 -1
- package/dist/api/routes/sign-in.d.mts +0 -1
- package/dist/api/routes/sign-in.mjs +4 -11
- package/dist/api/routes/sign-up.mjs +1 -1
- package/dist/api/routes/update-user.mjs +1 -1
- package/dist/api/to-auth-endpoints.mjs +7 -1
- package/dist/client/index.d.mts +2 -2
- package/dist/client/plugins/index.d.mts +2 -1
- package/dist/cookies/cookie-utils.d.mts +10 -1
- package/dist/cookies/cookie-utils.mjs +19 -1
- package/dist/cookies/index.d.mts +2 -2
- package/dist/cookies/index.mjs +2 -2
- package/dist/db/internal-adapter.mjs +103 -7
- package/dist/db/with-hooks.d.mts +1 -0
- package/dist/db/with-hooks.mjs +58 -1
- package/dist/integrations/cookie-plugin-guard.mjs +18 -0
- package/dist/integrations/next-js.mjs +6 -0
- package/dist/integrations/svelte-kit.mjs +6 -0
- package/dist/integrations/tanstack-start-solid.mjs +6 -0
- package/dist/integrations/tanstack-start.mjs +6 -0
- package/dist/oauth2/link-account.mjs +3 -1
- package/dist/package.mjs +1 -1
- package/dist/plugins/access/access.d.mts +3 -15
- package/dist/plugins/access/index.d.mts +2 -2
- package/dist/plugins/access/types.d.mts +11 -4
- package/dist/plugins/admin/access/statement.d.mts +29 -93
- package/dist/plugins/admin/client.d.mts +5 -0
- package/dist/plugins/admin/client.mjs +5 -0
- package/dist/plugins/admin/routes.mjs +1 -0
- package/dist/plugins/anonymous/client.d.mts +1 -0
- package/dist/plugins/anonymous/error-codes.d.mts +1 -0
- package/dist/plugins/anonymous/error-codes.mjs +1 -0
- package/dist/plugins/anonymous/index.d.mts +1 -0
- package/dist/plugins/anonymous/index.mjs +16 -2
- package/dist/plugins/bearer/index.mjs +2 -4
- package/dist/plugins/captcha/index.mjs +14 -1
- package/dist/plugins/device-authorization/error-codes.mjs +1 -0
- package/dist/plugins/device-authorization/index.d.mts +1 -0
- package/dist/plugins/device-authorization/routes.mjs +34 -3
- package/dist/plugins/email-otp/routes.mjs +3 -3
- package/dist/plugins/generic-oauth/routes.mjs +3 -3
- package/dist/plugins/index.d.mts +2 -2
- package/dist/plugins/magic-link/index.d.mts +8 -1
- package/dist/plugins/magic-link/index.mjs +5 -17
- package/dist/plugins/mcp/authorize.mjs +8 -2
- package/dist/plugins/mcp/index.mjs +73 -30
- package/dist/plugins/oidc-provider/authorize.mjs +8 -2
- package/dist/plugins/oidc-provider/index.mjs +63 -33
- package/dist/plugins/one-tap/index.mjs +16 -10
- package/dist/plugins/organization/access/statement.d.mts +68 -201
- package/dist/plugins/organization/client.d.mts +1 -0
- package/dist/plugins/organization/client.mjs +1 -1
- package/dist/plugins/organization/error-codes.d.mts +1 -0
- package/dist/plugins/organization/error-codes.mjs +1 -0
- package/dist/plugins/organization/routes/crud-access-control.d.mts +2 -2
- package/dist/plugins/organization/routes/crud-invites.d.mts +8 -1
- package/dist/plugins/organization/routes/crud-invites.mjs +5 -3
- package/dist/plugins/organization/routes/crud-team.mjs +7 -2
- package/dist/plugins/organization/types.d.mts +12 -2
- package/dist/plugins/siwe/client.d.mts +4 -0
- package/dist/plugins/siwe/client.mjs +5 -1
- package/dist/plugins/siwe/index.d.mts +13 -2
- package/dist/plugins/siwe/index.mjs +179 -165
- package/dist/plugins/username/index.d.mts +11 -0
- package/dist/plugins/username/index.mjs +18 -2
- package/dist/test-utils/test-instance.d.mts +1 -6
- package/dist/test-utils/test-instance.mjs +11 -2
- package/package.json +10 -10
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
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<
|
|
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
|
|
120
|
-
|
|
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
|
-
}
|
|
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
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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">;
|
|
@@ -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 {
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
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
|
/**
|
|
@@ -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
|
}, {
|