diff options
| -rw-r--r-- | src/graphql/user/resolvers.ts | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/src/graphql/user/resolvers.ts b/src/graphql/user/resolvers.ts index 285c98f0..9773d8b0 100644 --- a/src/graphql/user/resolvers.ts +++ b/src/graphql/user/resolvers.ts @@ -98,6 +98,26 @@ const authenticatedPreferencesOperation = async ( }; }; +const ensureOwnerOrPrivileged = ( + identity: UserIdentity, + authorised: boolean, + targetUserId: number +) => { + if (!authorised && identity.id !== targetUserId) throw new Error('Unauthorized'); +}; + +const ensureBadgeOwnerOrPrivileged = async ( + identity: UserIdentity, + authorised: boolean, + badgeId: number +) => { + if (authorised) return; + + const ownsBadge = (await getUserBadges(identity.id)).some((badge) => badge.id === badgeId); + + if (!ownsBadge) throw new Error('Unauthorized'); +}; + export const resolvers: WithIndex<Resolvers> = { Query: { User: async (_, args) => { @@ -123,15 +143,16 @@ export const resolvers: WithIndex<Resolvers> = { }, Mutation: { shadowHideBadges: async (_, args, context) => - await authenticatedBadgesOperation( - context, - async (_, authorised) => await setShadowHidden(args.userId, authorised) - ), + await authenticatedBadgesOperation(context, async (identity, authorised) => { + ensureOwnerOrPrivileged(identity, authorised, args.userId); + + await setShadowHidden(args.userId, authorised); + }), shadowHideBadge: async (_, args, context) => - await authenticatedBadgesOperation( - context, - async () => await setShadowHiddenBadge(args.id, args.state == null ? true : args.state) - ), + await authenticatedBadgesOperation(context, async (identity, authorised) => { + await ensureBadgeOwnerOrPrivileged(identity, authorised, args.id); + await setShadowHiddenBadge(args.id, args.state == null ? true : args.state); + }), hideBadge: async (_, args, context) => await authenticatedBadgesOperation(context, async (identity) => { const allBadges = await getUserBadges(identity.id); |