@rio.js/enterprise 1.4.0
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/README.md +89 -0
- package/dist/adapter-factory-BTRALCLD-kJBwe70v.mjs +836 -0
- package/dist/better-auth-CStoaWiq.d.mts +10 -0
- package/dist/better-auth-CqfhQJYE.mjs +558 -0
- package/dist/better-auth.d.mts +2 -0
- package/dist/better-auth.mjs +17 -0
- package/dist/bun-sqlite-dialect-2R9nCsVF-DFs6tpGr.mjs +155 -0
- package/dist/client--1_AEBPu-8Ae9icC9.mjs +125 -0
- package/dist/client.d.mts +17 -0
- package/dist/client.mjs +381 -0
- package/dist/db-BVXTgOd3.mjs +681 -0
- package/dist/db-BadqSwVl.d.mts +9542 -0
- package/dist/db-schema.final-DWleoQm0.mjs +785 -0
- package/dist/db.d.mts +2 -0
- package/dist/db.mjs +3 -0
- package/dist/dialect-C6_pK3V9-CPJHWkYR.mjs +72 -0
- package/dist/dist-CygcgJYk.mjs +422 -0
- package/dist/env-DwlNAN_D-C1zHd0cf-Cdlw8sNp.mjs +289 -0
- package/dist/esm-C5TuvtGn.mjs +15816 -0
- package/dist/index.d.mts +6 -0
- package/dist/index.mjs +17 -0
- package/dist/init-D8lwWc90.mjs +27 -0
- package/dist/json-oFuWgANh-O1U6k3bL.mjs +3811 -0
- package/dist/kysely-adapter-D_seG51p.mjs +297 -0
- package/dist/memory-adapter-CY-oDozb.mjs +215 -0
- package/dist/misc-CbURQDlR-sLtUwwQY.mjs +7 -0
- package/dist/node-sqlite-dialect-CdC7L-ji-QLbJGmDc.mjs +155 -0
- package/dist/parser-bL7W2mQ0-YdTgjtji.mjs +140 -0
- package/dist/plugins-BNFht2HW.mjs +23358 -0
- package/dist/plugins.d.mts +1 -0
- package/dist/plugins.mjs +13 -0
- package/dist/react--VZQu7s1.mjs +560 -0
- package/dist/react.d.mts +1 -0
- package/dist/react.mjs +6 -0
- package/dist/server.d.mts +10 -0
- package/dist/server.mjs +45 -0
- package/dist/social-providers-DNfE9Ak7-Be5zMAEe.mjs +2920 -0
- package/dist/social-providers.d.mts +1 -0
- package/dist/social-providers.mjs +6 -0
- package/dist/verify-CN5Qc0e-.mjs +1183 -0
- package/package.json +98 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { a as DEFAULT_MIGRATION_LOCK_TABLE, c as DefaultQueryCompiler, l as sql, o as DEFAULT_MIGRATION_TABLE, s as CompiledQuery } from "./esm-C5TuvtGn.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../better-auth/dist/bun-sqlite-dialect-2R9nCsVF.mjs
|
|
4
|
+
var BunSqliteAdapter = class {
|
|
5
|
+
get supportsCreateIfNotExists() {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
get supportsTransactionalDdl() {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
get supportsReturning() {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
async acquireMigrationLock() {}
|
|
15
|
+
async releaseMigrationLock() {}
|
|
16
|
+
get supportsOutput() {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
var BunSqliteDriver = class {
|
|
21
|
+
#config;
|
|
22
|
+
#connectionMutex = new ConnectionMutex();
|
|
23
|
+
#db;
|
|
24
|
+
#connection;
|
|
25
|
+
constructor(config) {
|
|
26
|
+
this.#config = { ...config };
|
|
27
|
+
}
|
|
28
|
+
async init() {
|
|
29
|
+
this.#db = this.#config.database;
|
|
30
|
+
this.#connection = new BunSqliteConnection(this.#db);
|
|
31
|
+
if (this.#config.onCreateConnection) await this.#config.onCreateConnection(this.#connection);
|
|
32
|
+
}
|
|
33
|
+
async acquireConnection() {
|
|
34
|
+
await this.#connectionMutex.lock();
|
|
35
|
+
return this.#connection;
|
|
36
|
+
}
|
|
37
|
+
async beginTransaction(connection) {
|
|
38
|
+
await connection.executeQuery(CompiledQuery.raw("begin"));
|
|
39
|
+
}
|
|
40
|
+
async commitTransaction(connection) {
|
|
41
|
+
await connection.executeQuery(CompiledQuery.raw("commit"));
|
|
42
|
+
}
|
|
43
|
+
async rollbackTransaction(connection) {
|
|
44
|
+
await connection.executeQuery(CompiledQuery.raw("rollback"));
|
|
45
|
+
}
|
|
46
|
+
async releaseConnection() {
|
|
47
|
+
this.#connectionMutex.unlock();
|
|
48
|
+
}
|
|
49
|
+
async destroy() {
|
|
50
|
+
this.#db?.close();
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
var BunSqliteConnection = class {
|
|
54
|
+
#db;
|
|
55
|
+
constructor(db) {
|
|
56
|
+
this.#db = db;
|
|
57
|
+
}
|
|
58
|
+
executeQuery(compiledQuery) {
|
|
59
|
+
const { sql: sql$1, parameters } = compiledQuery;
|
|
60
|
+
const stmt = this.#db.prepare(sql$1);
|
|
61
|
+
return Promise.resolve({ rows: stmt.all(parameters) });
|
|
62
|
+
}
|
|
63
|
+
async *streamQuery() {
|
|
64
|
+
throw new Error("Streaming query is not supported by SQLite driver.");
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var ConnectionMutex = class {
|
|
68
|
+
#promise;
|
|
69
|
+
#resolve;
|
|
70
|
+
async lock() {
|
|
71
|
+
while (this.#promise) await this.#promise;
|
|
72
|
+
this.#promise = new Promise((resolve) => {
|
|
73
|
+
this.#resolve = resolve;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
unlock() {
|
|
77
|
+
const resolve = this.#resolve;
|
|
78
|
+
this.#promise = void 0;
|
|
79
|
+
this.#resolve = void 0;
|
|
80
|
+
resolve?.();
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
var BunSqliteIntrospector = class {
|
|
84
|
+
#db;
|
|
85
|
+
constructor(db) {
|
|
86
|
+
this.#db = db;
|
|
87
|
+
}
|
|
88
|
+
async getSchemas() {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
async getTables(options = { withInternalKyselyTables: false }) {
|
|
92
|
+
let query = this.#db.selectFrom("sqlite_schema").where("type", "=", "table").where("name", "not like", "sqlite_%").select("name").$castTo();
|
|
93
|
+
if (!options.withInternalKyselyTables) query = query.where("name", "!=", DEFAULT_MIGRATION_TABLE).where("name", "!=", DEFAULT_MIGRATION_LOCK_TABLE);
|
|
94
|
+
const tables = await query.execute();
|
|
95
|
+
return Promise.all(tables.map(({ name }) => this.#getTableMetadata(name)));
|
|
96
|
+
}
|
|
97
|
+
async getMetadata(options) {
|
|
98
|
+
return { tables: await this.getTables(options) };
|
|
99
|
+
}
|
|
100
|
+
async #getTableMetadata(table) {
|
|
101
|
+
const db = this.#db;
|
|
102
|
+
const autoIncrementCol = (await db.selectFrom("sqlite_master").where("name", "=", table).select("sql").$castTo().execute())[0]?.sql?.split(/[\(\),]/)?.find((it) => it.toLowerCase().includes("autoincrement"))?.split(/\s+/)?.[0]?.replace(/["`]/g, "");
|
|
103
|
+
return {
|
|
104
|
+
name: table,
|
|
105
|
+
columns: (await db.selectFrom(sql`pragma_table_info(${table})`.as("table_info")).select([
|
|
106
|
+
"name",
|
|
107
|
+
"type",
|
|
108
|
+
"notnull",
|
|
109
|
+
"dflt_value"
|
|
110
|
+
]).execute()).map((col) => ({
|
|
111
|
+
name: col.name,
|
|
112
|
+
dataType: col.type,
|
|
113
|
+
isNullable: !col.notnull,
|
|
114
|
+
isAutoIncrementing: col.name === autoIncrementCol,
|
|
115
|
+
hasDefaultValue: col.dflt_value != null
|
|
116
|
+
})),
|
|
117
|
+
isView: true
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
var BunSqliteQueryCompiler = class extends DefaultQueryCompiler {
|
|
122
|
+
getCurrentParameterPlaceholder() {
|
|
123
|
+
return "?";
|
|
124
|
+
}
|
|
125
|
+
getLeftIdentifierWrapper() {
|
|
126
|
+
return "\"";
|
|
127
|
+
}
|
|
128
|
+
getRightIdentifierWrapper() {
|
|
129
|
+
return "\"";
|
|
130
|
+
}
|
|
131
|
+
getAutoIncrement() {
|
|
132
|
+
return "autoincrement";
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
var BunSqliteDialect = class {
|
|
136
|
+
#config;
|
|
137
|
+
constructor(config) {
|
|
138
|
+
this.#config = { ...config };
|
|
139
|
+
}
|
|
140
|
+
createDriver() {
|
|
141
|
+
return new BunSqliteDriver(this.#config);
|
|
142
|
+
}
|
|
143
|
+
createQueryCompiler() {
|
|
144
|
+
return new BunSqliteQueryCompiler();
|
|
145
|
+
}
|
|
146
|
+
createAdapter() {
|
|
147
|
+
return new BunSqliteAdapter();
|
|
148
|
+
}
|
|
149
|
+
createIntrospector(db) {
|
|
150
|
+
return new BunSqliteIntrospector(db);
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
//#endregion
|
|
155
|
+
export { BunSqliteDialect };
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { g as BetterAuthError } from "./env-DwlNAN_D-C1zHd0cf-Cdlw8sNp.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../better-auth/dist/has-permission-BYrcx2Uw.mjs
|
|
4
|
+
function role(statements) {
|
|
5
|
+
return {
|
|
6
|
+
authorize(request, connector = "AND") {
|
|
7
|
+
let success = false;
|
|
8
|
+
for (const [requestedResource, requestedActions] of Object.entries(request)) {
|
|
9
|
+
const allowedActions = statements[requestedResource];
|
|
10
|
+
if (!allowedActions) return {
|
|
11
|
+
success: false,
|
|
12
|
+
error: `You are not allowed to access resource: ${requestedResource}`
|
|
13
|
+
};
|
|
14
|
+
if (Array.isArray(requestedActions)) success = requestedActions.every((requestedAction) => allowedActions.includes(requestedAction));
|
|
15
|
+
else if (typeof requestedActions === "object") {
|
|
16
|
+
const actions = requestedActions;
|
|
17
|
+
if (actions.connector === "OR") success = actions.actions.some((requestedAction) => allowedActions.includes(requestedAction));
|
|
18
|
+
else success = actions.actions.every((requestedAction) => allowedActions.includes(requestedAction));
|
|
19
|
+
} else throw new BetterAuthError("Invalid access control request");
|
|
20
|
+
if (success && connector === "OR") return { success };
|
|
21
|
+
if (!success && connector === "AND") return {
|
|
22
|
+
success: false,
|
|
23
|
+
error: `unauthorized to access resource "${requestedResource}"`
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (success) return { success };
|
|
27
|
+
return {
|
|
28
|
+
success: false,
|
|
29
|
+
error: "Not authorized"
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
statements
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function createAccessControl(s) {
|
|
36
|
+
return {
|
|
37
|
+
newRole(statements) {
|
|
38
|
+
return role(statements);
|
|
39
|
+
},
|
|
40
|
+
statements: s
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const defaultAc = createAccessControl({
|
|
44
|
+
user: [
|
|
45
|
+
"create",
|
|
46
|
+
"list",
|
|
47
|
+
"set-role",
|
|
48
|
+
"ban",
|
|
49
|
+
"impersonate",
|
|
50
|
+
"delete",
|
|
51
|
+
"set-password",
|
|
52
|
+
"get",
|
|
53
|
+
"update"
|
|
54
|
+
],
|
|
55
|
+
session: [
|
|
56
|
+
"list",
|
|
57
|
+
"revoke",
|
|
58
|
+
"delete"
|
|
59
|
+
]
|
|
60
|
+
});
|
|
61
|
+
const adminAc = defaultAc.newRole({
|
|
62
|
+
user: [
|
|
63
|
+
"create",
|
|
64
|
+
"list",
|
|
65
|
+
"set-role",
|
|
66
|
+
"ban",
|
|
67
|
+
"impersonate",
|
|
68
|
+
"delete",
|
|
69
|
+
"set-password",
|
|
70
|
+
"get",
|
|
71
|
+
"update"
|
|
72
|
+
],
|
|
73
|
+
session: [
|
|
74
|
+
"list",
|
|
75
|
+
"revoke",
|
|
76
|
+
"delete"
|
|
77
|
+
]
|
|
78
|
+
});
|
|
79
|
+
const userAc = defaultAc.newRole({
|
|
80
|
+
user: [],
|
|
81
|
+
session: []
|
|
82
|
+
});
|
|
83
|
+
const defaultRoles = {
|
|
84
|
+
admin: adminAc,
|
|
85
|
+
user: userAc
|
|
86
|
+
};
|
|
87
|
+
const hasPermission = (input) => {
|
|
88
|
+
if (input.userId && input.options?.adminUserIds?.includes(input.userId)) return true;
|
|
89
|
+
if (!input.permissions && !input.permission) return false;
|
|
90
|
+
const roles = (input.role || input.options?.defaultRole || "user").split(",");
|
|
91
|
+
const acRoles = input.options?.roles || defaultRoles;
|
|
92
|
+
for (const role$1 of roles) if ((acRoles[role$1]?.authorize(input.permission ?? input.permissions))?.success) return true;
|
|
93
|
+
return false;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
//#endregion
|
|
97
|
+
//#region ../better-auth/dist/client--1_AEBPu.mjs
|
|
98
|
+
const twoFactorClient = (options) => {
|
|
99
|
+
return {
|
|
100
|
+
id: "two-factor",
|
|
101
|
+
$InferServerPlugin: {},
|
|
102
|
+
atomListeners: [{
|
|
103
|
+
matcher: (path) => path.startsWith("/two-factor/"),
|
|
104
|
+
signal: "$sessionSignal"
|
|
105
|
+
}],
|
|
106
|
+
pathMethods: {
|
|
107
|
+
"/two-factor/disable": "POST",
|
|
108
|
+
"/two-factor/enable": "POST",
|
|
109
|
+
"/two-factor/send-otp": "POST",
|
|
110
|
+
"/two-factor/generate-backup-codes": "POST"
|
|
111
|
+
},
|
|
112
|
+
fetchPlugins: [{
|
|
113
|
+
id: "two-factor",
|
|
114
|
+
name: "two-factor",
|
|
115
|
+
hooks: { async onSuccess(context) {
|
|
116
|
+
if (context.data?.twoFactorRedirect) {
|
|
117
|
+
if (options?.onTwoFactorRedirect) await options.onTwoFactorRedirect();
|
|
118
|
+
}
|
|
119
|
+
} }
|
|
120
|
+
}]
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
//#endregion
|
|
125
|
+
export { role as a, hasPermission as i, adminAc as n, userAc as o, createAccessControl as r, twoFactorClient as t };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AuthClient } from "better-auth/react";
|
|
2
|
+
import { adminClient, apiKeyClient, lastLoginMethodClient, organizationClient, twoFactorClient } from "better-auth/client/plugins";
|
|
3
|
+
import { ssoClient } from "@better-auth/sso/client";
|
|
4
|
+
export * from "better-auth/client/plugins";
|
|
5
|
+
|
|
6
|
+
//#region src/client.d.ts
|
|
7
|
+
|
|
8
|
+
declare const createEnterpriseClient: ({
|
|
9
|
+
baseURL
|
|
10
|
+
}: {
|
|
11
|
+
baseURL: string;
|
|
12
|
+
}) => AuthClient<{
|
|
13
|
+
baseURL: string;
|
|
14
|
+
plugins: [ReturnType<typeof organizationClient>, ReturnType<typeof adminClient>, ReturnType<typeof apiKeyClient>, ReturnType<typeof ssoClient>, ReturnType<typeof twoFactorClient>, ReturnType<typeof lastLoginMethodClient>];
|
|
15
|
+
}>;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { createEnterpriseClient };
|
package/dist/client.mjs
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import "./env-DwlNAN_D-C1zHd0cf-Cdlw8sNp.mjs";
|
|
2
|
+
import "./dist-CygcgJYk.mjs";
|
|
3
|
+
import "./misc-CbURQDlR-sLtUwwQY.mjs";
|
|
4
|
+
import "./parser-bL7W2mQ0-YdTgjtji.mjs";
|
|
5
|
+
import { i as hasPermission, n as adminAc, o as userAc, t as twoFactorClient } from "./client--1_AEBPu-8Ae9icC9.mjs";
|
|
6
|
+
import { i as useAuthQuery, n as createAuthClient } from "./react--VZQu7s1.mjs";
|
|
7
|
+
import { atom } from "nanostores";
|
|
8
|
+
|
|
9
|
+
//#region ../better-auth/dist/client/plugins/index.mjs
|
|
10
|
+
const inferAdditionalFields = (schema) => {
|
|
11
|
+
return {
|
|
12
|
+
id: "additional-fields-client",
|
|
13
|
+
$InferServerPlugin: {}
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
const adminClient = (options) => {
|
|
17
|
+
const roles = {
|
|
18
|
+
admin: adminAc,
|
|
19
|
+
user: userAc,
|
|
20
|
+
...options?.roles
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
id: "admin-client",
|
|
24
|
+
$InferServerPlugin: {},
|
|
25
|
+
getActions: () => ({ admin: { checkRolePermission: (data) => {
|
|
26
|
+
return hasPermission({
|
|
27
|
+
role: data.role,
|
|
28
|
+
options: {
|
|
29
|
+
ac: options?.ac,
|
|
30
|
+
roles
|
|
31
|
+
},
|
|
32
|
+
permissions: data.permissions ?? data.permission
|
|
33
|
+
});
|
|
34
|
+
} } }),
|
|
35
|
+
pathMethods: {
|
|
36
|
+
"/admin/list-users": "GET",
|
|
37
|
+
"/admin/stop-impersonating": "POST"
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
const anonymousClient = () => {
|
|
42
|
+
return {
|
|
43
|
+
id: "anonymous",
|
|
44
|
+
$InferServerPlugin: {},
|
|
45
|
+
pathMethods: { "/sign-in/anonymous": "POST" },
|
|
46
|
+
atomListeners: [{
|
|
47
|
+
matcher: (path) => path === "/sign-in/anonymous",
|
|
48
|
+
signal: "$sessionSignal"
|
|
49
|
+
}]
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
const apiKeyClient = () => {
|
|
53
|
+
return {
|
|
54
|
+
id: "api-key",
|
|
55
|
+
$InferServerPlugin: {},
|
|
56
|
+
pathMethods: {
|
|
57
|
+
"/api-key/create": "POST",
|
|
58
|
+
"/api-key/delete": "POST",
|
|
59
|
+
"/api-key/delete-all-expired-api-keys": "POST"
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
const customSessionClient = () => {
|
|
64
|
+
return InferServerPlugin();
|
|
65
|
+
};
|
|
66
|
+
const deviceAuthorizationClient = () => {
|
|
67
|
+
return {
|
|
68
|
+
id: "device-authorization",
|
|
69
|
+
$InferServerPlugin: {},
|
|
70
|
+
pathMethods: {
|
|
71
|
+
"/device/code": "POST",
|
|
72
|
+
"/device/token": "POST",
|
|
73
|
+
"/device": "GET",
|
|
74
|
+
"/device/approve": "POST",
|
|
75
|
+
"/device/deny": "POST"
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
const emailOTPClient = () => {
|
|
80
|
+
return {
|
|
81
|
+
id: "email-otp",
|
|
82
|
+
$InferServerPlugin: {},
|
|
83
|
+
atomListeners: [{
|
|
84
|
+
matcher: (path) => path === "/email-otp/verify-email" || path === "/sign-in/email-otp",
|
|
85
|
+
signal: "$sessionSignal"
|
|
86
|
+
}]
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
const genericOAuthClient = () => {
|
|
90
|
+
return {
|
|
91
|
+
id: "generic-oauth-client",
|
|
92
|
+
$InferServerPlugin: {}
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
const jwtClient = () => {
|
|
96
|
+
return {
|
|
97
|
+
id: "better-auth-client",
|
|
98
|
+
$InferServerPlugin: {}
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
function getCookieValue(name) {
|
|
102
|
+
if (typeof document === "undefined") return null;
|
|
103
|
+
const cookie = document.cookie.split("; ").find((row) => row.startsWith(`${name}=`));
|
|
104
|
+
return cookie ? cookie.split("=")[1] : null;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Client-side plugin to retrieve the last used login method
|
|
108
|
+
*/
|
|
109
|
+
const lastLoginMethodClient = (config = {}) => {
|
|
110
|
+
const cookieName = config.cookieName || "better-auth.last_used_login_method";
|
|
111
|
+
return {
|
|
112
|
+
id: "last-login-method-client",
|
|
113
|
+
getActions() {
|
|
114
|
+
return {
|
|
115
|
+
getLastUsedLoginMethod: () => {
|
|
116
|
+
return getCookieValue(cookieName);
|
|
117
|
+
},
|
|
118
|
+
clearLastUsedLoginMethod: () => {
|
|
119
|
+
if (typeof document !== "undefined") document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
|
|
120
|
+
},
|
|
121
|
+
isLastUsedLoginMethod: (method) => {
|
|
122
|
+
return getCookieValue(cookieName) === method;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
const magicLinkClient = () => {
|
|
129
|
+
return {
|
|
130
|
+
id: "magic-link",
|
|
131
|
+
$InferServerPlugin: {}
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
const multiSessionClient = () => {
|
|
135
|
+
return {
|
|
136
|
+
id: "multi-session",
|
|
137
|
+
$InferServerPlugin: {},
|
|
138
|
+
atomListeners: [{
|
|
139
|
+
matcher(path) {
|
|
140
|
+
return path === "/multi-session/set-active";
|
|
141
|
+
},
|
|
142
|
+
signal: "$sessionSignal"
|
|
143
|
+
}]
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
const oidcClient = () => {
|
|
147
|
+
return {
|
|
148
|
+
id: "oidc-client",
|
|
149
|
+
$InferServerPlugin: {}
|
|
150
|
+
};
|
|
151
|
+
};
|
|
152
|
+
let isRequestInProgress = false;
|
|
153
|
+
const oneTapClient = (options) => {
|
|
154
|
+
return {
|
|
155
|
+
id: "one-tap",
|
|
156
|
+
getActions: ($fetch, _) => ({ oneTap: async (opts, fetchOptions) => {
|
|
157
|
+
if (isRequestInProgress) {
|
|
158
|
+
console.warn("A Google One Tap request is already in progress. Please wait.");
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
isRequestInProgress = true;
|
|
162
|
+
try {
|
|
163
|
+
if (typeof window === "undefined" || !window.document) {
|
|
164
|
+
console.warn("Google One Tap is only available in browser environments");
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const { autoSelect, cancelOnTapOutside, context } = opts ?? {};
|
|
168
|
+
const contextValue = context ?? options.context ?? "signin";
|
|
169
|
+
await loadGoogleScript();
|
|
170
|
+
await new Promise((resolve, reject) => {
|
|
171
|
+
let isResolved = false;
|
|
172
|
+
const baseDelay = options.promptOptions?.baseDelay ?? 1e3;
|
|
173
|
+
const maxAttempts = options.promptOptions?.maxAttempts ?? 5;
|
|
174
|
+
window.google?.accounts.id.initialize({
|
|
175
|
+
client_id: options.clientId,
|
|
176
|
+
callback: async (response) => {
|
|
177
|
+
isResolved = true;
|
|
178
|
+
try {
|
|
179
|
+
await $fetch("/one-tap/callback", {
|
|
180
|
+
method: "POST",
|
|
181
|
+
body: { idToken: response.credential },
|
|
182
|
+
...opts?.fetchOptions,
|
|
183
|
+
...fetchOptions
|
|
184
|
+
});
|
|
185
|
+
if (!opts?.fetchOptions && !fetchOptions || opts?.callbackURL) window.location.href = opts?.callbackURL ?? "/";
|
|
186
|
+
resolve();
|
|
187
|
+
} catch (error) {
|
|
188
|
+
console.error("Error during One Tap callback:", error);
|
|
189
|
+
reject(error);
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
auto_select: autoSelect,
|
|
193
|
+
cancel_on_tap_outside: cancelOnTapOutside,
|
|
194
|
+
context: contextValue,
|
|
195
|
+
...options.additionalOptions
|
|
196
|
+
});
|
|
197
|
+
const handlePrompt = (attempt) => {
|
|
198
|
+
if (isResolved) return;
|
|
199
|
+
window.google?.accounts.id.prompt((notification) => {
|
|
200
|
+
if (isResolved) return;
|
|
201
|
+
if (notification.isDismissedMoment && notification.isDismissedMoment()) if (attempt < maxAttempts) {
|
|
202
|
+
const delay = Math.pow(2, attempt) * baseDelay;
|
|
203
|
+
setTimeout(() => handlePrompt(attempt + 1), delay);
|
|
204
|
+
} else opts?.onPromptNotification?.(notification);
|
|
205
|
+
else if (notification.isSkippedMoment && notification.isSkippedMoment()) if (attempt < maxAttempts) {
|
|
206
|
+
const delay = Math.pow(2, attempt) * baseDelay;
|
|
207
|
+
setTimeout(() => handlePrompt(attempt + 1), delay);
|
|
208
|
+
} else opts?.onPromptNotification?.(notification);
|
|
209
|
+
});
|
|
210
|
+
};
|
|
211
|
+
handlePrompt(0);
|
|
212
|
+
});
|
|
213
|
+
} catch (error) {
|
|
214
|
+
console.error("Error during Google One Tap flow:", error);
|
|
215
|
+
throw error;
|
|
216
|
+
} finally {
|
|
217
|
+
isRequestInProgress = false;
|
|
218
|
+
}
|
|
219
|
+
} }),
|
|
220
|
+
getAtoms($fetch) {
|
|
221
|
+
return {};
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
};
|
|
225
|
+
const loadGoogleScript = () => {
|
|
226
|
+
return new Promise((resolve) => {
|
|
227
|
+
if (window.googleScriptInitialized) {
|
|
228
|
+
resolve();
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const script = document.createElement("script");
|
|
232
|
+
script.src = "https://accounts.google.com/gsi/client";
|
|
233
|
+
script.async = true;
|
|
234
|
+
script.defer = true;
|
|
235
|
+
script.onload = () => {
|
|
236
|
+
window.googleScriptInitialized = true;
|
|
237
|
+
resolve();
|
|
238
|
+
};
|
|
239
|
+
document.head.appendChild(script);
|
|
240
|
+
});
|
|
241
|
+
};
|
|
242
|
+
const oneTimeTokenClient = () => {
|
|
243
|
+
return {
|
|
244
|
+
id: "one-time-token",
|
|
245
|
+
$InferServerPlugin: {}
|
|
246
|
+
};
|
|
247
|
+
};
|
|
248
|
+
const organizationClient = (options) => {
|
|
249
|
+
const $listOrg = atom(false);
|
|
250
|
+
const $activeOrgSignal = atom(false);
|
|
251
|
+
const $activeMemberSignal = atom(false);
|
|
252
|
+
const $activeMemberRoleSignal = atom(false);
|
|
253
|
+
return {
|
|
254
|
+
id: "organization",
|
|
255
|
+
$InferServerPlugin: {},
|
|
256
|
+
getActions: ($fetch, _$store, co) => ({
|
|
257
|
+
$Infer: {
|
|
258
|
+
ActiveOrganization: {},
|
|
259
|
+
Organization: {},
|
|
260
|
+
Invitation: {},
|
|
261
|
+
Member: {},
|
|
262
|
+
Team: {}
|
|
263
|
+
},
|
|
264
|
+
organization: {}
|
|
265
|
+
}),
|
|
266
|
+
getAtoms: ($fetch) => {
|
|
267
|
+
const listOrganizations = useAuthQuery($listOrg, "/organization/list", $fetch, { method: "GET" });
|
|
268
|
+
return {
|
|
269
|
+
$listOrg,
|
|
270
|
+
$activeOrgSignal,
|
|
271
|
+
$activeMemberSignal,
|
|
272
|
+
$activeMemberRoleSignal,
|
|
273
|
+
activeOrganization: useAuthQuery([$activeOrgSignal], "/organization/get-full-organization", $fetch, () => ({ method: "GET" })),
|
|
274
|
+
listOrganizations,
|
|
275
|
+
activeMember: useAuthQuery([$activeMemberSignal], "/organization/get-active-member", $fetch, { method: "GET" }),
|
|
276
|
+
activeMemberRole: useAuthQuery([$activeMemberRoleSignal], "/organization/get-active-member-role", $fetch, { method: "GET" })
|
|
277
|
+
};
|
|
278
|
+
},
|
|
279
|
+
pathMethods: {
|
|
280
|
+
"/organization/get-full-organization": "GET",
|
|
281
|
+
"/organization/list-user-teams": "GET"
|
|
282
|
+
},
|
|
283
|
+
atomListeners: [
|
|
284
|
+
{
|
|
285
|
+
matcher(path) {
|
|
286
|
+
return path === "/organization/create" || path === "/organization/delete" || path === "/organization/update";
|
|
287
|
+
},
|
|
288
|
+
signal: "$listOrg"
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
matcher(path) {
|
|
292
|
+
return path.startsWith("/organization");
|
|
293
|
+
},
|
|
294
|
+
signal: "$activeOrgSignal"
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
matcher(path) {
|
|
298
|
+
return path.startsWith("/organization/set-active");
|
|
299
|
+
},
|
|
300
|
+
signal: "$sessionSignal"
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
matcher(path) {
|
|
304
|
+
return path.includes("/organization/update-member-role");
|
|
305
|
+
},
|
|
306
|
+
signal: "$activeMemberSignal"
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
matcher(path) {
|
|
310
|
+
return path.includes("/organization/update-member-role");
|
|
311
|
+
},
|
|
312
|
+
signal: "$activeMemberRoleSignal"
|
|
313
|
+
}
|
|
314
|
+
]
|
|
315
|
+
};
|
|
316
|
+
};
|
|
317
|
+
const inferOrgAdditionalFields = (schema) => {
|
|
318
|
+
return {};
|
|
319
|
+
};
|
|
320
|
+
const phoneNumberClient = () => {
|
|
321
|
+
return {
|
|
322
|
+
id: "phoneNumber",
|
|
323
|
+
$InferServerPlugin: {},
|
|
324
|
+
atomListeners: [{
|
|
325
|
+
matcher(path) {
|
|
326
|
+
return path === "/phone-number/update" || path === "/phone-number/verify" || path === "/sign-in/phone-number";
|
|
327
|
+
},
|
|
328
|
+
signal: "$sessionSignal"
|
|
329
|
+
}]
|
|
330
|
+
};
|
|
331
|
+
};
|
|
332
|
+
const siweClient = () => {
|
|
333
|
+
return {
|
|
334
|
+
id: "siwe",
|
|
335
|
+
$InferServerPlugin: {}
|
|
336
|
+
};
|
|
337
|
+
};
|
|
338
|
+
const usernameClient = () => {
|
|
339
|
+
return {
|
|
340
|
+
id: "username",
|
|
341
|
+
$InferServerPlugin: {},
|
|
342
|
+
atomListeners: [{
|
|
343
|
+
matcher: (path) => path === "/sign-in/username",
|
|
344
|
+
signal: "$sessionSignal"
|
|
345
|
+
}]
|
|
346
|
+
};
|
|
347
|
+
};
|
|
348
|
+
const InferServerPlugin = () => {
|
|
349
|
+
return {
|
|
350
|
+
id: "infer-server-plugin",
|
|
351
|
+
$InferServerPlugin: {}
|
|
352
|
+
};
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
//#endregion
|
|
356
|
+
//#region ../sso/dist/client.mjs
|
|
357
|
+
const ssoClient = (options) => {
|
|
358
|
+
return {
|
|
359
|
+
id: "sso-client",
|
|
360
|
+
$InferServerPlugin: {}
|
|
361
|
+
};
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
//#endregion
|
|
365
|
+
//#region src/client.ts
|
|
366
|
+
const createEnterpriseClient = ({ baseURL }) => {
|
|
367
|
+
return createAuthClient({
|
|
368
|
+
baseURL,
|
|
369
|
+
plugins: [
|
|
370
|
+
organizationClient(),
|
|
371
|
+
adminClient(),
|
|
372
|
+
apiKeyClient(),
|
|
373
|
+
ssoClient(),
|
|
374
|
+
twoFactorClient(),
|
|
375
|
+
lastLoginMethodClient()
|
|
376
|
+
]
|
|
377
|
+
});
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
//#endregion
|
|
381
|
+
export { InferServerPlugin, adminClient, anonymousClient, apiKeyClient, createEnterpriseClient, customSessionClient, deviceAuthorizationClient, emailOTPClient, genericOAuthClient, inferAdditionalFields, inferOrgAdditionalFields, jwtClient, lastLoginMethodClient, magicLinkClient, multiSessionClient, oidcClient, oneTapClient, oneTimeTokenClient, organizationClient, phoneNumberClient, siweClient, twoFactorClient, usernameClient };
|