@alauda/doom
Version:
Doctor Doom making docs.
68 lines (67 loc) • 3.41 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useMemo, useRef, useState, } from 'react';
import { ApiMethod, ResponseError, xfetch } from 'x-fetch';
import { ApiErrorAlert } from "../ApiErrorAlert/index.js";
import { Button } from "../Button/index.js";
import { CaptchaInput } from "../CaptchaInput/index.js";
import { FocusInput } from "../FocusInput/index.js";
import { FormItem } from "../FormItem/index.js";
import { useCloudAuth } from "../store.js";
import { getCloudOrigin } from "../utils.js";
import { cryptoPassword } from "./utils.js";
import { useMemoizedFn, useTranslation } from '@alauda/doom/runtime';
const isLoginError = (err) => err instanceof ResponseError;
export const LoginForm = ({ onSubmit, onLoggedIn, ...props }) => {
const t = useTranslation();
const [loading, setLoading] = useState();
const [error, setError] = useState();
const pwdPubkeyRef = useRef(null);
const { setAuthBasic } = useCloudAuth();
const captchaId = error?.data?.extra?.captchaId;
const [timestamp, setTimestamp] = useState();
const origin = useMemo(getCloudOrigin, []);
const handleSubmit = useMemoizedFn(async (ev) => {
ev.preventDefault();
ev.stopPropagation();
onSubmit?.(ev);
const formData = new FormData(ev.currentTarget);
setLoading(true);
if (pwdPubkeyRef.current == null) {
try {
pwdPubkeyRef.current = await xfetch(`${origin}/api/v1/pubkey`);
}
catch (err) {
setError(err);
setLoading(false);
return;
}
}
formData.set('password', cryptoPassword(pwdPubkeyRef.current, formData.get('password')));
if (captchaId) {
formData.set('captchaId', captchaId);
}
try {
const { accessToken } = await xfetch(`${origin}/api/v1/login`, {
method: ApiMethod.POST,
body: formData,
});
setAuthBasic(accessToken);
onLoggedIn?.();
}
catch (err) {
if (!isLoginError(err)) {
throw err;
}
if (err.data?.reason === 'PubkeyExpireError') {
pwdPubkeyRef.current = null;
await handleSubmit(ev);
return;
}
setError(err);
}
finally {
setLoading(false);
}
});
return (_jsxs("form", { onSubmit: handleSubmit, ...props, children: [error && _jsx(ApiErrorAlert, { error: error }), _jsx(FormItem, { label: t('account_id'), required: true, children: _jsx(FocusInput, { name: "tenant", placeholder: t('account_id') }) }), _jsx(FormItem, { label: t('username'), required: true, children: _jsx(FocusInput, { name: "username", placeholder: t('username') }) }), _jsx(FormItem, { label: t('password'), required: true, children: _jsx(FocusInput, { name: "password", type: "password", placeholder: t('password') }) }), captchaId && (_jsx(FormItem, { label: t('captcha'), required: true, children: _jsx(CaptchaInput, { Component: FocusInput, placeholder: t('captcha'), origin: origin, captchaId: captchaId, timestamp: timestamp, onTimestampChange: setTimestamp }) })), _jsx(FormItem, { children: _jsx(Button, { type: "primary", htmlType: "submit", block: true, loading: loading, children: t('login') }) })] }));
};