@object-ui/auth 17.2.0 → 17.5.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 +115 -0
- package/README.md +36 -13
- package/dist/AuthContext.d.ts +15 -0
- package/dist/AuthContext.d.ts.map +1 -1
- package/dist/AuthProvider.d.ts.map +1 -1
- package/dist/AuthProvider.js +88 -26
- package/dist/ForgotPasswordForm.d.ts.map +1 -1
- package/dist/ForgotPasswordForm.js +2 -1
- package/dist/LoginForm.d.ts.map +1 -1
- package/dist/LoginForm.js +9 -5
- package/dist/RegisterForm.d.ts.map +1 -1
- package/dist/RegisterForm.js +5 -2
- package/dist/createAuthClient.d.ts +22 -0
- package/dist/createAuthClient.d.ts.map +1 -1
- package/dist/createAuthClient.js +76 -21
- package/dist/createAuthenticatedFetch.d.ts.map +1 -1
- package/dist/createAuthenticatedFetch.js +33 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/useAuth.d.ts.map +1 -1
- package/dist/useAuth.js +1 -0
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,119 @@
|
|
|
1
1
|
# @object-ui/auth
|
|
2
2
|
|
|
3
|
+
## 17.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 5cc847c: The data lane now honors `set-auth-token`, so impersonation takes effect at all (#4467).
|
|
8
|
+
|
|
9
|
+
The console injects the same localStorage bearer from two lanes: the AUTH lane
|
|
10
|
+
(`createBearerFetch` inside `createAuthClient`) and the DATA lane
|
|
11
|
+
(`createAuthenticatedFetch` — the adapter, `provider: 'api'` data sources, and every
|
|
12
|
+
metadata `type: 'api'` action). better-auth's server-side bearer plugin hands a ROTATED
|
|
13
|
+
session token back in the `set-auth-token` response header on whichever lane the call
|
|
14
|
+
arrived over, and only the auth lane read it. A rotation issued to a data-lane call was
|
|
15
|
+
discarded and the browser kept sending the old token.
|
|
16
|
+
|
|
17
|
+
`POST /auth/admin/impersonate-user` is exactly such a call — an ordinary metadata action.
|
|
18
|
+
The impersonated session token was dropped on the floor while the server's bearer plugin
|
|
19
|
+
kept overwriting the impersonation cookie with the admin bearer the console kept sending,
|
|
20
|
+
so impersonation was a complete no-op in the console rather than merely an invisible one.
|
|
21
|
+
Support staff believed they were seeing a user's view while acting entirely as themselves.
|
|
22
|
+
|
|
23
|
+
Published behaviour that moves: a data-lane response carrying `set-auth-token` now
|
|
24
|
+
replaces the stored session token, on any API call this lane authenticated (untrusted
|
|
25
|
+
targets remain the `sameOriginOnly` option's job — it short-circuits before any header
|
|
26
|
+
work). The accepted cost, recorded on the card: while impersonating, the administrator's
|
|
27
|
+
own token is replaced in localStorage for the duration, and a client that misses the stop
|
|
28
|
+
rotation is stranded until re-login.
|
|
29
|
+
|
|
30
|
+
Also in this release, all additive:
|
|
31
|
+
|
|
32
|
+
- `AuthContextValue.refreshSession()` re-resolves `user`/`session` from the server in
|
|
33
|
+
place, without raising `isLoading` — the transitions that change WHO the session is
|
|
34
|
+
without going through `signIn`/`signOut`.
|
|
35
|
+
- `TokenStorage.subscribeRotation()` notifies when a token already in hand is replaced by
|
|
36
|
+
a different one. First store, `clear()`, and re-storing the same value stay silent:
|
|
37
|
+
those transitions have an owner that updates identity itself.
|
|
38
|
+
- `AuthClientSession.impersonatedBy?: string` — optional, set by better-auth's admin
|
|
39
|
+
plugin for the life of an impersonated session.
|
|
40
|
+
|
|
41
|
+
### Patch Changes
|
|
42
|
+
|
|
43
|
+
- 58bebf6: Organization & invitation console: translate the English holdouts a zh session was left reading (#4474)
|
|
44
|
+
|
|
45
|
+
Three families of string, one sweep over `console/organizations/`:
|
|
46
|
+
|
|
47
|
+
- **Role names** now come from the single shared `ORG_ROLE_LABELS` map at every
|
|
48
|
+
site. The role badges on the members and invitations pages were rendering the
|
|
49
|
+
raw server identifier (`owner`) under a CSS `capitalize` that made it look like
|
|
50
|
+
a label in English and left it untranslated everywhere else; the accept page
|
|
51
|
+
did the same in its role row and inside its otherwise-translated sentence. The
|
|
52
|
+
map's four `organization.roles.*` keys existed in no locale pack, so even the
|
|
53
|
+
dropdown that did consult it fell through to English — all ten packs now carry
|
|
54
|
+
them. An unrecognized role renders verbatim rather than blank.
|
|
55
|
+
- **Server-echoed errors** are mapped by better-auth's stable `code`, never by
|
|
56
|
+
matching its English text. `createAuthClient` was dropping that code for every
|
|
57
|
+
`organization.*` call while preserving it for sign-in/sign-up, so the console
|
|
58
|
+
had nothing to key on; all sixteen organization methods now go through the same
|
|
59
|
+
`toAuthError` helper. Messages are unchanged — the code simply stops being
|
|
60
|
+
thrown away. An unmapped code still shows the server's own sentence.
|
|
61
|
+
- **Icon-only `aria-label`s** (member actions, copy invitation link, cancel
|
|
62
|
+
invitation, and a fourth on the share-link copy button) are translated — for an
|
|
63
|
+
icon-only control this is the only name a screen reader gets.
|
|
64
|
+
|
|
65
|
+
- 564252c: `features.passkeys` and `features.magicLink` are documented as reserved, so enabling them no longer implies a login-page entry point that does not exist
|
|
66
|
+
|
|
67
|
+
`GET /api/v1/auth/config` advertises eight login-surface capability flags. Six of them gate something real — `sso` gates the "Sign in with SSO" button, `phoneNumberOtp` the verification-code mode, `deviceAuthorization` the device-approval page — and each carries a doc comment saying what it gates. Two did not gate anything: `passkeys` and `magicLink` existed only as two undocumented lines in `AuthPublicConfig.features`, consumed by no component, no route and no metadata. A deployer who turned one on got a flag that changed nothing, with nothing anywhere to say so. That is the mirror of the defect the audit was looking for (framework#2874 P2②): not UI advertising a capability the backend lacks, but a backend advertising a capability the UI lacks.
|
|
68
|
+
|
|
69
|
+
Both flags are now marked reserved at the two places a deployer meets them. The declarations in `packages/auth/src/types.ts` carry doc comments — which ship in the published `.d.ts`, so the warning appears on hover — stating that enabling the flag adds no entry point and naming the follow-up card. `packages/auth/README.md` gains a "Server Feature Flags" section documenting what the `features` map is for and a "Reserved flags" table saying the same thing in prose. Per the maintainer's ruling on objectui#2514, the UI is deliberately not built here; it is filed as objectui#4179 and left unscheduled.
|
|
70
|
+
|
|
71
|
+
No runtime behaviour changes: nothing read these flags before and nothing reads them now. What changes is that the published types and docs stop being silent about it.
|
|
72
|
+
|
|
73
|
+
The three artifacts are pinned together by `packages/auth/src/__tests__/reserved-auth-features.test.ts`, which asserts the declarations still exist, that each carries a reserved marking naming the card, that the README section says the same, and — the inverse direction — that no source file under `packages/*/src`, `apps/*/src` or `examples/*/src` references either identifier. The sweep covers `.json` as well as `.ts`/`.tsx` because `AppContent` hands the whole `features` object to `ExpressionProvider`, so authored metadata can reach these flags without any source file naming them. Two calibration cases keep the pin from rotting into a vacuous pass: one asserts the sweep reads a non-trivial number of files, the other that it can still find a flag that _is_ consumed. When the UI is eventually built, the pin fails and its docblock spells out the retirement checklist — the doc comments, the README section and the pin itself come out in the same PR.
|
|
74
|
+
|
|
75
|
+
`features.twoFactor` is untouched and explicitly excluded: two-factor is implemented in this package (`enableTwoFactor` / `verifyTwoFactor`) and its challenge is driven by server-side remediation rather than by the flag, so `LoginForm` not reading it is the design rather than a gap. The README says so, and the pin asserts `twoFactor` never appears in the reserved table.
|
|
76
|
+
|
|
77
|
+
- Updated dependencies [f650253]
|
|
78
|
+
- Updated dependencies [3d9769a]
|
|
79
|
+
- Updated dependencies [92876f0]
|
|
80
|
+
- Updated dependencies [d9d3463]
|
|
81
|
+
- Updated dependencies [2a40f69]
|
|
82
|
+
- Updated dependencies [bec3e14]
|
|
83
|
+
- Updated dependencies [1f9b905]
|
|
84
|
+
- Updated dependencies [abb0f81]
|
|
85
|
+
- Updated dependencies [38ab505]
|
|
86
|
+
- Updated dependencies [7e4f0e5]
|
|
87
|
+
- Updated dependencies [c1d939f]
|
|
88
|
+
- Updated dependencies [bb68488]
|
|
89
|
+
- Updated dependencies [ab04728]
|
|
90
|
+
- @object-ui/types@17.5.0
|
|
91
|
+
|
|
92
|
+
## 17.4.0
|
|
93
|
+
|
|
94
|
+
### Patch Changes
|
|
95
|
+
|
|
96
|
+
- Updated dependencies [d229dfa]
|
|
97
|
+
- Updated dependencies [c2fd122]
|
|
98
|
+
- Updated dependencies [48132f7]
|
|
99
|
+
- Updated dependencies [7e5bb5d]
|
|
100
|
+
- Updated dependencies [e6fdbdc]
|
|
101
|
+
- Updated dependencies [7e2b7e9]
|
|
102
|
+
- Updated dependencies [c1e1e6b]
|
|
103
|
+
- @object-ui/types@17.4.0
|
|
104
|
+
|
|
105
|
+
## 17.3.0
|
|
106
|
+
|
|
107
|
+
### Patch Changes
|
|
108
|
+
|
|
109
|
+
- Updated dependencies [d915c47]
|
|
110
|
+
- Updated dependencies [9e9e9a9]
|
|
111
|
+
- Updated dependencies [23018cc]
|
|
112
|
+
- Updated dependencies [f44d872]
|
|
113
|
+
- Updated dependencies [f833d3a]
|
|
114
|
+
- Updated dependencies [d22ae31]
|
|
115
|
+
- @object-ui/types@17.3.0
|
|
116
|
+
|
|
3
117
|
## 17.2.0
|
|
4
118
|
|
|
5
119
|
### Minor Changes
|
|
@@ -856,6 +970,7 @@
|
|
|
856
970
|
no visible effect — the user/session were nulled but the UI stayed authenticated.
|
|
857
971
|
|
|
858
972
|
Changes:
|
|
973
|
+
|
|
859
974
|
- **`@object-ui/auth`** — added `isAuthEnabled: boolean` to `AuthContextValue`
|
|
860
975
|
(`true` only when real auth is in use, `false` for guest/preview modes).
|
|
861
976
|
- **`@object-ui/app-shell`** — `AppHeader` and `AppSidebar` now hide the "Log out"
|
package/README.md
CHANGED
|
@@ -21,7 +21,6 @@ npm install @object-ui/auth
|
|
|
21
21
|
|
|
22
22
|
**Peer Dependencies:**
|
|
23
23
|
- `react` ^18.0.0 || ^19.0.0
|
|
24
|
-
- `react-dom` ^18.0.0 || ^19.0.0
|
|
25
24
|
|
|
26
25
|
## Quick Start
|
|
27
26
|
|
|
@@ -138,6 +137,42 @@ const authedFetch = createAuthenticatedFetch();
|
|
|
138
137
|
const apiProviderFetch = createAuthenticatedFetch({ sameOriginOnly: true });
|
|
139
138
|
```
|
|
140
139
|
|
|
140
|
+
## Server Feature Flags (`GET /auth/config`)
|
|
141
|
+
|
|
142
|
+
`createAuthClient().getConfig()` fetches the server's public auth configuration. The
|
|
143
|
+
`features` map on it tells the login surface which capabilities the deployment actually
|
|
144
|
+
has, so the UI never renders an entry point whose endpoint is not mounted — `features.sso`
|
|
145
|
+
gates the "Sign in with SSO" button, `features.phoneNumberOtp` gates the
|
|
146
|
+
verification-code mode, `features.deviceAuthorization` gates the device-approval page,
|
|
147
|
+
and so on.
|
|
148
|
+
|
|
149
|
+
### Reserved flags — advertised by the server, consumed by nothing
|
|
150
|
+
|
|
151
|
+
Two members of that map are **declared but deliberately not consumed** by this package:
|
|
152
|
+
|
|
153
|
+
| Flag | Status | What enabling it does in the UI today |
|
|
154
|
+
| --- | --- | --- |
|
|
155
|
+
| `features.passkeys` | **Reserved** | Nothing. There is no passkey sign-in or registration UI for it to gate. |
|
|
156
|
+
| `features.magicLink` | **Reserved** | Nothing. There is neither a magic-link request step nor a route that consumes the emailed token. |
|
|
157
|
+
|
|
158
|
+
They are typed so the `/auth/config` payload round-trips without loss, not because
|
|
159
|
+
anything reads them. **Turning either flag on server-side adds no entry point to the login
|
|
160
|
+
page.** If you are enabling one because you expect a button to appear, it will not — and
|
|
161
|
+
that is the whole reason this section exists.
|
|
162
|
+
|
|
163
|
+
Building the two flows is tracked as a separate, unscheduled feature card,
|
|
164
|
+
[objectui#4179](https://github.com/objectstack-ai/objectui/issues/4179). Documenting them
|
|
165
|
+
as reserved rather than building them now follows the maintainer's ruling on
|
|
166
|
+
[objectui#2514](https://github.com/objectstack-ai/objectui/issues/2514): mark them
|
|
167
|
+
reserved today, build the UI when the login surface gets roadmap time, at which point it
|
|
168
|
+
renders driven by these same flags. When that lands, this section retires with it.
|
|
169
|
+
|
|
170
|
+
`features.twoFactor` is **not** in this category, despite also not being read by
|
|
171
|
+
`LoginForm`. Two-factor authentication is implemented here (`enableTwoFactor` /
|
|
172
|
+
`verifyTwoFactor` on the auth client) and its challenge is driven by server-side
|
|
173
|
+
remediation rather than by the flag, so the login form ignoring the flag is the design,
|
|
174
|
+
not a gap.
|
|
175
|
+
|
|
141
176
|
## Preview Mode
|
|
142
177
|
|
|
143
178
|
Preview mode allows visitors (e.g. marketplace customers) to explore the platform without registering or logging in. The `AuthProvider` auto-authenticates with a simulated user identity and bypasses login/registration screens.
|
|
@@ -207,20 +242,8 @@ function MyComponent() {
|
|
|
207
242
|
|
|
208
243
|
> **⚠️ Security:** Preview mode should **never** be used in production environments.
|
|
209
244
|
|
|
210
|
-
<!-- release-metadata:v3.3.0 -->
|
|
211
|
-
|
|
212
|
-
## Compatibility
|
|
213
|
-
|
|
214
|
-
- **React:** 18.x or 19.x
|
|
215
|
-
- **Node.js:** ≥ 18
|
|
216
|
-
- **TypeScript:** ≥ 5.0 (strict mode)
|
|
217
|
-
- **`@objectstack/spec`:** ^3.3.0
|
|
218
|
-
- **`@objectstack/client`:** ^3.3.0
|
|
219
|
-
- **Tailwind CSS:** ≥ 3.4 (for packages with UI)
|
|
220
|
-
|
|
221
245
|
## Links
|
|
222
246
|
|
|
223
|
-
- 📚 [Documentation](https://www.objectui.org/docs/packages/auth)
|
|
224
247
|
- 📦 [npm package](https://www.npmjs.com/package/@object-ui/auth)
|
|
225
248
|
- 📝 [Changelog](./CHANGELOG.md)
|
|
226
249
|
- 🐛 [Report an issue](https://github.com/objectstack-ai/objectui/issues)
|
package/dist/AuthContext.d.ts
CHANGED
|
@@ -39,6 +39,21 @@ export interface AuthContextValue {
|
|
|
39
39
|
}>;
|
|
40
40
|
/** Sign out the current user */
|
|
41
41
|
signOut: () => Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* objectui#4467 — re-resolve `user`/`session` from the server, in place.
|
|
44
|
+
*
|
|
45
|
+
* The same loader the provider runs on mount, exposed for the transitions
|
|
46
|
+
* that change WHO the session is without going through `signIn`/`signOut`:
|
|
47
|
+
* starting and stopping impersonation. Deliberately does NOT raise
|
|
48
|
+
* `isLoading` — a refresh must not blank the console it is running under.
|
|
49
|
+
*
|
|
50
|
+
* Callers rarely need it: a session rotation observed on the wire refreshes
|
|
51
|
+
* identity on its own (see `TokenStorage.subscribeRotation`). Call it when
|
|
52
|
+
* you must AWAIT the new identity before deciding what to show — the
|
|
53
|
+
* impersonation banner's exit does, so a stop that did not restore the
|
|
54
|
+
* administrator can fail loudly instead of appearing to succeed.
|
|
55
|
+
*/
|
|
56
|
+
refreshSession: () => Promise<void>;
|
|
42
57
|
/** Update user profile */
|
|
43
58
|
updateUser: (data: Partial<AuthUser>) => Promise<void>;
|
|
44
59
|
/** Request password reset */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthContext.d.ts","sourceRoot":"","sources":["../src/AuthContext.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AuthContext.d.ts","sourceRoot":"","sources":["../src/AuthContext.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../src/AuthProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../src/AuthProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAA4D,MAAM,OAAO,CAAC;AAEjF,OAAO,KAAK,EAAwB,mBAAmB,EAAE,kBAAkB,EAAyG,MAAM,SAAS,CAAC;AAKpM,MAAM,WAAW,iBAAkB,SAAQ,mBAAmB;IAC5D,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,MAAM,EAAE,cAAc,EACtB,iBAAiB,EACjB,OAAc,EACd,WAAW,EACX,QAAQ,GACT,EAAE,iBAAiB,qBAytBnB"}
|
package/dist/AuthProvider.js
CHANGED
|
@@ -6,10 +6,10 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
6
6
|
* This source code is licensed under the MIT license found in the
|
|
7
7
|
* LICENSE file in the root directory of this source tree.
|
|
8
8
|
*/
|
|
9
|
-
import { useState, useEffect, useCallback, useMemo } from 'react';
|
|
9
|
+
import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
|
10
10
|
import { authGateEvents } from './auth-gate-events';
|
|
11
11
|
import { AuthCtx } from './AuthContext';
|
|
12
|
-
import { createAuthClient } from './createAuthClient';
|
|
12
|
+
import { createAuthClient, TokenStorage } from './createAuthClient';
|
|
13
13
|
import { ActiveOrganizationStorage } from './createAuthenticatedFetch';
|
|
14
14
|
/**
|
|
15
15
|
* Authentication context provider.
|
|
@@ -55,6 +55,88 @@ export function AuthProvider({ authUrl, client: externalClient, onAuthStateChang
|
|
|
55
55
|
const isAuthenticated = (enabled && !isPreviewMode)
|
|
56
56
|
? user !== null && session !== null
|
|
57
57
|
: true;
|
|
58
|
+
// True while `loadSession` is awaiting the server. Read by the rotation
|
|
59
|
+
// subscription below: a rotation the server performs INSIDE our own
|
|
60
|
+
// `getSession` is already reflected in the answer we are about to apply, and
|
|
61
|
+
// re-entering on it would loop this provider against the server forever.
|
|
62
|
+
const sessionLoadInFlight = useRef(false);
|
|
63
|
+
/**
|
|
64
|
+
* The ONE session loader. Runs on mount (below) and on every later
|
|
65
|
+
* re-resolution — `refreshSession` on the context, and the rotation
|
|
66
|
+
* subscription — so "how the console learns who it is" has a single
|
|
67
|
+
* implementation rather than one per caller.
|
|
68
|
+
*
|
|
69
|
+
* `isCancelled` mirrors `refreshOrganizations` further down: an unmount or a
|
|
70
|
+
* superseding call must not write state, and must not clear the loading flag
|
|
71
|
+
* on behalf of a newer load.
|
|
72
|
+
*/
|
|
73
|
+
const loadSession = useCallback(async (isCancelled) => {
|
|
74
|
+
sessionLoadInFlight.current = true;
|
|
75
|
+
try {
|
|
76
|
+
const result = await client.getSession();
|
|
77
|
+
if (isCancelled?.())
|
|
78
|
+
return;
|
|
79
|
+
if (result) {
|
|
80
|
+
setUser(result.user);
|
|
81
|
+
setSession(result.session);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
// A re-resolution that comes back empty means the session ENDED
|
|
85
|
+
// (revoked, expired, signed out in another tab). On mount both are
|
|
86
|
+
// already null, so this changes nothing there.
|
|
87
|
+
setUser(null);
|
|
88
|
+
setSession(null);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
if (isCancelled?.())
|
|
93
|
+
return;
|
|
94
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
sessionLoadInFlight.current = false;
|
|
98
|
+
if (!isCancelled?.()) {
|
|
99
|
+
setIsLoading(false);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}, [client]);
|
|
103
|
+
/**
|
|
104
|
+
* objectui#4467 — re-resolve identity in place. Never raises `isLoading`:
|
|
105
|
+
* the console stays on screen while the answer is fetched (`loadSession`
|
|
106
|
+
* only ever lowers the flag). Guest / preview identities are synthetic and
|
|
107
|
+
* have no server to ask, so this is a no-op there.
|
|
108
|
+
*/
|
|
109
|
+
const refreshSession = useCallback(async () => {
|
|
110
|
+
if (!enabled || isPreviewMode)
|
|
111
|
+
return;
|
|
112
|
+
await loadSession();
|
|
113
|
+
}, [enabled, isPreviewMode, loadSession]);
|
|
114
|
+
/**
|
|
115
|
+
* objectui#4467 — an OWNERLESS session rotation re-resolves identity.
|
|
116
|
+
*
|
|
117
|
+
* `TokenStorage` notifies only when a token we already held is replaced by a
|
|
118
|
+
* different one (see its header). Sign-in / sign-out do not qualify: those
|
|
119
|
+
* callers update identity themselves. What does qualify is a rotation
|
|
120
|
+
* observed on the wire by code that has no idea it just changed who the user
|
|
121
|
+
* is — `createAuthenticatedFetch` capturing `set-auth-token` from a generic
|
|
122
|
+
* metadata action, which is exactly how the console starts and stops
|
|
123
|
+
* impersonation.
|
|
124
|
+
*
|
|
125
|
+
* This is the honest seam for the refresh. The console's action runtime
|
|
126
|
+
* executes `type: 'api'` actions generically; it cannot know that one
|
|
127
|
+
* particular endpoint was auth-relevant without hard-coding that endpoint
|
|
128
|
+
* into a generic runtime. The rotation IS the signal, and it is the server's
|
|
129
|
+
* own declaration rather than our guess about the URL.
|
|
130
|
+
*/
|
|
131
|
+
useEffect(() => {
|
|
132
|
+
if (!enabled || isPreviewMode)
|
|
133
|
+
return;
|
|
134
|
+
return TokenStorage.subscribeRotation(() => {
|
|
135
|
+
if (sessionLoadInFlight.current)
|
|
136
|
+
return;
|
|
137
|
+
void loadSession();
|
|
138
|
+
});
|
|
139
|
+
}, [enabled, isPreviewMode, loadSession]);
|
|
58
140
|
// Load session on mount (only if auth is enabled and not in preview mode)
|
|
59
141
|
useEffect(() => {
|
|
60
142
|
if (isPreviewMode) {
|
|
@@ -95,30 +177,9 @@ export function AuthProvider({ authUrl, client: externalClient, onAuthStateChang
|
|
|
95
177
|
return;
|
|
96
178
|
}
|
|
97
179
|
let cancelled = false;
|
|
98
|
-
|
|
99
|
-
try {
|
|
100
|
-
const result = await client.getSession();
|
|
101
|
-
if (cancelled)
|
|
102
|
-
return;
|
|
103
|
-
if (result) {
|
|
104
|
-
setUser(result.user);
|
|
105
|
-
setSession(result.session);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
catch (err) {
|
|
109
|
-
if (cancelled)
|
|
110
|
-
return;
|
|
111
|
-
setError(err instanceof Error ? err : new Error(String(err)));
|
|
112
|
-
}
|
|
113
|
-
finally {
|
|
114
|
-
if (!cancelled) {
|
|
115
|
-
setIsLoading(false);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
loadSession();
|
|
180
|
+
loadSession(() => cancelled);
|
|
120
181
|
return () => { cancelled = true; };
|
|
121
|
-
}, [client, enabled, isPreviewMode, previewMode]);
|
|
182
|
+
}, [client, enabled, isPreviewMode, previewMode, loadSession]);
|
|
122
183
|
// Notify on auth state changes
|
|
123
184
|
useEffect(() => {
|
|
124
185
|
onAuthStateChange?.({
|
|
@@ -527,6 +588,7 @@ export function AuthProvider({ authUrl, client: externalClient, onAuthStateChang
|
|
|
527
588
|
signIn,
|
|
528
589
|
signUp,
|
|
529
590
|
signOut,
|
|
591
|
+
refreshSession,
|
|
530
592
|
updateUser,
|
|
531
593
|
forgotPassword,
|
|
532
594
|
sendVerificationEmail,
|
|
@@ -568,7 +630,7 @@ export function AuthProvider({ authUrl, client: externalClient, onAuthStateChang
|
|
|
568
630
|
listUserInvitations,
|
|
569
631
|
}), [
|
|
570
632
|
user, session, isAuthenticated, isAuthEnabled, isLoading, error, isPreviewMode, previewMode,
|
|
571
|
-
signIn, signUp, signOut, updateUser, forgotPassword, sendVerificationEmail, resetPassword, changePassword, setInitialPassword, hasLocalPassword, getAuthConfig, signInWithProvider,
|
|
633
|
+
signIn, signUp, signOut, refreshSession, updateUser, forgotPassword, sendVerificationEmail, resetPassword, changePassword, setInitialPassword, hasLocalPassword, getAuthConfig, signInWithProvider,
|
|
572
634
|
sendPhoneOtp, signInWithPhoneOtp, signInWithPhonePassword, requestPhonePasswordReset, resetPasswordWithPhoneOtp,
|
|
573
635
|
remediationRequired, enrollTotp, verifyTotp,
|
|
574
636
|
organizations, activeOrganization, activeMember, isOrganizationsLoading, switchOrganization, createOrganization, refreshOrganizations,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ForgotPasswordForm.d.ts","sourceRoot":"","sources":["../src/ForgotPasswordForm.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAYtD,qDAAqD;AACrD,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qFAAqF;IACrF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6FAA6F;IAC7F,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mFAAmF;IACnF,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4FAA4F;IAC5F,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2FAA2F;IAC3F,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gDAAgD;IAChD,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,wBAAwB;IACxB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAC5D,uCAAuC;IACvC,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAqBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,SAAS,EACT,OAAO,EACP,QAAmB,EACnB,KAA6B,EAC7B,WAAyF,EACzF,IAAI,EACJ,QAAgB,EAChB,aAAa,EAAE,QAAsB,EACrC,MAAW,GACZ,EAAE,uBAAuB,
|
|
1
|
+
{"version":3,"file":"ForgotPasswordForm.d.ts","sourceRoot":"","sources":["../src/ForgotPasswordForm.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAYtD,qDAAqD;AACrD,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qFAAqF;IACrF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6FAA6F;IAC7F,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mFAAmF;IACnF,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4FAA4F;IAC5F,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2FAA2F;IAC3F,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gDAAgD;IAChD,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,wBAAwB;IACxB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAC5D,uCAAuC;IACvC,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAqBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,SAAS,EACT,OAAO,EACP,QAAmB,EACnB,KAA6B,EAC7B,WAAyF,EACzF,IAAI,EACJ,QAAgB,EAChB,aAAa,EAAE,QAAsB,EACrC,MAAW,GACZ,EAAE,uBAAuB,qBA0UzB"}
|
|
@@ -95,7 +95,8 @@ export function ForgotPasswordForm({ onSuccess, onError, loginUrl = '/login', ti
|
|
|
95
95
|
e.preventDefault();
|
|
96
96
|
setError(null);
|
|
97
97
|
try {
|
|
98
|
-
|
|
98
|
+
// Trim pasted/autofilled whitespace before the reset request (#3238).
|
|
99
|
+
await forgotPassword(email.trim());
|
|
99
100
|
setSubmitted(true);
|
|
100
101
|
onSuccess?.();
|
|
101
102
|
}
|
package/dist/LoginForm.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoginForm.d.ts","sourceRoot":"","sources":["../src/LoginForm.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAYtD,4CAA4C;AAC5C,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6FAA6F;IAC7F,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,6DAA6D;IAC7D,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8GAA8G;IAC9G,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wFAAwF;IACxF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gGAAgG;IAChG,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,8FAA8F;IAC9F,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iGAAiG;IACjG,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,yHAAyH;IACzH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,mCAAmC;IACnC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAC5D,uCAAuC;IACvC,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAsBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,EACxB,SAAS,EACT,OAAO,EACP,WAAyB,EACzB,iBAAsC,EACtC,KAAiC,EACjC,WAAyD,EACzD,IAAI,EACJ,QAAgB,EAChB,aAAa,EAAE,QAAsB,EACrC,MAAW,EACX,aAAa,GACd,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"LoginForm.d.ts","sourceRoot":"","sources":["../src/LoginForm.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAYtD,4CAA4C;AAC5C,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6FAA6F;IAC7F,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,6DAA6D;IAC7D,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8GAA8G;IAC9G,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wFAAwF;IACxF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gGAAgG;IAChG,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,8FAA8F;IAC9F,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iGAAiG;IACjG,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,yHAAyH;IACzH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,mCAAmC;IACnC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAC5D,uCAAuC;IACvC,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAsBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,EACxB,SAAS,EACT,OAAO,EACP,WAAyB,EACzB,iBAAsC,EACtC,KAAiC,EACjC,WAAyD,EACzD,IAAI,EACJ,QAAgB,EAChB,aAAa,EAAE,QAAsB,EACrC,MAAW,EACX,aAAa,GACd,EAAE,cAAc,qBAgbhB"}
|
package/dist/LoginForm.js
CHANGED
|
@@ -141,18 +141,21 @@ export function LoginForm({ onSuccess, onError, registerUrl = '/register', forgo
|
|
|
141
141
|
const handleSubmit = async (e) => {
|
|
142
142
|
e.preventDefault();
|
|
143
143
|
setError(null);
|
|
144
|
+
// Autofill and copy-paste routinely smuggle in leading/trailing whitespace
|
|
145
|
+
// that the server rejects as "Invalid email" (#3238) — trim before use.
|
|
146
|
+
const identifier = email.trim();
|
|
144
147
|
try {
|
|
145
148
|
if (mode === 'phone-otp') {
|
|
146
149
|
await signInWithPhoneOtp(phone.trim(), otpCode.trim());
|
|
147
150
|
}
|
|
148
|
-
else if (phonePasswordEnabled && looksLikePhoneIdentifier(
|
|
151
|
+
else if (phonePasswordEnabled && looksLikePhoneIdentifier(identifier)) {
|
|
149
152
|
// Unified identifier: a phone-shaped entry routes to phone+password.
|
|
150
153
|
// Normalize identically to the backend (strip formatting, no country
|
|
151
154
|
// code) or the phoneNumber lookup fails.
|
|
152
|
-
await signInWithPhonePassword(normalizePhoneIdentifier(
|
|
155
|
+
await signInWithPhonePassword(normalizePhoneIdentifier(identifier) ?? identifier, password);
|
|
153
156
|
}
|
|
154
157
|
else {
|
|
155
|
-
await signIn(
|
|
158
|
+
await signIn(identifier, password);
|
|
156
159
|
}
|
|
157
160
|
onSuccess?.();
|
|
158
161
|
}
|
|
@@ -202,8 +205,9 @@ export function LoginForm({ onSuccess, onError, registerUrl = '/register', forgo
|
|
|
202
205
|
if (ssoSubmitting)
|
|
203
206
|
return;
|
|
204
207
|
setError(null);
|
|
208
|
+
const identifier = email.trim();
|
|
205
209
|
// SSO routes by email domain — a phone-shaped identifier can't map to an IdP.
|
|
206
|
-
if (looksLikePhoneIdentifier(
|
|
210
|
+
if (looksLikePhoneIdentifier(identifier)) {
|
|
207
211
|
setError('Enter your email address to sign in with SSO.');
|
|
208
212
|
return;
|
|
209
213
|
}
|
|
@@ -213,7 +217,7 @@ export function LoginForm({ onSuccess, onError, registerUrl = '/register', forgo
|
|
|
213
217
|
const res = await fetch('/api/v1/auth/sign-in/sso', {
|
|
214
218
|
method: 'POST',
|
|
215
219
|
headers: { 'content-type': 'application/json' },
|
|
216
|
-
body: JSON.stringify({ email, callbackURL: base + '/home' }),
|
|
220
|
+
body: JSON.stringify({ email: identifier, callbackURL: base + '/home' }),
|
|
217
221
|
credentials: 'include',
|
|
218
222
|
});
|
|
219
223
|
const data = (await res.json().catch(() => ({})));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RegisterForm.d.ts","sourceRoot":"","sources":["../src/RegisterForm.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAWtD,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC;sFACkF;IAClF,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB;;2CAEuC;IACvC,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,qCAAqC;IACrC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAC5D,uCAAuC;IACvC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAwBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,sBAAsB,EACtB,OAAO,EACP,QAAmB,EACnB,KAA2B,EAC3B,WAAqD,EACrD,IAAI,EACJ,QAAgB,EAChB,aAAa,EAAE,QAAsB,EACrC,MAAW,EACX,aAAa,GACd,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"RegisterForm.d.ts","sourceRoot":"","sources":["../src/RegisterForm.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAWtD,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC;sFACkF;IAClF,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB;;2CAEuC;IACvC,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,qCAAqC;IACrC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAC5D,uCAAuC;IACvC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAwBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,sBAAsB,EACtB,OAAO,EACP,QAAmB,EACnB,KAA2B,EAC3B,WAAqD,EACrD,IAAI,EACJ,QAAgB,EAChB,aAAa,EAAE,QAAsB,EACrC,MAAW,EACX,aAAa,GACd,EAAE,iBAAiB,qBAuKnB"}
|
package/dist/RegisterForm.js
CHANGED
|
@@ -60,10 +60,13 @@ export function RegisterForm({ onSuccess, onVerificationRequired, onError, login
|
|
|
60
60
|
setError(l.passwordTooShortError);
|
|
61
61
|
return;
|
|
62
62
|
}
|
|
63
|
+
// Autofill and copy-paste routinely smuggle in leading/trailing whitespace
|
|
64
|
+
// that the server rejects as "Invalid email" (#3238) — trim before use.
|
|
65
|
+
const trimmedEmail = email.trim();
|
|
63
66
|
try {
|
|
64
|
-
const result = await signUp(name,
|
|
67
|
+
const result = await signUp(name, trimmedEmail, password);
|
|
65
68
|
if (result?.requiresVerification) {
|
|
66
|
-
onVerificationRequired?.(
|
|
69
|
+
onVerificationRequired?.(trimmedEmail);
|
|
67
70
|
return;
|
|
68
71
|
}
|
|
69
72
|
onSuccess?.();
|
|
@@ -9,12 +9,34 @@ import type { AuthClient, AuthClientConfig } from './types';
|
|
|
9
9
|
/**
|
|
10
10
|
* Simple token storage backed by localStorage.
|
|
11
11
|
* Falls back to in-memory storage when localStorage is unavailable (SSR, tests).
|
|
12
|
+
*
|
|
13
|
+
* ## Rotation notifications (objectui#4467)
|
|
14
|
+
*
|
|
15
|
+
* `subscribeRotation` fires when a token WE ALREADY HELD is replaced by a
|
|
16
|
+
* different one — i.e. the server rotated the session under a request nobody
|
|
17
|
+
* was watching. That is the only case with no owner: sign-in, sign-up and
|
|
18
|
+
* sign-out all set/clear this storage from `AuthProvider`, which updates its
|
|
19
|
+
* own identity state in the same breath, so those transitions deliberately
|
|
20
|
+
* stay silent (first store: no notify; `clear()`: no notify; re-storing the
|
|
21
|
+
* same value, as `getSession` does on every boot: no notify).
|
|
22
|
+
*
|
|
23
|
+
* A rotation with no owner is exactly what impersonation produces — the
|
|
24
|
+
* console POSTs `/auth/admin/impersonate-user` through a generic metadata
|
|
25
|
+
* action, the server hands back a NEW session token in `set-auth-token`, and
|
|
26
|
+
* nothing in that code path knows the identity just changed. See
|
|
27
|
+
* `AuthProvider`'s subscription and `__tests__/impersonation-lane-4467.test.tsx`.
|
|
12
28
|
*/
|
|
13
29
|
export declare const TokenStorage: {
|
|
14
30
|
_memoryToken: string | null;
|
|
31
|
+
_rotationListeners: Set<() => void>;
|
|
15
32
|
get(): string | null;
|
|
16
33
|
set(token: string): void;
|
|
17
34
|
clear(): void;
|
|
35
|
+
/**
|
|
36
|
+
* Observe session-token ROTATIONS (see the header for what does and does not
|
|
37
|
+
* count as one). Returns an unsubscribe function.
|
|
38
|
+
*/
|
|
39
|
+
subscribeRotation(listener: () => void): () => void;
|
|
18
40
|
};
|
|
19
41
|
/**
|
|
20
42
|
* Create an auth client instance backed by the official better-auth client.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createAuthClient.d.ts","sourceRoot":"","sources":["../src/createAuthClient.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EACV,UAAU,EAAE,gBAAgB,EAE7B,MAAM,SAAS,CAAC;AAIjB
|
|
1
|
+
{"version":3,"file":"createAuthClient.d.ts","sourceRoot":"","sources":["../src/createAuthClient.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EACV,UAAU,EAAE,gBAAgB,EAE7B,MAAM,SAAS,CAAC;AAIjB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,YAAY;kBACD,MAAM,GAAG,IAAI;kCACD,IAAI;WAE/B,MAAM,GAAG,IAAI;eAST,MAAM,GAAG,IAAI;aAkBf,IAAI;IASb;;;OAGG;gCACyB,MAAM,IAAI,GAAG,MAAM,IAAI;CAMpD,CAAC;AAwIF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,UAAU,CAqrBrE"}
|
package/dist/createAuthClient.js
CHANGED
|
@@ -11,9 +11,26 @@ const TOKEN_STORAGE_KEY = 'auth-session-token';
|
|
|
11
11
|
/**
|
|
12
12
|
* Simple token storage backed by localStorage.
|
|
13
13
|
* Falls back to in-memory storage when localStorage is unavailable (SSR, tests).
|
|
14
|
+
*
|
|
15
|
+
* ## Rotation notifications (objectui#4467)
|
|
16
|
+
*
|
|
17
|
+
* `subscribeRotation` fires when a token WE ALREADY HELD is replaced by a
|
|
18
|
+
* different one — i.e. the server rotated the session under a request nobody
|
|
19
|
+
* was watching. That is the only case with no owner: sign-in, sign-up and
|
|
20
|
+
* sign-out all set/clear this storage from `AuthProvider`, which updates its
|
|
21
|
+
* own identity state in the same breath, so those transitions deliberately
|
|
22
|
+
* stay silent (first store: no notify; `clear()`: no notify; re-storing the
|
|
23
|
+
* same value, as `getSession` does on every boot: no notify).
|
|
24
|
+
*
|
|
25
|
+
* A rotation with no owner is exactly what impersonation produces — the
|
|
26
|
+
* console POSTs `/auth/admin/impersonate-user` through a generic metadata
|
|
27
|
+
* action, the server hands back a NEW session token in `set-auth-token`, and
|
|
28
|
+
* nothing in that code path knows the identity just changed. See
|
|
29
|
+
* `AuthProvider`'s subscription and `__tests__/impersonation-lane-4467.test.tsx`.
|
|
14
30
|
*/
|
|
15
31
|
export const TokenStorage = {
|
|
16
32
|
_memoryToken: null,
|
|
33
|
+
_rotationListeners: new Set(),
|
|
17
34
|
get() {
|
|
18
35
|
try {
|
|
19
36
|
if (typeof localStorage !== 'undefined') {
|
|
@@ -24,6 +41,7 @@ export const TokenStorage = {
|
|
|
24
41
|
return this._memoryToken;
|
|
25
42
|
},
|
|
26
43
|
set(token) {
|
|
44
|
+
const previous = this.get();
|
|
27
45
|
this._memoryToken = token;
|
|
28
46
|
try {
|
|
29
47
|
if (typeof localStorage !== 'undefined') {
|
|
@@ -31,6 +49,15 @@ export const TokenStorage = {
|
|
|
31
49
|
}
|
|
32
50
|
}
|
|
33
51
|
catch { /* SSR / test */ }
|
|
52
|
+
// Rotation = a token we were already using got replaced. See the header.
|
|
53
|
+
if (previous && previous !== token) {
|
|
54
|
+
for (const listener of [...this._rotationListeners]) {
|
|
55
|
+
try {
|
|
56
|
+
listener();
|
|
57
|
+
}
|
|
58
|
+
catch { /* a listener must never break the write that triggered it */ }
|
|
59
|
+
}
|
|
60
|
+
}
|
|
34
61
|
},
|
|
35
62
|
clear() {
|
|
36
63
|
this._memoryToken = null;
|
|
@@ -41,15 +68,43 @@ export const TokenStorage = {
|
|
|
41
68
|
}
|
|
42
69
|
catch { /* SSR / test */ }
|
|
43
70
|
},
|
|
71
|
+
/**
|
|
72
|
+
* Observe session-token ROTATIONS (see the header for what does and does not
|
|
73
|
+
* count as one). Returns an unsubscribe function.
|
|
74
|
+
*/
|
|
75
|
+
subscribeRotation(listener) {
|
|
76
|
+
this._rotationListeners.add(listener);
|
|
77
|
+
return () => {
|
|
78
|
+
this._rotationListeners.delete(listener);
|
|
79
|
+
};
|
|
80
|
+
},
|
|
44
81
|
};
|
|
45
82
|
/**
|
|
46
83
|
* Build an `Error` from a better-auth client error, preserving the machine
|
|
47
|
-
* `code` on the thrown Error so callers (LoginForm/RegisterForm
|
|
48
|
-
* a localized message instead of surfacing
|
|
49
|
-
* back to the server message, then
|
|
84
|
+
* `code` on the thrown Error so callers (LoginForm/RegisterForm, and every
|
|
85
|
+
* organization screen) can map it to a localized message instead of surfacing
|
|
86
|
+
* the raw English server text. Falls back to the server message, then
|
|
87
|
+
* `fallbackMessage`, then the HTTP status.
|
|
88
|
+
*
|
|
89
|
+
* ## Why every organization route now comes through here (objectui#4474)
|
|
90
|
+
*
|
|
91
|
+
* This helper existed for sign-in/sign-up only. Every `organization.*` method
|
|
92
|
+
* below threw `new Error(error.message ?? '…')` directly and therefore **dropped
|
|
93
|
+
* `code` at the boundary** — so a console screen holding the rejection had the
|
|
94
|
+
* English sentence and nothing else to key on. That is what forced the
|
|
95
|
+
* organization UI to echo better-auth's English verbatim in a zh session: the
|
|
96
|
+
* only remaining way to localize it would have been matching the English text,
|
|
97
|
+
* which binds the console to a third party's copy-editing and breaks silently
|
|
98
|
+
* the day they reword a sentence.
|
|
99
|
+
*
|
|
100
|
+
* The repair belongs HERE rather than at the console call sites: the code is
|
|
101
|
+
* produced at this boundary, and a consumer cannot recover information the
|
|
102
|
+
* producer discarded. `message` is unchanged for every caller — this only stops
|
|
103
|
+
* throwing away the half of the pair that was already being computed.
|
|
104
|
+
* `packages/auth/src/__tests__/org-error-code-4474.test.ts` pins both halves.
|
|
50
105
|
*/
|
|
51
|
-
function toAuthError(error) {
|
|
52
|
-
const err = new Error(error.message ?? `Auth request failed with status ${error.status}`);
|
|
106
|
+
function toAuthError(error, fallbackMessage) {
|
|
107
|
+
const err = new Error(error.message ?? fallbackMessage ?? `Auth request failed with status ${error.status}`);
|
|
53
108
|
if (error.code)
|
|
54
109
|
err.code = error.code;
|
|
55
110
|
return err;
|
|
@@ -630,7 +685,7 @@ export function createAuthClient(config) {
|
|
|
630
685
|
async listOrganizations() {
|
|
631
686
|
const { data, error } = await betterAuth.organization.list();
|
|
632
687
|
if (error)
|
|
633
|
-
throw
|
|
688
|
+
throw toAuthError(error, 'Failed to list organizations');
|
|
634
689
|
return (data ?? []);
|
|
635
690
|
},
|
|
636
691
|
async createOrganization(orgData) {
|
|
@@ -640,7 +695,7 @@ export function createAuthClient(config) {
|
|
|
640
695
|
logo: orgData.logo,
|
|
641
696
|
});
|
|
642
697
|
if (error)
|
|
643
|
-
throw
|
|
698
|
+
throw toAuthError(error, 'Failed to create organization');
|
|
644
699
|
return data;
|
|
645
700
|
},
|
|
646
701
|
async setActiveOrganization(orgId) {
|
|
@@ -648,7 +703,7 @@ export function createAuthClient(config) {
|
|
|
648
703
|
organizationId: orgId,
|
|
649
704
|
});
|
|
650
705
|
if (error)
|
|
651
|
-
throw
|
|
706
|
+
throw toAuthError(error, 'Failed to set active organization');
|
|
652
707
|
return (data ?? null);
|
|
653
708
|
},
|
|
654
709
|
async getActiveOrganization() {
|
|
@@ -677,7 +732,7 @@ export function createAuthClient(config) {
|
|
|
677
732
|
query: { organizationId: orgId },
|
|
678
733
|
});
|
|
679
734
|
if (error)
|
|
680
|
-
throw
|
|
735
|
+
throw toAuthError(error, 'Failed to get members');
|
|
681
736
|
const result = data;
|
|
682
737
|
if (Array.isArray(result))
|
|
683
738
|
return result;
|
|
@@ -697,7 +752,7 @@ export function createAuthClient(config) {
|
|
|
697
752
|
...(inviteData.positions?.length ? { positions: inviteData.positions } : {}),
|
|
698
753
|
});
|
|
699
754
|
if (error)
|
|
700
|
-
throw
|
|
755
|
+
throw toAuthError(error, 'Failed to invite member');
|
|
701
756
|
return data;
|
|
702
757
|
},
|
|
703
758
|
async removeMember(removeData) {
|
|
@@ -706,7 +761,7 @@ export function createAuthClient(config) {
|
|
|
706
761
|
memberIdOrUserId: removeData.memberIdOrUserId,
|
|
707
762
|
});
|
|
708
763
|
if (error)
|
|
709
|
-
throw
|
|
764
|
+
throw toAuthError(error, 'Failed to remove member');
|
|
710
765
|
},
|
|
711
766
|
async updateMemberRole(payload) {
|
|
712
767
|
const { error } = await betterAuth.organization.updateMemberRole({
|
|
@@ -715,7 +770,7 @@ export function createAuthClient(config) {
|
|
|
715
770
|
role: payload.role,
|
|
716
771
|
});
|
|
717
772
|
if (error)
|
|
718
|
-
throw
|
|
773
|
+
throw toAuthError(error, 'Failed to update member role');
|
|
719
774
|
},
|
|
720
775
|
async updateOrganization(orgId, orgData) {
|
|
721
776
|
const { data, error } = await betterAuth.organization.update({
|
|
@@ -723,7 +778,7 @@ export function createAuthClient(config) {
|
|
|
723
778
|
data: orgData,
|
|
724
779
|
});
|
|
725
780
|
if (error)
|
|
726
|
-
throw
|
|
781
|
+
throw toAuthError(error, 'Failed to update organization');
|
|
727
782
|
return data;
|
|
728
783
|
},
|
|
729
784
|
async deleteOrganization(orgId) {
|
|
@@ -731,14 +786,14 @@ export function createAuthClient(config) {
|
|
|
731
786
|
organizationId: orgId,
|
|
732
787
|
});
|
|
733
788
|
if (error)
|
|
734
|
-
throw
|
|
789
|
+
throw toAuthError(error, 'Failed to delete organization');
|
|
735
790
|
},
|
|
736
791
|
async leaveOrganization(orgId) {
|
|
737
792
|
const { error } = await betterAuth.organization.leave({
|
|
738
793
|
organizationId: orgId,
|
|
739
794
|
});
|
|
740
795
|
if (error)
|
|
741
|
-
throw
|
|
796
|
+
throw toAuthError(error, 'Failed to leave organization');
|
|
742
797
|
},
|
|
743
798
|
// --- Invitation methods ---
|
|
744
799
|
async listInvitations(orgId) {
|
|
@@ -746,36 +801,36 @@ export function createAuthClient(config) {
|
|
|
746
801
|
query: { organizationId: orgId },
|
|
747
802
|
});
|
|
748
803
|
if (error)
|
|
749
|
-
throw
|
|
804
|
+
throw toAuthError(error, 'Failed to list invitations');
|
|
750
805
|
return (data ?? []);
|
|
751
806
|
},
|
|
752
807
|
async cancelInvitation(invitationId) {
|
|
753
808
|
const { error } = await betterAuth.organization.cancelInvitation({ invitationId });
|
|
754
809
|
if (error)
|
|
755
|
-
throw
|
|
810
|
+
throw toAuthError(error, 'Failed to cancel invitation');
|
|
756
811
|
},
|
|
757
812
|
async getInvitation(invitationId) {
|
|
758
813
|
const { data, error } = await betterAuth.organization.getInvitation({
|
|
759
814
|
query: { id: invitationId },
|
|
760
815
|
});
|
|
761
816
|
if (error)
|
|
762
|
-
throw
|
|
817
|
+
throw toAuthError(error, 'Failed to load invitation');
|
|
763
818
|
return data;
|
|
764
819
|
},
|
|
765
820
|
async acceptInvitation(invitationId) {
|
|
766
821
|
const { error } = await betterAuth.organization.acceptInvitation({ invitationId });
|
|
767
822
|
if (error)
|
|
768
|
-
throw
|
|
823
|
+
throw toAuthError(error, 'Failed to accept invitation');
|
|
769
824
|
},
|
|
770
825
|
async rejectInvitation(invitationId) {
|
|
771
826
|
const { error } = await betterAuth.organization.rejectInvitation({ invitationId });
|
|
772
827
|
if (error)
|
|
773
|
-
throw
|
|
828
|
+
throw toAuthError(error, 'Failed to reject invitation');
|
|
774
829
|
},
|
|
775
830
|
async listUserInvitations() {
|
|
776
831
|
const { data, error } = await betterAuth.organization.listUserInvitations();
|
|
777
832
|
if (error)
|
|
778
|
-
throw
|
|
833
|
+
throw toAuthError(error, 'Failed to list invitations');
|
|
779
834
|
return (data ?? []);
|
|
780
835
|
},
|
|
781
836
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createAuthenticatedFetch.d.ts","sourceRoot":"","sources":["../src/createAuthenticatedFetch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAID;;;GAGG;AACH,eAAO,MAAM,yBAAyB;kBACd,MAAM,GAAG,IAAI;WAE5B,MAAM,GAAG,IAAI;eAST,MAAM,GAAG,IAAI;aASf,IAAI;CAQd,CAAC;AAEF,MAAM,WAAW,+BAA+B;IAC9C;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAYD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,CAAC,EAAE,+BAA+B,GACxC,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"createAuthenticatedFetch.d.ts","sourceRoot":"","sources":["../src/createAuthenticatedFetch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAID;;;GAGG;AACH,eAAO,MAAM,yBAAyB;kBACd,MAAM,GAAG,IAAI;WAE5B,MAAM,GAAG,IAAI;eAST,MAAM,GAAG,IAAI;aASf,IAAI;CAQd,CAAC;AAEF,MAAM,WAAW,+BAA+B;IAC9C;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAYD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,CAAC,EAAE,+BAA+B,GACxC,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CA2ErE"}
|
|
@@ -103,6 +103,39 @@ export function createAuthenticatedFetch(options) {
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
const response = await fetch(input, { ...init, headers });
|
|
106
|
+
// Adopt a session rotation the server declares on the response, exactly as
|
|
107
|
+
// the auth lane already does (`createBearerFetch` in createAuthClient.ts).
|
|
108
|
+
//
|
|
109
|
+
// ## Why this lane needs it too (objectui#4467)
|
|
110
|
+
//
|
|
111
|
+
// The console injects the same localStorage bearer from two places: the
|
|
112
|
+
// AUTH lane (sign-in / get-session / the auth endpoints) and THIS one — the
|
|
113
|
+
// adapter, `provider: 'api'` data sources, and every metadata `type: 'api'`
|
|
114
|
+
// action (`useConsoleActionRuntime`'s `apiHandler`). better-auth's
|
|
115
|
+
// server-side bearer plugin hands a rotated session token back in
|
|
116
|
+
// `set-auth-token` on whichever lane the call arrived over. Only the auth
|
|
117
|
+
// lane read it, so a rotation issued to a data-lane call was dropped on the
|
|
118
|
+
// floor and the browser kept sending the OLD token.
|
|
119
|
+
//
|
|
120
|
+
// Impersonation is exactly that call: `POST /auth/admin/impersonate-user`
|
|
121
|
+
// runs as an ordinary metadata action, so the impersonated session token
|
|
122
|
+
// arrived here and was discarded — while the server's bearer plugin kept
|
|
123
|
+
// overwriting the impersonation cookie with the admin bearer we kept
|
|
124
|
+
// sending. Impersonation was a complete no-op in the console, not merely an
|
|
125
|
+
// invisible one.
|
|
126
|
+
//
|
|
127
|
+
// The rule is the server's declared contract and carries no knowledge of
|
|
128
|
+
// which endpoint rotated: one contract, one answer, on both lanes. Gated on
|
|
129
|
+
// `isApiCall` — the same condition that decided we authenticated this
|
|
130
|
+
// request at all — so a response we never sent the bearer to cannot rotate
|
|
131
|
+
// the session. Untrusted targets are the `sameOriginOnly` option's job (it
|
|
132
|
+
// short-circuits above, before any header work).
|
|
133
|
+
if (isApiCall) {
|
|
134
|
+
const rotatedToken = response.headers.get('set-auth-token');
|
|
135
|
+
if (rotatedToken) {
|
|
136
|
+
TokenStorage.set(rotatedToken);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
106
139
|
// ADR-0069 — surface an auth-policy gate (expired password / required MFA)
|
|
107
140
|
// to the remediation overlay. Clone so the caller still reads the body.
|
|
108
141
|
if (isApiCall && response.status === 403) {
|
package/dist/types.d.ts
CHANGED
|
@@ -85,6 +85,18 @@ export interface AuthClientSession {
|
|
|
85
85
|
expiresAt?: Date;
|
|
86
86
|
/** Refresh token */
|
|
87
87
|
refreshToken?: string;
|
|
88
|
+
/**
|
|
89
|
+
* objectui#4467 — set by better-auth's admin plugin while this session is an
|
|
90
|
+
* IMPERSONATION: the id of the administrator who started it. Present on
|
|
91
|
+
* `GET /auth/get-session` for the whole life of the impersonated session, so
|
|
92
|
+
* a console that reads it survives full SPA reboots (it is a property of the
|
|
93
|
+
* session, not a memory of the click that created it).
|
|
94
|
+
*
|
|
95
|
+
* Its presence is what raises the impersonation banner — see
|
|
96
|
+
* `@object-ui/app-shell`'s `ImpersonationBanner`. Absent on every ordinary
|
|
97
|
+
* session, which is why the banner costs a normal session nothing.
|
|
98
|
+
*/
|
|
99
|
+
impersonatedBy?: string;
|
|
88
100
|
}
|
|
89
101
|
/** Authentication state */
|
|
90
102
|
export interface AuthState {
|
|
@@ -138,7 +150,36 @@ export interface AuthPublicConfig {
|
|
|
138
150
|
socialProviders?: AuthSocialProvider[];
|
|
139
151
|
features?: {
|
|
140
152
|
twoFactor?: boolean;
|
|
153
|
+
/**
|
|
154
|
+
* RESERVED — declared so the `/auth/config` payload types cleanly, and
|
|
155
|
+
* consumed by nothing in this repository. Enabling it server-side adds
|
|
156
|
+
* **no** passkey entry point to the login page, because there is no passkey
|
|
157
|
+
* sign-in or registration UI for it to gate. Contrast `sso`,
|
|
158
|
+
* `phoneNumberOtp` and `deviceAuthorization` below, which each gate a real
|
|
159
|
+
* surface.
|
|
160
|
+
*
|
|
161
|
+
* Building the flow is objectui#4179, filed unscheduled. This marking
|
|
162
|
+
* follows the maintainer's 2026-08-03 ruling on objectui#2514: document the
|
|
163
|
+
* flag as reserved now, build the UI when the login surface gets roadmap
|
|
164
|
+
* time (at which point it renders driven by this flag).
|
|
165
|
+
*
|
|
166
|
+
* Pinned by `__tests__/reserved-auth-features.test.ts`. That pin fails the
|
|
167
|
+
* moment a consumer appears, because the declaration, this doc comment and
|
|
168
|
+
* `README.md`'s reserved section have to retire in one PR — see the pin's
|
|
169
|
+
* docblock for the retirement checklist.
|
|
170
|
+
*/
|
|
141
171
|
passkeys?: boolean;
|
|
172
|
+
/**
|
|
173
|
+
* RESERVED — declared so the `/auth/config` payload types cleanly, and
|
|
174
|
+
* consumed by nothing in this repository. Enabling it server-side adds
|
|
175
|
+
* **no** "email me a sign-in link" entry point to the login page: there is
|
|
176
|
+
* neither a magic-link request step nor a route that consumes the emailed
|
|
177
|
+
* token.
|
|
178
|
+
*
|
|
179
|
+
* Same ruling, same follow-up card and same pin as `passkeys` above
|
|
180
|
+
* (objectui#2514 / objectui#4179 /
|
|
181
|
+
* `__tests__/reserved-auth-features.test.ts`).
|
|
182
|
+
*/
|
|
142
183
|
magicLink?: boolean;
|
|
143
184
|
organization?: boolean;
|
|
144
185
|
/**
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EACV,QAAQ,IAAI,YAAY,EACxB,cAAc,EACd,mBAAmB,EACpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAEjE;;GAEG;AAEH;;;;;;;;;;;;GAYG;AACH,YAAY,EAAE,cAAc,EAAE,CAAC;AAE/B;;;;;;;;;;;GAWG;AACH,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,CAAC;AAEpD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,QAAS,SAAQ,YAAY;IAC5C,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mBAAmB;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,gCAAgC;IAChC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,+BAA+B;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAWjG;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAiB;IAChC,mBAAmB;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,oBAAoB;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/useAuth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../src/useAuth.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAW,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE/D;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,IAAI,gBAAgB,
|
|
1
|
+
{"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../src/useAuth.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAW,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE/D;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,IAAI,gBAAgB,CA6D1C"}
|
package/dist/useAuth.js
CHANGED
|
@@ -36,6 +36,7 @@ export function useAuth() {
|
|
|
36
36
|
signIn: async () => { throw new Error('useAuth must be used within an AuthProvider'); },
|
|
37
37
|
signUp: async () => { throw new Error('useAuth must be used within an AuthProvider'); },
|
|
38
38
|
signOut: async () => { throw new Error('useAuth must be used within an AuthProvider'); },
|
|
39
|
+
refreshSession: async () => { throw new Error('useAuth must be used within an AuthProvider'); },
|
|
39
40
|
updateUser: async () => { throw new Error('useAuth must be used within an AuthProvider'); },
|
|
40
41
|
forgotPassword: async () => { throw new Error('useAuth must be used within an AuthProvider'); },
|
|
41
42
|
sendVerificationEmail: async () => { throw new Error('useAuth must be used within an AuthProvider'); },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/auth",
|
|
3
|
-
"version": "17.
|
|
3
|
+
"version": "17.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Authentication system for Object UI with AuthProvider, useAuth hook, AuthGuard, and form components.",
|
|
@@ -30,12 +30,12 @@
|
|
|
30
30
|
"react": "^18.0.0 || ^19.0.0"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@objectstack/spec": "^17.0.0-rc.
|
|
34
|
-
"better-auth": "^1.6.
|
|
35
|
-
"@object-ui/types": "17.
|
|
33
|
+
"@objectstack/spec": "^17.0.0-rc.6",
|
|
34
|
+
"better-auth": "^1.6.26",
|
|
35
|
+
"@object-ui/types": "17.5.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@types/react": "19.2.
|
|
38
|
+
"@types/react": "19.2.18",
|
|
39
39
|
"react": "19.2.8",
|
|
40
40
|
"typescript": "^6.0.3",
|
|
41
41
|
"vitest": "^4.1.10"
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"build": "tsc",
|
|
66
66
|
"clean": "rm -rf dist",
|
|
67
67
|
"test": "vitest run",
|
|
68
|
-
"type-check": "tsc --noEmit && tsc -p tsconfig.
|
|
68
|
+
"type-check": "tsc --noEmit && tsc -p tsconfig.test.json",
|
|
69
69
|
"lint": "eslint ."
|
|
70
70
|
}
|
|
71
71
|
}
|