1
0
Fork 0
mirror of https://github.com/alangrainger/immich-public-proxy.git synced 2024-12-28 20:01:57 +00:00

Simplify code for readability

This commit is contained in:
Alan Grainger 2024-11-12 19:47:40 +01:00
parent bd7e4f4e6a
commit d5400c9a21

View file

@ -16,14 +16,18 @@ app.use(express.json())
// Serve static assets from the /public folder // Serve static assets from the /public folder
app.use(express.static('public', { setHeaders: addResponseHeaders })) app.use(express.static('public', { setHeaders: addResponseHeaders }))
// An incoming request for a shared link /*
* [ROUTE] An incoming request for a shared link
*/
app.get('/share/:key', async (req, res) => { app.get('/share/:key', async (req, res) => {
await immich.handleShareRequest({ await immich.handleShareRequest({
key: req.params.key key: req.params.key
}, res) }, res)
}) })
// Receive an unlock request from the password page /*
* [ROUTE] Receive an unlock request from the password page
*/
app.post('/unlock', async (req, res) => { app.post('/unlock', async (req, res) => {
await immich.handleShareRequest({ await immich.handleShareRequest({
key: toString(req.body.key), key: toString(req.body.key),
@ -31,50 +35,69 @@ app.post('/unlock', async (req, res) => {
}, res) }, res)
}) })
// Output the buffer data for a photo or video /*
* [ROUTE] Output the buffer data for a photo or video
*/
app.get('/:type(photo|video)/:key/:id/:size?', async (req, res) => { app.get('/:type(photo|video)/:key/:id/:size?', async (req, res) => {
// Add the headers configured in config.json (most likely `cache-control`)
addResponseHeaders(res) addResponseHeaders(res)
// Check for valid key and ID // Check for valid key and ID
if (immich.isKey(req.params.key) && immich.isId(req.params.id)) { if (!immich.isKey(req.params.key) || !immich.isId(req.params.id)) {
// Validate the size parameter log('Invalid key or ID for ' + req.path)
if (req.params.size && !Object.values(ImageSize).includes(req.params.size as ImageSize)) { res.status(404).send()
log('Invalid size parameter ' + req.path) return
res.status(404).send() }
return
} // Validate the size parameter
let password if (req.params.size && !Object.values(ImageSize).includes(req.params.size as ImageSize)) {
// Validate the password payload, if one was provided log('Invalid size parameter ' + req.path)
if (req.query?.cr && req.query?.iv) { res.status(404).send()
try { return
const payload = JSON.parse(decrypt({ }
iv: toString(req.query.iv),
cr: toString(req.query.cr) // Validate the password payload, if one was provided
})) let password
if (payload?.expires && dayjs(payload.expires) > dayjs()) { if (req.query?.cr && req.query?.iv) {
password = payload.password try {
} else { const payload = JSON.parse(decrypt({
log(`Attempted to load assets from ${req.params.key} with an expired decryption token`) iv: toString(req.query.iv),
} cr: toString(req.query.cr)
} catch (e) { } }))
} if (payload?.expires && dayjs(payload.expires) > dayjs()) {
// Check if the key is a valid share link password = payload.password
const sharedLink = (await immich.getShareByKey(req.params.key, password))?.link } else {
const request = { key: req.params.key, range: req.headers.range || '' } log(`Attempted to load assets from ${req.params.key} with an expired decryption token`)
if (sharedLink?.assets.length) { // Send 404 rather than 401 so as not to provide information to an attacker that there is "something" at this path
// Check that the requested asset exists in this share res.status(404).send()
const asset = sharedLink.assets.find(x => x.id === req.params.id)
if (asset) {
asset.type = req.params.type === 'video' ? AssetType.video : AssetType.image
render.assetBuffer(request, res, asset, req.params.size).then()
return return
} }
} } catch (e) { }
}
// Fetch the shared link information from Immich, so we can check to make sure that the requested asset
// is allowed by this shared link.
const sharedLink = (await immich.getShareByKey(req.params.key, password))?.link
const request = {
key: req.params.key,
range: req.headers.range || ''
}
if (sharedLink?.assets.length) {
// Check that the requested asset exists in this share
const asset = sharedLink.assets.find(x => x.id === req.params.id)
if (asset) {
asset.type = req.params.type === 'video' ? AssetType.video : AssetType.image
render.assetBuffer(request, res, asset, req.params.size).then()
}
} else {
log('No asset found for ' + req.path)
res.status(404).send()
} }
log('No asset found for ' + req.path)
res.status(404).send()
}) })
// Healthcheck /*
* [ROUTE] Healthcheck
*/
app.get('/healthcheck', async (_req, res) => { app.get('/healthcheck', async (_req, res) => {
if (await immich.accessible()) { if (await immich.accessible()) {
res.send('ok') res.send('ok')
@ -83,12 +106,15 @@ app.get('/healthcheck', async (_req, res) => {
} }
}) })
// Send a 404 for all other routes /*
* Send a 404 for all other routes
*/
app.get('*', (req, res) => { app.get('*', (req, res) => {
log('Invalid route ' + req.path) log('Invalid route ' + req.path)
res.status(404).send() res.status(404).send()
}) })
// Start the ExpressJS server
app.listen(3000, () => { app.listen(3000, () => {
console.log(dayjs().format() + ' Server started') console.log(dayjs().format() + ' Server started')
}) })