@baliola/auth-sdk 0.5.0 → 0.7.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/CHANGELOG.md +78 -0
- package/README.md +118 -24
- package/dist/{authError-CYUAl2Jt.js → authError-BPxMHQK2.js} +73 -1
- package/dist/{authError-DgPEjTfW.d.ts → authError-E11ZMcID.d.ts} +42 -1
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +1 -1
- package/dist/{client-DxhQkQcE.js → client-Dlhhdp-T.js} +217 -35
- package/dist/errors/index.d.ts +2 -2
- package/dist/errors/index.js +2 -2
- package/dist/{index-URk8yf8l.d.ts → index-DwFEdFaS.d.ts} +99 -18
- package/dist/index.d.ts +6 -6
- package/dist/index.js +3 -3
- package/dist/roles-BZecOymZ.d.ts +123 -0
- package/dist/{session-Cs_P7ojF.d.ts → session-flM0yXx2.d.ts} +6 -4
- package/dist/{sessionStore-BDdEpbL8.d.ts → sessionStore-D2kXjvNM.d.ts} +1 -1
- package/dist/store/index.d.ts +1 -1
- package/dist/types/index.d.ts +3 -3
- package/dist/wallet/index.d.ts +1 -1
- package/package.json +1 -1
- package/dist/requests-jRLgNXyf.d.ts +0 -75
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,84 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@baliola/auth-sdk` are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.7.0
|
|
6
|
+
|
|
7
|
+
Self-service roles and a stricter login contract. baliola-auth added `POST /auth/roles/apply` and
|
|
8
|
+
`GET /auth/roles/status` (issue #61), dropped `flow` and `methods` from the send-login-code
|
|
9
|
+
response so it can no longer reveal whether an email is registered, and is making `clientId`
|
|
10
|
+
mandatory on every login and register body (issue #60) so that only the Console client can mint a
|
|
11
|
+
token carrying global roles.
|
|
12
|
+
|
|
13
|
+
### New features
|
|
14
|
+
|
|
15
|
+
- feat(client): `auth.roles.apply({ roleName })` posts a self-service application for an
|
|
16
|
+
allowlisted global role and returns the account role row (`RoleApplicationStatus`);
|
|
17
|
+
`auth.roles.status()` returns one `RoleStatus` per self-applicable role, with `status: 'none'`
|
|
18
|
+
when the account never applied. Both need a session. Conflicts surface as `AuthError` with
|
|
19
|
+
`code` `role_already_active` or `application_pending`.
|
|
20
|
+
- feat(types): `ApplyRoleInput`, `RoleApplicationState`, `RoleApplicationStatus`, `RoleStatus`,
|
|
21
|
+
and `RolesNamespace` are exported from the root and the `./types` subpath.
|
|
22
|
+
- feat(errors): `ValidationError` (`code: 'validation_error'`, 400) with
|
|
23
|
+
`issues: ValidationIssue[]`, one `{ path, message }` per rejected request field.
|
|
24
|
+
baliola-auth now routes every request validation failure through the standard error
|
|
25
|
+
envelope under this code, so a login body without `clientId` or an `apply` with a role name
|
|
26
|
+
outside the allowlist is an `instanceof ValidationError`. Exported from the root and the
|
|
27
|
+
`./errors` subpath, together with the `ValidationIssue` type.
|
|
28
|
+
- Admin role management (`/admin/roles/*`: approve, revoke, list applications) is deliberately not
|
|
29
|
+
in this SDK. It is a client library for end-user apps; the Baliola Console keeps its own direct
|
|
30
|
+
client for `/admin/*`. This closes the open question on issue #61.
|
|
31
|
+
|
|
32
|
+
### Breaking changes
|
|
33
|
+
|
|
34
|
+
- feat(client)!: `clientId` is now a required option of `createAuthClient`. Construction throws
|
|
35
|
+
`Error('createAuthClient: clientId is required')` when it is missing or empty, the same way
|
|
36
|
+
`baseUrl` is handled. Every login and register body always carries it, and
|
|
37
|
+
`auth.google.startUrl` no longer has its own `clientId` check. The "central" multi-project login
|
|
38
|
+
that omitted `clientId` is gone on the server side, so there is nothing to migrate to: pass the
|
|
39
|
+
client id of the project the app belongs to.
|
|
40
|
+
- chore(types)!: `SendLoginCodeResult` is narrowed to `{ otp: OtpInfo }`. The `flow` and `methods`
|
|
41
|
+
fields are removed because the server no longer sends them (baliola-auth commit `7f29126`);
|
|
42
|
+
whether the email is a login or a signup is only known after `verifyLoginCode`.
|
|
43
|
+
- Per `RELEASING.md` these are pre-1.0 breaks shipped as a minor with this explicit callout.
|
|
44
|
+
|
|
45
|
+
## 0.6.0
|
|
46
|
+
|
|
47
|
+
Hosted Google login. baliola-auth now runs the Google OAuth round trip itself
|
|
48
|
+
(`GET /auth/google/start`, `GET /auth/google/callback`, `POST /auth/google/exchange`),
|
|
49
|
+
so an app can offer "Sign in with Google" without loading Google Identity Services. The
|
|
50
|
+
browser only ever sees a one-time code, never a token.
|
|
51
|
+
|
|
52
|
+
- feat(client): `auth.google.signInWithPopup(opts?)` opens the hosted login in a popup,
|
|
53
|
+
waits for the exit message, exchanges the one-time code, and stores the session.
|
|
54
|
+
`opts.returnTo` (default: current href without hash) and `opts.popup.width` /
|
|
55
|
+
`opts.popup.height` (default 500 x 640). Browser only.
|
|
56
|
+
- feat(client): `auth.google.completeRedirect(opts?)` finishes a hosted login started in
|
|
57
|
+
`redirect` mode on the `returnTo` page: resolves `null` when the URL carries no `code`
|
|
58
|
+
or `error`, verifies the nonce saved by `startUrl`, strips `code`, `error`, and `nonce`
|
|
59
|
+
from the URL before exchanging. Browser only.
|
|
60
|
+
- feat(client): `auth.google.startUrl({ mode, returnTo?, nonce })` builds the
|
|
61
|
+
`/auth/google/start` URL from the client's `clientId`, and `auth.google.exchange({ code })`
|
|
62
|
+
posts the one-time code and stores the session like every other login method. Both are
|
|
63
|
+
the manual path underneath the two methods above.
|
|
64
|
+
- feat(errors): `GoogleSignInCancelledError` (`code: 'oauth_cancelled'`,
|
|
65
|
+
`reason: 'popup_blocked' | 'popup_closed' | 'access_denied'`) and `GoogleSignInError`
|
|
66
|
+
(`code` is the exit or exchange failure: `invalid_google_code`, `email_unverified`,
|
|
67
|
+
`invalid_oauth_state`, `oauth_unexpected`, or the SDK-side `oauth_nonce_mismatch`).
|
|
68
|
+
`authErrorFromResponse` now maps server `invalid_google_code` and `email_unverified` to
|
|
69
|
+
`GoogleSignInError`; `status` and `code` are unchanged, so `instanceof AuthError` and
|
|
70
|
+
`err.code` branches keep working.
|
|
71
|
+
- feat(types): `GoogleExchangeInput`, `GoogleStartMode`, `GoogleStartOptions`,
|
|
72
|
+
`GoogleSignInWithPopupOptions`, `GoogleCompleteRedirectOptions`, and
|
|
73
|
+
`GoogleSignInCancelledReason` are exported from the root and the `./types` (or
|
|
74
|
+
`./errors`) subpath.
|
|
75
|
+
- feat(client)!: **Breaking.** `auth.google.login` accepts `{ idToken }` only.
|
|
76
|
+
`LoginWithGoogleInput` is narrowed from `{ idToken: string } | { code: string }` to
|
|
77
|
+
`{ idToken: string }`. The server no longer accepts `{ code }` on `/auth/google/login`
|
|
78
|
+
(it is a 400 now); apps that used the Google Identity Services code client should move
|
|
79
|
+
to `auth.google.signInWithPopup()`. `RELEASING.md` would call this removal a major
|
|
80
|
+
bump; the user chose 0.6.0 under the pre-1.0 rule that breaks ship as minors with an
|
|
81
|
+
explicit CHANGELOG callout, which this bullet is.
|
|
82
|
+
|
|
5
83
|
## 0.5.0
|
|
6
84
|
|
|
7
85
|
- feat(types): `auth.getProfile()` now returns `account.hasPassword`, a boolean
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @baliola/auth-sdk
|
|
2
2
|
|
|
3
|
-
Client SDK for the Baliola Auth service. Two clearly separated email flows (passwordless OTP, password + verification OTP) plus Google login, with typed methods, typed errors, auto-refresh, and cross-tab sync.
|
|
3
|
+
Client SDK for the Baliola Auth service. Two clearly separated email flows (passwordless OTP, password + verification OTP) plus Google login (hosted popup, hosted redirect, or Google Identity Services), with typed methods, typed errors, auto-refresh, and cross-tab sync.
|
|
4
4
|
|
|
5
5
|
Guides:
|
|
6
6
|
|
|
@@ -31,7 +31,7 @@ import { createAuthClient, localStorageStore, OtpInvalidError } from '@baliola/a
|
|
|
31
31
|
|
|
32
32
|
const auth = createAuthClient({
|
|
33
33
|
baseUrl: AUTH_URL,
|
|
34
|
-
clientId: 'your-project-client-id', //
|
|
34
|
+
clientId: 'your-project-client-id', // required; scopes every login to this project
|
|
35
35
|
store: localStorageStore(), // omit for in-memory (server-side / tests)
|
|
36
36
|
});
|
|
37
37
|
await auth.loadSession(); // rehydrate from store at app boot
|
|
@@ -66,7 +66,7 @@ The SDK is namespaced by flow so that each method's purpose is unambiguous at th
|
|
|
66
66
|
|
|
67
67
|
```ts
|
|
68
68
|
auth.emailOtp.sendLoginCode({ email, captchaToken });
|
|
69
|
-
// → {
|
|
69
|
+
// → { otp: OtpInfo } (never says whether the email is registered)
|
|
70
70
|
|
|
71
71
|
auth.emailOtp.verifyLoginCode({ email, code });
|
|
72
72
|
// → AuthSession (also populates the session mirror)
|
|
@@ -98,15 +98,44 @@ auth.emailPassword.changePassword({ currentPassword, newPassword });
|
|
|
98
98
|
|
|
99
99
|
### `auth.google`
|
|
100
100
|
|
|
101
|
+
Three ways in. The hosted flow needs a `clientId` on the client and a `returnTo` whose origin is
|
|
102
|
+
one of the project's `allowedOrigins`. Google Identity Services is not loaded in your page.
|
|
103
|
+
|
|
101
104
|
```ts
|
|
102
|
-
|
|
103
|
-
|
|
105
|
+
import { GoogleSignInCancelledError, GoogleSignInError } from '@baliola/auth-sdk';
|
|
106
|
+
|
|
107
|
+
// 1. Hosted popup (recommended). Opens the auth server's Google login in a popup,
|
|
108
|
+
// exchanges the one-time code it posts back, and stores the session.
|
|
109
|
+
try {
|
|
110
|
+
const session = await auth.google.signInWithPopup();
|
|
111
|
+
// optional: { returnTo: '/auth/callback', popup: { width: 500, height: 640 } }
|
|
112
|
+
} catch (e) {
|
|
113
|
+
if (e instanceof GoogleSignInCancelledError) return; // e.reason: 'popup_blocked' | 'popup_closed' | 'access_denied'
|
|
114
|
+
if (e instanceof GoogleSignInError) return showError(e.code); // 'email_unverified', 'invalid_google_code', ...
|
|
115
|
+
throw e;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 2. Hosted redirect. Send the tab to Google, then finish on the returnTo page.
|
|
119
|
+
location.assign(auth.google.startUrl({ mode: 'redirect', nonce: crypto.randomUUID() }));
|
|
120
|
+
// ...on the returnTo page, at boot:
|
|
121
|
+
const session = await auth.google.completeRedirect(); // null when the URL has no code or error
|
|
104
122
|
|
|
105
|
-
//
|
|
106
|
-
|
|
107
|
-
auth.google.login({ code }); // → AuthSession
|
|
123
|
+
// 3. Google Identity Services. idToken comes from the GIS button or One Tap.
|
|
124
|
+
auth.google.login({ idToken }); // → AuthSession
|
|
108
125
|
```
|
|
109
126
|
|
|
127
|
+
Manual control: `startUrl({ mode: 'popup' | 'redirect', returnTo?, nonce })` builds
|
|
128
|
+
`GET {baseUrl}/auth/google/start`, and `exchange({ code })` turns the one-time code from the exit into
|
|
129
|
+
a stored session. Both are what `signInWithPopup` and `completeRedirect` use internally.
|
|
130
|
+
|
|
131
|
+
How the popup exit reaches you: the auth server's callback page runs
|
|
132
|
+
`window.opener.postMessage({ type: 'baliola-auth:google', nonce, code }, returnToOrigin)` on success,
|
|
133
|
+
or `{ type: 'baliola-auth:google', nonce, error }` on failure, then closes. `signInWithPopup` accepts
|
|
134
|
+
a message only when `event.origin` is the auth server origin, `type` matches, and `nonce` is the one
|
|
135
|
+
it generated. In `redirect` mode the exit is a 302 to `returnTo` with `code` and `nonce` (or `error`
|
|
136
|
+
and `nonce`) query params; `completeRedirect` checks `nonce` against the value `startUrl` saved in
|
|
137
|
+
`sessionStorage` and strips all three params from the URL before exchanging.
|
|
138
|
+
|
|
110
139
|
### Custodial wallet (smart-account signer)
|
|
111
140
|
|
|
112
141
|
```ts
|
|
@@ -114,7 +143,7 @@ import { createAuthClient } from '@baliola/auth-sdk';
|
|
|
114
143
|
import { createRemoteSigner } from '@baliola/auth-sdk/wallet';
|
|
115
144
|
import { toSmartAccount } from '@baliola/smart-account-sdk';
|
|
116
145
|
|
|
117
|
-
const auth = createAuthClient({ baseUrl });
|
|
146
|
+
const auth = createAuthClient({ baseUrl, clientId });
|
|
118
147
|
await auth.emailOtp.verifyLoginCode({ email, code }); // authenticated session
|
|
119
148
|
|
|
120
149
|
const owner = await createRemoteSigner(auth); // viem LocalAccount, signs server-side
|
|
@@ -123,6 +152,22 @@ const account = await toSmartAccount({ owner, chain: 'macTestnet' });
|
|
|
123
152
|
|
|
124
153
|
The private key never leaves baliola-auth; `owner.signMessage({ raw })` calls `POST /auth/wallet/sign`.
|
|
125
154
|
|
|
155
|
+
### `auth.roles` (self-service role applications)
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
const app = await auth.roles.apply({ roleName: 'module_deployer' }); // POST /auth/roles/apply
|
|
159
|
+
// app = { id, accountId, roleId, projectId, status: 'pending_approval', assignedBy, assignedAt, approvedAt, revokedAt }
|
|
160
|
+
|
|
161
|
+
const rows = await auth.roles.status(); // GET /auth/roles/status
|
|
162
|
+
// rows = [{ roleName, displayName, status: 'none'|'pending_approval'|'active'|'revoked', accountRoleId, assignedAt, approvedAt, revokedAt }]
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Both need a session. `apply` rejects with `AuthError` whose `code` is `role_already_active` or
|
|
166
|
+
`application_pending` (409) when there is nothing to do, and with a 400 when the role name is not
|
|
167
|
+
on the server's self-applicable allowlist (`ValidationError`, `issues[0].path === 'roleName'`). Approving, revoking, and listing applications are `/admin/*` endpoints and are
|
|
168
|
+
deliberately not part of this SDK; an admin surface such as the Baliola Console calls them with
|
|
169
|
+
its own client.
|
|
170
|
+
|
|
126
171
|
### Profile (identity read)
|
|
127
172
|
|
|
128
173
|
```ts
|
|
@@ -196,6 +241,8 @@ import {
|
|
|
196
241
|
RateLimitedError,
|
|
197
242
|
InvalidPasswordError,
|
|
198
243
|
InvalidEmailError,
|
|
244
|
+
GoogleSignInCancelledError,
|
|
245
|
+
GoogleSignInError,
|
|
199
246
|
} from '@baliola/auth-sdk';
|
|
200
247
|
|
|
201
248
|
try {
|
|
@@ -213,19 +260,22 @@ try {
|
|
|
213
260
|
| Error class | `code` | Status | Carries |
|
|
214
261
|
| ------------------------------ | ---------------------------- | ------ | ------------------------------------------ |
|
|
215
262
|
| `OtpInvalidError` | `otp_invalid` | 400 | `attemptsRemaining`, `canResendInSeconds` |
|
|
216
|
-
| `OtpExpiredError` | `otp_expired` | 400 |
|
|
263
|
+
| `OtpExpiredError` | `otp_expired` | 400 | none |
|
|
217
264
|
| `MaxAttemptsError` | `max_attempts_exceeded` | 429 | `retryAfterSeconds` |
|
|
218
|
-
| `NoPendingOtpError` | `no_pending_otp` | 400 |
|
|
265
|
+
| `NoPendingOtpError` | `no_pending_otp` | 400 | none |
|
|
219
266
|
| `ResendCooldownError` | `resend_cooldown` | 429 | `canResendInSeconds` |
|
|
220
|
-
| `MaxResendsError` | `max_resends_exceeded` | 429 |
|
|
221
|
-
| `InvalidCredentialsError` | `invalid_credentials` | 401 |
|
|
222
|
-
| `NoPasswordSetError` | `no_password_set` | 400 |
|
|
223
|
-
| `AccountSuspendedError` | `account_suspended` | 403 |
|
|
224
|
-
| `EmailAlreadyHasPasswordError` | `email_already_has_password` | 409 |
|
|
225
|
-
| `CaptchaFailedError` | `captcha_failed` | 400 |
|
|
267
|
+
| `MaxResendsError` | `max_resends_exceeded` | 429 | none |
|
|
268
|
+
| `InvalidCredentialsError` | `invalid_credentials` | 401 | none |
|
|
269
|
+
| `NoPasswordSetError` | `no_password_set` | 400 | none |
|
|
270
|
+
| `AccountSuspendedError` | `account_suspended` | 403 | none |
|
|
271
|
+
| `EmailAlreadyHasPasswordError` | `email_already_has_password` | 409 | none |
|
|
272
|
+
| `CaptchaFailedError` | `captcha_failed` | 400 | none |
|
|
226
273
|
| `InvalidPasswordError` | `invalid_password` | 400 | `reason: 'too_short'\|'no_uppercase'\|...` |
|
|
227
|
-
| `InvalidEmailError` | `invalid_email` | 400 |
|
|
274
|
+
| `InvalidEmailError` | `invalid_email` | 400 | none |
|
|
228
275
|
| `RateLimitedError` | (legacy 429) | 429 | `retryAfterSeconds`, `retryAfterHuman` |
|
|
276
|
+
| `GoogleSignInCancelledError` | `oauth_cancelled` | 0 | `reason: 'popup_blocked'\|'popup_closed'\|'access_denied'` |
|
|
277
|
+
| `GoogleSignInError` | `invalid_google_code`, `email_unverified`, `invalid_oauth_state`, `oauth_unexpected`, `oauth_nonce_mismatch` | 401 / 400 / 0 | none |
|
|
278
|
+
| `ValidationError` | `validation_error` | 400 | `issues: { path, message }[]` |
|
|
229
279
|
| `AuthError` (base) | varies | varies | `status: 0` for network/timeout |
|
|
230
280
|
|
|
231
281
|
## Stores
|
|
@@ -249,7 +299,7 @@ Cross-tab sync (login / logout / refresh) is automatic via `BroadcastChannel`, r
|
|
|
249
299
|
```ts
|
|
250
300
|
createAuthClient({
|
|
251
301
|
baseUrl: AUTH_URL, // required, no trailing slash
|
|
252
|
-
clientId: 'your-project-client-id', //
|
|
302
|
+
clientId: 'your-project-client-id', // required; sent on every login and register body
|
|
253
303
|
store: memoryStore(), // default; or localStorageStore() / custom
|
|
254
304
|
fetch: globalThis.fetch, // override for tests / interceptors
|
|
255
305
|
timeoutMs: 15_000, // per-request, default 15s
|
|
@@ -258,7 +308,8 @@ createAuthClient({
|
|
|
258
308
|
});
|
|
259
309
|
```
|
|
260
310
|
|
|
261
|
-
`clientId` is constructor-only
|
|
311
|
+
`clientId` is constructor-only, there is no per-call override. To switch projects, create a new client.
|
|
312
|
+
`createAuthClient` throws a plain `Error` when `clientId` is missing or empty, the same way it does for `baseUrl`.
|
|
262
313
|
|
|
263
314
|
## Decoding the JWT
|
|
264
315
|
|
|
@@ -272,7 +323,7 @@ const session = auth.getSession();
|
|
|
272
323
|
if (session) {
|
|
273
324
|
const claims = decodeJwt<AccessTokenPayload>(session.accessToken);
|
|
274
325
|
// claims.accountId, claims.email
|
|
275
|
-
// claims.projects: { id, name, clientId }[] //
|
|
326
|
+
// claims.projects: { id, name, clientId }[] // the project the login was scoped to; the Console client also carries global roles
|
|
276
327
|
// claims.roles?: string[]; claims.permissions?: string[]
|
|
277
328
|
}
|
|
278
329
|
```
|
|
@@ -285,8 +336,6 @@ if (session) {
|
|
|
285
336
|
|
|
286
337
|
```json
|
|
287
338
|
{
|
|
288
|
-
"flow": "signup",
|
|
289
|
-
"methods": ["passwordless"],
|
|
290
339
|
"otp": {
|
|
291
340
|
"expiresInSeconds": 300,
|
|
292
341
|
"expiresAt": "2026-05-04T12:05:00.000Z",
|
|
@@ -309,7 +358,7 @@ if (session) {
|
|
|
309
358
|
}
|
|
310
359
|
```
|
|
311
360
|
|
|
312
|
-
**`auth.emailOtp.verifyLoginCode` / `auth.emailPassword.verifyRegistrationCode` / `auth.emailPassword.login` / `auth.google.login` success (`AuthSession`):**
|
|
361
|
+
**`auth.emailOtp.verifyLoginCode` / `auth.emailPassword.verifyRegistrationCode` / `auth.emailPassword.login` / `auth.google.login` / `auth.google.exchange` success (`AuthSession`):**
|
|
313
362
|
|
|
314
363
|
```json
|
|
315
364
|
{
|
|
@@ -332,6 +381,38 @@ if (session) {
|
|
|
332
381
|
}
|
|
333
382
|
```
|
|
334
383
|
|
|
384
|
+
**`auth.roles.apply` success (`RoleApplicationStatus`, HTTP 201):**
|
|
385
|
+
|
|
386
|
+
```json
|
|
387
|
+
{
|
|
388
|
+
"id": "6f1c2d3e-0000-4000-8000-000000000001",
|
|
389
|
+
"accountId": "6f1c2d3e-0000-4000-8000-0000000000aa",
|
|
390
|
+
"roleId": "6f1c2d3e-0000-4000-8000-0000000000bb",
|
|
391
|
+
"projectId": null,
|
|
392
|
+
"status": "pending_approval",
|
|
393
|
+
"assignedBy": null,
|
|
394
|
+
"assignedAt": "2026-09-04T00:00:00.000Z",
|
|
395
|
+
"approvedAt": null,
|
|
396
|
+
"revokedAt": null
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
**`auth.roles.status` success (`RoleStatus[]`):**
|
|
401
|
+
|
|
402
|
+
```json
|
|
403
|
+
[
|
|
404
|
+
{
|
|
405
|
+
"roleName": "module_deployer",
|
|
406
|
+
"displayName": "Module Deployer",
|
|
407
|
+
"status": "none",
|
|
408
|
+
"accountRoleId": null,
|
|
409
|
+
"assignedAt": null,
|
|
410
|
+
"approvedAt": null,
|
|
411
|
+
"revokedAt": null
|
|
412
|
+
}
|
|
413
|
+
]
|
|
414
|
+
```
|
|
415
|
+
|
|
335
416
|
**Verify-code failure (e.g. `OtpInvalidError`):**
|
|
336
417
|
|
|
337
418
|
```json
|
|
@@ -349,6 +430,19 @@ if (session) {
|
|
|
349
430
|
}
|
|
350
431
|
```
|
|
351
432
|
|
|
433
|
+
**`auth.google.exchange` failure (`GoogleSignInError`, 401):**
|
|
434
|
+
|
|
435
|
+
```json
|
|
436
|
+
{
|
|
437
|
+
"message": "Invalid or expired login code",
|
|
438
|
+
"data": null,
|
|
439
|
+
"error": {
|
|
440
|
+
"code": "invalid_google_code",
|
|
441
|
+
"details": { "name": "UnauthorizedError", "requestId": "..." }
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
352
446
|
## License
|
|
353
447
|
|
|
354
448
|
Proprietary — see [LICENSE](./LICENSE).
|
|
@@ -131,6 +131,54 @@ var InvalidEmailError = class extends AuthError {
|
|
|
131
131
|
this.name = "InvalidEmailError";
|
|
132
132
|
}
|
|
133
133
|
};
|
|
134
|
+
/**
|
|
135
|
+
* The hosted Google sign-in ended without a session because of the user or
|
|
136
|
+
* the browser: the popup was blocked, the popup was closed early, or the
|
|
137
|
+
* user cancelled on Google's account chooser. `code` is always
|
|
138
|
+
* `oauth_cancelled`; branch on `reason` for the specific cause.
|
|
139
|
+
*/
|
|
140
|
+
var GoogleSignInCancelledError = class extends AuthError {
|
|
141
|
+
reason;
|
|
142
|
+
constructor(init) {
|
|
143
|
+
super({
|
|
144
|
+
status: 0,
|
|
145
|
+
code: "oauth_cancelled",
|
|
146
|
+
serverMessage: `Google sign-in cancelled: ${init.reason}`,
|
|
147
|
+
...init.cause !== void 0 && { cause: init.cause }
|
|
148
|
+
});
|
|
149
|
+
this.name = "GoogleSignInCancelledError";
|
|
150
|
+
this.reason = init.reason;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* The hosted Google sign-in failed. `code` is the failure code the exit or
|
|
155
|
+
* the exchange returned: `invalid_oauth_state`, `invalid_google_code`,
|
|
156
|
+
* `email_unverified`, `oauth_unexpected`, or the SDK-side
|
|
157
|
+
* `oauth_nonce_mismatch`. `status` is the HTTP status when the exchange
|
|
158
|
+
* request failed, otherwise `0`.
|
|
159
|
+
*/
|
|
160
|
+
var GoogleSignInError = class extends AuthError {
|
|
161
|
+
constructor(init) {
|
|
162
|
+
super({
|
|
163
|
+
...init,
|
|
164
|
+
status: init.status ?? 0,
|
|
165
|
+
serverMessage: init.serverMessage ?? `Google sign-in failed: ${init.code}`
|
|
166
|
+
});
|
|
167
|
+
this.name = "GoogleSignInError";
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* Request validation failed. Thrown for `validation_error` (400) on any
|
|
172
|
+
* endpoint; `issues` names each rejected field.
|
|
173
|
+
*/
|
|
174
|
+
var ValidationError = class extends AuthError {
|
|
175
|
+
issues;
|
|
176
|
+
constructor(init) {
|
|
177
|
+
super(init);
|
|
178
|
+
this.name = "ValidationError";
|
|
179
|
+
this.issues = init.issues;
|
|
180
|
+
}
|
|
181
|
+
};
|
|
134
182
|
function num(d, key, fallback = 0) {
|
|
135
183
|
const v = d?.[key];
|
|
136
184
|
return typeof v === "number" ? v : fallback;
|
|
@@ -139,6 +187,21 @@ function str(d, key, fallback = "") {
|
|
|
139
187
|
const v = d?.[key];
|
|
140
188
|
return typeof v === "string" ? v : fallback;
|
|
141
189
|
}
|
|
190
|
+
function issues(d) {
|
|
191
|
+
const raw = d?.["issues"];
|
|
192
|
+
if (!Array.isArray(raw)) return [];
|
|
193
|
+
const out = [];
|
|
194
|
+
for (const entry of raw) {
|
|
195
|
+
if (typeof entry !== "object" || entry === null) continue;
|
|
196
|
+
const record = entry;
|
|
197
|
+
if (typeof record["path"] !== "string" || typeof record["message"] !== "string") continue;
|
|
198
|
+
out.push({
|
|
199
|
+
path: record["path"],
|
|
200
|
+
message: record["message"]
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
return out;
|
|
204
|
+
}
|
|
142
205
|
/**
|
|
143
206
|
* Map a backend error response onto the right AuthError subclass.
|
|
144
207
|
* Falls back to `AuthError` (with status + code preserved) for unknown codes.
|
|
@@ -189,6 +252,15 @@ async function authErrorFromResponse(response) {
|
|
|
189
252
|
});
|
|
190
253
|
}
|
|
191
254
|
case "invalid_email": return new InvalidEmailError(init);
|
|
255
|
+
case "invalid_google_code":
|
|
256
|
+
case "email_unverified": return new GoogleSignInError({
|
|
257
|
+
...init,
|
|
258
|
+
code
|
|
259
|
+
});
|
|
260
|
+
case "validation_error": return new ValidationError({
|
|
261
|
+
...init,
|
|
262
|
+
issues: issues(details)
|
|
263
|
+
});
|
|
192
264
|
default:
|
|
193
265
|
if (response.status === 429) {
|
|
194
266
|
const retryAfterSeconds = num(details, "retryAfter") || num(details, "retryAfterSeconds") || Number(response.headers.get("Retry-After") ?? 0);
|
|
@@ -212,4 +284,4 @@ function authErrorFromFetchFailure(cause, isTimeout = false) {
|
|
|
212
284
|
});
|
|
213
285
|
}
|
|
214
286
|
//#endregion
|
|
215
|
-
export {
|
|
287
|
+
export { ResendCooldownError as _, GoogleSignInCancelledError as a, authErrorFromResponse as b, InvalidEmailError as c, MaxResendsError as d, NoPasswordSetError as f, RateLimitedError as g, OtpInvalidError as h, EmailAlreadyHasPasswordError as i, InvalidPasswordError as l, OtpExpiredError as m, AuthError as n, GoogleSignInError as o, NoPendingOtpError as p, CaptchaFailedError as r, InvalidCredentialsError as s, AccountSuspendedError as t, MaxAttemptsError as u, ValidationError as v, authErrorFromFetchFailure as y };
|
|
@@ -92,6 +92,47 @@ declare class InvalidPasswordError extends AuthError {
|
|
|
92
92
|
declare class InvalidEmailError extends AuthError {
|
|
93
93
|
constructor(init: AuthErrorInit);
|
|
94
94
|
}
|
|
95
|
+
type GoogleSignInCancelledReason = 'popup_blocked' | 'popup_closed' | 'access_denied';
|
|
96
|
+
/**
|
|
97
|
+
* The hosted Google sign-in ended without a session because of the user or
|
|
98
|
+
* the browser: the popup was blocked, the popup was closed early, or the
|
|
99
|
+
* user cancelled on Google's account chooser. `code` is always
|
|
100
|
+
* `oauth_cancelled`; branch on `reason` for the specific cause.
|
|
101
|
+
*/
|
|
102
|
+
declare class GoogleSignInCancelledError extends AuthError {
|
|
103
|
+
readonly reason: GoogleSignInCancelledReason;
|
|
104
|
+
constructor(init: {
|
|
105
|
+
reason: GoogleSignInCancelledReason;
|
|
106
|
+
cause?: unknown;
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* The hosted Google sign-in failed. `code` is the failure code the exit or
|
|
111
|
+
* the exchange returned: `invalid_oauth_state`, `invalid_google_code`,
|
|
112
|
+
* `email_unverified`, `oauth_unexpected`, or the SDK-side
|
|
113
|
+
* `oauth_nonce_mismatch`. `status` is the HTTP status when the exchange
|
|
114
|
+
* request failed, otherwise `0`.
|
|
115
|
+
*/
|
|
116
|
+
declare class GoogleSignInError extends AuthError {
|
|
117
|
+
constructor(init: {
|
|
118
|
+
code: string;
|
|
119
|
+
} & Partial<AuthErrorInit>);
|
|
120
|
+
}
|
|
121
|
+
/** One failing request field, as reported by the server's validation hook. */
|
|
122
|
+
type ValidationIssue = {
|
|
123
|
+
/** Dot-joined path of the field, for example `clientId` or `otp`. */path: string;
|
|
124
|
+
message: string;
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Request validation failed. Thrown for `validation_error` (400) on any
|
|
128
|
+
* endpoint; `issues` names each rejected field.
|
|
129
|
+
*/
|
|
130
|
+
declare class ValidationError extends AuthError {
|
|
131
|
+
readonly issues: ValidationIssue[];
|
|
132
|
+
constructor(init: AuthErrorInit & {
|
|
133
|
+
issues: ValidationIssue[];
|
|
134
|
+
});
|
|
135
|
+
}
|
|
95
136
|
/**
|
|
96
137
|
* Map a backend error response onto the right AuthError subclass.
|
|
97
138
|
* Falls back to `AuthError` (with status + code preserved) for unknown codes.
|
|
@@ -100,4 +141,4 @@ declare function authErrorFromResponse(response: Response): Promise<AuthError>;
|
|
|
100
141
|
/** Network/timeout failures land here. */
|
|
101
142
|
declare function authErrorFromFetchFailure(cause: unknown, isTimeout?: boolean): AuthError;
|
|
102
143
|
//#endregion
|
|
103
|
-
export { authErrorFromFetchFailure as _, EmailAlreadyHasPasswordError as a,
|
|
144
|
+
export { authErrorFromResponse as C, authErrorFromFetchFailure as S, OtpInvalidError as _, EmailAlreadyHasPasswordError as a, ValidationError as b, GoogleSignInError as c, InvalidPasswordError as d, MaxAttemptsError as f, OtpExpiredError as g, NoPendingOtpError as h, CaptchaFailedError as i, InvalidCredentialsError as l, NoPasswordSetError as m, AuthError as n, GoogleSignInCancelledError as o, MaxResendsError as p, AuthErrorInit as r, GoogleSignInCancelledReason as s, AccountSuspendedError as t, InvalidEmailError as u, RateLimitedError as v, ValidationIssue as x, ResendCooldownError as y };
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as GoogleNamespace, c as
|
|
2
|
-
export { AuthClient, AuthFetchInit, CreateAuthClientOptions, EmailOtpNamespace, EmailPasswordNamespace, GoogleNamespace, ProactiveRefreshConfig, SubscribeOptions, WalletNamespace, createAuthClient };
|
|
1
|
+
import { a as GoogleNamespace, c as SubscribeOptions, d as AuthFetchInit, i as EmailPasswordNamespace, l as WalletNamespace, n as CreateAuthClientOptions, o as ProactiveRefreshConfig, r as EmailOtpNamespace, s as RolesNamespace, t as AuthClient, u as createAuthClient } from "../index-DwFEdFaS.js";
|
|
2
|
+
export { AuthClient, AuthFetchInit, CreateAuthClientOptions, EmailOtpNamespace, EmailPasswordNamespace, GoogleNamespace, ProactiveRefreshConfig, RolesNamespace, SubscribeOptions, WalletNamespace, createAuthClient };
|
package/dist/client/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createAuthClient } from "../client-
|
|
1
|
+
import { t as createAuthClient } from "../client-Dlhhdp-T.js";
|
|
2
2
|
export { createAuthClient };
|
|
@@ -1,5 +1,142 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as GoogleSignInCancelledError, b as authErrorFromResponse, n as AuthError, o as GoogleSignInError, y as authErrorFromFetchFailure } from "./authError-BPxMHQK2.js";
|
|
2
2
|
import { n as memoryStore } from "./sessionStore-DD6lON9W.js";
|
|
3
|
+
//#region src/client/googleHosted.ts
|
|
4
|
+
const NONCE_STORAGE_KEY = "baliola-auth:google:nonce";
|
|
5
|
+
const MESSAGE_TYPE = "baliola-auth:google";
|
|
6
|
+
const POPUP_WINDOW_NAME = "baliola-auth-google";
|
|
7
|
+
const DEFAULT_POPUP_WIDTH = 500;
|
|
8
|
+
const DEFAULT_POPUP_HEIGHT = 640;
|
|
9
|
+
const POPUP_POLL_INTERVAL_MS = 500;
|
|
10
|
+
function browserWindow() {
|
|
11
|
+
return typeof globalThis.window === "undefined" ? null : globalThis.window;
|
|
12
|
+
}
|
|
13
|
+
function requireBrowserWindow(method) {
|
|
14
|
+
const win = browserWindow();
|
|
15
|
+
if (!win) throw new Error(`google.${method}: only available in a browser (window is undefined)`);
|
|
16
|
+
return win;
|
|
17
|
+
}
|
|
18
|
+
function parseExitMessage(data) {
|
|
19
|
+
if (typeof data !== "object" || data === null) return null;
|
|
20
|
+
const record = data;
|
|
21
|
+
if (record["type"] !== MESSAGE_TYPE) return null;
|
|
22
|
+
const nonce = record["nonce"];
|
|
23
|
+
return {
|
|
24
|
+
nonce: typeof nonce === "string" ? nonce : null,
|
|
25
|
+
...typeof record["code"] === "string" && { code: record["code"] },
|
|
26
|
+
...typeof record["error"] === "string" && { error: record["error"] }
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function exitError(code) {
|
|
30
|
+
if (code === "access_denied") return new GoogleSignInCancelledError({ reason: "access_denied" });
|
|
31
|
+
return new GoogleSignInError({ code });
|
|
32
|
+
}
|
|
33
|
+
function createGoogleHosted(ctx) {
|
|
34
|
+
const authOrigin = new URL(ctx.baseUrl).origin;
|
|
35
|
+
function resolveReturnTo(returnTo) {
|
|
36
|
+
if (returnTo !== void 0 && /^https?:\/\//i.test(returnTo)) return returnTo;
|
|
37
|
+
const win = browserWindow();
|
|
38
|
+
if (!win) throw new Error("google.startUrl: returnTo must be an absolute URL outside a browser (window is undefined)");
|
|
39
|
+
if (returnTo === void 0) {
|
|
40
|
+
const current = new URL(win.location.href);
|
|
41
|
+
current.hash = "";
|
|
42
|
+
return current.toString();
|
|
43
|
+
}
|
|
44
|
+
return new URL(returnTo, win.location.href).toString();
|
|
45
|
+
}
|
|
46
|
+
function saveRedirectNonce(nonce) {
|
|
47
|
+
if (typeof globalThis.sessionStorage === "undefined") throw new Error("google.startUrl: sessionStorage is required for redirect mode");
|
|
48
|
+
globalThis.sessionStorage.setItem(NONCE_STORAGE_KEY, nonce);
|
|
49
|
+
}
|
|
50
|
+
function startUrl(opts) {
|
|
51
|
+
const url = new URL(`${ctx.baseUrl}/auth/google/start`);
|
|
52
|
+
url.searchParams.set("clientId", ctx.clientId);
|
|
53
|
+
url.searchParams.set("returnTo", resolveReturnTo(opts.returnTo));
|
|
54
|
+
url.searchParams.set("mode", opts.mode);
|
|
55
|
+
url.searchParams.set("nonce", opts.nonce);
|
|
56
|
+
if (opts.mode === "redirect") saveRedirectNonce(opts.nonce);
|
|
57
|
+
return url.toString();
|
|
58
|
+
}
|
|
59
|
+
function signInWithPopup(opts = {}) {
|
|
60
|
+
return new Promise((resolve, reject) => {
|
|
61
|
+
const win = requireBrowserWindow("signInWithPopup");
|
|
62
|
+
const nonce = crypto.randomUUID();
|
|
63
|
+
const url = startUrl({
|
|
64
|
+
mode: "popup",
|
|
65
|
+
nonce,
|
|
66
|
+
...opts.returnTo !== void 0 && { returnTo: opts.returnTo }
|
|
67
|
+
});
|
|
68
|
+
const width = opts.popup?.width ?? DEFAULT_POPUP_WIDTH;
|
|
69
|
+
const height = opts.popup?.height ?? DEFAULT_POPUP_HEIGHT;
|
|
70
|
+
const popup = win.open(url, POPUP_WINDOW_NAME, `popup,width=${width},height=${height}`);
|
|
71
|
+
if (!popup) {
|
|
72
|
+
reject(new GoogleSignInCancelledError({ reason: "popup_blocked" }));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
let settled = false;
|
|
76
|
+
let closeTimer = null;
|
|
77
|
+
const cleanup = () => {
|
|
78
|
+
settled = true;
|
|
79
|
+
win.removeEventListener("message", onMessage);
|
|
80
|
+
clearInterval(pollTimer);
|
|
81
|
+
if (closeTimer !== null) clearTimeout(closeTimer);
|
|
82
|
+
};
|
|
83
|
+
const onMessage = (event) => {
|
|
84
|
+
if (settled || event.origin !== authOrigin) return;
|
|
85
|
+
const message = parseExitMessage(event.data);
|
|
86
|
+
if (!message || message.nonce !== nonce) return;
|
|
87
|
+
cleanup();
|
|
88
|
+
if (message.code !== void 0) {
|
|
89
|
+
ctx.exchange({ code: message.code }).then(resolve, reject);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
reject(exitError(message.error ?? "oauth_unexpected"));
|
|
93
|
+
};
|
|
94
|
+
const pollTimer = setInterval(() => {
|
|
95
|
+
if (settled || !popup.closed || closeTimer !== null) return;
|
|
96
|
+
closeTimer = setTimeout(() => {
|
|
97
|
+
if (settled) return;
|
|
98
|
+
cleanup();
|
|
99
|
+
reject(new GoogleSignInCancelledError({ reason: "popup_closed" }));
|
|
100
|
+
}, POPUP_POLL_INTERVAL_MS);
|
|
101
|
+
}, POPUP_POLL_INTERVAL_MS);
|
|
102
|
+
win.addEventListener("message", onMessage);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function takeRedirectNonce() {
|
|
106
|
+
if (typeof globalThis.sessionStorage === "undefined") return null;
|
|
107
|
+
const saved = globalThis.sessionStorage.getItem(NONCE_STORAGE_KEY);
|
|
108
|
+
globalThis.sessionStorage.removeItem(NONCE_STORAGE_KEY);
|
|
109
|
+
return saved;
|
|
110
|
+
}
|
|
111
|
+
function stripExitParams(url) {
|
|
112
|
+
for (const key of [
|
|
113
|
+
"code",
|
|
114
|
+
"error",
|
|
115
|
+
"nonce"
|
|
116
|
+
]) url.searchParams.delete(key);
|
|
117
|
+
if (typeof globalThis.history === "undefined") return;
|
|
118
|
+
globalThis.history.replaceState(globalThis.history.state, "", url.toString());
|
|
119
|
+
}
|
|
120
|
+
async function completeRedirect(opts = {}) {
|
|
121
|
+
const win = requireBrowserWindow("completeRedirect");
|
|
122
|
+
const url = new URL(opts.url ?? win.location.href);
|
|
123
|
+
const code = url.searchParams.get("code");
|
|
124
|
+
const error = url.searchParams.get("error");
|
|
125
|
+
if (code === null && error === null) return null;
|
|
126
|
+
const nonce = url.searchParams.get("nonce");
|
|
127
|
+
const saved = takeRedirectNonce();
|
|
128
|
+
stripExitParams(url);
|
|
129
|
+
if (saved === null || nonce !== saved) throw new GoogleSignInError({ code: "oauth_nonce_mismatch" });
|
|
130
|
+
if (code === null) throw exitError(error ?? "oauth_unexpected");
|
|
131
|
+
return ctx.exchange({ code });
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
startUrl,
|
|
135
|
+
signInWithPopup,
|
|
136
|
+
completeRedirect
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
//#endregion
|
|
3
140
|
//#region src/client/methods.ts
|
|
4
141
|
function toAuthSession(data) {
|
|
5
142
|
const issuedAt = Date.now();
|
|
@@ -16,13 +153,10 @@ function toAuthSession(data) {
|
|
|
16
153
|
};
|
|
17
154
|
}
|
|
18
155
|
function createMethods(ctx) {
|
|
19
|
-
const withClientId = (body) => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
clientId: ctx.clientId
|
|
24
|
-
};
|
|
25
|
-
};
|
|
156
|
+
const withClientId = (body) => ({
|
|
157
|
+
...body,
|
|
158
|
+
clientId: ctx.clientId
|
|
159
|
+
});
|
|
26
160
|
return {
|
|
27
161
|
/** emailOtp.* (passwordless) */
|
|
28
162
|
async sendLoginCode(input) {
|
|
@@ -130,7 +264,15 @@ function createMethods(ctx) {
|
|
|
130
264
|
path: "/auth/google/login",
|
|
131
265
|
method: "POST",
|
|
132
266
|
authMode: "none",
|
|
133
|
-
body: withClientId(
|
|
267
|
+
body: withClientId({ idToken: input.idToken })
|
|
268
|
+
}));
|
|
269
|
+
},
|
|
270
|
+
async googleExchange(input) {
|
|
271
|
+
return toAuthSession(await ctx.transport.request({
|
|
272
|
+
path: "/auth/google/exchange",
|
|
273
|
+
method: "POST",
|
|
274
|
+
authMode: "none",
|
|
275
|
+
body: { code: input.code }
|
|
134
276
|
}));
|
|
135
277
|
},
|
|
136
278
|
/** wallet.* */
|
|
@@ -149,6 +291,22 @@ function createMethods(ctx) {
|
|
|
149
291
|
body: { hash }
|
|
150
292
|
});
|
|
151
293
|
},
|
|
294
|
+
/** roles.* */
|
|
295
|
+
async applyRole(input) {
|
|
296
|
+
return ctx.transport.request({
|
|
297
|
+
path: "/auth/roles/apply",
|
|
298
|
+
method: "POST",
|
|
299
|
+
authMode: "bearer+session",
|
|
300
|
+
body: { roleName: input.roleName }
|
|
301
|
+
});
|
|
302
|
+
},
|
|
303
|
+
async getRoleStatus() {
|
|
304
|
+
return ctx.transport.request({
|
|
305
|
+
path: "/auth/roles/status",
|
|
306
|
+
method: "GET",
|
|
307
|
+
authMode: "bearer+session"
|
|
308
|
+
});
|
|
309
|
+
},
|
|
152
310
|
/** profile */
|
|
153
311
|
async getProfile() {
|
|
154
312
|
return ctx.transport.request({
|
|
@@ -381,7 +539,9 @@ const DEFAULT_PROACTIVE_LEAD_TIME_MS = 6e4;
|
|
|
381
539
|
const BROADCAST_CHANNEL_NAME = "baliola.auth.session.v1";
|
|
382
540
|
function createAuthClient(options) {
|
|
383
541
|
if (!options.baseUrl) throw new Error("createAuthClient: baseUrl is required");
|
|
542
|
+
if (!options.clientId) throw new Error("createAuthClient: clientId is required");
|
|
384
543
|
const baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
544
|
+
const clientId = options.clientId;
|
|
385
545
|
const store = options.store ?? memoryStore();
|
|
386
546
|
const fetchImpl = options.fetch ?? ((input, init) => globalThis.fetch(input, init));
|
|
387
547
|
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
@@ -439,39 +599,61 @@ function createAuthClient(options) {
|
|
|
439
599
|
});
|
|
440
600
|
const methods = createMethods({
|
|
441
601
|
transport,
|
|
442
|
-
|
|
602
|
+
clientId
|
|
443
603
|
});
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
return session;
|
|
451
|
-
},
|
|
452
|
-
resendLoginCode: (input) => methods.resendLoginCode(input)
|
|
604
|
+
const emailOtp = {
|
|
605
|
+
sendLoginCode: (input) => methods.sendLoginCode(input),
|
|
606
|
+
async verifyLoginCode(input) {
|
|
607
|
+
const session = await methods.verifyLoginCode(input);
|
|
608
|
+
await setSession(session);
|
|
609
|
+
return session;
|
|
453
610
|
},
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
611
|
+
resendLoginCode: (input) => methods.resendLoginCode(input)
|
|
612
|
+
};
|
|
613
|
+
const emailPassword = {
|
|
614
|
+
register: (input) => methods.register(input),
|
|
615
|
+
async verifyRegistrationCode(input) {
|
|
616
|
+
const session = await methods.verifyRegistrationCode(input);
|
|
617
|
+
await setSession(session);
|
|
618
|
+
return session;
|
|
619
|
+
},
|
|
620
|
+
resendRegistrationCode: (input) => methods.resendRegistrationCode(input),
|
|
621
|
+
async login(input) {
|
|
622
|
+
const session = await methods.loginWithPassword(input);
|
|
623
|
+
await setSession(session);
|
|
624
|
+
return session;
|
|
625
|
+
},
|
|
626
|
+
setPassword: (input) => methods.setPassword(input),
|
|
627
|
+
changePassword: (input) => methods.changePassword(input)
|
|
628
|
+
};
|
|
629
|
+
async function googleExchange(input) {
|
|
630
|
+
const session = await methods.googleExchange(input);
|
|
631
|
+
await setSession(session);
|
|
632
|
+
return session;
|
|
633
|
+
}
|
|
634
|
+
const googleHosted = createGoogleHosted({
|
|
635
|
+
baseUrl,
|
|
636
|
+
clientId,
|
|
637
|
+
exchange: googleExchange
|
|
638
|
+
});
|
|
639
|
+
return {
|
|
640
|
+
emailOtp,
|
|
641
|
+
emailPassword,
|
|
642
|
+
google: {
|
|
462
643
|
async login(input) {
|
|
463
|
-
const session = await methods.
|
|
644
|
+
const session = await methods.loginWithGoogle(input);
|
|
464
645
|
await setSession(session);
|
|
465
646
|
return session;
|
|
466
647
|
},
|
|
467
|
-
|
|
468
|
-
|
|
648
|
+
startUrl: (opts) => googleHosted.startUrl(opts),
|
|
649
|
+
exchange: googleExchange,
|
|
650
|
+
signInWithPopup: (opts) => googleHosted.signInWithPopup(opts),
|
|
651
|
+
completeRedirect: (opts) => googleHosted.completeRedirect(opts)
|
|
652
|
+
},
|
|
653
|
+
roles: {
|
|
654
|
+
apply: (input) => methods.applyRole(input),
|
|
655
|
+
status: () => methods.getRoleStatus()
|
|
469
656
|
},
|
|
470
|
-
google: { async login(input) {
|
|
471
|
-
const session = await methods.loginWithGoogle(input);
|
|
472
|
-
await setSession(session);
|
|
473
|
-
return session;
|
|
474
|
-
} },
|
|
475
657
|
wallet: {
|
|
476
658
|
getAddress: async () => (await methods.getWalletAddress()).address,
|
|
477
659
|
signHash: async (hash) => (await methods.signWalletHash(hash)).signature
|
package/dist/errors/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { AccountSuspendedError, AuthError, type AuthErrorInit, CaptchaFailedError, EmailAlreadyHasPasswordError, InvalidCredentialsError, InvalidEmailError, InvalidPasswordError, MaxAttemptsError, MaxResendsError, NoPasswordSetError, NoPendingOtpError, OtpExpiredError, OtpInvalidError, RateLimitedError, ResendCooldownError, authErrorFromFetchFailure, authErrorFromResponse };
|
|
1
|
+
import { C as authErrorFromResponse, S as authErrorFromFetchFailure, _ as OtpInvalidError, a as EmailAlreadyHasPasswordError, b as ValidationError, c as GoogleSignInError, d as InvalidPasswordError, f as MaxAttemptsError, g as OtpExpiredError, h as NoPendingOtpError, i as CaptchaFailedError, l as InvalidCredentialsError, m as NoPasswordSetError, n as AuthError, o as GoogleSignInCancelledError, p as MaxResendsError, r as AuthErrorInit, s as GoogleSignInCancelledReason, t as AccountSuspendedError, u as InvalidEmailError, v as RateLimitedError, x as ValidationIssue, y as ResendCooldownError } from "../authError-E11ZMcID.js";
|
|
2
|
+
export { AccountSuspendedError, AuthError, type AuthErrorInit, CaptchaFailedError, EmailAlreadyHasPasswordError, GoogleSignInCancelledError, type GoogleSignInCancelledReason, GoogleSignInError, InvalidCredentialsError, InvalidEmailError, InvalidPasswordError, MaxAttemptsError, MaxResendsError, NoPasswordSetError, NoPendingOtpError, OtpExpiredError, OtpInvalidError, RateLimitedError, ResendCooldownError, ValidationError, type ValidationIssue, authErrorFromFetchFailure, authErrorFromResponse };
|
package/dist/errors/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
export { AccountSuspendedError, AuthError, CaptchaFailedError, EmailAlreadyHasPasswordError, InvalidCredentialsError, InvalidEmailError, InvalidPasswordError, MaxAttemptsError, MaxResendsError, NoPasswordSetError, NoPendingOtpError, OtpExpiredError, OtpInvalidError, RateLimitedError, ResendCooldownError, authErrorFromFetchFailure, authErrorFromResponse };
|
|
1
|
+
import { _ as ResendCooldownError, a as GoogleSignInCancelledError, b as authErrorFromResponse, c as InvalidEmailError, d as MaxResendsError, f as NoPasswordSetError, g as RateLimitedError, h as OtpInvalidError, i as EmailAlreadyHasPasswordError, l as InvalidPasswordError, m as OtpExpiredError, n as AuthError, o as GoogleSignInError, p as NoPendingOtpError, r as CaptchaFailedError, s as InvalidCredentialsError, t as AccountSuspendedError, u as MaxAttemptsError, v as ValidationError, y as authErrorFromFetchFailure } from "../authError-BPxMHQK2.js";
|
|
2
|
+
export { AccountSuspendedError, AuthError, CaptchaFailedError, EmailAlreadyHasPasswordError, GoogleSignInCancelledError, GoogleSignInError, InvalidCredentialsError, InvalidEmailError, InvalidPasswordError, MaxAttemptsError, MaxResendsError, NoPasswordSetError, NoPendingOtpError, OtpExpiredError, OtpInvalidError, RateLimitedError, ResendCooldownError, ValidationError, authErrorFromFetchFailure, authErrorFromResponse };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as ResendCodeResult, l as SendLoginCodeResult, n as AuthSession, r as ErrorHandler, s as RegisterResult, u as SessionChangeHandler } from "./session-
|
|
2
|
-
import { n as SessionStore } from "./sessionStore-
|
|
3
|
-
import {
|
|
1
|
+
import { c as ResendCodeResult, l as SendLoginCodeResult, n as AuthSession, r as ErrorHandler, s as RegisterResult, u as SessionChangeHandler } from "./session-flM0yXx2.js";
|
|
2
|
+
import { n as SessionStore } from "./sessionStore-D2kXjvNM.js";
|
|
3
|
+
import { C as ProfileResult, _ as SendLoginCodeInput, b as VerifyRegistrationCodeInput, c as GoogleExchangeInput, d as GoogleStartOptions, f as LoginWithGoogleInput, g as ResendRegistrationCodeInput, h as ResendLoginCodeInput, i as RoleStatus, l as GoogleSignInWithPopupOptions, m as RegisterInput, o as ChangePasswordInput, p as LoginWithPasswordInput, r as RoleApplicationStatus, s as GoogleCompleteRedirectOptions, t as ApplyRoleInput, v as SetPasswordInput, y as VerifyLoginCodeInput } from "./roles-BZecOymZ.js";
|
|
4
4
|
|
|
5
5
|
//#region src/client/transport.d.ts
|
|
6
6
|
type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
@@ -31,8 +31,13 @@ type ProactiveRefreshConfig = false | {
|
|
|
31
31
|
/** Refresh proactively if `expiresAt - now < leadTimeMs`. Defaults to 60_000 (60s). */leadTimeMs?: number;
|
|
32
32
|
};
|
|
33
33
|
type CreateAuthClientOptions = {
|
|
34
|
-
/** Base URL of the Baliola Auth server (no trailing slash). */baseUrl: string;
|
|
35
|
-
|
|
34
|
+
/** Base URL of the Baliola Auth server (no trailing slash). */baseUrl: string;
|
|
35
|
+
/**
|
|
36
|
+
* The project's client id. Sent on every login and register body and used
|
|
37
|
+
* to build the hosted Google login URL. baliola-auth rejects login and
|
|
38
|
+
* register requests without one.
|
|
39
|
+
*/
|
|
40
|
+
clientId: string;
|
|
36
41
|
/**
|
|
37
42
|
* Pluggable session store. Defaults to `memoryStore()`. Use
|
|
38
43
|
* `localStorageStore()` in browsers for persistence across reloads.
|
|
@@ -65,10 +70,12 @@ type EmailOtpNamespace = {
|
|
|
65
70
|
* Send a 6-digit one-time code to the email. Used for passwordless
|
|
66
71
|
* login (existing accounts) or signup (creates a new account on verify).
|
|
67
72
|
*
|
|
73
|
+
* The response never says whether the email is registered; the login
|
|
74
|
+
* versus signup branch is resolved by `verifyLoginCode`.
|
|
75
|
+
*
|
|
68
76
|
* @example
|
|
69
77
|
* const r = await auth.emailOtp.sendLoginCode({ email, captchaToken })
|
|
70
|
-
* // r = {
|
|
71
|
-
* // otp: { expiresInSeconds, expiresAt, canResendInSeconds, resendsRemaining } }
|
|
78
|
+
* // r = { otp: { expiresInSeconds, expiresAt, canResendInSeconds, resendsRemaining } }
|
|
72
79
|
*
|
|
73
80
|
* @throws CaptchaFailedError, RateLimitedError, InvalidEmailError, AuthError.
|
|
74
81
|
*/
|
|
@@ -118,19 +125,92 @@ type EmailPasswordNamespace = {
|
|
|
118
125
|
/** Google flow. */
|
|
119
126
|
type GoogleNamespace = {
|
|
120
127
|
/**
|
|
121
|
-
* Sign in with Google
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* for the ID token using its client secret.
|
|
128
|
+
* Sign in with a Google ID token from the Google Identity Services button
|
|
129
|
+
* or One Tap. Apps that do not load Google Identity Services should use
|
|
130
|
+
* `signInWithPopup` instead.
|
|
125
131
|
*
|
|
126
|
-
* @throws AuthError
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
* @example
|
|
130
|
-
* await auth.google.login({ idToken });
|
|
131
|
-
* await auth.google.login({ code });
|
|
132
|
+
* @throws AuthError (401) when the ID token fails verification,
|
|
133
|
+
* GoogleSignInError with code `email_unverified`,
|
|
134
|
+
* AccountSuspendedError, AuthError.
|
|
132
135
|
*/
|
|
133
136
|
login(input: LoginWithGoogleInput): Promise<AuthSession>;
|
|
137
|
+
/**
|
|
138
|
+
* Build the `GET /auth/google/start` URL for the hosted login. Use it to
|
|
139
|
+
* drive the redirect flow yourself (`location.assign(url)`), or a custom
|
|
140
|
+
* popup. In `redirect` mode the nonce is saved in `sessionStorage` for
|
|
141
|
+
* `completeRedirect` to verify.
|
|
142
|
+
*
|
|
143
|
+
* @throws Error when `returnTo` is relative outside a browser, or when
|
|
144
|
+
* `sessionStorage` is missing in `redirect` mode.
|
|
145
|
+
*/
|
|
146
|
+
startUrl(opts: GoogleStartOptions & {
|
|
147
|
+
nonce: string;
|
|
148
|
+
}): string;
|
|
149
|
+
/**
|
|
150
|
+
* Exchange the one-time `code` from a hosted login exit for a session.
|
|
151
|
+
* `signInWithPopup` and `completeRedirect` call this for you; call it
|
|
152
|
+
* yourself only when driving `startUrl` manually.
|
|
153
|
+
*
|
|
154
|
+
* @throws GoogleSignInError with code `invalid_google_code` (401) when the
|
|
155
|
+
* code is unknown, expired (60 s), or already used;
|
|
156
|
+
* AccountSuspendedError, AuthError.
|
|
157
|
+
*/
|
|
158
|
+
exchange(input: GoogleExchangeInput): Promise<AuthSession>;
|
|
159
|
+
/**
|
|
160
|
+
* Sign in with Google through the auth-hosted flow in a popup. Opens
|
|
161
|
+
* `startUrl` in a popup window, waits for the exit message, exchanges the
|
|
162
|
+
* one-time code, and stores the session. Browser only.
|
|
163
|
+
*
|
|
164
|
+
* @throws GoogleSignInCancelledError (`reason`: `popup_blocked`,
|
|
165
|
+
* `popup_closed`, or `access_denied`), GoogleSignInError with the
|
|
166
|
+
* exit or exchange code, Error outside a browser.
|
|
167
|
+
* @example
|
|
168
|
+
* try {
|
|
169
|
+
* const session = await auth.google.signInWithPopup();
|
|
170
|
+
* } catch (e) {
|
|
171
|
+
* if (e instanceof GoogleSignInCancelledError) return; // user backed out
|
|
172
|
+
* throw e;
|
|
173
|
+
* }
|
|
174
|
+
*/
|
|
175
|
+
signInWithPopup(opts?: GoogleSignInWithPopupOptions): Promise<AuthSession>;
|
|
176
|
+
/**
|
|
177
|
+
* Finish a hosted Google login started in `redirect` mode. Call it on the
|
|
178
|
+
* `returnTo` page. Resolves `null` when the URL carries no `code` or
|
|
179
|
+
* `error`, otherwise verifies the nonce saved by `startUrl`, strips
|
|
180
|
+
* `code`, `error`, and `nonce` from the URL, and exchanges the code.
|
|
181
|
+
* Browser only.
|
|
182
|
+
*
|
|
183
|
+
* @throws GoogleSignInError (`oauth_nonce_mismatch`, or the exit or
|
|
184
|
+
* exchange code), GoogleSignInCancelledError (`access_denied`),
|
|
185
|
+
* Error outside a browser.
|
|
186
|
+
* @example
|
|
187
|
+
* const session = await auth.google.completeRedirect();
|
|
188
|
+
* if (session) router.replace('/dashboard');
|
|
189
|
+
*/
|
|
190
|
+
completeRedirect(opts?: GoogleCompleteRedirectOptions): Promise<AuthSession | null>;
|
|
191
|
+
};
|
|
192
|
+
/** Self-service role applications (`/auth/roles/*`). */
|
|
193
|
+
type RolesNamespace = {
|
|
194
|
+
/**
|
|
195
|
+
* Apply for a self-applicable global role. The application lands at
|
|
196
|
+
* `pending_approval` until an admin approves it.
|
|
197
|
+
*
|
|
198
|
+
* @throws AuthError with `code` `role_already_active` or
|
|
199
|
+
* `application_pending` (409), `role_not_self_applicable` (403),
|
|
200
|
+
* a 400 for a role name outside the allowlist, a 401 for a missing
|
|
201
|
+
* or expired session, and other API errors.
|
|
202
|
+
* @example
|
|
203
|
+
* const app = await auth.roles.apply({ roleName: 'module_deployer' });
|
|
204
|
+
* // app.status === 'pending_approval'
|
|
205
|
+
*/
|
|
206
|
+
apply(input: ApplyRoleInput): Promise<RoleApplicationStatus>;
|
|
207
|
+
/**
|
|
208
|
+
* Application status for every self-applicable role. Always one row per
|
|
209
|
+
* role; `status` is `none` when the account has never applied.
|
|
210
|
+
*
|
|
211
|
+
* @throws AuthError on 401 (missing or expired session) and other API errors.
|
|
212
|
+
*/
|
|
213
|
+
status(): Promise<RoleStatus[]>;
|
|
134
214
|
};
|
|
135
215
|
/** Custodial wallet (Console tier). */
|
|
136
216
|
type WalletNamespace = {
|
|
@@ -141,6 +221,7 @@ type AuthClient = {
|
|
|
141
221
|
emailOtp: EmailOtpNamespace;
|
|
142
222
|
emailPassword: EmailPasswordNamespace;
|
|
143
223
|
google: GoogleNamespace;
|
|
224
|
+
roles: RolesNamespace;
|
|
144
225
|
wallet: WalletNamespace;
|
|
145
226
|
/**
|
|
146
227
|
* Fetch the token holder's identity: account (id, email, live status,
|
|
@@ -167,4 +248,4 @@ type AuthClient = {
|
|
|
167
248
|
};
|
|
168
249
|
declare function createAuthClient(options: CreateAuthClientOptions): AuthClient;
|
|
169
250
|
//#endregion
|
|
170
|
-
export { GoogleNamespace as a,
|
|
251
|
+
export { GoogleNamespace as a, SubscribeOptions as c, AuthFetchInit as d, EmailPasswordNamespace as i, WalletNamespace as l, CreateAuthClientOptions as n, ProactiveRefreshConfig as o, EmailOtpNamespace as r, RolesNamespace as s, AuthClient as t, createAuthClient as u };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as OtpInfo, c as ResendCodeResult, i as ErrorSource, l as SendLoginCodeResult, n as AuthSession, o as Project, r as ErrorHandler, s as RegisterResult, t as Account, u as SessionChangeHandler } from "./session-
|
|
2
|
-
import { a as GoogleNamespace, c as
|
|
3
|
-
import { i as memoryStore, n as SessionStore, r as localStorageStore, t as LocalStorageStoreOptions } from "./sessionStore-
|
|
4
|
-
import { a as
|
|
5
|
-
import {
|
|
1
|
+
import { a as OtpInfo, c as ResendCodeResult, i as ErrorSource, l as SendLoginCodeResult, n as AuthSession, o as Project, r as ErrorHandler, s as RegisterResult, t as Account, u as SessionChangeHandler } from "./session-flM0yXx2.js";
|
|
2
|
+
import { a as GoogleNamespace, c as SubscribeOptions, d as AuthFetchInit, i as EmailPasswordNamespace, l as WalletNamespace, n as CreateAuthClientOptions, o as ProactiveRefreshConfig, r as EmailOtpNamespace, s as RolesNamespace, t as AuthClient, u as createAuthClient } from "./index-DwFEdFaS.js";
|
|
3
|
+
import { i as memoryStore, n as SessionStore, r as localStorageStore, t as LocalStorageStoreOptions } from "./sessionStore-D2kXjvNM.js";
|
|
4
|
+
import { C as ProfileResult, S as ProfileAccount, _ as SendLoginCodeInput, a as CaptchaArgs, b as VerifyRegistrationCodeInput, c as GoogleExchangeInput, d as GoogleStartOptions, f as LoginWithGoogleInput, g as ResendRegistrationCodeInput, h as ResendLoginCodeInput, i as RoleStatus, l as GoogleSignInWithPopupOptions, m as RegisterInput, n as RoleApplicationState, o as ChangePasswordInput, p as LoginWithPasswordInput, r as RoleApplicationStatus, s as GoogleCompleteRedirectOptions, t as ApplyRoleInput, u as GoogleStartMode, v as SetPasswordInput, x as Profile, y as VerifyLoginCodeInput } from "./roles-BZecOymZ.js";
|
|
5
|
+
import { C as authErrorFromResponse, S as authErrorFromFetchFailure, _ as OtpInvalidError, a as EmailAlreadyHasPasswordError, b as ValidationError, c as GoogleSignInError, d as InvalidPasswordError, f as MaxAttemptsError, g as OtpExpiredError, h as NoPendingOtpError, i as CaptchaFailedError, l as InvalidCredentialsError, m as NoPasswordSetError, n as AuthError, o as GoogleSignInCancelledError, p as MaxResendsError, r as AuthErrorInit, s as GoogleSignInCancelledReason, t as AccountSuspendedError, u as InvalidEmailError, v as RateLimitedError, x as ValidationIssue, y as ResendCooldownError } from "./authError-E11ZMcID.js";
|
|
6
6
|
import { n as AccessTokenPayloadProject, t as AccessTokenPayload } from "./tokens-BXrPLi5B.js";
|
|
7
7
|
|
|
8
8
|
//#region src/types/wallet.d.ts
|
|
@@ -16,4 +16,4 @@ type SignHashResult = {
|
|
|
16
16
|
address: string;
|
|
17
17
|
};
|
|
18
18
|
//#endregion
|
|
19
|
-
export { type AccessTokenPayload, type AccessTokenPayloadProject, type Account, AccountSuspendedError, type AuthClient, AuthError, type AuthErrorInit, type AuthFetchInit, type AuthSession, type CaptchaArgs, CaptchaFailedError, type ChangePasswordInput, type CreateAuthClientOptions, EmailAlreadyHasPasswordError, type EmailOtpNamespace, type EmailPasswordNamespace, type ErrorHandler, type ErrorSource, type GoogleNamespace, InvalidCredentialsError, InvalidEmailError, InvalidPasswordError, type LocalStorageStoreOptions, type LoginWithGoogleInput, type LoginWithPasswordInput, MaxAttemptsError, MaxResendsError, NoPasswordSetError, NoPendingOtpError, OtpExpiredError, type OtpInfo, OtpInvalidError, type ProactiveRefreshConfig, type Profile, type ProfileAccount, type ProfileResult, type Project, RateLimitedError, type RegisterInput, type RegisterResult, type ResendCodeResult, ResendCooldownError, type ResendLoginCodeInput, type ResendRegistrationCodeInput, type SendLoginCodeInput, type SendLoginCodeResult, type SessionChangeHandler, type SessionStore, type SetPasswordInput, type SignHashResult, type SubscribeOptions, type VerifyLoginCodeInput, type VerifyRegistrationCodeInput, type WalletAddressResult, type WalletNamespace, authErrorFromFetchFailure, authErrorFromResponse, createAuthClient, localStorageStore, memoryStore };
|
|
19
|
+
export { type AccessTokenPayload, type AccessTokenPayloadProject, type Account, AccountSuspendedError, type ApplyRoleInput, type AuthClient, AuthError, type AuthErrorInit, type AuthFetchInit, type AuthSession, type CaptchaArgs, CaptchaFailedError, type ChangePasswordInput, type CreateAuthClientOptions, EmailAlreadyHasPasswordError, type EmailOtpNamespace, type EmailPasswordNamespace, type ErrorHandler, type ErrorSource, type GoogleCompleteRedirectOptions, type GoogleExchangeInput, type GoogleNamespace, GoogleSignInCancelledError, type GoogleSignInCancelledReason, GoogleSignInError, type GoogleSignInWithPopupOptions, type GoogleStartMode, type GoogleStartOptions, InvalidCredentialsError, InvalidEmailError, InvalidPasswordError, type LocalStorageStoreOptions, type LoginWithGoogleInput, type LoginWithPasswordInput, MaxAttemptsError, MaxResendsError, NoPasswordSetError, NoPendingOtpError, OtpExpiredError, type OtpInfo, OtpInvalidError, type ProactiveRefreshConfig, type Profile, type ProfileAccount, type ProfileResult, type Project, RateLimitedError, type RegisterInput, type RegisterResult, type ResendCodeResult, ResendCooldownError, type ResendLoginCodeInput, type ResendRegistrationCodeInput, type RoleApplicationState, type RoleApplicationStatus, type RoleStatus, type RolesNamespace, type SendLoginCodeInput, type SendLoginCodeResult, type SessionChangeHandler, type SessionStore, type SetPasswordInput, type SignHashResult, type SubscribeOptions, ValidationError, type ValidationIssue, type VerifyLoginCodeInput, type VerifyRegistrationCodeInput, type WalletAddressResult, type WalletNamespace, authErrorFromFetchFailure, authErrorFromResponse, createAuthClient, localStorageStore, memoryStore };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import {
|
|
1
|
+
import { _ as ResendCooldownError, a as GoogleSignInCancelledError, b as authErrorFromResponse, c as InvalidEmailError, d as MaxResendsError, f as NoPasswordSetError, g as RateLimitedError, h as OtpInvalidError, i as EmailAlreadyHasPasswordError, l as InvalidPasswordError, m as OtpExpiredError, n as AuthError, o as GoogleSignInError, p as NoPendingOtpError, r as CaptchaFailedError, s as InvalidCredentialsError, t as AccountSuspendedError, u as MaxAttemptsError, v as ValidationError, y as authErrorFromFetchFailure } from "./authError-BPxMHQK2.js";
|
|
2
|
+
import { t as createAuthClient } from "./client-Dlhhdp-T.js";
|
|
3
3
|
import { n as memoryStore, t as localStorageStore } from "./sessionStore-DD6lON9W.js";
|
|
4
|
-
export { AccountSuspendedError, AuthError, CaptchaFailedError, EmailAlreadyHasPasswordError, InvalidCredentialsError, InvalidEmailError, InvalidPasswordError, MaxAttemptsError, MaxResendsError, NoPasswordSetError, NoPendingOtpError, OtpExpiredError, OtpInvalidError, RateLimitedError, ResendCooldownError, authErrorFromFetchFailure, authErrorFromResponse, createAuthClient, localStorageStore, memoryStore };
|
|
4
|
+
export { AccountSuspendedError, AuthError, CaptchaFailedError, EmailAlreadyHasPasswordError, GoogleSignInCancelledError, GoogleSignInError, InvalidCredentialsError, InvalidEmailError, InvalidPasswordError, MaxAttemptsError, MaxResendsError, NoPasswordSetError, NoPendingOtpError, OtpExpiredError, OtpInvalidError, RateLimitedError, ResendCooldownError, ValidationError, authErrorFromFetchFailure, authErrorFromResponse, createAuthClient, localStorageStore, memoryStore };
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { t as Account } from "./session-flM0yXx2.js";
|
|
2
|
+
|
|
3
|
+
//#region src/types/profile.d.ts
|
|
4
|
+
/** The account's profile record; every field is user-editable and nullable. */
|
|
5
|
+
type Profile = {
|
|
6
|
+
displayName: string | null;
|
|
7
|
+
avatarUrl: string | null;
|
|
8
|
+
primaryEmail: string | null;
|
|
9
|
+
primaryPhone: string | null;
|
|
10
|
+
};
|
|
11
|
+
/** The account as returned by `auth.getProfile`, with sign-in capability flags. */
|
|
12
|
+
type ProfileAccount = Account & {
|
|
13
|
+
/**
|
|
14
|
+
* `true` when the account can sign in with a password; `false` for
|
|
15
|
+
* Google-only or code-only accounts, which should call
|
|
16
|
+
* `auth.emailPassword.setPassword` rather than `changePassword`.
|
|
17
|
+
*/
|
|
18
|
+
hasPassword: boolean;
|
|
19
|
+
};
|
|
20
|
+
/** Result of `auth.getProfile`, the identity read for the token holder. */
|
|
21
|
+
type ProfileResult = {
|
|
22
|
+
/** `status` is the live account status, not a token-time snapshot. */account: ProfileAccount; /** `null` when the account has no profile row yet. */
|
|
23
|
+
profile: Profile | null;
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/types/requests.d.ts
|
|
27
|
+
/** Optional captcha argument shared by every public unauthenticated entrypoint. */
|
|
28
|
+
type CaptchaArgs = {
|
|
29
|
+
/** Cloudflare Turnstile token. Required when captcha is enabled on the server. */captchaToken?: string;
|
|
30
|
+
};
|
|
31
|
+
type SendLoginCodeInput = {
|
|
32
|
+
email: string;
|
|
33
|
+
} & CaptchaArgs;
|
|
34
|
+
type VerifyLoginCodeInput = {
|
|
35
|
+
email: string;
|
|
36
|
+
code: string;
|
|
37
|
+
};
|
|
38
|
+
type ResendLoginCodeInput = {
|
|
39
|
+
email: string;
|
|
40
|
+
} & CaptchaArgs;
|
|
41
|
+
type RegisterInput = {
|
|
42
|
+
email: string;
|
|
43
|
+
password: string;
|
|
44
|
+
} & CaptchaArgs;
|
|
45
|
+
type VerifyRegistrationCodeInput = {
|
|
46
|
+
email: string;
|
|
47
|
+
code: string;
|
|
48
|
+
};
|
|
49
|
+
type ResendRegistrationCodeInput = {
|
|
50
|
+
email: string;
|
|
51
|
+
} & CaptchaArgs;
|
|
52
|
+
type LoginWithPasswordInput = {
|
|
53
|
+
email: string;
|
|
54
|
+
password: string;
|
|
55
|
+
} & CaptchaArgs;
|
|
56
|
+
type SetPasswordInput = {
|
|
57
|
+
password: string;
|
|
58
|
+
};
|
|
59
|
+
type ChangePasswordInput = {
|
|
60
|
+
currentPassword: string;
|
|
61
|
+
newPassword: string;
|
|
62
|
+
};
|
|
63
|
+
/** `idToken` comes from Google Identity Services (`renderButton` / One Tap). */
|
|
64
|
+
type LoginWithGoogleInput = {
|
|
65
|
+
idToken: string;
|
|
66
|
+
};
|
|
67
|
+
/** The one-time code handed to the app by the hosted Google login exit. */
|
|
68
|
+
type GoogleExchangeInput = {
|
|
69
|
+
code: string;
|
|
70
|
+
};
|
|
71
|
+
type GoogleStartMode = 'popup' | 'redirect';
|
|
72
|
+
type GoogleStartOptions = {
|
|
73
|
+
/**
|
|
74
|
+
* Where the browser lands after Google. Absolute URL or a path resolved
|
|
75
|
+
* against `window.location`. Its origin must be one of the project's
|
|
76
|
+
* `allowedOrigins`. Default: the current href without its hash.
|
|
77
|
+
*/
|
|
78
|
+
returnTo?: string; /** `popup` posts the result to `window.opener`; `redirect` 302s back to `returnTo`. */
|
|
79
|
+
mode: GoogleStartMode; /** Opaque value echoed back on the exit. Supplied by `signInWithPopup`; callers normally omit it. */
|
|
80
|
+
nonce?: string;
|
|
81
|
+
};
|
|
82
|
+
type GoogleSignInWithPopupOptions = {
|
|
83
|
+
/** See `GoogleStartOptions.returnTo`. Default: the current href without its hash. */returnTo?: string;
|
|
84
|
+
popup?: {
|
|
85
|
+
/** Popup width in CSS pixels. Default: 500. */width?: number; /** Popup height in CSS pixels. Default: 640. */
|
|
86
|
+
height?: number;
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
type GoogleCompleteRedirectOptions = {
|
|
90
|
+
/** URL to read `code`, `error`, and `nonce` from. Default: `window.location.href`. */url?: string;
|
|
91
|
+
};
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region src/types/roles.d.ts
|
|
94
|
+
/** Lifecycle of a role application, as stored on the server. */
|
|
95
|
+
type RoleApplicationState = 'pending_approval' | 'active' | 'revoked';
|
|
96
|
+
/** Input of `auth.roles.apply`. */
|
|
97
|
+
type ApplyRoleInput = {
|
|
98
|
+
/** Role to apply for. Only names on the server's self-applicable allowlist are accepted. */roleName: string;
|
|
99
|
+
};
|
|
100
|
+
/** Result of `auth.roles.apply`: the account role row the server created. */
|
|
101
|
+
type RoleApplicationStatus = {
|
|
102
|
+
id: string;
|
|
103
|
+
accountId: string;
|
|
104
|
+
roleId: string; /** `null` for a global role. */
|
|
105
|
+
projectId: string | null;
|
|
106
|
+
status: RoleApplicationState; /** Account id that created the row: an admin, or the applicant for a self-service application. */
|
|
107
|
+
assignedBy: string | null;
|
|
108
|
+
assignedAt: string;
|
|
109
|
+
approvedAt: string | null;
|
|
110
|
+
revokedAt: string | null;
|
|
111
|
+
};
|
|
112
|
+
/** One row of `auth.roles.status`, from the caller's point of view. */
|
|
113
|
+
type RoleStatus = {
|
|
114
|
+
roleName: string;
|
|
115
|
+
displayName: string | null; /** `none` when the account has never applied for this role. */
|
|
116
|
+
status: RoleApplicationState | 'none'; /** `null` until the account applies. */
|
|
117
|
+
accountRoleId: string | null;
|
|
118
|
+
assignedAt: string | null;
|
|
119
|
+
approvedAt: string | null;
|
|
120
|
+
revokedAt: string | null;
|
|
121
|
+
};
|
|
122
|
+
//#endregion
|
|
123
|
+
export { ProfileResult as C, ProfileAccount as S, SendLoginCodeInput as _, CaptchaArgs as a, VerifyRegistrationCodeInput as b, GoogleExchangeInput as c, GoogleStartOptions as d, LoginWithGoogleInput as f, ResendRegistrationCodeInput as g, ResendLoginCodeInput as h, RoleStatus as i, GoogleSignInWithPopupOptions as l, RegisterInput as m, RoleApplicationState as n, ChangePasswordInput as o, LoginWithPasswordInput as p, RoleApplicationStatus as r, GoogleCompleteRedirectOptions as s, ApplyRoleInput as t, GoogleStartMode as u, SetPasswordInput as v, Profile as x, VerifyLoginCodeInput as y };
|
|
@@ -28,11 +28,13 @@ type OtpInfo = {
|
|
|
28
28
|
canResendInSeconds: number; /** Resend attempts left for this OTP record. */
|
|
29
29
|
resendsRemaining: number;
|
|
30
30
|
};
|
|
31
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Result of `auth.emailOtp.sendLoginCode`. Carries only OTP timing: the
|
|
33
|
+
* server does not reveal whether the email is registered, so login versus
|
|
34
|
+
* signup is only known after `verifyLoginCode`.
|
|
35
|
+
*/
|
|
32
36
|
type SendLoginCodeResult = {
|
|
33
|
-
/**
|
|
34
|
-
methods: ('password' | 'passwordless')[]; /** OTP timing metadata. */
|
|
35
|
-
otp: OtpInfo;
|
|
37
|
+
/** OTP timing metadata. */otp: OtpInfo;
|
|
36
38
|
};
|
|
37
39
|
/** Result of any resend method (`emailOtp.resendLoginCode`, `emailPassword.resendRegistrationCode`). */
|
|
38
40
|
type ResendCodeResult = {
|
package/dist/store/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as memoryStore, n as SessionStore, r as localStorageStore, t as LocalStorageStoreOptions } from "../sessionStore-
|
|
1
|
+
import { i as memoryStore, n as SessionStore, r as localStorageStore, t as LocalStorageStoreOptions } from "../sessionStore-D2kXjvNM.js";
|
|
2
2
|
export { type LocalStorageStoreOptions, type SessionStore, localStorageStore, memoryStore };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as OtpInfo, c as ResendCodeResult, i as ErrorSource, l as SendLoginCodeResult, n as AuthSession, o as Project, r as ErrorHandler, s as RegisterResult, t as Account, u as SessionChangeHandler } from "../session-
|
|
2
|
-
import { a as
|
|
1
|
+
import { a as OtpInfo, c as ResendCodeResult, i as ErrorSource, l as SendLoginCodeResult, n as AuthSession, o as Project, r as ErrorHandler, s as RegisterResult, t as Account, u as SessionChangeHandler } from "../session-flM0yXx2.js";
|
|
2
|
+
import { C as ProfileResult, S as ProfileAccount, _ as SendLoginCodeInput, a as CaptchaArgs, b as VerifyRegistrationCodeInput, c as GoogleExchangeInput, d as GoogleStartOptions, f as LoginWithGoogleInput, g as ResendRegistrationCodeInput, h as ResendLoginCodeInput, i as RoleStatus, l as GoogleSignInWithPopupOptions, m as RegisterInput, n as RoleApplicationState, o as ChangePasswordInput, p as LoginWithPasswordInput, r as RoleApplicationStatus, s as GoogleCompleteRedirectOptions, t as ApplyRoleInput, u as GoogleStartMode, v as SetPasswordInput, x as Profile, y as VerifyLoginCodeInput } from "../roles-BZecOymZ.js";
|
|
3
3
|
import { n as AccessTokenPayloadProject, t as AccessTokenPayload } from "../tokens-BXrPLi5B.js";
|
|
4
|
-
export { type AccessTokenPayload, type AccessTokenPayloadProject, type Account, type AuthSession, type CaptchaArgs, type ChangePasswordInput, type ErrorHandler, type ErrorSource, type LoginWithGoogleInput, type LoginWithPasswordInput, type OtpInfo, type Profile, type ProfileAccount, type ProfileResult, type Project, type RegisterInput, type RegisterResult, type ResendCodeResult, type ResendLoginCodeInput, type ResendRegistrationCodeInput, type SendLoginCodeInput, type SendLoginCodeResult, type SessionChangeHandler, type SetPasswordInput, type VerifyLoginCodeInput, type VerifyRegistrationCodeInput };
|
|
4
|
+
export { type AccessTokenPayload, type AccessTokenPayloadProject, type Account, type ApplyRoleInput, type AuthSession, type CaptchaArgs, type ChangePasswordInput, type ErrorHandler, type ErrorSource, type GoogleCompleteRedirectOptions, type GoogleExchangeInput, type GoogleSignInWithPopupOptions, type GoogleStartMode, type GoogleStartOptions, type LoginWithGoogleInput, type LoginWithPasswordInput, type OtpInfo, type Profile, type ProfileAccount, type ProfileResult, type Project, type RegisterInput, type RegisterResult, type ResendCodeResult, type ResendLoginCodeInput, type ResendRegistrationCodeInput, type RoleApplicationState, type RoleApplicationStatus, type RoleStatus, type SendLoginCodeInput, type SendLoginCodeResult, type SessionChangeHandler, type SetPasswordInput, type VerifyLoginCodeInput, type VerifyRegistrationCodeInput };
|
package/dist/wallet/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { t as Account } from "./session-Cs_P7ojF.js";
|
|
2
|
-
|
|
3
|
-
//#region src/types/profile.d.ts
|
|
4
|
-
/** The account's profile record; every field is user-editable and nullable. */
|
|
5
|
-
type Profile = {
|
|
6
|
-
displayName: string | null;
|
|
7
|
-
avatarUrl: string | null;
|
|
8
|
-
primaryEmail: string | null;
|
|
9
|
-
primaryPhone: string | null;
|
|
10
|
-
};
|
|
11
|
-
/** The account as returned by `auth.getProfile`, with sign-in capability flags. */
|
|
12
|
-
type ProfileAccount = Account & {
|
|
13
|
-
/**
|
|
14
|
-
* `true` when the account can sign in with a password; `false` for
|
|
15
|
-
* Google-only or code-only accounts, which should call
|
|
16
|
-
* `auth.emailPassword.setPassword` rather than `changePassword`.
|
|
17
|
-
*/
|
|
18
|
-
hasPassword: boolean;
|
|
19
|
-
};
|
|
20
|
-
/** Result of `auth.getProfile`, the identity read for the token holder. */
|
|
21
|
-
type ProfileResult = {
|
|
22
|
-
/** `status` is the live account status, not a token-time snapshot. */account: ProfileAccount; /** `null` when the account has no profile row yet. */
|
|
23
|
-
profile: Profile | null;
|
|
24
|
-
};
|
|
25
|
-
//#endregion
|
|
26
|
-
//#region src/types/requests.d.ts
|
|
27
|
-
/** Optional captcha argument shared by every public unauthenticated entrypoint. */
|
|
28
|
-
type CaptchaArgs = {
|
|
29
|
-
/** Cloudflare Turnstile token. Required when captcha is enabled on the server. */captchaToken?: string;
|
|
30
|
-
};
|
|
31
|
-
type SendLoginCodeInput = {
|
|
32
|
-
email: string;
|
|
33
|
-
} & CaptchaArgs;
|
|
34
|
-
type VerifyLoginCodeInput = {
|
|
35
|
-
email: string;
|
|
36
|
-
code: string;
|
|
37
|
-
};
|
|
38
|
-
type ResendLoginCodeInput = {
|
|
39
|
-
email: string;
|
|
40
|
-
} & CaptchaArgs;
|
|
41
|
-
type RegisterInput = {
|
|
42
|
-
email: string;
|
|
43
|
-
password: string;
|
|
44
|
-
} & CaptchaArgs;
|
|
45
|
-
type VerifyRegistrationCodeInput = {
|
|
46
|
-
email: string;
|
|
47
|
-
code: string;
|
|
48
|
-
};
|
|
49
|
-
type ResendRegistrationCodeInput = {
|
|
50
|
-
email: string;
|
|
51
|
-
} & CaptchaArgs;
|
|
52
|
-
type LoginWithPasswordInput = {
|
|
53
|
-
email: string;
|
|
54
|
-
password: string;
|
|
55
|
-
} & CaptchaArgs;
|
|
56
|
-
type SetPasswordInput = {
|
|
57
|
-
password: string;
|
|
58
|
-
};
|
|
59
|
-
type ChangePasswordInput = {
|
|
60
|
-
currentPassword: string;
|
|
61
|
-
newPassword: string;
|
|
62
|
-
};
|
|
63
|
-
/**
|
|
64
|
-
* Exactly one of the two shapes. `idToken` comes from Google Identity Services
|
|
65
|
-
* (`renderButton` / One Tap). `code` is the authorization code from
|
|
66
|
-
* `google.accounts.oauth2.initCodeClient` in popup mode; the server exchanges
|
|
67
|
-
* it for the ID token, so the client secret never reaches the browser.
|
|
68
|
-
*/
|
|
69
|
-
type LoginWithGoogleInput = {
|
|
70
|
-
idToken: string;
|
|
71
|
-
} | {
|
|
72
|
-
code: string;
|
|
73
|
-
};
|
|
74
|
-
//#endregion
|
|
75
|
-
export { RegisterInput as a, SendLoginCodeInput as c, VerifyRegistrationCodeInput as d, Profile as f, LoginWithPasswordInput as i, SetPasswordInput as l, ProfileResult as m, ChangePasswordInput as n, ResendLoginCodeInput as o, ProfileAccount as p, LoginWithGoogleInput as r, ResendRegistrationCodeInput as s, CaptchaArgs as t, VerifyLoginCodeInput as u };
|