Redirect to page user was trying to access on login

This commit is contained in:
SleeplessOne1917 2023-07-07 08:52:10 -04:00
parent 02198f1076
commit 335e8b38c9
2 changed files with 106 additions and 72 deletions

View file

@ -1,12 +1,33 @@
import { InfernoNode } from "inferno"; import { Component, InfernoNode } from "inferno";
import { Redirect } from "inferno-router";
import { UserService } from "../../services"; import { UserService } from "../../services";
import { Spinner } from "./icon";
function AuthGuard(props: { children?: InfernoNode }) { interface AuthGuardState {
if (!UserService.Instance.myUserInfo) { hasRedirected: boolean;
return <Redirect to="/login" />; }
} else {
return props.children; class AuthGuard extends Component<{ children?: InfernoNode }, AuthGuardState> {
state = {
hasRedirected: false,
} as AuthGuardState;
constructor(props: any, context: any) {
super(props, context);
}
componentDidMount() {
if (!UserService.Instance.myUserInfo) {
this.context.router.history.replace(
"/login",
this.context.router.history.location
);
} else {
this.setState({ hasRedirected: true });
}
}
render() {
return this.state.hasRedirected ? this.props.children : <Spinner />;
} }
} }

View file

@ -1,7 +1,9 @@
import { myAuth, setIsoData } from "@utils/app"; import { myAuth, setIsoData } from "@utils/app";
import { isBrowser } from "@utils/browser"; import { isBrowser } from "@utils/browser";
import { Location } from "history";
import { Component, linkEvent } from "inferno"; import { Component, linkEvent } from "inferno";
import { NavLink } from "inferno-router"; import { NavLink } from "inferno-router";
import { RouteComponentProps } from "inferno-router/dist/Route";
import { GetSiteResponse, LoginResponse } from "lemmy-js-client"; import { GetSiteResponse, LoginResponse } from "lemmy-js-client";
import { I18NextService, UserService } from "../../services"; import { I18NextService, UserService } from "../../services";
import { HttpService, RequestState } from "../../services/HttpService"; import { HttpService, RequestState } from "../../services/HttpService";
@ -20,7 +22,78 @@ interface State {
siteRes: GetSiteResponse; siteRes: GetSiteResponse;
} }
export class Login extends Component<any, State> { async function handleLoginSubmit(i: Login, event: any) {
event.preventDefault();
const { password, totp_2fa_token, username_or_email } = i.state.form;
if (username_or_email && password) {
i.setState({ loginRes: { state: "loading" } });
const loginRes = await HttpService.client.login({
username_or_email,
password,
totp_2fa_token,
});
switch (loginRes.state) {
case "failed": {
if (loginRes.msg === "missing_totp_token") {
i.setState({ showTotp: true });
toast(I18NextService.i18n.t("enter_two_factor_code"), "info");
}
i.setState({ loginRes: { state: "failed", msg: loginRes.msg } });
break;
}
case "success": {
UserService.Instance.login({
res: loginRes.data,
});
const site = await HttpService.client.getSite({
auth: myAuth(),
});
if (site.state === "success") {
UserService.Instance.myUserInfo = site.data.my_user;
}
const { hash, pathname, search } = (i.props.history.location.state ??
{}) as Location;
console.log("Login state");
console.log(i.props.history.location.state);
i.props.history.location.state
? i.props.history.replace({ hash, pathname, search })
: i.props.history.action === "PUSH"
? i.props.history.back()
: i.props.history.replace("/");
break;
}
}
}
}
function handleLoginUsernameChange(i: Login, event: any) {
i.state.form.username_or_email = event.target.value.trim();
i.setState(i.state);
}
function handleLoginTotpChange(i: Login, event: any) {
i.state.form.totp_2fa_token = event.target.value;
i.setState(i.state);
}
function handleLoginPasswordChange(i: Login, event: any) {
i.state.form.password = event.target.value;
i.setState(i.state);
}
export class Login extends Component<
RouteComponentProps<Record<string, never>>,
State
> {
private isoData = setIsoData(this.context); private isoData = setIsoData(this.context);
state: State = { state: State = {
@ -68,7 +141,7 @@ export class Login extends Component<any, State> {
loginForm() { loginForm() {
return ( return (
<div> <div>
<form onSubmit={linkEvent(this, this.handleLoginSubmit)}> <form onSubmit={linkEvent(this, handleLoginSubmit)}>
<h1 className="h4 mb-4">{I18NextService.i18n.t("login")}</h1> <h1 className="h4 mb-4">{I18NextService.i18n.t("login")}</h1>
<div className="mb-3 row"> <div className="mb-3 row">
<label <label
@ -83,7 +156,7 @@ export class Login extends Component<any, State> {
className="form-control" className="form-control"
id="login-email-or-username" id="login-email-or-username"
value={this.state.form.username_or_email} value={this.state.form.username_or_email}
onInput={linkEvent(this, this.handleLoginUsernameChange)} onInput={linkEvent(this, handleLoginUsernameChange)}
autoComplete="email" autoComplete="email"
required required
minLength={3} minLength={3}
@ -99,7 +172,7 @@ export class Login extends Component<any, State> {
type="password" type="password"
id="login-password" id="login-password"
value={this.state.form.password} value={this.state.form.password}
onInput={linkEvent(this, this.handleLoginPasswordChange)} onInput={linkEvent(this, handleLoginPasswordChange)}
className="form-control" className="form-control"
autoComplete="current-password" autoComplete="current-password"
required required
@ -130,7 +203,7 @@ export class Login extends Component<any, State> {
pattern="[0-9]*" pattern="[0-9]*"
autoComplete="one-time-code" autoComplete="one-time-code"
value={this.state.form.totp_2fa_token} value={this.state.form.totp_2fa_token}
onInput={linkEvent(this, this.handleLoginTotpChange)} onInput={linkEvent(this, handleLoginTotpChange)}
/> />
</div> </div>
</div> </div>
@ -150,64 +223,4 @@ export class Login extends Component<any, State> {
</div> </div>
); );
} }
async handleLoginSubmit(i: Login, event: any) {
event.preventDefault();
const { password, totp_2fa_token, username_or_email } = i.state.form;
if (username_or_email && password) {
i.setState({ loginRes: { state: "loading" } });
const loginRes = await HttpService.client.login({
username_or_email,
password,
totp_2fa_token,
});
switch (loginRes.state) {
case "failed": {
if (loginRes.msg === "missing_totp_token") {
i.setState({ showTotp: true });
toast(I18NextService.i18n.t("enter_two_factor_code"), "info");
}
i.setState({ loginRes: { state: "failed", msg: loginRes.msg } });
break;
}
case "success": {
UserService.Instance.login({
res: loginRes.data,
});
const site = await HttpService.client.getSite({
auth: myAuth(),
});
if (site.state === "success") {
UserService.Instance.myUserInfo = site.data.my_user;
}
i.props.history.action === "PUSH"
? i.props.history.back()
: i.props.history.replace("/");
break;
}
}
}
}
handleLoginUsernameChange(i: Login, event: any) {
i.state.form.username_or_email = event.target.value.trim();
i.setState(i.state);
}
handleLoginTotpChange(i: Login, event: any) {
i.state.form.totp_2fa_token = event.target.value;
i.setState(i.state);
}
handleLoginPasswordChange(i: Login, event: any) {
i.state.form.password = event.target.value;
i.setState(i.state);
}
} }