mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-29 13:46:18 +01:00
feat: Auth and User System (#205)
* server-side JWT auth implementation * move oauth routes and strategies, fix bugs * backend modifications for wiring up the frontend login and reg forms * Add frontend data services for login and registration * Add login and registration forms * Implment auth context, functional client side auth * protect routes with jwt auth * finish local strategy (using local storage) * Start setting up google auth * disable token refresh, remove old auth middleware * refactor client, add ApiErrorBoundary context * disable google and facebook strategies * fix: fix presets not displaying specific to user * fix: fix issue with browser refresh * fix: casing issue with User.js (#11) * delete user.js to be renamed * fix: fix casing issue with User.js * comment out api error watcher temporarily * fix: issue with api error watcher (#12) * delete user.js to be renamed * fix: fix casing issue with User.js * comment out api error watcher temporarily * feat: add google auth social login * fix: make google login url dynamic based on dev/prod * fix: bug where UI is briefly displayed before redirecting to login * fix: fix cookie expires value for local auth * Update README.md * Update LOCAL_INSTALL structure * Add local testing instructions * Only load google strategy if client id and secret are provided * Update .env.example files with new params * fix issue with not redirecting to register form * only show google login button if value is set in .env * cleanup log messages * Add label to button for google login on login form * doc: fix client/server url values in .env.example * feat: add error message details to registration failure * Restore preventing paste on confirm password * auto-login user after registering * feat: forgot password (#24) * make login/reg pages look like openai's * add password reset data services * new form designs similar to openai, add password reset pages * add api's for password reset * email utils for password reset * remove bcrypt salt rounds from process.env * refactor: restructure api auth code, consolidate routes (#25) * add api's for password reset * remove bcrypt salt rounds from process.env * refactor: consolidate auth routes, use controller pattern * refactor: code cleanup * feat: migrate data to first user (#26) * refactor: use /api for auth routes * fix: use user id instead of username * feat: migrate data to first user on register * fix: fix social login routes after refactor (#27) * refactor: use /api for auth routes * fix: use user id instead of username * feat: migrate data to first user on register * fix: fix social login routes * fix: issue with auto-login when logging out then logging in with new browser window (#28) * refactor: use /api for auth routes * fix: use user id instead of username * feat: migrate data to first user on register * fix: fix social login routes * fix: fix issue with auto-login in new tab * doc: Update README and .env.example files with user system information (#29) * refactor: use /api for auth routes * fix: use user id instead of username * feat: migrate data to first user on register * fix: fix social login routes * fix: fix issue with auto-login in new tab * doc: update README and .env.example files * Fixup: LOCAL_INSTALL.md PS instructions (#200) (#30) Co-authored-by: alfredo-f <alfredo.fomitchenko@mail.polimi.it> * feat: send user with completion to protect against abuse (#31) * Fixup: LOCAL_INSTALL.md PS instructions (#200) * server-side JWT auth implementation * move oauth routes and strategies, fix bugs * backend modifications for wiring up the frontend login and reg forms * Add frontend data services for login and registration * Add login and registration forms * Implment auth context, functional client side auth * protect routes with jwt auth * finish local strategy (using local storage) * Start setting up google auth * disable token refresh, remove old auth middleware * refactor client, add ApiErrorBoundary context * disable google and facebook strategies * fix: fix presets not displaying specific to user * fix: fix issue with browser refresh * fix: casing issue with User.js (#11) * delete user.js to be renamed * fix: fix casing issue with User.js * comment out api error watcher temporarily * feat: add google auth social login * fix: make google login url dynamic based on dev/prod * fix: bug where UI is briefly displayed before redirecting to login * fix: fix cookie expires value for local auth * Only load google strategy if client id and secret are provided * Update .env.example files with new params * fix issue with not redirecting to register form * only show google login button if value is set in .env * cleanup log messages * Add label to button for google login on login form * doc: fix client/server url values in .env.example * feat: add error message details to registration failure * Restore preventing paste on confirm password * auto-login user after registering * feat: forgot password (#24) * make login/reg pages look like openai's * add password reset data services * new form designs similar to openai, add password reset pages * add api's for password reset * email utils for password reset * remove bcrypt salt rounds from process.env * refactor: restructure api auth code, consolidate routes (#25) * add api's for password reset * remove bcrypt salt rounds from process.env * refactor: consolidate auth routes, use controller pattern * refactor: code cleanup * feat: migrate data to first user (#26) * refactor: use /api for auth routes * fix: use user id instead of username * feat: migrate data to first user on register * fix: fix social login routes after refactor (#27) * refactor: use /api for auth routes * fix: use user id instead of username * feat: migrate data to first user on register * fix: fix social login routes * fix: issue with auto-login when logging out then logging in with new browser window (#28) * refactor: use /api for auth routes * fix: use user id instead of username * feat: migrate data to first user on register * fix: fix social login routes * fix: fix issue with auto-login in new tab * doc: Update README and .env.example files with user system information (#29) * refactor: use /api for auth routes * fix: use user id instead of username * feat: migrate data to first user on register * fix: fix social login routes * fix: fix issue with auto-login in new tab * doc: update README and .env.example files * Send user id to openai to protect against abuse * add meilisearch to gitignore * Remove webpack --------- Co-authored-by: alfredo-f <alfredo.fomitchenko@mail.polimi.it> --------- Co-authored-by: Danny Avila <110412045+danny-avila@users.noreply.github.com> Co-authored-by: Alfredo Fomitchenko <alfredo.fomitchenko@mail.polimi.it>
This commit is contained in:
parent
65543eb084
commit
dac19038a3
68 changed files with 3968 additions and 3394 deletions
|
|
@ -1,5 +1,5 @@
|
|||
export const user = () => {
|
||||
return `/api/me`;
|
||||
return `/api/auth/user`;
|
||||
};
|
||||
|
||||
export const messages = (id: string) => {
|
||||
|
|
@ -49,3 +49,35 @@ export const aiEndpoints = () => {
|
|||
export const tokenizer = () => {
|
||||
return `/api/tokenizer`;
|
||||
}
|
||||
|
||||
export const login = () => {
|
||||
return '/api/auth/login';
|
||||
}
|
||||
|
||||
export const logout = () => {
|
||||
return '/api/auth/logout';
|
||||
}
|
||||
|
||||
export const register = () => {
|
||||
return '/api/auth/register';
|
||||
}
|
||||
|
||||
export const loginFacebook = () => {
|
||||
return '/api/auth/facebook';
|
||||
}
|
||||
|
||||
export const loginGoogle = () => {
|
||||
return '/api/auth/google';
|
||||
}
|
||||
|
||||
export const refreshToken = () => {
|
||||
return '/api/auth/refresh';
|
||||
}
|
||||
|
||||
export const requestPasswordReset = () => {
|
||||
return '/api/auth/requestPasswordReset';
|
||||
}
|
||||
|
||||
export const resetPassword = () => {
|
||||
return '/api/auth/resetPassword';
|
||||
}
|
||||
|
|
@ -67,4 +67,32 @@ export const getAIEndpoints = () => {
|
|||
|
||||
export const updateTokenCount = (text: string) => {
|
||||
return request.post(endpoints.tokenizer(), {arg: text});
|
||||
}
|
||||
|
||||
export const login = (payload: t.TLoginUser) => {
|
||||
return request.post(endpoints.login(), payload);
|
||||
}
|
||||
|
||||
export const logout = () => {
|
||||
return request.post(endpoints.logout());
|
||||
}
|
||||
|
||||
export const register = (payload: t.TRegisterUser) => {
|
||||
return request.post(endpoints.register(), payload);
|
||||
}
|
||||
|
||||
export const refreshToken = () => {
|
||||
return request.post(endpoints.refreshToken());
|
||||
}
|
||||
|
||||
export const getLoginGoogle = () => {
|
||||
return request.get(endpoints.loginGoogle());
|
||||
}
|
||||
|
||||
export const requestPasswordReset = (payload: t.TRequestPasswordReset) => {
|
||||
return request.post(endpoints.requestPasswordReset(), payload);
|
||||
}
|
||||
|
||||
export const resetPassword = (payload: t.TResetPassword) => {
|
||||
return request.post(endpoints.resetPassword(), payload);
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import {
|
|||
} from "@tanstack/react-query";
|
||||
import * as t from "./types";
|
||||
import * as dataService from "./data-service";
|
||||
import axios from 'axios';
|
||||
|
||||
export enum QueryKeys {
|
||||
messages = "messsages",
|
||||
|
|
@ -25,11 +26,13 @@ export const useAbortRequestWithMessage = (): UseMutationResult<void, Error, { e
|
|||
return useMutation(({ endpoint, abortKey, message }) => dataService.abortRequestWithMessage(endpoint, abortKey, message));
|
||||
};
|
||||
|
||||
export const useGetUserQuery = (): QueryObserverResult<t.TUser> => {
|
||||
export const useGetUserQuery = (config?: UseQueryOptions<t.TUser>): QueryObserverResult<t.TUser> => {
|
||||
return useQuery<t.TUser>([QueryKeys.user], () => dataService.getUser(), {
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnReconnect: false,
|
||||
refetchOnMount: false,
|
||||
retry: false,
|
||||
...config,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -120,11 +123,13 @@ export const useClearConversationsMutation = (): UseMutationResult<unknown> => {
|
|||
});
|
||||
};
|
||||
|
||||
export const useGetConversationsQuery = (pageNumber: string): QueryObserverResult<t.TConversation[]> => {
|
||||
return useQuery([QueryKeys.allConversations, pageNumber], () =>
|
||||
export const useGetConversationsQuery = (pageNumber: string, config?: UseQueryOptions<t.TConversation[]>): QueryObserverResult<t.TConversation[]> => {
|
||||
return useQuery<t.TConversation[]>([QueryKeys.allConversations, pageNumber], () =>
|
||||
dataService.getConversations(pageNumber), {
|
||||
refetchOnReconnect: false,
|
||||
refetchOnMount: false,
|
||||
retry: 1,
|
||||
...config,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
@ -176,11 +181,12 @@ export const useUpdatePresetMutation = (): UseMutationResult<t.TPreset[], unknow
|
|||
);
|
||||
};
|
||||
|
||||
export const useGetPresetsQuery = (): QueryObserverResult<t.TPreset[], unknown> => {
|
||||
return useQuery([QueryKeys.presets], () => dataService.getPresets(), {
|
||||
export const useGetPresetsQuery = (config?: UseQueryOptions<t.TPreset[]>): QueryObserverResult<t.TPreset[], unknown> => {
|
||||
return useQuery<t.TPreset[]>([QueryKeys.presets], () => dataService.getPresets(), {
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnReconnect: false,
|
||||
refetchOnMount: false,
|
||||
...config,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -223,4 +229,52 @@ export const useUpdateTokenCountMutation = (): UseMutationResult<t.TUpdateTokenC
|
|||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export const useLoginUserMutation = (): UseMutationResult<t.TLoginUserResponse, unknown, t.TLoginUserRequest, unknown> => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation(
|
||||
(payload: t.TLoginUserRequest) =>
|
||||
dataService.login(payload),
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries([QueryKeys.user]);
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export const useRegisterUserMutation = (): UseMutationResult<t.TRegisterUserResponse, unknown, t.TRegisterUser, unknown> => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation(
|
||||
(payload: t.TRegisterUser) =>
|
||||
dataService.register(payload),
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries([QueryKeys.user]);
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export const useLogoutUserMutation = (): UseMutationResult<unknown> => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation(() => dataService.logout(), {
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries([QueryKeys.user]);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export const useRefreshTokenMutation = (): UseMutationResult<t.TRefreshTokenResponse, unknown, unknown, unknown> => {
|
||||
return useMutation(() => dataService.refreshToken(), {
|
||||
});
|
||||
}
|
||||
|
||||
export const useRequestPasswordResetMutation = (): UseMutationResult<unknown> => {
|
||||
return useMutation((payload: t.TRequestPasswordReset) => dataService.requestPasswordReset(payload));
|
||||
}
|
||||
|
||||
export const useResetPasswordMutation = (): UseMutationResult<unknown> => {
|
||||
return useMutation((payload: t.TResetPassword) => dataService.resetPassword(payload));
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import axios, { AxiosRequestConfig } from "axios";
|
||||
|
||||
async function _get<T>(url: string, options?: AxiosRequestConfig): Promise<T> {
|
||||
const response = await axios.get(url, { withCredentials: true, ...options});
|
||||
const response = await axios.get(url, { ...options});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -98,8 +98,14 @@ export type TPreset = {
|
|||
}
|
||||
|
||||
export type TUser = {
|
||||
id: string,
|
||||
username: string,
|
||||
display: string
|
||||
email: string,
|
||||
name: string,
|
||||
avatar: string,
|
||||
role: string,
|
||||
createdAt: string,
|
||||
updatedAt: string,
|
||||
};
|
||||
|
||||
export type TGetConversationsResponse = {
|
||||
|
|
@ -160,4 +166,31 @@ export type TMessageTreeNode = {}
|
|||
|
||||
export type TSearchMessage = {}
|
||||
|
||||
export type TSearchMessageTreeNode = {}
|
||||
export type TSearchMessageTreeNode = {}
|
||||
|
||||
export type TRegisterUser = {
|
||||
name: string,
|
||||
email: string,
|
||||
username: string,
|
||||
password: string,
|
||||
}
|
||||
|
||||
export type TLoginUser = {
|
||||
email: string,
|
||||
password: string,
|
||||
}
|
||||
|
||||
export type TLoginResponse = {
|
||||
token: string,
|
||||
user: TUser
|
||||
}
|
||||
|
||||
export type TRequestPasswordReset = {
|
||||
email: string,
|
||||
}
|
||||
|
||||
export type TResetPassword = {
|
||||
userId: string,
|
||||
token: string,
|
||||
password: string,
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue