Expire asset decryption tokens
This commit is contained in:
parent
f445844766
commit
f78a02bb8d
4
.github/workflows/ci.yaml
vendored
4
.github/workflows/ci.yaml
vendored
@ -53,7 +53,7 @@ jobs:
|
|||||||
build-args: |
|
build-args: |
|
||||||
PACKAGE_VERSION=${{ env.PACKAGE_VERSION }}
|
PACKAGE_VERSION=${{ env.PACKAGE_VERSION }}
|
||||||
tags: |
|
tags: |
|
||||||
${{ github.repository }}:latest
|
|
||||||
${{ github.repository }}:${{ env.PACKAGE_VERSION }}
|
${{ github.repository }}:${{ env.PACKAGE_VERSION }}
|
||||||
ghcr.io/${{ github.repository }}:latest
|
${{ github.repository }}:latest
|
||||||
ghcr.io/${{ github.repository }}:${{ env.PACKAGE_VERSION }}
|
ghcr.io/${{ github.repository }}:${{ env.PACKAGE_VERSION }}
|
||||||
|
ghcr.io/${{ github.repository }}:latest
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "immich-public-proxy",
|
"name": "immich-public-proxy",
|
||||||
"version": "1.3.5",
|
"version": "1.3.6",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "ts-node src/index.ts",
|
"dev": "ts-node src/index.ts",
|
||||||
"build": "npx tsc",
|
"build": "npx tsc",
|
||||||
|
@ -187,7 +187,7 @@ class Immich {
|
|||||||
photoUrl (key: string, id: string, size?: ImageSize, password?: string) {
|
photoUrl (key: string, id: string, size?: ImageSize, password?: string) {
|
||||||
const params = { key, size }
|
const params = { key, size }
|
||||||
if (password) {
|
if (password) {
|
||||||
Object.assign(params, encrypt(password))
|
Object.assign(params, this.encryptPassword(password))
|
||||||
}
|
}
|
||||||
return this.buildUrl(`/photo/${key}/${id}`, params)
|
return this.buildUrl(`/photo/${key}/${id}`, params)
|
||||||
}
|
}
|
||||||
@ -196,7 +196,7 @@ class Immich {
|
|||||||
* Return the video data URL for a video
|
* Return the video data URL for a video
|
||||||
*/
|
*/
|
||||||
videoUrl (key: string, id: string, password?: string) {
|
videoUrl (key: string, id: string, password?: string) {
|
||||||
const params = password ? encrypt(password) : {}
|
const params = password ? this.encryptPassword(password) : {}
|
||||||
return this.buildUrl(`/video/${key}/${id}`, params)
|
return this.buildUrl(`/video/${key}/${id}`, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,6 +215,18 @@ class Immich {
|
|||||||
isKey (key: string) {
|
isKey (key: string) {
|
||||||
return !!key.match(/^[\w-]+$/)
|
return !!key.match(/^[\w-]+$/)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When loading assets from a password-protected link, make the decryption key valid for a
|
||||||
|
* short time. If the visitor loads the share link again, it will renew that expiry time.
|
||||||
|
* This prevents people from sharing the image links and bypassing password protection.
|
||||||
|
*/
|
||||||
|
encryptPassword (password: string) {
|
||||||
|
return encrypt(JSON.stringify({
|
||||||
|
password,
|
||||||
|
expires: dayjs().add(1, 'hour').format()
|
||||||
|
}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const immich = new Immich()
|
const immich = new Immich()
|
||||||
|
@ -37,13 +37,20 @@ app.get('/:type(photo|video)/:key/:id', async (req, res) => {
|
|||||||
res.set('Cache-Control', 'public, max-age=' + process.env.CACHE_AGE)
|
res.set('Cache-Control', 'public, max-age=' + process.env.CACHE_AGE)
|
||||||
// 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)) {
|
||||||
// Decrypt the password, if one was provided
|
|
||||||
let password
|
let password
|
||||||
|
// Validate the password payload, if one was provided
|
||||||
if (req.query?.cr && req.query?.iv) {
|
if (req.query?.cr && req.query?.iv) {
|
||||||
password = decrypt({
|
try {
|
||||||
iv: toString(req.query.iv),
|
const payload = JSON.parse(decrypt({
|
||||||
cr: toString(req.query.cr)
|
iv: toString(req.query.iv),
|
||||||
})
|
cr: toString(req.query.cr)
|
||||||
|
}))
|
||||||
|
if (payload?.expires && dayjs(payload.expires) > dayjs()) {
|
||||||
|
password = payload.password
|
||||||
|
} else {
|
||||||
|
log(`Attempted to load assets from ${req.params.key} with an expired decryption token`)
|
||||||
|
}
|
||||||
|
} catch (e) { }
|
||||||
}
|
}
|
||||||
// Check if the key is a valid share link
|
// Check if the key is a valid share link
|
||||||
const sharedLink = (await immich.getShareByKey(req.params.key, password))?.link
|
const sharedLink = (await immich.getShareByKey(req.params.key, password))?.link
|
||||||
|
Loading…
Reference in New Issue
Block a user