diff --git a/.env b/.env
index 29ce2e6..63e92e2 100644
--- a/.env
+++ b/.env
@@ -1,3 +1,4 @@
VITE_APP_API_URL=http://localhost:2021
VITE_IS_LANDING_DEFAULT=false
VITE_OPENREPLAY_PROJECT_KEY=
+VITE_IS_SELF_HOSTED=false
\ No newline at end of file
diff --git a/.env.development b/.env.development
index d19eccf..07d358f 100644
--- a/.env.development
+++ b/.env.development
@@ -1,3 +1,4 @@
VITE_APP_API_URL=http://localhost:2021
VITE_APP_REDIRECT_URL=http://localhost:5173
-VITE_APP_GOOGLE_CLIENT_ID=USE_YOUR_OWN_CLIENT_ID
\ No newline at end of file
+VITE_APP_GOOGLE_CLIENT_ID=USE_YOUR_OWN_CLIENT_ID
+VITE_IS_SELF_HOSTED=true
\ No newline at end of file
diff --git a/.env.selfhosted b/.env.selfhosted
index f1d1a63..bcf4ec9 100644
--- a/.env.selfhosted
+++ b/.env.selfhosted
@@ -1,3 +1,4 @@
VITE_APP_API_URL=
VITE_APP_REDIRECT_URL=http://localhost:5173
-VITE_APP_GOOGLE_CLIENT_ID=USE_YOUR_OWN_CLIENT_ID
\ No newline at end of file
+VITE_APP_GOOGLE_CLIENT_ID=USE_YOUR_OWN_CLIENT_ID
+VITE_IS_SELF_HOSTED=true
\ No newline at end of file
diff --git a/src/views/Modals/Inputs/PasswordChangeModal.jsx b/src/views/Modals/Inputs/PasswordChangeModal.jsx
new file mode 100644
index 0000000..581b2f9
--- /dev/null
+++ b/src/views/Modals/Inputs/PasswordChangeModal.jsx
@@ -0,0 +1,117 @@
+import {
+ Box,
+ Button,
+ FormControl,
+ FormHelperText,
+ Input,
+ Modal,
+ ModalDialog,
+ Typography,
+} from '@mui/joy'
+import React, { useEffect } from 'react'
+
+function PassowrdChangeModal({ isOpen, onClose }) {
+ const [password, setPassword] = React.useState('')
+ const [confirmPassword, setConfirmPassword] = React.useState('')
+ const [passwordError, setPasswordError] = React.useState(false)
+ const [passwordTouched, setPasswordTouched] = React.useState(false)
+ const [confirmPasswordTouched, setConfirmPasswordTouched] =
+ React.useState(false)
+ useEffect(() => {
+ if (!passwordTouched || !confirmPasswordTouched) {
+ return
+ } else if (password !== confirmPassword) {
+ setPasswordError('Passwords do not match')
+ } else if (password.length < 8) {
+ setPasswordError('Password must be at least 8 characters')
+ } else if (password.length > 50) {
+ setPasswordError('Password must be less than 50 characters')
+ } else {
+ setPasswordError(null)
+ }
+ }, [password, confirmPassword, passwordTouched, confirmPasswordTouched])
+
+ const handleAction = isConfirmed => {
+ if (!isConfirmed) {
+ onClose(null)
+ return
+ }
+ onClose(password)
+ }
+
+ return (
+
+
+
+ Change Password
+
+
+
+ Please enter your new password.
+
+
+
+ New Password
+
+ {
+ setPasswordTouched(true)
+ setPassword(e.target.value)
+ }}
+ />
+
+
+
+
+ Confirm Password
+
+ {
+ setConfirmPasswordTouched(true)
+ setConfirmPassword(e.target.value)
+ }}
+ />
+
+ {passwordError}
+
+
+
+
+
+
+
+ )
+}
+export default PassowrdChangeModal
diff --git a/src/views/Settings/Settings.jsx b/src/views/Settings/Settings.jsx
index d612eec..9d53380 100644
--- a/src/views/Settings/Settings.jsx
+++ b/src/views/Settings/Settings.jsx
@@ -24,7 +24,9 @@ import {
GetUserProfile,
JoinCircle,
LeaveCircle,
+ UpdatePassword,
} from '../../utils/Fetcher'
+import PassowrdChangeModal from '../Modals/Inputs/PasswordChangeModal'
import APITokenSettings from './APITokenSettings'
import NotificationSetting from './NotificationSetting'
import ThemeToggle from './ThemeToggle'
@@ -35,6 +37,7 @@ const Settings = () => {
const [circleMemberRequests, setCircleMemberRequests] = useState([])
const [circleInviteCode, setCircleInviteCode] = useState('')
const [circleMembers, setCircleMembers] = useState([])
+ const [changePasswordModal, setChangePasswordModal] = useState(false)
useEffect(() => {
GetUserProfile().then(resp => {
resp.json().then(data => {
@@ -314,7 +317,7 @@ const Settings = () => {
Account Settings
- Change your account settings, including your password, display name
+ Change your account settings, type or update your password
Account Type : {getSubscriptionStatus()}
@@ -365,6 +368,39 @@ const Settings = () => {
)}
+ {import.meta.env.VITE_IS_SELF_HOSTED === 'true' && (
+
+
+ Password :
+
+
+
+ {changePasswordModal ? (
+ {
+ if (password) {
+ UpdatePassword(password).then(resp => {
+ if (resp.ok) {
+ alert('Password changed successfully')
+ } else {
+ alert('Password change failed')
+ }
+ })
+ }
+ setChangePasswordModal(false)
+ }}
+ />
+ ) : null}
+
+ )}