perms + re-auth after passwd change
This commit is contained in:
parent
d775b65738
commit
17b338fc49
@ -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 ] }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -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 <div>
|
||||
@ -13,14 +14,18 @@ const Main = () =>
|
||||
</div>;
|
||||
};
|
||||
|
||||
const Home = () =>
|
||||
const Home = () =>
|
||||
{
|
||||
|
||||
return <ErrorBoundary>
|
||||
<Routes>
|
||||
<Route path="/" element={<Main />} />
|
||||
<Route path="/profile" element={<Profile />} />
|
||||
<Route path="/applications/*" element={<Applications />} />
|
||||
<Route path="/applications/*" element={
|
||||
<PermissionBarrier permission='applications'>
|
||||
<Applications />
|
||||
</PermissionBarrier>
|
||||
} />
|
||||
</Routes>
|
||||
</ErrorBoundary>;
|
||||
};
|
||||
|
@ -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<string | null>(null);
|
||||
const [ displayInput, setDisplayInput ] = useState(false);
|
||||
|
||||
const [ qr, setQr ] = useState<string | null>(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<HTMLInputElement>(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}) =>
|
||||
</div>;
|
||||
|
||||
|
||||
if (user.twoFactor)
|
||||
if (user.twoFactor)
|
||||
inner = <div>
|
||||
{displayInput ?
|
||||
<form>
|
||||
@ -72,7 +73,7 @@ const TwoFactorControls = ({ user }: {user: User}) =>
|
||||
|
||||
};
|
||||
|
||||
const ExternalProfile = ({ profile }: {profile: EP}) =>
|
||||
const ExternalProfile = ({ profile }: {profile: EP}) =>
|
||||
{
|
||||
return <div>
|
||||
<b>{capitalise(profile.provider)}</b>
|
||||
@ -81,7 +82,7 @@ const ExternalProfile = ({ profile }: {profile: EP}) =>
|
||||
</div>;
|
||||
};
|
||||
|
||||
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<File | null>(null);
|
||||
const [ error, setError ] = useState<string | null>(null);
|
||||
@ -105,9 +106,9 @@ const Profile = () =>
|
||||
const newPassRef = useRef<HTMLInputElement>(null);
|
||||
const newPassRepeatRef = useRef<HTMLInputElement>(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');
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user