mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 05:05:42 +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