better-auth 0.0.2-beta.7 → 0.0.2
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/access.d.ts +4 -0
- package/dist/access.js +126 -0
- package/dist/access.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +553 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/plugins.d.ts +2436 -0
- package/dist/client/plugins.js +411 -0
- package/dist/client/plugins.js.map +1 -0
- package/dist/client-A2Mt04KQ.d.ts +3503 -0
- package/dist/client.d.ts +1433 -0
- package/dist/client.js +693 -0
- package/dist/client.js.map +1 -0
- package/dist/helper-B5_2Vzba.d.ts +14 -0
- package/dist/index-Dg4eEXZW.d.ts +24 -0
- package/dist/index-W5nXvJ-p.d.ts +1498 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.js +2195 -1191
- package/dist/index.js.map +1 -1
- package/dist/next-js.d.ts +14 -0
- package/dist/next-js.js +14 -0
- package/dist/next-js.js.map +1 -0
- package/dist/plugins.d.ts +892 -49
- package/dist/plugins.js +3951 -253
- package/dist/plugins.js.map +1 -1
- package/dist/preact.d.ts +8 -0
- package/dist/preact.js +294 -0
- package/dist/preact.js.map +1 -0
- package/dist/react.d.ts +14 -0
- package/dist/react.js +314 -0
- package/dist/react.js.map +1 -0
- package/dist/schema-BOszzrbQ.d.ts +792 -0
- package/dist/social.d.ts +4 -0
- package/dist/social.js +509 -0
- package/dist/social.js.map +1 -0
- package/dist/solid-start.d.ts +18 -0
- package/dist/solid-start.js +14 -0
- package/dist/solid-start.js.map +1 -0
- package/dist/solid.d.ts +2790 -0
- package/dist/solid.js +306 -0
- package/dist/solid.js.map +1 -0
- package/dist/statement-COylZd3J.d.ts +81 -0
- package/dist/svelte-kit.d.ts +10 -7
- package/dist/svelte-kit.js +12 -17
- package/dist/svelte-kit.js.map +1 -1
- package/dist/svelte.d.ts +2791 -0
- package/dist/svelte.js +304 -0
- package/dist/svelte.js.map +1 -0
- package/dist/type-DbMyI3b5.d.ts +5724 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/vue.d.ts +14 -0
- package/dist/vue.js +311 -0
- package/dist/vue.js.map +1 -0
- package/package.json +80 -54
- package/LICENSE +0 -21
- package/dist/actions.d.ts +0 -33
- package/dist/actions.js +0 -1373
- package/dist/actions.js.map +0 -1
- package/dist/adapters/drizzle-adapter.d.ts +0 -10
- package/dist/adapters/drizzle-adapter.js +0 -1095
- package/dist/adapters/drizzle-adapter.js.map +0 -1
- package/dist/adapters/memory.d.ts +0 -8
- package/dist/adapters/memory.js +0 -136
- package/dist/adapters/memory.js.map +0 -1
- package/dist/adapters/mongodb-adapter.d.ts +0 -9
- package/dist/adapters/mongodb-adapter.js +0 -97
- package/dist/adapters/mongodb-adapter.js.map +0 -1
- package/dist/adapters/prisma-adapter.d.ts +0 -7
- package/dist/adapters/prisma-adapter.js +0 -144
- package/dist/adapters/prisma-adapter.js.map +0 -1
- package/dist/adapters/redis-adapter.d.ts +0 -7
- package/dist/adapters/redis-adapter.js +0 -65
- package/dist/adapters/redis-adapter.js.map +0 -1
- package/dist/adapters.d.ts +0 -3
- package/dist/adapters.js +0 -206
- package/dist/adapters.js.map +0 -1
- package/dist/h3.d.ts +0 -10
- package/dist/h3.js +0 -326
- package/dist/h3.js.map +0 -1
- package/dist/hono.d.ts +0 -10
- package/dist/hono.js +0 -25
- package/dist/hono.js.map +0 -1
- package/dist/index-UcTu1vUg.d.ts +0 -107
- package/dist/next.d.ts +0 -17
- package/dist/next.js +0 -26
- package/dist/next.js.map +0 -1
- package/dist/options-CH15FEBw.d.ts +0 -1562
- package/dist/providers.d.ts +0 -3
- package/dist/providers.js +0 -653
- package/dist/providers.js.map +0 -1
- package/dist/routes/session.d.ts +0 -39
- package/dist/routes/session.js +0 -128
- package/dist/routes/session.js.map +0 -1
- package/dist/types-DAxaMWCy.d.ts +0 -136
package/dist/client.js
ADDED
|
@@ -0,0 +1,693 @@
|
|
|
1
|
+
// src/client/base.ts
|
|
2
|
+
import { createFetch } from "@better-fetch/fetch";
|
|
3
|
+
|
|
4
|
+
// src/error/better-auth-error.ts
|
|
5
|
+
var BetterAuthError = class extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// src/utils/base-url.ts
|
|
12
|
+
function checkHasPath(url) {
|
|
13
|
+
try {
|
|
14
|
+
const parsedUrl = new URL(url);
|
|
15
|
+
return parsedUrl.pathname !== "/";
|
|
16
|
+
} catch (error) {
|
|
17
|
+
console.error("Invalid URL:", error);
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function withPath(url, path = "/api/auth") {
|
|
22
|
+
const hasPath = checkHasPath(url);
|
|
23
|
+
if (hasPath) {
|
|
24
|
+
return {
|
|
25
|
+
baseURL: new URL(url).origin,
|
|
26
|
+
withPath: url
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
path = path.startsWith("/") ? path : `/${path}`;
|
|
30
|
+
return {
|
|
31
|
+
baseURL: url,
|
|
32
|
+
withPath: `${url}${path}`
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function getBaseURL(url, path) {
|
|
36
|
+
if (url) {
|
|
37
|
+
return withPath(url, path);
|
|
38
|
+
}
|
|
39
|
+
const env = typeof process !== "undefined" ? process.env : typeof import.meta !== "undefined" ? (
|
|
40
|
+
//@ts-ignore
|
|
41
|
+
import.meta.env
|
|
42
|
+
) : {};
|
|
43
|
+
const fromEnv = env.BETTER_AUTH_URL || env.AUTH_URL || env.NEXT_PUBLIC_AUTH_URL || env.NEXT_PUBLIC_BETTER_AUTH_URL || env.PUBLIC_AUTH_URL || env.PUBLIC_BETTER_AUTH_URL || env.NUXT_PUBLIC_BETTER_AUTH_URL || env.NUXT_PUBLIC_AUTH_URL;
|
|
44
|
+
if (fromEnv) {
|
|
45
|
+
return withPath(fromEnv, path);
|
|
46
|
+
}
|
|
47
|
+
const isDev = !fromEnv && (env.NODE_ENV === "development" || env.NODE_ENV === "test");
|
|
48
|
+
if (isDev) {
|
|
49
|
+
return {
|
|
50
|
+
baseURL: "http://localhost:3000",
|
|
51
|
+
withPath: "http://localhost:3000/api/auth"
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
throw new BetterAuthError(
|
|
55
|
+
"Could not infer baseURL from environment variables"
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/client/fetch-plugins.ts
|
|
60
|
+
import { betterFetch } from "@better-fetch/fetch";
|
|
61
|
+
var redirectPlugin = {
|
|
62
|
+
id: "redirect",
|
|
63
|
+
name: "Redirect",
|
|
64
|
+
hooks: {
|
|
65
|
+
onSuccess(context) {
|
|
66
|
+
if (context.data?.url && context.data?.redirect) {
|
|
67
|
+
window.location.href = context.data.url;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var addCurrentURL = {
|
|
73
|
+
id: "add-current-url",
|
|
74
|
+
name: "Add current URL",
|
|
75
|
+
hooks: {
|
|
76
|
+
onRequest(context) {
|
|
77
|
+
if (typeof window !== "undefined") {
|
|
78
|
+
const url = new URL(context.url);
|
|
79
|
+
url.searchParams.set("currentURL", window.location.href);
|
|
80
|
+
context.url = url;
|
|
81
|
+
}
|
|
82
|
+
return context;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
var csrfPlugin = {
|
|
87
|
+
id: "csrf",
|
|
88
|
+
name: "CSRF Check",
|
|
89
|
+
async init(url, options) {
|
|
90
|
+
if (options?.method !== "GET") {
|
|
91
|
+
options = options || {};
|
|
92
|
+
const { data, error } = await betterFetch("/csrf", {
|
|
93
|
+
body: void 0,
|
|
94
|
+
baseURL: options.baseURL,
|
|
95
|
+
plugins: [],
|
|
96
|
+
method: "GET",
|
|
97
|
+
credentials: "include"
|
|
98
|
+
});
|
|
99
|
+
if (error?.status === 404) {
|
|
100
|
+
throw new BetterAuthError(
|
|
101
|
+
"Route not found. Make sure the server is running and the base URL is correct and includes the path (e.g. http://localhost:3000/api/auth)."
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
if (error) {
|
|
105
|
+
throw new BetterAuthError(error.message || "Failed to get CSRF token.");
|
|
106
|
+
}
|
|
107
|
+
options.body = {
|
|
108
|
+
...options?.body,
|
|
109
|
+
csrfToken: data.csrfToken
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
options.credentials = "include";
|
|
113
|
+
return { url, options };
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// src/client/proxy.ts
|
|
118
|
+
function getMethod(path, knownPathMethods, args) {
|
|
119
|
+
const method = knownPathMethods[path];
|
|
120
|
+
const { options, query, ...body } = args || {};
|
|
121
|
+
if (method) {
|
|
122
|
+
return method;
|
|
123
|
+
}
|
|
124
|
+
if (options?.method) {
|
|
125
|
+
return options.method;
|
|
126
|
+
}
|
|
127
|
+
if (body && Object.keys(body).length > 0) {
|
|
128
|
+
return "POST";
|
|
129
|
+
}
|
|
130
|
+
return "GET";
|
|
131
|
+
}
|
|
132
|
+
function createDynamicPathProxy(routes, client, knownPathMethods, $signal, $signals) {
|
|
133
|
+
function createProxy(path = []) {
|
|
134
|
+
return new Proxy(function() {
|
|
135
|
+
}, {
|
|
136
|
+
get(target, prop) {
|
|
137
|
+
const fullPath = [...path, prop];
|
|
138
|
+
let current = routes;
|
|
139
|
+
for (const segment of fullPath) {
|
|
140
|
+
if (current && typeof current === "object" && segment in current) {
|
|
141
|
+
current = current[segment];
|
|
142
|
+
} else {
|
|
143
|
+
current = void 0;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (typeof current === "function") {
|
|
148
|
+
return current;
|
|
149
|
+
}
|
|
150
|
+
return createProxy(fullPath);
|
|
151
|
+
},
|
|
152
|
+
apply: async (_, __, args) => {
|
|
153
|
+
const routePath = "/" + path.map(
|
|
154
|
+
(segment) => segment.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)
|
|
155
|
+
).join("/");
|
|
156
|
+
const arg = args[0] || {};
|
|
157
|
+
const method = getMethod(routePath, knownPathMethods, arg);
|
|
158
|
+
const { query, options, ...body } = arg;
|
|
159
|
+
return await client(routePath, {
|
|
160
|
+
...options,
|
|
161
|
+
body: method === "GET" ? void 0 : body,
|
|
162
|
+
query,
|
|
163
|
+
method,
|
|
164
|
+
async onSuccess(context) {
|
|
165
|
+
const signal = $signal?.find((s) => s.matcher(routePath));
|
|
166
|
+
if (!signal) return;
|
|
167
|
+
const signalAtom = $signals?.[signal.atom];
|
|
168
|
+
if (!signalAtom) return;
|
|
169
|
+
signalAtom.set(!signalAtom.get());
|
|
170
|
+
await options?.onSuccess?.(context);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return createProxy();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// src/client/session-atom.ts
|
|
180
|
+
import { atom, computed, task } from "nanostores";
|
|
181
|
+
function getSessionAtom(client) {
|
|
182
|
+
const $signal = atom(false);
|
|
183
|
+
const $session = computed(
|
|
184
|
+
$signal,
|
|
185
|
+
() => task(async () => {
|
|
186
|
+
const session = await client("/session", {
|
|
187
|
+
credentials: "include",
|
|
188
|
+
method: "GET"
|
|
189
|
+
});
|
|
190
|
+
return session.data;
|
|
191
|
+
})
|
|
192
|
+
);
|
|
193
|
+
return { $session, $sessionSignal: $signal };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// src/client/base.ts
|
|
197
|
+
var createAuthFetch = (options) => {
|
|
198
|
+
const $baseFetch = createFetch();
|
|
199
|
+
return createFetch({
|
|
200
|
+
method: "GET",
|
|
201
|
+
...options,
|
|
202
|
+
baseURL: getBaseURL(options?.baseURL).withPath,
|
|
203
|
+
plugins: [
|
|
204
|
+
...options?.plugins || [],
|
|
205
|
+
...options?.authPlugins?.flatMap((plugin) => plugin($baseFetch).fetchPlugins).filter((plugin) => plugin !== void 0) || [],
|
|
206
|
+
...options?.csrfPlugin !== false ? [csrfPlugin] : [],
|
|
207
|
+
redirectPlugin,
|
|
208
|
+
addCurrentURL
|
|
209
|
+
]
|
|
210
|
+
});
|
|
211
|
+
};
|
|
212
|
+
var createAuthClient = (options, additionalActions = {}) => {
|
|
213
|
+
const $fetch = createAuthFetch(options);
|
|
214
|
+
const { $session, $sessionSignal } = getSessionAtom($fetch);
|
|
215
|
+
let pluginsActions = {};
|
|
216
|
+
const pluginProxySignals = [];
|
|
217
|
+
let pluginSignals = {};
|
|
218
|
+
let pluginPathMethods = {};
|
|
219
|
+
for (const plugin of options?.authPlugins || []) {
|
|
220
|
+
const pl = plugin($fetch);
|
|
221
|
+
if (pl.authProxySignal) {
|
|
222
|
+
pluginProxySignals.push(...pl.authProxySignal);
|
|
223
|
+
}
|
|
224
|
+
if (pl.actions) {
|
|
225
|
+
pluginsActions = {
|
|
226
|
+
...pluginsActions,
|
|
227
|
+
...pl.actions
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
if (pl.signals) {
|
|
231
|
+
pluginSignals = {
|
|
232
|
+
...pluginSignals,
|
|
233
|
+
...pl.signals
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
if (pl.pathMethods) {
|
|
237
|
+
pluginPathMethods = {
|
|
238
|
+
...pluginPathMethods,
|
|
239
|
+
...pl.pathMethods
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
const actions = {
|
|
244
|
+
$atoms: {
|
|
245
|
+
$session
|
|
246
|
+
},
|
|
247
|
+
$fetch,
|
|
248
|
+
...pluginsActions,
|
|
249
|
+
...additionalActions
|
|
250
|
+
};
|
|
251
|
+
const proxy = createDynamicPathProxy(
|
|
252
|
+
actions,
|
|
253
|
+
$fetch,
|
|
254
|
+
{
|
|
255
|
+
...pluginPathMethods,
|
|
256
|
+
"/sign-out": "POST"
|
|
257
|
+
},
|
|
258
|
+
[
|
|
259
|
+
{
|
|
260
|
+
matcher: (path) => path === "/organization/create",
|
|
261
|
+
atom: "$listOrg"
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
matcher: (path) => path.startsWith("/organization"),
|
|
265
|
+
atom: "$activeOrgSignal"
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
matcher: (path) => path === "/sign-out" || path.startsWith("/sign-up") || path.startsWith("/sign-in"),
|
|
269
|
+
atom: "$sessionSignal"
|
|
270
|
+
},
|
|
271
|
+
...pluginProxySignals
|
|
272
|
+
],
|
|
273
|
+
{
|
|
274
|
+
$sessionSignal,
|
|
275
|
+
...pluginSignals
|
|
276
|
+
}
|
|
277
|
+
);
|
|
278
|
+
return proxy;
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
// src/client/create-client-plugin.ts
|
|
282
|
+
var createClientPlugin = () => {
|
|
283
|
+
return ($fn) => {
|
|
284
|
+
return ($fetch) => {
|
|
285
|
+
const data = $fn($fetch);
|
|
286
|
+
return {
|
|
287
|
+
...data,
|
|
288
|
+
integrations: data.integrations,
|
|
289
|
+
plugin: {}
|
|
290
|
+
};
|
|
291
|
+
};
|
|
292
|
+
};
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
// src/plugins/two-factor/client.ts
|
|
296
|
+
var twoFactorClient = (options = {
|
|
297
|
+
redirect: true,
|
|
298
|
+
twoFactorPage: "/"
|
|
299
|
+
}) => {
|
|
300
|
+
return createClientPlugin()(($fetch) => {
|
|
301
|
+
return {
|
|
302
|
+
id: "two-factor",
|
|
303
|
+
authProxySignal: [
|
|
304
|
+
{
|
|
305
|
+
matcher: (path) => path === "/two-factor/enable" || path === "/two-factor/send-otp",
|
|
306
|
+
atom: "$sessionSignal"
|
|
307
|
+
}
|
|
308
|
+
],
|
|
309
|
+
pathMethods: {
|
|
310
|
+
"enable/totp": "POST",
|
|
311
|
+
"/two-factor/disable": "POST",
|
|
312
|
+
"/two-factor/enable": "POST",
|
|
313
|
+
"/two-factor/send-otp": "POST"
|
|
314
|
+
},
|
|
315
|
+
fetchPlugins: [
|
|
316
|
+
{
|
|
317
|
+
id: "two-factor",
|
|
318
|
+
name: "two-factor",
|
|
319
|
+
hooks: {
|
|
320
|
+
async onSuccess(context) {
|
|
321
|
+
if (context.data?.twoFactorRedirect) {
|
|
322
|
+
if (options.redirect) {
|
|
323
|
+
window.location.href = options.twoFactorPage;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
]
|
|
330
|
+
};
|
|
331
|
+
});
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
// src/plugins/organization/client.ts
|
|
335
|
+
import { atom as atom2, computed as computed2, task as task2 } from "nanostores";
|
|
336
|
+
|
|
337
|
+
// src/plugins/organization/access/src/access.ts
|
|
338
|
+
var ParsingError = class extends Error {
|
|
339
|
+
path;
|
|
340
|
+
constructor(message, path) {
|
|
341
|
+
super(message);
|
|
342
|
+
this.path = path;
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
var AccessControl = class {
|
|
346
|
+
constructor(s) {
|
|
347
|
+
this.s = s;
|
|
348
|
+
this.statements = s;
|
|
349
|
+
}
|
|
350
|
+
statements;
|
|
351
|
+
newRole(statements) {
|
|
352
|
+
return new Role(statements);
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
var Role = class _Role {
|
|
356
|
+
statements;
|
|
357
|
+
constructor(statements) {
|
|
358
|
+
this.statements = statements;
|
|
359
|
+
}
|
|
360
|
+
authorize(request, connector) {
|
|
361
|
+
for (const [requestedResource, requestedActions] of Object.entries(
|
|
362
|
+
request
|
|
363
|
+
)) {
|
|
364
|
+
const allowedActions = this.statements[requestedResource];
|
|
365
|
+
if (!allowedActions) {
|
|
366
|
+
return {
|
|
367
|
+
success: false,
|
|
368
|
+
error: `You are not allowed to access resource: ${requestedResource}`
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
const success = connector === "OR" ? requestedActions.some(
|
|
372
|
+
(requestedAction) => allowedActions.includes(requestedAction)
|
|
373
|
+
) : requestedActions.every(
|
|
374
|
+
(requestedAction) => allowedActions.includes(requestedAction)
|
|
375
|
+
);
|
|
376
|
+
if (success) {
|
|
377
|
+
return { success };
|
|
378
|
+
}
|
|
379
|
+
return {
|
|
380
|
+
success: false,
|
|
381
|
+
error: `unauthorized to access resource "${requestedResource}"`
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
return {
|
|
385
|
+
success: false,
|
|
386
|
+
error: "Not authorized"
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
static fromString(s) {
|
|
390
|
+
const statements = JSON.parse(s);
|
|
391
|
+
if (typeof statements !== "object") {
|
|
392
|
+
throw new ParsingError("statements is not an object", ".");
|
|
393
|
+
}
|
|
394
|
+
for (const [resource, actions] of Object.entries(statements)) {
|
|
395
|
+
if (typeof resource !== "string") {
|
|
396
|
+
throw new ParsingError("invalid resource identifier", resource);
|
|
397
|
+
}
|
|
398
|
+
if (!Array.isArray(actions)) {
|
|
399
|
+
throw new ParsingError("actions is not an array", resource);
|
|
400
|
+
}
|
|
401
|
+
for (let i = 0; i < actions.length; i++) {
|
|
402
|
+
if (typeof actions[i] !== "string") {
|
|
403
|
+
throw new ParsingError("action is not a string", `${resource}[${i}]`);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return new _Role(statements);
|
|
408
|
+
}
|
|
409
|
+
toString() {
|
|
410
|
+
return JSON.stringify(this.statements);
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
// src/plugins/organization/access/statement.ts
|
|
415
|
+
var createAccessControl = (statements) => {
|
|
416
|
+
return new AccessControl(statements);
|
|
417
|
+
};
|
|
418
|
+
var defaultStatements = {
|
|
419
|
+
organization: ["update", "delete"],
|
|
420
|
+
member: ["create", "update", "delete"],
|
|
421
|
+
invitation: ["create", "cancel"]
|
|
422
|
+
};
|
|
423
|
+
var defaultAc = createAccessControl(defaultStatements);
|
|
424
|
+
var adminAc = defaultAc.newRole({
|
|
425
|
+
organization: ["update"],
|
|
426
|
+
invitation: ["create", "cancel"],
|
|
427
|
+
member: ["create", "update", "delete"]
|
|
428
|
+
});
|
|
429
|
+
var ownerAc = defaultAc.newRole({
|
|
430
|
+
organization: ["update", "delete"],
|
|
431
|
+
member: ["create", "update", "delete"],
|
|
432
|
+
invitation: ["create", "cancel"]
|
|
433
|
+
});
|
|
434
|
+
var memberAc = defaultAc.newRole({
|
|
435
|
+
organization: [],
|
|
436
|
+
member: [],
|
|
437
|
+
invitation: []
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
// src/plugins/organization/client.ts
|
|
441
|
+
var organizationClient = (options) => createClientPlugin()(($fetch) => {
|
|
442
|
+
const activeOrgId = atom2(null);
|
|
443
|
+
const $listOrg = atom2(false);
|
|
444
|
+
const $activeOrgSignal = atom2(false);
|
|
445
|
+
const $activeOrganization = computed2(
|
|
446
|
+
[activeOrgId, $activeOrgSignal],
|
|
447
|
+
() => task2(async () => {
|
|
448
|
+
if (!activeOrgId.get()) {
|
|
449
|
+
return null;
|
|
450
|
+
}
|
|
451
|
+
const organization = await $fetch("/organization/set-active", {
|
|
452
|
+
method: "POST",
|
|
453
|
+
credentials: "include",
|
|
454
|
+
body: {
|
|
455
|
+
orgId: activeOrgId.get()
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
return organization.data;
|
|
459
|
+
})
|
|
460
|
+
);
|
|
461
|
+
const $listOrganizations = computed2(
|
|
462
|
+
$listOrg,
|
|
463
|
+
() => task2(async () => {
|
|
464
|
+
const organizations = await $fetch(
|
|
465
|
+
"/organization/list",
|
|
466
|
+
{
|
|
467
|
+
method: "GET"
|
|
468
|
+
}
|
|
469
|
+
);
|
|
470
|
+
return organizations.data;
|
|
471
|
+
})
|
|
472
|
+
);
|
|
473
|
+
const $activeInvitationId = atom2(null);
|
|
474
|
+
const $invitation = computed2(
|
|
475
|
+
$activeInvitationId,
|
|
476
|
+
() => task2(async () => {
|
|
477
|
+
if (!$activeInvitationId.get()) {
|
|
478
|
+
return {
|
|
479
|
+
error: {
|
|
480
|
+
message: "No invitation found",
|
|
481
|
+
status: 400,
|
|
482
|
+
data: null
|
|
483
|
+
},
|
|
484
|
+
data: null
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
const res = await $fetch("/organization/get-active-invitation", {
|
|
488
|
+
method: "GET",
|
|
489
|
+
query: {
|
|
490
|
+
id: $activeInvitationId.get()
|
|
491
|
+
},
|
|
492
|
+
credentials: "include"
|
|
493
|
+
});
|
|
494
|
+
return res;
|
|
495
|
+
})
|
|
496
|
+
);
|
|
497
|
+
return {
|
|
498
|
+
id: "organization",
|
|
499
|
+
actions: {
|
|
500
|
+
organization: {
|
|
501
|
+
setActive(orgId) {
|
|
502
|
+
activeOrgId.set(orgId);
|
|
503
|
+
},
|
|
504
|
+
setInvitationId: (id) => {
|
|
505
|
+
$activeInvitationId.set(id);
|
|
506
|
+
},
|
|
507
|
+
hasPermission: async (permission) => {
|
|
508
|
+
await $fetch("/organization/has-permission", {
|
|
509
|
+
method: "POST",
|
|
510
|
+
body: {
|
|
511
|
+
permission
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
integrations: {
|
|
518
|
+
react(useStore) {
|
|
519
|
+
return {
|
|
520
|
+
organization: {
|
|
521
|
+
useActiveOrganization() {
|
|
522
|
+
return useStore($activeOrganization);
|
|
523
|
+
},
|
|
524
|
+
useListOrganization() {
|
|
525
|
+
return useStore($listOrganizations);
|
|
526
|
+
},
|
|
527
|
+
useInvitation() {
|
|
528
|
+
return useStore($invitation);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
},
|
|
533
|
+
vue(useStore) {
|
|
534
|
+
return {
|
|
535
|
+
useActiveOrganization() {
|
|
536
|
+
return useStore($activeOrganization);
|
|
537
|
+
},
|
|
538
|
+
useListOrganization() {
|
|
539
|
+
return useStore($listOrganizations);
|
|
540
|
+
},
|
|
541
|
+
useInvitation() {
|
|
542
|
+
return useStore($invitation);
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
},
|
|
546
|
+
preact(useStore) {
|
|
547
|
+
return {
|
|
548
|
+
useActiveOrganization() {
|
|
549
|
+
return useStore($activeOrganization);
|
|
550
|
+
},
|
|
551
|
+
useListOrganization() {
|
|
552
|
+
return useStore($listOrganizations);
|
|
553
|
+
},
|
|
554
|
+
useInvitation() {
|
|
555
|
+
return useStore($invitation);
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
},
|
|
559
|
+
svelte() {
|
|
560
|
+
return {
|
|
561
|
+
$activeOrganization,
|
|
562
|
+
$listOrganizations,
|
|
563
|
+
$invitation
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
},
|
|
567
|
+
signals: {
|
|
568
|
+
$listOrg,
|
|
569
|
+
$activeOrgSignal
|
|
570
|
+
},
|
|
571
|
+
authProxySignal: [
|
|
572
|
+
{
|
|
573
|
+
matcher(path) {
|
|
574
|
+
return path.startsWith("/organization");
|
|
575
|
+
},
|
|
576
|
+
atom: "$listOrg"
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
matcher(path) {
|
|
580
|
+
return path.startsWith("/organization");
|
|
581
|
+
},
|
|
582
|
+
atom: "$activeOrgSignal"
|
|
583
|
+
}
|
|
584
|
+
]
|
|
585
|
+
};
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
// src/plugins/passkey/client.ts
|
|
589
|
+
import {
|
|
590
|
+
WebAuthnError,
|
|
591
|
+
startAuthentication,
|
|
592
|
+
startRegistration
|
|
593
|
+
} from "@simplewebauthn/browser";
|
|
594
|
+
var getPasskeyActions = ($fetch) => {
|
|
595
|
+
const signInPasskey = async (opts) => {
|
|
596
|
+
const response = await $fetch(
|
|
597
|
+
"/passkey/generate-authenticate-options",
|
|
598
|
+
{
|
|
599
|
+
method: "POST",
|
|
600
|
+
body: {
|
|
601
|
+
email: opts?.email
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
);
|
|
605
|
+
if (!response.data) {
|
|
606
|
+
return response;
|
|
607
|
+
}
|
|
608
|
+
try {
|
|
609
|
+
const res = await startAuthentication(
|
|
610
|
+
response.data,
|
|
611
|
+
opts?.autoFill || false
|
|
612
|
+
);
|
|
613
|
+
const verified = await $fetch("/passkey/verify-authentication", {
|
|
614
|
+
body: {
|
|
615
|
+
response: res,
|
|
616
|
+
type: "authenticate"
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
if (!verified.data) {
|
|
620
|
+
return verified;
|
|
621
|
+
}
|
|
622
|
+
} catch (e) {
|
|
623
|
+
console.log(e);
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
const registerPasskey = async () => {
|
|
627
|
+
const options = await $fetch(
|
|
628
|
+
"/passkey/generate-register-options",
|
|
629
|
+
{
|
|
630
|
+
method: "GET"
|
|
631
|
+
}
|
|
632
|
+
);
|
|
633
|
+
if (!options.data) {
|
|
634
|
+
return options;
|
|
635
|
+
}
|
|
636
|
+
try {
|
|
637
|
+
const res = await startRegistration(options.data);
|
|
638
|
+
const verified = await $fetch("/passkey/verify-registration", {
|
|
639
|
+
body: {
|
|
640
|
+
response: res,
|
|
641
|
+
type: "register"
|
|
642
|
+
}
|
|
643
|
+
});
|
|
644
|
+
if (!verified.data) {
|
|
645
|
+
return verified;
|
|
646
|
+
}
|
|
647
|
+
} catch (e) {
|
|
648
|
+
if (e instanceof WebAuthnError) {
|
|
649
|
+
if (e.code === "ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED") {
|
|
650
|
+
return {
|
|
651
|
+
data: null,
|
|
652
|
+
error: {
|
|
653
|
+
message: "previously registered",
|
|
654
|
+
status: 400,
|
|
655
|
+
statusText: "BAD_REQUEST"
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
};
|
|
662
|
+
return {
|
|
663
|
+
signInPasskey,
|
|
664
|
+
registerPasskey
|
|
665
|
+
};
|
|
666
|
+
};
|
|
667
|
+
var passkeyClient = createClientPlugin()(
|
|
668
|
+
($fetch) => {
|
|
669
|
+
return {
|
|
670
|
+
id: "passkey",
|
|
671
|
+
actions: getPasskeyActions($fetch)
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
);
|
|
675
|
+
|
|
676
|
+
// src/plugins/username/client.ts
|
|
677
|
+
var usernameClient = createClientPlugin()(
|
|
678
|
+
($fetch) => {
|
|
679
|
+
return {
|
|
680
|
+
id: "username"
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
);
|
|
684
|
+
export {
|
|
685
|
+
createAuthClient,
|
|
686
|
+
createAuthFetch,
|
|
687
|
+
getPasskeyActions,
|
|
688
|
+
organizationClient,
|
|
689
|
+
passkeyClient,
|
|
690
|
+
twoFactorClient,
|
|
691
|
+
usernameClient
|
|
692
|
+
};
|
|
693
|
+
//# sourceMappingURL=client.js.map
|