mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-12-08 03:16:09 -05:00
fix: clear cached store data on logout to prevent user data leakage (#6665)
This commit is contained in:
@@ -52,7 +52,7 @@ export const useStore = function <T extends BoundT>(
|
||||
return await storeActions.refresh(1, -1, params);
|
||||
},
|
||||
flushStore() {
|
||||
store = ref([]);
|
||||
store.value = [];
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,31 @@
|
||||
export { useCategoryStore, usePublicCategoryStore, useCategoryData } from "./use-category-store";
|
||||
export { useFoodStore, usePublicFoodStore, useFoodData } from "./use-food-store";
|
||||
export { useHouseholdStore, usePublicHouseholdStore } from "./use-household-store";
|
||||
export { useLabelStore, useLabelData } from "./use-label-store";
|
||||
export { useTagStore, usePublicTagStore, useTagData } from "./use-tag-store";
|
||||
export { useToolStore, usePublicToolStore, useToolData } from "./use-tool-store";
|
||||
export { useUnitStore, useUnitData } from "./use-unit-store";
|
||||
import { resetCategoryStore } from "./use-category-store";
|
||||
import { resetFoodStore } from "./use-food-store";
|
||||
import { resetHouseholdStore } from "./use-household-store";
|
||||
import { resetLabelStore } from "./use-label-store";
|
||||
import { resetTagStore } from "./use-tag-store";
|
||||
import { resetToolStore } from "./use-tool-store";
|
||||
import { resetUnitStore } from "./use-unit-store";
|
||||
import { resetCookbookStore } from "./use-cookbook-store";
|
||||
import { resetUserStore } from "./use-user-store";
|
||||
|
||||
export { useCategoryStore, usePublicCategoryStore, useCategoryData, resetCategoryStore } from "./use-category-store";
|
||||
export { useFoodStore, usePublicFoodStore, useFoodData, resetFoodStore } from "./use-food-store";
|
||||
export { useHouseholdStore, usePublicHouseholdStore, resetHouseholdStore } from "./use-household-store";
|
||||
export { useLabelStore, useLabelData, resetLabelStore } from "./use-label-store";
|
||||
export { useTagStore, usePublicTagStore, useTagData, resetTagStore } from "./use-tag-store";
|
||||
export { useToolStore, usePublicToolStore, useToolData, resetToolStore } from "./use-tool-store";
|
||||
export { useUnitStore, useUnitData, resetUnitStore } from "./use-unit-store";
|
||||
export { useCookbookStore, usePublicCookbookStore, resetCookbookStore } from "./use-cookbook-store";
|
||||
export { useUserStore, resetUserStore } from "./use-user-store";
|
||||
|
||||
export function clearAllStores() {
|
||||
resetCategoryStore();
|
||||
resetFoodStore();
|
||||
resetHouseholdStore();
|
||||
resetLabelStore();
|
||||
resetTagStore();
|
||||
resetToolStore();
|
||||
resetUnitStore();
|
||||
resetCookbookStore();
|
||||
resetUserStore();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,12 @@ const store: Ref<RecipeCategory[]> = ref([]);
|
||||
const loading = ref(false);
|
||||
const publicLoading = ref(false);
|
||||
|
||||
export function resetCategoryStore() {
|
||||
store.value = [];
|
||||
loading.value = false;
|
||||
publicLoading.value = false;
|
||||
}
|
||||
|
||||
export const useCategoryData = function () {
|
||||
return useData<RecipeCategory>({
|
||||
id: "",
|
||||
|
||||
@@ -7,6 +7,12 @@ const cookbooks: Ref<ReadCookBook[]> = ref([]);
|
||||
const loading = ref(false);
|
||||
const publicLoading = ref(false);
|
||||
|
||||
export function resetCookbookStore() {
|
||||
cookbooks.value = [];
|
||||
loading.value = false;
|
||||
publicLoading.value = false;
|
||||
}
|
||||
|
||||
export const useCookbookStore = function (i18n?: Composer) {
|
||||
const api = useUserApi(i18n);
|
||||
const store = useStore<ReadCookBook>("cookbook", cookbooks, loading, api.cookbooks);
|
||||
|
||||
@@ -7,6 +7,12 @@ const store: Ref<IngredientFood[]> = ref([]);
|
||||
const loading = ref(false);
|
||||
const publicLoading = ref(false);
|
||||
|
||||
export function resetFoodStore() {
|
||||
store.value = [];
|
||||
loading.value = false;
|
||||
publicLoading.value = false;
|
||||
}
|
||||
|
||||
export const useFoodData = function () {
|
||||
return useData<IngredientFood>({
|
||||
id: "",
|
||||
|
||||
@@ -7,6 +7,12 @@ const store: Ref<HouseholdSummary[]> = ref([]);
|
||||
const loading = ref(false);
|
||||
const publicLoading = ref(false);
|
||||
|
||||
export function resetHouseholdStore() {
|
||||
store.value = [];
|
||||
loading.value = false;
|
||||
publicLoading.value = false;
|
||||
}
|
||||
|
||||
export const useHouseholdStore = function (i18n?: Composer) {
|
||||
const api = useUserApi(i18n);
|
||||
return useReadOnlyStore<HouseholdSummary>("household", store, loading, api.households);
|
||||
|
||||
@@ -6,6 +6,11 @@ import { useUserApi } from "~/composables/api";
|
||||
const store: Ref<MultiPurposeLabelOut[]> = ref([]);
|
||||
const loading = ref(false);
|
||||
|
||||
export function resetLabelStore() {
|
||||
store.value = [];
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
export const useLabelData = function () {
|
||||
return useData<MultiPurposeLabelOut>({
|
||||
groupId: "",
|
||||
|
||||
@@ -7,6 +7,12 @@ const store: Ref<RecipeTag[]> = ref([]);
|
||||
const loading = ref(false);
|
||||
const publicLoading = ref(false);
|
||||
|
||||
export function resetTagStore() {
|
||||
store.value = [];
|
||||
loading.value = false;
|
||||
publicLoading.value = false;
|
||||
}
|
||||
|
||||
export const useTagData = function () {
|
||||
return useData<RecipeTag>({
|
||||
id: "",
|
||||
|
||||
@@ -11,6 +11,12 @@ const store: Ref<RecipeTool[]> = ref([]);
|
||||
const loading = ref(false);
|
||||
const publicLoading = ref(false);
|
||||
|
||||
export function resetToolStore() {
|
||||
store.value = [];
|
||||
loading.value = false;
|
||||
publicLoading.value = false;
|
||||
}
|
||||
|
||||
export const useToolData = function () {
|
||||
return useData<RecipeToolWithOnHand>({
|
||||
id: "",
|
||||
|
||||
@@ -6,6 +6,11 @@ import { useUserApi } from "~/composables/api";
|
||||
const store: Ref<IngredientUnit[]> = ref([]);
|
||||
const loading = ref(false);
|
||||
|
||||
export function resetUnitStore() {
|
||||
store.value = [];
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
export const useUnitData = function () {
|
||||
return useData<IngredientUnit>({
|
||||
id: "",
|
||||
|
||||
@@ -7,6 +7,11 @@ import { BaseCRUDAPIReadOnly } from "~/lib/api/base/base-clients";
|
||||
const store: Ref<UserSummary[]> = ref([]);
|
||||
const loading = ref(false);
|
||||
|
||||
export function resetUserStore() {
|
||||
store.value = [];
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
class GroupUserAPIReadOnly extends BaseCRUDAPIReadOnly<UserSummary> {
|
||||
baseRoute = "/api/groups/members";
|
||||
itemRoute = (idOrUsername: string | number) => `/groups/members/${idOrUsername}`;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ref, computed } from "vue";
|
||||
import type { UserOut } from "~/lib/api/types/user";
|
||||
import { clearAllStores } from "~/composables/store";
|
||||
|
||||
interface AuthData {
|
||||
value: UserOut | null;
|
||||
@@ -101,6 +102,13 @@ export const useAuthBackend = function (): AuthState {
|
||||
setToken(null);
|
||||
authUser.value = null;
|
||||
authStatus.value = "unauthenticated";
|
||||
|
||||
// Clear all cached store data to prevent data leakage between users
|
||||
clearAllStores();
|
||||
|
||||
// Clear Nuxt's useAsyncData cache
|
||||
clearNuxtData();
|
||||
|
||||
await router.push(callbackUrl || "/login");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user