Skip to content

Commit

Permalink
[feat] add reset password API support (#119)
Browse files Browse the repository at this point in the history
Also make sure to verify permission on reload
  • Loading branch information
kartik-gupta-ij authored Aug 18, 2023
1 parent 40755d9 commit aebbd16
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 40 deletions.
3 changes: 2 additions & 1 deletion src/api/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ export const ABOUT_URL = `${API_V1}/about`;
// Users Management
export const USERS_LIST_URL = `${API_V1}/user`;
export const USER_URL = (username: string) => `${USERS_LIST_URL}/${username}`;
export const USER_ROLES_URL = (username: string) => `${USER_URL(username)}/role`;
export const USER_ROLES_URL = (username: string) => `${USER_URL(username)}/role`;
export const USER_PASSWORD_URL = (username: string) => `${USER_URL(username)}/generate-new-password`;
10 changes: 7 additions & 3 deletions src/api/users.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Axios } from "./axios";
import { USERS_LIST_URL, USER_ROLES_URL, USER_URL } from "./constants";
import { USERS_LIST_URL, USER_PASSWORD_URL, USER_ROLES_URL, USER_URL } from "./constants";

export const getUsers = () => {
return Axios().get(USERS_LIST_URL);
}

export const putUser = (username: string, roles?: object[]) => {
return Axios().put(USER_URL(username), roles );
export const postUser = (username: string, roles?: object[]) => {
return Axios().post(USER_URL(username), roles );
}

export const deleteUser = (username: string) => {
Expand All @@ -19,4 +19,8 @@ export const putUserRoles = (username: string, roles: object[]) => {

export const getUserRoles = (username: string) => {
return Axios().get(USER_ROLES_URL(username));
}

export const postUserResetPassword = (username: string) => {
return Axios().post(USER_PASSWORD_URL(username));
}
1 change: 1 addition & 0 deletions src/components/Navbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ const Navbar: FC<NavbarProps> = (props) => {
} else if (userSepecficStreams && Boolean(userSepecficStreams.length)) {
if (location.pathname === USERS_MANAGEMENT_ROUTE) {
handleChangeWithoutRiderection(userSepecficStreams[0].name, location.pathname);
navigate(`/users`);
} else {
handleChange(userSepecficStreams[0].name);
}
Expand Down
36 changes: 32 additions & 4 deletions src/hooks/useGetLogStreamList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@ import { useEffect } from 'react';
import useMountedState from './useMountedState';
import { notifications } from '@mantine/notifications';
import { IconFileAlert, IconCheck } from '@tabler/icons-react';
import { useLocalStorage } from '@mantine/hooks';
import { useNavigate } from 'react-router-dom';
import { LOGIN_ROUTE } from '@/constants/routes';

export const useGetLogStreamList = () => {
const [data, setData] = useMountedState<LogStreamData | null>(null);
const [error, setError] = useMountedState<string | null>(null);
const [loading, setLoading] = useMountedState<boolean>(false);
const [, , removeCredentials] = useLocalStorage({ key: 'credentials' });
const [, , removeUsername] = useLocalStorage({ key: 'username' });
const navigate = useNavigate();

const getData = async () => {
try {
Expand Down Expand Up @@ -38,23 +44,45 @@ export const useGetLogStreamList = () => {
color: 'green',
title: 'Streams was loaded',
message: 'Successfully Loaded!!',
icon: <IconCheck size="1rem" />,
icon: <IconCheck size="1rem" />,
autoClose: 1000,
});
}

if(streams && streams.length===0){
if (streams && streams.length === 0) {
notifications.update({
id: 'load-data',
color: 'red',
title: 'No Streams',
message: 'No Streams Found in your account',
icon: <IconFileAlert size="1rem" />,
icon: <IconFileAlert size="1rem" />,
autoClose: 2000,
});
}
break;
}
case StatusCodes.UNAUTHORIZED: {
setError('Unauthorized');
notifications.update({
id: 'load-data',
color: 'red',
title: 'Error Occured',
message: 'Unauthorized',
icon: <IconFileAlert size="1rem" />,
autoClose: 2000,
});

removeCredentials();
removeUsername();
navigate(
{
pathname: LOGIN_ROUTE,
},
{ replace: true },
);

break;
}
default: {
setError('Failed to get log streams');
notifications.update({
Expand Down Expand Up @@ -89,5 +117,5 @@ export const useGetLogStreamList = () => {
getData();
}, []);

return { data, error, loading, getData ,resetData};
return { data, error, loading, getData, resetData };
};
19 changes: 19 additions & 0 deletions src/hooks/useGetUserRoles.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { StatusCodes } from 'http-status-codes';
import useMountedState from './useMountedState';
import { getUserRoles } from '@/api/users';
import { useLocalStorage } from '@mantine/hooks';
import { useNavigate } from 'react-router-dom';
import { LOGIN_ROUTE } from '@/constants/routes';

export const useGetUserRole = () => {
const [data, setData] = useMountedState<any | null>(null);
const [error, setError] = useMountedState<string | null>(null);
const [loading, setLoading] = useMountedState<boolean>(false);
const [, , removeCredentials] = useLocalStorage({ key: 'credentials' });
const [, , removeUsername] = useLocalStorage({ key: 'username' });
const navigate = useNavigate();

const getRoles = async (userName:string) => {
try {
Expand All @@ -18,6 +24,19 @@ export const useGetUserRole = () => {
setData(res.data);
break;
}
case StatusCodes.UNAUTHORIZED: {
setError('Unauthorized');
removeCredentials();
removeUsername();
navigate(
{
pathname: LOGIN_ROUTE,
},
{ replace: true },
);

break;
}
default: {
setError('Failed to get Roles');
console.error(res);
Expand Down
76 changes: 76 additions & 0 deletions src/hooks/usePostResetPassword.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { StatusCodes } from 'http-status-codes';
import useMountedState from './useMountedState';
import { postUserResetPassword } from '@/api/users';
import { notifications } from '@mantine/notifications';
import { IconCheck, IconFileAlert } from '@tabler/icons-react';

export const usePostUserResetPassword = () => {
const [data, setData] = useMountedState<any | null>(null);
const [error, setError] = useMountedState<string | null>(null);
const [loading, setLoading] = useMountedState<boolean>(false);

const resetPasswordUser = async (userName:string) => {
try {
setLoading(true);
notifications.show({
id: 'load-data',
loading: true,
color: '#545BEB',
title: 'Changing Password',
message: 'Password will be Changed.',
autoClose: false,
withCloseButton: false,
});
setError(null);
const res = await postUserResetPassword(userName);

switch (res.status) {
case StatusCodes.OK: {
setData(res.data);
notifications.update({
id: 'load-data',
color: 'green',
title: 'Password was Changed',
message: 'Successfully Changed!!',
icon: <IconCheck size="1rem" />,
autoClose: 3000,
});
break;

}
default: {
setError(res.data);
console.error(res);
notifications.update({
id: 'load-data',
color: 'red',
title: 'Error Occured',
message: res.data,
icon: <IconFileAlert size="1rem" />,
autoClose: 2000,
});
}
}
} catch(error) {
setError('Failed to get Create User');
notifications.update({
id: 'load-data',
color: 'red',
title: 'Error Occured',
message: 'Error Occured while Creating User',
icon: <IconFileAlert size="1rem" />,
autoClose: 2000,
});
console.error(error);
} finally {
setLoading(false);
}
};

const resetData = () => {
setData(null);
};

return { data, error, loading, resetPasswordUser, resetData };
};

6 changes: 3 additions & 3 deletions src/hooks/usePutUser.tsx → src/hooks/usePostUser.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { StatusCodes } from 'http-status-codes';
import useMountedState from './useMountedState';
import { putUser } from '@/api/users';
import { postUser } from '@/api/users';
import { notifications } from '@mantine/notifications';
import { IconCheck, IconFileAlert } from '@tabler/icons-react';

export const usePutUser = () => {
export const usePostUser = () => {
const [data, setData] = useMountedState<any | null>(null);
const [error, setError] = useMountedState<string | null>(null);
const [loading, setLoading] = useMountedState<boolean>(false);
Expand All @@ -22,7 +22,7 @@ export const usePutUser = () => {
withCloseButton: false,
});
setError(null);
const res = await putUser(userName,roles);
const res = await postUser(userName,roles);

switch (res.status) {
case StatusCodes.OK: {
Expand Down
16 changes: 6 additions & 10 deletions src/pages/Users/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Box, Button, Modal, ScrollArea, Select, Table, Text, TextInput} from '@mantine/core';
import { Box, Button, Modal, ScrollArea, Select, Table, Text, TextInput } from '@mantine/core';
import { useDocumentTitle } from '@mantine/hooks';
import { FC, useEffect, useState } from 'react';

import { useGetUsers } from '@/hooks/useGetUsers';
import { useUsersStyles } from './styles';
import { usePutUser } from '@/hooks/usePutUser';
import { usePostUser } from '@/hooks/usePostUser';
import { Prism } from '@mantine/prism';
import RoleTd from './row';
import { useGetLogStreamList } from '@/hooks/useGetLogStreamList';
Expand All @@ -15,15 +15,13 @@ const Users: FC = () => {
state: { subCreateUserModalTogle },
} = useHeaderContext();


useEffect(() => {
const listener = subCreateUserModalTogle.subscribe(setModalOpen);
return () => {
listener();
};
}, [subCreateUserModalTogle.get()]);


const [modalOpen, setModalOpen] = useState<boolean>(false);
const [createUserInput, setCreateUserInput] = useState<string>('');
const [tagInput, setTagInput] = useState<string>('');
Expand All @@ -39,7 +37,7 @@ const Users: FC = () => {
loading: CreatedUserLoading,
createUser,
resetData: resetCreateUser,
} = usePutUser();
} = usePostUser();
const { data: users, error: usersError, loading: usersLoading, getUsersList, resetData: usersReset } = useGetUsers();

const [tableRows, setTableRows] = useState<any>([]);
Expand Down Expand Up @@ -102,9 +100,7 @@ const Users: FC = () => {
});
}
if (selectedPrivilege === 'reader' || selectedPrivilege === 'writer') {
if (
streams?.find((stream) => stream.name === SelectedStream)
) {
if (streams?.find((stream) => stream.name === SelectedStream)) {
if (tagInput !== '' && tagInput !== undefined && selectedPrivilege !== 'writer') {
userRole?.push({
privilege: selectedPrivilege,
Expand All @@ -127,7 +123,7 @@ const Users: FC = () => {
};

const createVaildtion = () => {
if (users?.includes(createUserInput) || createUserInput.length <3) {
if (users?.includes(createUserInput) || createUserInput.length < 3) {
return true;
}
if (selectedPrivilege !== '') {
Expand Down Expand Up @@ -163,7 +159,7 @@ const Users: FC = () => {
<th style={{ textAlign: 'center' }}>Reset Password</th>
</tr>
</thead>
<tbody >{tableRows}</tbody>
<tbody>{tableRows}</tbody>
</Table>
</ScrollArea>
<Modal
Expand Down
Loading

0 comments on commit aebbd16

Please sign in to comment.