@protobase/server 0.26.9 → 0.27.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/api-cors.js +14 -3
- package/dist/app-name.d.ts +4 -0
- package/dist/better-auth/create-auth.d.ts +2 -2
- package/dist/better-auth/create-auth.js +4 -3
- package/dist/better-auth/origins.js +6 -1
- package/dist/better-auth/passkey-plugin.js +5 -5
- package/dist/create-admin.d.ts +4 -1
- package/dist/create-admin.js +3 -3
- package/dist/gotrue/provider-flows.js +42 -0
- package/dist/gotrue/provider-routes.js +39 -25
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/mobile-config.d.ts +9 -0
- package/dist/mobile-config.js +8 -0
- package/dist/project-config.d.ts +3 -0
- package/dist/project-config.js +4 -2
- package/package.json +4 -4
package/dist/admin-options.d.ts
CHANGED
|
@@ -55,8 +55,8 @@ export type AdminOptions = {
|
|
|
55
55
|
/**
|
|
56
56
|
* The websites whose browser code may call the API (`/api/*` but `/api/auth/*`) besides the app's own origins (see
|
|
57
57
|
* `createAuth`'s `origins`): a list of origins, or `*` for any. Defaults to the one the platform passes in
|
|
58
|
-
* `PROTOBASE_CORS_ORIGINS` (`*` or comma separated), when set.
|
|
59
|
-
* CORS headers.
|
|
58
|
+
* `PROTOBASE_CORS_ORIGINS` (`*` or comma separated), when set. A `mobile` section adds the app's Capacitor origins
|
|
59
|
+
* (`capacitor://localhost`, `https://localhost`). With none of these nor other origins, the API sends no CORS headers.
|
|
60
60
|
*/
|
|
61
61
|
cors?: CorsOrigins;
|
|
62
62
|
/** The runtime updates endpoint behind the top bar's update button (see `RuntimeOptions`); `false` turns it off. */
|
package/dist/api-cors.js
CHANGED
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
import { readList } from "./better-auth/origins.js";
|
|
2
|
+
import { capacitorOrigins } from "./mobile-config.js";
|
|
2
3
|
import { cors } from "hono/cors";
|
|
3
4
|
//#region src/api-cors.ts
|
|
4
5
|
const corsOriginsVariable = "PROTOBASE_CORS_ORIGINS";
|
|
5
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* The origins in `PROTOBASE_CORS_ORIGINS`, `*` or comma separated; `undefined` when it is unset. One that is not an
|
|
8
|
+
* http or https URL stops the server at startup: another scheme, such as `capacitor:`, has the origin `null`.
|
|
9
|
+
*/
|
|
6
10
|
const readCorsOrigins = (env) => {
|
|
7
11
|
const value = env[corsOriginsVariable]?.trim();
|
|
8
12
|
if (!value) return void 0;
|
|
9
13
|
if (value === "*") return "*";
|
|
10
14
|
return readList(value).map((origin) => {
|
|
11
15
|
if (!URL.canParse(origin)) throw new Error(`${corsOriginsVariable} lists "${origin}", which is not a URL such as https://shop.com`);
|
|
12
|
-
|
|
16
|
+
const url = new URL(origin);
|
|
17
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error(`${corsOriginsVariable} lists "${origin}", but it takes http and https origins only; a mobile section in protobase.config.ts allows the app's Capacitor origins`);
|
|
18
|
+
return url.origin;
|
|
13
19
|
});
|
|
14
20
|
};
|
|
21
|
+
/** The allowed origins plus the Capacitor ones when the app has a mobile section; `*` stays `*`. */
|
|
22
|
+
const withMobileOrigins = (allowed, mobile) => {
|
|
23
|
+
if (!mobile || allowed === "*") return allowed;
|
|
24
|
+
return [.../* @__PURE__ */ new Set([...allowed ?? [], ...capacitorOrigins])];
|
|
25
|
+
};
|
|
15
26
|
const allowHeaders = [
|
|
16
27
|
"authorization",
|
|
17
28
|
"content-type",
|
|
@@ -53,4 +64,4 @@ const apiCors = ({ own, allowed, skip }) => {
|
|
|
53
64
|
return (c, next) => skip(c.req.path) ? next() : handler(c, next);
|
|
54
65
|
};
|
|
55
66
|
//#endregion
|
|
56
|
-
export { apiCors, corsOriginsVariable, readCorsOrigins };
|
|
67
|
+
export { apiCors, corsOriginsVariable, readCorsOrigins, withMobileOrigins };
|
|
@@ -1347,7 +1347,7 @@ export declare const createAuth: (options: CreateAuthOptions) => import("better-
|
|
|
1347
1347
|
$Infer: {
|
|
1348
1348
|
body: {
|
|
1349
1349
|
token: string;
|
|
1350
|
-
issuer
|
|
1350
|
+
issuer?: string;
|
|
1351
1351
|
};
|
|
1352
1352
|
response: {
|
|
1353
1353
|
payload: {
|
|
@@ -4018,7 +4018,7 @@ export declare const createAuth: (options: CreateAuthOptions) => import("better-
|
|
|
4018
4018
|
userId: string;
|
|
4019
4019
|
expiresAt: Date;
|
|
4020
4020
|
token: string;
|
|
4021
|
-
ipAddress
|
|
4021
|
+
ipAddress? /** The RP ID of new passkeys. */ : string | null | undefined;
|
|
4022
4022
|
userAgent?: string | null | undefined;
|
|
4023
4023
|
};
|
|
4024
4024
|
user: Record<string, any> & {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { multiHostBaseURL, readOrigins, resolveOrigins } from "./origins.js";
|
|
1
|
+
import { appOrigins, multiHostBaseURL, readOrigins, resolveOrigins } from "./origins.js";
|
|
2
2
|
import { defaultAppName, readAppName } from "../app-name.js";
|
|
3
3
|
import { goTrueIssuer, goTrueKeyPair } from "../gotrue/keys.js";
|
|
4
4
|
import { roleDefinitions } from "./organizations/role-definitions.js";
|
|
@@ -148,7 +148,8 @@ const betterAuthOptions = (options, { origins = [], passkeyDomain, roles, defini
|
|
|
148
148
|
passkeyPlugin({
|
|
149
149
|
domain: passkeyDomain ?? hosts[0],
|
|
150
150
|
hosts,
|
|
151
|
-
formerDomain: hosts[0]
|
|
151
|
+
formerDomain: hosts[0],
|
|
152
|
+
origins: appOrigins(options.baseURL, origins)
|
|
152
153
|
}),
|
|
153
154
|
...mail ? [emailOTP(emailCodeOptions(mail))] : [],
|
|
154
155
|
...mail && signUpRole ? [signUpPlugin({
|
|
@@ -310,7 +311,7 @@ const createAuth = (options) => {
|
|
|
310
311
|
/** Issuer and audience of the tokens: `baseURL`, on every origin. */
|
|
311
312
|
issuer: options.baseURL,
|
|
312
313
|
/** Every origin the app is served on, `baseURL`'s first. */
|
|
313
|
-
origins:
|
|
314
|
+
origins: appOrigins(options.baseURL, origins),
|
|
314
315
|
/** The RP ID of new passkeys. */
|
|
315
316
|
passkeyDomain,
|
|
316
317
|
roles,
|
|
@@ -24,6 +24,11 @@ const resolveOrigins = (baseURL, origins) => {
|
|
|
24
24
|
return [...new Set(resolved)].filter((origin) => origin !== base.origin);
|
|
25
25
|
};
|
|
26
26
|
/**
|
|
27
|
+
* Every origin the app is served on: `baseURL`'s, then the others from `resolveOrigins`. The only origins a passkey's
|
|
28
|
+
* answer may name, and the list `/.well-known/webauthn` serves; never empty.
|
|
29
|
+
*/
|
|
30
|
+
const appOrigins = (baseURL, origins) => [new URL(baseURL).origin, ...origins];
|
|
31
|
+
/**
|
|
27
32
|
* Better Auth's `baseURL` for an app on several origins: each request is answered for its own host when that is one of
|
|
28
33
|
* them (its links, such as a password reset, and its passkey and sign-in callbacks then stay on that host), and for
|
|
29
34
|
* `baseURL` otherwise. With no other origins it is `baseURL` itself.
|
|
@@ -40,4 +45,4 @@ const multiHostBaseURL = (baseURL, origins) => {
|
|
|
40
45
|
/** Where browsers read which origins may use the app's passkeys (WebAuthn Related Origin Requests). */
|
|
41
46
|
const webauthnPath = "/.well-known/webauthn";
|
|
42
47
|
//#endregion
|
|
43
|
-
export { multiHostBaseURL, originsVariable, readList, readOrigins, resolveOrigins, webauthnPath };
|
|
48
|
+
export { appOrigins, multiHostBaseURL, originsVariable, readList, readOrigins, resolveOrigins, webauthnPath };
|
|
@@ -18,11 +18,13 @@ const decodeBase64 = (value) => Uint8Array.from(atob(value), (char) => char.char
|
|
|
18
18
|
* RP ID it was made with, so changing the passkey domain breaks none. A sign-in asks the browser for passkeys of one RP
|
|
19
19
|
* ID, `?rpId=` or the passkey domain, and checks the passkey it gets against its own. On an app with several origins,
|
|
20
20
|
* browsers let each origin use the passkeys of the others through `/.well-known/webauthn` (Related Origin Requests).
|
|
21
|
+
* Adding a passkey and signing in with one both accept only an answer that names one of the app's own origins.
|
|
21
22
|
*/
|
|
22
|
-
const passkeyPlugin = ({ domain, hosts, formerDomain }) => {
|
|
23
|
+
const passkeyPlugin = ({ domain, hosts, formerDomain, origins }) => {
|
|
23
24
|
const base = passkey({
|
|
24
25
|
schema: pluginNames.passkey,
|
|
25
|
-
rpID: domain
|
|
26
|
+
rpID: domain,
|
|
27
|
+
origin: origins
|
|
26
28
|
});
|
|
27
29
|
const rpIDOf = (stored) => stored.rpID ?? formerDomain;
|
|
28
30
|
/** `GET /passkey/generate-authenticate-options?rpId=`: what the browser needs to ask for a passkey of that RP ID. */
|
|
@@ -70,8 +72,6 @@ const passkeyPlugin = ({ domain, hosts, formerDomain }) => {
|
|
|
70
72
|
method: "POST",
|
|
71
73
|
body: z$1.object({ response: z$1.record(z$1.any(), z$1.any()) })
|
|
72
74
|
}, async (ctx) => {
|
|
73
|
-
const origin = ctx.headers?.get("origin");
|
|
74
|
-
if (!origin) throw new APIError("BAD_REQUEST", { message: "origin missing" });
|
|
75
75
|
const response = ctx.body.response;
|
|
76
76
|
const cookie = ctx.context.createAuthCookie(challengeCookie);
|
|
77
77
|
const token = await ctx.getSignedCookie(cookie.name, ctx.context.secret);
|
|
@@ -91,7 +91,7 @@ const passkeyPlugin = ({ domain, hosts, formerDomain }) => {
|
|
|
91
91
|
const verification = await verifyAuthenticationResponse({
|
|
92
92
|
response,
|
|
93
93
|
expectedChallenge,
|
|
94
|
-
expectedOrigin:
|
|
94
|
+
expectedOrigin: origins,
|
|
95
95
|
expectedRPID: rpIDOf(stored),
|
|
96
96
|
credential: {
|
|
97
97
|
id: stored.credentialID,
|
package/dist/create-admin.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MobileConfig } from "./mobile-config.js";
|
|
1
2
|
import { AdminAuth } from "./better-auth/create-auth.js";
|
|
2
3
|
import { EventsOptions } from "./changes/events-options.js";
|
|
3
4
|
import { JobDefinition } from "./jobs/job-types.js";
|
|
@@ -43,6 +44,8 @@ export type CreateAdminInput = {
|
|
|
43
44
|
subscriptions?: SubscriptionDefinition[];
|
|
44
45
|
/** Webhook subscriptions made in the admin app, from `extends: [webhooks()]` (see `WebhooksOptions`). */
|
|
45
46
|
webhooks?: WebhooksOptions;
|
|
47
|
+
/** The app's iOS and Android build (see `MobileConfig`): the API answers its Capacitor origins through CORS. */
|
|
48
|
+
mobile?: MobileConfig;
|
|
46
49
|
/**
|
|
47
50
|
* The plugins the app's bundle carries, as `protobase build` writes them: its protobase.ui.tsx and its extensions'
|
|
48
51
|
* UI configs, each a plugin.json path on the app's origin. `/meta` names them to everyone, before any other plugin,
|
|
@@ -69,5 +72,5 @@ export type CreateAdminInput = {
|
|
|
69
72
|
upgradeWebSocket?: UpgradeWebSocket;
|
|
70
73
|
};
|
|
71
74
|
/** The admin REST API as a Hono app. It uses only Web APIs, so it runs on Node, Workers and anywhere else Hono does. */
|
|
72
|
-
export declare const createAdmin: ({ resources: appResources, views: appViews, pages, userMenu, bottomBars, db, authenticate, auth, functions, files: filesOptions, events, history: historyOptions, jobs, subscriptions, webhooks: webhooksOptions, bundlePlugins, fieldTypes, options, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }: CreateAdminInput) => Admin;
|
|
75
|
+
export declare const createAdmin: ({ resources: appResources, views: appViews, pages, userMenu, bottomBars, db, authenticate, auth, functions, files: filesOptions, events, history: historyOptions, jobs, subscriptions, webhooks: webhooksOptions, mobile, bundlePlugins, fieldTypes, options, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }: CreateAdminInput) => Admin;
|
|
73
76
|
//#endregion
|
package/dist/create-admin.js
CHANGED
|
@@ -10,7 +10,7 @@ import { assistantSettings } from "./assistant/assistant-settings.js";
|
|
|
10
10
|
import { builtInAssistant } from "./assistant/built-in-assistant.js";
|
|
11
11
|
import { consoleAuditQueue } from "./audit/console-queue.js";
|
|
12
12
|
import { webauthnPath } from "./better-auth/origins.js";
|
|
13
|
-
import { apiCors, readCorsOrigins } from "./api-cors.js";
|
|
13
|
+
import { apiCors, readCorsOrigins, withMobileOrigins } from "./api-cors.js";
|
|
14
14
|
import { apiKeySettings } from "./api-keys/api-key-settings.js";
|
|
15
15
|
import { apiKeyCaller } from "./api-keys/resolve-caller.js";
|
|
16
16
|
import { jwtVerifier } from "./auth/jwt.js";
|
|
@@ -75,7 +75,7 @@ const declaredRoles = (auth, roles) => {
|
|
|
75
75
|
return names.length > 0 ? [...new Set(names)] : void 0;
|
|
76
76
|
};
|
|
77
77
|
/** The admin REST API as a Hono app. It uses only Web APIs, so it runs on Node, Workers and anywhere else Hono does. */
|
|
78
|
-
const createAdmin = ({ resources: appResources, views: appViews = [], pages = [], userMenu, bottomBars = [], db, authenticate, auth, functions = {}, files: filesOptions, events, history: historyOptions, jobs = [], subscriptions = [], webhooks: webhooksOptions, bundlePlugins = [], fieldTypes = {}, options = {}, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }) => {
|
|
78
|
+
const createAdmin = ({ resources: appResources, views: appViews = [], pages = [], userMenu, bottomBars = [], db, authenticate, auth, functions = {}, files: filesOptions, events, history: historyOptions, jobs = [], subscriptions = [], webhooks: webhooksOptions, mobile, bundlePlugins = [], fieldTypes = {}, options = {}, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }) => {
|
|
79
79
|
const basePath = options.basePath ?? "/api/v1";
|
|
80
80
|
const appModels = appResources.map((resource) => resource.toModel());
|
|
81
81
|
const withComments = appModels.some((model) => model.comments);
|
|
@@ -219,7 +219,7 @@ const createAdmin = ({ resources: appResources, views: appViews = [], pages = []
|
|
|
219
219
|
}, withAnonymous(authenticate, options.roles));
|
|
220
220
|
const app = new Hono();
|
|
221
221
|
app.onError(onError);
|
|
222
|
-
const corsOrigins = options.cors ?? readCorsOrigins(globalThis.process?.env ?? {});
|
|
222
|
+
const corsOrigins = withMobileOrigins(options.cors ?? readCorsOrigins(globalThis.process?.env ?? {}), Boolean(mobile));
|
|
223
223
|
const ownOrigins = auth?.origins ?? [];
|
|
224
224
|
if (corsOrigins !== void 0 || ownOrigins.length > 1) {
|
|
225
225
|
const answering = [authBasePath, ...Object.entries(apiFunctions).filter(([, fn]) => fn.options.cors).map(([name]) => `${systemPath}/functions/${name}`)];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { goTruePath } from "./keys.js";
|
|
2
|
+
import { hashOf } from "../better-auth/sign-up/sign-up-code.js";
|
|
3
|
+
import { generateRandomString } from "better-auth/crypto";
|
|
4
|
+
import { deleteCookie, getCookie, setCookie } from "hono/cookie";
|
|
5
|
+
//#region src/gotrue/provider-flows.ts
|
|
6
|
+
const flowSeconds = 600;
|
|
7
|
+
const flowCookie = (context) => context.createAuthCookie("gotrue_flow", {
|
|
8
|
+
maxAge: flowSeconds,
|
|
9
|
+
path: `${goTruePath}/callback`
|
|
10
|
+
});
|
|
11
|
+
const identifierOf = async (id) => `gotrue-provider-flow-${await hashOf(id)}`;
|
|
12
|
+
/** Keeps `flow` and gives the browser its id; answers the flow's hand-off secret. */
|
|
13
|
+
const startFlow = async (c, context, flow) => {
|
|
14
|
+
const id = generateRandomString(32);
|
|
15
|
+
const secret = generateRandomString(32);
|
|
16
|
+
const stored = {
|
|
17
|
+
...flow,
|
|
18
|
+
handOff: await hashOf(secret)
|
|
19
|
+
};
|
|
20
|
+
await context.internalAdapter.createVerificationValue({
|
|
21
|
+
identifier: await identifierOf(id),
|
|
22
|
+
value: JSON.stringify(stored),
|
|
23
|
+
expiresAt: new Date(Date.now() + flowSeconds * 1e3)
|
|
24
|
+
});
|
|
25
|
+
const { name, attributes } = flowCookie(context);
|
|
26
|
+
setCookie(c, name, id, attributes);
|
|
27
|
+
return secret;
|
|
28
|
+
};
|
|
29
|
+
/** Takes the flow of the browser's cookie, so it works once, and clears the cookie; nothing when there is none. */
|
|
30
|
+
const takeFlow = async (c, context) => {
|
|
31
|
+
const { name, attributes } = flowCookie(context);
|
|
32
|
+
const id = getCookie(c, name);
|
|
33
|
+
if (!id) return void 0;
|
|
34
|
+
deleteCookie(c, name, attributes);
|
|
35
|
+
const consumed = await context.internalAdapter.consumeVerificationValue(await identifierOf(id));
|
|
36
|
+
if (!consumed || new Date(consumed.expiresAt) < /* @__PURE__ */ new Date()) return void 0;
|
|
37
|
+
return JSON.parse(consumed.value);
|
|
38
|
+
};
|
|
39
|
+
/** Whether `secret` is the flow's hand-off secret. */
|
|
40
|
+
const isHandOff = async (flow, secret) => !!secret && await hashOf(secret) === flow.handOff;
|
|
41
|
+
//#endregion
|
|
42
|
+
export { isHandOff, startFlow, takeFlow };
|
|
@@ -2,6 +2,7 @@ import { goTruePath } from "./keys.js";
|
|
|
2
2
|
import { GoTrueError } from "./errors.js";
|
|
3
3
|
import { callBetterAuth } from "./forward.js";
|
|
4
4
|
import { issueAuthCode } from "./auth-codes.js";
|
|
5
|
+
import { isHandOff, startFlow, takeFlow } from "./provider-flows.js";
|
|
5
6
|
import { Hono } from "hono";
|
|
6
7
|
//#region src/gotrue/provider-routes.ts
|
|
7
8
|
const challengeOf = (query) => {
|
|
@@ -27,52 +28,65 @@ const providerRoutes = ({ auth, context, sessionOf }) => {
|
|
|
27
28
|
if (requested && URL.canParse(requested) && (await context()).isTrustedOrigin(requested)) return requested;
|
|
28
29
|
return own;
|
|
29
30
|
};
|
|
31
|
+
const implicitFragment = async (userId) => {
|
|
32
|
+
const session = await sessionOf((await (await context()).internalAdapter.createSession(userId)).token);
|
|
33
|
+
return {
|
|
34
|
+
access_token: session.access_token,
|
|
35
|
+
token_type: "bearer",
|
|
36
|
+
expires_in: String(session.expires_in),
|
|
37
|
+
expires_at: String(session.expires_at),
|
|
38
|
+
refresh_token: session.refresh_token
|
|
39
|
+
};
|
|
40
|
+
};
|
|
30
41
|
return new Hono().get("/authorize", async (c) => {
|
|
31
42
|
const query = c.req.query();
|
|
32
43
|
const provider = query.provider ?? "";
|
|
33
44
|
if (!auth.socialProviders.includes(provider)) throw new GoTrueError(400, "validation_failed", `Unsupported provider: ${provider || "none"} is not one of this app's`);
|
|
34
45
|
const challenge = challengeOf(query);
|
|
46
|
+
const redirectTo = await destination(query.redirect_to, c.req.raw);
|
|
47
|
+
if (!challenge && new URL(redirectTo).protocol !== "https:") throw new GoTrueError(400, "validation_failed", "A redirect_to that is not https needs a code_challenge");
|
|
48
|
+
const before = await auth.api.getSession({ headers: c.req.raw.headers });
|
|
49
|
+
const secret = await startFlow(c, await context(), {
|
|
50
|
+
redirectTo,
|
|
51
|
+
challenge,
|
|
52
|
+
sessionBefore: before?.session.id
|
|
53
|
+
});
|
|
35
54
|
const callback = new URL(`${goTruePath}/callback`, c.req.url);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
callback.searchParams.set("code_challenge", challenge.challenge);
|
|
39
|
-
callback.searchParams.set("code_challenge_method", challenge.method);
|
|
40
|
-
}
|
|
55
|
+
const success = new URL(callback);
|
|
56
|
+
success.searchParams.set("flow", secret);
|
|
41
57
|
const { json, headers } = await callBetterAuth(auth, c.req.raw, "/sign-in/social", {
|
|
42
58
|
provider,
|
|
43
|
-
callbackURL:
|
|
59
|
+
callbackURL: success.toString(),
|
|
44
60
|
errorCallbackURL: callback.toString(),
|
|
45
61
|
disableRedirect: true,
|
|
46
62
|
...query.scopes && { scopes: query.scopes.split(/[\s,]+/).filter(Boolean) }
|
|
47
63
|
});
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
return response;
|
|
64
|
+
for (const cookie of headers.getSetCookie()) c.header("set-cookie", cookie, { append: true });
|
|
65
|
+
return c.redirect(String(json.url), 302);
|
|
51
66
|
}).get("/callback", async (c) => {
|
|
52
67
|
const query = c.req.query();
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
const
|
|
57
|
-
if (!
|
|
68
|
+
const ctx = await context();
|
|
69
|
+
const flow = await takeFlow(c, ctx);
|
|
70
|
+
const signedIn = flow && !query.error && await isHandOff(flow, query.flow) && await auth.api.getSession({ headers: c.req.raw.headers });
|
|
71
|
+
const made = signedIn && signedIn.session.id !== flow.sessionBefore ? signedIn : void 0;
|
|
72
|
+
if (!flow || !made) {
|
|
58
73
|
const error = query.error ?? "access_denied";
|
|
74
|
+
const target = flow?.redirectTo ?? await destination(query.redirect_to, c.req.raw);
|
|
75
|
+
const where = (flow ? flow.challenge : query.code_challenge) ? "search" : "hash";
|
|
59
76
|
return c.redirect(withParams(target, {
|
|
60
77
|
error,
|
|
61
78
|
error_code: error,
|
|
62
79
|
error_description: query.error_description ?? "The sign-in with the provider did not complete"
|
|
63
80
|
}, where), 302);
|
|
64
81
|
}
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
refresh_token: session.refresh_token
|
|
74
|
-
};
|
|
75
|
-
return c.redirect(withParams(target, fragment, "hash"), 302);
|
|
82
|
+
const { redirectTo, challenge } = flow;
|
|
83
|
+
const handOff = challenge ? withParams(redirectTo, { code: await issueAuthCode(ctx, made.user.id, challenge) }, "search") : withParams(redirectTo, await implicitFragment(made.user.id), "hash");
|
|
84
|
+
const { headers } = await auth.api.signOut({
|
|
85
|
+
headers: c.req.raw.headers,
|
|
86
|
+
returnHeaders: true
|
|
87
|
+
});
|
|
88
|
+
for (const cookie of headers.getSetCookie()) c.header("set-cookie", cookie, { append: true });
|
|
89
|
+
return c.redirect(handOff, 302);
|
|
76
90
|
});
|
|
77
91
|
};
|
|
78
92
|
//#endregion
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MobileConfig } from "./mobile-config.js";
|
|
1
2
|
import { SignInPolicy, SignInRule, StaffAccessRule, defaultSignInPolicy, signInPolicyMethods } from "./better-auth/sign-in-policy.js";
|
|
2
3
|
import { StaffSignIn } from "./better-auth/staff-log.js";
|
|
3
4
|
import { MailMessage, Mailer } from "./mail/smtp-mailer.js";
|
|
@@ -55,6 +56,7 @@ import { parseRoles } from "./better-auth/parse-roles.js";
|
|
|
55
56
|
import { LinkedAccount, NewUser, StoredUser, createUser, deleteUser, hasUsers, listUsers, roleChoices, setUserBanned, setUserRole } from "./better-auth/users.js";
|
|
56
57
|
import { IssueTokenOptions, issueToken, maxTokenTtlSeconds } from "./better-auth/tokens.js";
|
|
57
58
|
import { webauthnPath } from "./better-auth/origins.js";
|
|
59
|
+
import { defaultAppName } from "./app-name.js";
|
|
58
60
|
import { authSchemaMigration, checkAuthSchema } from "./better-auth/auth-schema.js";
|
|
59
61
|
import { changesMigration, checkChanges, migrationCommand } from "./changes/capture-schema.js";
|
|
60
62
|
import { checkComputed, computedMigration } from "./computed/computed-schema.js";
|
|
@@ -96,4 +98,4 @@ import { isSchedule } from "./jobs/schedule.js";
|
|
|
96
98
|
import { DrainResult, JobsRuntime, StartJobsOptions, startJobs } from "./jobs/runtime.js";
|
|
97
99
|
import { jobsDrainApp } from "./jobs/drain-route.js";
|
|
98
100
|
import { checkJobsSchema, jobsSchema, jobsSchemaMigration } from "./jobs/schema.js";
|
|
99
|
-
export { type Admin, type AdminAuth, type AdminOptions, type ApiFunction, type ApiKeys, type ApiKeysOptions, type ApprovalAnswer, type ApprovalRequest, type AssistantBackend, type AssistantOptions, type AssistantSettings, type AssistantTool, type AuditEvent, type AuditQueue, type Authenticator, type BetterAuthAuthenticatorOptions, type Caller, type CallerOptions, type CapturedRow, type ChatMessage, type ChatTextPart, type CheckAiInput, type CleanupEntry, type CleanupReport, type CleanupSchedule, type CoalescedChange, type CommentItem, type CommentUsers, type Completion, type CompletionOptions, type Conversation, type ConversationRecord, type ConversationStore, type ConversationsOptions, type CorsOptions, type CorsOrigins, type CreateAdminInput, type CreateAuthOptions, type DrainResult, type EmailComponent, type EmailOptions, type EmailTemplate, type EnqueueOptions, type ErrorReporter, type ErrorReportingOptions, type ErrorReportingSettings, type EventData, type EventsOptions, FatalJobError, type FileCleanupInput, type FileLimits, type FileObject, type FileProvider, type FileRef, type FileStore, type FileVariantObject, type FilesOptions, type FunctionApp, type FunctionCaller, type FunctionContext, type FunctionEnv, type FunctionHandler, type FunctionOptions, type FunctionRecords, type FunctionSource, type HistoryOptions, HttpProblem, type IssueTokenOptions, type JobContext, type JobDefinition, type JobOptions, type JobsRuntime, type JwtOptions, type JwtVerifyOptions, type LinkedAccount, type ListParams, type LocalFilesOptions, type MailMessage, type Mailer, type MapLayer, type MapOptions, type MapSettings, type MemberInput, MissingCredentials, ModelError, type ModelSettings, type NewOrganization, type NewUser, type OperatorProvider, type OrganizationRole, type OrganizationsOptions, type PipelineHook, type PlatformSignIn, type PluginOption, type PluginRef, type ProjectConfig, type ProtectedFunctionOptions, type PublicFunctionContext, type PublicFunctionEnv, type PublicFunctionHandler, type PublicFunctionOptions, type QueryOptions, type QueryResult, type ReasoningDetail, type ReasoningEffort, type RecordKeyInput, type RecordPage, type RenderedEmail, type ResourceChange, type ResourceSource, type RoleDefinition, type RolesInput, type RunContext, type RuntimeOptions, type S3Bucket, type S3FilesOptions, type S3ListPage, type S3Object, type ScanGuardMode, type ScheduledDelete, type Session, type SessionOrganization, type Sharp, type SignInPolicy, type SignInRule, type SignatureOptions, type SourceOption, type SourceRef, type StaffAccessRule, type StaffSignIn, type StandardSchema, type StandardWebhookOptions, type StartJobsOptions, type StoreFileInput, type StoredMember, type StoredObject, type StoredOrganization, type StoredUser, type SubscriptionDefinition, type SubscriptionEvent, type SubscriptionOptions, type TenantValue, type ToolCall, type ToolContext, type ToolRecord, type ToolRecords, type ToolSpec, type TrustedApp, type TurnOptions, type User, type UserCreatedHook, type ViewSource, type WebhooksOptions, type WidgetOptions, type WriteEvent, type WriteOperation, addAppRoleToOwners, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaMigration, badRequest, beforeSignInPluginsVariable, betterAuthAuthenticator, betterAuthTokens, changesMigration, checkAi, checkAuthSchema, checkChanges, checkComments, checkComputed, checkJobsSchema, checkSourceNames, checkViewQueries, checkWebhooksSchema, coalesce, commentsMigration, computedMigration, configExports, consoleAuditQueue, conversationKey, createAdmin, createAuth, createConversations, createFileCleanup, createOrganization, createUser, defaultSignInPolicy, defineConfig, defineEmail, defineFunction, defineJob, defineTool, deleteUser, errorReportingSettings, errorReportingVariable, eventMatcher, fileConversationStore, fileSize, fileType, forbidden, formatUri, functionApp, handleDroppedConnections, hasUsers, imageSize, isBackgroundWork, isCaptured, isJobDefinition, isSchedule, issueToken, jobDefinitions, jobsDrainApp, jobsSchema, jobsSchemaMigration, jwtAuthenticator, jwtVerifier, limitedFileStore, listOrganizations, listUsers, localFileStore, localFiles, mapSettings, mapStyleUrl, mapStyleVariable, maxTokenTtlSeconds, maxWidgetPropsBytes, mergeConfig, migrationCommand, newWebhookSecret, normalizeRoles, notFound, parseColumns, parseRoles, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, processor, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readWriteQueryTool, recordOf, removeMember, renderVariant, requestApproval, requireEnv, resourceChange, roleChoices, runInBackground, runReadOnlyQuery, runReadWriteQuery, runTurn, runtimeUrl, runtimeVariable, s3FileStore, s3Files, seesAssistant, seesRuntime, setMemberRoles, setUserBanned, setUserRole, signInPolicyMethods, sourceOptions, sourcesFor, sourcesVariable, startErrorReporting, startJobs, storageCleanupSchedule, storeFile, streamChatCompletion, subscription, thumbHash, unauthorized, variantPath, verifySignature, verifyStandardWebhook, webauthnPath, webhooks, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps };
|
|
101
|
+
export { type Admin, type AdminAuth, type AdminOptions, type ApiFunction, type ApiKeys, type ApiKeysOptions, type ApprovalAnswer, type ApprovalRequest, type AssistantBackend, type AssistantOptions, type AssistantSettings, type AssistantTool, type AuditEvent, type AuditQueue, type Authenticator, type BetterAuthAuthenticatorOptions, type Caller, type CallerOptions, type CapturedRow, type ChatMessage, type ChatTextPart, type CheckAiInput, type CleanupEntry, type CleanupReport, type CleanupSchedule, type CoalescedChange, type CommentItem, type CommentUsers, type Completion, type CompletionOptions, type Conversation, type ConversationRecord, type ConversationStore, type ConversationsOptions, type CorsOptions, type CorsOrigins, type CreateAdminInput, type CreateAuthOptions, type DrainResult, type EmailComponent, type EmailOptions, type EmailTemplate, type EnqueueOptions, type ErrorReporter, type ErrorReportingOptions, type ErrorReportingSettings, type EventData, type EventsOptions, FatalJobError, type FileCleanupInput, type FileLimits, type FileObject, type FileProvider, type FileRef, type FileStore, type FileVariantObject, type FilesOptions, type FunctionApp, type FunctionCaller, type FunctionContext, type FunctionEnv, type FunctionHandler, type FunctionOptions, type FunctionRecords, type FunctionSource, type HistoryOptions, HttpProblem, type IssueTokenOptions, type JobContext, type JobDefinition, type JobOptions, type JobsRuntime, type JwtOptions, type JwtVerifyOptions, type LinkedAccount, type ListParams, type LocalFilesOptions, type MailMessage, type Mailer, type MapLayer, type MapOptions, type MapSettings, type MemberInput, MissingCredentials, type MobileConfig, ModelError, type ModelSettings, type NewOrganization, type NewUser, type OperatorProvider, type OrganizationRole, type OrganizationsOptions, type PipelineHook, type PlatformSignIn, type PluginOption, type PluginRef, type ProjectConfig, type ProtectedFunctionOptions, type PublicFunctionContext, type PublicFunctionEnv, type PublicFunctionHandler, type PublicFunctionOptions, type QueryOptions, type QueryResult, type ReasoningDetail, type ReasoningEffort, type RecordKeyInput, type RecordPage, type RenderedEmail, type ResourceChange, type ResourceSource, type RoleDefinition, type RolesInput, type RunContext, type RuntimeOptions, type S3Bucket, type S3FilesOptions, type S3ListPage, type S3Object, type ScanGuardMode, type ScheduledDelete, type Session, type SessionOrganization, type Sharp, type SignInPolicy, type SignInRule, type SignatureOptions, type SourceOption, type SourceRef, type StaffAccessRule, type StaffSignIn, type StandardSchema, type StandardWebhookOptions, type StartJobsOptions, type StoreFileInput, type StoredMember, type StoredObject, type StoredOrganization, type StoredUser, type SubscriptionDefinition, type SubscriptionEvent, type SubscriptionOptions, type TenantValue, type ToolCall, type ToolContext, type ToolRecord, type ToolRecords, type ToolSpec, type TrustedApp, type TurnOptions, type User, type UserCreatedHook, type ViewSource, type WebhooksOptions, type WidgetOptions, type WriteEvent, type WriteOperation, addAppRoleToOwners, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaMigration, badRequest, beforeSignInPluginsVariable, betterAuthAuthenticator, betterAuthTokens, changesMigration, checkAi, checkAuthSchema, checkChanges, checkComments, checkComputed, checkJobsSchema, checkSourceNames, checkViewQueries, checkWebhooksSchema, coalesce, commentsMigration, computedMigration, configExports, consoleAuditQueue, conversationKey, createAdmin, createAuth, createConversations, createFileCleanup, createOrganization, createUser, defaultAppName, defaultSignInPolicy, defineConfig, defineEmail, defineFunction, defineJob, defineTool, deleteUser, errorReportingSettings, errorReportingVariable, eventMatcher, fileConversationStore, fileSize, fileType, forbidden, formatUri, functionApp, handleDroppedConnections, hasUsers, imageSize, isBackgroundWork, isCaptured, isJobDefinition, isSchedule, issueToken, jobDefinitions, jobsDrainApp, jobsSchema, jobsSchemaMigration, jwtAuthenticator, jwtVerifier, limitedFileStore, listOrganizations, listUsers, localFileStore, localFiles, mapSettings, mapStyleUrl, mapStyleVariable, maxTokenTtlSeconds, maxWidgetPropsBytes, mergeConfig, migrationCommand, newWebhookSecret, normalizeRoles, notFound, parseColumns, parseRoles, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, processor, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readWriteQueryTool, recordOf, removeMember, renderVariant, requestApproval, requireEnv, resourceChange, roleChoices, runInBackground, runReadOnlyQuery, runReadWriteQuery, runTurn, runtimeUrl, runtimeVariable, s3FileStore, s3Files, seesAssistant, seesRuntime, setMemberRoles, setUserBanned, setUserRole, signInPolicyMethods, sourceOptions, sourcesFor, sourcesVariable, startErrorReporting, startJobs, storageCleanupSchedule, storeFile, streamChatCompletion, subscription, thumbHash, unauthorized, variantPath, verifySignature, verifyStandardWebhook, webauthnPath, webhooks, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps };
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ import { webauthnPath } from "./better-auth/origins.js";
|
|
|
21
21
|
import { apiKeySettings, apiKeyVariables } from "./api-keys/api-key-settings.js";
|
|
22
22
|
import { apiKeyCaller } from "./api-keys/resolve-caller.js";
|
|
23
23
|
import { jwtAuthenticator, jwtVerifier } from "./auth/jwt.js";
|
|
24
|
+
import { defaultAppName } from "./app-name.js";
|
|
24
25
|
import { defaultSignInPolicy, signInPolicyMethods } from "./better-auth/sign-in-policy.js";
|
|
25
26
|
import { parseRoles } from "./better-auth/parse-roles.js";
|
|
26
27
|
import { readOperatorSettings } from "./better-auth/operator-provider.js";
|
|
@@ -73,4 +74,4 @@ import { aspectRatio, fileSize, fileType, imageSize, processor } from "./files/p
|
|
|
73
74
|
import { defineEmail } from "./mail/define-email.js";
|
|
74
75
|
import { startJobs } from "./jobs/runtime.js";
|
|
75
76
|
import { jobsDrainApp } from "./jobs/drain-route.js";
|
|
76
|
-
export { FatalJobError, HttpProblem, MissingCredentials, ModelError, addAppRoleToOwners, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaMigration, badRequest, beforeSignInPluginsVariable, betterAuthAuthenticator, betterAuthTokens, changesMigration, checkAi, checkAuthSchema, checkChanges, checkComments, checkComputed, checkJobsSchema, checkSourceNames, checkViewQueries, checkWebhooksSchema, coalesce, commentsMigration, computedMigration, configExports, consoleAuditQueue, conversationKey, createAdmin, createAuth, createConversations, createFileCleanup, createOrganization, createUser, defaultSignInPolicy, defineConfig, defineEmail, defineFunction, defineJob, defineTool, deleteUser, errorReportingSettings, errorReportingVariable, eventMatcher, fileConversationStore, fileSize, fileType, forbidden, formatUri, functionApp, handleDroppedConnections, hasUsers, imageSize, isBackgroundWork, isCaptured, isJobDefinition, isSchedule, issueToken, jobDefinitions, jobsDrainApp, jobsSchema, jobsSchemaMigration, jwtAuthenticator, jwtVerifier, limitedFileStore, listOrganizations, listUsers, localFileStore, localFiles, mapSettings, mapStyleUrl, mapStyleVariable, maxTokenTtlSeconds, maxWidgetPropsBytes, mergeConfig, migrationCommand, newWebhookSecret, normalizeRoles, notFound, parseColumns, parseRoles, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, processor, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readWriteQueryTool, recordOf, removeMember, renderVariant, requestApproval, requireEnv, resourceChange, roleChoices, runInBackground, runReadOnlyQuery, runReadWriteQuery, runTurn, runtimeUrl, runtimeVariable, s3FileStore, s3Files, seesAssistant, seesRuntime, setMemberRoles, setUserBanned, setUserRole, signInPolicyMethods, sourceOptions, sourcesFor, sourcesVariable, startErrorReporting, startJobs, storageCleanupSchedule, storeFile, streamChatCompletion, subscription, thumbHash, unauthorized, variantPath, verifySignature, verifyStandardWebhook, webauthnPath, webhooks, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps };
|
|
77
|
+
export { FatalJobError, HttpProblem, MissingCredentials, ModelError, addAppRoleToOwners, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaMigration, badRequest, beforeSignInPluginsVariable, betterAuthAuthenticator, betterAuthTokens, changesMigration, checkAi, checkAuthSchema, checkChanges, checkComments, checkComputed, checkJobsSchema, checkSourceNames, checkViewQueries, checkWebhooksSchema, coalesce, commentsMigration, computedMigration, configExports, consoleAuditQueue, conversationKey, createAdmin, createAuth, createConversations, createFileCleanup, createOrganization, createUser, defaultAppName, defaultSignInPolicy, defineConfig, defineEmail, defineFunction, defineJob, defineTool, deleteUser, errorReportingSettings, errorReportingVariable, eventMatcher, fileConversationStore, fileSize, fileType, forbidden, formatUri, functionApp, handleDroppedConnections, hasUsers, imageSize, isBackgroundWork, isCaptured, isJobDefinition, isSchedule, issueToken, jobDefinitions, jobsDrainApp, jobsSchema, jobsSchemaMigration, jwtAuthenticator, jwtVerifier, limitedFileStore, listOrganizations, listUsers, localFileStore, localFiles, mapSettings, mapStyleUrl, mapStyleVariable, maxTokenTtlSeconds, maxWidgetPropsBytes, mergeConfig, migrationCommand, newWebhookSecret, normalizeRoles, notFound, parseColumns, parseRoles, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, processor, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readWriteQueryTool, recordOf, removeMember, renderVariant, requestApproval, requireEnv, resourceChange, roleChoices, runInBackground, runReadOnlyQuery, runReadWriteQuery, runTurn, runtimeUrl, runtimeVariable, s3FileStore, s3Files, seesAssistant, seesRuntime, setMemberRoles, setUserBanned, setUserRole, signInPolicyMethods, sourceOptions, sourcesFor, sourcesVariable, startErrorReporting, startJobs, storageCleanupSchedule, storeFile, streamChatCompletion, subscription, thumbHash, unauthorized, variantPath, verifySignature, verifyStandardWebhook, webauthnPath, webhooks, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/mobile-config.d.ts
|
|
2
|
+
/** The `mobile` section of `protobase.config.ts`: with it, `protobase mobile` builds the app for iOS and Android. */
|
|
3
|
+
export type MobileConfig = {
|
|
4
|
+
/** The app's id in reverse-DNS form, such as `com.example.shop`. */
|
|
5
|
+
appId: string;
|
|
6
|
+
/** Extra native Capacitor plugins the app needs, as npm name → version range, such as `{ '@capacitor/camera': '^8.0.0' }`. */
|
|
7
|
+
plugins?: Record<string, string>;
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region src/mobile-config.ts
|
|
2
|
+
/**
|
|
3
|
+
* The origins Capacitor's WebView serves the app's files on: `capacitor://localhost` on iOS, `https://localhost` on
|
|
4
|
+
* Android. They hold because `protobase mobile` never sets Capacitor's `server.hostname` or schemes.
|
|
5
|
+
*/
|
|
6
|
+
const capacitorOrigins = ["capacitor://localhost", "https://localhost"];
|
|
7
|
+
//#endregion
|
|
8
|
+
export { capacitorOrigins };
|
package/dist/project-config.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MobileConfig } from "./mobile-config.js";
|
|
1
2
|
import { AdminAuth } from "./better-auth/create-auth.js";
|
|
2
3
|
import { EventsOptions } from "./changes/events-options.js";
|
|
3
4
|
import { Authenticator } from "./types.js";
|
|
@@ -32,6 +33,8 @@ export type ProjectConfig = {
|
|
|
32
33
|
webhooks?: WebhooksOptions;
|
|
33
34
|
/** The module of the app's jobs, e.g. `import * as jobs from './config/jobs'`: every `defineJob` it exports. */
|
|
34
35
|
jobs?: Record<string, unknown>;
|
|
36
|
+
/** The app's iOS and Android build (see `MobileConfig`): `protobase mobile` needs it, and the API answers the app's origins. */
|
|
37
|
+
mobile?: MobileConfig;
|
|
35
38
|
options?: AdminOptions;
|
|
36
39
|
};
|
|
37
40
|
/** Typed identity, for `export default defineConfig({ extends: [...], config, auth, ... })` in `protobase.config.ts`. */
|
package/dist/project-config.js
CHANGED
|
@@ -143,13 +143,14 @@ const mergedOptions = (named) => {
|
|
|
143
143
|
*/
|
|
144
144
|
const mergeConfig = (...configs) => {
|
|
145
145
|
const named = configs.flatMap((config, index) => flatten(config, config.name ?? `config ${index + 1}`));
|
|
146
|
-
const { db, authenticate, auth, events, history, webhooks } = lastSet(named.map(({ config }) => ({
|
|
146
|
+
const { db, authenticate, auth, events, history, webhooks, mobile } = lastSet(named.map(({ config }) => ({
|
|
147
147
|
db: config.db,
|
|
148
148
|
authenticate: config.authenticate,
|
|
149
149
|
auth: config.auth,
|
|
150
150
|
events: config.events,
|
|
151
151
|
history: config.history,
|
|
152
|
-
webhooks: config.webhooks
|
|
152
|
+
webhooks: config.webhooks,
|
|
153
|
+
mobile: config.mobile
|
|
153
154
|
})));
|
|
154
155
|
const module = mergedModule(named);
|
|
155
156
|
const functions = mergedFunctions(named);
|
|
@@ -169,6 +170,7 @@ const mergeConfig = (...configs) => {
|
|
|
169
170
|
...history && { history },
|
|
170
171
|
...webhooks && { webhooks },
|
|
171
172
|
...jobs && { jobs },
|
|
173
|
+
...mobile && { mobile },
|
|
172
174
|
...options && { options }
|
|
173
175
|
};
|
|
174
176
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@protobase/server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"description": "The Protobase REST API as a Hono app, with Better Auth sign-in.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@better-auth/passkey": "^1.7.7",
|
|
34
34
|
"@better-auth/sso": "^1.7.7",
|
|
35
|
-
"@protobase/layout": "0.
|
|
36
|
-
"@protobase/query": "0.
|
|
37
|
-
"@protobase/schema": "0.
|
|
35
|
+
"@protobase/layout": "0.27.0",
|
|
36
|
+
"@protobase/query": "0.27.0",
|
|
37
|
+
"@protobase/schema": "0.27.0",
|
|
38
38
|
"@react-email/render": "^2.1.0",
|
|
39
39
|
"@scalar/hono-api-reference": "^0.12.10",
|
|
40
40
|
"@sentry/core": "^11.7.0",
|