diff --git a/src/auth/passport.ts b/src/auth/passport.ts index 7a34f6748..85ca2e5d4 100644 --- a/src/auth/passport.ts +++ b/src/auth/passport.ts @@ -8,6 +8,7 @@ import prisma from "@mirlo/prisma"; import { findArtistIdForURLSlug } from "../utils/artist"; import logger from "../logger"; import { AppError } from "../utils/error"; +import { doesTrackGroupBelongToUser } from "../utils/ownership"; const JWTStrategy = passportJWT.Strategy; @@ -165,21 +166,7 @@ export const trackGroupBelongsToLoggedInUser = async ( httpCode: 401, }); } else { - const trackGroup = await prisma.trackGroup.findFirst({ - where: { - artist: { - userId: loggedInUser.id, - }, - id: Number(trackGroupId), - }, - }); - - if (!trackGroup) { - throw new AppError({ - description: "TrackGroup does not exist or does not belong to user", - httpCode: 404, - }); - } + await doesTrackGroupBelongToUser(Number(trackGroupId), loggedInUser); } } catch (e) { return next(e); @@ -205,6 +192,9 @@ export const trackBelongsToLoggedInUser = async ( httpCode: 401, }); } else { + if (loggedInUser.isAdmin) { + return next(); + } const track = await prisma.track.findFirst({ where: { trackGroup: { diff --git a/src/routers/v1/manage/trackGroups/{trackGroupId}/codes.ts b/src/routers/v1/manage/trackGroups/{trackGroupId}/codes.ts index ed2b93523..7139ea1e7 100644 --- a/src/routers/v1/manage/trackGroups/{trackGroupId}/codes.ts +++ b/src/routers/v1/manage/trackGroups/{trackGroupId}/codes.ts @@ -27,7 +27,7 @@ export default function () { try { const trackGroup = await doesTrackGroupBelongToUser( Number(trackGroupId), - loggedInUser.id + loggedInUser ); if (trackGroupId) { diff --git a/src/routers/v1/manage/trackGroups/{trackGroupId}/cover.ts b/src/routers/v1/manage/trackGroups/{trackGroupId}/cover.ts index 19680453d..d9d7c2ded 100644 --- a/src/routers/v1/manage/trackGroups/{trackGroupId}/cover.ts +++ b/src/routers/v1/manage/trackGroups/{trackGroupId}/cover.ts @@ -34,7 +34,7 @@ export default function () { const { trackGroupId } = req.params as unknown as Params; const loggedInUser = req.user as User; try { - await doesTrackGroupBelongToUser(Number(trackGroupId), loggedInUser.id); + await doesTrackGroupBelongToUser(Number(trackGroupId), loggedInUser); const jobId = await processTrackGroupCover({ req, res })( Number(trackGroupId) @@ -85,7 +85,7 @@ export default function () { try { const trackgroup = await doesTrackGroupBelongToUser( Number(trackGroupId), - loggedInUser.id + loggedInUser ); await deleteTrackGroupCover(trackgroup.id); diff --git a/src/routers/v1/manage/trackGroups/{trackGroupId}/index.ts b/src/routers/v1/manage/trackGroups/{trackGroupId}/index.ts index 1c8c76bc2..a0373dc2b 100644 --- a/src/routers/v1/manage/trackGroups/{trackGroupId}/index.ts +++ b/src/routers/v1/manage/trackGroups/{trackGroupId}/index.ts @@ -39,7 +39,7 @@ const findNewSlug = async ( export default function () { const operations = { - PUT: [userAuthenticated, contentBelongsToLoggedInUserArtist, PUT], + PUT: [userAuthenticated, trackGroupBelongsToLoggedInUser, PUT], DELETE: [userAuthenticated, trackGroupBelongsToLoggedInUser, DELETE], GET: [userAuthenticated, trackGroupBelongsToLoggedInUser, GET], }; @@ -75,15 +75,14 @@ export default function () { async function PUT(req: Request, res: Response, next: NextFunction) { const { trackGroupId } = req.params as unknown as Params; const data = req.body; - const loggedInUser = req.user as User; try { const artist = (await prisma.artist.findFirst({ where: { - userId: loggedInUser.id, id: Number(data.artistId), }, })) as Artist; // By now we know that the artist exists + // and the user can edit it const newValues = pick(data, [ "title", @@ -95,6 +94,8 @@ export default function () { "credits", ]); + console.log(newValues); + await prisma.trackGroup.updateMany({ where: { id: Number(trackGroupId), artistId: artist.id }, data: newValues, diff --git a/src/routers/v1/manage/trackGroups/{trackGroupId}/publish.ts b/src/routers/v1/manage/trackGroups/{trackGroupId}/publish.ts index 5a00026aa..4c3dc6167 100644 --- a/src/routers/v1/manage/trackGroups/{trackGroupId}/publish.ts +++ b/src/routers/v1/manage/trackGroups/{trackGroupId}/publish.ts @@ -16,7 +16,7 @@ export default function () { try { const trackGroup = await doesTrackGroupBelongToUser( Number(trackGroupId), - Number(loggedInUser.id) + loggedInUser ); const updatedTrackgroup = await prisma.trackGroup.update({ where: { id: Number(trackGroupId) || undefined }, diff --git a/src/routers/v1/manage/trackGroups/{trackGroupId}/tags.ts b/src/routers/v1/manage/trackGroups/{trackGroupId}/tags.ts index 04b384e63..4df7d62b8 100644 --- a/src/routers/v1/manage/trackGroups/{trackGroupId}/tags.ts +++ b/src/routers/v1/manage/trackGroups/{trackGroupId}/tags.ts @@ -25,7 +25,7 @@ export default function () { try { const trackgroup = await doesTrackGroupBelongToUser( Number(trackGroupId), - loggedInUser.id + loggedInUser ); await prisma.trackGroupTag.deleteMany({ diff --git a/src/routers/v1/manage/trackGroups/{trackGroupId}/trackOrder.ts b/src/routers/v1/manage/trackGroups/{trackGroupId}/trackOrder.ts index 91006432c..bcd8f0529 100644 --- a/src/routers/v1/manage/trackGroups/{trackGroupId}/trackOrder.ts +++ b/src/routers/v1/manage/trackGroups/{trackGroupId}/trackOrder.ts @@ -24,7 +24,7 @@ export default function () { try { const trackGroup = await doesTrackGroupBelongToUser( Number(trackGroupId), - loggedInUser.id + loggedInUser ); await Promise.all( diff --git a/src/routers/v1/manage/tracks/index.ts b/src/routers/v1/manage/tracks/index.ts index 93a231208..66b85f03e 100644 --- a/src/routers/v1/manage/tracks/index.ts +++ b/src/routers/v1/manage/tracks/index.ts @@ -54,10 +54,7 @@ export default function () { const { title, trackGroupId, trackArtists, order, metadata, isPreview } = req.body; try { - await doesTrackGroupBelongToUser( - Number(trackGroupId), - Number(loggedInUser.id) - ); + await doesTrackGroupBelongToUser(Number(trackGroupId), loggedInUser); const createdTrack = await prisma.track.create({ data: { diff --git a/src/routers/v1/manage/tracks/{trackId}/audio.ts b/src/routers/v1/manage/tracks/{trackId}/audio.ts index 00c9a3ad8..0aea464e9 100644 --- a/src/routers/v1/manage/tracks/{trackId}/audio.ts +++ b/src/routers/v1/manage/tracks/{trackId}/audio.ts @@ -33,7 +33,7 @@ export default function () { const { trackId } = req.params as unknown as Params; const loggedInUser = req.user as User; try { - const track = doesTrackBelongToUser(Number(trackId), loggedInUser.id); + const track = doesTrackBelongToUser(Number(trackId), loggedInUser); if (!track) { res.status(400).json({ diff --git a/src/routers/v1/manage/tracks/{trackId}/index.ts b/src/routers/v1/manage/tracks/{trackId}/index.ts index 9ab860551..815887dc4 100644 --- a/src/routers/v1/manage/tracks/{trackId}/index.ts +++ b/src/routers/v1/manage/tracks/{trackId}/index.ts @@ -28,25 +28,11 @@ export default function () { GET: [userAuthenticated, trackBelongsToLoggedInUser, GET], }; - // FIXME: only allow updating of tracks owned by userId async function PUT(req: Request, res: Response, next: NextFunction) { const { trackId } = req.params; const { title, isPreview, trackArtists } = req.body as TrackBody; - const loggedInUser = req.user as User; try { - const track = await doesTrackBelongToUser( - Number(trackId), - Number(loggedInUser.id) - ); - - if (!track) { - res.status(400).json({ - error: "Track must belong to user", - }); - return next(); - } - await updateTrackArtists(Number(trackId), trackArtists); const newTrack = await prisma.track.update({ @@ -106,7 +92,7 @@ export default function () { const loggedInUser = req.user as User; const trackId = Number(trackIdString); - const track = await doesTrackBelongToUser(trackId, Number(loggedInUser.id)); + const track = await doesTrackBelongToUser(trackId, loggedInUser); if (!track) { res.status(400).json({ error: "Track must belong to user", diff --git a/src/routers/v1/manage/tracks/{trackId}/trackArtists.ts b/src/routers/v1/manage/tracks/{trackId}/trackArtists.ts index b46d90419..51b3d496e 100644 --- a/src/routers/v1/manage/tracks/{trackId}/trackArtists.ts +++ b/src/routers/v1/manage/tracks/{trackId}/trackArtists.ts @@ -3,9 +3,7 @@ import { trackBelongsToLoggedInUser, userAuthenticated, } from "../../../../../auth/passport"; -import { doesTrackBelongToUser } from "../../../../../utils/ownership"; import { updateTrackArtists } from "../../../../../utils/tracks"; -import { User } from "@mirlo/prisma/client"; interface TrackBody { title: string; @@ -28,22 +26,9 @@ export default function () { const { trackId } = req.params as { trackId: string; }; - const loggedInUser = req.user as User; const { trackArtists } = req.body as TrackBody; try { - const track = await doesTrackBelongToUser( - Number(trackId), - Number(loggedInUser.id) - ); - - if (!track) { - res.status(400).json({ - error: "Track must belong to user", - }); - return next(); - } - const newTrackArtists = await updateTrackArtists( Number(trackId), trackArtists diff --git a/src/routers/v1/trackGroups/{id}/download.ts b/src/routers/v1/trackGroups/{id}/download.ts index e394a12d7..1ecae03f1 100644 --- a/src/routers/v1/trackGroups/{id}/download.ts +++ b/src/routers/v1/trackGroups/{id}/download.ts @@ -34,12 +34,12 @@ export default function () { let trackGroup; if (req.user) { - const { id: userId, isAdmin } = req.user as User; + const user = req.user as User; - if (!isAdmin) { + if (!user.isAdmin) { const purchase = await findPurchaseAndVoidToken( Number(trackGroupId), - userId + user ); trackGroup = purchase.trackGroup; diff --git a/src/routers/v1/trackGroups/{id}/generateDownload.ts b/src/routers/v1/trackGroups/{id}/generateDownload.ts index 22f7006c9..7313612c7 100644 --- a/src/routers/v1/trackGroups/{id}/generateDownload.ts +++ b/src/routers/v1/trackGroups/{id}/generateDownload.ts @@ -33,12 +33,12 @@ export default function () { let trackGroup; if (req.user) { - const { id: userId, isAdmin } = req.user as User; + const user = req.user as User; - if (!isAdmin) { + if (!user.isAdmin) { const purchase = await findPurchaseAndVoidToken( Number(trackGroupId), - userId + user ); trackGroup = purchase.trackGroup; diff --git a/src/routers/v1/tracks/{id}/stream/{segment}.ts b/src/routers/v1/tracks/{id}/stream/{segment}.ts index b08a6f091..a7848b4d6 100644 --- a/src/routers/v1/tracks/{id}/stream/{segment}.ts +++ b/src/routers/v1/tracks/{id}/stream/{segment}.ts @@ -66,7 +66,7 @@ export default function () { const isUserAbleToListenToTrack = await canUserListenToTrack( track?.id, - user?.id + user ); if (!track || !isUserAbleToListenToTrack) { diff --git a/src/utils/ownership.ts b/src/utils/ownership.ts index 61109909c..c4034b99c 100644 --- a/src/utils/ownership.ts +++ b/src/utils/ownership.ts @@ -1,4 +1,9 @@ -import { ArtistSubscriptionTier, Prisma } from "@mirlo/prisma/client"; +import { + ArtistSubscriptionTier, + Prisma, + TrackGroup, + User, +} from "@mirlo/prisma/client"; import prisma from "@mirlo/prisma"; import { AppError } from "./error"; @@ -27,36 +32,39 @@ export const doesSubscriptionTierBelongToUser = async ( export const doesTrackGroupBelongToUser = async ( trackGroupId: number, - userId: number + user: User ) => { - const artists = await prisma.artist.findMany({ - where: { - userId: Number(userId), - }, - }); - - const trackgroup = await prisma.trackGroup.findFirst({ - where: { - artistId: { in: artists.map((a) => a.id) }, - id: Number(trackGroupId), - }, - include: trackGroupSingleInclude({ loggedInUserId: userId }), - }); + let trackGroup; + if (user.isAdmin) { + trackGroup = await prisma.trackGroup.findFirst({ + where: { + id: Number(trackGroupId), + }, + include: trackGroupSingleInclude({ loggedInUserId: user.id }), + }); + } else { + trackGroup = await prisma.trackGroup.findFirst({ + where: { + artist: { + userId: user.id, + }, + id: Number(trackGroupId), + }, + include: trackGroupSingleInclude({ loggedInUserId: user.id }), + }); + } - if (!trackgroup) { + if (!trackGroup) { throw new AppError({ description: "TrackGroup does not exist or does not belong to user", httpCode: 404, name: "TrackGroup does not exist or does not belong to user", }); } - return trackgroup; + return trackGroup; }; -export const doesTrackBelongToUser = async ( - trackId: number, - userId: number -) => { +export const doesTrackBelongToUser = async (trackId: number, user: User) => { try { const track = await prisma.track.findUnique({ where: { @@ -67,7 +75,7 @@ export const doesTrackBelongToUser = async ( if (track) { const trackGroup = await doesTrackGroupBelongToUser( track?.trackGroupId, - userId + user ); if (trackGroup) { return track; @@ -80,10 +88,7 @@ export const doesTrackBelongToUser = async ( } }; -export const canUserListenToTrack = async ( - trackId?: number, - userId?: number -) => { +export const canUserListenToTrack = async (trackId?: number, user?: User) => { if (!trackId) { return false; } @@ -98,8 +103,8 @@ export const canUserListenToTrack = async ( return true; } - if (track && userId) { - const trackGroup = await doesTrackBelongToUser(track.trackGroupId, userId); + if (track && user) { + const trackGroup = await doesTrackBelongToUser(track.trackGroupId, user); if (trackGroup) { return true; } @@ -107,7 +112,7 @@ export const canUserListenToTrack = async ( const purchase = await prisma.userTrackGroupPurchase.findFirst({ where: { trackGroupId: track.trackGroupId, - userId: userId, + userId: user.id, }, }); diff --git a/src/utils/trackGroup.ts b/src/utils/trackGroup.ts index 95f4d5f97..b4e12d2ef 100644 --- a/src/utils/trackGroup.ts +++ b/src/utils/trackGroup.ts @@ -5,6 +5,7 @@ import { TrackGroupCover, Prisma, TrackGroupTag, + User, } from "@mirlo/prisma/client"; import prisma from "@mirlo/prisma"; import { generateFullStaticImageUrl } from "./images"; @@ -349,11 +350,11 @@ export const basicTrackGroupInclude = { export const findPurchaseAndVoidToken = async ( trackGroupId: number, - userId: number + user: User ) => { let isCreator; try { - isCreator = await doesTrackGroupBelongToUser(Number(trackGroupId), userId); + isCreator = await doesTrackGroupBelongToUser(Number(trackGroupId), user); } catch (e) {} logger.info(`trackGroupId: ${trackGroupId} isCreator: ${isCreator}`); @@ -362,7 +363,7 @@ export const findPurchaseAndVoidToken = async ( trackGroupId: Number(trackGroupId), ...(!isCreator ? { - userId: Number(userId), + userId: Number(user.id), trackGroup: { published: true, },