@protobase/client 0.3.5 → 0.4.1
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/_virtual/_rolldown/runtime.js +13 -0
- package/dist/account-security.d.ts +54 -0
- package/dist/account-security.js +75 -0
- package/dist/auth-error.d.ts +8 -0
- package/dist/auth-error.js +16 -0
- package/dist/auth-types.d.ts +32 -0
- package/dist/auth.d.ts +57 -34
- package/dist/auth.js +33 -61
- package/dist/better-auth-client.d.ts +2241 -0
- package/dist/better-auth-client.js +18 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +3 -1
- package/dist/sign-in-flows.js +69 -0
- package/dist/sign-in-policy.d.ts +37 -0
- package/dist/sign-in-policy.js +20 -0
- package/dist/staff-sign-in.d.ts +32 -0
- package/dist/staff-sign-in.js +45 -0
- package/dist/static-session.d.ts +10 -0
- package/dist/static-session.js +81 -0
- package/package.json +4 -3
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { __exportAll };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { BetterAuthClient } from "./better-auth-client.js";
|
|
2
|
+
import { SignInPolicy } from "./sign-in-policy.js";
|
|
3
|
+
//#region src/account-security.d.ts
|
|
4
|
+
/** What a sign-in policy can require that an account sets up once. */
|
|
5
|
+
export type RequiredSetup = 'twoFactor' | 'passkey';
|
|
6
|
+
/**
|
|
7
|
+
* The signed-in account's ways to sign in: the policy as it applies, whether mail is on (for emailed codes), what the
|
|
8
|
+
* account has (a password, how many passkeys, two-factor authentication, and whether that has an authenticator app
|
|
9
|
+
* with backup codes or only emailed codes), and what the policy requires that it lacks.
|
|
10
|
+
*/
|
|
11
|
+
export type AccountSignIn = {
|
|
12
|
+
policy: SignInPolicy;
|
|
13
|
+
mail: boolean;
|
|
14
|
+
account: {
|
|
15
|
+
password: boolean;
|
|
16
|
+
passkeys: number;
|
|
17
|
+
twoFactor: boolean;
|
|
18
|
+
authenticatorApp: boolean;
|
|
19
|
+
};
|
|
20
|
+
missing: RequiredSetup[];
|
|
21
|
+
};
|
|
22
|
+
export type Passkey = {
|
|
23
|
+
id: string;
|
|
24
|
+
name?: string;
|
|
25
|
+
createdAt?: string;
|
|
26
|
+
backedUp: boolean;
|
|
27
|
+
};
|
|
28
|
+
/** A new authenticator app: the `otpauth://` URI it scans, and the backup codes that work once each instead of a code. */
|
|
29
|
+
export type AuthenticatorSetup = {
|
|
30
|
+
totpURI: string;
|
|
31
|
+
backupCodes: string[];
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The signed-in person's passkeys and two-factor authentication. `password` is asked for by the changes that need it
|
|
35
|
+
* when the account has one. Each call rejects with `AuthError`.
|
|
36
|
+
*/
|
|
37
|
+
export declare const accountSecurity: (client: BetterAuthClient) => {
|
|
38
|
+
signInMethods: () => Promise<AccountSignIn>;
|
|
39
|
+
passkeys: () => Promise<Passkey[]>;
|
|
40
|
+
/** Asks the browser to create a passkey for this site, named `name` in the list. */
|
|
41
|
+
addPasskey: (name?: string) => Promise<void>;
|
|
42
|
+
renamePasskey: (id: string, name: string) => Promise<void>;
|
|
43
|
+
removePasskey: (id: string) => Promise<void>;
|
|
44
|
+
/** Starts two-factor authentication with an authenticator app; it is on once `confirmAuthenticatorApp` takes a code from the app. */
|
|
45
|
+
startAuthenticatorApp: (password?: string) => Promise<AuthenticatorSetup>;
|
|
46
|
+
confirmAuthenticatorApp: (code: string) => Promise<void>;
|
|
47
|
+
/** Turns on two-factor authentication with a code emailed at each sign-in. */
|
|
48
|
+
turnOnEmailedCodes: (password?: string) => Promise<void>;
|
|
49
|
+
turnOffTwoFactor: (password?: string) => Promise<void>;
|
|
50
|
+
/** New backup codes for the authenticator app; the old ones stop working. */
|
|
51
|
+
newBackupCodes: (password?: string) => Promise<string[]>;
|
|
52
|
+
};
|
|
53
|
+
export type AccountSecurity = ReturnType<typeof accountSecurity>;
|
|
54
|
+
//#endregion
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { authError } from "./auth-error.js";
|
|
2
|
+
//#region src/account-security.ts
|
|
3
|
+
/**
|
|
4
|
+
* The signed-in person's passkeys and two-factor authentication. `password` is asked for by the changes that need it
|
|
5
|
+
* when the account has one. Each call rejects with `AuthError`.
|
|
6
|
+
*/
|
|
7
|
+
const accountSecurity = (client) => ({
|
|
8
|
+
signInMethods: async () => {
|
|
9
|
+
const { data, error } = await client.$fetch("/account/sign-in-methods");
|
|
10
|
+
if (error || !data) throw authError(error, "Could not read your sign-in methods");
|
|
11
|
+
return data;
|
|
12
|
+
},
|
|
13
|
+
passkeys: async () => {
|
|
14
|
+
const { data, error } = await client.passkey.listUserPasskeys();
|
|
15
|
+
if (error || !data) throw authError(error, "Could not read your passkeys");
|
|
16
|
+
return data.map((key) => ({
|
|
17
|
+
id: key.id,
|
|
18
|
+
backedUp: key.backedUp,
|
|
19
|
+
...key.name && { name: key.name },
|
|
20
|
+
...key.createdAt && { createdAt: new Date(key.createdAt).toISOString() }
|
|
21
|
+
}));
|
|
22
|
+
},
|
|
23
|
+
/** Asks the browser to create a passkey for this site, named `name` in the list. */
|
|
24
|
+
addPasskey: async (name) => {
|
|
25
|
+
const { error } = await client.passkey.addPasskey(name ? { name } : {});
|
|
26
|
+
if (error) throw authError(error, "Could not add the passkey");
|
|
27
|
+
},
|
|
28
|
+
renamePasskey: async (id, name) => {
|
|
29
|
+
const { error } = await client.passkey.updatePasskey({
|
|
30
|
+
id,
|
|
31
|
+
name
|
|
32
|
+
});
|
|
33
|
+
if (error) throw authError(error, "Could not rename the passkey");
|
|
34
|
+
},
|
|
35
|
+
removePasskey: async (id) => {
|
|
36
|
+
const { error } = await client.passkey.deletePasskey({ id });
|
|
37
|
+
if (error) throw authError(error, "Could not remove the passkey");
|
|
38
|
+
},
|
|
39
|
+
/** Starts two-factor authentication with an authenticator app; it is on once `confirmAuthenticatorApp` takes a code from the app. */
|
|
40
|
+
startAuthenticatorApp: async (password) => {
|
|
41
|
+
const { data, error } = await client.twoFactor.enable({
|
|
42
|
+
method: "totp",
|
|
43
|
+
...password && { password }
|
|
44
|
+
});
|
|
45
|
+
if (error || data?.method !== "totp") throw authError(error, "Could not start two-factor authentication");
|
|
46
|
+
return {
|
|
47
|
+
totpURI: data.totpURI,
|
|
48
|
+
backupCodes: data.backupCodes
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
confirmAuthenticatorApp: async (code) => {
|
|
52
|
+
const { error } = await client.twoFactor.verifyTotp({ code });
|
|
53
|
+
if (error) throw authError(error, "The code did not work");
|
|
54
|
+
},
|
|
55
|
+
/** Turns on two-factor authentication with a code emailed at each sign-in. */
|
|
56
|
+
turnOnEmailedCodes: async (password) => {
|
|
57
|
+
const { error } = await client.twoFactor.enable({
|
|
58
|
+
method: "otp",
|
|
59
|
+
...password && { password }
|
|
60
|
+
});
|
|
61
|
+
if (error) throw authError(error, "Could not turn on two-factor authentication");
|
|
62
|
+
},
|
|
63
|
+
turnOffTwoFactor: async (password) => {
|
|
64
|
+
const { error } = await client.twoFactor.disable(password ? { password } : {});
|
|
65
|
+
if (error) throw authError(error, "Could not turn off two-factor authentication");
|
|
66
|
+
},
|
|
67
|
+
/** New backup codes for the authenticator app; the old ones stop working. */
|
|
68
|
+
newBackupCodes: async (password) => {
|
|
69
|
+
const { data, error } = await client.twoFactor.generateBackupCodes(password ? { password } : {});
|
|
70
|
+
if (error || !data) throw authError(error, "Could not make new backup codes");
|
|
71
|
+
return data.backupCodes;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
//#endregion
|
|
75
|
+
export { accountSecurity };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region src/auth-error.d.ts
|
|
2
|
+
/** A failed sign-in or account change, with Better Auth's status and code (for example `INVALID_EMAIL_OR_PASSWORD`). */
|
|
3
|
+
export declare class AuthError extends Error {
|
|
4
|
+
readonly status: number;
|
|
5
|
+
readonly code?: string | undefined;
|
|
6
|
+
constructor(message: string, status: number, code?: string | undefined);
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/auth-error.ts
|
|
2
|
+
/** A failed sign-in or account change, with Better Auth's status and code (for example `INVALID_EMAIL_OR_PASSWORD`). */
|
|
3
|
+
var AuthError = class extends Error {
|
|
4
|
+
status;
|
|
5
|
+
code;
|
|
6
|
+
constructor(message, status, code) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.status = status;
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.name = "AuthError";
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
/** Better Auth's error from a client call as an `AuthError`, with `fallback` when it has no message. */
|
|
14
|
+
const authError = (error, fallback) => new AuthError(error?.message || fallback, error?.status ?? 500, error?.code);
|
|
15
|
+
//#endregion
|
|
16
|
+
export { AuthError, authError };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region src/auth-types.d.ts
|
|
2
|
+
export type AuthUser = {
|
|
3
|
+
id: string;
|
|
4
|
+
email: string;
|
|
5
|
+
name: string;
|
|
6
|
+
role?: string | null;
|
|
7
|
+
};
|
|
8
|
+
/** A way to sign in the server offers: a password, a code emailed to the address, or a passkey. */
|
|
9
|
+
export type SignInMethod = 'password' | 'emailCode' | 'passkey';
|
|
10
|
+
/** The second step of a sign-in: a code from an authenticator app (`totp`), or one emailed for it (`otp`). A backup code works whenever `totp` does. */
|
|
11
|
+
export type TwoFactorMethod = 'totp' | 'otp';
|
|
12
|
+
/** A sign-in either finished, or waits for the second step with one of `methods`. */
|
|
13
|
+
export type SignInResult = {
|
|
14
|
+
kind: 'signed-in';
|
|
15
|
+
user: AuthUser;
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'two-factor';
|
|
18
|
+
methods: TwoFactorMethod[];
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* `needsAdmin` while no user exists yet; `signInMethods` the ways to sign in the server's policy leaves on;
|
|
22
|
+
* `passwordReset` when the server can email reset links; `socialProviders` the ids of the sign-in providers, for example
|
|
23
|
+
* `github`; `staffSignIn` the operator provider's name when its staff can sign in as people.
|
|
24
|
+
*/
|
|
25
|
+
export type SetupStatus = {
|
|
26
|
+
needsAdmin: boolean;
|
|
27
|
+
signInMethods: SignInMethod[];
|
|
28
|
+
passwordReset: boolean;
|
|
29
|
+
socialProviders: string[];
|
|
30
|
+
staffSignIn?: string;
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
package/dist/auth.d.ts
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
|
+
import { SignInPolicy, SignInPolicyState } from "./sign-in-policy.js";
|
|
2
|
+
import { AccountSignIn, AuthenticatorSetup, Passkey } from "./account-security.js";
|
|
3
|
+
import { StaffSignIn } from "./staff-sign-in.js";
|
|
4
|
+
import { AuthUser, SetupStatus, SignInResult, TwoFactorMethod } from "./auth-types.js";
|
|
5
|
+
import { AuthError } from "./auth-error.js";
|
|
1
6
|
//#region src/auth.d.ts
|
|
2
|
-
export type AuthUser = {
|
|
3
|
-
id: string;
|
|
4
|
-
email: string;
|
|
5
|
-
name: string;
|
|
6
|
-
role?: string | null;
|
|
7
|
-
};
|
|
8
|
-
/** A failed sign-in or sign-out, with Better Auth's status and code (for example `INVALID_EMAIL_OR_PASSWORD`). */
|
|
9
|
-
export declare class AuthError extends Error {
|
|
10
|
-
readonly status: number;
|
|
11
|
-
readonly code?: string | undefined;
|
|
12
|
-
constructor(message: string, status: number, code?: string | undefined);
|
|
13
|
-
}
|
|
14
7
|
export type AuthSessionOptions = {
|
|
15
8
|
/** Origin of the server; defaults to the page's own. */
|
|
16
9
|
origin?: string;
|
|
@@ -24,25 +17,13 @@ export type AuthSessionOptions = {
|
|
|
24
17
|
};
|
|
25
18
|
/** The expiry of a JWT in milliseconds, read from its payload (the signature is the server's business). */
|
|
26
19
|
export declare const tokenExpiry: (token: string) => number;
|
|
27
|
-
/** `needsAdmin` while no user exists yet; `passwordReset` when the server can email reset links; `socialProviders` the ids of the sign-in providers, for example `github`. */
|
|
28
|
-
export type SetupStatus = {
|
|
29
|
-
needsAdmin: boolean;
|
|
30
|
-
passwordReset: boolean;
|
|
31
|
-
socialProviders: string[];
|
|
32
|
-
};
|
|
33
20
|
/**
|
|
34
|
-
* The browser side of Better Auth: sign in with
|
|
35
|
-
*
|
|
21
|
+
* The browser side of Better Auth: sign in with a password, an emailed code or a passkey (with a second step for an
|
|
22
|
+
* account with two-factor authentication), the account's passkeys and two-factor authentication (`account`), the
|
|
23
|
+
* sign-in policy for admins (`signInPolicy`), staff of the operator signing in as people (`staff`), and a short-lived
|
|
24
|
+
* JWT held in memory only (never in storage), fetched with the session cookie and refreshed before it expires.
|
|
36
25
|
*/
|
|
37
26
|
export declare const createAuthSession: (options?: AuthSessionOptions) => {
|
|
38
|
-
token: ({ refresh }?: {
|
|
39
|
-
refresh?: boolean;
|
|
40
|
-
}) => Promise<string | undefined>;
|
|
41
|
-
/** Whether the first admin is still missing. Every server has a login, so a 404 means the URL is not a Protobase server. */
|
|
42
|
-
status: () => Promise<SetupStatus>;
|
|
43
|
-
/** The signed-in user from the session cookie, or `undefined`. */
|
|
44
|
-
session: () => Promise<AuthUser | undefined>;
|
|
45
|
-
signIn: (email: string, password: string) => Promise<AuthUser>;
|
|
46
27
|
/**
|
|
47
28
|
* Starts sign-in with a provider such as `github`: resolves with the provider's authorization URL, for the page to go to.
|
|
48
29
|
* The provider sends the browser back to `callbackURL` signed in, or with `?error=<code>`.
|
|
@@ -56,11 +37,53 @@ export declare const createAuthSession: (options?: AuthSessionOptions) => {
|
|
|
56
37
|
requestPasswordReset: (email: string, redirectTo: string) => Promise<void>;
|
|
57
38
|
/** Sets a new password with the token from a reset link; the link works once. */
|
|
58
39
|
resetPassword: (token: string, newPassword: string) => Promise<void>;
|
|
40
|
+
account: {
|
|
41
|
+
signInMethods: () => Promise<AccountSignIn>;
|
|
42
|
+
passkeys: () => Promise<Passkey[]>;
|
|
43
|
+
addPasskey: (name?: string) => Promise<void>;
|
|
44
|
+
renamePasskey: (id: string, name: string) => Promise<void>;
|
|
45
|
+
removePasskey: (id: string) => Promise<void>;
|
|
46
|
+
startAuthenticatorApp: (password?: string) => Promise<AuthenticatorSetup>;
|
|
47
|
+
confirmAuthenticatorApp: (code: string) => Promise<void>;
|
|
48
|
+
turnOnEmailedCodes: (password?: string) => Promise<void>;
|
|
49
|
+
turnOffTwoFactor: (password?: string) => Promise<void>;
|
|
50
|
+
newBackupCodes: (password?: string) => Promise<string[]>;
|
|
51
|
+
};
|
|
52
|
+
signInPolicy: {
|
|
53
|
+
read: () => Promise<SignInPolicyState>;
|
|
54
|
+
save: (policy: SignInPolicy) => Promise<SignInPolicyState>;
|
|
55
|
+
};
|
|
56
|
+
staff: {
|
|
57
|
+
stop: () => Promise<void>;
|
|
58
|
+
start: (input: {
|
|
59
|
+
email: string;
|
|
60
|
+
reason: string;
|
|
61
|
+
callbackURL: string;
|
|
62
|
+
}) => Promise<string>;
|
|
63
|
+
current: () => Promise<StaffSignIn | undefined>;
|
|
64
|
+
log: () => Promise<StaffSignIn[]>;
|
|
65
|
+
};
|
|
66
|
+
signIn: (email: string, password: string) => Promise<SignInResult>;
|
|
67
|
+
sendSignInCode: (email: string) => Promise<void>;
|
|
68
|
+
signInWithCode: (email: string, code: string) => Promise<SignInResult>;
|
|
69
|
+
signInWithPasskey: () => Promise<AuthUser>;
|
|
70
|
+
sendTwoFactorCode: () => Promise<void>;
|
|
71
|
+
verifyTwoFactor: ({ method, code, trustDevice }: {
|
|
72
|
+
method: TwoFactorMethod | "backup";
|
|
73
|
+
code: string;
|
|
74
|
+
trustDevice?: boolean;
|
|
75
|
+
}) => Promise<AuthUser>;
|
|
76
|
+
token: ({ refresh }?: {
|
|
77
|
+
refresh?: boolean;
|
|
78
|
+
}) => Promise<string | undefined>;
|
|
79
|
+
/**
|
|
80
|
+
* Whether the first admin is still missing, and how people can sign in. Every server has a login, so a 404 means the
|
|
81
|
+
* URL is not a Protobase server. A server from before sign-in methods were listed offers passwords only.
|
|
82
|
+
*/
|
|
83
|
+
status: () => Promise<SetupStatus>;
|
|
84
|
+
/** The signed-in user from the session cookie, or `undefined`. */
|
|
85
|
+
session: () => Promise<AuthUser | undefined>;
|
|
59
86
|
};
|
|
60
87
|
export type AuthSession = ReturnType<typeof createAuthSession>;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
* It never refreshes, so use a token that outlives the run.
|
|
64
|
-
*/
|
|
65
|
-
export declare const createStaticSession: (token: string, user?: AuthUser) => AuthSession;
|
|
66
|
-
//#endregion
|
|
88
|
+
//#endregion
|
|
89
|
+
export { AuthError };
|
package/dist/auth.js
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { AuthError, authError } from "./auth-error.js";
|
|
2
|
+
import { accountSecurity } from "./account-security.js";
|
|
3
|
+
import { betterAuthClient } from "./better-auth-client.js";
|
|
4
|
+
import { signInFlows } from "./sign-in-flows.js";
|
|
5
|
+
import { signInPolicyClient } from "./sign-in-policy.js";
|
|
6
|
+
import { staffSignInClient } from "./staff-sign-in.js";
|
|
3
7
|
//#region src/auth.ts
|
|
4
|
-
/** A failed sign-in or sign-out, with Better Auth's status and code (for example `INVALID_EMAIL_OR_PASSWORD`). */
|
|
5
|
-
var AuthError = class extends Error {
|
|
6
|
-
status;
|
|
7
|
-
code;
|
|
8
|
-
constructor(message, status, code) {
|
|
9
|
-
super(message);
|
|
10
|
-
this.status = status;
|
|
11
|
-
this.code = code;
|
|
12
|
-
this.name = "AuthError";
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
8
|
/** The expiry of a JWT in milliseconds, read from its payload (the signature is the server's business). */
|
|
16
9
|
const tokenExpiry = (token) => {
|
|
17
10
|
const payload = token.split(".")[1];
|
|
@@ -21,20 +14,18 @@ const tokenExpiry = (token) => {
|
|
|
21
14
|
return json.exp * 1e3;
|
|
22
15
|
};
|
|
23
16
|
/**
|
|
24
|
-
* The browser side of Better Auth: sign in with
|
|
25
|
-
*
|
|
17
|
+
* The browser side of Better Auth: sign in with a password, an emailed code or a passkey (with a second step for an
|
|
18
|
+
* account with two-factor authentication), the account's passkeys and two-factor authentication (`account`), the
|
|
19
|
+
* sign-in policy for admins (`signInPolicy`), staff of the operator signing in as people (`staff`), and a short-lived
|
|
20
|
+
* JWT held in memory only (never in storage), fetched with the session cookie and refreshed before it expires.
|
|
26
21
|
*/
|
|
27
22
|
const createAuthSession = (options = {}) => {
|
|
28
23
|
const origin = options.origin ?? globalThis.location?.origin ?? "http://localhost";
|
|
29
24
|
const basePath = options.basePath ?? "/api/auth";
|
|
30
25
|
const margin = options.refreshMarginMs ?? 6e4;
|
|
31
26
|
const doFetch = options.fetch ?? ((input, init) => fetch(input, init));
|
|
32
|
-
const client =
|
|
33
|
-
|
|
34
|
-
basePath,
|
|
35
|
-
plugins: [jwtClient()],
|
|
36
|
-
fetchOptions: { customFetchImpl: doFetch }
|
|
37
|
-
});
|
|
27
|
+
const client = betterAuthClient(origin, basePath, doFetch);
|
|
28
|
+
const staff = staffSignInClient(client);
|
|
38
29
|
let cached;
|
|
39
30
|
let pending;
|
|
40
31
|
let timer;
|
|
@@ -66,7 +57,10 @@ const createAuthSession = (options = {}) => {
|
|
|
66
57
|
};
|
|
67
58
|
return {
|
|
68
59
|
token,
|
|
69
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* Whether the first admin is still missing, and how people can sign in. Every server has a login, so a 404 means the
|
|
62
|
+
* URL is not a Protobase server. A server from before sign-in methods were listed offers passwords only.
|
|
63
|
+
*/
|
|
70
64
|
status: async () => {
|
|
71
65
|
const response = await doFetch(`${origin}${basePath}/status`);
|
|
72
66
|
if (response.status === 404) throw new AuthError("This server has no sign-in. Is the API URL right?", 404);
|
|
@@ -74,8 +68,10 @@ const createAuthSession = (options = {}) => {
|
|
|
74
68
|
const body = await response.json();
|
|
75
69
|
return {
|
|
76
70
|
needsAdmin: Boolean(body.needsAdmin),
|
|
71
|
+
signInMethods: body.signInMethods ?? ["password"],
|
|
77
72
|
passwordReset: Boolean(body.passwordReset),
|
|
78
|
-
socialProviders: body.socialProviders ?? []
|
|
73
|
+
socialProviders: body.socialProviders ?? [],
|
|
74
|
+
...body.staffSignIn && { staffSignIn: body.staffSignIn }
|
|
79
75
|
};
|
|
80
76
|
},
|
|
81
77
|
/** The signed-in user from the session cookie, or `undefined`. */
|
|
@@ -83,15 +79,7 @@ const createAuthSession = (options = {}) => {
|
|
|
83
79
|
const { data } = await client.getSession();
|
|
84
80
|
return data?.user;
|
|
85
81
|
},
|
|
86
|
-
|
|
87
|
-
const { data, error } = await client.signIn.email({
|
|
88
|
-
email,
|
|
89
|
-
password
|
|
90
|
-
});
|
|
91
|
-
if (error || !data) throw new AuthError(error?.message || "Sign-in failed", error?.status ?? 500, error?.code);
|
|
92
|
-
await token({ refresh: true });
|
|
93
|
-
return data.user;
|
|
94
|
-
},
|
|
82
|
+
...signInFlows(client, () => token({ refresh: true })),
|
|
95
83
|
/**
|
|
96
84
|
* Starts sign-in with a provider such as `github`: resolves with the provider's authorization URL, for the page to go to.
|
|
97
85
|
* The provider sends the browser back to `callbackURL` signed in, or with `?error=<code>`.
|
|
@@ -103,7 +91,7 @@ const createAuthSession = (options = {}) => {
|
|
|
103
91
|
errorCallbackURL: callbackURL,
|
|
104
92
|
disableRedirect: true
|
|
105
93
|
});
|
|
106
|
-
if (error || !data?.url) throw
|
|
94
|
+
if (error || !data?.url) throw authError(error, "Sign-in failed");
|
|
107
95
|
return data.url;
|
|
108
96
|
},
|
|
109
97
|
signOut: async () => {
|
|
@@ -119,7 +107,7 @@ const createAuthSession = (options = {}) => {
|
|
|
119
107
|
email,
|
|
120
108
|
redirectTo
|
|
121
109
|
});
|
|
122
|
-
if (error) throw
|
|
110
|
+
if (error) throw authError(error, "Could not send the reset link");
|
|
123
111
|
},
|
|
124
112
|
/** Sets a new password with the token from a reset link; the link works once. */
|
|
125
113
|
resetPassword: async (token, newPassword) => {
|
|
@@ -127,34 +115,18 @@ const createAuthSession = (options = {}) => {
|
|
|
127
115
|
token,
|
|
128
116
|
newPassword
|
|
129
117
|
});
|
|
130
|
-
if (error) throw
|
|
118
|
+
if (error) throw authError(error, "Could not set the password");
|
|
119
|
+
},
|
|
120
|
+
account: accountSecurity(client),
|
|
121
|
+
signInPolicy: signInPolicyClient(client),
|
|
122
|
+
staff: {
|
|
123
|
+
...staff,
|
|
124
|
+
stop: async () => {
|
|
125
|
+
forget();
|
|
126
|
+
await staff.stop();
|
|
127
|
+
}
|
|
131
128
|
}
|
|
132
129
|
};
|
|
133
130
|
};
|
|
134
|
-
/**
|
|
135
|
-
* A session that is already signed in with a token you hold, for stories and scripts (`protobase token <email>`).
|
|
136
|
-
* It never refreshes, so use a token that outlives the run.
|
|
137
|
-
*/
|
|
138
|
-
const createStaticSession = (token, user = {
|
|
139
|
-
id: "token",
|
|
140
|
-
email: "token",
|
|
141
|
-
name: "API token",
|
|
142
|
-
role: null
|
|
143
|
-
}) => ({
|
|
144
|
-
token: async () => token,
|
|
145
|
-
status: async () => ({
|
|
146
|
-
needsAdmin: false,
|
|
147
|
-
passwordReset: false,
|
|
148
|
-
socialProviders: []
|
|
149
|
-
}),
|
|
150
|
-
session: async () => user,
|
|
151
|
-
signIn: async () => user,
|
|
152
|
-
signInSocial: async () => {
|
|
153
|
-
throw new AuthError("A static session cannot sign in with a provider", 400);
|
|
154
|
-
},
|
|
155
|
-
signOut: async () => void 0,
|
|
156
|
-
requestPasswordReset: async () => void 0,
|
|
157
|
-
resetPassword: async () => void 0
|
|
158
|
-
});
|
|
159
131
|
//#endregion
|
|
160
|
-
export { AuthError, createAuthSession,
|
|
132
|
+
export { AuthError, createAuthSession, tokenExpiry };
|