取消运营后台注册功能
This commit is contained in:
parent
20ca5384fc
commit
970dc8bfee
@ -2019,14 +2019,8 @@ def dingtalk_login_callback(response: Response, code: str = "", state: str = "",
|
|||||||
|
|
||||||
|
|
||||||
@app.post("/api/admin/auth/register", status_code=status.HTTP_201_CREATED)
|
@app.post("/api/admin/auth/register", status_code=status.HTTP_201_CREATED)
|
||||||
def register(payload: RegisterRequest, db: Session = Depends(get_db)):
|
def register(_: RegisterRequest):
|
||||||
if db.scalar(select(AdminUser).where(AdminUser.username == payload.username)):
|
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="运营后台已关闭自助注册,请联系管理员创建账号")
|
||||||
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="用户名已存在")
|
|
||||||
user = AdminUser(username=payload.username, password_hash=hash_password(payload.password), display_name=payload.display_name, role_code="operator")
|
|
||||||
db.add(user)
|
|
||||||
db.commit()
|
|
||||||
db.refresh(user)
|
|
||||||
return {"success": True, "data": {"user": public_user(user)}}
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/api/admin/auth/me")
|
@app.get("/api/admin/auth/me")
|
||||||
|
|||||||
@ -80,13 +80,15 @@ async function readReferenceFile(file, requestApi = api) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function LoginPage({ onLogin }) {
|
function LoginPage({ onLogin }) {
|
||||||
const [registering, setRegistering] = useState(false);
|
|
||||||
const [username, setUsername] = useState("");
|
const [username, setUsername] = useState("");
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
const [displayName, setDisplayName] = useState("");
|
|
||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [dingtalkLoading, setDingtalkLoading] = useState(false);
|
const [dingtalkLoading, setDingtalkLoading] = useState(false);
|
||||||
|
const [autoDingtalkLogin, setAutoDingtalkLogin] = useState(false);
|
||||||
|
const autoLoginStarted = useRef(false);
|
||||||
|
const query = new URLSearchParams(window.location.search);
|
||||||
|
const inDingtalkWorkbench = /DingTalk|AliApp\(DT/i.test(navigator.userAgent || "") || query.get("from") === "dingtalk";
|
||||||
async function loginWithDingTalk() {
|
async function loginWithDingTalk() {
|
||||||
setDingtalkLoading(true);
|
setDingtalkLoading(true);
|
||||||
setError("");
|
setError("");
|
||||||
@ -96,42 +98,36 @@ function LoginPage({ onLogin }) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
setDingtalkLoading(false);
|
setDingtalkLoading(false);
|
||||||
|
setAutoDingtalkLogin(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function submit(event) {
|
async function submit(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
setError("");
|
setError("");
|
||||||
if (!username.trim() || !password || (registering && !displayName.trim()))
|
if (!username.trim() || !password)
|
||||||
return setError("\u8bf7\u5b8c\u6574\u586b\u5199\u4fe1\u606f");
|
return setError("\u8bf7\u5b8c\u6574\u586b\u5199\u4fe1\u606f");
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
if (registering) {
|
|
||||||
await api("/api/admin/auth/register", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
username,
|
|
||||||
password,
|
|
||||||
display_name: displayName,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
setRegistering(false);
|
|
||||||
setPassword("");
|
|
||||||
setError(
|
|
||||||
"\u6ce8\u518c\u6210\u529f\uff0c\u8bf7\u4f7f\u7528\u65b0\u8d26\u53f7\u767b\u5f55",
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
const result = await api("/api/admin/auth/login", {
|
const result = await api("/api/admin/auth/login", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify({ username, password }),
|
body: JSON.stringify({ username, password }),
|
||||||
});
|
});
|
||||||
onLogin(result.data.user);
|
onLogin(result.data.user);
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
if (!inDingtalkWorkbench || query.get("dingtalk") === "success" || autoLoginStarted.current) return;
|
||||||
|
autoLoginStarted.current = true;
|
||||||
|
setAutoDingtalkLogin(true);
|
||||||
|
loginWithDingTalk();
|
||||||
|
}, []);
|
||||||
|
if (autoDingtalkLogin) {
|
||||||
|
return <div className="loading-screen">正在验证钉钉身份…</div>;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<main className="login-shell">
|
<main className="login-shell">
|
||||||
<div className="login-decoration">
|
<div className="login-decoration">
|
||||||
@ -144,28 +140,17 @@ function LoginPage({ onLogin }) {
|
|||||||
<MessageCircle size={28} />
|
<MessageCircle size={28} />
|
||||||
</div>
|
</div>
|
||||||
<div className="brand-title">{Z.brand}</div>
|
<div className="brand-title">{Z.brand}</div>
|
||||||
<h1>{registering ? Z.register : Z.backend}</h1>
|
<h1>{Z.backend}</h1>
|
||||||
<p className="login-subtitle">从钉钉工作台进入,使用钉钉身份安全登录</p>
|
<p className="login-subtitle">从钉钉工作台进入,使用钉钉身份安全登录</p>
|
||||||
<button className="dingtalk-login-button" type="button" onClick={loginWithDingTalk} disabled={dingtalkLoading}>
|
<button className="dingtalk-login-button" type="button" onClick={loginWithDingTalk} disabled={dingtalkLoading}>
|
||||||
{dingtalkLoading ? "正在跳转钉钉…" : "使用钉钉登录"}
|
{dingtalkLoading ? "正在跳转钉钉…" : "使用钉钉登录"}
|
||||||
</button>
|
</button>
|
||||||
<div className="login-divider"><span>或使用后台账号</span></div>
|
<div className="login-divider"><span>或使用后台账号</span></div>
|
||||||
<form onSubmit={submit} className="login-form">
|
<form onSubmit={submit} className="login-form">
|
||||||
{registering && (
|
|
||||||
<label>
|
|
||||||
{Z.displayName}
|
|
||||||
<input
|
|
||||||
autoFocus
|
|
||||||
value={displayName}
|
|
||||||
onChange={(event) => setDisplayName(event.target.value)}
|
|
||||||
placeholder={"\u8bf7\u8f93\u5165\u663e\u793a\u540d\u79f0"}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
)}
|
|
||||||
<label>
|
<label>
|
||||||
{Z.username}
|
{Z.username}
|
||||||
<input
|
<input
|
||||||
autoFocus={!registering}
|
autoFocus
|
||||||
value={username}
|
value={username}
|
||||||
onChange={(event) => setUsername(event.target.value)}
|
onChange={(event) => setUsername(event.target.value)}
|
||||||
placeholder={"\u8bf7\u8f93\u5165\u7528\u6237\u540d"}
|
placeholder={"\u8bf7\u8f93\u5165\u7528\u6237\u540d"}
|
||||||
@ -178,33 +163,15 @@ function LoginPage({ onLogin }) {
|
|||||||
value={password}
|
value={password}
|
||||||
onChange={(event) => setPassword(event.target.value)}
|
onChange={(event) => setPassword(event.target.value)}
|
||||||
placeholder={
|
placeholder={
|
||||||
registering
|
"\u8bf7\u8f93\u5165\u5bc6\u7801"
|
||||||
? "\u81f3\u5c11 8 \u4f4d\u5bc6\u7801"
|
|
||||||
: "\u8bf7\u8f93\u5165\u5bc6\u7801"
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
{error && <div className="form-error">{error}</div>}
|
{error && <div className="form-error">{error}</div>}
|
||||||
<button className="primary-button login-button" disabled={loading}>
|
<button className="primary-button login-button" disabled={loading}>
|
||||||
{loading
|
{loading ? "\u767b\u5f55\u4e2d\u2026" : Z.login}
|
||||||
? registering
|
|
||||||
? "\u6ce8\u518c\u4e2d\u2026"
|
|
||||||
: "\u767b\u5f55\u4e2d\u2026"
|
|
||||||
: registering
|
|
||||||
? Z.register
|
|
||||||
: Z.login}
|
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
<button
|
|
||||||
className="text-button"
|
|
||||||
onClick={() => {
|
|
||||||
setRegistering(!registering);
|
|
||||||
setError("");
|
|
||||||
setPassword("");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{registering ? "\u8fd4\u56de\u767b\u5f55" : Z.register}
|
|
||||||
</button>
|
|
||||||
<div className="login-hint">
|
<div className="login-hint">
|
||||||
{
|
{
|
||||||
"\u8fd0\u8425\u8d26\u53f7\u767b\u5f55 \u00b7 \u7528\u6237 A/B \u8bf7\u4f7f\u7528\u72ec\u7acb\u4efb\u52a1\u94fe\u63a5"
|
"\u8fd0\u8425\u8d26\u53f7\u767b\u5f55 \u00b7 \u7528\u6237 A/B \u8bf7\u4f7f\u7528\u72ec\u7acb\u4efb\u52a1\u94fe\u63a5"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user