Repository navigation
Commit 8a83814
fix(auth): draw the phone way in on first paint when email+password is off and no single sign-on exists (#31533)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} -->
_Requested by **Steedos** · [project
thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9UbbWNorSGyVMaofehjghex5nx)_
Fixes #31492
Clause-②: no
Metadata-protocol: none
## 维护者速读
-
**改了什么**:邮箱+密码登录关闭、未提供也未强制单点登录、但开了手机登录时,登录卡片首屏直接给出手机号+密码与验证码登录,不再折叠成单点登录视图,也不再出现「返回单点登录」按钮;账号框此时写「手机号」。
- **为什么改**:只靠手机登录的部署,用户打开登录页只看到「改用密码登录」,点进去还有一个指向并不存在的单点登录的返回按钮,首屏没有入口。
- **风险与回滚**:风险低,只改 `@object-ui/auth` 的 `LoginForm`
一个组件的显示判定;有单点登录、强制单点登录、无任何登录方式、配置读取失败这几种情况保持原样(有对照测试)。回滚即 revert 本 PR。
- **先看**:`ui/packages/auth/src/LoginForm.tsx` 的 `passwordFormCollapsed`
与 `formMode`
两处;`ui/packages/auth/src/__tests__/noSignInMethod-29159.test.tsx` 新增的
describe。
- **两分钟验证**:`cd ui && pnpm exec vitest run
packages/auth/src/__tests__/noSignInMethod-29159.test.tsx`,预期 16 个用例全绿。
- **需要你做的**:无,席位落地。
## What changes
`ui/packages/auth/src/LoginForm.tsx`, the card's Mechanism quoted:
"`passwordFormCollapsed = ssoEnforced || passwordSignInOff` (line 342),
and the `backToSsoText` button renders on `passwordFormCollapsed &&
showPasswordFallback` (line 788). #29159 gated only the copy
(`ssoOnlyCopy`, line 510, which checks `ssoEnforced || ssoEnabled`); the
collapse and the back button are not gated on SSO being present."
- **Collapse.** `passwordFormCollapsed = ssoEnforced ||
(passwordSignInOff && (ssoEnabled || !phoneSignInOffered))`, where
`phoneSignInOffered = phonePasswordEnabled || phoneOtpEnabled`. The one
cell that changes is the password door shut, `features.sso` false,
`features.ssoEnforced` false and a phone way in advertised: the form is
drawn on first paint. Every other cell keeps today's collapse. Decided
from the advertised config only; a failed config fetch leaves every flag
at its default and keeps the password form (break-glass).
- **Back to single sign-on.** No new condition: the button still renders
on `passwordFormCollapsed && showPasswordFallback`. After the change the
form collapses only where SSO is enforced or offered, or where the door
is shut with no phone way in, and in that last cell the break-glass link
is never offered (`breakGlassOffered = !passwordSignInOff ||
phonePasswordEnabled`), so the button can only be reached where there is
single sign-on to go back to. The comment above it says so.
- **OTP-only server.** With the password door shut and phone OTP the
only way in, the form opens on the verification-code step (`formMode`)
and does not offer "Sign in with password instead", a switch to a form
the server refuses. Without this, the uncollapsed card would have drawn
an email+password form on first paint.
- **Identifier label.** The brief asked me to report whether the
identifier keeps reading "Email or phone number" while email sign-in is
refused. I changed it: with the password door shut and phone+password
on, the field reads "Phone number", with the phone placeholder and
`type="tel"`. It reuses the existing `phoneLabel` / `phonePlaceholder`
labels, which the Console already fills from `auth.login.phoneLabel` /
`auth.login.phonePlaceholder`. No locale key is added, so `Clause-②: no`
holds. Reason: the server refuses an email address there
(`EMAIL_PASSWORD_DISABLED`), so offering one is a way in that does not
exist. Submit routing is unchanged: a phone-shaped entry goes to
phone+password.
- **Doors the server refuses stay hidden.** The sign-up link stays
hidden while `emailPassword.enabled` is false, as before (it used to
ride on the collapse). The host's password-form description ("Enter your
email and password to continue") is not drawn either, matching the
no-method state. The Console renders with `hideHeader`, so its card is
unaffected by the description change.
## Tests
`ui/packages/auth/src/__tests__/noSignInMethod-29159.test.tsx` holds the
password-off config matrix, so the new cases go there as one top-level
`describe` (no new file). Its client helper gained an `overrides`
argument for the sign-in spies.
- Password off + phone (both ways) + no SSO, the card's repro config:
not collapsed; "Phone number", Password and "Sign in with verification
code" on first paint; no "Use a password instead", no "Back to single
sign-on", no SSO copy, no sign-up, no password-form description.
- The same in the verification-code form (under `hideHeader`, as the
Console renders it): no back button, and the switch back to
phone+password is offered.
- A phone number and password entered on first paint call
`signInWithPhonePassword` and not `signIn`.
- Password off + phone OTP only: the verification-code form on first
paint, with no password field and no switch to a password form.
- Password off + phone+password only: the form with no verification-code
link and no back button.
- CONTROL, password off + phone + SSO advertised: still collapsed with
the SSO button; break-glass opens the form and "Back to single sign-on"
is there.
- CONTROL, declared enforcement + password off + phone: still collapsed;
break-glass and back return to the collapsed view.
- Unchanged cells already pinned in the same file and in
`ssoEnforcedFirstPaint-29274.test.tsx`,
`ssoEnforcedLoginCopy-12682.test.tsx` and `LoginForm.test.tsx`: password
off + SSO on, SSO enforced, no method at all, failed config fetch.
- One existing case changed: "with password off and phone sign-in on, is
not the no-method state" clicked "Use a password instead" to reach the
OTP link. That click path was the defect. It now asserts the OTP link on
first paint.
<details><summary>Readings (fix commit f0a0c9c on base d02c99e; head
3a40e3e after merging main f4b1f9e)</summary>
- `pnpm exec vitest run packages/auth/src/__tests__/` from `ui/`,
locked: base d02c99e 45 files / 398 tests passed; f0a0c9c 45 files /
405 tests passed; head 3a40e3e (after rebuilding the auth closure) 45
files / 405 tests passed.
- Ablation, run through `scripts/ablation-replace.mjs` on the committed
head: `passwordFormCollapsed` restored to `ssoEnforced ||
passwordSignInOff`, anchor 1 to 0, blob af50e01 to 7530ce6b.
`noSignInMethod-29159.test.tsx` went to 6 failed / 10 passed: the five
new phone-only cases plus the edited existing case. Both CONTROLs stayed
green. Restored: blob equal to HEAD (af50e01) and `git diff HEAD`
empty.
- `pnpm exec turbo run type-check --filter=@object-ui/auth`: exit 0
(`tsc --noEmit && tsc -p tsconfig.test.json`), on f0a0c9c and again on
3a40e3e.
- `pnpm exec eslint` on both touched source files, from `ui/`: exit 0.
</details>
## Acceptance notes
- With the password door shut and SSO offered, a server that offers
phone OTP but not phone+password still hides the OTP way in behind the
collapse: there is no password door, so no break-glass link is offered.
The card leaves that cell unchanged by design ("password off + SSO on
(unchanged collapse)"). Noted here, not fixed.
- With the password door shut, no SSO, a phone way in and a social
provider, the provider divider still reads the host's `orText` ("or
continue with email" by default) above a phone form. Copy only. Noted,
not fixed.
- Live dogfood shot: not taken (optional per the brief).
## Verification
The derived gate list (`node scripts/pm/dispatch-gates.mjs --commands
--repo objectstack-ai/objectstack`, 36 commands, the same list on both
heads) was run locally on f0a0c9c and again on head 3a40e3e: 36 of 36
exit 0 each time, and `--ran` reconciles 36 derived, 36 run, 0
NOT-MEASURED. That includes `node scripts/check-sdui-manifest.mjs` (exit
0) and `pnpm --dir ui exec vitest run scripts/` (170 files passed, 2
skipped). Per-command exit codes are in the os-dev report on the card.
CI runs the rest.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01QsR2jTpDZ3S2UNafH1sonG)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent 46ec2ec commit 8a83814
3 files changed
Lines changed: 217 additions & 25 deletions
File tree
- .changeset
- ui/packages/auth/src
- __tests__
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
336 | 336 | | |
337 | 337 | | |
338 | 338 | | |
| 339 | + | |
| 340 | + | |
339 | 341 | | |
340 | 342 | | |
341 | | - | |
342 | | - | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
343 | 350 | | |
344 | 351 | | |
345 | 352 | | |
346 | 353 | | |
347 | 354 | | |
348 | 355 | | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
349 | 363 | | |
350 | 364 | | |
351 | 365 | | |
| |||
407 | 421 | | |
408 | 422 | | |
409 | 423 | | |
410 | | - | |
| 424 | + | |
411 | 425 | | |
412 | 426 | | |
413 | 427 | | |
| |||
570 | 584 | | |
571 | 585 | | |
572 | 586 | | |
573 | | - | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
574 | 591 | | |
575 | 592 | | |
576 | 593 | | |
| |||
607 | 624 | | |
608 | 625 | | |
609 | 626 | | |
610 | | - | |
| 627 | + | |
611 | 628 | | |
612 | 629 | | |
613 | 630 | | |
| |||
674 | 691 | | |
675 | 692 | | |
676 | 693 | | |
677 | | - | |
678 | | - | |
679 | | - | |
680 | | - | |
681 | | - | |
682 | | - | |
683 | | - | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
684 | 703 | | |
685 | 704 | | |
686 | 705 | | |
| |||
691 | 710 | | |
692 | 711 | | |
693 | 712 | | |
694 | | - | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
695 | 718 | | |
696 | 719 | | |
697 | 720 | | |
698 | 721 | | |
699 | | - | |
700 | | - | |
701 | | - | |
702 | | - | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
703 | 733 | | |
704 | 734 | | |
705 | 735 | | |
| |||
783 | 813 | | |
784 | 814 | | |
785 | 815 | | |
786 | | - | |
787 | | - | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
788 | 822 | | |
789 | 823 | | |
790 | 824 | | |
| |||
854 | 888 | | |
855 | 889 | | |
856 | 890 | | |
857 | | - | |
| 891 | + | |
| 892 | + | |
| 893 | + | |
858 | 894 | | |
859 | 895 | | |
860 | 896 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
40 | 43 | | |
41 | 44 | | |
42 | 45 | | |
| |||
48 | 51 | | |
49 | 52 | | |
50 | 53 | | |
51 | | - | |
| 54 | + | |
52 | 55 | | |
53 | 56 | | |
54 | 57 | | |
55 | 58 | | |
56 | 59 | | |
| 60 | + | |
57 | 61 | | |
58 | 62 | | |
59 | 63 | | |
60 | | - | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
61 | 69 | | |
62 | 70 | | |
63 | 71 | | |
64 | | - | |
| 72 | + | |
65 | 73 | | |
66 | 74 | | |
67 | 75 | | |
| |||
172 | 180 | | |
173 | 181 | | |
174 | 182 | | |
175 | | - | |
176 | | - | |
| 183 | + | |
| 184 | + | |
177 | 185 | | |
178 | 186 | | |
179 | 187 | | |
| |||
195 | 203 | | |
196 | 204 | | |
197 | 205 | | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
0 commit comments