fix: Security Issues (#3530)

Co-authored-by: boc-the-git <3479092+boc-the-git@users.noreply.github.com>
This commit is contained in:
Michael Genson 2024-04-30 15:53:55 -05:00 committed by GitHub
parent 2ff37c86d6
commit ec458a0a08
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 11 additions and 36 deletions

View File

@ -1,10 +1,9 @@
import { BaseCRUDAPI } from "../base/base-clients";
import { QueryValue, route } from "~/lib/api/base/route";
import { PaginationData, RequestResponse } from "~/lib/api/types/non-generated";
import { PaginationData } from "~/lib/api/types/non-generated";
import {
ChangePassword,
DeleteTokenResponse,
GroupInDB,
LongLiveTokenIn,
LongLiveTokenOut,
ResetPassword,
@ -30,7 +29,6 @@ const routes = {
groupUsers: `${prefix}/users/group-users`,
usersSelf: `${prefix}/users/self`,
ratingsSelf: `${prefix}/users/self/ratings`,
groupsSelf: `${prefix}/users/self/group`,
passwordReset: `${prefix}/users/reset-password`,
passwordChange: `${prefix}/users/password`,
users: `${prefix}/users`,
@ -57,10 +55,6 @@ export class UserApi extends BaseCRUDAPI<UserIn, UserOut, UserBase> {
return await this.requests.get<PaginationData<UserSummary>>(route(routes.groupUsers, { page, perPage, ...params }));
}
async getSelfGroup(): Promise<RequestResponse<GroupInDB>> {
return await this.requests.get(routes.groupsSelf, {});
}
async addFavorite(id: string, slug: string) {
return await this.requests.post(routes.usersIdFavoritesSlug(id, slug), {});
}

View File

@ -156,6 +156,7 @@ export default {
propertyName: "access_token",
},
refresh: { url: "api/auth/refresh", method: "post" },
logout: { url: "api/auth/logout", method: "post" },
user: { url: "api/users/self", method: "get" },
},
},

View File

@ -190,7 +190,6 @@
<script lang="ts">
import { computed, defineComponent, useContext, ref, toRefs, reactive, useAsync, useRoute } from "@nuxtjs/composition-api";
import { invoke, until } from "@vueuse/core";
import UserProfileLinkCard from "@/components/Domain/User/UserProfileLinkCard.vue";
import { useUserApi } from "~/composables/api";
import { validators } from "~/composables/use-validators";
@ -198,7 +197,7 @@ import { alert } from "~/composables/use-toast";
import UserAvatar from "@/components/Domain/User/UserAvatar.vue";
import { useAsyncKey } from "~/composables/use-utils";
import StatsCards from "~/components/global/StatsCards.vue";
import { GroupInDB, UserOut } from "~/lib/api/types/user";
import { UserOut } from "~/lib/api/types/user";
export default defineComponent({
name: "UserProfile",
@ -216,7 +215,6 @@ export default defineComponent({
// @ts-ignore $auth.user is typed as unknown, but it's a user
const user = computed<UserOut | null>(() => $auth.user);
const group = ref<GroupInDB | null>(null);
const showPublicLink = ref(false);
const publicLink = ref("");
@ -225,16 +223,6 @@ export default defineComponent({
const token = ref("");
const api = useUserApi();
invoke(async () => {
await until(user.value).not.toBeNull();
if (!user.value) {
return;
}
const { data } = await api.users.getSelfGroup();
group.value = data;
});
async function getSignupLink() {
const { data } = await api.groups.createInvitation({ uses: 1 });
if (data) {
@ -333,7 +321,6 @@ export default defineComponent({
getStatsTitle,
getStatsIcon,
getStatsTo,
group,
stats,
user,
constructLink,

View File

@ -72,3 +72,9 @@ async def refresh_token(current_user: PrivateUser = Depends(get_current_user)):
"""Use a valid token to get another token"""
access_token = security.create_access_token(data=dict(sub=str(current_user.id)))
return MealieAuthToken.respond(access_token)
@user_router.post("/logout")
async def logout(response: Response):
response.delete_cookie("mealie.access_token")
return {"message": "Logged out"}

View File

@ -11,14 +11,7 @@ from mealie.routes.users._helpers import assert_user_change_allowed
from mealie.schema.response import ErrorResponse, SuccessResponse
from mealie.schema.response.pagination import PaginationQuery
from mealie.schema.user import ChangePassword, UserBase, UserIn, UserOut
from mealie.schema.user.user import (
GroupInDB,
UserPagination,
UserRatings,
UserRatingSummary,
UserSummary,
UserSummaryPagination,
)
from mealie.schema.user.user import UserPagination, UserRatings, UserRatingSummary, UserSummary, UserSummaryPagination
user_router = UserAPIRouter(prefix="/users", tags=["Users: CRUD"])
admin_router = AdminAPIRouter(prefix="/users", tags=["Users: Admin CRUD"])
@ -100,10 +93,6 @@ class UserController(BaseUserController):
def get_logged_in_user_favorites(self):
return UserRatings(ratings=self.repos.user_ratings.get_by_user(self.user.id, favorites_only=True))
@user_router.get("/self/group", response_model=GroupInDB)
def get_logged_in_user_group(self):
return self.group
@user_router.put("/password")
def update_password(self, password_change: ChangePassword):
"""Resets the User Password"""

View File

@ -206,7 +206,7 @@ class UpdateGroup(GroupBase):
class GroupInDB(UpdateGroup):
users: list[UserOut] | None = None
users: list[UserSummary] | None = None
preferences: ReadGroupPreferences | None = None
webhooks: list[ReadWebhook] = []

View File

@ -183,8 +183,6 @@ users_self = "/api/users/self"
"""`/api/users/self`"""
users_self_favorites = "/api/users/self/favorites"
"""`/api/users/self/favorites`"""
users_self_group = "/api/users/self/group"
"""`/api/users/self/group`"""
users_self_ratings = "/api/users/self/ratings"
"""`/api/users/self/ratings`"""
utils_download = "/api/utils/download"