1
0
mirror of https://github.com/sasjs/server.git synced 2026-01-06 06:10:04 +00:00

feat: ask for updated password on first login

This commit is contained in:
2022-11-22 19:58:17 +05:00
parent 68758aa616
commit 1d48f8856b
16 changed files with 185 additions and 11 deletions

View File

@@ -8,6 +8,7 @@ import Header from './components/header'
import Home from './components/home'
import Studio from './containers/Studio'
import Settings from './containers/Settings'
import UpdatePassword from './components/updatePassword'
import { AppContext } from './context/appContext'
import AuthCode from './containers/AuthCode'
@@ -29,6 +30,20 @@ function App() {
)
}
if (appContext.needsToUpdatePassword) {
return (
<ThemeProvider theme={theme}>
<HashRouter>
<Header />
<Routes>
<Route path="*" element={<UpdatePassword />} />
</Routes>
<ToastContainer />
</HashRouter>
</ThemeProvider>
)
}
return (
<ThemeProvider theme={theme}>
<HashRouter>

View File

@@ -32,6 +32,7 @@ const Login = () => {
appContext.setDisplayName?.(user.displayName)
appContext.setIsAdmin?.(user.isAdmin)
appContext.setLoggedIn?.(loggedIn)
appContext.setNeedsToUpdatePassword?.(user.needsToUpdatePassword)
}
}

View File

@@ -108,7 +108,7 @@ type PasswordInputProps = {
handleBlur?: () => void
}
const PasswordInput = ({
export const PasswordInput = ({
label,
password,
setPassword,

View File

@@ -0,0 +1,109 @@
import React, { useState, useEffect, useContext } from 'react'
import axios from 'axios'
import { Box, CssBaseline, Button, CircularProgress } from '@mui/material'
import { toast } from 'react-toastify'
import { PasswordInput } from './passwordModal'
import { AppContext } from '../context/appContext'
const UpdatePassword = () => {
const appContext = useContext(AppContext)
const [isLoading, setIsLoading] = useState(false)
const [currentPassword, setCurrentPassword] = useState('')
const [newPassword, setNewPassword] = useState('')
const [hasError, setHasError] = useState(false)
const [errorText, setErrorText] = useState('')
useEffect(() => {
if (
currentPassword.length > 0 &&
newPassword.length > 0 &&
newPassword === currentPassword
) {
setErrorText('New password should be different to current password.')
setHasError(true)
} else if (newPassword.length >= 6) {
setErrorText('')
setHasError(false)
}
}, [currentPassword, newPassword])
const handleBlur = () => {
if (newPassword.length < 6) {
setErrorText('Password length should be at least 6 characters.')
setHasError(true)
}
}
const handleSubmit = async (e: any) => {
e.preventDefault()
if (hasError || !currentPassword || !newPassword) return
setIsLoading(true)
axios
.patch(`/SASjsApi/auth/updatePassword`, {
currentPassword,
newPassword
})
.then((res: any) => {
appContext.setNeedsToUpdatePassword?.(false)
toast.success('Password updated', {
theme: 'dark',
position: toast.POSITION.BOTTOM_RIGHT
})
})
.catch((err) => {
toast.error('Failed: ' + err.response?.data || err.text, {
theme: 'dark',
position: toast.POSITION.BOTTOM_RIGHT
})
})
.finally(() => {
setIsLoading(false)
})
}
return isLoading ? (
<CircularProgress
style={{ position: 'absolute', left: '50%', top: '50%' }}
/>
) : (
<Box
className="main"
component="form"
onSubmit={handleSubmit}
sx={{
'& > :not(style)': { m: 1, width: '25ch' }
}}
>
<CssBaseline />
<h2>Welcome to SASjs Server!</h2>
<p style={{ width: 'auto' }}>
This is your first time login to SASjs server. Therefore, you need to
update your password.
</p>
<PasswordInput
label="Current Password"
password={currentPassword}
setPassword={setCurrentPassword}
/>
<PasswordInput
label="New Password"
password={newPassword}
setPassword={setNewPassword}
hasError={hasError}
errorText={errorText}
handleBlur={handleBlur}
/>
<Button
type="submit"
variant="outlined"
disabled={hasError || !currentPassword || !newPassword}
>
Update
</Button>
</Box>
)
}
export default UpdatePassword

View File

@@ -25,6 +25,8 @@ interface AppContextProps {
checkingSession: boolean
loggedIn: boolean
setLoggedIn: Dispatch<SetStateAction<boolean>> | null
needsToUpdatePassword: boolean
setNeedsToUpdatePassword: Dispatch<SetStateAction<boolean>> | null
userId: number
setUserId: Dispatch<SetStateAction<number>> | null
username: string
@@ -42,6 +44,8 @@ export const AppContext = createContext<AppContextProps>({
checkingSession: false,
loggedIn: false,
setLoggedIn: null,
needsToUpdatePassword: false,
setNeedsToUpdatePassword: null,
userId: 0,
setUserId: null,
username: '',
@@ -59,6 +63,7 @@ const AppContextProvider = (props: { children: ReactNode }) => {
const { children } = props
const [checkingSession, setCheckingSession] = useState(false)
const [loggedIn, setLoggedIn] = useState(false)
const [needsToUpdatePassword, setNeedsToUpdatePassword] = useState(false)
const [userId, setUserId] = useState(0)
const [username, setUsername] = useState('')
const [displayName, setDisplayName] = useState('')
@@ -79,6 +84,7 @@ const AppContextProvider = (props: { children: ReactNode }) => {
setDisplayName(data.displayName)
setIsAdmin(data.isAdmin)
setLoggedIn(true)
setNeedsToUpdatePassword(data.needsToUpdatePassword)
})
.catch(() => {
setLoggedIn(false)
@@ -120,6 +126,8 @@ const AppContextProvider = (props: { children: ReactNode }) => {
checkingSession,
loggedIn,
setLoggedIn,
needsToUpdatePassword,
setNeedsToUpdatePassword,
userId,
setUserId,
username,