mirror of
https://github.com/inventree/InvenTree.git
synced 2025-07-03 20:20:58 +00:00
[PUI] Add 2FA login (#7469)
* Add `2fa_urls`
* Add new fields to serializer
* Add new interface to PUI interfaces
* fix url resolving
* add frontend redirect for MFA login
* redirect login if mfa is required
* Merege upstream/master into branch
* reset default login
* remove mfa states
* fix auth args
* add handler for MFA redirect auth
* Revert "Merege upstream/master into branch"
This reverts commit 717001d8f1
.
* revert api version bump
* revert frontend error handling change
* reduce complexity
* reset schema text
* Add e2e test for MFA login url
* accept either POST or body data for login pre-check
* remove CUI test
* style fixes
This commit is contained in:
@ -1,15 +1,45 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import axios from 'axios';
|
||||
import { NavigateFunction } from 'react-router-dom';
|
||||
|
||||
import { api, setApiDefaults } from '../App';
|
||||
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
||||
import { apiUrl } from '../states/ApiState';
|
||||
import { apiUrl, useServerApiState } from '../states/ApiState';
|
||||
import { useLocalState } from '../states/LocalState';
|
||||
import { useUserState } from '../states/UserState';
|
||||
import { fetchGlobalStates } from '../states/states';
|
||||
import { showLoginNotification } from './notifications';
|
||||
|
||||
/**
|
||||
* sends a request to the specified url from a form. this will change the window location.
|
||||
* @param {string} path the path to send the post request to
|
||||
* @param {object} params the parameters to add to the url
|
||||
* @param {string} [method=post] the method to use on the form
|
||||
*
|
||||
* Source https://stackoverflow.com/questions/133925/javascript-post-request-like-a-form-submit/133997#133997
|
||||
*/
|
||||
|
||||
function post(path: string, params: any, method = 'post') {
|
||||
const form = document.createElement('form');
|
||||
form.method = method;
|
||||
form.action = path;
|
||||
|
||||
for (const key in params) {
|
||||
if (params.hasOwnProperty(key)) {
|
||||
const hiddenField = document.createElement('input');
|
||||
hiddenField.type = 'hidden';
|
||||
hiddenField.name = key;
|
||||
hiddenField.value = params[key];
|
||||
|
||||
form.appendChild(hiddenField);
|
||||
}
|
||||
}
|
||||
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to login using username:password combination.
|
||||
* If login is successful, an API token will be returned.
|
||||
@ -50,7 +80,19 @@ export const doBasicLogin = async (username: string, password: string) => {
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
.catch((err) => {
|
||||
if (
|
||||
err?.response.status == 403 &&
|
||||
err?.response.data.detail == 'MFA required for this user'
|
||||
) {
|
||||
post(apiUrl(ApiEndpoints.user_login), {
|
||||
username: username,
|
||||
password: password,
|
||||
csrfmiddlewaretoken: getCsrfCookie(),
|
||||
mfa: true
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (result) {
|
||||
await fetchUserState();
|
||||
@ -65,7 +107,7 @@ export const doBasicLogin = async (username: string, password: string) => {
|
||||
*
|
||||
* @arg deleteToken: If true, delete the token from the server
|
||||
*/
|
||||
export const doLogout = async (navigate: any) => {
|
||||
export const doLogout = async (navigate: NavigateFunction) => {
|
||||
const { clearUserState, isLoggedIn } = useUserState.getState();
|
||||
|
||||
// Logout from the server session
|
||||
|
Reference in New Issue
Block a user