@@ -7,18 +7,11 @@ import path from 'path'
77import { fileURLToPath } from 'url'
88import database from '../../lib/database.js'
99import api from '../../lib/api.js'
10- import { NotFoundError , ValidationError } from '../../lib/errors.js'
10+ import { NotFoundError , ValidationError , ForbiddenError } from '../../lib/errors.js'
1111import { readFile } from '../../lib/fs.js'
1212import addEndpoint from './middleware/add-endpoint.js'
1313import logger from '../../lib/logger.js'
14- import {
15- getCachedProxyConfig ,
16- parseS3Url ,
17- shouldProxyAssets ,
18- generatePresignedUrl ,
19- determineS3Region ,
20- initProxyConfig ,
21- } from '../../lib/asset-proxy.js'
14+ import { getAssetProxyBuckets , getAssetPresignedUrl } from '../../lib/asset-proxy.js'
2215
2316/**
2417 * @typedef {import('express').Request } Request
@@ -28,7 +21,7 @@ import {
2821 */
2922
3023export const createApp = async ( ) => {
31- await initProxyConfig ( )
24+ await getAssetProxyBuckets ( )
3225
3326 const txnEnabled = process . env [ 'ENABLE_TRANSACTIONS_EXTENSION' ] === 'true'
3427
@@ -463,79 +456,72 @@ export const createApp = async () => {
463456 }
464457 } )
465458
466- /**
467- * Redirects a request for a proxied asset to a presigned S3 URL
468- * @param {Request } req - Express request
469- * @param {Response } res - Express response
470- * @param {NextFunction } next - Express next function
471- * @returns {Promise<void> } Resolves when done
472- */
473- const redirectProxiedAssetRequest = async ( req , res , next ) => {
474- logger . debug ( 'Asset proxy request' , { params : req . params } )
475- try {
476- const proxyConfig = getCachedProxyConfig ( )
477- if ( ! proxyConfig . enabled ) {
478- return next ( createError ( 403 ) )
479- }
480-
481- const { collectionId, itemId, assetKey } = req . params
482- const itemOrCollection = itemId // itemId is only defined for item assets
483- ? await api . getItem ( database , collectionId , itemId , req . endpoint , req . query , req . headers )
484- : await api . getCollection ( database , collectionId , req . endpoint , req . query , req . headers )
485- if ( itemOrCollection instanceof NotFoundError ) {
486- return next ( createError ( 404 ) )
487- }
488- if ( itemOrCollection instanceof Error ) {
489- return next ( createError ( 500 ) )
490- }
491-
492- // @ts -ignore - assetKey guaranteed by Express route
493- const asset = itemOrCollection . assets ?. [ assetKey ] || null
494- if ( ! asset ) {
495- return next ( createError ( 404 ) )
496- }
497-
498- const alternateHref = asset . alternate ?. s3 ?. href || null
499- if ( ! alternateHref ) {
500- return next ( createError ( 404 ) )
501- }
459+ app . get ( '/collections/:collectionId/items/:itemId/assets/:assetKey' ,
460+ async ( req , res , next ) => {
461+ try {
462+ const item = await api . getItem (
463+ database ,
464+ req . params . collectionId ,
465+ req . params . itemId ,
466+ req . endpoint ,
467+ req . query ,
468+ req . headers ,
469+ )
502470
503- const s3Info = parseS3Url ( alternateHref )
504- if ( ! s3Info ) {
505- return next ( createError ( 500 , 'Asset S3 href is invalid' ) )
471+ if ( item instanceof NotFoundError ) {
472+ next ( createError ( 404 ) )
473+ } else if ( item instanceof Error ) {
474+ next ( createError ( 500 ) )
475+ } else {
476+ const presignedUrl = await getAssetPresignedUrl ( item , req . params . assetKey )
477+ if ( presignedUrl instanceof ValidationError ) {
478+ next ( createError ( 400 ) )
479+ } else if ( presignedUrl instanceof ForbiddenError ) {
480+ next ( createError ( 403 ) )
481+ } else if ( presignedUrl instanceof NotFoundError ) {
482+ next ( createError ( 404 ) )
483+ } else if ( presignedUrl instanceof Error ) {
484+ next ( createError ( 500 ) )
485+ } else {
486+ res . redirect ( presignedUrl )
487+ }
488+ }
489+ } catch ( error ) {
490+ next ( error )
506491 }
492+ } )
507493
508- if ( ! shouldProxyAssets ( s3Info . bucket , proxyConfig ) ) {
509- return next ( createError ( 403 ) )
510- }
494+ app . get ( '/collections/:collectionId/assets/:assetKey' , async ( req , res , next ) => {
495+ try {
496+ const collection = await api . getCollection (
497+ database ,
498+ req . params . collectionId ,
499+ req . endpoint ,
500+ req . query ,
501+ req . headers ,
502+ )
511503
512- let region = null
513- if ( s3Info . region ) {
514- region = s3Info . region
504+ if ( collection instanceof NotFoundError ) {
505+ next ( createError ( 404 ) )
506+ } else if ( collection instanceof Error ) {
507+ next ( createError ( 500 ) )
515508 } else {
516- region = determineS3Region ( asset , itemOrCollection )
509+ const presignedUrl = await getAssetPresignedUrl ( collection , req . params . assetKey )
510+ if ( presignedUrl instanceof ValidationError ) {
511+ next ( createError ( 400 ) )
512+ } else if ( presignedUrl instanceof ForbiddenError ) {
513+ next ( createError ( 403 ) )
514+ } else if ( presignedUrl instanceof NotFoundError ) {
515+ next ( createError ( 404 ) )
516+ } else if ( presignedUrl instanceof Error ) {
517+ next ( createError ( 500 ) )
518+ } else {
519+ res . redirect ( presignedUrl )
520+ }
517521 }
518-
519- const presignedUrl = await generatePresignedUrl (
520- s3Info . bucket ,
521- s3Info . key ,
522- region ,
523- proxyConfig . urlExpiry
524- )
525-
526- return res . redirect ( presignedUrl )
527522 } catch ( error ) {
528- return next ( error )
523+ next ( error )
529524 }
530- }
531-
532- app . get ( '/collections/:collectionId/items/:itemId/assets/:assetKey' ,
533- async ( req , res , next ) => {
534- await redirectProxiedAssetRequest ( req , res , next )
535- } )
536-
537- app . get ( '/collections/:collectionId/assets/:assetKey' , async ( req , res , next ) => {
538- await redirectProxiedAssetRequest ( req , res , next )
539525 } )
540526
541527 // catch 404 and forward to error handler
0 commit comments