feat: add user management screen

feat: login screen

fix: login routing and layout

feat: add users migration

feat: passport login strategy

fix: users migration

feat: simple authentication

fix: request body

feat: JWT authorization

feat: 2fa step on login

feat: 2fa flow

feat: add rememberme to req body

fix: hide 2fa secret from jwt

fix: block login access to logged in user

fix: rerouting to wizard

refactor: login screen

feat: setup 2fa state on login

feat: 2fa secret qr code

fix: remove jwt from 2fa secret

fix: wizard redirect after login

fix: 2fa setup flow

fix: user id to uuid

feat: user roles

feat: user sessions and db persistence

feat: session saving on DB and cookie

refactor: unused code

feat: cookie auto renew on request

feat: get user data endpoint

fix: repeated requests

feat: react routing

fix: private routes

refactor: auth

feat: sessions aware of ua and ip

feat: sessions on gql

feat: session management screen

feat: replace user_tokens usage for users

feat: user deletion also deletes active sessions

feat: remember me alters session cookie accordingly

feat: last session by all users

fix: login feedback

fix: page loading UX

feat: routes based on user role

feat: header aware of roles

feat: reset password

fix: reset password endpoint

feat: handle password change

feat: reset 2FA

feat: user role on management screen

feat: change user role

fix: user last session query

fix: context

fix: destroy own session

feat: reset password now resets sessions

feat: reset 2fa now resets sessions

refactor: user data

refactor: user management screen

feat: user enable

feat: schema directives

fix: remove schema directive temp

feat: create new users

feat: register endpoint

feat: modals for reset links

fix: directive Date errors

feat: superuser directive

feat: create user url modal

fix: user management layout

feat: confirmation modals

fix: info text

feat: 2fa input component

feat: code input on 2fa state

feat: add button styling

feat: confirmation modal on superuser action

feat: rework 2fa setup screen

feat: rework reset 2fa screen

fix: session management screen

fix: user management screen

fix: blacklist roles

chore: migrate old customer values to new columns

fix: value migration

fix: value migration

refactor: remove old code
This commit is contained in:
Sérgio Salgado 2020-10-27 10:05:06 +00:00 committed by Josh Harvey
parent 368781864e
commit fded22f39a
50 changed files with 9839 additions and 4501 deletions

View file

