@protobase/server 0.48.0 → 0.49.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/dist/admin-options.d.ts +2 -2
- package/dist/app-identity.d.ts +2 -2
- package/dist/app-name.d.ts +2 -0
- package/dist/better-auth/auth-settings.d.ts +8754 -0
- package/dist/better-auth/auth-settings.js +43 -0
- package/dist/better-auth/authenticate-settings.d.ts +15 -0
- package/dist/better-auth/authenticate-settings.js +12 -0
- package/dist/better-auth/create-auth.d.ts +23 -11
- package/dist/better-auth/create-auth.js +21 -9
- package/dist/better-auth/mcp/mcp-auth-plugins.d.ts +2719 -0
- package/dist/better-auth/mcp/mcp-auth-plugins.js +68 -0
- package/dist/better-auth/mcp/mcp-plugins.d.ts +7 -2
- package/dist/better-auth/mcp/mcp-plugins.js +3 -68
- package/dist/better-auth/mcp/mcp-token-claims.js +1 -1
- package/dist/better-auth/organizations/store.d.ts +1 -0
- package/dist/better-auth/saml-plugin.d.ts +993 -0
- package/dist/better-auth/saml-plugin.js +36 -0
- package/dist/better-auth/saml-sign-in.d.ts +27 -1
- package/dist/better-auth/saml-sign-in.js +1 -33
- package/dist/better-auth/user-table.js +1 -1
- package/dist/better-auth/users.d.ts +1 -1
- package/dist/create-admin.d.ts +5 -3
- package/dist/create-admin.js +3 -1
- package/dist/encryption/keyring.js +1 -1
- package/dist/files/options.d.ts +5 -8
- package/dist/files/provider-settings.d.ts +16 -0
- package/dist/files/provider-settings.js +17 -0
- package/dist/files/runtime.js +4 -4
- package/dist/forms/runtime.js +3 -3
- package/dist/index.d.ts +16 -15
- package/dist/index.js +8 -10
- package/dist/internal.d.ts +13 -0
- package/dist/internal.js +13 -0
- package/dist/jobs/declared-job.d.ts +24 -0
- package/dist/jobs/declared-job.js +26 -0
- package/dist/jobs/job-types.d.ts +1 -1
- package/dist/mcp/mcp-authenticator.js +3 -3
- package/dist/notifications/device-store-of.d.ts +1 -1
- package/dist/notifications/device-store-of.js +1 -1
- package/dist/notifications/device-store.d.ts +1 -1
- package/dist/notifications/device-store.js +1 -1
- package/dist/notifications/history-store-of.d.ts +1 -1
- package/dist/notifications/history-store-of.js +1 -1
- package/dist/notifications/history-store.d.ts +1 -1
- package/dist/notifications/history-store.js +1 -1
- package/dist/notifications/options.d.ts +3 -1
- package/dist/notifications/options.js +1 -1
- package/dist/notifications/schema.d.ts +2 -2
- package/dist/notifications/schema.js +7 -7
- package/dist/notifications/send-notification.js +1 -1
- package/dist/notifications/sender.d.ts +1 -1
- package/dist/notifications/sender.js +2 -2
- package/dist/notifications/senders-of.d.ts +1 -1
- package/dist/notifications/senders-of.js +1 -1
- package/dist/package.js +1 -1
- package/dist/webhooks/subscription.d.ts +1 -0
- package/dist/webhooks/table/options.d.ts +1 -1
- package/dist/webhooks/table/schema.d.ts +2 -2
- package/dist/webhooks/table/schema.js +2 -2
- package/dist/webhooks/table/webhook-table.js +2 -2
- package/dist/webhooks/table/webhooks-module.d.ts +108 -0
- package/dist/webhooks/table/webhooks-module.js +11 -0
- package/package.json +6 -5
- package/dist/notifications/plugin.d.ts +0 -13
- package/dist/notifications/plugin.js +0 -16
- package/dist/project-config.d.ts +0 -54
- package/dist/project-config.js +0 -182
- package/dist/webhooks/table/plugin.d.ts +0 -10
- package/dist/webhooks/table/plugin.js +0 -18
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { buildAuth } from "./create-auth.js";
|
|
2
|
+
import { PostgresDialect } from "kysely";
|
|
3
|
+
//#region src/better-auth/auth-settings.ts
|
|
4
|
+
const organizationOptions = (organizations, hooks, app) => {
|
|
5
|
+
if (!organizations) return void 0;
|
|
6
|
+
const own = hooks.organizationHooks ?? {};
|
|
7
|
+
const betterAuthHooks = Object.fromEntries(Object.entries(own).map(([name, hook]) => [name, (input) => hook(input, app)]));
|
|
8
|
+
return {
|
|
9
|
+
...organizations === true ? {} : organizations,
|
|
10
|
+
...hooks.generateOrganizationId && { generateId: () => hooks.generateOrganizationId(app) },
|
|
11
|
+
...hooks.onOrganizationCreated && { onCreated: (input) => hooks.onOrganizationCreated(input, app) },
|
|
12
|
+
...hooks.beforeOrganizationDeleted && { beforeDelete: (organization) => hooks.beforeOrganizationDeleted(organization, app) },
|
|
13
|
+
...Object.keys(betterAuthHooks).length > 0 && { hooks: betterAuthHooks }
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
/** createAuth's options for the `auth` settings, the store in the app's own database. */
|
|
17
|
+
const appAuthOptions = (settings, { pool, db, hooks = {}, mailer }) => {
|
|
18
|
+
const { schema = "auth", secret, generateUserId, mailer: mail, organizations, mcp, ...rest } = settings;
|
|
19
|
+
if (!secret) throw new Error("the auth secret is not set: give it the app's secret, PROTOBASE_SECRET, made with `openssl rand -base64 32`");
|
|
20
|
+
const app = { db };
|
|
21
|
+
const organizationsOptions = organizationOptions(organizations, hooks, app);
|
|
22
|
+
const userId = hooks.generateUserId ? () => hooks.generateUserId(app) : generateUserId;
|
|
23
|
+
const onUserCreated = hooks.onUserCreated && ((user, context) => hooks.onUserCreated(user, context, app));
|
|
24
|
+
return {
|
|
25
|
+
...rest,
|
|
26
|
+
database: {
|
|
27
|
+
dialect: new PostgresDialect({ pool }),
|
|
28
|
+
type: "postgres",
|
|
29
|
+
schemaName: schema,
|
|
30
|
+
transaction: true
|
|
31
|
+
},
|
|
32
|
+
secret,
|
|
33
|
+
...userId && { generateUserId: userId },
|
|
34
|
+
...onUserCreated && { onUserCreated },
|
|
35
|
+
...mail === false ? { mailer: false } : mailer && { mailer },
|
|
36
|
+
...organizationsOptions && { organizations: organizationsOptions },
|
|
37
|
+
...mcp && { mcp }
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
/** The app's Better Auth from its `auth` settings, built at serve time with only the plugins they turn on. */
|
|
41
|
+
const buildAppAuth = (settings, input) => buildAuth(appAuthOptions(settings, input));
|
|
42
|
+
//#endregion
|
|
43
|
+
export { appAuthOptions, buildAppAuth };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { TenantValue } from "../types.js";
|
|
2
|
+
import { BetterAuthAuthenticator, BetterAuthAuthenticatorOptions } from "./authenticator.js";
|
|
3
|
+
import { AdminAuth } from "./create-auth.js";
|
|
4
|
+
//#region src/better-auth/authenticate-settings.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* `authenticate` in `protobase.config.ts`: how the API verifies the app's tokens, as data. Without it, the tokens of
|
|
7
|
+
* the app's own `auth`; `jwksUrl` and `issuer` verify those of an auth server elsewhere instead.
|
|
8
|
+
*/
|
|
9
|
+
export type AuthenticateSettings = Omit<BetterAuthAuthenticatorOptions, 'auth' | 'tenant'> & {
|
|
10
|
+
/** The one tenant everyone works in, for an app without organizations; never read from the token. */
|
|
11
|
+
tenant?: TenantValue;
|
|
12
|
+
};
|
|
13
|
+
/** The authenticator of the `authenticate` settings, over the app's Better Auth when it has one. */
|
|
14
|
+
export declare const buildAuthenticator: (settings?: AuthenticateSettings, auth?: AdminAuth) => BetterAuthAuthenticator;
|
|
15
|
+
//#endregion
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { betterAuthAuthenticator } from "./authenticator.js";
|
|
2
|
+
//#region src/better-auth/authenticate-settings.ts
|
|
3
|
+
/** The authenticator of the `authenticate` settings, over the app's Better Auth when it has one. */
|
|
4
|
+
const buildAuthenticator = (settings = {}, auth) => {
|
|
5
|
+
if (!auth && !settings.jwksUrl) throw new Error("No authenticator: give the config `auth`, or `authenticate.jwksUrl` and `issuer` for an auth server elsewhere; see https://docs.protobase.net/reference/auth/");
|
|
6
|
+
return betterAuthAuthenticator({
|
|
7
|
+
...settings,
|
|
8
|
+
...auth && { auth }
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
export { buildAuthenticator };
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { UserColumn, UserTableOptions } from "./user-table.js";
|
|
2
2
|
import { Mailer } from "../mail/smtp-mailer.js";
|
|
3
3
|
import { SignInPolicy } from "./sign-in-policy.js";
|
|
4
|
-
import { OperatorProvider } from "./operator-provider.js";
|
|
5
|
-
import { PlatformSignIn } from "./platform-sign-in.js";
|
|
6
|
-
import { RoleDefinitions, RolesInput } from "./organizations/role-definitions.js";
|
|
7
|
-
import { OrganizationRole } from "./organizations/store.js";
|
|
8
|
-
import { OrganizationsOptions, ResolvedOrganizations } from "./organizations/options.js";
|
|
9
4
|
import { StaffSignIn } from "./staff-log.js";
|
|
10
|
-
import "
|
|
5
|
+
import { RoleDefinitions, RolesInput } from "./organizations/role-definitions.js";
|
|
11
6
|
import { ConnectedApp } from "./mcp/connected-apps.js";
|
|
12
7
|
import { ReplacingContext } from "./end-replaced-session.js";
|
|
13
8
|
import { UserDeletionListener } from "./user-deletion.js";
|
|
14
|
-
import "./
|
|
9
|
+
import { OrganizationRole } from "./organizations/store.js";
|
|
10
|
+
import { OrganizationsOptions, ResolvedOrganizations } from "./organizations/options.js";
|
|
15
11
|
import { McpAuthOptions } from "./mcp/mcp-plugins.js";
|
|
12
|
+
import { OperatorProvider } from "./operator-provider.js";
|
|
13
|
+
import { PlatformSignIn } from "./platform-sign-in.js";
|
|
14
|
+
import "../index.js";
|
|
15
|
+
import "./auth-base-path.js";
|
|
16
|
+
import { mcpAuthPlugins } from "./mcp/mcp-auth-plugins.js";
|
|
16
17
|
import { SsoOptions } from "./saml-sign-in.js";
|
|
18
|
+
import { samlPlugin } from "./saml-plugin.js";
|
|
17
19
|
import { signUpPaths } from "./sign-up/sign-up-plugin.js";
|
|
18
20
|
import { PasswordHash } from "./password-hashes.js";
|
|
19
21
|
import { BetterAuthOptions } from "better-auth";
|
|
@@ -169,7 +171,17 @@ export type UserCreatedHook = NonNullable<UserCreateHooks['after']>;
|
|
|
169
171
|
*/
|
|
170
172
|
/** The configured roles with `admin` first; `admin` is added when missing. */
|
|
171
173
|
export declare const normalizeRoles: (roles?: RolesInput) => string[];
|
|
172
|
-
|
|
174
|
+
/**
|
|
175
|
+
* The plugins only some apps use, which `loadAuthPlugins` imports when the options turn them on: the SSO plugin of
|
|
176
|
+
* `sso.saml` and the OAuth provider of `mcp`.
|
|
177
|
+
*/
|
|
178
|
+
export type AuthPlugins = {
|
|
179
|
+
samlPlugin?: typeof samlPlugin;
|
|
180
|
+
mcpAuthPlugins?: typeof mcpAuthPlugins;
|
|
181
|
+
};
|
|
182
|
+
/** The optional plugins `options` turns on, imported: an app without SAML or MCP loads neither. */
|
|
183
|
+
export declare const loadAuthPlugins: (options: Pick<CreateAuthOptions, "sso" | "mcp">) => Promise<AuthPlugins>;
|
|
184
|
+
export declare const createAuth: (options: CreateAuthOptions, plugins?: AuthPlugins) => import("better-auth").Auth<{
|
|
173
185
|
user: {
|
|
174
186
|
modelName: string;
|
|
175
187
|
fields: {
|
|
@@ -473,9 +485,7 @@ export declare const createAuth: (options: CreateAuthOptions) => import("better-
|
|
|
473
485
|
expiresAt: Date;
|
|
474
486
|
token: string;
|
|
475
487
|
ipAddress?: string | null | undefined;
|
|
476
|
-
userAgent
|
|
477
|
-
/** Sign-in attempts allowed per minute and client, default 5; also the sign-up requests allowed. */
|
|
478
|
-
/** Sign-in attempts allowed per minute and client, default 5; also the sign-up requests allowed. */ : string | null | undefined;
|
|
488
|
+
userAgent?: string | null | undefined;
|
|
479
489
|
};
|
|
480
490
|
};
|
|
481
491
|
}>>[];
|
|
@@ -8868,4 +8878,6 @@ export declare const createAuth: (options: CreateAuthOptions) => import("better-
|
|
|
8868
8878
|
} | undefined;
|
|
8869
8879
|
};
|
|
8870
8880
|
export type AdminAuth = ReturnType<typeof createAuth>;
|
|
8881
|
+
/** `createAuth` with the optional plugins its options turn on loaded first (see `loadAuthPlugins`). */
|
|
8882
|
+
export declare const buildAuth: (options: CreateAuthOptions) => Promise<AdminAuth>;
|
|
8871
8883
|
//#endregion
|
|
@@ -20,27 +20,27 @@ import { signUpPaths, signUpPlugin } from "./sign-up/sign-up-plugin.js";
|
|
|
20
20
|
import { leakedPasswordsPlugin } from "./leaked-passwords.js";
|
|
21
21
|
import { userDeletion } from "./user-deletion.js";
|
|
22
22
|
import { revokeMcpGrants } from "./mcp/revoke-grants.js";
|
|
23
|
-
import {
|
|
23
|
+
import { mcpUnusedPaths, resolveMcp } from "./mcp/mcp-plugins.js";
|
|
24
24
|
import { lastOrganizationField, sessionOrganizationHooks } from "./organizations/session-organization.js";
|
|
25
|
-
import { tokenClaims } from "./token-claims.js";
|
|
26
|
-
import { mcpAuthPlugins, mcpUnusedPaths, resolveMcp } from "./mcp/mcp-plugins.js";
|
|
27
25
|
import { organizationPlugin } from "./organizations/organization-plugin.js";
|
|
28
26
|
import { protobaseOrganizationPlugin } from "./organizations/protobase-plugin.js";
|
|
29
27
|
import { resolveOrganizations } from "./organizations/options.js";
|
|
30
28
|
import { passkeyHosts, readPasskeyDomain, resolvePasskeyDomain } from "./passkey-domain.js";
|
|
29
|
+
import { coreNames, pluginNames } from "./snake-case-names.js";
|
|
31
30
|
import { passkeyPlugin } from "./passkey-plugin.js";
|
|
32
31
|
import { passwordResetOptions } from "./password-reset.js";
|
|
33
32
|
import { rolesPlugin } from "./roles/roles-plugin.js";
|
|
34
33
|
import { platformSignInFor, platformSignInProvider, readPlatformSignIn, resolvePlatformSignIn } from "./platform-sign-in.js";
|
|
35
34
|
import { appSignInPolicy } from "./app-sign-in-policy.js";
|
|
36
35
|
import { assertNoEndpointKeyClashes } from "./endpoint-key-clashes.js";
|
|
37
|
-
import { emailInDomains, resolveSamlProviders, samlDisabledPaths, samlGuardPlugin
|
|
36
|
+
import { emailInDomains, resolveSamlProviders, samlDisabledPaths, samlGuardPlugin } from "./saml-sign-in.js";
|
|
38
37
|
import { noAccountMailPlugin } from "./no-account-mail.js";
|
|
39
38
|
import { emailCodeOptions, twoFactorCodeOptions, unusedEmailCodePaths } from "./sign-in-mail.js";
|
|
40
39
|
import { confirmedOnCreate, confirmedOnUpdate, emailConfirmedField } from "./email-confirmed.js";
|
|
41
40
|
import { rehashPasswordsPlugin, verifyAcceptedHash } from "./password-hashes.js";
|
|
42
41
|
import { staffSignInPlugin } from "./staff-plugin.js";
|
|
43
42
|
import { strongSignInsPlugin } from "./strong-sign-ins.js";
|
|
43
|
+
import { tokenClaims } from "./token-claims.js";
|
|
44
44
|
import { twoFactorAfterPasswordOrCode } from "./two-factor-challenge.js";
|
|
45
45
|
import { metadataField, userFieldsNamed, userModel, userTable, withUserColumns } from "./user-table.js";
|
|
46
46
|
import { usersPlugin } from "./users/users-plugin.js";
|
|
@@ -70,6 +70,15 @@ const tokenLifetime = "15m";
|
|
|
70
70
|
/** The configured roles with `admin` first; `admin` is added when missing. */
|
|
71
71
|
const normalizeRoles = (roles) => roleDefinitions(roles).names;
|
|
72
72
|
const adminImpersonationPaths = ["/admin/impersonate-user", "/admin/stop-impersonating"];
|
|
73
|
+
/** The optional plugins `options` turns on, imported: an app without SAML or MCP loads neither. */
|
|
74
|
+
const loadAuthPlugins = async (options) => ({
|
|
75
|
+
...(options.sso?.saml.length ?? 0) > 0 && { samlPlugin: (await import("./saml-plugin.js")).samlPlugin },
|
|
76
|
+
...options.mcp && { mcpAuthPlugins: (await import("./mcp/mcp-auth-plugins.js")).mcpAuthPlugins }
|
|
77
|
+
});
|
|
78
|
+
const loaded = (plugin, option) => {
|
|
79
|
+
if (!plugin) throw new Error(`${option} needs its plugin loaded: build auth with buildAuth, which loads it`);
|
|
80
|
+
return plugin;
|
|
81
|
+
};
|
|
73
82
|
const newUserId = (generate) => generate === "uuid" ? crypto.randomUUID() : generate();
|
|
74
83
|
const noContext = () => Promise.reject(/* @__PURE__ */ new Error("The auth context is read only once createAuth has made the instance"));
|
|
75
84
|
const organizationPaths = ["/organization/set-active", "/organization/accept-invitation"];
|
|
@@ -77,7 +86,7 @@ const organizationPaths = ["/organization/set-active", "/organization/accept-inv
|
|
|
77
86
|
* The options `createAuth` gives Better Auth, with the roles, default role, mailer, operator provider and platform
|
|
78
87
|
* sign-in provider already resolved.
|
|
79
88
|
*/
|
|
80
|
-
const betterAuthOptions = (options, { origins = [], passkeyDomain, roles, definitions, defaultRole, appName = defaultAppName, mailer, signUpRole, operator, platformSignIn, saml = [], organizations, mcp, context = noContext, signInPolicy = defaultSignInPolicy, mobile, deletion }) => {
|
|
89
|
+
const betterAuthOptions = (options, { origins = [], passkeyDomain, roles, definitions, defaultRole, appName = defaultAppName, mailer, signUpRole, operator, platformSignIn, saml = [], organizations, mcp, context = noContext, signInPolicy = defaultSignInPolicy, mobile, deletion, ...plugins }) => {
|
|
81
90
|
const secure = options.baseURL.startsWith("https://");
|
|
82
91
|
const signIn = platformSignInFor(platformSignIn, Object.keys(options.socialProviders ?? {}));
|
|
83
92
|
const hosts = passkeyHosts([options.baseURL, ...origins]);
|
|
@@ -185,7 +194,7 @@ const betterAuthOptions = (options, { origins = [], passkeyDomain, roles, defini
|
|
|
185
194
|
defaultPolicy: signInPolicy
|
|
186
195
|
})] : [],
|
|
187
196
|
...signIn ? [genericOAuth({ config: [platformSignInProvider(signIn)] })] : [],
|
|
188
|
-
...saml.length > 0 ? [samlPlugin(saml, options.baseURL), samlGuardPlugin(samlIds)] : [],
|
|
197
|
+
...saml.length > 0 ? [loaded(plugins.samlPlugin, "sso.saml")(saml, options.baseURL), samlGuardPlugin(samlIds)] : [],
|
|
189
198
|
signInPolicyPlugin(policy),
|
|
190
199
|
setPasswordPlugin(),
|
|
191
200
|
...options.leakedPasswords ? [leakedPasswordsPlugin()] : [],
|
|
@@ -220,7 +229,7 @@ const betterAuthOptions = (options, { origins = [], passkeyDomain, roles, defini
|
|
|
220
229
|
...organizations && { organizations }
|
|
221
230
|
}),
|
|
222
231
|
...passwordHashes.length > 0 ? [rehashPasswordsPlugin(passwordHashes)] : [],
|
|
223
|
-
...mcp ? mcpAuthPlugins({
|
|
232
|
+
...mcp ? loaded(plugins.mcpAuthPlugins, "mcp")({
|
|
224
233
|
mcp,
|
|
225
234
|
organizations: Boolean(organizations),
|
|
226
235
|
mail: Boolean(mailer),
|
|
@@ -318,7 +327,7 @@ const checkSignUpRole = (role, roles) => {
|
|
|
318
327
|
if (!roles.includes(role)) throw new Error(`signUp.role "${role}" is not one of the roles: ${roles.join(", ")}`);
|
|
319
328
|
return role;
|
|
320
329
|
};
|
|
321
|
-
const createAuth = (options) => {
|
|
330
|
+
const createAuth = (options, plugins = {}) => {
|
|
322
331
|
if (options.signUp && options.organizations) throw new Error("signUp is not available with organizations: their people join by invitation");
|
|
323
332
|
const definitions = roleDefinitions(options.roles, { organizations: options.organizations !== void 0 });
|
|
324
333
|
const roles = definitions.names;
|
|
@@ -344,6 +353,7 @@ const createAuth = (options) => {
|
|
|
344
353
|
const mobile = mobileRequests();
|
|
345
354
|
const deletion = userDeletion();
|
|
346
355
|
const authOptions = betterAuthOptions(options, {
|
|
356
|
+
...plugins,
|
|
347
357
|
mobile,
|
|
348
358
|
deletion,
|
|
349
359
|
origins,
|
|
@@ -428,5 +438,7 @@ const createAuth = (options) => {
|
|
|
428
438
|
}
|
|
429
439
|
});
|
|
430
440
|
};
|
|
441
|
+
/** `createAuth` with the optional plugins its options turn on loaded first (see `loadAuthPlugins`). */
|
|
442
|
+
const buildAuth = async (options) => createAuth(options, await loadAuthPlugins(options));
|
|
431
443
|
//#endregion
|
|
432
|
-
export { authBasePath, betterAuthOptions, createAuth, normalizeRoles };
|
|
444
|
+
export { authBasePath, betterAuthOptions, buildAuth, createAuth, loadAuthPlugins, normalizeRoles };
|