feat: Add imgproxy signer service

- imgproxy-signer.mjs: 图片代理签名服务
This commit is contained in:
john
2026-06-27 08:25:27 +08:00
parent 3bb5d21425
commit da239bdf09
+53
View File
@@ -0,0 +1,53 @@
import crypto from 'node:crypto';
export function createImgproxySigner(key, salt) {
const keyBuf = Buffer.from(key, 'hex');
const saltBuf = Buffer.from(salt, 'hex');
function signPath(path) {
const signaturePayload = Buffer.concat([saltBuf, Buffer.from(path)]);
const signature = crypto.createHmac('sha256', keyBuf).update(signaturePayload).digest();
const signatureB64 = signature.toString('base64url');
return `/${signatureB64}${path}`;
}
function buildUrl(baseUrl, storagePath, preset = 'display') {
if (!baseUrl || !storagePath) {
throw new Error('baseUrl and storagePath are required');
}
let width, height, quality, format;
switch (preset) {
case 'vision':
width = 768;
height = 768;
quality = 60;
format = 'jpg';
break;
case 'thumb':
width = 256;
height = 256;
quality = 70;
format = 'jpg';
break;
case 'display':
default:
width = 1280;
height = 1280;
quality = 85;
format = 'jpg';
break;
}
const encodedPath = encodeURIComponent(`local://${storagePath}`);
const unsignedPath = `/unsafe/${width}x${height}/${quality}/${format}/${encodedPath}`;
const signedPath = signPath(unsignedPath);
const baseUrlNormalized = String(baseUrl).replace(/\/$/, '');
return `${baseUrlNormalized}${signedPath}`;
}
return { buildUrl, signPath };
}
export default createImgproxySigner;