@@ -140,6 +140,7 @@ const { setupApolloServer } = require('./src/graphql');
140140
141141// Tier middleware — attaches req.user.tier to every request
142142const { attachTier } = require ( './middleware/tierAuth' ) ;
143+ const { MerchantCorsMiddleware } = require ( './src/middleware/merchantCorsMiddleware' ) ;
143144
144145/**
145146 * Create the Express application with injectable services for testing.
@@ -173,7 +174,8 @@ async function createApp(dependencies = {}) {
173174 const tokenService = dependencies . tokenService || new CdnTokenService ( config ) ;
174175
175176 // ── Global middleware ──────────────────────────────────────────────────────
176- app . use ( cors ( ) ) ;
177+ const merchantCors = new MerchantCorsMiddleware ( database ) ;
178+ app . use ( cors ( merchantCors . corsOptionsDelegate ( ) ) ) ;
177179 app . use ( express . json ( { limit : '10mb' } ) ) ;
178180 app . use ( express . urlencoded ( { extended : true } ) ) ;
179181
@@ -248,6 +250,9 @@ async function createApp(dependencies = {}) {
248250 amlScannerWorker . start ( ) . catch ( error => {
249251 console . error ( 'Failed to start AML scanner worker:' , error ) ;
250252 } ) ;
253+ }
254+
255+
251256
252257 // Start federation worker if ActivityPub is enabled
253258 if ( config . activityPub ?. enabled !== false ) {
@@ -344,14 +349,12 @@ async function createApp(dependencies = {}) {
344349 } ) ;
345350
346351 // Start federation worker if ActivityPub is enabled
347- if ( config . activityPub ?. enabled !== false ) {
348- federationWorker . start ( ) . catch ( error => {
349- console . error ( 'Failed to start federation worker:' , error ) ;
350- } ) ;
351- }
352+ if ( config . activityPub ?. enabled !== false ) {
353+ federationWorker . start ( ) . catch ( error => {
354+ console . error ( 'Failed to start federation worker:' , error ) ;
355+ } ) ;
356+ }
352357
353- app . use ( cors ( ) ) ;
354- app . use ( express . json ( ) ) ;
355358
356359
357360 // Subscription events webhook
@@ -678,51 +681,48 @@ async function createApp(dependencies = {}) {
678681 requireCreatorAuth ( creatorAuthService ) ,
679682 ( req , res ) => {
680683 const format = String ( req . query . format || '' ) . toLowerCase ( ) ;
681- // Get creator stats (including cached subscriber count)
682- app . get ( '/api/creator/:id/stats' , ( req , res ) => {
683- try {
684- const creatorId = req . params . id ;
685- const subscriberCount = database . getCreatorSubscriberCount ( creatorId ) ;
686684
687- return res . status ( 200 ) . json ( { success : true , data : { creatorId, subscriberCount } } ) ;
688- } catch ( error ) {
689- return res . status ( 500 ) . json ( { success : false , error : error . message || 'Failed to fetch stats' } ) ;
690- }
691- } ) ;
692-
693- app . get ( '/api/creator/audit-log/export' , requireCreatorAuth ( creatorAuthService ) , ( req , res ) => {
694- const format = String ( req . query . format || '' ) . toLowerCase ( ) ;
695-
696- if ( ! [ 'csv' , 'pdf' ] . includes ( format ) ) {
697- return res . status ( 400 ) . json ( { success : false , error : 'format must be one of: csv, pdf' } ) ;
698- }
685+ if ( ! [ 'csv' , 'pdf' ] . includes ( format ) ) {
686+ return res . status ( 400 ) . json ( { success : false , error : 'format must be one of: csv, pdf' } ) ;
687+ }
699688
700- const logs = auditLogService . listByCreatorId ( req . creator . id ) ;
701- const exportTimestamp = new Date ( ) . toISOString ( ) ;
702-
703- if ( format === 'csv' ) {
704- const csv = buildAuditLogCsv ( logs ) ;
705- res . setHeader ( 'Content-Type' , 'text/csv; charset=utf-8' ) ;
706- res . setHeader (
707- 'Content-Disposition' ,
708- `attachment; filename="creator-audit-log-${ req . creator . id } .csv"` ,
709- ) ;
710- return res . status ( 200 ) . send ( csv ) ;
711- }
689+ const logs = auditLogService . listByCreatorId ( req . creator . id ) ;
690+ const exportTimestamp = new Date ( ) . toISOString ( ) ;
712691
713- const pdf = buildAuditLogPdf ( {
714- creatorId : req . creator . id ,
715- exportedAt : exportTimestamp ,
716- logs,
717- } ) ;
718- res . setHeader ( 'Content-Type' , 'application/pdf' ) ;
692+ if ( format === 'csv' ) {
693+ const csv = buildAuditLogCsv ( logs ) ;
694+ res . setHeader ( 'Content-Type' , 'text/csv; charset=utf-8' ) ;
719695 res . setHeader (
720696 'Content-Disposition' ,
721- `attachment; filename="creator-audit-log-${ req . creator . id } .pdf "` ,
697+ `attachment; filename="creator-audit-log-${ req . creator . id } .csv "` ,
722698 ) ;
723- return res . status ( 200 ) . send ( pdf ) ;
724- } ,
699+ return res . status ( 200 ) . send ( csv ) ;
700+ }
701+
702+ const pdf = buildAuditLogPdf ( {
703+ creatorId : req . creator . id ,
704+ exportedAt : exportTimestamp ,
705+ logs,
706+ } ) ;
707+ res . setHeader ( 'Content-Type' , 'application/pdf' ) ;
708+ res . setHeader (
709+ 'Content-Disposition' ,
710+ `attachment; filename="creator-audit-log-${ req . creator . id } .pdf"` ,
725711 ) ;
712+ return res . status ( 200 ) . send ( pdf ) ;
713+ }
714+ ) ;
715+
716+ app . get ( '/api/creator/:id/stats' , ( req , res ) => {
717+ try {
718+ const creatorId = req . params . id ;
719+ const subscriberCount = database . getCreatorSubscriberCount ( creatorId ) ;
720+ return res . status ( 200 ) . json ( { success : true , data : { creatorId, subscriberCount } } ) ;
721+ } catch ( error ) {
722+ return res . status ( 500 ) . json ( { success : false , error : error . message || 'Failed to fetch stats' } ) ;
723+ }
724+ } ) ;
725+
726726
727727 // ── Error handlers ─────────────────────────────────────────────────────────
728728 app . use ( createErrorMonitoringMiddleware ( endpointMonitoringService ) ) ;
@@ -896,10 +896,10 @@ async function createApp(dependencies = {}) {
896896 } ) ;
897897 } ) ;
898898
899- return app ;
900- }
899+ return app ;
901900}
902901
902+
903903// ── Private helpers ────────────────────────────────────────────────────────
904904
905905function extractToken ( req ) {
0 commit comments