mirror of
https://gitlab.com/comunic/comunicconsole
synced 2024-11-23 13:59:23 +00:00
Can login using access reset token
This commit is contained in:
parent
b1929fc21f
commit
05117e71a3
@ -25,12 +25,13 @@ export async function serverRequest(uri: string, args?: any): Promise<any> {
|
||||
|
||||
// TODO : add access token, once supported
|
||||
|
||||
const result = await (
|
||||
await fetch((await ConfigHelper.apiURL()) + uri, {
|
||||
const result = await fetch((await ConfigHelper.apiURL()) + uri, {
|
||||
method: "POST",
|
||||
body: fd,
|
||||
})
|
||||
).json();
|
||||
});
|
||||
|
||||
return result;
|
||||
if (result.status !== 200)
|
||||
throw new Error("Request failed with status " + result.status);
|
||||
|
||||
return await result.json();
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ export interface AuthOptions {
|
||||
reset_token: string;
|
||||
}
|
||||
|
||||
const SESSION_STORAGE_TOKEN = "auth_token";
|
||||
|
||||
export class AccountHelper {
|
||||
/**
|
||||
* Check whether access token are available
|
||||
@ -30,4 +32,19 @@ export class AccountHelper {
|
||||
mail: mail,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to authenticate user using a reset token
|
||||
*
|
||||
* @param mail Email address of the admin
|
||||
* @param token The reset token
|
||||
*/
|
||||
static async authWithResetToken(mail: string, token: string) {
|
||||
const res = await serverRequest("accounts/auth_with_reset_token", {
|
||||
mail: mail,
|
||||
token: token,
|
||||
});
|
||||
|
||||
sessionStorage.setItem(SESSION_STORAGE_TOKEN, res.token);
|
||||
}
|
||||
}
|
||||
|
@ -5,24 +5,41 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
Typography,
|
||||
Link,
|
||||
makeStyles,
|
||||
Avatar,
|
||||
Box,
|
||||
Button,
|
||||
Container,
|
||||
CssBaseline,
|
||||
Avatar,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
ListItemText,
|
||||
Paper,
|
||||
TextField,
|
||||
FormControlLabel,
|
||||
Checkbox,
|
||||
Button,
|
||||
Grid,
|
||||
Box,
|
||||
Typography,
|
||||
} from "@material-ui/core";
|
||||
|
||||
import { ErrorOutline, Lock, VpnKey } from "@material-ui/icons";
|
||||
import LockOutlinedIcon from "@material-ui/icons/LockOutlined";
|
||||
import React from "react";
|
||||
import { AccountHelper } from "../../helpers/AccountHelper";
|
||||
import { matAlert } from "../widgets/DialogsProvider";
|
||||
import { AccountHelper, AuthOptions } from "../../helpers/AccountHelper";
|
||||
import { input, matAlert } from "../widgets/DialogsProvider";
|
||||
|
||||
function ErrorGettingOptions() {
|
||||
return (
|
||||
<Paper
|
||||
style={{
|
||||
width: "100%",
|
||||
padding: "10px",
|
||||
marginTop: "10px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<ErrorOutline></ErrorOutline>
|
||||
Could not get your auth options!
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
function Copyright() {
|
||||
return (
|
||||
@ -37,6 +54,8 @@ function Copyright() {
|
||||
|
||||
interface LoginRouteState {
|
||||
currEmail: string;
|
||||
errorGettingAuthOptions: boolean;
|
||||
authOptions?: AuthOptions;
|
||||
}
|
||||
|
||||
export class LoginRoute extends React.Component<{}, LoginRouteState> {
|
||||
@ -45,6 +64,8 @@ export class LoginRoute extends React.Component<{}, LoginRouteState> {
|
||||
|
||||
this.state = {
|
||||
currEmail: "",
|
||||
errorGettingAuthOptions: false,
|
||||
authOptions: undefined,
|
||||
};
|
||||
|
||||
this.handleChangedEmail = this.handleChangedEmail.bind(this);
|
||||
@ -56,17 +77,31 @@ export class LoginRoute extends React.Component<{}, LoginRouteState> {
|
||||
}
|
||||
|
||||
handleChangedEmail(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
this.setState({ currEmail: e.target.value });
|
||||
this.setState({
|
||||
currEmail: e.target.value,
|
||||
errorGettingAuthOptions: false,
|
||||
authOptions: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
handleSubmitEmail(e: React.ChangeEvent<any>) {
|
||||
async handleSubmitEmail(e: React.ChangeEvent<any>) {
|
||||
try {
|
||||
e.preventDefault();
|
||||
|
||||
if (!this.canSubmit) return;
|
||||
|
||||
AccountHelper.getAuthOptions(this.state.currEmail).then((r) =>
|
||||
matAlert("reset token => " + r.reset_token)
|
||||
const options = await AccountHelper.getAuthOptions(
|
||||
this.state.currEmail
|
||||
);
|
||||
this.setState({
|
||||
errorGettingAuthOptions: false,
|
||||
authOptions: options,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Failed to get auth options!", e);
|
||||
|
||||
this.setState({ errorGettingAuthOptions: true });
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -138,6 +173,23 @@ export class LoginRoute extends React.Component<{}, LoginRouteState> {
|
||||
Sign In
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
{/* Login error (if any) */}
|
||||
{this.state.errorGettingAuthOptions ? (
|
||||
ErrorGettingOptions()
|
||||
) : (
|
||||
<div></div>
|
||||
)}
|
||||
|
||||
{/* Auth options */}
|
||||
{this.state.authOptions ? (
|
||||
<AuthOptionsWidget
|
||||
email={this.state.currEmail}
|
||||
options={this.state.authOptions}
|
||||
></AuthOptionsWidget>
|
||||
) : (
|
||||
<div></div>
|
||||
)}
|
||||
</div>
|
||||
<Box mt={8}>
|
||||
<Copyright />
|
||||
@ -147,3 +199,75 @@ export class LoginRoute extends React.Component<{}, LoginRouteState> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
interface AuthOptionsWidgetProps {
|
||||
email: string;
|
||||
options: AuthOptions;
|
||||
}
|
||||
|
||||
interface AuthOptionsWidgetState {}
|
||||
|
||||
class AuthOptionsWidget extends React.Component<
|
||||
AuthOptionsWidgetProps,
|
||||
AuthOptionsWidgetState
|
||||
> {
|
||||
constructor(props: Readonly<AuthOptionsWidgetProps>) {
|
||||
super(props);
|
||||
|
||||
this.state = {};
|
||||
|
||||
this.loginWithResetToken = this.loginWithResetToken.bind(this);
|
||||
}
|
||||
|
||||
async loginWithResetToken() {
|
||||
try {
|
||||
const token = await input({
|
||||
label: "Reset token",
|
||||
message: "Please specify here your token:",
|
||||
minLength: 2,
|
||||
title: "Login using access token",
|
||||
});
|
||||
|
||||
await AccountHelper.authWithResetToken(this.props.email, token);
|
||||
|
||||
document.location.href = document.location.href + "";
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
matAlert("Authentication failed!");
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Paper style={{ width: "100%", marginTop: "10px" }}>
|
||||
<List style={{ width: "100%" }}>
|
||||
{/* Password reset token */}
|
||||
{this.props.options.reset_token ? (
|
||||
<ListItem button onClick={this.loginWithResetToken}>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<Lock />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText
|
||||
primary="Reset token"
|
||||
secondary="Sign in using a reset token"
|
||||
/>
|
||||
</ListItem>
|
||||
) : (
|
||||
<span></span>
|
||||
)}
|
||||
|
||||
<ListItem>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<VpnKey />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="Work" secondary="Jan 7, 2014" />
|
||||
</ListItem>
|
||||
</List>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user