Skip to content
10 changes: 5 additions & 5 deletions apps/processor/src/api/avatar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Router, Request, Response } from 'express';
import multer from 'multer';
import { promises as fs } from 'fs';
import path from 'path';
import { hasServiceScope } from '../middleware/auth';
import { hasAuthScope } from '../middleware/auth';
import { processorLogger } from '../logger';
import {
DEFAULT_IMAGE_EXTENSION,
Expand Down Expand Up @@ -42,7 +42,7 @@ if (!AVATAR_ROOT) {
// Avatar upload endpoint
router.post('/upload', upload.single('file'), async (req: Request, res: Response) => {
try {
const auth = req.serviceAuth;
const auth = req.auth;
if (!auth) {
return res.status(401).json({ error: 'Service authentication required' });
}
Expand All @@ -64,7 +64,7 @@ router.post('/upload', upload.single('file'), async (req: Request, res: Response
if (
auth.userId &&
userId !== auth.userId &&
!hasServiceScope(auth, 'avatars:write:any')
!hasAuthScope(auth, 'avatars:write:any')
) {
return res.status(403).json({ error: 'Cannot modify avatar for another user' });
}
Expand Down Expand Up @@ -127,7 +127,7 @@ router.post('/upload', upload.single('file'), async (req: Request, res: Response
// Avatar deletion endpoint
router.delete('/:userId', async (req: Request, res: Response) => {
try {
const auth = req.serviceAuth;
const auth = req.auth;
if (!auth) {
return res.status(401).json({ error: 'Service authentication required' });
}
Expand All @@ -144,7 +144,7 @@ router.delete('/:userId', async (req: Request, res: Response) => {
if (
auth.userId &&
userId !== auth.userId &&
!hasServiceScope(auth, 'avatars:write:any')
!hasAuthScope(auth, 'avatars:write:any')
) {
return res.status(403).json({ error: 'Cannot delete avatar for another user' });
}
Expand Down
4 changes: 2 additions & 2 deletions apps/processor/src/api/ingest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ const router = Router();
// Enqueue ingestion job by pageId
router.post('/by-page/:pageId', async (req, res) => {
try {
if (!req.serviceAuth) {
if (!req.auth) {
return res.status(401).json({ error: 'Service authentication required' });
}

const userId = req.serviceAuth.userId;
const userId = req.auth.userId;
if (!userId) {
return res.status(401).json({ error: 'Service authentication required' });
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Expand Down
6 changes: 3 additions & 3 deletions apps/processor/src/api/optimize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const router = Router();
// Optimize image endpoint - synchronous if cached, async if not
router.post('/', async (req, res) => {
try {
const auth = req.serviceAuth;
const auth = req.auth;
if (!auth) {
return res.status(401).json({ error: 'Service authentication required' });
}
Expand Down Expand Up @@ -107,7 +107,7 @@ router.post('/', async (req, res) => {
// Batch optimize endpoint for multiple presets
router.post('/batch', async (req, res) => {
try {
const auth = req.serviceAuth;
const auth = req.auth;
if (!auth) {
return res.status(401).json({ error: 'Service authentication required' });
}
Expand Down Expand Up @@ -190,7 +190,7 @@ router.post('/batch', async (req, res) => {
// Prepare image for AI endpoint
router.post('/prepare-for-ai', async (req, res) => {
try {
const auth = req.serviceAuth;
const auth = req.auth;
if (!auth) {
return res.status(401).json({ error: 'Service authentication required' });
}
Expand Down
6 changes: 3 additions & 3 deletions apps/processor/src/api/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const router = Router();
router.get('/:contentHash/original', async (req, res) => {
try {
const { contentHash } = req.params;
const auth = req.serviceAuth;
const auth = req.auth;

if (!auth) {
return res.status(401).json({ error: 'Service authentication required' });
Expand Down Expand Up @@ -127,7 +127,7 @@ router.get('/:contentHash/original', async (req, res) => {
router.get('/:contentHash/:preset', async (req, res) => {
try {
const { contentHash, preset } = req.params;
const auth = req.serviceAuth;
const auth = req.auth;

if (!auth) {
return res.status(401).json({ error: 'Service authentication required' });
Expand Down Expand Up @@ -203,7 +203,7 @@ router.get('/:contentHash/:preset', async (req, res) => {
router.get('/:contentHash/metadata', async (req, res) => {
try {
const { contentHash } = req.params;
const auth = req.serviceAuth;
const auth = req.auth;

if (!auth) {
return res.status(401).json({ error: 'Service authentication required' });
Expand Down
56 changes: 28 additions & 28 deletions apps/processor/src/api/upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import path from 'path';
import { contentStore, queueManager } from '../server';
import { processorLogger } from '../logger';
import { rateLimitUpload } from '../middleware/rate-limit';
import { hasServiceScope } from '../middleware/auth';
import { hasAuthScope } from '../middleware/auth';
import { resolvePathWithin, sanitizeExtension } from '../utils/security';

const router = Router();
Expand Down Expand Up @@ -83,8 +83,8 @@ const upload = multer({
});

router.use((req, res, next) => {
if (!req.serviceAuth) {
return res.status(401).json({ error: 'Service authentication required' });
if (!req.auth) {
return res.status(401).json({ error: 'Authentication required' });
}
return next();
});
Expand All @@ -96,14 +96,15 @@ router.post('/single', upload.single('file'), async (req, res) => {
let tempFilePath: string | undefined;

try {
const auth = req.serviceAuth;
const auth = req.auth;
if (!auth) {
return res.status(401).json({ error: 'Service authentication required' });
return res.status(401).json({ error: 'Authentication required' });
}

const resourcePageId = auth.claims.resource;
// Get resource binding (pageId) from session
const resourcePageId = auth.resourceBinding?.type === 'page' ? auth.resourceBinding.id : undefined;
if (!resourcePageId) {
return res.status(403).json({ error: 'Service token missing page scope' });
return res.status(403).json({ error: 'Token missing page resource binding' });
}

const driveId = typeof req.body?.driveId === 'string' ? req.body.driveId : undefined;
Expand All @@ -112,7 +113,7 @@ router.post('/single', upload.single('file'), async (req, res) => {
}

if (!auth.driveId || auth.driveId !== driveId) {
return res.status(403).json({ error: 'Service token drive does not match requested drive' });
return res.status(403).json({ error: 'Token drive does not match requested drive' });
}

const pageId = typeof req.body?.pageId === 'string' ? req.body.pageId : undefined;
Expand All @@ -121,21 +122,20 @@ router.post('/single', upload.single('file'), async (req, res) => {
}

if (resourcePageId && resourcePageId !== pageId) {
return res.status(403).json({ error: 'Service token resource does not match requested page' });
return res.status(403).json({ error: 'Token resource does not match requested page' });
}

const providedUserId = typeof req.body?.userId === 'string' ? req.body.userId : undefined;
if (
auth.userId &&
providedUserId &&
providedUserId !== auth.userId &&
!hasServiceScope(auth, 'files:write:any')
!hasAuthScope(auth, 'files:write:any')
) {
return res.status(403).json({ error: 'Cannot upload on behalf of another user' });
}

const uploaderId = auth.userId ?? providedUserId;
const tenantId = auth.tenantId;

if (!req.file) {
return res.status(400).json({ error: 'No file provided' });
Expand All @@ -157,10 +157,10 @@ router.post('/single', upload.single('file'), async (req, res) => {
const alreadyStored = await contentStore.originalExists(contentHash);
if (alreadyStored) {
await contentStore.appendUploadMetadata(contentHash, {
tenantId,
tenantId: auth.userId,
driveId,
userId: uploaderId,
service: auth.service
service: 'processor'
});

processorLogger.info('Upload deduplicated', {
Expand Down Expand Up @@ -194,10 +194,10 @@ router.post('/single', upload.single('file'), async (req, res) => {
originalname,
contentHash,
{
tenantId,
tenantId: auth.userId,
driveId,
userId: uploaderId,
service: auth.service
service: 'processor'
}
);
processorLogger.info('Saved original upload', {
Expand Down Expand Up @@ -233,7 +233,7 @@ router.post('/single', upload.single('file'), async (req, res) => {
processorLogger.error('Upload error', error as Error, {
tempFilePath,
pageId: req.body?.pageId,
userId: req.serviceAuth?.userId ?? req.body?.userId
userId: req.auth?.userId ?? req.body?.userId
});

// Clean up temporary file on error
Expand All @@ -260,14 +260,15 @@ router.post('/multiple', upload.array('files', 10), async (req, res) => {
const tempFilePaths: string[] = [];

try {
const auth = req.serviceAuth;
const auth = req.auth;
if (!auth) {
return res.status(401).json({ error: 'Service authentication required' });
return res.status(401).json({ error: 'Authentication required' });
}

const resourcePageId = auth.claims.resource;
// Get resource binding (pageId) from session
const resourcePageId = auth.resourceBinding?.type === 'page' ? auth.resourceBinding.id : undefined;
if (!resourcePageId) {
return res.status(403).json({ error: 'Service token missing page scope' });
return res.status(403).json({ error: 'Token missing page resource binding' });
}

const driveId = typeof req.body?.driveId === 'string' ? req.body.driveId : undefined;
Expand All @@ -276,29 +277,28 @@ router.post('/multiple', upload.array('files', 10), async (req, res) => {
}

if (!auth.driveId || auth.driveId !== driveId) {
return res.status(403).json({ error: 'Service token drive does not match requested drive' });
return res.status(403).json({ error: 'Token drive does not match requested drive' });
}

const providedUserId = typeof req.body?.userId === 'string' ? req.body.userId : undefined;
if (
auth.userId &&
providedUserId &&
providedUserId !== auth.userId &&
!hasServiceScope(auth, 'files:write:any')
!hasAuthScope(auth, 'files:write:any')
) {
return res.status(403).json({ error: 'Cannot upload on behalf of another user' });
}

const uploaderId = auth.userId ?? providedUserId;
const tenantId = auth.tenantId;

if (!req.files || !Array.isArray(req.files)) {
return res.status(400).json({ error: 'No files provided' });
}

const pageId = typeof req.body?.pageId === 'string' ? req.body.pageId : undefined;
if (resourcePageId && pageId && resourcePageId !== pageId) {
return res.status(403).json({ error: 'Service token resource does not match requested page' });
return res.status(403).json({ error: 'Token resource does not match requested page' });
}
const results = [];

Expand All @@ -319,18 +319,18 @@ router.post('/multiple', upload.array('files', 10), async (req, res) => {

if (!alreadyStored) {
await contentStore.saveOriginalFromFile(tempPath, originalname, contentHash, {
tenantId,
tenantId: auth.userId,
driveId,
userId: uploaderId,
service: auth.service
service: 'processor'
});
}
if (alreadyStored) {
await contentStore.appendUploadMetadata(contentHash, {
tenantId,
tenantId: auth.userId,
driveId,
userId: uploaderId,
service: auth.service
service: 'processor'
});
}

Expand Down
Loading
Loading