@ -13,7 +13,11 @@ import {
} from 'react-router-dom'
import AppContext from 'src/AppContext'
import AuthRegister from 'src/pages/AuthRegister'
// import AuthRegister from 'src/pages/AuthRegister'
import Login from 'src/pages/Authentication/Login'
import Register from 'src/pages/Authentication/Register'
import Reset2FA from 'src/pages/Authentication/Reset2FA'
import ResetPassword from 'src/pages/Authentication/ResetPassword'
import Blacklist from 'src/pages/Blacklist'
import Cashout from 'src/pages/Cashout'
import Commissions from 'src/pages/Commissions'
@ -34,13 +38,18 @@ import ReceiptPrinting from 'src/pages/OperatorInfo/ReceiptPrinting'
import TermsConditions from 'src/pages/OperatorInfo/TermsConditions'
import ServerLogs from 'src/pages/ServerLogs'
import Services from 'src/pages/Services/Services'
// import TokenManagement from 'src/pages/TokenManagement/TokenManagement'
import SessionManagement from 'src/pages/SessionManagement/SessionManagement'
import Transactions from 'src/pages/Transactions/Transactions'
import Triggers from 'src/pages/Triggers'
import UserManagement from 'src/pages/UserManagement/UserManagement'
import WalletSettings from 'src/pages/Wallet/Wallet'
import Wizard from 'src/pages/Wizard'
import { namespaces } from 'src/utils/config'
import PrivateRoute from './PrivateRoute'
import PublicRoute from './PublicRoute'
import { ROLES } from './utils'
const useStyles = makeStyles({
wrapper: {
flex: 1,
@ -55,12 +64,14 @@ const tree = [
key: 'transactions',
label: 'Transactions',
route: '/transactions',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: Transactions
},
{
key: 'maintenance',
label: 'Maintenance',
route: '/maintenance',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
get component() {
return () => <Redirect to={this.children[0].route} />
},
@ -69,30 +80,35 @@ const tree = [
key: 'cash_cassettes',
label: 'Cash Cassettes',
route: '/maintenance/cash-cassettes',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: CashCassettes
},
{
key: 'funding',
label: 'Funding',
route: '/maintenance/funding',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: Funding
},
{
key: 'logs',
label: 'Machine Logs',
route: '/maintenance/logs',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: MachineLogs
},
{
key: 'machine-status',
label: 'Machine Status',
route: '/maintenance/machine-status',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: MachineStatus
},
{
key: 'server-logs',
label: 'Server',
route: '/maintenance/server-logs',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: ServerLogs
}
]
@ -101,6 +117,7 @@ const tree = [
key: 'settings',
label: 'Settings',
route: '/settings',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
get component() {
return () => <Redirect to={this.children[0].route} />
},
@ -109,36 +126,42 @@ const tree = [
key: namespaces.COMMISSIONS,
label: 'Commissions',
route: '/settings/commissions',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: Commissions
},
{
key: namespaces.LOCALE,
label: 'Locales',
route: '/settings/locale',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: Locales
},
{
key: namespaces.CASH_OUT,
label: 'Cash-out',
route: '/settings/cash-out',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: Cashout
},
{
key: namespaces.NOTIFICATIONS,
label: 'Notifications',
route: '/settings/notifications',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: Notifications
},
{
key: 'services',
label: '3rd party services',
route: '/settings/3rd-party-services',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: Services
},
{
key: namespaces.WALLETS,
label: 'Wallet',
route: '/settings/wallet-settings',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: WalletSettings
},
{
@ -146,6 +169,7 @@ const tree = [
label: 'Operator Info',
route: '/settings/operator-info',
title: 'Operator Information',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
get component() {
return () => (
<Redirect
@ -161,24 +185,28 @@ const tree = [
key: 'contact-info',
label: 'Contact information',
route: '/settings/operator-info/contact-info',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: ContactInfo
},
{
key: 'receipt-printing',
label: 'Receipt',
route: '/settings/operator-info/receipt-printing',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: ReceiptPrinting
},
{
key: 'coin-atm-radar',
label: 'Coin ATM Radar',
route: '/settings/operator-info/coin-atm-radar',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: CoinAtmRadar
},
{
key: 'terms-conditions',
label: 'Terms & Conditions',
route: '/settings/operator-info/terms-conditions',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: TermsConditions
}
]
@ -189,6 +217,7 @@ const tree = [
key: 'compliance',
label: 'Compliance',
route: '/compliance',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
get component() {
return () => <Redirect to={this.children[0].route} />
},
@ -197,18 +226,21 @@ const tree = [
key: 'triggers',
label: 'Triggers',
route: '/compliance/triggers',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: Triggers
},
{
key: 'customers',
label: 'Customers',
route: '/compliance/customers',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: Customers
},
{
key: 'blacklist',
label: 'Blacklist',
route: '/compliance/blacklist',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: Blacklist
},
{
@ -220,9 +252,35 @@ const tree = [
{
key: 'customer',
route: '/compliance/customer/:id',
allowedRoles: [ROLES.USER, ROLES.SUPERUSER],
component: CustomerProfile
}
]
},
{
key: 'system',
label: 'System',
route: '/system',
allowedRoles: [ROLES.SUPERUSER],
get component() {
return () => <Redirect to={this.children[0].route} />
},
children: [
{
key: 'user-management',
label: 'User Management',
route: '/system/user-management',
allowedRoles: [ROLES.SUPERUSER],
component: UserManagement
},
{
key: 'session-management',
label: 'Session Management',
route: '/system/session-management',
allowedRoles: [ROLES.SUPERUSER],
component: SessionManagement
}
]
}
// {
// key: 'system',
@ -276,13 +334,32 @@ const Routes = () => {
const history = useHistory()
const location = useLocation()
const { wizardTested, userData } = useContext(AppContext)
const { wizardTested } = useContext(AppContext)
const dontTriggerPages = ['/404', '/register', '/wizard']
const dontTriggerPages = [
'/404',
'/register',
'/wizard',
'/login',
'/register',
'/resetpassword',
'/reset2fa'
]
if (!wizardTested && !R.contains(location.pathname)(dontTriggerPages)) {
history.push('/wizard')
return null
}
const getFilteredRoutes = () => {
if (!userData) return []
return flattened.filter(value => {
const keys = value.allowedRoles.map(v => {
return v.key
})
return R.includes(userData.role, keys)
})
}
const Transition = location.state ? Slide : Fade
@ -300,10 +377,10 @@ const Routes = () => {
return (
<Switch>
<Route exact path="/">
<Redirect to={{ pathname: '/dashboard' }} />
</Route>
<Route path={'/dashboard'}>
<PrivateRoute exact path="/">
<Redirect to={{ pathname: '/transactions' }} />
</PrivateRoute>
<PrivateRoute path={'/dashboard'}>
<Transition
className={classes.wrapper}
{...transitionProps}
@ -316,12 +393,15 @@ const Routes = () => {
</div>
}
/>
</Route>
<Route path="/machines" component={Machines} />
<Route path="/wizard" component={Wizard} />
<Route path="/register" component={AuthRegister} />
</PrivateRoute>
<PrivateRoute path="/machines" component={Machines} />
<PrivateRoute path="/wizard" component={Wizard} />
<Route path="/register" component={Register} />
<PublicRoute path="/login" restricted component={Login} />
<Route path="/resetpassword" component={ResetPassword} />
<Route path="/reset2fa" component={Reset2FA} />
{/* <Route path="/configmigration" component={ConfigMigration} /> */}
{flattened.map(({ route, component: Page, key }) => (
{getFilteredRoutes().map(({ route, component: Page, key }) => (
<Route path={route} key={key}>
<Transition
className={classes.wrapper}
@ -331,7 +411,9 @@ const Routes = () => {
unmountOnExit
children={
<div className={classes.wrapper}>
<Page name={key} />
<PrivateRoute path={route} key={key}>
<Page name={key} />
</PrivateRoute>
</div>
}
/>