@softr/sdk 0.0.63 → 0.0.64-alpha.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/auth/isomorphic.d.ts +60 -1
- package/dist/auth/isomorphic.js +63 -5
- package/dist/auth/methods/passwordLink.d.ts +47 -0
- package/dist/auth/methods/passwordLink.js +86 -0
- package/dist/auth/methods/settings.d.ts +11 -0
- package/dist/auth/methods/settings.js +17 -0
- package/dist/auth/methods/signup.js +1 -0
- package/dist/auth/methods/social.js +1 -0
- package/dist/auth/methods/utils.d.ts +1 -1
- package/dist/auth/platform.d.ts +46 -0
- package/dist/auth/platform.js +54 -0
- package/dist/auth/server.d.ts +6 -0
- package/dist/auth/server.js +7 -1
- package/dist/default-error-overlay.d.ts +2 -2
- package/dist/index.d.ts +4 -3
- package/dist/index.js +3 -3
- package/dist/mcp.d.ts +2 -8
- package/dist/mcp.js +8 -8
- package/dist/package.js +1 -1
- package/dist/pwa.d.ts +2 -2
- package/dist/softr-config.d.ts +1 -0
- package/dist/softr-config.js +26 -5
- package/dist/visibility/route.d.ts +26 -6
- package/dist/visibility/route.js +36 -13
- package/package.json +33 -10
- package/schema/softr.schema.json +42 -1
- package/skills/softr-sdk/SKILL.md +4 -3
- package/skills/softr-sdk/auth/SKILL.md +129 -31
- package/skills/softr-sdk/charts-and-metrics/SKILL.md +1 -1
- package/skills/softr-sdk/current-user/SKILL.md +1 -1
- package/skills/softr-sdk/file-uploads/SKILL.md +1 -1
- package/skills/softr-sdk/formatting/SKILL.md +4 -4
- package/skills/softr-sdk/integrations/SKILL.md +1 -1
- package/skills/softr-sdk/mcp/SKILL.md +7 -14
- package/skills/softr-sdk/pwa/SKILL.md +3 -3
- package/skills/softr-sdk/record-mutations/SKILL.md +1 -1
- package/skills/softr-sdk/record-queries/SKILL.md +1 -1
- package/skills/softr-sdk/region-visibility/SKILL.md +1 -1
- package/skills/softr-sdk/routes-and-visibility/SKILL.md +24 -12
- package/skills/softr-sdk/workflows/SKILL.md +1 -1
|
@@ -2,6 +2,8 @@ import { User } from "./user.js";
|
|
|
2
2
|
import { Formatting } from "../formatting.js";
|
|
3
3
|
import { Permissions } from "./permissions.js";
|
|
4
4
|
import { SoftrContext } from "./context.js";
|
|
5
|
+
import * as react0 from "react";
|
|
6
|
+
import { ReactNode } from "react";
|
|
5
7
|
import * as _tanstack_react_start0 from "@tanstack/react-start";
|
|
6
8
|
|
|
7
9
|
//#region src/auth/isomorphic.d.ts
|
|
@@ -54,5 +56,62 @@ declare function initialSoftrContext(): SoftrContext;
|
|
|
54
56
|
* }
|
|
55
57
|
*/
|
|
56
58
|
declare function useCurrentUser(): User | null;
|
|
59
|
+
/** Which ways in this app offers, each named for the `auth` call it unlocks. */
|
|
60
|
+
type AuthOptions = {
|
|
61
|
+
/** `auth.signIn` */
|
|
62
|
+
password: boolean;
|
|
63
|
+
/** `auth.sendSignInCode`, then `auth.signInWithCode` */
|
|
64
|
+
emailCode: boolean;
|
|
65
|
+
/** `auth.signInWithMagicLink` */
|
|
66
|
+
magicLink: boolean;
|
|
67
|
+
/** `auth.signInWithGoogle`, with the client id to start Google sign-in with. */
|
|
68
|
+
google: {
|
|
69
|
+
clientId: string;
|
|
70
|
+
} | null;
|
|
71
|
+
/** `auth.signUp`, then `auth.confirmSignUp` */
|
|
72
|
+
signUp: boolean;
|
|
73
|
+
/** The builder asked for strong passwords whenever a visitor sets one. */
|
|
74
|
+
strongPasswords: boolean;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Loads the app's {@link AuthOptions}. Call it from the auth layout's loader
|
|
78
|
+
* and hand the result to {@link AuthSettingsProvider}.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* export const Route = createFileRoute("/_auth")({
|
|
82
|
+
* loader: () => getAuthSettings(),
|
|
83
|
+
* staleTime: 60_000,
|
|
84
|
+
* })
|
|
85
|
+
*/
|
|
86
|
+
declare const getAuthSettings: _tanstack_react_start0.OptionalFetcher<undefined, undefined, Promise<AuthOptions>>;
|
|
87
|
+
/**
|
|
88
|
+
* Makes the auth options readable with {@link useAuthSettings} anywhere below.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* function AuthLayout() {
|
|
92
|
+
* const authSettings = Route.useLoaderData()
|
|
93
|
+
* return (
|
|
94
|
+
* <AuthSettingsProvider value={authSettings}>
|
|
95
|
+
* <Outlet />
|
|
96
|
+
* </AuthSettingsProvider>
|
|
97
|
+
* )
|
|
98
|
+
* }
|
|
99
|
+
*/
|
|
100
|
+
declare function AuthSettingsProvider({
|
|
101
|
+
value,
|
|
102
|
+
children
|
|
103
|
+
}: {
|
|
104
|
+
value: AuthOptions;
|
|
105
|
+
children?: ReactNode;
|
|
106
|
+
}): react0.JSX.Element;
|
|
107
|
+
/**
|
|
108
|
+
* Which ways in this app offers. Requires an {@link AuthSettingsProvider}
|
|
109
|
+
* above it.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* const options = useAuthSettings()
|
|
113
|
+
* return options.password && <PasswordForm />
|
|
114
|
+
*/
|
|
115
|
+
declare function useAuthSettings(): AuthOptions;
|
|
57
116
|
//#endregion
|
|
58
|
-
export { getSoftrContext, initialSoftrContext, softrAuthMiddleware, useCurrentUser };
|
|
117
|
+
export { AuthOptions, AuthSettingsProvider, getAuthSettings, getSoftrContext, initialSoftrContext, softrAuthMiddleware, useAuthSettings, useCurrentUser };
|
package/dist/auth/isomorphic.js
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import { assert, panic } from "../assertions.js";
|
|
1
|
+
import { assert, panic, requireDefined } from "../assertions.js";
|
|
2
2
|
import { readUserTimezone, writeCookies } from "../cookies.js";
|
|
3
3
|
import { sessionConfig } from "./config.js";
|
|
4
4
|
import { clearSession, makeSessionDataCookie, readSessionData, readSessionToken } from "./session.js";
|
|
5
5
|
import { makePlatform } from "./platform.js";
|
|
6
6
|
import { defaultFormatting, resolveFormatting } from "../formatting.js";
|
|
7
7
|
import { readLocaleSettings } from "../locale-settings.js";
|
|
8
|
+
import { settings } from "./methods/settings.js";
|
|
8
9
|
import { bootErrorMiddleware } from "../boot-error.js";
|
|
9
10
|
import { pwaMiddleware } from "../pwa.js";
|
|
11
|
+
import { createContext, useContext } from "react";
|
|
10
12
|
import { createMiddleware, createServerFn, getGlobalStartContext } from "@tanstack/react-start";
|
|
11
13
|
import { getRequestHeader } from "@tanstack/react-start/server";
|
|
12
14
|
import { rootRouteId, useRouteContext } from "@tanstack/react-router";
|
|
15
|
+
import { jsx } from "react/jsx-runtime";
|
|
13
16
|
|
|
14
|
-
//#region src/auth/isomorphic.
|
|
17
|
+
//#region src/auth/isomorphic.tsx
|
|
15
18
|
/**
|
|
16
19
|
* Resolves the Softr visitor, their permissions and the app's formatting for
|
|
17
20
|
* every request, so that `getSoftrContext` and the route guards have something
|
|
@@ -41,11 +44,11 @@ function softrAuthMiddleware() {
|
|
|
41
44
|
writeCookies([makeSessionDataCookie(session, token)]);
|
|
42
45
|
return session;
|
|
43
46
|
}
|
|
44
|
-
const [{ user, permissions }, settings] = await Promise.all([getSession(), readLocaleSettings()]);
|
|
47
|
+
const [{ user, permissions }, settings$1] = await Promise.all([getSession(), readLocaleSettings()]);
|
|
45
48
|
return next({ context: {
|
|
46
49
|
user,
|
|
47
50
|
permissions,
|
|
48
|
-
formatting: resolveFormatting(settings, getRequestHeader("accept-language") ?? null, readUserTimezone())
|
|
51
|
+
formatting: resolveFormatting(settings$1, getRequestHeader("accept-language") ?? null, readUserTimezone())
|
|
49
52
|
} });
|
|
50
53
|
});
|
|
51
54
|
}
|
|
@@ -94,6 +97,61 @@ function useCurrentUser() {
|
|
|
94
97
|
select: (context) => context.user
|
|
95
98
|
});
|
|
96
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Loads the app's {@link AuthOptions}. Call it from the auth layout's loader
|
|
102
|
+
* and hand the result to {@link AuthSettingsProvider}.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* export const Route = createFileRoute("/_auth")({
|
|
106
|
+
* loader: () => getAuthSettings(),
|
|
107
|
+
* staleTime: 60_000,
|
|
108
|
+
* })
|
|
109
|
+
*/
|
|
110
|
+
const getAuthSettings = createServerFn({ method: "GET" }).handler(async () => {
|
|
111
|
+
const raw = await settings();
|
|
112
|
+
const on = (method) => raw.loginEnabled && raw.authenticationMethods.includes(method);
|
|
113
|
+
const emailMethods = on("EMAIL") ? raw.emailAuth?.loginMethods ?? [] : [];
|
|
114
|
+
const clientId = raw.googleAuth?.clientId?.trim();
|
|
115
|
+
return {
|
|
116
|
+
password: emailMethods.includes("PASSWORD"),
|
|
117
|
+
emailCode: emailMethods.includes("EMAIL_CODE"),
|
|
118
|
+
magicLink: on("MAGIC_LINK"),
|
|
119
|
+
google: on("GOOGLE") && clientId ? { clientId } : null,
|
|
120
|
+
signUp: raw.loginEnabled && (raw.signUpPolicy === "OPEN_TO_PUBLIC" || raw.signUpPolicy === "DOMAIN_RESTRICTED"),
|
|
121
|
+
strongPasswords: on("EMAIL") && (raw.emailAuth?.strongPasswords ?? false)
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
const AuthSettingsContext = createContext(null);
|
|
125
|
+
/**
|
|
126
|
+
* Makes the auth options readable with {@link useAuthSettings} anywhere below.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* function AuthLayout() {
|
|
130
|
+
* const authSettings = Route.useLoaderData()
|
|
131
|
+
* return (
|
|
132
|
+
* <AuthSettingsProvider value={authSettings}>
|
|
133
|
+
* <Outlet />
|
|
134
|
+
* </AuthSettingsProvider>
|
|
135
|
+
* )
|
|
136
|
+
* }
|
|
137
|
+
*/
|
|
138
|
+
function AuthSettingsProvider({ value, children }) {
|
|
139
|
+
return /* @__PURE__ */ jsx(AuthSettingsContext.Provider, {
|
|
140
|
+
value,
|
|
141
|
+
children
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Which ways in this app offers. Requires an {@link AuthSettingsProvider}
|
|
146
|
+
* above it.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* const options = useAuthSettings()
|
|
150
|
+
* return options.password && <PasswordForm />
|
|
151
|
+
*/
|
|
152
|
+
function useAuthSettings() {
|
|
153
|
+
return requireDefined(useContext(AuthSettingsContext), "useAuthSettings needs an AuthSettingsProvider above it.");
|
|
154
|
+
}
|
|
97
155
|
|
|
98
156
|
//#endregion
|
|
99
|
-
export { getSoftrContext, initialSoftrContext, softrAuthMiddleware, useCurrentUser };
|
|
157
|
+
export { AuthSettingsProvider, getAuthSettings, getSoftrContext, initialSoftrContext, softrAuthMiddleware, useAuthSettings, useCurrentUser };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { User } from "../user.js";
|
|
2
|
+
import { AuthError, Result } from "./utils.js";
|
|
3
|
+
|
|
4
|
+
//#region src/auth/methods/passwordLink.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Emails a link to set a new password.
|
|
8
|
+
*
|
|
9
|
+
* Succeeds whether or not the address has an account, and sends nothing when
|
|
10
|
+
* it has none.
|
|
11
|
+
*/
|
|
12
|
+
declare function requestPasswordReset(details: {
|
|
13
|
+
email: string;
|
|
14
|
+
}): Promise<Result<null, AuthError>>;
|
|
15
|
+
/**
|
|
16
|
+
* Checks a password reset or invitation link, and returns the address it was
|
|
17
|
+
* mailed to. The link stays usable.
|
|
18
|
+
*/
|
|
19
|
+
declare function checkPasswordLink(details: {
|
|
20
|
+
token: string;
|
|
21
|
+
}): Promise<Result<{
|
|
22
|
+
email: string;
|
|
23
|
+
}, AuthError>>;
|
|
24
|
+
/**
|
|
25
|
+
* Sets a new password with a password reset or invitation link, and signs the
|
|
26
|
+
* visitor in.
|
|
27
|
+
*
|
|
28
|
+
* Any success uses up the link, `authenticatorRequired` included, and ends
|
|
29
|
+
* the visitor's other sessions.
|
|
30
|
+
*/
|
|
31
|
+
declare function setPasswordWithLink(details: {
|
|
32
|
+
token: string;
|
|
33
|
+
password: string;
|
|
34
|
+
}): Promise<Result<{
|
|
35
|
+
status: "signedIn";
|
|
36
|
+
user: User;
|
|
37
|
+
} | {
|
|
38
|
+
status: "authenticatorRequired";
|
|
39
|
+
/**
|
|
40
|
+
* `verify`: they have an authenticator app and owe a code.
|
|
41
|
+
* `setup`: the app requires one and they have none yet.
|
|
42
|
+
* `setupOptional`: same, except they may skip it instead.
|
|
43
|
+
*/
|
|
44
|
+
step: "verify" | "setup" | "setupOptional";
|
|
45
|
+
}, AuthError>>;
|
|
46
|
+
//#endregion
|
|
47
|
+
export { checkPasswordLink, requestPasswordReset, setPasswordWithLink };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { assert, panic } from "../../assertions.js";
|
|
2
|
+
import { writeCookies } from "../../cookies.js";
|
|
3
|
+
import { sessionConfig } from "../config.js";
|
|
4
|
+
import { clearPendingAuth, makePendingAuthCookie, makeSessionDataCookie, makeSessionTokenCookie } from "../session.js";
|
|
5
|
+
import { makePlatform } from "../platform.js";
|
|
6
|
+
import { authError } from "./utils.js";
|
|
7
|
+
|
|
8
|
+
//#region src/auth/methods/passwordLink.ts
|
|
9
|
+
/**
|
|
10
|
+
* Emails a link to set a new password.
|
|
11
|
+
*
|
|
12
|
+
* Succeeds whether or not the address has an account, and sends nothing when
|
|
13
|
+
* it has none.
|
|
14
|
+
*/
|
|
15
|
+
async function requestPasswordReset(details) {
|
|
16
|
+
const result = await makePlatform(sessionConfig().applicationId).forgotPassword(details);
|
|
17
|
+
if (!result.ok) {
|
|
18
|
+
if (result.status === 429) return authError("tooManyAttempts", result.message);
|
|
19
|
+
panic(`Expected the password reset link to be emailed, but got ${result.status}: ${result.message}.`);
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
success: true,
|
|
23
|
+
data: null
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Checks a password reset or invitation link, and returns the address it was
|
|
28
|
+
* mailed to. The link stays usable.
|
|
29
|
+
*/
|
|
30
|
+
async function checkPasswordLink(details) {
|
|
31
|
+
const result = await makePlatform(sessionConfig().applicationId).checkPasswordToken(details);
|
|
32
|
+
if (!result.ok) {
|
|
33
|
+
if (result.status === 429) return authError("tooManyAttempts", result.message);
|
|
34
|
+
if (result.status === 400 || result.status === 401) return authError("linkExpired", result.message);
|
|
35
|
+
panic(`Expected the link to be checked, but got ${result.status}: ${result.message}.`);
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
success: true,
|
|
39
|
+
data: result.data
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Sets a new password with a password reset or invitation link, and signs the
|
|
44
|
+
* visitor in.
|
|
45
|
+
*
|
|
46
|
+
* Any success uses up the link, `authenticatorRequired` included, and ends
|
|
47
|
+
* the visitor's other sessions.
|
|
48
|
+
*/
|
|
49
|
+
async function setPasswordWithLink(details) {
|
|
50
|
+
const result = await makePlatform(sessionConfig().applicationId).setPassword(details);
|
|
51
|
+
if (!result.ok) {
|
|
52
|
+
if (result.status === 429) return authError("tooManyAttempts", result.message);
|
|
53
|
+
if (result.status === 400 && result.message === "Password must be at least 8 characters long.") return authError("invalidDetails", result.message);
|
|
54
|
+
if (result.status === 400 || result.status === 401) return authError("linkExpired", result.message);
|
|
55
|
+
panic(`Expected the password to be set, but got ${result.status}: ${result.message}.`);
|
|
56
|
+
}
|
|
57
|
+
if (result.data.status === "MFA_REQUIRED") {
|
|
58
|
+
const { mfa } = result.data;
|
|
59
|
+
assert(mfa, "Expected a challenge from setting a password, but got none");
|
|
60
|
+
writeCookies([makePendingAuthCookie(mfa.challengeToken)]);
|
|
61
|
+
return {
|
|
62
|
+
success: true,
|
|
63
|
+
data: {
|
|
64
|
+
status: "authenticatorRequired",
|
|
65
|
+
step: mfa.action === "VERIFICATION_REQUIRED" ? "verify" : mfa.action === "SETUP_REQUIRED" ? "setup" : "setupOptional"
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const { session } = result.data;
|
|
70
|
+
assert(session, "Expected a session from setting a password, but got none");
|
|
71
|
+
writeCookies([makeSessionTokenCookie(session.jwt), makeSessionDataCookie({
|
|
72
|
+
user: session.user,
|
|
73
|
+
permissions: session.permissions
|
|
74
|
+
}, session.jwt)]);
|
|
75
|
+
clearPendingAuth();
|
|
76
|
+
return {
|
|
77
|
+
success: true,
|
|
78
|
+
data: {
|
|
79
|
+
status: "signedIn",
|
|
80
|
+
user: session.user
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
//#endregion
|
|
86
|
+
export { checkPasswordLink, requestPasswordReset, setPasswordWithLink };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AuthSettings } from "../platform.js";
|
|
2
|
+
|
|
3
|
+
//#region src/auth/methods/settings.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* How visitors may sign in and sign up to this app, as configured in Studio.
|
|
7
|
+
* A login or sign-up page renders only the methods it lists.
|
|
8
|
+
*/
|
|
9
|
+
declare function settings(): Promise<AuthSettings>;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { settings };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { panic } from "../../assertions.js";
|
|
2
|
+
import { sessionConfig } from "../config.js";
|
|
3
|
+
import { makePlatform } from "../platform.js";
|
|
4
|
+
|
|
5
|
+
//#region src/auth/methods/settings.ts
|
|
6
|
+
/**
|
|
7
|
+
* How visitors may sign in and sign up to this app, as configured in Studio.
|
|
8
|
+
* A login or sign-up page renders only the methods it lists.
|
|
9
|
+
*/
|
|
10
|
+
async function settings() {
|
|
11
|
+
const result = await makePlatform(sessionConfig().applicationId).authSettings();
|
|
12
|
+
if (!result.ok) panic(`Expected the auth settings, but got ${result.status}: ${result.message}`);
|
|
13
|
+
return result.data;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
export { settings };
|
|
@@ -17,6 +17,7 @@ async function signUp(details) {
|
|
|
17
17
|
if (result.status === 409) return authError("emailTaken", result.message);
|
|
18
18
|
if (result.status === 429) return authError("tooManyAttempts", result.message);
|
|
19
19
|
if (result.status === 400) return authError("invalidDetails", result.message);
|
|
20
|
+
if (result.status === 401 && result.message === "Email domain not allowed") return authError("emailDomainNotAllowed", result.message);
|
|
20
21
|
if (result.status >= 500) panic(`Expected the sign-up code to be emailed, but got ${result.status}: ` + result.message);
|
|
21
22
|
throw new Error(`${result.message}. Check SOFTR_APPLICATION_ID and that the app allows sign-up.`);
|
|
22
23
|
}
|
|
@@ -22,6 +22,7 @@ async function signInWithGoogle(credentials) {
|
|
|
22
22
|
const result = await makePlatform(sessionConfig().applicationId).signInWithGoogle(credentials);
|
|
23
23
|
if (!result.ok) {
|
|
24
24
|
if (result.status === 429) return authError("tooManyAttempts", result.message);
|
|
25
|
+
if (result.status === 400 && result.message.startsWith("Emails with ") && result.message.endsWith(" domain is not allowed to signup.")) return authError("emailDomainNotAllowed", result.message);
|
|
25
26
|
if (result.status === 400 || result.status === 401) return authError("invalidCredentials", result.message);
|
|
26
27
|
if (result.status >= 500) panic(`Expected Google sign-in to succeed, but got ${result.status}: ` + result.message);
|
|
27
28
|
throw new Error(`${result.message}. Check SOFTR_APPLICATION_ID and that the app allows Google sign-in.`);
|
|
@@ -10,6 +10,6 @@ type AuthError = {
|
|
|
10
10
|
code: AuthErrorCode;
|
|
11
11
|
message: string;
|
|
12
12
|
};
|
|
13
|
-
type AuthErrorCode = "invalidCredentials" | "tooManyAttempts" | "emailTaken" | "invalidDetails" | "invalidCode" | "notAuthenticated";
|
|
13
|
+
type AuthErrorCode = "invalidCredentials" | "tooManyAttempts" | "emailTaken" | "invalidDetails" | "invalidCode" | "notAuthenticated" | "emailDomainNotAllowed" | "linkExpired";
|
|
14
14
|
//#endregion
|
|
15
15
|
export { AuthError, Result };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import "./user.js";
|
|
2
|
+
import "./context.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/auth/platform.d.ts
|
|
6
|
+
|
|
7
|
+
declare const authSettingsSchema: z.ZodObject<{
|
|
8
|
+
loginEnabled: z.ZodBoolean;
|
|
9
|
+
authenticationMethods: z.ZodArray<z.ZodEnum<{
|
|
10
|
+
EMAIL: "EMAIL";
|
|
11
|
+
SSO: "SSO";
|
|
12
|
+
GOOGLE: "GOOGLE";
|
|
13
|
+
MAGIC_LINK: "MAGIC_LINK";
|
|
14
|
+
}>>;
|
|
15
|
+
signUpPolicy: z.ZodNullable<z.ZodEnum<{
|
|
16
|
+
DISABLED: "DISABLED";
|
|
17
|
+
OPEN_TO_PUBLIC: "OPEN_TO_PUBLIC";
|
|
18
|
+
DOMAIN_RESTRICTED: "DOMAIN_RESTRICTED";
|
|
19
|
+
}>>;
|
|
20
|
+
sessionExpirationDays: z.ZodNullable<z.ZodNumber>;
|
|
21
|
+
inactivityTimeoutMinutes: z.ZodNullable<z.ZodNumber>;
|
|
22
|
+
emailAuth: z.ZodNullable<z.ZodObject<{
|
|
23
|
+
loginMethods: z.ZodArray<z.ZodEnum<{
|
|
24
|
+
PASSWORD: "PASSWORD";
|
|
25
|
+
EMAIL_CODE: "EMAIL_CODE";
|
|
26
|
+
}>>;
|
|
27
|
+
strongPasswords: z.ZodBoolean;
|
|
28
|
+
emailCodeExpirationMinutes: z.ZodNullable<z.ZodNumber>;
|
|
29
|
+
}, z.core.$strip>>;
|
|
30
|
+
googleAuth: z.ZodNullable<z.ZodObject<{
|
|
31
|
+
clientId: z.ZodNullable<z.ZodString>;
|
|
32
|
+
userType: z.ZodNullable<z.ZodEnum<{
|
|
33
|
+
INTERNAL: "INTERNAL";
|
|
34
|
+
EXTERNAL: "EXTERNAL";
|
|
35
|
+
}>>;
|
|
36
|
+
}, z.core.$strip>>;
|
|
37
|
+
sso: z.ZodNullable<z.ZodObject<{
|
|
38
|
+
type: z.ZodNullable<z.ZodEnum<{
|
|
39
|
+
SAML: "SAML";
|
|
40
|
+
OPEN_ID: "OPEN_ID";
|
|
41
|
+
}>>;
|
|
42
|
+
}, z.core.$strip>>;
|
|
43
|
+
}, z.core.$strip>;
|
|
44
|
+
type AuthSettings = z.infer<typeof authSettingsSchema>;
|
|
45
|
+
//#endregion
|
|
46
|
+
export { AuthSettings };
|
package/dist/auth/platform.js
CHANGED
|
@@ -6,8 +6,35 @@ import { userSchema } from "./user.js";
|
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
|
|
8
8
|
//#region src/auth/platform.ts
|
|
9
|
+
const authSettingsSchema = z.object({
|
|
10
|
+
loginEnabled: z.boolean(),
|
|
11
|
+
authenticationMethods: z.array(z.enum([
|
|
12
|
+
"EMAIL",
|
|
13
|
+
"SSO",
|
|
14
|
+
"GOOGLE",
|
|
15
|
+
"MAGIC_LINK"
|
|
16
|
+
])),
|
|
17
|
+
signUpPolicy: z.enum([
|
|
18
|
+
"DISABLED",
|
|
19
|
+
"OPEN_TO_PUBLIC",
|
|
20
|
+
"DOMAIN_RESTRICTED"
|
|
21
|
+
]).nullable(),
|
|
22
|
+
sessionExpirationDays: z.number().nullable(),
|
|
23
|
+
inactivityTimeoutMinutes: z.number().nullable(),
|
|
24
|
+
emailAuth: z.object({
|
|
25
|
+
loginMethods: z.array(z.enum(["PASSWORD", "EMAIL_CODE"])),
|
|
26
|
+
strongPasswords: z.boolean(),
|
|
27
|
+
emailCodeExpirationMinutes: z.number().nullable()
|
|
28
|
+
}).nullable(),
|
|
29
|
+
googleAuth: z.object({
|
|
30
|
+
clientId: z.string().nullable(),
|
|
31
|
+
userType: z.enum(["INTERNAL", "EXTERNAL"]).nullable()
|
|
32
|
+
}).nullable(),
|
|
33
|
+
sso: z.object({ type: z.enum(["SAML", "OPEN_ID"]).nullable() }).nullable()
|
|
34
|
+
});
|
|
9
35
|
function makePlatform(applicationId) {
|
|
10
36
|
return {
|
|
37
|
+
authSettings: () => request(`/v1/vibe/applications/${applicationId}/users/auth-settings`, { method: "GET" }, authSettingsSchema),
|
|
11
38
|
session: async (token) => {
|
|
12
39
|
const result = await request(`/v1/vibe/applications/${applicationId}/users/session`, {
|
|
13
40
|
method: "GET",
|
|
@@ -99,6 +126,33 @@ function makePlatform(applicationId) {
|
|
|
99
126
|
challengeToken: z.string()
|
|
100
127
|
}).nullish()
|
|
101
128
|
})),
|
|
129
|
+
forgotPassword: (body) => request(`/v1/vibe/applications/${applicationId}/users/forgot-password`, {
|
|
130
|
+
method: "POST",
|
|
131
|
+
json: body
|
|
132
|
+
}, z.null()),
|
|
133
|
+
checkPasswordToken: (body) => request(`/v1/vibe/applications/${applicationId}/users/set-password/check`, {
|
|
134
|
+
method: "POST",
|
|
135
|
+
json: body
|
|
136
|
+
}, z.object({ email: z.string() })),
|
|
137
|
+
setPassword: (body) => request(`/v1/vibe/applications/${applicationId}/users/set-password`, {
|
|
138
|
+
method: "POST",
|
|
139
|
+
json: body
|
|
140
|
+
}, z.object({
|
|
141
|
+
status: z.enum(["AUTHENTICATED", "MFA_REQUIRED"]),
|
|
142
|
+
session: z.object({
|
|
143
|
+
jwt: z.string(),
|
|
144
|
+
user: userSchema,
|
|
145
|
+
permissions: permissionsSchema
|
|
146
|
+
}).nullish(),
|
|
147
|
+
mfa: z.object({
|
|
148
|
+
action: z.enum([
|
|
149
|
+
"VERIFICATION_REQUIRED",
|
|
150
|
+
"SETUP_REQUIRED",
|
|
151
|
+
"SETUP_OPTIONAL"
|
|
152
|
+
]),
|
|
153
|
+
challengeToken: z.string()
|
|
154
|
+
}).nullish()
|
|
155
|
+
})),
|
|
102
156
|
sendSignUpCode: (body) => request(`/v1/vibe/applications/${applicationId}/users/sign-up/send-code`, {
|
|
103
157
|
method: "POST",
|
|
104
158
|
json: body
|
package/dist/auth/server.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { confirmAuthenticatorSetup, removeAuthenticator, resetAuthenticator, sen
|
|
|
2
2
|
import { sendSignInCode, signInWithCode } from "./methods/code.js";
|
|
3
3
|
import { signInWithMagicLink } from "./methods/magicLink.js";
|
|
4
4
|
import { signIn, signOut } from "./methods/password.js";
|
|
5
|
+
import { checkPasswordLink, requestPasswordReset, setPasswordWithLink } from "./methods/passwordLink.js";
|
|
6
|
+
import { settings } from "./methods/settings.js";
|
|
5
7
|
import { confirmSignUp, signUp } from "./methods/signup.js";
|
|
6
8
|
import { signInWithGoogle } from "./methods/social.js";
|
|
7
9
|
import "@tanstack/react-start/server-only";
|
|
@@ -20,6 +22,9 @@ declare const auth: {
|
|
|
20
22
|
signInWithCode: typeof signInWithCode;
|
|
21
23
|
signInWithGoogle: typeof signInWithGoogle;
|
|
22
24
|
signInWithMagicLink: typeof signInWithMagicLink;
|
|
25
|
+
requestPasswordReset: typeof requestPasswordReset;
|
|
26
|
+
checkPasswordLink: typeof checkPasswordLink;
|
|
27
|
+
setPasswordWithLink: typeof setPasswordWithLink;
|
|
23
28
|
startAuthenticatorSetup: typeof startAuthenticatorSetup;
|
|
24
29
|
confirmAuthenticatorSetup: typeof confirmAuthenticatorSetup;
|
|
25
30
|
skipAuthenticatorSetup: typeof skipAuthenticatorSetup;
|
|
@@ -27,6 +32,7 @@ declare const auth: {
|
|
|
27
32
|
sendAuthenticatorResetCode: typeof sendAuthenticatorResetCode;
|
|
28
33
|
resetAuthenticator: typeof resetAuthenticator;
|
|
29
34
|
removeAuthenticator: typeof removeAuthenticator;
|
|
35
|
+
settings: typeof settings;
|
|
30
36
|
};
|
|
31
37
|
//#endregion
|
|
32
38
|
export { auth };
|
package/dist/auth/server.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { settings } from "./methods/settings.js";
|
|
1
2
|
import { confirmAuthenticatorSetup, removeAuthenticator, resetAuthenticator, sendAuthenticatorResetCode, skipAuthenticatorSetup, startAuthenticatorSetup, verifyAuthenticator } from "./methods/authenticator.js";
|
|
2
3
|
import { sendSignInCode, signInWithCode } from "./methods/code.js";
|
|
3
4
|
import { signInWithMagicLink } from "./methods/magicLink.js";
|
|
4
5
|
import { signIn, signOut } from "./methods/password.js";
|
|
6
|
+
import { checkPasswordLink, requestPasswordReset, setPasswordWithLink } from "./methods/passwordLink.js";
|
|
5
7
|
import { confirmSignUp, signUp } from "./methods/signup.js";
|
|
6
8
|
import { signInWithGoogle } from "./methods/social.js";
|
|
7
9
|
import "@tanstack/react-start/server-only";
|
|
@@ -19,13 +21,17 @@ const auth = {
|
|
|
19
21
|
signInWithCode,
|
|
20
22
|
signInWithGoogle,
|
|
21
23
|
signInWithMagicLink,
|
|
24
|
+
requestPasswordReset,
|
|
25
|
+
checkPasswordLink,
|
|
26
|
+
setPasswordWithLink,
|
|
22
27
|
startAuthenticatorSetup,
|
|
23
28
|
confirmAuthenticatorSetup,
|
|
24
29
|
skipAuthenticatorSetup,
|
|
25
30
|
verifyAuthenticator,
|
|
26
31
|
sendAuthenticatorResetCode,
|
|
27
32
|
resetAuthenticator,
|
|
28
|
-
removeAuthenticator
|
|
33
|
+
removeAuthenticator,
|
|
34
|
+
settings
|
|
29
35
|
};
|
|
30
36
|
|
|
31
37
|
//#endregion
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react6 from "react";
|
|
2
2
|
|
|
3
3
|
//#region src/default-error-overlay.d.ts
|
|
4
4
|
type Props = {
|
|
@@ -8,6 +8,6 @@ type Props = {
|
|
|
8
8
|
declare function DefaultErrorOverlay({
|
|
9
9
|
error,
|
|
10
10
|
reset
|
|
11
|
-
}: Props):
|
|
11
|
+
}: Props): react6.JSX.Element;
|
|
12
12
|
//#endregion
|
|
13
13
|
export { DefaultErrorOverlay };
|
package/dist/index.d.ts
CHANGED
|
@@ -4,12 +4,13 @@ import { FileAttachment } from "./core/file-upload.js";
|
|
|
4
4
|
import { FileItem, useFileUpload } from "./core/use-file-upload.js";
|
|
5
5
|
import { DateOptions, DateParts, DateSeparator, DateValue, FixedDateFormat, FormattedDate, Formatting, FormattingScope, WeekDay, formatDate, formatDateTime, formatNumber, useFormatting } from "./formatting.js";
|
|
6
6
|
import { SoftrContext } from "./auth/context.js";
|
|
7
|
+
import { AuthSettings } from "./auth/platform.js";
|
|
7
8
|
import { checkAccess, defineVisibility, isAuthorized } from "./visibility/visibility.js";
|
|
8
|
-
import { assertRouteAccess, guardRoute, isAccessError, isAlreadyAuthenticatedError, isForbiddenError, isUnauthenticatedError } from "./visibility/route.js";
|
|
9
|
-
import { getSoftrContext, initialSoftrContext, softrAuthMiddleware, useCurrentUser } from "./auth/isomorphic.js";
|
|
9
|
+
import { assertRouteAccess, authRedirectTarget, guardRoute, isAccessError, isAlreadyAuthenticatedError, isForbiddenError, isUnauthenticatedError } from "./visibility/route.js";
|
|
10
|
+
import { AuthOptions, AuthSettingsProvider, getAuthSettings, getSoftrContext, initialSoftrContext, softrAuthMiddleware, useAuthSettings, useCurrentUser } from "./auth/isomorphic.js";
|
|
10
11
|
import { softrMcpMiddleware } from "./mcp.js";
|
|
11
12
|
import { useUserTimezone } from "./timezone.js";
|
|
12
13
|
import { PwaInstall, PwaPlatform, SoftrPwaHead, usePwaInstall } from "./pwa.js";
|
|
13
14
|
import { DefaultErrorOverlay } from "./default-error-overlay.js";
|
|
14
15
|
import { Audience } from "./visibility/audience.js";
|
|
15
|
-
export { type ActionPermissions, Audience, type DateOptions, type DateParts, type DateSeparator, type DateValue, DefaultErrorOverlay, type FileAttachment, type FileItem, type FixedDateFormat, FormattedDate, type Formatting, FormattingScope, type PwaInstall, type PwaPlatform, type SoftrContext, type SoftrDatasources, SoftrPwaHead, type SoftrUserGroupId, type SoftrUserGroups, type User, type WeekDay, assertRouteAccess, checkAccess, defineIntegration, defineMutation, defineQuery, defineVisibility, defineWorkflow, formatDate, formatDateTime, formatNumber, getSoftrContext, guardRoute, initialSoftrContext, isAccessError, isAlreadyAuthenticatedError, isAuthorized, isForbiddenError, isUnauthenticatedError, softrAuthMiddleware, softrMcpMiddleware, useCurrentUser, useFileUpload, useFormatting, usePwaInstall, useUserTimezone };
|
|
16
|
+
export { type ActionPermissions, Audience, type AuthOptions, type AuthSettings, AuthSettingsProvider, type DateOptions, type DateParts, type DateSeparator, type DateValue, DefaultErrorOverlay, type FileAttachment, type FileItem, type FixedDateFormat, FormattedDate, type Formatting, FormattingScope, type PwaInstall, type PwaPlatform, type SoftrContext, type SoftrDatasources, SoftrPwaHead, type SoftrUserGroupId, type SoftrUserGroups, type User, type WeekDay, assertRouteAccess, authRedirectTarget, checkAccess, defineIntegration, defineMutation, defineQuery, defineVisibility, defineWorkflow, formatDate, formatDateTime, formatNumber, getAuthSettings, getSoftrContext, guardRoute, initialSoftrContext, isAccessError, isAlreadyAuthenticatedError, isAuthorized, isForbiddenError, isUnauthenticatedError, softrAuthMiddleware, softrMcpMiddleware, useAuthSettings, useCurrentUser, useFileUpload, useFormatting, usePwaInstall, useUserTimezone };
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { useFileUpload } from "./core/use-file-upload.js";
|
|
2
2
|
import { defineIntegration, defineMutation, defineQuery, defineWorkflow } from "./action.js";
|
|
3
3
|
import { checkAccess, defineVisibility, isAuthorized } from "./visibility/visibility.js";
|
|
4
|
-
import { assertRouteAccess, guardRoute, isAccessError, isAlreadyAuthenticatedError, isForbiddenError, isUnauthenticatedError } from "./visibility/route.js";
|
|
4
|
+
import { assertRouteAccess, authRedirectTarget, guardRoute, isAccessError, isAlreadyAuthenticatedError, isForbiddenError, isUnauthenticatedError } from "./visibility/route.js";
|
|
5
5
|
import { FormattedDate, FormattingScope, formatDate, formatDateTime, formatNumber, useFormatting } from "./formatting.js";
|
|
6
6
|
import { SoftrPwaHead, usePwaInstall } from "./pwa.js";
|
|
7
|
-
import { getSoftrContext, initialSoftrContext, softrAuthMiddleware, useCurrentUser } from "./auth/isomorphic.js";
|
|
7
|
+
import { AuthSettingsProvider, getAuthSettings, getSoftrContext, initialSoftrContext, softrAuthMiddleware, useAuthSettings, useCurrentUser } from "./auth/isomorphic.js";
|
|
8
8
|
import { softrMcpMiddleware } from "./mcp.js";
|
|
9
9
|
import { useUserTimezone } from "./timezone.js";
|
|
10
10
|
import { DefaultErrorOverlay } from "./default-error-overlay.js";
|
|
11
11
|
import { Audience } from "./visibility/audience.js";
|
|
12
12
|
|
|
13
|
-
export { Audience, DefaultErrorOverlay, FormattedDate, FormattingScope, SoftrPwaHead, assertRouteAccess, checkAccess, defineIntegration, defineMutation, defineQuery, defineVisibility, defineWorkflow, formatDate, formatDateTime, formatNumber, getSoftrContext, guardRoute, initialSoftrContext, isAccessError, isAlreadyAuthenticatedError, isAuthorized, isForbiddenError, isUnauthenticatedError, softrAuthMiddleware, softrMcpMiddleware, useCurrentUser, useFileUpload, useFormatting, usePwaInstall, useUserTimezone };
|
|
13
|
+
export { Audience, AuthSettingsProvider, DefaultErrorOverlay, FormattedDate, FormattingScope, SoftrPwaHead, assertRouteAccess, authRedirectTarget, checkAccess, defineIntegration, defineMutation, defineQuery, defineVisibility, defineWorkflow, formatDate, formatDateTime, formatNumber, getAuthSettings, getSoftrContext, guardRoute, initialSoftrContext, isAccessError, isAlreadyAuthenticatedError, isAuthorized, isForbiddenError, isUnauthenticatedError, softrAuthMiddleware, softrMcpMiddleware, useAuthSettings, useCurrentUser, useFileUpload, useFormatting, usePwaInstall, useUserTimezone };
|
package/dist/mcp.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DatasourceAction } from "./action.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as _tanstack_react_start4 from "@tanstack/react-start";
|
|
3
3
|
|
|
4
4
|
//#region src/mcp.d.ts
|
|
5
5
|
|
|
@@ -12,12 +12,6 @@ type SoftrMcpOptions = {
|
|
|
12
12
|
* decide who may run the ones that are listed.
|
|
13
13
|
*/
|
|
14
14
|
actions?: Array<DatasourceAction>;
|
|
15
|
-
/**
|
|
16
|
-
* The app's sign-in page, as a path on this app. A signed-out visitor who
|
|
17
|
-
* opens the approval page is sent here with `?redirect=` pointing back at it.
|
|
18
|
-
* Defaults to `/login`.
|
|
19
|
-
*/
|
|
20
|
-
loginPath?: string;
|
|
21
15
|
};
|
|
22
16
|
/**
|
|
23
17
|
* Serves the MCP endpoint and its OAuth flow from the app's own origin.
|
|
@@ -37,6 +31,6 @@ type SoftrMcpOptions = {
|
|
|
37
31
|
* ],
|
|
38
32
|
* }))
|
|
39
33
|
*/
|
|
40
|
-
declare function softrMcpMiddleware(options?: SoftrMcpOptions):
|
|
34
|
+
declare function softrMcpMiddleware(options?: SoftrMcpOptions): _tanstack_react_start4.RequestMiddlewareAfterServer<{}, undefined, undefined>;
|
|
41
35
|
//#endregion
|
|
42
36
|
export { softrMcpMiddleware };
|