Skip to content

Commit c969b9c

Browse files
committed
refactor: second iteration of initial implementation
1 parent 83cdb90 commit c969b9c

File tree

7 files changed

+362
-347
lines changed

7 files changed

+362
-347
lines changed

src/lambdas/api/app.js

Lines changed: 61 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,11 @@ import path from 'path'
77
import { fileURLToPath } from 'url'
88
import database from '../../lib/database.js'
99
import api from '../../lib/api.js'
10-
import { NotFoundError, ValidationError } from '../../lib/errors.js'
10+
import { NotFoundError, ValidationError, ForbiddenError } from '../../lib/errors.js'
1111
import { readFile } from '../../lib/fs.js'
1212
import addEndpoint from './middleware/add-endpoint.js'
1313
import 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

3023
export 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

src/lib/api.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { isIndexNotFoundError } from './database.js'
77
import logger from './logger.js'
88
import { bboxToPolygon } from './geo-utils.js'
99
import {
10-
getCachedProxyConfig,
10+
isAssetProxyEnabled,
1111
proxyAssets,
1212
} from './asset-proxy.js'
1313

@@ -563,8 +563,7 @@ export const addItemLinks = function (results, endpoint) {
563563

564564
// Impure - mutates results
565565
export const proxyStacObjectAssets = function (results, endpoint) {
566-
const proxyConfig = getCachedProxyConfig()
567-
if (!proxyConfig.enabled) {
566+
if (!isAssetProxyEnabled()) {
568567
return results
569568
}
570569

@@ -581,7 +580,6 @@ export const proxyStacObjectAssets = function (results, endpoint) {
581580
endpoint,
582581
collectionId,
583582
itemId,
584-
proxyConfig
585583
)
586584

587585
if (wasProxied) {

0 commit comments

Comments
 (0)