From 2b61d257266ea2aad5a303373ec26e7b8bb040d8 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Wed, 22 May 2024 16:49:08 -0700 Subject: [PATCH] adding mfa login for admin --- app/mobile/src/access/admin/Admin.jsx | 43 +++++++++ app/mobile/src/access/admin/Admin.styled.js | 92 ++++++++++++++++++++ app/mobile/src/access/admin/useAdmin.hook.js | 30 +++++-- 3 files changed, 160 insertions(+), 5 deletions(-) diff --git a/app/mobile/src/access/admin/Admin.jsx b/app/mobile/src/access/admin/Admin.jsx index dc1fda62..cc9a35a0 100644 --- a/app/mobile/src/access/admin/Admin.jsx +++ b/app/mobile/src/access/admin/Admin.jsx @@ -5,6 +5,8 @@ import { useAdmin } from './useAdmin.hook'; import Colors from 'constants/Colors'; import MatIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import { tos } from 'constants/TermsOfService'; +import { BlurView } from "@react-native-community/blur"; +import { InputCode } from 'utils/InputCode'; export function Admin() { @@ -111,6 +113,47 @@ export function Admin() { + + + + + + { state.strings.mfaTitle } + { state.strings.mfaEnter } + + + { state.mfaError == '403' && ( + { state.strings.mfaError } + )} + { state.mfaError == '429' && ( + { state.strings.mfaDisabled } + )} + + + + { state.strings.cancel } + + { state.mfaCode != '' && ( + + { state.strings.mfaConfirm } + + )} + { state.mfaCode == '' && ( + + { state.strings.mfaConfirm } + + )} + + + + + ); } diff --git a/app/mobile/src/access/admin/Admin.styled.js b/app/mobile/src/access/admin/Admin.styled.js index 652375af..c47f86ac 100644 --- a/app/mobile/src/access/admin/Admin.styled.js +++ b/app/mobile/src/access/admin/Admin.styled.js @@ -15,6 +15,98 @@ export const styles = StyleSheet.create({ space: { width: 32, }, + mfaOverlay: { + width: '100%', + height: '100%', + }, + mfaError: { + width: '100%', + height: 24, + display: 'flex', + alignItems: 'center', + }, + mfaErrorLabel: { + color: Colors.dangerText, + }, + mfaControl: { + height: 32, + display: 'flex', + flexDirection: 'row', + width: '100%', + justifyContent: 'flex-end', + gap: 16, + }, + mfaCancel: { + width: 72, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + backgroundColor: Colors.cancelButton, + borderRadius: 4, + }, + mfaCancelLabel: { + color: Colors.cancelButtonText, + }, + mfaConfirm: { + width: 72, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + backgroundColor: Colors.primaryButton, + borderRadius: 4, + }, + mfaConfirmLabel: { + color: Colors.primaryButtonText, + }, + mfaDisabled: { + width: 72, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + backgroundColor: Colors.disabledButton, + borderRadius: 4, + }, + mfaDisabledLabel: { + color: Colors.disabledButtonText, + }, + mfaBase: { + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: '100%', + display: 'flex', + alignItems: 'center', + justifyContent: 'center' + }, + mfaContainer: { + backgroundColor: Colors.modalBase, + borderColor: Colors.modalBorder, + borderWidth: 1, + width: '80%', + maxWidth: 400, + display: 'flex', + gap: 8, + alignItems: 'center', + borderRadius: 8, + padding: 16, + }, + mfaTitle: { + fontSize: 20, + color: Colors.descriptionText, + paddingBottom: 8, + }, + mfaDescription: { + fontSize: 14, + color: Colors.descriptionText, + }, + mfaCode: { + width: 400, + borderWidth: 1, + borderColor: '#333333', + width: '100%', + opacity: 0, + }, modalContainer: { width: '100%', height: '100%', diff --git a/app/mobile/src/access/admin/useAdmin.hook.js b/app/mobile/src/access/admin/useAdmin.hook.js index 2aa06ef0..11d2eb79 100644 --- a/app/mobile/src/access/admin/useAdmin.hook.js +++ b/app/mobile/src/access/admin/useAdmin.hook.js @@ -23,7 +23,9 @@ export function useAdmin() { agree: false, showTerms: false, + mfaModal: false, mfaCode: '', + mfaError: null, }); const updateState = (value) => { @@ -85,10 +87,22 @@ export function useAdmin() { const unclaimed = await getNodeStatus(node); if (unclaimed) { await setNodeStatus(node, state.token); - } - const session = await setNodeAccess(node, state.token, state.mfaCode); - updateState({ server: node, busy: false }); - navigate('/dashboard', { state: { server: node, token: session }}); + } + try { + const session = await setNodeAccess(node, state.token, state.mfaCode); + updateState({ server: node, busy: false }); + navigate('/dashboard', { state: { server: node, token: session }}); + } + catch (err) { + if (err.message == '405' || err.message == '403' || err.message == '429') { + updateState({ mfaModal: true, mfaError: err.message }); + } + else { + console.log(err.message); + updateState({ busy: false, showAlert: true }); + throw new Error('login failed'); + } + } } catch (err) { console.log(err); @@ -96,7 +110,13 @@ export function useAdmin() { throw new Error("access failed"); } } - } + }, + setCode: (mfaCode) => { + updateState({ mfaCode }); + }, + dismissMFA: () => { + updateState({ mfaModal: false }); + }, }; return { state, actions };