移除验证码输入框
This commit is contained in:
@@ -2800,32 +2800,6 @@ button:active:not(:disabled),
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.auth-captcha-row {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: minmax(0, 1fr) 118px;
|
|
||||||
gap: 8px;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.auth-captcha-button {
|
|
||||||
height: 44px;
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 8px;
|
|
||||||
background: #ffffff;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.auth-captcha-button img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: block;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.auth-submit,
|
.auth-submit,
|
||||||
.auth-submit.button {
|
.auth-submit.button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -2899,8 +2873,4 @@ button:active:not(:disabled),
|
|||||||
width: 34px;
|
width: 34px;
|
||||||
min-height: 34px;
|
min-height: 34px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.auth-captcha-row {
|
|
||||||
grid-template-columns: minmax(0, 1fr) 104px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useEffect, useMemo, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import type { FormEvent } from "react";
|
import type { FormEvent } from "react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { Loader2, LogIn, RefreshCw } from "lucide-react";
|
import { Loader2, LogIn } from "lucide-react";
|
||||||
import { pulseFeedback, revealChildren, runScopedMotion } from "@/lib/ui/motion";
|
import { pulseFeedback, revealChildren, runScopedMotion } from "@/lib/ui/motion";
|
||||||
|
|
||||||
export function AuthLoginPanel({
|
export function AuthLoginPanel({
|
||||||
@@ -19,8 +19,6 @@ export function AuthLoginPanel({
|
|||||||
}) {
|
}) {
|
||||||
const [username, setUsername] = useState("");
|
const [username, setUsername] = useState("");
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
const [code, setCode] = useState("");
|
|
||||||
const [randomStr, setRandomStr] = useState("");
|
|
||||||
const [submitting, setSubmitting] = useState(false);
|
const [submitting, setSubmitting] = useState(false);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const screenRef = useRef<HTMLDivElement | null>(null);
|
const screenRef = useRef<HTMLDivElement | null>(null);
|
||||||
@@ -35,16 +33,6 @@ export function AuthLoginPanel({
|
|||||||
pulseFeedback(feedbackRef.current);
|
pulseFeedback(feedbackRef.current);
|
||||||
}, [error, message, missing?.join(",")]);
|
}, [error, message, missing?.join(",")]);
|
||||||
|
|
||||||
const captchaSrc = useMemo(() => {
|
|
||||||
if (!randomStr) return "";
|
|
||||||
return `/api/auth/captcha?randomStr=${encodeURIComponent(randomStr)}`;
|
|
||||||
}, [randomStr]);
|
|
||||||
|
|
||||||
function refreshCaptcha() {
|
|
||||||
setCode("");
|
|
||||||
setRandomStr(crypto.randomUUID());
|
|
||||||
}
|
|
||||||
|
|
||||||
async function submit(event: FormEvent<HTMLFormElement>) {
|
async function submit(event: FormEvent<HTMLFormElement>) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (!configured || submitting) return;
|
if (!configured || submitting) return;
|
||||||
@@ -52,10 +40,6 @@ export function AuthLoginPanel({
|
|||||||
setError(null);
|
setError(null);
|
||||||
try {
|
try {
|
||||||
const payload: Record<string, string> = { username, password, next };
|
const payload: Record<string, string> = { username, password, next };
|
||||||
if (code.trim() && randomStr) {
|
|
||||||
payload.code = code.trim();
|
|
||||||
payload.randomStr = randomStr;
|
|
||||||
}
|
|
||||||
const response = await fetch("/api/auth/password", {
|
const response = await fetch("/api/auth/password", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
@@ -66,7 +50,6 @@ export function AuthLoginPanel({
|
|||||||
window.location.assign(result.redirectTo || next || "/create");
|
window.location.assign(result.redirectTo || next || "/create");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err instanceof Error ? err.message : String(err));
|
setError(err instanceof Error ? err.message : String(err));
|
||||||
refreshCaptcha();
|
|
||||||
} finally {
|
} finally {
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
}
|
}
|
||||||
@@ -116,29 +99,6 @@ export function AuthLoginPanel({
|
|||||||
placeholder="请输入密码"
|
placeholder="请输入密码"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label className="field" data-animate>
|
|
||||||
<span>验证码</span>
|
|
||||||
<div className="auth-captcha-row">
|
|
||||||
<input
|
|
||||||
autoComplete="off"
|
|
||||||
value={code}
|
|
||||||
onChange={(event) => setCode(event.target.value)}
|
|
||||||
disabled={!configured || submitting}
|
|
||||||
placeholder="需要时填写"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
className="auth-captcha-button"
|
|
||||||
type="button"
|
|
||||||
onClick={refreshCaptcha}
|
|
||||||
disabled={!configured || submitting}
|
|
||||||
aria-label="刷新验证码"
|
|
||||||
title="刷新验证码"
|
|
||||||
>
|
|
||||||
{captchaSrc ? <img src={captchaSrc} alt="验证码" /> : <RefreshCw size={18} />}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<button className="button primary auth-submit" type="submit" disabled={!configured || submitting || !username.trim() || !password} data-animate>
|
<button className="button primary auth-submit" type="submit" disabled={!configured || submitting || !username.trim() || !password} data-animate>
|
||||||
{submitting ? <Loader2 className="spin" size={18} /> : <LogIn size={18} />}
|
{submitting ? <Loader2 className="spin" size={18} /> : <LogIn size={18} />}
|
||||||
登录
|
登录
|
||||||
|
|||||||
14
tests/auth-login-panel.test.ts
Normal file
14
tests/auth-login-panel.test.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { readFile } from "node:fs/promises";
|
||||||
|
import { join } from "node:path";
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
describe("AuthLoginPanel", () => {
|
||||||
|
it("does not render captcha controls", async () => {
|
||||||
|
const source = await readFile(join(process.cwd(), "components", "auth-login-panel.tsx"), "utf8");
|
||||||
|
|
||||||
|
expect(source).not.toContain("auth-captcha-row");
|
||||||
|
expect(source).not.toContain("auth-captcha-button");
|
||||||
|
expect(source).not.toContain("/api/auth/captcha");
|
||||||
|
expect(source).not.toContain("randomStr");
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user