fix(auth): handle null backend values and surface login errors on splash
Two related fixes for OAuth login failures:
- `UserSchema`: backend (Facebook/Apple) returns `null` for fields like
`email`; Zod's `.default("")` rejects `null`, causing silent login
failures. Introduce `stringOrEmpty` / `numberOrZero` / `booleanOrFalse`
helpers (`nullable().transform(v => v ?? x).default(x)`) and apply
across the schema so input accepts `string | null | undefined` while
output stays the typed primitive.
- `SplashScreen`: render `state.errorMessage` (set by auth state machine
`onError`, e.g. Facebook sync / schema mismatch) so users no longer
get stuck on splash without feedback.
This commit is contained in:
@@ -24,7 +24,7 @@ export function SplashScreen() {
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// useEffect ① 启动时检查 localStorage 里的 loginToken:
|
||||
// - loginToken(OAuth/email sync 写下的)→ 视为"已登录"跳 /chat
|
||||
// - **不**查 guestToken —— 游客用户**停留 splash**(按你要求)
|
||||
// - 不查 guestToken —— 游客用户停留 splash(按你要求)
|
||||
// - 都没有 → 留 splash
|
||||
// proxy 读不到 localStorage(Edge runtime),所以这条 fallback 必须在 Client 侧。
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
@@ -43,11 +43,11 @@ export function SplashScreen() {
|
||||
}, [router]);
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// useEffect ② 按钮**刚**派了事件(pendingRedirect=true) +
|
||||
// useEffect ② 按钮刚派了事件(pendingRedirect=true) +
|
||||
// loginStatus 是非 notLoggedIn → 跳 /chat
|
||||
//
|
||||
// **关键**:`pendingRedirect` 是 auth context 里的**持久**状态(不是 ref)——
|
||||
// re-mount 时**不**重置,区分"刚按了"和"历史登录"准确无误。
|
||||
// 关键:`pendingRedirect` 是 auth context 里的持久状态(不是 ref)——
|
||||
// re-mount 时不重置,区分"刚按了"和"历史登录"准确无误。
|
||||
// 跳完调 `AuthClearPendingRedirect` 置 false(一次性信号)。
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
useEffect(() => {
|
||||
@@ -88,6 +88,26 @@ export function SplashScreen() {
|
||||
<div className={styles.buttonArea}>
|
||||
<SplashButton />
|
||||
</div>
|
||||
{/*
|
||||
* 登录错误提示 —— auth state machine 的 onError 会设 errorMessage
|
||||
* (如 Facebook 同步后端失败 / 后端返回数据 schema 不匹配等)。
|
||||
* 之前没显示,导致用户卡在 splash 看不到原因。
|
||||
*/}
|
||||
{state.errorMessage ? (
|
||||
<p
|
||||
role="alert"
|
||||
style={{
|
||||
color: "#c0392b",
|
||||
fontSize: "0.875rem",
|
||||
marginTop: "1rem",
|
||||
textAlign: "center",
|
||||
maxWidth: "320px",
|
||||
lineHeight: 1.4,
|
||||
}}
|
||||
>
|
||||
{state.errorMessage}
|
||||
</p>
|
||||
) : null}
|
||||
<p className={styles.bottom}>
|
||||
Elio Silvestri, Your exclusive AI boyfriend
|
||||
<br />
|
||||
|
||||
Reference in New Issue
Block a user