mirror of
https://github.com/lifegpc/eh-downloader.git
synced 2026-07-08 01:31:00 +08:00
Add Login page
This commit is contained in:
85
components/Login.tsx
Normal file
85
components/Login.tsx
Normal file
@@ -0,0 +1,85 @@
|
||||
import { Component, ContextType } from "preact";
|
||||
import { GlobalCtx } from "./GlobalContext.tsx";
|
||||
import BMd3TextField from "./BMd3TextField.tsx";
|
||||
import t from "../server/i18n.ts";
|
||||
import { useState } from "preact/hooks";
|
||||
import { MdTonalButton } from "../server/dmodule.ts";
|
||||
import { set_state } from "../server/state.ts";
|
||||
import pbkdf2Hmac from "pbkdf2-hmac/?target=es2022";
|
||||
import { encode } from "std/encoding/base64.ts";
|
||||
|
||||
type Props = {
|
||||
show: boolean;
|
||||
};
|
||||
|
||||
export default class Login extends Component<Props> {
|
||||
static contextType = GlobalCtx;
|
||||
declare context: ContextType<typeof GlobalCtx>;
|
||||
render() {
|
||||
if (!this.props.show) return null;
|
||||
if (!MdTonalButton.value) return null;
|
||||
const [username, set_username] = useState<string>();
|
||||
const [password, set_password] = useState<string>();
|
||||
const [disabled, set_disabled] = useState(false);
|
||||
const login = async (username: string, password: string) => {
|
||||
set_disabled(true);
|
||||
const b = new URLSearchParams();
|
||||
b.append("username", username);
|
||||
const p = new Uint8Array(
|
||||
await pbkdf2Hmac(
|
||||
password,
|
||||
"eh-downloader-salt",
|
||||
210000,
|
||||
64,
|
||||
"SHA-512",
|
||||
),
|
||||
);
|
||||
const t = (new Date()).getTime();
|
||||
const p2 = encode(
|
||||
new Uint8Array(
|
||||
await pbkdf2Hmac(p, t.toString(), 1000, 64, "SHA-512"),
|
||||
),
|
||||
);
|
||||
b.append("password", p2);
|
||||
b.append("t", t.toString());
|
||||
b.append("set_cookie", "1");
|
||||
const re2 = await fetch("/api/token", { method: "PUT", body: b });
|
||||
const token = await re2.json();
|
||||
if (!token.ok) {
|
||||
throw Error(token.error);
|
||||
}
|
||||
};
|
||||
const Button = MdTonalButton.value;
|
||||
return (
|
||||
<div>
|
||||
<BMd3TextField
|
||||
label={t("user.username")}
|
||||
type="text"
|
||||
value={username}
|
||||
set_value={set_username}
|
||||
/>
|
||||
<BMd3TextField
|
||||
label={t("user.password")}
|
||||
type="password"
|
||||
value={password}
|
||||
set_value={set_password}
|
||||
/>
|
||||
<Button
|
||||
disabled={disabled || !username || !password}
|
||||
onClick={() => {
|
||||
if (!username || !password) return;
|
||||
login(username, password).then(() => {
|
||||
set_disabled(false);
|
||||
set_state("#/");
|
||||
}).catch((e) => {
|
||||
console.error(e);
|
||||
set_disabled(false);
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t("user.login")}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import { initCfg } from "../server/cfg.ts";
|
||||
import { load_dmodule } from "../server/dmodule.ts";
|
||||
import CreateRootUser from "../components/CreateRootUser.tsx";
|
||||
import { check_auth_status } from "../server/auth.ts";
|
||||
import Login from "../components/Login.tsx";
|
||||
|
||||
export type ContainerProps = {
|
||||
i18n: I18NMap;
|
||||
@@ -108,6 +109,7 @@ export default class Container extends Component<ContainerProps> {
|
||||
/>
|
||||
<NewTask show={state === "#/task_manager/new"} />
|
||||
<CreateRootUser show={state === "#/create_root_user"} />
|
||||
<Login show={state === "#/login"} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ export async function check_auth_status() {
|
||||
const re = await fetch("/api/user");
|
||||
const u: JSONResult<BUser> = await re.json();
|
||||
if (u.ok) return true;
|
||||
if (u.status !== 404 && u.status !== 1) {
|
||||
if (u.status !== 404 && u.status !== 1 && u.status !== 401) {
|
||||
throw Error(u.error);
|
||||
}
|
||||
const re2 = await fetch("/api/status");
|
||||
@@ -20,5 +20,5 @@ export async function check_auth_status() {
|
||||
if (!parse_bool(localStorage.getItem("skip_create_root_user"), false)) {
|
||||
set_state("#/create_root_user");
|
||||
}
|
||||
}
|
||||
} else set_state("#/login");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user