diff --git a/src/App.tsx b/src/App.tsx index d21e84d..dbc57bf 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -48,7 +48,7 @@ function App() { to: '/home', label: 'Home', items: [ { to: '/profile', label: 'Profile', relative: true }, - { to: '/applications', label: 'Applications', relative: true } + { to: '/applications', label: 'Applications', relative: true, permission: [ 'applications', 5 ] } ] }, { diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 27d8174..b81dd76 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -4,8 +4,9 @@ import '../css/pages/Home.css'; import ErrorBoundary from '../util/ErrorBoundary'; import Applications from './home/Applications'; import Profile from './home/Profile'; +import { PermissionBarrier } from '../structures/PermissionBarrier'; -const Main = () => +const Main = () => { return
@@ -13,14 +14,18 @@ const Main = () =>
; }; -const Home = () => +const Home = () => { return } /> } /> - } /> + + + + } /> ; }; diff --git a/src/pages/home/Profile.tsx b/src/pages/home/Profile.tsx index 0c98ae4..43eb30e 100644 --- a/src/pages/home/Profile.tsx +++ b/src/pages/home/Profile.tsx @@ -1,44 +1,45 @@ import React, { useRef, useState } from 'react'; -import { capitalise, get, post } from '../../util/Util'; +import { capitalise, clearSession, get, post } from '../../util/Util'; import { useLoginContext } from '../../structures/UserContext'; import { FileSelector } from '../../components/InputElements'; import { ExternalProfile as EP, User } from '../../@types/ApiStructures'; +import { useNavigate } from 'react-router'; -const TwoFactorControls = ({ user }: {user: User}) => +const TwoFactorControls = ({ user }: {user: User}) => { const [ twoFactorError, set2FAError ] = useState(null); const [ displayInput, setDisplayInput ] = useState(false); const [ qr, setQr ] = useState(null); - const displayQr = async () => + const displayQr = async () => { const response = await get('/api/user/2fa'); - if (response.status !== 200) + if (response.status !== 200) return set2FAError(response.message || 'Uknown error'); setQr(response.message as string); }; const codeRef = useRef(null); - const disable2FA: React.MouseEventHandler = async (event) => + const disable2FA: React.MouseEventHandler = async (event) => { event.preventDefault(); const code = codeRef.current?.value; - if (!code) + if (!code) return; const response = await post('/api/user/2fa/disable', { code }); - if (response.status !== 200) + if (response.status !== 200) return set2FAError(response.message || 'Unknown error'); }; - const submitCode: React.MouseEventHandler = async (event) => + const submitCode: React.MouseEventHandler = async (event) => { event.preventDefault(); const code = codeRef.current?.value; - if (!code) + if (!code) return; const response = await post('/api/user/2fa/verify', { code }); - if (response.status !== 200) + if (response.status !== 200) return set2FAError(response.message || 'Unknown error'); }; @@ -55,7 +56,7 @@ const TwoFactorControls = ({ user }: {user: User}) => ; - if (user.twoFactor) + if (user.twoFactor) inner =
{displayInput ?
@@ -72,7 +73,7 @@ const TwoFactorControls = ({ user }: {user: User}) => }; -const ExternalProfile = ({ profile }: {profile: EP}) => +const ExternalProfile = ({ profile }: {profile: EP}) => { return
{capitalise(profile.provider)} @@ -81,7 +82,7 @@ const ExternalProfile = ({ profile }: {profile: EP}) =>
; }; -const ThirdPartyConnections = ({ user }: {user: User}) => +const ThirdPartyConnections = ({ user }: {user: User}) => { const { externalProfiles } = user; @@ -92,9 +93,9 @@ const ThirdPartyConnections = ({ user }: {user: User}) => }; -const Profile = () => +const Profile = () => { - + const navigate = useNavigate(); const user = useLoginContext()[0] as User; const [ file, setFile ] = useState(null); const [ error, setError ] = useState(null); @@ -105,9 +106,9 @@ const Profile = () => const newPassRef = useRef(null); const newPassRepeatRef = useRef(null); - const submit: React.MouseEventHandler = async (event) => + const submit: React.MouseEventHandler = async (event) => { - if (!file) + if (!file) return; const button = event.target as HTMLButtonElement; button.disabled = true; @@ -118,14 +119,14 @@ const Profile = () => const response = await post('/api/user/avatar', body, { headers: null }); - if (!response.success) + if (!response.success) setError(response.message || 'Unknown error'); - else + else setFile(null); button.disabled = false; }; - const updateSettings: React.MouseEventHandler = async (event) => + const updateSettings: React.MouseEventHandler = async (event) => { event.preventDefault(); const button = event.target as HTMLButtonElement; @@ -136,23 +137,33 @@ const Profile = () => const newPassword = newPassRef.current?.value; const newPasswordRepeat = newPassRepeatRef.current?.value; - if (!currentPassword) + if (!currentPassword) return setError('Missing password'); button.disabled = true; const data: {username?: string, displayName?: string, password?: string, newPassword?: string} = { username, displayName, password: currentPassword }; - if (currentPassword && newPassword && newPasswordRepeat) + if (currentPassword && newPassword && newPasswordRepeat) { - if (newPassword !== newPasswordRepeat) + if (currentPassword === newPassword) + { + button.disabled = false; + return setError('Old and new passwords cannot be the same'); + } + if (newPassword !== newPasswordRepeat) { button.disabled = false; return setError('Passwords do not match'); } data.newPassword = newPassword; } + const response = await post('/api/user/settings', data); - console.log(response); button.disabled = false; + if (response.data?.reAuth) + { + clearSession(); + navigate('/login'); + } };