diff --git a/src/modules/atproto/infrastructure/services/BlueskyProfileService.ts b/src/modules/atproto/infrastructure/services/BlueskyProfileService.ts index 48d16a23..5e9be7e0 100644 --- a/src/modules/atproto/infrastructure/services/BlueskyProfileService.ts +++ b/src/modules/atproto/infrastructure/services/BlueskyProfileService.ts @@ -9,23 +9,39 @@ import { DID } from '../../domain/DID'; export class BlueskyProfileService implements IProfileService { constructor(private readonly agentService: IAgentService) {} - async getProfile(userId: string): Promise> { + async getProfile( + userId: string, + callerDid?: string, + ): Promise> { try { - // Get an authenticated agent - we can use any available agent for public profile data - const agentResult = await this.agentService.getAuthenticatedAgent( - new DID(userId), - ); + let agent; - if (agentResult.isErr()) { - return err( - new Error( - `Failed to get authenticated agent: ${agentResult.error.message}`, - ), + if (callerDid) { + // Use caller's authenticated agent + const agentResult = await this.agentService.getAuthenticatedAgent( + new DID(callerDid), ); + if (agentResult.isErr()) { + return err( + new Error( + `Failed to get authenticated agent: ${agentResult.error.message}`, + ), + ); + } + agent = agentResult.value; + } else { + // Fall back to unauthenticated agent for public profiles + const agentResult = this.agentService.getUnauthenticatedAgent(); + if (agentResult.isErr()) { + return err( + new Error( + `Failed to get unauthenticated agent: ${agentResult.error.message}`, + ), + ); + } + agent = agentResult.value; } - const agent = agentResult.value; - if (!agent) { return err(new Error('No authenticated agent available')); } diff --git a/src/modules/cards/application/useCases/queries/GetCollectionPageUseCase.ts b/src/modules/cards/application/useCases/queries/GetCollectionPageUseCase.ts index 688194b7..88f933e9 100644 --- a/src/modules/cards/application/useCases/queries/GetCollectionPageUseCase.ts +++ b/src/modules/cards/application/useCases/queries/GetCollectionPageUseCase.ts @@ -12,6 +12,7 @@ import { IProfileService } from '../../../domain/services/IProfileService'; export interface GetCollectionPageQuery { collectionId: string; + callerDid?: string; page?: number; limit?: number; sortBy?: CardSortField; diff --git a/src/modules/cards/domain/services/IProfileService.ts b/src/modules/cards/domain/services/IProfileService.ts index 4cc4a68b..5ee3048b 100644 --- a/src/modules/cards/domain/services/IProfileService.ts +++ b/src/modules/cards/domain/services/IProfileService.ts @@ -1,7 +1,7 @@ import { Result } from 'src/shared/core/Result'; export interface IProfileService { - getProfile(userId: string): Promise>; + getProfile(userId: string, callerId?: string): Promise>; } export interface UserProfile { diff --git a/src/modules/cards/infrastructure/http/controllers/GetCollectionPageController.ts b/src/modules/cards/infrastructure/http/controllers/GetCollectionPageController.ts index fd719e0a..5d1e345c 100644 --- a/src/modules/cards/infrastructure/http/controllers/GetCollectionPageController.ts +++ b/src/modules/cards/infrastructure/http/controllers/GetCollectionPageController.ts @@ -13,6 +13,7 @@ export class GetCollectionPageController extends Controller { try { const { collectionId } = req.params; const { page, limit, sortBy, sortOrder } = req.query; + const callerDid = req.did; if (!collectionId) { return this.badRequest(res, 'Collection ID is required'); @@ -20,6 +21,7 @@ export class GetCollectionPageController extends Controller { const result = await this.getCollectionPageUseCase.execute({ collectionId, + callerDid, page: page ? parseInt(page as string) : undefined, limit: limit ? parseInt(limit as string) : undefined, sortBy: sortBy as CardSortField, diff --git a/src/modules/cards/infrastructure/http/routes/collectionRoutes.ts b/src/modules/cards/infrastructure/http/routes/collectionRoutes.ts index bd19c48f..fd7d5290 100644 --- a/src/modules/cards/infrastructure/http/routes/collectionRoutes.ts +++ b/src/modules/cards/infrastructure/http/routes/collectionRoutes.ts @@ -16,30 +16,35 @@ export function createCollectionRoutes( ): Router { const router = Router(); - // Apply authentication middleware to all collection routes - router.use(authMiddleware.ensureAuthenticated()); - // Query routes // GET /api/collections - Get my collections - router.get('/', (req, res) => getMyCollectionsController.execute(req, res)); + router.get('/', authMiddleware.ensureAuthenticated(), (req, res) => + getMyCollectionsController.execute(req, res), + ); // GET /api/collections/:collectionId - Get collection page - router.get('/:collectionId', (req, res) => + router.get('/:collectionId', authMiddleware.optionalAuth(), (req, res) => getCollectionPageController.execute(req, res), ); // Command routes // POST /api/collections - Create a new collection - router.post('/', (req, res) => createCollectionController.execute(req, res)); + router.post('/', authMiddleware.ensureAuthenticated(), (req, res) => + createCollectionController.execute(req, res), + ); // PUT /api/collections/:collectionId - Update collection details - router.put('/:collectionId', (req, res) => - updateCollectionController.execute(req, res), + router.put( + '/:collectionId', + authMiddleware.ensureAuthenticated(), + (req, res) => updateCollectionController.execute(req, res), ); // DELETE /api/collections/:collectionId - Delete a collection - router.delete('/:collectionId', (req, res) => - deleteCollectionController.execute(req, res), + router.delete( + '/:collectionId', + authMiddleware.ensureAuthenticated(), + (req, res) => deleteCollectionController.execute(req, res), ); return router;