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