mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-11 21:18:51 +01:00
* 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>
280 lines
No EOL
8.3 KiB
TypeScript
280 lines
No EOL
8.3 KiB
TypeScript
import {
|
|
UseQueryOptions,
|
|
useQuery,
|
|
useMutation,
|
|
useQueryClient,
|
|
UseMutationResult,
|
|
QueryObserverResult,
|
|
} from "@tanstack/react-query";
|
|
import * as t from "./types";
|
|
import * as dataService from "./data-service";
|
|
import axios from 'axios';
|
|
|
|
export enum QueryKeys {
|
|
messages = "messsages",
|
|
allConversations = "allConversations",
|
|
conversation = "conversation",
|
|
searchEnabled = "searchEnabled",
|
|
user = "user",
|
|
endpoints = "endpoints",
|
|
presets = "presets",
|
|
searchResults = "searchResults",
|
|
tokenCount = "tokenCount",
|
|
}
|
|
|
|
export const useAbortRequestWithMessage = (): UseMutationResult<void, Error, { endpoint: string; abortKey: string; message: string }> => {
|
|
return useMutation(({ endpoint, abortKey, message }) => dataService.abortRequestWithMessage(endpoint, abortKey, message));
|
|
};
|
|
|
|
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,
|
|
});
|
|
};
|
|
|
|
export const useGetMessagesByConvoId = (
|
|
id: string,
|
|
config?: UseQueryOptions<t.TMessage[]>
|
|
): QueryObserverResult<t.TMessage[]> => {
|
|
return useQuery<t.TMessage[]>([QueryKeys.messages, id], () =>
|
|
dataService.getMessagesByConvoId(id),
|
|
{
|
|
refetchOnWindowFocus: false,
|
|
refetchOnReconnect: false,
|
|
refetchOnMount: false,
|
|
...config,
|
|
}
|
|
);
|
|
};
|
|
|
|
export const useGetConversationByIdQuery = (
|
|
id: string,
|
|
config?: UseQueryOptions<t.TConversation>
|
|
): QueryObserverResult<t.TConversation> => {
|
|
return useQuery<t.TConversation>([QueryKeys.conversation, id], () =>
|
|
dataService.getConversationById(id),
|
|
{
|
|
refetchOnWindowFocus: false,
|
|
refetchOnReconnect: false,
|
|
refetchOnMount: false,
|
|
...config
|
|
}
|
|
);
|
|
}
|
|
|
|
//This isn't ideal because its just a query and we're using mutation, but it was the only way
|
|
//to make it work with how the Chat component is structured
|
|
export const useGetConversationByIdMutation = (
|
|
id: string,
|
|
): UseMutationResult<t.TConversation> => {
|
|
const queryClient = useQueryClient();
|
|
return useMutation(() => dataService.getConversationById(id),
|
|
{
|
|
onSuccess: (res: t.TConversation) => {
|
|
queryClient.invalidateQueries([QueryKeys.conversation, id]);
|
|
},
|
|
}
|
|
);
|
|
};
|
|
|
|
export const useUpdateConversationMutation = (
|
|
id: string
|
|
): UseMutationResult<t.TUpdateConversationResponse, unknown, t.TUpdateConversationRequest, unknown> => {
|
|
const queryClient = useQueryClient();
|
|
return useMutation(
|
|
(payload: t.TUpdateConversationRequest) =>
|
|
dataService.updateConversation(payload),
|
|
{
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries([QueryKeys.conversation, id]);
|
|
queryClient.invalidateQueries([QueryKeys.allConversations]);
|
|
},
|
|
}
|
|
);
|
|
};
|
|
|
|
|
|
export const useDeleteConversationMutation = (
|
|
id?: string
|
|
): UseMutationResult<t.TDeleteConversationResponse, unknown, t.TDeleteConversationRequest, unknown> => {
|
|
const queryClient = useQueryClient();
|
|
return useMutation(
|
|
(payload: t.TDeleteConversationRequest) =>
|
|
dataService.deleteConversation(payload),
|
|
{
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries([QueryKeys.conversation, id]);
|
|
queryClient.invalidateQueries([QueryKeys.allConversations]);
|
|
},
|
|
}
|
|
);
|
|
};
|
|
|
|
export const useClearConversationsMutation = (): UseMutationResult<unknown> => {
|
|
const queryClient = useQueryClient();
|
|
return useMutation(() => dataService.clearAllConversations(), {
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries([QueryKeys.allConversations]);
|
|
},
|
|
});
|
|
};
|
|
|
|
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,
|
|
}
|
|
);
|
|
}
|
|
|
|
export const useGetSearchEnabledQuery = (config?: UseQueryOptions<boolean>): QueryObserverResult<boolean> => {
|
|
return useQuery<boolean>([QueryKeys.searchEnabled], () =>
|
|
dataService.getSearchEnabled(), {
|
|
refetchOnWindowFocus: false,
|
|
refetchOnReconnect: false,
|
|
refetchOnMount: false,
|
|
...config,
|
|
}
|
|
);
|
|
}
|
|
|
|
export const useGetEndpointsQuery = (): QueryObserverResult<t.TEndpoints> => {
|
|
return useQuery([QueryKeys.endpoints], () =>
|
|
dataService.getAIEndpoints(), {
|
|
refetchOnWindowFocus: false,
|
|
refetchOnReconnect: false,
|
|
refetchOnMount: false,
|
|
}
|
|
);
|
|
}
|
|
|
|
export const useCreatePresetMutation = (): UseMutationResult<t.TPreset[], unknown, t.TPreset, unknown> => {
|
|
const queryClient = useQueryClient();
|
|
return useMutation(
|
|
(payload: t.TPreset) =>
|
|
dataService.createPreset(payload),
|
|
{
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries([QueryKeys.presets]);
|
|
},
|
|
}
|
|
);
|
|
};
|
|
|
|
export const useUpdatePresetMutation = (): UseMutationResult<t.TPreset[], unknown, t.TPreset, unknown> => {
|
|
const queryClient = useQueryClient();
|
|
return useMutation(
|
|
(payload: t.TPreset) =>
|
|
dataService.updatePreset(payload),
|
|
{
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries([QueryKeys.presets]);
|
|
},
|
|
}
|
|
);
|
|
};
|
|
|
|
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,
|
|
});
|
|
};
|
|
|
|
export const useDeletePresetMutation = (): UseMutationResult<t.TPreset[], unknown, t.TPreset | {}, unknown> => {
|
|
const queryClient = useQueryClient();
|
|
return useMutation(
|
|
(payload: t.TPreset | {}) =>
|
|
dataService.deletePreset(payload),
|
|
{
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries([QueryKeys.presets]);
|
|
},
|
|
}
|
|
);
|
|
}
|
|
|
|
export const useSearchQuery = (
|
|
searchQuery: string,
|
|
pageNumber: string,
|
|
config?: UseQueryOptions<t.TSearchResults>
|
|
): QueryObserverResult<t.TSearchResults> => {
|
|
return useQuery<t.TSearchResults>([QueryKeys.searchResults, pageNumber, searchQuery], () =>
|
|
dataService.searchConversations(searchQuery, pageNumber), {
|
|
refetchOnWindowFocus: false,
|
|
refetchOnReconnect: false,
|
|
refetchOnMount: false,
|
|
...config
|
|
}
|
|
);
|
|
}
|
|
|
|
export const useUpdateTokenCountMutation = (): UseMutationResult<t.TUpdateTokenCountResponse, unknown, string, unknown> => {
|
|
const queryClient = useQueryClient();
|
|
return useMutation(
|
|
(text: string) =>
|
|
dataService.updateTokenCount(text),
|
|
{
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries([QueryKeys.tokenCount]);
|
|
},
|
|
}
|
|
);
|
|
}
|
|
|
|
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));
|
|
} |