@websolutespa/bom-mixer-image 1.8.3 → 1.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/index.js +20 -10
- package/dist/index.mjs +20 -10
- package/package.json +1 -1
- package/src/image/image.handler.ts +27 -34
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -100,10 +100,7 @@ function imageHandler({
|
|
|
100
100
|
response.setHeader("Cache-Control", `public, max-age=${IMAGE_MAX_AGE}`);
|
|
101
101
|
return response.send(cachedImage);
|
|
102
102
|
}
|
|
103
|
-
|
|
104
|
-
const referer = headers.referer;
|
|
105
|
-
const publicUrl = process.env.NEXT_PUBLIC_URL || "";
|
|
106
|
-
if (referer && publicUrl !== "https://" && referer.indexOf(publicUrl) !== 0) {
|
|
103
|
+
if (isInvalidReferer(request)) {
|
|
107
104
|
return response.status(401).send("you are not authorized to perform this action");
|
|
108
105
|
}
|
|
109
106
|
if (imageOptions.url.indexOf("http") === -1 && isVercel()) {
|
|
@@ -135,6 +132,15 @@ function imageHandler({
|
|
|
135
132
|
}
|
|
136
133
|
});
|
|
137
134
|
}
|
|
135
|
+
function isInvalidReferer(request) {
|
|
136
|
+
const { headers } = request;
|
|
137
|
+
const referer = headers.referer;
|
|
138
|
+
const publicUrl = process.env.NEXT_PUBLIC_URL || "";
|
|
139
|
+
if (IMAGE_STRATEGY !== import_bom_core.ImageStrategy.Token && referer && publicUrl !== "https://" && referer.indexOf(publicUrl) !== 0) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
138
144
|
function getImageOptions(request, options) {
|
|
139
145
|
const { slugs, origin = "", search = "", w, h, x, y, q } = request.query;
|
|
140
146
|
if (!Array.isArray(slugs) || slugs.length === 0) {
|
|
@@ -183,9 +189,10 @@ function getEncryptedImageOptions(request, options) {
|
|
|
183
189
|
throw "missing t parameter";
|
|
184
190
|
}
|
|
185
191
|
const imageResize = (0, import_bom_core.decryptImageResize)(t);
|
|
186
|
-
|
|
192
|
+
imageResize.src = decodeURIComponent(imageResize.src);
|
|
193
|
+
const url = decodeURIComponent(origin + "/" + slugs.join("/") + search);
|
|
187
194
|
if (imageResize.src !== url) {
|
|
188
|
-
throw
|
|
195
|
+
throw `invalid src parameter ${imageResize.src} ${url}`;
|
|
189
196
|
}
|
|
190
197
|
return {
|
|
191
198
|
...imageResize,
|
|
@@ -245,10 +252,10 @@ async function resizeImage(originalImage, imageOptions) {
|
|
|
245
252
|
return defaultResizeOptions();
|
|
246
253
|
}
|
|
247
254
|
}
|
|
248
|
-
function getOriginalImage(url, domains, headers
|
|
255
|
+
function getOriginalImage(url, domains, headers) {
|
|
249
256
|
return new Promise((resolve, reject) => {
|
|
250
257
|
if (url.indexOf("http") === 0) {
|
|
251
|
-
if (
|
|
258
|
+
if (isInvalidDomain(url, domains)) {
|
|
252
259
|
return reject({ status: 401, message: "invalid origin" });
|
|
253
260
|
}
|
|
254
261
|
fetch(url, {
|
|
@@ -311,9 +318,12 @@ function urlToCachedName(options) {
|
|
|
311
318
|
const cachedName = options.h ? path.join(cacheDir, `${parsedName.name}_w_${options.w}_h_${options.h || 0}_x_${options.x || IMAGE_FOCAL_X}_y_${options.y || IMAGE_FOCAL_Y}_q_${options.q}${parsedName.ext}`) : path.join(cacheDir, `${parsedName.name}_w_${options.w}_q_${options.q}${parsedName.ext}`);
|
|
312
319
|
return cachedName;
|
|
313
320
|
}
|
|
314
|
-
function
|
|
321
|
+
function isInvalidDomain(src, domains) {
|
|
322
|
+
if (IMAGE_STRATEGY === import_bom_core.ImageStrategy.Token) {
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
315
325
|
const url = new URL(src);
|
|
316
|
-
return domains.includes(url.hostname);
|
|
326
|
+
return !domains.includes(url.hostname);
|
|
317
327
|
}
|
|
318
328
|
// Annotate the CommonJS export names for ESM import in node:
|
|
319
329
|
0 && (module.exports = {
|
package/dist/index.mjs
CHANGED
|
@@ -64,10 +64,7 @@ function imageHandler({
|
|
|
64
64
|
response.setHeader("Cache-Control", `public, max-age=${IMAGE_MAX_AGE}`);
|
|
65
65
|
return response.send(cachedImage);
|
|
66
66
|
}
|
|
67
|
-
|
|
68
|
-
const referer = headers.referer;
|
|
69
|
-
const publicUrl = process.env.NEXT_PUBLIC_URL || "";
|
|
70
|
-
if (referer && publicUrl !== "https://" && referer.indexOf(publicUrl) !== 0) {
|
|
67
|
+
if (isInvalidReferer(request)) {
|
|
71
68
|
return response.status(401).send("you are not authorized to perform this action");
|
|
72
69
|
}
|
|
73
70
|
if (imageOptions.url.indexOf("http") === -1 && isVercel()) {
|
|
@@ -99,6 +96,15 @@ function imageHandler({
|
|
|
99
96
|
}
|
|
100
97
|
});
|
|
101
98
|
}
|
|
99
|
+
function isInvalidReferer(request) {
|
|
100
|
+
const { headers } = request;
|
|
101
|
+
const referer = headers.referer;
|
|
102
|
+
const publicUrl = process.env.NEXT_PUBLIC_URL || "";
|
|
103
|
+
if (IMAGE_STRATEGY !== ImageStrategy.Token && referer && publicUrl !== "https://" && referer.indexOf(publicUrl) !== 0) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
102
108
|
function getImageOptions(request, options) {
|
|
103
109
|
const { slugs, origin = "", search = "", w, h, x, y, q } = request.query;
|
|
104
110
|
if (!Array.isArray(slugs) || slugs.length === 0) {
|
|
@@ -147,9 +153,10 @@ function getEncryptedImageOptions(request, options) {
|
|
|
147
153
|
throw "missing t parameter";
|
|
148
154
|
}
|
|
149
155
|
const imageResize = decryptImageResize(t);
|
|
150
|
-
|
|
156
|
+
imageResize.src = decodeURIComponent(imageResize.src);
|
|
157
|
+
const url = decodeURIComponent(origin + "/" + slugs.join("/") + search);
|
|
151
158
|
if (imageResize.src !== url) {
|
|
152
|
-
throw
|
|
159
|
+
throw `invalid src parameter ${imageResize.src} ${url}`;
|
|
153
160
|
}
|
|
154
161
|
return {
|
|
155
162
|
...imageResize,
|
|
@@ -209,10 +216,10 @@ async function resizeImage(originalImage, imageOptions) {
|
|
|
209
216
|
return defaultResizeOptions();
|
|
210
217
|
}
|
|
211
218
|
}
|
|
212
|
-
function getOriginalImage(url, domains, headers
|
|
219
|
+
function getOriginalImage(url, domains, headers) {
|
|
213
220
|
return new Promise((resolve, reject) => {
|
|
214
221
|
if (url.indexOf("http") === 0) {
|
|
215
|
-
if (
|
|
222
|
+
if (isInvalidDomain(url, domains)) {
|
|
216
223
|
return reject({ status: 401, message: "invalid origin" });
|
|
217
224
|
}
|
|
218
225
|
fetch(url, {
|
|
@@ -275,9 +282,12 @@ function urlToCachedName(options) {
|
|
|
275
282
|
const cachedName = options.h ? path.join(cacheDir, `${parsedName.name}_w_${options.w}_h_${options.h || 0}_x_${options.x || IMAGE_FOCAL_X}_y_${options.y || IMAGE_FOCAL_Y}_q_${options.q}${parsedName.ext}`) : path.join(cacheDir, `${parsedName.name}_w_${options.w}_q_${options.q}${parsedName.ext}`);
|
|
276
283
|
return cachedName;
|
|
277
284
|
}
|
|
278
|
-
function
|
|
285
|
+
function isInvalidDomain(src, domains) {
|
|
286
|
+
if (IMAGE_STRATEGY === ImageStrategy.Token) {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
279
289
|
const url = new URL(src);
|
|
280
|
-
return domains.includes(url.hostname);
|
|
290
|
+
return !domains.includes(url.hostname);
|
|
281
291
|
}
|
|
282
292
|
export {
|
|
283
293
|
imageHandler
|
package/package.json
CHANGED
|
@@ -72,15 +72,7 @@ export function imageHandler({
|
|
|
72
72
|
return response.send(cachedImage);
|
|
73
73
|
}
|
|
74
74
|
// Check referrer
|
|
75
|
-
|
|
76
|
-
const referer = headers.referer;
|
|
77
|
-
const publicUrl = process.env.NEXT_PUBLIC_URL || '';
|
|
78
|
-
// console.log('referef', referer, 'publicUrl', publicUrl);
|
|
79
|
-
if (
|
|
80
|
-
referer &&
|
|
81
|
-
publicUrl !== 'https://' &&
|
|
82
|
-
referer.indexOf(publicUrl) !== 0
|
|
83
|
-
) {
|
|
75
|
+
if (isInvalidReferer(request)) {
|
|
84
76
|
return response.status(401).send('you are not authorized to perform this action');
|
|
85
77
|
}
|
|
86
78
|
// Temporarily fix Vercel local image issue
|
|
@@ -129,6 +121,22 @@ export function imageHandler({
|
|
|
129
121
|
});
|
|
130
122
|
}
|
|
131
123
|
|
|
124
|
+
function isInvalidReferer(request: NextApiRequest): boolean {
|
|
125
|
+
const { headers } = request;
|
|
126
|
+
const referer = headers.referer;
|
|
127
|
+
const publicUrl = process.env.NEXT_PUBLIC_URL || '';
|
|
128
|
+
// console.log('referef', referer, 'publicUrl', publicUrl, 'IMAGE_STRATEGY', IMAGE_STRATEGY, ImageStrategy.Token);
|
|
129
|
+
if (
|
|
130
|
+
IMAGE_STRATEGY !== ImageStrategy.Token &&
|
|
131
|
+
referer &&
|
|
132
|
+
publicUrl !== 'https://' &&
|
|
133
|
+
referer.indexOf(publicUrl) !== 0
|
|
134
|
+
) {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
|
|
132
140
|
function getImageOptions(request: NextApiRequest, options: IImageHandlerOptions): IImageOptions {
|
|
133
141
|
// Destructuring 'slugs', 'origin', 'search', 'w', 'h', 'x', 'y', 'q' from the request query
|
|
134
142
|
const { slugs, origin = '', search = '', w, h, x, y, q } = request.query;
|
|
@@ -211,11 +219,12 @@ function getEncryptedImageOptions(request: NextApiRequest, options: IImageHandle
|
|
|
211
219
|
throw 'invalid q parameter';
|
|
212
220
|
}
|
|
213
221
|
*/
|
|
222
|
+
imageResize.src = decodeURIComponent(imageResize.src);
|
|
214
223
|
// Generating url
|
|
215
|
-
const url = origin + '/' + slugs.join('/') + search;
|
|
224
|
+
const url = decodeURIComponent(origin + '/' + slugs.join('/') + search);
|
|
216
225
|
//
|
|
217
226
|
if (imageResize.src !== url) {
|
|
218
|
-
throw
|
|
227
|
+
throw `invalid src parameter ${imageResize.src} ${url}`;
|
|
219
228
|
}
|
|
220
229
|
//
|
|
221
230
|
return {
|
|
@@ -285,16 +294,12 @@ async function resizeImage(originalImage: sharp.Sharp, imageOptions: IImageOptio
|
|
|
285
294
|
}
|
|
286
295
|
|
|
287
296
|
// Defining the 'getOriginalImage' function
|
|
288
|
-
function getOriginalImage(url: string, domains: string[], headers: IncomingHttpHeaders
|
|
297
|
+
function getOriginalImage(url: string, domains: string[], headers: IncomingHttpHeaders): Promise<Buffer> {
|
|
289
298
|
// Returning a new promise
|
|
290
299
|
return new Promise((resolve, reject) => {
|
|
291
300
|
// Checking if 'url' starts with 'http'
|
|
292
301
|
if (url.indexOf('http') === 0) {
|
|
293
|
-
if (
|
|
294
|
-
!skipUrlValidity &&
|
|
295
|
-
!checkUrlValidity(url, domains)
|
|
296
|
-
) {
|
|
297
|
-
// console.error('imageHandler.getOriginalImage.error invalid origin');
|
|
302
|
+
if (isInvalidDomain(url, domains)) {
|
|
298
303
|
return reject({ status: 401, message: 'invalid origin' });
|
|
299
304
|
}
|
|
300
305
|
// Fetching the image from the URL
|
|
@@ -330,21 +335,6 @@ function getOriginalImage(url: string, domains: string[], headers: IncomingHttpH
|
|
|
330
335
|
// Resolving the promise with the image data
|
|
331
336
|
return resolve(data);
|
|
332
337
|
});
|
|
333
|
-
/*
|
|
334
|
-
// Check if the file exists
|
|
335
|
-
if (fs.existsSync(filePath)) {
|
|
336
|
-
fs.readFile(filePath, (error, data) => {
|
|
337
|
-
if (error) {
|
|
338
|
-
return reject(error);
|
|
339
|
-
}
|
|
340
|
-
// Resolving the promise with the image data
|
|
341
|
-
return resolve(data);
|
|
342
|
-
});
|
|
343
|
-
} else {
|
|
344
|
-
const origin = getOrigin(headers);
|
|
345
|
-
return getOriginalImage(`${origin}${url}`, domains, headers, true);
|
|
346
|
-
}
|
|
347
|
-
*/
|
|
348
338
|
}
|
|
349
339
|
});
|
|
350
340
|
}
|
|
@@ -407,7 +397,10 @@ function urlToCachedName(options: IImageOptions): string {
|
|
|
407
397
|
return cachedName;
|
|
408
398
|
}
|
|
409
399
|
|
|
410
|
-
function
|
|
400
|
+
function isInvalidDomain(src: string, domains: string[]): boolean {
|
|
401
|
+
if (IMAGE_STRATEGY === ImageStrategy.Token) {
|
|
402
|
+
return false;
|
|
403
|
+
}
|
|
411
404
|
const url = new URL(src);
|
|
412
|
-
return domains.includes(url.hostname);
|
|
405
|
+
return !domains.includes(url.hostname);
|
|
413
406
|
}
|