diff --git a/dist/immich.js b/dist/immich.js index edaa202..ea54f36 100644 --- a/dist/immich.js +++ b/dist/immich.js @@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const types_1 = require("./types"); class Immich { + /** + * Make a request to Immich API. We're not using the SDK to limit + * the possible attack surface of this app. + */ request(endpoint) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const res = yield fetch(process.env.IMMICH_URL + '/api' + endpoint, { @@ -21,12 +25,23 @@ class Immich { } }); } + /** + * Query Immich for the SharedLink metadata for a given key. + * The key is what is returned in the URL when you create a share in Immich. + * Immich doesn't have a method to query by key, so this method gets all + * known shared links, and returns the link which matches the provided key. + */ getShareByKey(key) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const res = ((yield this.request('/shared-links')) || []); return res === null || res === void 0 ? void 0 : res.find(x => x.key === key); }); } + /** + * Stream asset buffer data from Immich. + * For photos, you can request 'thumbnail' or 'original' size. + * For videos, it is Immich's streaming quality, not the original quality. + */ getAssetBuffer(asset, size) { return tslib_1.__awaiter(this, void 0, void 0, function* () { switch (asset.type) { @@ -38,22 +53,40 @@ class Immich { } }); } + /** + * Get the content-type of an Immich asset + */ getContentType(asset) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const assetBuffer = yield this.getAssetBuffer(asset); return assetBuffer.headers.get('Content-Type'); }); } - photoUrl(id, size) { - return `${process.env.SERVER_URL}/photo/${id}` + (size ? `?size=${size}` : ''); + /** + * Return the image data URL for a photo + */ + photoUrl(key, id, size) { + return `${process.env.SERVER_URL}/photo/${key}/${id}` + (size ? `?size=${size}` : ''); } - videoUrl(id) { - return `${process.env.SERVER_URL}/video/${id}`; + /** + * Return the video data URL for a video + */ + videoUrl(key, id) { + return `${process.env.SERVER_URL}/video/${key}/${id}`; } + /** + * Check if a provided ID matches the Immich ID format + */ isId(id) { return !!id.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/); } + /** + * Check if a provided key matches the Immich shared-link key format + */ + isKey(key) { + return !!key.match(/^[\w-]+$/); + } } const immich = new Immich(); exports.default = immich; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1taWNoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ltbWljaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBaUU7QUFFakUsTUFBTSxNQUFNO0lBQ0osT0FBTyxDQUFFLFFBQWdCOztZQUM3QixNQUFNLEdBQUcsR0FBRyxNQUFNLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsR0FBRyxNQUFNLEdBQUcsUUFBUSxFQUFFO2dCQUNsRSxPQUFPLEVBQUU7b0JBQ1AsV0FBVyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxJQUFJLEVBQUU7aUJBQ3ZDO2FBQ0YsQ0FBQyxDQUFBO1lBQ0YsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUN2QixNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLENBQUE7Z0JBQ3pELElBQUksV0FBVyxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUM7b0JBQzdDLE9BQU8sR0FBRyxDQUFDLElBQUksRUFBRSxDQUFBO2dCQUNuQixDQUFDO3FCQUFNLENBQUM7b0JBQ04sT0FBTyxHQUFHLENBQUE7Z0JBQ1osQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO0tBQUE7SUFFSyxhQUFhLENBQUUsR0FBVzs7WUFDOUIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFBLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsS0FBSSxFQUFFLENBQWlCLENBQUE7WUFDdkUsT0FBTyxHQUFHLGFBQUgsR0FBRyx1QkFBSCxHQUFHLENBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQTtRQUN0QyxDQUFDO0tBQUE7SUFFSyxjQUFjLENBQUUsS0FBWSxFQUFFLElBQWdCOztZQUNsRCxRQUFRLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDbkIsS0FBSyxpQkFBUyxDQUFDLEtBQUs7b0JBQ2xCLElBQUksR0FBRyxJQUFJLEtBQUssaUJBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLGlCQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxpQkFBUyxDQUFDLFFBQVEsQ0FBQTtvQkFDOUUsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUMsRUFBRSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQTtnQkFDekQsS0FBSyxpQkFBUyxDQUFDLEtBQUs7b0JBQ2xCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDLEVBQUUsR0FBRyxpQkFBaUIsQ0FBQyxDQUFBO1lBQ2xFLENBQUM7UUFDSCxDQUFDO0tBQUE7SUFFSyxjQUFjLENBQUUsS0FBWTs7WUFDaEMsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFBO1lBQ3BELE9BQU8sV0FBVyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUE7UUFDaEQsQ0FBQztLQUFBO0lBRUQsUUFBUSxDQUFFLEVBQVUsRUFBRSxJQUFnQjtRQUNwQyxPQUFPLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLFVBQVUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQ2hGLENBQUM7SUFFRCxRQUFRLENBQUUsRUFBVTtRQUNsQixPQUFPLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLFVBQVUsRUFBRSxFQUFFLENBQUE7SUFDaEQsQ0FBQztJQUVELElBQUksQ0FBRSxFQUFVO1FBQ2QsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxnRUFBZ0UsQ0FBQyxDQUFBO0lBQ3JGLENBQUM7Q0FDRjtBQUVELE1BQU0sTUFBTSxHQUFHLElBQUksTUFBTSxFQUFFLENBQUE7QUFFM0Isa0JBQWUsTUFBTSxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXNzZXQsIEFzc2V0VHlwZSwgSW1hZ2VTaXplLCBTaGFyZWRMaW5rIH0gZnJvbSAnLi90eXBlcydcblxuY2xhc3MgSW1taWNoIHtcbiAgYXN5bmMgcmVxdWVzdCAoZW5kcG9pbnQ6IHN0cmluZykge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKHByb2Nlc3MuZW52LklNTUlDSF9VUkwgKyAnL2FwaScgKyBlbmRwb2ludCwge1xuICAgICAgaGVhZGVyczoge1xuICAgICAgICAneC1hcGkta2V5JzogcHJvY2Vzcy5lbnYuQVBJX0tFWSB8fCAnJ1xuICAgICAgfVxuICAgIH0pXG4gICAgaWYgKHJlcy5zdGF0dXMgPT09IDIwMCkge1xuICAgICAgY29uc3QgY29udGVudFR5cGUgPSByZXMuaGVhZGVycy5nZXQoJ0NvbnRlbnQtVHlwZScpIHx8ICcnXG4gICAgICBpZiAoY29udGVudFR5cGUuaW5jbHVkZXMoJ2FwcGxpY2F0aW9uL2pzb24nKSkge1xuICAgICAgICByZXR1cm4gcmVzLmpzb24oKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHJlc1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdldFNoYXJlQnlLZXkgKGtleTogc3RyaW5nKSB7XG4gICAgY29uc3QgcmVzID0gKGF3YWl0IHRoaXMucmVxdWVzdCgnL3NoYXJlZC1saW5rcycpIHx8IFtdKSBhcyBTaGFyZWRMaW5rW11cbiAgICByZXR1cm4gcmVzPy5maW5kKHggPT4geC5rZXkgPT09IGtleSlcbiAgfVxuXG4gIGFzeW5jIGdldEFzc2V0QnVmZmVyIChhc3NldDogQXNzZXQsIHNpemU/OiBJbWFnZVNpemUpIHtcbiAgICBzd2l0Y2ggKGFzc2V0LnR5cGUpIHtcbiAgICAgIGNhc2UgQXNzZXRUeXBlLmltYWdlOlxuICAgICAgICBzaXplID0gc2l6ZSA9PT0gSW1hZ2VTaXplLnRodW1ibmFpbCA/IEltYWdlU2l6ZS50aHVtYm5haWwgOiBJbWFnZVNpemUub3JpZ2luYWxcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnL2Fzc2V0cy8nICsgYXNzZXQuaWQgKyAnLycgKyBzaXplKVxuICAgICAgY2FzZSBBc3NldFR5cGUudmlkZW86XG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJy9hc3NldHMvJyArIGFzc2V0LmlkICsgJy92aWRlby9wbGF5YmFjaycpXG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ2V0Q29udGVudFR5cGUgKGFzc2V0OiBBc3NldCkge1xuICAgIGNvbnN0IGFzc2V0QnVmZmVyID0gYXdhaXQgdGhpcy5nZXRBc3NldEJ1ZmZlcihhc3NldClcbiAgICByZXR1cm4gYXNzZXRCdWZmZXIuaGVhZGVycy5nZXQoJ0NvbnRlbnQtVHlwZScpXG4gIH1cblxuICBwaG90b1VybCAoaWQ6IHN0cmluZywgc2l6ZT86IEltYWdlU2l6ZSkge1xuICAgIHJldHVybiBgJHtwcm9jZXNzLmVudi5TRVJWRVJfVVJMfS9waG90by8ke2lkfWAgKyAoc2l6ZSA/IGA/c2l6ZT0ke3NpemV9YCA6ICcnKVxuICB9XG5cbiAgdmlkZW9VcmwgKGlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYCR7cHJvY2Vzcy5lbnYuU0VSVkVSX1VSTH0vdmlkZW8vJHtpZH1gXG4gIH1cblxuICBpc0lkIChpZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuICEhaWQubWF0Y2goL15bMC05YS1mXXs4fS1bMC05YS1mXXs0fS1bMC05YS1mXXs0fS1bMC05YS1mXXs0fS1bMC05YS1mXXsxMn0kLylcbiAgfVxufVxuXG5jb25zdCBpbW1pY2ggPSBuZXcgSW1taWNoKClcblxuZXhwb3J0IGRlZmF1bHQgaW1taWNoXG4iXX0= \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1taWNoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ltbWljaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBaUU7QUFFakUsTUFBTSxNQUFNO0lBQ1Y7OztPQUdHO0lBQ0csT0FBTyxDQUFFLFFBQWdCOztZQUM3QixNQUFNLEdBQUcsR0FBRyxNQUFNLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsR0FBRyxNQUFNLEdBQUcsUUFBUSxFQUFFO2dCQUNsRSxPQUFPLEVBQUU7b0JBQ1AsV0FBVyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxJQUFJLEVBQUU7aUJBQ3ZDO2FBQ0YsQ0FBQyxDQUFBO1lBQ0YsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUN2QixNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLENBQUE7Z0JBQ3pELElBQUksV0FBVyxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUM7b0JBQzdDLE9BQU8sR0FBRyxDQUFDLElBQUksRUFBRSxDQUFBO2dCQUNuQixDQUFDO3FCQUFNLENBQUM7b0JBQ04sT0FBTyxHQUFHLENBQUE7Z0JBQ1osQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO0tBQUE7SUFFRDs7Ozs7T0FLRztJQUNHLGFBQWEsQ0FBRSxHQUFXOztZQUM5QixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUEsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxLQUFJLEVBQUUsQ0FBaUIsQ0FBQTtZQUN2RSxPQUFPLEdBQUcsYUFBSCxHQUFHLHVCQUFILEdBQUcsQ0FBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLEdBQUcsQ0FBQyxDQUFBO1FBQ3RDLENBQUM7S0FBQTtJQUVEOzs7O09BSUc7SUFDRyxjQUFjLENBQUUsS0FBWSxFQUFFLElBQWdCOztZQUNsRCxRQUFRLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDbkIsS0FBSyxpQkFBUyxDQUFDLEtBQUs7b0JBQ2xCLElBQUksR0FBRyxJQUFJLEtBQUssaUJBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLGlCQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxpQkFBUyxDQUFDLFFBQVEsQ0FBQTtvQkFDOUUsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUMsRUFBRSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQTtnQkFDekQsS0FBSyxpQkFBUyxDQUFDLEtBQUs7b0JBQ2xCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDLEVBQUUsR0FBRyxpQkFBaUIsQ0FBQyxDQUFBO1lBQ2xFLENBQUM7UUFDSCxDQUFDO0tBQUE7SUFFRDs7T0FFRztJQUNHLGNBQWMsQ0FBRSxLQUFZOztZQUNoQyxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUE7WUFDcEQsT0FBTyxXQUFXLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQTtRQUNoRCxDQUFDO0tBQUE7SUFFRDs7T0FFRztJQUNILFFBQVEsQ0FBRSxHQUFXLEVBQUUsRUFBVSxFQUFFLElBQWdCO1FBQ2pELE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsVUFBVSxHQUFHLElBQUksRUFBRSxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQ3ZGLENBQUM7SUFFRDs7T0FFRztJQUNILFFBQVEsQ0FBRSxHQUFXLEVBQUUsRUFBVTtRQUMvQixPQUFPLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLFVBQVUsR0FBRyxJQUFJLEVBQUUsRUFBRSxDQUFBO0lBQ3ZELENBQUM7SUFFRDs7T0FFRztJQUNILElBQUksQ0FBRSxFQUFVO1FBQ2QsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxnRUFBZ0UsQ0FBQyxDQUFBO0lBQ3JGLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBRSxHQUFXO1FBQ2hCLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUE7SUFDaEMsQ0FBQztDQUNGO0FBRUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxNQUFNLEVBQUUsQ0FBQTtBQUUzQixrQkFBZSxNQUFNLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBc3NldCwgQXNzZXRUeXBlLCBJbWFnZVNpemUsIFNoYXJlZExpbmsgfSBmcm9tICcuL3R5cGVzJ1xuXG5jbGFzcyBJbW1pY2gge1xuICAvKipcbiAgICogTWFrZSBhIHJlcXVlc3QgdG8gSW1taWNoIEFQSS4gV2UncmUgbm90IHVzaW5nIHRoZSBTREsgdG8gbGltaXRcbiAgICogdGhlIHBvc3NpYmxlIGF0dGFjayBzdXJmYWNlIG9mIHRoaXMgYXBwLlxuICAgKi9cbiAgYXN5bmMgcmVxdWVzdCAoZW5kcG9pbnQ6IHN0cmluZykge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKHByb2Nlc3MuZW52LklNTUlDSF9VUkwgKyAnL2FwaScgKyBlbmRwb2ludCwge1xuICAgICAgaGVhZGVyczoge1xuICAgICAgICAneC1hcGkta2V5JzogcHJvY2Vzcy5lbnYuQVBJX0tFWSB8fCAnJ1xuICAgICAgfVxuICAgIH0pXG4gICAgaWYgKHJlcy5zdGF0dXMgPT09IDIwMCkge1xuICAgICAgY29uc3QgY29udGVudFR5cGUgPSByZXMuaGVhZGVycy5nZXQoJ0NvbnRlbnQtVHlwZScpIHx8ICcnXG4gICAgICBpZiAoY29udGVudFR5cGUuaW5jbHVkZXMoJ2FwcGxpY2F0aW9uL2pzb24nKSkge1xuICAgICAgICByZXR1cm4gcmVzLmpzb24oKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHJlc1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBRdWVyeSBJbW1pY2ggZm9yIHRoZSBTaGFyZWRMaW5rIG1ldGFkYXRhIGZvciBhIGdpdmVuIGtleS5cbiAgICogVGhlIGtleSBpcyB3aGF0IGlzIHJldHVybmVkIGluIHRoZSBVUkwgd2hlbiB5b3UgY3JlYXRlIGEgc2hhcmUgaW4gSW1taWNoLlxuICAgKiBJbW1pY2ggZG9lc24ndCBoYXZlIGEgbWV0aG9kIHRvIHF1ZXJ5IGJ5IGtleSwgc28gdGhpcyBtZXRob2QgZ2V0cyBhbGxcbiAgICoga25vd24gc2hhcmVkIGxpbmtzLCBhbmQgcmV0dXJucyB0aGUgbGluayB3aGljaCBtYXRjaGVzIHRoZSBwcm92aWRlZCBrZXkuXG4gICAqL1xuICBhc3luYyBnZXRTaGFyZUJ5S2V5IChrZXk6IHN0cmluZykge1xuICAgIGNvbnN0IHJlcyA9IChhd2FpdCB0aGlzLnJlcXVlc3QoJy9zaGFyZWQtbGlua3MnKSB8fCBbXSkgYXMgU2hhcmVkTGlua1tdXG4gICAgcmV0dXJuIHJlcz8uZmluZCh4ID0+IHgua2V5ID09PSBrZXkpXG4gIH1cblxuICAvKipcbiAgICogU3RyZWFtIGFzc2V0IGJ1ZmZlciBkYXRhIGZyb20gSW1taWNoLlxuICAgKiBGb3IgcGhvdG9zLCB5b3UgY2FuIHJlcXVlc3QgJ3RodW1ibmFpbCcgb3IgJ29yaWdpbmFsJyBzaXplLlxuICAgKiBGb3IgdmlkZW9zLCBpdCBpcyBJbW1pY2gncyBzdHJlYW1pbmcgcXVhbGl0eSwgbm90IHRoZSBvcmlnaW5hbCBxdWFsaXR5LlxuICAgKi9cbiAgYXN5bmMgZ2V0QXNzZXRCdWZmZXIgKGFzc2V0OiBBc3NldCwgc2l6ZT86IEltYWdlU2l6ZSkge1xuICAgIHN3aXRjaCAoYXNzZXQudHlwZSkge1xuICAgICAgY2FzZSBBc3NldFR5cGUuaW1hZ2U6XG4gICAgICAgIHNpemUgPSBzaXplID09PSBJbWFnZVNpemUudGh1bWJuYWlsID8gSW1hZ2VTaXplLnRodW1ibmFpbCA6IEltYWdlU2l6ZS5vcmlnaW5hbFxuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCcvYXNzZXRzLycgKyBhc3NldC5pZCArICcvJyArIHNpemUpXG4gICAgICBjYXNlIEFzc2V0VHlwZS52aWRlbzpcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnL2Fzc2V0cy8nICsgYXNzZXQuaWQgKyAnL3ZpZGVvL3BsYXliYWNrJylcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBjb250ZW50LXR5cGUgb2YgYW4gSW1taWNoIGFzc2V0XG4gICAqL1xuICBhc3luYyBnZXRDb250ZW50VHlwZSAoYXNzZXQ6IEFzc2V0KSB7XG4gICAgY29uc3QgYXNzZXRCdWZmZXIgPSBhd2FpdCB0aGlzLmdldEFzc2V0QnVmZmVyKGFzc2V0KVxuICAgIHJldHVybiBhc3NldEJ1ZmZlci5oZWFkZXJzLmdldCgnQ29udGVudC1UeXBlJylcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGltYWdlIGRhdGEgVVJMIGZvciBhIHBob3RvXG4gICAqL1xuICBwaG90b1VybCAoa2V5OiBzdHJpbmcsIGlkOiBzdHJpbmcsIHNpemU/OiBJbWFnZVNpemUpIHtcbiAgICByZXR1cm4gYCR7cHJvY2Vzcy5lbnYuU0VSVkVSX1VSTH0vcGhvdG8vJHtrZXl9LyR7aWR9YCArIChzaXplID8gYD9zaXplPSR7c2l6ZX1gIDogJycpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSB2aWRlbyBkYXRhIFVSTCBmb3IgYSB2aWRlb1xuICAgKi9cbiAgdmlkZW9VcmwgKGtleTogc3RyaW5nLCBpZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGAke3Byb2Nlc3MuZW52LlNFUlZFUl9VUkx9L3ZpZGVvLyR7a2V5fS8ke2lkfWBcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIHByb3ZpZGVkIElEIG1hdGNoZXMgdGhlIEltbWljaCBJRCBmb3JtYXRcbiAgICovXG4gIGlzSWQgKGlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gISFpZC5tYXRjaCgvXlswLTlhLWZdezh9LVswLTlhLWZdezR9LVswLTlhLWZdezR9LVswLTlhLWZdezR9LVswLTlhLWZdezEyfSQvKVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgcHJvdmlkZWQga2V5IG1hdGNoZXMgdGhlIEltbWljaCBzaGFyZWQtbGluayBrZXkgZm9ybWF0XG4gICAqL1xuICBpc0tleSAoa2V5OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gISFrZXkubWF0Y2goL15bXFx3LV0rJC8pXG4gIH1cbn1cblxuY29uc3QgaW1taWNoID0gbmV3IEltbWljaCgpXG5cbmV4cG9ydCBkZWZhdWx0IGltbWljaFxuIl19 \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 08ae955..b2965e3 100644 --- a/dist/index.js +++ b/dist/index.js @@ -15,52 +15,55 @@ const getSize = (req) => { return ((_a = req === null || req === void 0 ? void 0 : req.query) === null || _a === void 0 ? void 0 : _a.size) === 'thumbnail' ? types_1.ImageSize.thumbnail : types_1.ImageSize.original; }; app.get('/share/:key', (req, res) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { - if (req.params.key.match(/[^\w-]/)) { - // Invalid characters in the incoming URL + if (!immich_1.default.isKey(req.params.key)) { res.status(404).send(); } else { - const share = yield immich_1.default.getShareByKey(req.params.key); - if (!share || !share.assets.length) { + const sharedLink = yield immich_1.default.getShareByKey(req.params.key); + if (!sharedLink || !sharedLink.assets.length) { res.status(404).send(); } - else if (share.assets.length === 1) { + else if (sharedLink.assets.length === 1) { // This is an individual item (not a gallery) - const asset = share.assets[0]; + const asset = sharedLink.assets[0]; if (asset.type === types_1.AssetType.image) { - // Output the image directly - yield render_1.default.assetBuffer(res, share.assets[0], getSize(req)); + // For photos, output the image directly + yield render_1.default.assetBuffer(res, sharedLink.assets[0], getSize(req)); } else if (asset.type === types_1.AssetType.video) { - // Show the video as a web player - yield render_1.default.gallery(res, share.assets, 1); + // For videos, show the video as a web player + yield render_1.default.gallery(res, sharedLink, 1); } } else { // Multiple images - render as a gallery - yield render_1.default.gallery(res, share.assets); + yield render_1.default.gallery(res, sharedLink); } } })); // Output the buffer data for an photo or video -app.get('/:type(photo|video)/:id', (req, res) => { - if (!immich_1.default.isId(req.params.id)) { - // Invalid characters in the incoming URL - res.status(404).send(); - return; - } - const asset = { - id: req.params.id, - type: req.params.type === 'video' ? types_1.AssetType.video : types_1.AssetType.image - }; - switch (req.params.type) { - case 'photo': - case 'video': - render_1.default.assetBuffer(res, asset, getSize(req)).then(); - break; +app.get('/:type(photo|video)/:key/:id', (req, res) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { + // Check for valid key and ID + if (immich_1.default.isKey(req.params.key) && immich_1.default.isId(req.params.id)) { + // Check if the key is a valid share link + const sharedLink = yield immich_1.default.getShareByKey(req.params.key); + if (sharedLink === null || sharedLink === void 0 ? void 0 : 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' ? types_1.AssetType.video : types_1.AssetType.image; + render_1.default.assetBuffer(res, asset, getSize(req)).then(); + return; + } + } } + res.status(404).send(); +})); +// Send a 404 for all other unmatched routes +app.get('*', (_req, res) => { + res.status(404).send(); }); app.listen(3000, () => { console.log((0, dayjs_1.default)().format() + ' Server started'); }); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsOERBQTZCO0FBQzdCLDhEQUE2QjtBQUM3Qiw4REFBNkI7QUFDN0IsMERBQXlCO0FBQ3pCLG1DQUE4QztBQUc5QyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUE7QUFFMUIsTUFBTSxHQUFHLEdBQUcsSUFBQSxpQkFBTyxHQUFFLENBQUE7QUFDckIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUE7QUFDN0IsR0FBRyxDQUFDLEdBQUcsQ0FBQyxpQkFBTyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFBO0FBRWpDLE1BQU0sT0FBTyxHQUFHLENBQUMsR0FBWSxFQUFFLEVBQUU7O0lBQy9CLE9BQU8sQ0FBQSxNQUFBLEdBQUcsYUFBSCxHQUFHLHVCQUFILEdBQUcsQ0FBRSxLQUFLLDBDQUFFLElBQUksTUFBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLGlCQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxpQkFBUyxDQUFDLFFBQVEsQ0FBQTtBQUNwRixDQUFDLENBQUE7QUFFRCxHQUFHLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFPLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtJQUN4QyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQ25DLHlDQUF5QztRQUN6QyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFBO0lBQ3hCLENBQUM7U0FBTSxDQUFDO1FBQ04sTUFBTSxLQUFLLEdBQUcsTUFBTSxnQkFBTSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ3hELElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ25DLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUE7UUFDeEIsQ0FBQzthQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDckMsNkNBQTZDO1lBQzdDLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUE7WUFDN0IsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLGlCQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ25DLDRCQUE0QjtnQkFDNUIsTUFBTSxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtZQUM5RCxDQUFDO2lCQUFNLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxpQkFBUyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUMxQyxpQ0FBaUM7Z0JBQ2pDLE1BQU0sZ0JBQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUE7WUFDNUMsQ0FBQztRQUNILENBQUM7YUFBTSxDQUFDO1lBQ04sd0NBQXdDO1lBQ3hDLE1BQU0sZ0JBQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUN6QyxDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUMsQ0FBQSxDQUFDLENBQUE7QUFFRiwrQ0FBK0M7QUFDL0MsR0FBRyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtJQUM5QyxJQUFJLENBQUMsZ0JBQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ2hDLHlDQUF5QztRQUN6QyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFBO1FBQ3RCLE9BQU07SUFDUixDQUFDO0lBQ0QsTUFBTSxLQUFLLEdBQUc7UUFDWixFQUFFLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1FBQ2pCLElBQUksRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLGlCQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxpQkFBUyxDQUFDLEtBQUs7S0FDdEUsQ0FBQTtJQUNELFFBQVEsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN4QixLQUFLLE9BQU8sQ0FBQztRQUNiLEtBQUssT0FBTztZQUNWLGdCQUFNLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUE7WUFDbkQsTUFBSztJQUNULENBQUM7QUFDSCxDQUFDLENBQUMsQ0FBQTtBQUVGLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRTtJQUNwQixPQUFPLENBQUMsR0FBRyxDQUFDLElBQUEsZUFBSyxHQUFFLENBQUMsTUFBTSxFQUFFLEdBQUcsaUJBQWlCLENBQUMsQ0FBQTtBQUNuRCxDQUFDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnXG5pbXBvcnQgaW1taWNoIGZyb20gJy4vaW1taWNoJ1xuaW1wb3J0IHJlbmRlciBmcm9tICcuL3JlbmRlcidcbmltcG9ydCBkYXlqcyBmcm9tICdkYXlqcydcbmltcG9ydCB7IEFzc2V0VHlwZSwgSW1hZ2VTaXplIH0gZnJvbSAnLi90eXBlcydcbmltcG9ydCB7IFJlcXVlc3QgfSBmcm9tICdleHByZXNzLXNlcnZlLXN0YXRpYy1jb3JlJ1xuXG5yZXF1aXJlKCdkb3RlbnYnKS5jb25maWcoKVxuXG5jb25zdCBhcHAgPSBleHByZXNzKClcbmFwcC5zZXQoJ3ZpZXcgZW5naW5lJywgJ2VqcycpXG5hcHAudXNlKGV4cHJlc3Muc3RhdGljKCdwdWJsaWMnKSlcblxuY29uc3QgZ2V0U2l6ZSA9IChyZXE6IFJlcXVlc3QpID0+IHtcbiAgcmV0dXJuIHJlcT8ucXVlcnk/LnNpemUgPT09ICd0aHVtYm5haWwnID8gSW1hZ2VTaXplLnRodW1ibmFpbCA6IEltYWdlU2l6ZS5vcmlnaW5hbFxufVxuXG5hcHAuZ2V0KCcvc2hhcmUvOmtleScsIGFzeW5jIChyZXEsIHJlcykgPT4ge1xuICBpZiAocmVxLnBhcmFtcy5rZXkubWF0Y2goL1teXFx3LV0vKSkge1xuICAgIC8vIEludmFsaWQgY2hhcmFjdGVycyBpbiB0aGUgaW5jb21pbmcgVVJMXG4gICAgcmVzLnN0YXR1cyg0MDQpLnNlbmQoKVxuICB9IGVsc2Uge1xuICAgIGNvbnN0IHNoYXJlID0gYXdhaXQgaW1taWNoLmdldFNoYXJlQnlLZXkocmVxLnBhcmFtcy5rZXkpXG4gICAgaWYgKCFzaGFyZSB8fCAhc2hhcmUuYXNzZXRzLmxlbmd0aCkge1xuICAgICAgcmVzLnN0YXR1cyg0MDQpLnNlbmQoKVxuICAgIH0gZWxzZSBpZiAoc2hhcmUuYXNzZXRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgLy8gVGhpcyBpcyBhbiBpbmRpdmlkdWFsIGl0ZW0gKG5vdCBhIGdhbGxlcnkpXG4gICAgICBjb25zdCBhc3NldCA9IHNoYXJlLmFzc2V0c1swXVxuICAgICAgaWYgKGFzc2V0LnR5cGUgPT09IEFzc2V0VHlwZS5pbWFnZSkge1xuICAgICAgICAvLyBPdXRwdXQgdGhlIGltYWdlIGRpcmVjdGx5XG4gICAgICAgIGF3YWl0IHJlbmRlci5hc3NldEJ1ZmZlcihyZXMsIHNoYXJlLmFzc2V0c1swXSwgZ2V0U2l6ZShyZXEpKVxuICAgICAgfSBlbHNlIGlmIChhc3NldC50eXBlID09PSBBc3NldFR5cGUudmlkZW8pIHtcbiAgICAgICAgLy8gU2hvdyB0aGUgdmlkZW8gYXMgYSB3ZWIgcGxheWVyXG4gICAgICAgIGF3YWl0IHJlbmRlci5nYWxsZXJ5KHJlcywgc2hhcmUuYXNzZXRzLCAxKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBNdWx0aXBsZSBpbWFnZXMgLSByZW5kZXIgYXMgYSBnYWxsZXJ5XG4gICAgICBhd2FpdCByZW5kZXIuZ2FsbGVyeShyZXMsIHNoYXJlLmFzc2V0cylcbiAgICB9XG4gIH1cbn0pXG5cbi8vIE91dHB1dCB0aGUgYnVmZmVyIGRhdGEgZm9yIGFuIHBob3RvIG9yIHZpZGVvXG5hcHAuZ2V0KCcvOnR5cGUocGhvdG98dmlkZW8pLzppZCcsIChyZXEsIHJlcykgPT4ge1xuICBpZiAoIWltbWljaC5pc0lkKHJlcS5wYXJhbXMuaWQpKSB7XG4gICAgLy8gSW52YWxpZCBjaGFyYWN0ZXJzIGluIHRoZSBpbmNvbWluZyBVUkxcbiAgICByZXMuc3RhdHVzKDQwNCkuc2VuZCgpXG4gICAgcmV0dXJuXG4gIH1cbiAgY29uc3QgYXNzZXQgPSB7XG4gICAgaWQ6IHJlcS5wYXJhbXMuaWQsXG4gICAgdHlwZTogcmVxLnBhcmFtcy50eXBlID09PSAndmlkZW8nID8gQXNzZXRUeXBlLnZpZGVvIDogQXNzZXRUeXBlLmltYWdlXG4gIH1cbiAgc3dpdGNoIChyZXEucGFyYW1zLnR5cGUpIHtcbiAgICBjYXNlICdwaG90byc6XG4gICAgY2FzZSAndmlkZW8nOlxuICAgICAgcmVuZGVyLmFzc2V0QnVmZmVyKHJlcywgYXNzZXQsIGdldFNpemUocmVxKSkudGhlbigpXG4gICAgICBicmVha1xuICB9XG59KVxuXG5hcHAubGlzdGVuKDMwMDAsICgpID0+IHtcbiAgY29uc29sZS5sb2coZGF5anMoKS5mb3JtYXQoKSArICcgU2VydmVyIHN0YXJ0ZWQnKVxufSlcbiJdfQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsOERBQTZCO0FBQzdCLDhEQUE2QjtBQUM3Qiw4REFBNkI7QUFDN0IsMERBQXlCO0FBQ3pCLG1DQUE4QztBQUc5QyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUE7QUFFMUIsTUFBTSxHQUFHLEdBQUcsSUFBQSxpQkFBTyxHQUFFLENBQUE7QUFDckIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUE7QUFDN0IsR0FBRyxDQUFDLEdBQUcsQ0FBQyxpQkFBTyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFBO0FBRWpDLE1BQU0sT0FBTyxHQUFHLENBQUMsR0FBWSxFQUFFLEVBQUU7O0lBQy9CLE9BQU8sQ0FBQSxNQUFBLEdBQUcsYUFBSCxHQUFHLHVCQUFILEdBQUcsQ0FBRSxLQUFLLDBDQUFFLElBQUksTUFBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLGlCQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxpQkFBUyxDQUFDLFFBQVEsQ0FBQTtBQUNwRixDQUFDLENBQUE7QUFFRCxHQUFHLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFPLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtJQUN4QyxJQUFJLENBQUMsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ2xDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUE7SUFDeEIsQ0FBQztTQUFNLENBQUM7UUFDTixNQUFNLFVBQVUsR0FBRyxNQUFNLGdCQUFNLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDN0QsSUFBSSxDQUFDLFVBQVUsSUFB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SUFDcEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFBLGVBQUssR0FBRSxDQUFDLE1BQU0sRUFBRSxHQUFHLGlCQUFpQixDQUFDLENBQUE7QUFDbkQsQ0FBQyxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJ1xuaW1wb3J0IGltbWljaCBmcm9tICcuL2ltbWljaCdcbmltcG9ydCByZW5kZXIgZnJvbSAnLi9yZW5kZXInXG5pbXBvcnQgZGF5anMgZnJvbSAnZGF5anMnXG5pbXBvcnQgeyBBc3NldFR5cGUsIEltYWdlU2l6ZSB9IGZyb20gJy4vdHlwZXMnXG5pbXBvcnQgeyBSZXF1ZXN0IH0gZnJvbSAnZXhwcmVzcy1zZXJ2ZS1zdGF0aWMtY29yZSdcblxucmVxdWlyZSgnZG90ZW52JykuY29uZmlnKClcblxuY29uc3QgYXBwID0gZXhwcmVzcygpXG5hcHAuc2V0KCd2aWV3IGVuZ2luZScsICdlanMnKVxuYXBwLnVzZShleHByZXNzLnN0YXRpYygncHVibGljJykpXG5cbmNvbnN0IGdldFNpemUgPSAocmVxOiBSZXF1ZXN0KSA9PiB7XG4gIHJldHVybiByZXE/LnF1ZXJ5Py5zaXplID09PSAndGh1bWJuYWlsJyA/IEltYWdlU2l6ZS50aHVtYm5haWwgOiBJbWFnZVNpemUub3JpZ2luYWxcbn1cblxuYXBwLmdldCgnL3NoYXJlLzprZXknLCBhc3luYyAocmVxLCByZXMpID0+IHtcbiAgaWYgKCFpbW1pY2guaXNLZXkocmVxLnBhcmFtcy5rZXkpKSB7XG4gICAgcmVzLnN0YXR1cyg0MDQpLnNlbmQoKVxuICB9IGVsc2Uge1xuICAgIGNvbnN0IHNoYXJlZExpbmsgPSBhd2FpdCBpbW1pY2guZ2V0U2hhcmVCeUtleShyZXEucGFyYW1zLmtleSlcbiAgICBpZiAoIXNoYXJlZExpbmsgfHwgIXNoYXJlZExpbmsuYXNzZXRzLmxlbmd0aCkge1xuICAgICAgcmVzLnN0YXR1cyg0MDQpLnNlbmQoKVxuICAgIH0gZWxzZSBpZiAoc2hhcmVkTGluay5hc3NldHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAvLyBUaGlzIGlzIGFuIGluZGl2aWR1YWwgaXRlbSAobm90IGEgZ2FsbGVyeSlcbiAgICAgIGNvbnN0IGFzc2V0ID0gc2hhcmVkTGluay5hc3NldHNbMF1cbiAgICAgIGlmIChhc3NldC50eXBlID09PSBBc3NldFR5cGUuaW1hZ2UpIHtcbiAgICAgICAgLy8gRm9yIHBob3Rvcywgb3V0cHV0IHRoZSBpbWFnZSBkaXJlY3RseVxuICAgICAgICBhd2FpdCByZW5kZXIuYXNzZXRCdWZmZXIocmVzLCBzaGFyZWRMaW5rLmFzc2V0c1swXSwgZ2V0U2l6ZShyZXEpKVxuICAgICAgfSBlbHNlIGlmIChhc3NldC50eXBlID09PSBBc3NldFR5cGUudmlkZW8pIHtcbiAgICAgICAgLy8gRm9yIHZpZGVvcywgc2hvdyB0aGUgdmlkZW8gYXMgYSB3ZWIgcGxheWVyXG4gICAgICAgIGF3YWl0IHJlbmRlci5nYWxsZXJ5KHJlcywgc2hhcmVkTGluaywgMSlcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTXVsdGlwbGUgaW1hZ2VzIC0gcmVuZGVyIGFzIGEgZ2FsbGVyeVxuICAgICAgYXdhaXQgcmVuZGVyLmdhbGxlcnkocmVzLCBzaGFyZWRMaW5rKVxuICAgIH1cbiAgfVxufSlcblxuLy8gT3V0cHV0IHRoZSBidWZmZXIgZGF0YSBmb3IgYW4gcGhvdG8gb3IgdmlkZW9cbmFwcC5nZXQoJy86dHlwZShwaG90b3x2aWRlbykvOmtleS86aWQnLCBhc3luYyAocmVxLCByZXMpID0+IHtcbiAgLy8gQ2hlY2sgZm9yIHZhbGlkIGtleSBhbmQgSURcbiAgaWYgKGltbWljaC5pc0tleShyZXEucGFyYW1zLmtleSkgJiYgaW1taWNoLmlzSWQocmVxLnBhcmFtcy5pZCkpIHtcbiAgICAvLyBDaGVjayBpZiB0aGUga2V5IGlzIGEgdmFsaWQgc2hhcmUgbGlua1xuICAgIGNvbnN0IHNoYXJlZExpbmsgPSBhd2FpdCBpbW1pY2guZ2V0U2hhcmVCeUtleShyZXEucGFyYW1zLmtleSlcbiAgICBpZiAoc2hhcmVkTGluaz8uYXNzZXRzLmxlbmd0aCkge1xuICAgICAgLy8gQ2hlY2sgdGhhdCB0aGUgcmVxdWVzdGVkIGFzc2V0IGV4aXN0cyBpbiB0aGlzIHNoYXJlXG4gICAgICBjb25zdCBhc3NldCA9IHNoYXJlZExpbmsuYXNzZXRzLmZpbmQoeCA9PiB4LmlkID09PSByZXEucGFyYW1zLmlkKVxuICAgICAgaWYgKGFzc2V0KSB7XG4gICAgICAgIGFzc2V0LnR5cGUgPSByZXEucGFyYW1zLnR5cGUgPT09ICd2aWRlbycgPyBBc3NldFR5cGUudmlkZW8gOiBBc3NldFR5cGUuaW1hZ2VcbiAgICAgICAgcmVuZGVyLmFzc2V0QnVmZmVyKHJlcywgYXNzZXQsIGdldFNpemUocmVxKSkudGhlbigpXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXMuc3RhdHVzKDQwNCkuc2VuZCgpXG59KVxuXG4vLyBTZW5kIGEgNDA0IGZvciBhbGwgb3RoZXIgdW5tYXRjaGVkIHJvdXRlc1xuYXBwLmdldCgnKicsIChfcmVxLCByZXMpID0+IHtcbiAgcmVzLnN0YXR1cyg0MDQpLnNlbmQoKVxufSlcblxuYXBwLmxpc3RlbigzMDAwLCAoKSA9PiB7XG4gIGNvbnNvbGUubG9nKGRheWpzKCkuZm9ybWF0KCkgKyAnIFNlcnZlciBzdGFydGVkJylcbn0pXG4iXX0= \ No newline at end of file diff --git a/dist/render.js b/dist/render.js index 12cac94..c4bf711 100644 --- a/dist/render.js +++ b/dist/render.js @@ -20,17 +20,17 @@ class Render { } }); } - gallery(res, assets, openItem) { + gallery(res, share, openItem) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const items = []; - for (const asset of assets) { + for (const asset of share.assets) { let video; if (asset.type === types_1.AssetType.video) { // Populate the data-video property video = JSON.stringify({ source: [ { - src: immich_1.default.videoUrl(asset.id), + src: immich_1.default.videoUrl(share.key, asset.id), type: yield immich_1.default.getContentType(asset) } ], @@ -41,8 +41,8 @@ class Render { }); } items.push({ - originalUrl: immich_1.default.photoUrl(asset.id), - thumbnailUrl: immich_1.default.photoUrl(asset.id, types_1.ImageSize.thumbnail), + originalUrl: immich_1.default.photoUrl(share.key, asset.id), + thumbnailUrl: immich_1.default.photoUrl(share.key, asset.id, types_1.ImageSize.thumbnail), video }); } @@ -55,4 +55,4 @@ class Render { } const render = new Render(); exports.default = render; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JlbmRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw4REFBNkI7QUFFN0IsbUNBQXFEO0FBQ3JELDBEQUF5QjtBQUV6QixNQUFNLE1BQU07SUFDSixXQUFXLENBQUUsR0FBYSxFQUFFLEtBQVksRUFBRSxJQUFnQjs7WUFDOUQsTUFBTSxJQUFJLEdBQUcsTUFBTSxnQkFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUE7WUFDckQsSUFBSSxJQUFJLEVBQUUsQ0FBQztnQkFDVCxLQUFLLE1BQU0sTUFBTSxJQUFJLENBQUMsY0FBYyxFQUFFLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztvQkFDeEQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFBO2dCQUN2QyxDQUFDO2dCQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFBLGVBQUssR0FBRSxDQUFDLE1BQU0sRUFBRSxrQkFBa0IsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUE7Z0JBQzVELEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUE7WUFDakQsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUE7WUFDeEIsQ0FBQztRQUNILENBQUM7S0FBQTtJQUVLLE9BQU8sQ0FBRSxHQUFhLEVBQUUsTUFBZSxFQUFFLFFBQWlCOztZQUM5RCxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUE7WUFDaEIsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUUsQ0FBQztnQkFDM0IsSUFBSSxLQUFLLENBQUE7Z0JBQ1QsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLGlCQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQ25DLG1DQUFtQztvQkFDbkMsS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7d0JBQ3JCLE1BQU0sRUFBRTs0QkFDTjtnQ0FDRSxHQUFHLEVBQUUsZ0JBQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQ0FDOUIsSUFBSSxFQUFFLE1BQU0sZ0JBQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDOzZCQUN6Qzt5QkFDRjt3QkFDRCxVQUFVLEVBQUU7NEJBQ1YsT0FBTyxFQUFFLEtBQUs7NEJBQ2QsUUFBUSxFQUFFLElBQUk7eUJBQ2Y7cUJBQ0YsQ0FBQyxDQUFBO2dCQUNKLENBQUM7Z0JBQ0QsS0FBSyxDQUFDLElBQUksQ0FBQztvQkFDVCxXQUFXLEVBQUUsZ0JBQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztvQkFDdEMsWUFBWSxFQUFFLGdCQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsaUJBQVMsQ0FBQyxTQUFTLENBQUM7b0JBQzVELEtBQUs7aUJBQ04sQ0FBQyxDQUFBO1lBQ0osQ0FBQztZQUNELEdBQUcsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFO2dCQUNwQixLQUFLO2dCQUNMLFFBQVE7YUFDVCxDQUFDLENBQUE7UUFDSixDQUFDO0tBQUE7Q0FDRjtBQUVELE1BQU0sTUFBTSxHQUFHLElBQUksTUFBTSxFQUFFLENBQUE7QUFFM0Isa0JBQWUsTUFBTSxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGltbWljaCBmcm9tICcuL2ltbWljaCdcbmltcG9ydCB7IFJlc3BvbnNlIH0gZnJvbSAnZXhwcmVzcy1zZXJ2ZS1zdGF0aWMtY29yZSdcbmltcG9ydCB7IEFzc2V0LCBBc3NldFR5cGUsIEltYWdlU2l6ZSB9IGZyb20gJy4vdHlwZXMnXG5pbXBvcnQgZGF5anMgZnJvbSAnZGF5anMnXG5cbmNsYXNzIFJlbmRlciB7XG4gIGFzeW5jIGFzc2V0QnVmZmVyIChyZXM6IFJlc3BvbnNlLCBhc3NldDogQXNzZXQsIHNpemU/OiBJbWFnZVNpemUpIHtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgaW1taWNoLmdldEFzc2V0QnVmZmVyKGFzc2V0LCBzaXplKVxuICAgIGlmIChkYXRhKSB7XG4gICAgICBmb3IgKGNvbnN0IGhlYWRlciBvZiBbJ2NvbnRlbnQtdHlwZScsICdjb250ZW50LWxlbmd0aCddKSB7XG4gICAgICAgIHJlcy5zZXQoaGVhZGVyLCBkYXRhLmhlYWRlcnNbaGVhZGVyXSlcbiAgICAgIH1cbiAgICAgIGNvbnNvbGUubG9nKGAke2RheWpzKCkuZm9ybWF0KCl9IFNlcnZpbmcgYXNzZXQgJHthc3NldC5pZH1gKVxuICAgICAgcmVzLnNlbmQoQnVmZmVyLmZyb20oYXdhaXQgZGF0YS5hcnJheUJ1ZmZlcigpKSlcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzLnN0YXR1cyg0MDQpLnNlbmQoKVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdhbGxlcnkgKHJlczogUmVzcG9uc2UsIGFzc2V0czogQXNzZXRbXSwgb3Blbkl0ZW0/OiBudW1iZXIpIHtcbiAgICBjb25zdCBpdGVtcyA9IFtdXG4gICAgZm9yIChjb25zdCBhc3NldCBvZiBhc3NldHMpIHtcbiAgICAgIGxldCB2aWRlb1xuICAgICAgaWYgKGFzc2V0LnR5cGUgPT09IEFzc2V0VHlwZS52aWRlbykge1xuICAgICAgICAvLyBQb3B1bGF0ZSB0aGUgZGF0YS12aWRlbyBwcm9wZXJ0eVxuICAgICAgICB2aWRlbyA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBzb3VyY2U6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgc3JjOiBpbW1pY2gudmlkZW9VcmwoYXNzZXQuaWQpLFxuICAgICAgICAgICAgICB0eXBlOiBhd2FpdCBpbW1pY2guZ2V0Q29udGVudFR5cGUoYXNzZXQpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXSxcbiAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICBwcmVsb2FkOiBmYWxzZSxcbiAgICAgICAgICAgIGNvbnRyb2xzOiB0cnVlXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfVxuICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgIG9yaWdpbmFsVXJsOiBpbW1pY2gucGhvdG9VcmwoYXNzZXQuaWQpLFxuICAgICAgICB0aHVtYm5haWxVcmw6IGltbWljaC5waG90b1VybChhc3NldC5pZCwgSW1hZ2VTaXplLnRodW1ibmFpbCksXG4gICAgICAgIHZpZGVvXG4gICAgICB9KVxuICAgIH1cbiAgICByZXMucmVuZGVyKCdnYWxsZXJ5Jywge1xuICAgICAgaXRlbXMsXG4gICAgICBvcGVuSXRlbVxuICAgIH0pXG4gIH1cbn1cblxuY29uc3QgcmVuZGVyID0gbmV3IFJlbmRlcigpXG5cbmV4cG9ydCBkZWZhdWx0IHJlbmRlclxuIl19 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JlbmRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw4REFBNkI7QUFFN0IsbUNBQWlFO0FBQ2pFLDBEQUF5QjtBQUV6QixNQUFNLE1BQU07SUFDSixXQUFXLENBQUUsR0FBYSxFQUFFLEtBQVksRUFBRSxJQUFnQjs7WUFDOUQsTUFBTSxJQUFJLEdBQUcsTUFBTSxnQkFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUE7WUFDckQsSUFBSSxJQUFJLEVBQUUsQ0FBQztnQkFDVCxLQUFLLE1BQU0sTUFBTSxJQUFJLENBQUMsY0FBYyxFQUFFLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztvQkFDeEQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFBO2dCQUN2QyxDQUFDO2dCQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFBLGVBQUssR0FBRSxDQUFDLE1BQU0sRUFBRSxrQkFBa0IsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUE7Z0JBQzVELEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUE7WUFDakQsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUE7WUFDeEIsQ0FBQztRQUNILENBQUM7S0FBQTtJQUVLLE9BQU8sQ0FBRSxHQUFhLEVBQUUsS0FBaUIsRUFBRSxRQUFpQjs7WUFDaEUsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFBO1lBQ2hCLEtBQUssTUFBTSxLQUFLLElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNqQyxJQUFJLEtBQUssQ0FBQTtnQkFDVCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssaUJBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDbkMsbUNBQW1DO29CQUNuQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQzt3QkFDckIsTUFBTSxFQUFFOzRCQUNOO2dDQUNFLEdBQUcsRUFBRSxnQkFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0NBQ3pDLElBQUksRUFBRSxNQUFNLGdCQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQzs2QkFDekM7eUJBQ0Y7d0JBQ0QsVUFBVSxFQUFFOzRCQUNWLE9BQU8sRUFBRSxLQUFLOzRCQUNkLFFBQVEsRUFBRSxJQUFJO3lCQUNmO3FCQUNGLENBQUMsQ0FBQTtnQkFDSixDQUFDO2dCQUNELEtBQUssQ0FBQyxJQUFJLENBQUM7b0JBQ1QsV0FBVyxFQUFFLGdCQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztvQkFDakQsWUFBWSxFQUFFLGdCQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxpQkFBUyxDQUFDLFNBQVMsQ0FBQztvQkFDdkUsS0FBSztpQkFDTixDQUFDLENBQUE7WUFDSixDQUFDO1lBQ0QsR0FBRyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUU7Z0JBQ3BCLEtBQUs7Z0JBQ0wsUUFBUTthQUNULENBQUMsQ0FBQTtRQUNKLENBQUM7S0FBQTtDQUNGO0FBRUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxNQUFNLEVBQUUsQ0FBQTtBQUUzQixrQkFBZSxNQUFNLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgaW1taWNoIGZyb20gJy4vaW1taWNoJ1xuaW1wb3J0IHsgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzLXNlcnZlLXN0YXRpYy1jb3JlJ1xuaW1wb3J0IHsgQXNzZXQsIEFzc2V0VHlwZSwgSW1hZ2VTaXplLCBTaGFyZWRMaW5rIH0gZnJvbSAnLi90eXBlcydcbmltcG9ydCBkYXlqcyBmcm9tICdkYXlqcydcblxuY2xhc3MgUmVuZGVyIHtcbiAgYXN5bmMgYXNzZXRCdWZmZXIgKHJlczogUmVzcG9uc2UsIGFzc2V0OiBBc3NldCwgc2l6ZT86IEltYWdlU2l6ZSkge1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBpbW1pY2guZ2V0QXNzZXRCdWZmZXIoYXNzZXQsIHNpemUpXG4gICAgaWYgKGRhdGEpIHtcbiAgICAgIGZvciAoY29uc3QgaGVhZGVyIG9mIFsnY29udGVudC10eXBlJywgJ2NvbnRlbnQtbGVuZ3RoJ10pIHtcbiAgICAgICAgcmVzLnNldChoZWFkZXIsIGRhdGEuaGVhZGVyc1toZWFkZXJdKVxuICAgICAgfVxuICAgICAgY29uc29sZS5sb2coYCR7ZGF5anMoKS5mb3JtYXQoKX0gU2VydmluZyBhc3NldCAke2Fzc2V0LmlkfWApXG4gICAgICByZXMuc2VuZChCdWZmZXIuZnJvbShhd2FpdCBkYXRhLmFycmF5QnVmZmVyKCkpKVxuICAgIH0gZWxzZSB7XG4gICAgICByZXMuc3RhdHVzKDQwNCkuc2VuZCgpXG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ2FsbGVyeSAocmVzOiBSZXNwb25zZSwgc2hhcmU6IFNoYXJlZExpbmssIG9wZW5JdGVtPzogbnVtYmVyKSB7XG4gICAgY29uc3QgaXRlbXMgPSBbXVxuICAgIGZvciAoY29uc3QgYXNzZXQgb2Ygc2hhcmUuYXNzZXRzKSB7XG4gICAgICBsZXQgdmlkZW9cbiAgICAgIGlmIChhc3NldC50eXBlID09PSBBc3NldFR5cGUudmlkZW8pIHtcbiAgICAgICAgLy8gUG9wdWxhdGUgdGhlIGRhdGEtdmlkZW8gcHJvcGVydHlcbiAgICAgICAgdmlkZW8gPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgc291cmNlOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHNyYzogaW1taWNoLnZpZGVvVXJsKHNoYXJlLmtleSwgYXNzZXQuaWQpLFxuICAgICAgICAgICAgICB0eXBlOiBhd2FpdCBpbW1pY2guZ2V0Q29udGVudFR5cGUoYXNzZXQpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXSxcbiAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICBwcmVsb2FkOiBmYWxzZSxcbiAgICAgICAgICAgIGNvbnRyb2xzOiB0cnVlXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfVxuICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgIG9yaWdpbmFsVXJsOiBpbW1pY2gucGhvdG9Vcmwoc2hhcmUua2V5LCBhc3NldC5pZCksXG4gICAgICAgIHRodW1ibmFpbFVybDogaW1taWNoLnBob3RvVXJsKHNoYXJlLmtleSwgYXNzZXQuaWQsIEltYWdlU2l6ZS50aHVtYm5haWwpLFxuICAgICAgICB2aWRlb1xuICAgICAgfSlcbiAgICB9XG4gICAgcmVzLnJlbmRlcignZ2FsbGVyeScsIHtcbiAgICAgIGl0ZW1zLFxuICAgICAgb3Blbkl0ZW1cbiAgICB9KVxuICB9XG59XG5cbmNvbnN0IHJlbmRlciA9IG5ldyBSZW5kZXIoKVxuXG5leHBvcnQgZGVmYXVsdCByZW5kZXJcbiJdfQ== \ No newline at end of file diff --git a/src/immich.ts b/src/immich.ts index e784310..3fb11a1 100644 --- a/src/immich.ts +++ b/src/immich.ts @@ -1,6 +1,10 @@ import { Asset, AssetType, ImageSize, SharedLink } from './types' class Immich { + /** + * Make a request to Immich API. We're not using the SDK to limit + * the possible attack surface of this app. + */ async request (endpoint: string) { const res = await fetch(process.env.IMMICH_URL + '/api' + endpoint, { headers: { @@ -17,11 +21,22 @@ class Immich { } } + /** + * Query Immich for the SharedLink metadata for a given key. + * The key is what is returned in the URL when you create a share in Immich. + * Immich doesn't have a method to query by key, so this method gets all + * known shared links, and returns the link which matches the provided key. + */ async getShareByKey (key: string) { const res = (await this.request('/shared-links') || []) as SharedLink[] return res?.find(x => x.key === key) } + /** + * Stream asset buffer data from Immich. + * For photos, you can request 'thumbnail' or 'original' size. + * For videos, it is Immich's streaming quality, not the original quality. + */ async getAssetBuffer (asset: Asset, size?: ImageSize) { switch (asset.type) { case AssetType.image: @@ -32,22 +47,41 @@ class Immich { } } + /** + * Get the content-type of an Immich asset + */ async getContentType (asset: Asset) { const assetBuffer = await this.getAssetBuffer(asset) return assetBuffer.headers.get('Content-Type') } - photoUrl (id: string, size?: ImageSize) { - return `${process.env.SERVER_URL}/photo/${id}` + (size ? `?size=${size}` : '') + /** + * Return the image data URL for a photo + */ + photoUrl (key: string, id: string, size?: ImageSize) { + return `${process.env.SERVER_URL}/photo/${key}/${id}` + (size ? `?size=${size}` : '') } - videoUrl (id: string) { - return `${process.env.SERVER_URL}/video/${id}` + /** + * Return the video data URL for a video + */ + videoUrl (key: string, id: string) { + return `${process.env.SERVER_URL}/video/${key}/${id}` } + /** + * Check if a provided ID matches the Immich ID format + */ isId (id: string) { return !!id.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/) } + + /** + * Check if a provided key matches the Immich shared-link key format + */ + isKey (key: string) { + return !!key.match(/^[\w-]+$/) + } } const immich = new Immich() diff --git a/src/index.ts b/src/index.ts index cebd6bd..b088087 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,42 +16,46 @@ const getSize = (req: Request) => { } app.get('/share/:key', async (req, res) => { - if (req.params.key.match(/[^\w-]/)) { - // Invalid characters in the incoming URL + if (!immich.isKey(req.params.key)) { res.status(404).send() } else { - const share = await immich.getShareByKey(req.params.key) - if (!share || !share.assets.length) { + const sharedLink = await immich.getShareByKey(req.params.key) + if (!sharedLink || !sharedLink.assets.length) { res.status(404).send() - } else if (share.assets.length === 1) { + } else if (sharedLink.assets.length === 1) { // This is an individual item (not a gallery) - const asset = share.assets[0] + const asset = sharedLink.assets[0] if (asset.type === AssetType.image) { // For photos, output the image directly - await render.assetBuffer(res, share.assets[0], getSize(req)) + await render.assetBuffer(res, sharedLink.assets[0], getSize(req)) } else if (asset.type === AssetType.video) { // For videos, show the video as a web player - await render.gallery(res, share.assets, 1) + await render.gallery(res, sharedLink, 1) } } else { // Multiple images - render as a gallery - await render.gallery(res, share.assets) + await render.gallery(res, sharedLink) } } }) // Output the buffer data for an photo or video -app.get('/:type(photo|video)/:id', (req, res) => { - if (!immich.isId(req.params.id) || !['photo', 'video'].includes(req.params.type)) { - // Invalid characters in the incoming URL - res.status(404).send() - return +app.get('/:type(photo|video)/:key/:id', async (req, res) => { + // Check for valid key and ID + if (immich.isKey(req.params.key) && immich.isId(req.params.id)) { + // Check if the key is a valid share link + const sharedLink = await immich.getShareByKey(req.params.key) + 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(res, asset, getSize(req)).then() + return + } + } } - const asset = { - id: req.params.id, - type: req.params.type === 'video' ? AssetType.video : AssetType.image - } - render.assetBuffer(res, asset, getSize(req)).then() + res.status(404).send() }) // Send a 404 for all other unmatched routes diff --git a/src/render.ts b/src/render.ts index dcfac2e..f428ee1 100644 --- a/src/render.ts +++ b/src/render.ts @@ -1,6 +1,6 @@ import immich from './immich' import { Response } from 'express-serve-static-core' -import { Asset, AssetType, ImageSize } from './types' +import { Asset, AssetType, ImageSize, SharedLink } from './types' import dayjs from 'dayjs' class Render { @@ -17,16 +17,16 @@ class Render { } } - async gallery (res: Response, assets: Asset[], openItem?: number) { + async gallery (res: Response, share: SharedLink, openItem?: number) { const items = [] - for (const asset of assets) { + for (const asset of share.assets) { let video if (asset.type === AssetType.video) { // Populate the data-video property video = JSON.stringify({ source: [ { - src: immich.videoUrl(asset.id), + src: immich.videoUrl(share.key, asset.id), type: await immich.getContentType(asset) } ], @@ -37,8 +37,8 @@ class Render { }) } items.push({ - originalUrl: immich.photoUrl(asset.id), - thumbnailUrl: immich.photoUrl(asset.id, ImageSize.thumbnail), + originalUrl: immich.photoUrl(share.key, asset.id), + thumbnailUrl: immich.photoUrl(share.key, asset.id, ImageSize.thumbnail), video }) }