mirror of
https://github.com/yusufipk/OpenFrame.git
synced 2026-09-11 09:36:08 +00:00
feat(auth): enhance project access handling with pre-fetched data and new utility functions
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { db } from '@/lib/db';
|
||||
import { auth, checkProjectAccess } from '@/lib/auth';
|
||||
import { auth, computeProjectAccess, projectAccessInclude } from '@/lib/auth';
|
||||
import { rateLimit } from '@/lib/rate-limit';
|
||||
import { notifyProjectOwner } from '@/lib/notifications';
|
||||
import { apiErrors, successResponse, withCacheControl } from '@/lib/api-response';
|
||||
@@ -46,14 +46,15 @@ export async function GET(request: NextRequest, { params }: RouteParams) {
|
||||
try {
|
||||
const session = await auth();
|
||||
const { versionId } = await params;
|
||||
const userId = session?.user?.id;
|
||||
|
||||
// Get version with project access info
|
||||
// Get version with project access data pre-fetched in the same query
|
||||
const version = await db.videoVersion.findUnique({
|
||||
where: { id: versionId },
|
||||
include: {
|
||||
video: {
|
||||
include: {
|
||||
project: true,
|
||||
project: { include: projectAccessInclude(userId) },
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -64,7 +65,7 @@ export async function GET(request: NextRequest, { params }: RouteParams) {
|
||||
}
|
||||
|
||||
const project = version.video.project;
|
||||
const access = await checkProjectAccess(project, session?.user?.id);
|
||||
const access = computeProjectAccess(project, userId);
|
||||
const shareSession = getShareSessionFromRequest(request, version.video.id);
|
||||
|
||||
const shareAccess = shareSession
|
||||
@@ -191,6 +192,7 @@ export async function POST(request: NextRequest, { params }: RouteParams) {
|
||||
|
||||
const session = await auth();
|
||||
const { versionId } = await params;
|
||||
const userId = session?.user?.id;
|
||||
|
||||
const version = await db.videoVersion.findUnique({
|
||||
where: { id: versionId },
|
||||
@@ -199,11 +201,9 @@ export async function POST(request: NextRequest, { params }: RouteParams) {
|
||||
include: {
|
||||
project: {
|
||||
include: {
|
||||
workspace: {
|
||||
select: {
|
||||
ownerId: true,
|
||||
},
|
||||
},
|
||||
...projectAccessInclude(userId),
|
||||
// workspace.select is already included by projectAccessInclude;
|
||||
// ownerId is present on workspace via projectAccessInclude
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -216,7 +216,7 @@ export async function POST(request: NextRequest, { params }: RouteParams) {
|
||||
}
|
||||
|
||||
const project = version.video.project;
|
||||
const access = await checkProjectAccess(project, session?.user?.id);
|
||||
const access = computeProjectAccess(project, userId);
|
||||
const shareSession = getShareSessionFromRequest(request, version.video.id);
|
||||
|
||||
const shareAccess = shareSession
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NextRequest } from 'next/server';
|
||||
import { db } from '@/lib/db';
|
||||
import { auth, checkProjectAccess } from '@/lib/auth';
|
||||
import { auth, computeProjectAccess, projectAccessInclude } from '@/lib/auth';
|
||||
import { apiErrors, successResponse } from '@/lib/api-response';
|
||||
import { rateLimit } from '@/lib/rate-limit';
|
||||
|
||||
@@ -17,11 +17,12 @@ export async function GET(request: NextRequest, { params }: RouteParams) {
|
||||
|
||||
const { videoId } = await params;
|
||||
|
||||
// Get the video and its active version
|
||||
// Get the video and its active version (project access data pre-fetched in same query)
|
||||
const userId = session.user.id;
|
||||
const video = await db.video.findUnique({
|
||||
where: { id: videoId },
|
||||
include: {
|
||||
project: true,
|
||||
project: { include: projectAccessInclude(userId) },
|
||||
versions: {
|
||||
where: { isActive: true },
|
||||
take: 1,
|
||||
@@ -33,8 +34,7 @@ export async function GET(request: NextRequest, { params }: RouteParams) {
|
||||
return apiErrors.notFound('Video');
|
||||
}
|
||||
|
||||
// Check access including workspace membership
|
||||
const access = await checkProjectAccess(video.project, session?.user?.id);
|
||||
const access = computeProjectAccess(video.project, userId);
|
||||
|
||||
if (!access.hasAccess) {
|
||||
return apiErrors.forbidden('Access denied');
|
||||
@@ -94,10 +94,12 @@ export async function POST(request: NextRequest, { params }: RouteParams) {
|
||||
|
||||
// Always load the requested video and validate access before writing progress.
|
||||
// If versionId is provided, verify it belongs to this video; otherwise resolve active version.
|
||||
// Project access data is pre-fetched in the same query — no extra round-trips.
|
||||
const userId = session.user.id;
|
||||
const video = await db.video.findUnique({
|
||||
where: { id: videoId },
|
||||
include: {
|
||||
project: true,
|
||||
project: { include: projectAccessInclude(userId) },
|
||||
versions: {
|
||||
where: versionId ? { id: versionId } : { isActive: true },
|
||||
take: 1,
|
||||
@@ -109,7 +111,7 @@ export async function POST(request: NextRequest, { params }: RouteParams) {
|
||||
return apiErrors.notFound('Video');
|
||||
}
|
||||
|
||||
const access = await checkProjectAccess(video.project, session?.user?.id);
|
||||
const access = computeProjectAccess(video.project, userId);
|
||||
if (!access.hasAccess) {
|
||||
return apiErrors.forbidden('Access denied');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user