@protobase/server 0.67.4 → 0.67.5
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/better-auth/create-auth.d.ts +13 -5
- package/dist/better-auth/create-auth.js +3 -3
- package/dist/better-auth/invitations/invitation-link-hook.js +9 -4
- package/dist/better-auth/organizations/options.d.ts +2 -2
- package/dist/better-auth/organizations/options.js +2 -3
- package/dist/better-auth/organizations/organization-plugin.js +4 -2
- package/dist/better-auth/users/user-endpoints.js +2 -1
- package/dist/mail/mailing-app.js +2 -1
- package/dist/package.js +1 -1
- package/dist/request-app-url.js +9 -0
- package/package.json +5 -4
|
@@ -590,7 +590,17 @@ export declare const createAuth: (options: CreateAuthOptions, plugins?: AuthPlug
|
|
|
590
590
|
userId: string;
|
|
591
591
|
expiresAt: Date;
|
|
592
592
|
token: string;
|
|
593
|
-
ipAddress
|
|
593
|
+
ipAddress?
|
|
594
|
+
/**
|
|
595
|
+
* What the sign-in page leads with: `password`, the email address and a password, with emailing a code below it; or
|
|
596
|
+
* `emailCode`, the address and "Email me a sign-in code", with the password behind "Use a password", for apps whose
|
|
597
|
+
* people mostly never set one. Only while the policy leaves both on; default `password`.
|
|
598
|
+
*/
|
|
599
|
+
/**
|
|
600
|
+
* What the sign-in page leads with: `password`, the email address and a password, with emailing a code below it; or
|
|
601
|
+
* `emailCode`, the address and "Email me a sign-in code", with the password behind "Use a password", for apps whose
|
|
602
|
+
* people mostly never set one. Only while the policy leaves both on; default `password`.
|
|
603
|
+
*/ : string | null | undefined;
|
|
594
604
|
userAgent?: string | null | undefined;
|
|
595
605
|
};
|
|
596
606
|
};
|
|
@@ -1666,7 +1676,7 @@ export declare const createAuth: (options: CreateAuthOptions, plugins?: AuthPlug
|
|
|
1666
1676
|
email: string;
|
|
1667
1677
|
emailVerified: boolean;
|
|
1668
1678
|
name: string;
|
|
1669
|
-
image
|
|
1679
|
+
image?: string | null | undefined;
|
|
1670
1680
|
};
|
|
1671
1681
|
};
|
|
1672
1682
|
}>>[];
|
|
@@ -2411,9 +2421,7 @@ export declare const createAuth: (options: CreateAuthOptions, plugins?: AuthPlug
|
|
|
2411
2421
|
email: string;
|
|
2412
2422
|
emailVerified: boolean;
|
|
2413
2423
|
name: string;
|
|
2414
|
-
image
|
|
2415
|
-
/** The RP ID of new passkeys, from `resolvePasskeyDomain`; default the host of `baseURL`. */
|
|
2416
|
-
/** The RP ID of new passkeys, from `resolvePasskeyDomain`; default the host of `baseURL`. */ : string | null | undefined;
|
|
2424
|
+
image?: string | null | undefined;
|
|
2417
2425
|
};
|
|
2418
2426
|
};
|
|
2419
2427
|
}>>[];
|
|
@@ -17,7 +17,7 @@ import { jsonOnlyOnMobile, mobileRequests } from "./mobile-requests.js";
|
|
|
17
17
|
import { passwordLength } from "./new-account-password.js";
|
|
18
18
|
import { platformMailer } from "../mail/platform-mailer.js";
|
|
19
19
|
import { readOperatorSettings, resolveOperator } from "./operator-provider.js";
|
|
20
|
-
import
|
|
20
|
+
import "./invitations/invitation-link-hook.js";
|
|
21
21
|
import { lastAdminGuardPlugin } from "./last-admin-guard.js";
|
|
22
22
|
import { setPasswordPath, setPasswordPlugin } from "./set-password.js";
|
|
23
23
|
import { emailCodeOptions, twoFactorCodeOptions, unusedEmailCodePaths } from "./sign-in-mail.js";
|
|
@@ -271,7 +271,7 @@ const betterAuthOptions = (options, { origins = [], passkeyDomain, roles, defini
|
|
|
271
271
|
definitions,
|
|
272
272
|
defaultPolicy: signInPolicy,
|
|
273
273
|
...mail && { mail },
|
|
274
|
-
invitationUrl: organizations
|
|
274
|
+
...organizations?.invitationUrl !== void 0 && { invitationUrl: organizations.invitationUrl },
|
|
275
275
|
invitationSeconds: organizations?.invitationExpiresIn ?? 604800,
|
|
276
276
|
...organizations && { organizations }
|
|
277
277
|
}),
|
|
@@ -410,7 +410,7 @@ const createAuth = (options, plugins = {}) => {
|
|
|
410
410
|
const personalMail = resolvePersonalMail(options.personalMail ?? [], socialProviders, options.encryptOAuthTokens === true);
|
|
411
411
|
const origins = resolveOrigins(options.baseURL, options.origins ?? platformOrigins());
|
|
412
412
|
const passkeyDomain = resolvePasskeyDomain(options.passkeyDomain ?? platformPasskeyDomain(), [options.baseURL, ...origins]);
|
|
413
|
-
const organizations = options.organizations && resolveOrganizations(options.organizations, definitions
|
|
413
|
+
const organizations = options.organizations && resolveOrganizations(options.organizations, definitions);
|
|
414
414
|
const mcp = options.mcp && resolveMcp(options.baseURL, options.mcp);
|
|
415
415
|
let instance;
|
|
416
416
|
const context = () => instance?.$context ?? Promise.reject(/* @__PURE__ */ new Error("The auth instance is not made yet"));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { requestAppUrl } from "../../request-app-url.js";
|
|
1
2
|
import { invitationLink, invitationToken } from "./invitation-token.js";
|
|
2
3
|
import { createAuthMiddleware } from "better-auth/api";
|
|
3
4
|
//#region src/better-auth/invitations/invitation-link-hook.ts
|
|
@@ -9,7 +10,7 @@ import { createAuthMiddleware } from "better-auth/api";
|
|
|
9
10
|
const invitationLinkHook = (paths, invitationUrl) => ({
|
|
10
11
|
matcher: (context) => paths.includes(context.path ?? ""),
|
|
11
12
|
handler: createAuthMiddleware(async (ctx) => {
|
|
12
|
-
const answer = await withInvitationLink(ctx.context.returned, ctx.context.secret, invitationUrl);
|
|
13
|
+
const answer = await withInvitationLink(ctx.context.returned, ctx.context.secret, invitationPage(invitationUrl, ctx.context.baseURL));
|
|
13
14
|
if (answer) ctx.context.returned = answer;
|
|
14
15
|
})
|
|
15
16
|
});
|
|
@@ -26,9 +27,13 @@ const withInvitationLink = async (returned, secret, invitationUrl) => {
|
|
|
26
27
|
link: invitationLink(invitationUrl, token)
|
|
27
28
|
};
|
|
28
29
|
};
|
|
29
|
-
/**
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* The page an invitation link opens, with `?token=`: the app's own `invitationUrl`, or `/-/invitation` on the origin
|
|
32
|
+
* the request came to, from Better Auth's `ctx.context.baseURL` (`requestAppUrl`), so a link made on one of the app's
|
|
33
|
+
* origins opens there.
|
|
34
|
+
*/
|
|
35
|
+
const invitationPage = (invitationUrl, requestURL) => invitationUrl ?? requestAppUrl(requestURL, "/-/invitation");
|
|
31
36
|
/** How long an invitation works unless the app says otherwise: 7 days, in seconds. */
|
|
32
37
|
const defaultInvitationSeconds = 604800;
|
|
33
38
|
//#endregion
|
|
34
|
-
export { defaultInvitationSeconds,
|
|
39
|
+
export { defaultInvitationSeconds, invitationLinkHook, invitationPage, withInvitationLink };
|
|
@@ -22,7 +22,7 @@ export type OrganizationsOptions = {
|
|
|
22
22
|
* rows in any `.tenant` resource; `'cascade'` leaves it to the project's foreign keys.
|
|
23
23
|
*/
|
|
24
24
|
deleteRecords?: 'refuse' | 'cascade';
|
|
25
|
-
/** The page an invitation link opens, with `?token=`. Default `
|
|
25
|
+
/** The page an invitation link opens, with `?token=`. Default `/-/invitation` on the origin the request came to. */
|
|
26
26
|
invitationUrl?: string;
|
|
27
27
|
/** Runs after an organization is created, with its owner's membership, for example to add the app's own row for it. */
|
|
28
28
|
onCreated?: (input: {
|
|
@@ -42,7 +42,7 @@ export type ResolvedOrganizations = {
|
|
|
42
42
|
membershipLimit: number;
|
|
43
43
|
generateId: () => string | Promise<string>;
|
|
44
44
|
deleteRecords: 'refuse' | 'cascade';
|
|
45
|
-
invitationUrl
|
|
45
|
+
invitationUrl?: string;
|
|
46
46
|
options: OrganizationsOptions;
|
|
47
47
|
};
|
|
48
48
|
//#endregion
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { membershipRoles } from "./role-definitions.js";
|
|
2
|
-
import { defaultInvitationUrl } from "../invitations/invitation-link-hook.js";
|
|
3
2
|
//#region src/better-auth/organizations/options.ts
|
|
4
|
-
const resolveOrganizations = (options, definitions
|
|
3
|
+
const resolveOrganizations = (options, definitions) => {
|
|
5
4
|
const holdable = membershipRoles(definitions);
|
|
6
5
|
const creatorAppRoles = options.creatorAppRoles === void 0 || options.creatorAppRoles === "all" ? holdable : options.creatorAppRoles;
|
|
7
6
|
const unknown = creatorAppRoles.find((name) => !holdable.includes(name));
|
|
@@ -16,7 +15,7 @@ const resolveOrganizations = (options, definitions, baseURL) => {
|
|
|
16
15
|
membershipLimit: options.membershipLimit ?? 1e3,
|
|
17
16
|
generateId: options.generateId ?? (() => crypto.randomUUID()),
|
|
18
17
|
deleteRecords: options.deleteRecords ?? "refuse",
|
|
19
|
-
invitationUrl: options.invitationUrl
|
|
18
|
+
...options.invitationUrl !== void 0 && { invitationUrl: options.invitationUrl },
|
|
20
19
|
options
|
|
21
20
|
};
|
|
22
21
|
};
|
|
@@ -2,8 +2,10 @@ import "./role-definitions.js";
|
|
|
2
2
|
import { checkAppRoleChange, effectiveRoles, globalRoles, parseAppRoles } from "./app-roles.js";
|
|
3
3
|
import { findMember } from "./store.js";
|
|
4
4
|
import { invitationLink, invitationToken } from "../invitations/invitation-token.js";
|
|
5
|
+
import { invitationPage } from "../invitations/invitation-link-hook.js";
|
|
5
6
|
import { sendAuthEmail } from "../auth-mail/send-auth-email.js";
|
|
6
7
|
import { APIError } from "better-auth/api";
|
|
8
|
+
import { getCurrentAuthEndpointContext } from "@better-auth/core/context";
|
|
7
9
|
import { organization } from "better-auth/plugins/organization";
|
|
8
10
|
//#region src/better-auth/organizations/organization-plugin.ts
|
|
9
11
|
/** The snake_case names of the organization plugin's tables and columns, with the app roles of members and invitations. */
|
|
@@ -112,8 +114,8 @@ const organizationPlugin = ({ resolved, secret, mail, context }) => {
|
|
|
112
114
|
cancelPendingInvitationsOnReInvite: true,
|
|
113
115
|
schema: organizationNames,
|
|
114
116
|
...mail && { sendInvitationEmail: async ({ invitation, organization, inviter }) => {
|
|
115
|
-
const
|
|
116
|
-
const url = invitationLink(
|
|
117
|
+
const page = invitationPage(resolved.invitationUrl, getCurrentAuthEndpointContext().context.baseURL);
|
|
118
|
+
const url = invitationLink(page, await invitationToken(secret, invitation));
|
|
117
119
|
await sendAuthEmail(mail, "invitationEmail", invitation.email, {
|
|
118
120
|
inviter: inviter.user.name || inviter.user.email,
|
|
119
121
|
organization: organization.name,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { adminOnly } from "../admin-only.js";
|
|
2
2
|
import { invitationLink, invitationToken } from "../invitations/invitation-token.js";
|
|
3
|
+
import { invitationPage } from "../invitations/invitation-link-hook.js";
|
|
3
4
|
import { sendAuthEmail } from "../auth-mail/send-auth-email.js";
|
|
4
5
|
import { createAppInvitation, deleteAppInvitation, listAppInvitations } from "./app-invitation-store.js";
|
|
5
6
|
import { roleLabels } from "../roles/role-labels.js";
|
|
@@ -46,7 +47,7 @@ const userEndpoints = ({ definitions, mail, invitationUrl, invitationSeconds })
|
|
|
46
47
|
inviterId: inviter.id
|
|
47
48
|
}, invitationSeconds);
|
|
48
49
|
if (mail) {
|
|
49
|
-
const url = invitationLink(invitationUrl, await invitationToken(ctx.context.secret, invitation));
|
|
50
|
+
const url = invitationLink(invitationPage(invitationUrl, ctx.context.baseURL), await invitationToken(ctx.context.secret, invitation));
|
|
50
51
|
await sendAuthEmail(mail, "invitationEmail", invitation.email, {
|
|
51
52
|
inviter: inviter.name || inviter.email,
|
|
52
53
|
url,
|
package/dist/mail/mailing-app.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { requestAppUrl } from "../request-app-url.js";
|
|
1
2
|
//#region src/mail/mailing-app.ts
|
|
2
3
|
/**
|
|
3
4
|
* The app as an auth email names it: `appName`, and the home page on the origin of `requestURL`, a URL on the origin
|
|
@@ -5,7 +6,7 @@
|
|
|
5
6
|
*/
|
|
6
7
|
const mailingApp = ({ appName, baseURL }, requestURL) => ({
|
|
7
8
|
name: appName,
|
|
8
|
-
url:
|
|
9
|
+
url: requestAppUrl(requestURL ?? baseURL, "/")
|
|
9
10
|
});
|
|
10
11
|
//#endregion
|
|
11
12
|
export { mailingApp };
|
package/dist/package.js
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/request-app-url.ts
|
|
2
|
+
/**
|
|
3
|
+
* The app's page at `path`, which starts with `/`, on the origin of `requestURL`: a URL Better Auth resolved for the
|
|
4
|
+
* request (`ctx.context.baseURL`), on the request's host when that is one of the app's origins and on `baseURL`'s
|
|
5
|
+
* otherwise. Only its origin counts, so Better Auth's base path, such as `/api/auth`, never reaches the page.
|
|
6
|
+
*/
|
|
7
|
+
const requestAppUrl = (requestURL, path) => new URL(path, requestURL).href;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { requestAppUrl };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@protobase/server",
|
|
3
|
-
"version": "0.67.
|
|
3
|
+
"version": "0.67.5",
|
|
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": {
|
|
@@ -37,15 +37,16 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@better-auth/cimd": "^1.7.12",
|
|
40
|
+
"@better-auth/core": "^1.7.12",
|
|
40
41
|
"@better-auth/mcp": "^1.7.12",
|
|
41
42
|
"@better-auth/oauth-provider": "^1.7.12",
|
|
42
43
|
"@better-auth/passkey": "^1.7.12",
|
|
43
44
|
"@better-auth/sso": "^1.7.12",
|
|
44
45
|
"@livekit/protocol": "1.53.1",
|
|
45
46
|
"@modelcontextprotocol/server": "^2.3.1",
|
|
46
|
-
"@protobase/layout": "0.67.
|
|
47
|
-
"@protobase/query": "0.67.
|
|
48
|
-
"@protobase/schema": "0.67.
|
|
47
|
+
"@protobase/layout": "0.67.5",
|
|
48
|
+
"@protobase/query": "0.67.5",
|
|
49
|
+
"@protobase/schema": "0.67.5",
|
|
49
50
|
"@react-email/render": "^2.1.0",
|
|
50
51
|
"@react-pdf/primitives": "^4.4.0",
|
|
51
52
|
"@react-pdf/renderer": "^4.9.0",
|