mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 13:37:30 +00:00
**Related issue:** Resolves #14401 this updates the mechanism of storing the auth token for a user that is used for making requests and validating a user session. We change the storage from local storage to a cookie. This allow a bit more security and prepares for a future change where we will allow the browser to handle setting and passing the auth token in the request. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. - [x] QA'd all new/changed functionality manually
125 lines
3.3 KiB
TypeScript
125 lines
3.3 KiB
TypeScript
import React, { useContext, useState, useEffect } from "react";
|
|
import { InjectedRouter } from "react-router";
|
|
import { Params } from "react-router/lib/Router";
|
|
|
|
import { AppContext } from "context/app";
|
|
import { RoutingContext } from "context/routing";
|
|
import paths from "router/paths";
|
|
import local from "utilities/local";
|
|
import authToken from "utilities/auth_token";
|
|
import configAPI from "services/entities/config";
|
|
import sessionsAPI from "services/entities/sessions";
|
|
|
|
import Button from "components/buttons/Button";
|
|
import AuthenticationFormWrapper from "components/AuthenticationFormWrapper";
|
|
import Spinner from "components/Spinner";
|
|
|
|
interface IMfaPage {
|
|
router: InjectedRouter; // v3
|
|
params: Params;
|
|
}
|
|
|
|
const baseClass = "mfa-page";
|
|
|
|
const MfaPage = ({ router, params }: IMfaPage) => {
|
|
const { token: mfaToken } = params;
|
|
const {
|
|
config,
|
|
currentUser,
|
|
setAvailableTeams,
|
|
setConfig,
|
|
setCurrentUser,
|
|
setCurrentTeam,
|
|
} = useContext(AppContext);
|
|
const { redirectLocation } = useContext(RoutingContext);
|
|
const [isExpired, setIsExpired] = useState(false);
|
|
const [shouldFinishMFA, setShouldFinishMFA] = useState(
|
|
!!local.getItem("auth_pending_mfa")
|
|
);
|
|
local.removeItem("auth_pending_mfa");
|
|
|
|
const finishMFA = async () => {
|
|
const { DASHBOARD, RESET_PASSWORD, NO_ACCESS } = paths;
|
|
|
|
try {
|
|
const response = await sessionsAPI.finishMFA({ token: mfaToken });
|
|
const { user, available_teams, token } = response;
|
|
|
|
authToken.save(token);
|
|
|
|
setCurrentUser(user);
|
|
setAvailableTeams(user, available_teams);
|
|
setCurrentTeam(undefined);
|
|
|
|
if (!user.global_role && user.teams.length === 0) {
|
|
router.push(NO_ACCESS);
|
|
return;
|
|
}
|
|
// Redirect to password reset page if user is forced to reset password.
|
|
// Any other requests will fail.
|
|
else if (user.force_password_reset) {
|
|
router.push(RESET_PASSWORD);
|
|
return;
|
|
} else if (config) {
|
|
router.push(redirectLocation || DASHBOARD);
|
|
return;
|
|
}
|
|
|
|
configAPI.loadAll().then((configResponse) => {
|
|
setConfig(configResponse);
|
|
router.push(redirectLocation || DASHBOARD);
|
|
});
|
|
} catch (response) {
|
|
setIsExpired(true);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (shouldFinishMFA) {
|
|
finishMFA();
|
|
}
|
|
}, [shouldFinishMFA, finishMFA]);
|
|
|
|
useEffect(() => {
|
|
if (currentUser) {
|
|
return router.push(paths.DASHBOARD);
|
|
}
|
|
}, [currentUser, router]);
|
|
|
|
const onClickLoginButton = () => {
|
|
router.push(paths.LOGIN);
|
|
};
|
|
|
|
const onClickFinishLoginButton = () => {
|
|
setShouldFinishMFA(true);
|
|
};
|
|
|
|
if (!shouldFinishMFA) {
|
|
return (
|
|
<AuthenticationFormWrapper className={baseClass}>
|
|
<Button onClick={onClickFinishLoginButton}>Log in</Button>
|
|
</AuthenticationFormWrapper>
|
|
);
|
|
}
|
|
|
|
if (isExpired) {
|
|
return (
|
|
<AuthenticationFormWrapper className={baseClass} header="Invalid token">
|
|
<>
|
|
<div className={`${baseClass}__description`}>
|
|
<p>Log in again for a new link.</p>
|
|
</div>
|
|
<Button onClick={onClickLoginButton}>Back to login</Button>
|
|
</>
|
|
</AuthenticationFormWrapper>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<AuthenticationFormWrapper className={baseClass}>
|
|
<Spinner />
|
|
</AuthenticationFormWrapper>
|
|
);
|
|
};
|
|
|
|
export default MfaPage;
|