Repository navigation
Commit 49aba82
fix(auth): sign-in, password reset and MFA set-up work at phone width (#29136)
Fixes #29080
Clause-②: no
Metadata-protocol: none
Part of #29040: the Auth flow child of the phone-width audit. Claim
6571286397, surface amendment 6571574347.
## 维护者速读
- **改了什么**:手机宽度(`sm` 断点以下)的登录、忘记密码、重置密码页和强制改密/MFA 遮罩:所有控件改为至少 44 px
的触控目标,登录与忘记密码的输入框字号改为 16 px,遮罩改为可滚动。桌面尺寸不变。
- **为什么改**:在 375 与 390 px 实测(showcase 与 CRM 两个示例):控件只有 28 到 40 px 高,文字链接
14 到 17 px;14 px 的输入框让 iOS 聚焦时整页放大;MFA 设置的扫码步骤在键盘弹出后标题被切掉、"Verify &
continue" 按钮落在键盘下方且无法滚动到,用户无法完成 MFA 注册。
- **风险与回滚**:只是 Tailwind 类名,全部以 `sm:` 收回,桌面 1280 px 实测尺寸与之前一致。回滚即 revert
本 PR。
-
**先看**:`ui/packages/app-shell/src/console/RemediationOverlay.tsx`(遮罩改为外层滚动、内层
`min-h-full`
居中);`ui/packages/auth/src/authStyles.tsx`(共享输入框与主按钮类);`ui/packages/auth/src/LoginForm.tsx`(显示密码按钮在手机上
44 px)。
- **两分钟验证**:手机宽度(375 px)打开 Console `/login`,所有输入框和按钮高 44
px,点输入框不放大;桌面打开同一页,外观与之前相同。
- **需要你做的**:无,席位落地。
## What changes
Below the `sm` breakpoint only:
- **Touch targets.** `AUTH_INPUT_CLASS` and `AUTH_PRIMARY_BUTTON_CLASS`
gain `min-h-[44px] sm:min-h-0`. The forms' secondary controls (text
buttons, the "Get code" button, the SSO button, "Forgot password?",
"Back to sign in") take the same floor through a module-internal
`AUTH_TOUCH_TARGET_CLASS`, not exported from the package entry. The
show-password toggle is `size-11` (`sm:size-7`) with the field's right
padding widened to match. On the Console pages: the dev-admin chip, the
Privacy and Terms links, the "Powered by ObjectStack" link, the
reset-password fields and button, and the locale button (grown by a
child selector in `AuthFooter`, so `LocaleSwitcher` itself is
untouched). Links inside a sentence ("Sign up", "Sign in", "Request a
new link") keep their size under WCAG 2.5.5's inline exception.
- **Input text.** `AUTH_INPUT_CLASS` is `text-base sm:text-sm`, so the
sign-in and forgot-password fields are 16 px on a phone and WebKit no
longer zooms the page on focus. (The reset page and the overlay already
use the 16 px components `Input`.)
- **The remediation overlay scrolls.** It was `fixed inset-0 flex
items-center` with no overflow. The overlay is now `overflow-y-auto` and
centres its card inside a `min-h-full` column, so a card taller than the
screen keeps its top and its submit reachable. Below `sm` its buttons,
inputs and the backup-codes summary are 44 px.
No shared layout file (ConsoleLayout, AppShell, UnifiedSidebar,
LocaleSwitcher) is touched. No export, prop or key is added, so the
declarations are `Clause-②: no` and `Metadata-protocol: none`, as
claimed.
## Run record
Tree `6b3ba82c` (origin/main), full `turbo run build`, `objectstack dev
--seed-admin --fresh` for **app-showcase** and **app-crm**, the Console
from `ui/apps/console` source through Vite, Playwright Chromium with
`isMobile` + `hasTouch`. MFA was driven for real: `PUT
/api/settings/auth` with `mfa_required: true` and
`mfa_grace_period_days: 0`, so data reads answer `403 MFA_REQUIRED` and
the Console raises its overlay; enrollment was completed with a TOTP
computed from the served secret.
Keyboard model: the layout viewport shrinks by the keyboard (336 px at
812, 346 px at 844, the WebView adjustResize case), each field is
focused and scrolled into view, and the field and its submit button must
sit in what is left. Showcase and CRM gave the same answer on every row.
| Page | Check | 375 before | 375 after | 390 before | 390 after |
|---|---|---|---|---|---|
| /login | no horizontal scroll (also with the error banner) | PASS |
PASS | PASS | PASS |
| /login | touch targets 44 px | FAIL: fields and Sign In 40, toggle
28x28, Forgot password 16, dev chip 28, locale 32x32, Privacy/Terms 16,
Powered-by 14 | PASS | FAIL (same) | PASS |
| /login | keyboard: field clear and no focus zoom | FAIL: fields 14 px,
iOS zooms | PASS: 16 px | FAIL | PASS |
| /login | dialogs fit (locale menu) | PASS | PASS | PASS | PASS |
| /login | long lists at 4x CPU | PASS: no long list; the 10-item locale
menu opens in 170 to 504 ms on the Vite dev server | PASS | PASS | PASS
|
| /forgot-password | no horizontal scroll (form and sent state) | PASS |
PASS | PASS | PASS |
| /forgot-password | touch targets | FAIL: field and button 40, Back to
sign in 17 | PASS | FAIL | PASS |
| /forgot-password | keyboard | FAIL: field 14 px | PASS | FAIL | PASS |
| /reset-password | no horizontal scroll | PASS | PASS | PASS | PASS |
| /reset-password | touch targets | FAIL: fields and button 40 | PASS |
FAIL | PASS |
| /reset-password | keyboard | PASS | PASS | PASS | PASS |
| MFA overlay, password step | scroll / fit / keyboard | PASS | PASS |
PASS | PASS |
| MFA overlay, password step | touch targets | FAIL: field and button
40, Sign out 16 | PASS | FAIL | PASS |
| MFA overlay, scan step | keyboard | FAIL: card top at -138 px, Verify
at 499 to 539 px of a 476 px viewport, nothing scrolls | PASS: overlay
scrolls, Verify at 315 to 359 | FAIL (card top -127) | PASS |
| MFA overlay, scan step | touch targets | FAIL: summary 16, field and
button 40, Sign out 16 | PASS | FAIL | PASS |
| 2FA sign-in, enrolled user | challenge reachable | FAIL, at any width
| not in this PR (#29105) | FAIL | not in this PR |
Desktop check after the fix, 1280 px: email and password fields 342x40
at 14 px, Sign In 342x40, toggle 28x28, dev chip 28 tall, locale 32x32,
the sizes main draws.
Screenshots before and after each fix, and the raw results, are in the
project folder `issue-29080/` (not on GitHub, as the card asks). The
register page under the examples' `invite_only` posture shows no form,
so it was measured only for its links.
## Tests
- New `ui/packages/auth/src/__tests__/phoneTouchTargets-29080.test.tsx`:
every input and button of `LoginForm` (with SSO and phone OTP on) and
`ForgotPasswordForm` carries the phone floor, the fields carry
`text-base sm:text-sm`, the toggle is `size-11 sm:size-7`.
- New
`ui/packages/app-shell/src/console/__tests__/RemediationOverlay.phoneScroll-29080.test.tsx`:
the overlay is `overflow-y-auto` and not `items-center`, its column is
`min-h-full`, its card carries the phone floor.
- Ablation, after committing the fix: overlay back to `flex items-center
justify-center` without overflow, the overlay test fails (1 failed); the
input class back to `h-10 ... text-sm`, the auth test fails (2 failed).
`ablation-replace.mjs` restored each file to its HEAD blob with an empty
`git diff HEAD`.
<details><summary>Suites and type-check</summary>
- `pnpm --dir ui exec vitest run packages/auth/` plus the 42 console and
app-shell test files that name the touched pages and the overlay: Test
Files 82 passed, Tests 572 passed.
- `turbo run type-check --filter=@object-ui/auth
--filter=@object-ui/app-shell --filter=@object-ui/console`: 73 tasks
successful.
</details>
## Acceptance notes
- The card asks for a fix for every failure or a card for each one not
fixed. All phone-width failures are fixed here. One failure is not a
phone-width defect: a TOTP-enrolled user's password sign-in answers
`twoFactorRedirect` and the Console stays on /login with no code field
and no message, at any width. It is filed as #29105.
- Playwright coverage at a phone viewport is optional for this flow
(#29040 requires it for Approvals and Record only); the run record above
was taken with Playwright against real stacks, and the class pins hold
the fixes in CI.
## Verification
All local readings at head `1f2e4483`. CI's check-runs carry every
family CI runs; they are not re-run here.
- `node scripts/pm/dispatch-gates.mjs --ran`: 34 derived, 34 run, 0
NOT-MEASURED, every exit 0 (`check-changeset-no-major`,
`check-adr-0087-registration`, `check-closing-keyword-parity` and
`check-partof-closing-keyword` read this body).
- `node scripts/check-sdui-manifest.mjs`: exit 0, no component config
changed.
- `pnpm --dir ui exec vitest run scripts/`: 169 files passed, 2 skipped
(4900 tests).
- `pnpm --dir ui check:new-line-citations`: 0 new citations.
- `pnpm check:type-check-debt`: exit 0.
- Dogfood battery: not owed, no `!` in the title and no `(narrowing)`
arm.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01QsR2jSjgRwjHh1CopZ7aDU
Co-authored-by: Claude <noreply@anthropic.com>1 parent 1ac1c24 commit 49aba82
11 files changed
Lines changed: 247 additions & 33 deletions
File tree
- .changeset
- ui
- apps/console/src/pages/auth
- packages
- app-shell/src/console
- __tests__
- 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 | + | |
| 17 | + | |
| 18 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
| 47 | + | |
47 | 48 | | |
48 | | - | |
| 49 | + | |
49 | 50 | | |
50 | 51 | | |
51 | 52 | | |
52 | 53 | | |
53 | 54 | | |
54 | | - | |
| 55 | + | |
| 56 | + | |
55 | 57 | | |
56 | 58 | | |
57 | 59 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
180 | 180 | | |
181 | 181 | | |
182 | 182 | | |
183 | | - | |
| 183 | + | |
184 | 184 | | |
185 | 185 | | |
186 | 186 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
440 | 440 | | |
441 | 441 | | |
442 | 442 | | |
443 | | - | |
| 443 | + | |
444 | 444 | | |
445 | 445 | | |
446 | 446 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
27 | 30 | | |
28 | 31 | | |
29 | 32 | | |
| |||
106 | 109 | | |
107 | 110 | | |
108 | 111 | | |
| 112 | + | |
109 | 113 | | |
110 | 114 | | |
111 | 115 | | |
| |||
122 | 126 | | |
123 | 127 | | |
124 | 128 | | |
| 129 | + | |
125 | 130 | | |
126 | 131 | | |
127 | 132 | | |
| |||
130 | 135 | | |
131 | 136 | | |
132 | 137 | | |
133 | | - | |
| 138 | + | |
134 | 139 | | |
135 | 140 | | |
136 | 141 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
74 | 83 | | |
75 | 84 | | |
76 | 85 | | |
| |||
| 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 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
17 | 18 | | |
18 | 19 | | |
19 | 20 | | |
| |||
273 | 274 | | |
274 | 275 | | |
275 | 276 | | |
276 | | - | |
| 277 | + | |
277 | 278 | | |
278 | 279 | | |
279 | 280 | | |
| |||
299 | 300 | | |
300 | 301 | | |
301 | 302 | | |
302 | | - | |
| 303 | + | |
303 | 304 | | |
304 | 305 | | |
305 | 306 | | |
| |||
360 | 361 | | |
361 | 362 | | |
362 | 363 | | |
363 | | - | |
| 364 | + | |
364 | 365 | | |
365 | 366 | | |
366 | 367 | | |
| |||
399 | 400 | | |
400 | 401 | | |
401 | 402 | | |
402 | | - | |
| 403 | + | |
403 | 404 | | |
404 | 405 | | |
405 | 406 | | |
| |||
434 | 435 | | |
435 | 436 | | |
436 | 437 | | |
437 | | - | |
| 438 | + | |
438 | 439 | | |
439 | 440 | | |
440 | 441 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
| |||
522 | 523 | | |
523 | 524 | | |
524 | 525 | | |
525 | | - | |
| 526 | + | |
526 | 527 | | |
527 | 528 | | |
528 | 529 | | |
| |||
544 | 545 | | |
545 | 546 | | |
546 | 547 | | |
547 | | - | |
| 548 | + | |
548 | 549 | | |
549 | 550 | | |
550 | 551 | | |
| |||
584 | 585 | | |
585 | 586 | | |
586 | 587 | | |
587 | | - | |
| 588 | + | |
588 | 589 | | |
589 | 590 | | |
590 | 591 | | |
| |||
600 | 601 | | |
601 | 602 | | |
602 | 603 | | |
603 | | - | |
| 604 | + | |
604 | 605 | | |
605 | 606 | | |
606 | 607 | | |
| |||
611 | 612 | | |
612 | 613 | | |
613 | 614 | | |
614 | | - | |
| 615 | + | |
615 | 616 | | |
616 | 617 | | |
617 | 618 | | |
| |||
633 | 634 | | |
634 | 635 | | |
635 | 636 | | |
636 | | - | |
| 637 | + | |
637 | 638 | | |
638 | 639 | | |
639 | 640 | | |
| |||
644 | 645 | | |
645 | 646 | | |
646 | 647 | | |
647 | | - | |
| 648 | + | |
648 | 649 | | |
649 | 650 | | |
650 | 651 | | |
| |||
656 | 657 | | |
657 | 658 | | |
658 | 659 | | |
659 | | - | |
| 660 | + | |
660 | 661 | | |
661 | 662 | | |
662 | 663 | | |
| |||
672 | 673 | | |
673 | 674 | | |
674 | 675 | | |
675 | | - | |
| 676 | + | |
676 | 677 | | |
677 | 678 | | |
678 | 679 | | |
| |||
0 commit comments