Skip to content

Commit 5e264de

Browse files
ankur-dwivediANKUR DWIVEDI
andauthored
fix: updated signed url generations for urls with symbols and unicode characters (#102)
* fix url for ' * added test cases * remove log * update version * update version * update version * remove codecov --------- Co-authored-by: ANKUR DWIVEDI <[email protected]>
1 parent ff88b20 commit 5e264de

File tree

4 files changed

+89
-26
lines changed

4 files changed

+89
-26
lines changed

.github/workflows/nodejs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ jobs:
2323
yarn install
2424
yarn test
2525
yarn test-e2e
26-
yarn report-coverage
26+
# yarn report-coverage
2727
env:
2828
CI: true

libs/url/builder.ts

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
Helper Modules
33
*/
4-
import url, { UrlWithStringQuery, URLSearchParams } from "url";
4+
import { URLSearchParams, URL } from "url";
55
import path from "path";
66
import crypto from "crypto";
77

@@ -38,32 +38,21 @@ export const encodeStringIfRequired = (str: string) => {
3838
}
3939

4040
const buildURL = function (opts: FinalUrlOptions): string {
41-
//Create correct query parameters
42-
var parsedURL: UrlWithStringQuery;
43-
var parsedHost: UrlWithStringQuery;
4441
var isSrcParameterUsedForURL: boolean = false;
4542

46-
var urlObject: { [key: string]: string | null } = { host: "", pathname: "", search: "" };
43+
var urlObject: URL;
4744

4845
if (opts.path) {
49-
parsedURL = url.parse(opts.path);
50-
parsedHost = url.parse(opts.urlEndpoint);
51-
52-
urlObject.protocol = parsedHost.protocol;
53-
urlObject.host = opts.urlEndpoint.replace(urlObject.protocol + "//", "");
46+
urlObject = new URL(opts.urlEndpoint)
5447
} else if (opts.src) {
55-
parsedURL = url.parse(opts.src);
5648
isSrcParameterUsedForURL = true;
57-
58-
urlObject.host = [parsedURL.auth, parsedURL.auth ? "@" : "", parsedURL.host].join("");
59-
urlObject.protocol = parsedURL.protocol;
49+
urlObject = new URL(opts.src)
6050
} else {
6151
return "";
6252
}
6353

64-
urlObject.pathname = parsedURL.pathname ? parsedURL.pathname : "";
6554

66-
var queryParameters = new URLSearchParams(parsedURL.query || "");
55+
var queryParameters = new URLSearchParams(urlObject.search || "");
6756
for (var i in opts.queryParameters) {
6857
queryParameters.set(i, opts.queryParameters[i]);
6958
}
@@ -75,13 +64,18 @@ const buildURL = function (opts: FinalUrlOptions): string {
7564
//string should be added only as a query parameter
7665
if (transformationUtils.addAsQueryParameter(opts) || isSrcParameterUsedForURL) {
7766
queryParameters.set(TRANSFORMATION_PARAMETER, transformationString);
67+
urlObject.pathname= `${urlObject.pathname}${opts.path||''}`;
7868
} else {
7969
urlObject.pathname = path.posix.join(
80-
[TRANSFORMATION_PARAMETER, transformationString].join(transformationUtils.getChainTransformDelimiter()),
8170
urlObject.pathname,
71+
[TRANSFORMATION_PARAMETER, transformationString].join(transformationUtils.getChainTransformDelimiter()),
72+
opts.path || '',
8273
);
8374
}
8475
}
76+
else{
77+
urlObject.pathname= `${urlObject.pathname}${opts.path||''}`;
78+
}
8579

8680
urlObject.host = urlFormatter.removeTrailingSlash(urlObject.host);
8781
urlObject.pathname = urlFormatter.addLeadingSlash(urlObject.pathname);
@@ -107,7 +101,7 @@ const buildURL = function (opts: FinalUrlOptions): string {
107101
expiryTimestamp = DEFAULT_TIMESTAMP;
108102
}
109103

110-
var intermediateURL = url.format(urlObject);
104+
var intermediateURL = urlObject.href;
111105

112106
var urlSignature = getSignature({
113107
privateKey: opts.privateKey,
@@ -122,8 +116,7 @@ const buildURL = function (opts: FinalUrlOptions): string {
122116
queryParameters.set(SIGNATURE_PARAMETER, urlSignature);
123117
urlObject.search = queryParameters.toString();
124118
}
125-
126-
return url.format(urlObject);
119+
return urlObject.href;
127120
};
128121

129122
function constructTransformationString(inputTransformation: Array<Transformation> | undefined) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "imagekit",
3-
"version": "5.2.0",
3+
"version": "5.2.1",
44
"description": "Offical NodeJS SDK for ImageKit.io integration",
55
"main": "./dist/index.js",
66
"types": "./dist/index.d.ts",

tests/url-generation.js

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ describe("URL generation", function () {
7474
path: "/test_é_path_alt.jpg",
7575
signed: true,
7676
});
77-
expect(url).equal(`https://ik.imagekit.io/test_url_endpoint/test_é_path_alt.jpg?ik-s=${signature}`);
77+
expect(url).equal(`https://ik.imagekit.io/test_url_endpoint/test_%C3%A9_path_alt.jpg?ik-s=${signature}`);
7878
});
7979

8080
it("Signed URL with é in filename and path", function () {
@@ -91,7 +91,7 @@ describe("URL generation", function () {
9191
path: "/aéb/test_é_path_alt.jpg",
9292
signed: true,
9393
});
94-
expect(url).equal(`https://ik.imagekit.io/test_url_endpoint/aéb/test_é_path_alt.jpg?ik-s=${signature}`);
94+
expect(url).equal(`https://ik.imagekit.io/test_url_endpoint/a%C3%A9b/test_%C3%A9_path_alt.jpg?ik-s=${signature}`);
9595
});
9696

9797
it("Signed URL with é in filename, path and transformation as path", function () {
@@ -112,7 +112,7 @@ describe("URL generation", function () {
112112
transformationPosition: "path",
113113
});
114114
expect(url).equal(
115-
`https://ik.imagekit.io/test_url_endpoint/tr:l-text,i-Imagekité,fs-50,l-end/aéb/test_é_path_alt.jpg?ik-s=${signature}`
115+
`https://ik.imagekit.io/test_url_endpoint/tr:l-text,i-Imagekit%C3%A9,fs-50,l-end/a%C3%A9b/test_%C3%A9_path_alt.jpg?ik-s=${signature}`
116116
);
117117
});
118118

@@ -133,7 +133,7 @@ describe("URL generation", function () {
133133
transformationPosition: "query",
134134
});
135135
expect(url).equal(
136-
`https://ik.imagekit.io/test_url_endpoint/aéb/test_é_path_alt.jpg?tr=l-text%2Ci-Imagekit%C3%A9%2Cfs-50%2Cl-end&ik-s=${signature}`
136+
`https://ik.imagekit.io/test_url_endpoint/a%C3%A9b/test_%C3%A9_path_alt.jpg?tr=l-text%2Ci-Imagekit%C3%A9%2Cfs-50%2Cl-end&ik-s=${signature}`
137137
);
138138
});
139139

@@ -333,6 +333,76 @@ describe("URL generation", function () {
333333
expect(url).equal(`https://ik.imagekit.io/test_url_endpoint/tr:di-test_path.jpg/test_path1.jpg`);
334334
});
335335

336+
it("Signed URL with ' in filename", function () {
337+
const testURL = "https://ik.imagekit.io/test_url_endpoint/test_'_path_alt.jpg";
338+
const signature = getSignature({
339+
privateKey: "test_private_key",
340+
url: testURL,
341+
urlEndpoint: "https://ik.imagekit.io/test_url_endpoint",
342+
expiryTimestamp: "9999999999",
343+
});
344+
const url = imagekit.url({
345+
path: "/test_'_path_alt.jpg",
346+
signed: true,
347+
});
348+
expect(url).equal(`https://ik.imagekit.io/test_url_endpoint/test_'_path_alt.jpg?ik-s=${signature}`);
349+
});
350+
351+
it("Signed URL with ' in filename and path", function () {
352+
const testURL = "https://ik.imagekit.io/test_url_endpoint/a'b/test_'_path_alt.jpg";
353+
const signature = getSignature({
354+
privateKey: "test_private_key",
355+
url: testURL,
356+
urlEndpoint: "https://ik.imagekit.io/test_url_endpoint",
357+
expiryTimestamp: "9999999999",
358+
});
359+
const url = imagekit.url({
360+
path: "/a'b/test_'_path_alt.jpg",
361+
signed: true,
362+
});
363+
expect(url).equal(`https://ik.imagekit.io/test_url_endpoint/a'b/test_'_path_alt.jpg?ik-s=${signature}`);
364+
});
365+
366+
it("Signed URL with ' in filename, path and transformation as path", function () {
367+
const testURL = "https://ik.imagekit.io/test_url_endpoint/tr:l-text,i-Imagekit',fs-50,l-end/a'b/test_'_path_alt.jpg";
368+
const signature = getSignature({
369+
privateKey: "test_private_key",
370+
url: testURL,
371+
urlEndpoint: "https://ik.imagekit.io/test_url_endpoint",
372+
expiryTimestamp: "9999999999",
373+
});
374+
375+
const url = imagekit.url({
376+
path: "/a'b/test_'_path_alt.jpg",
377+
signed: true,
378+
transformation: [{ raw: "l-text,i-Imagekit',fs-50,l-end" }],
379+
transformationPosition: "path",
380+
});
381+
expect(url).equal(
382+
`https://ik.imagekit.io/test_url_endpoint/tr:l-text,i-Imagekit',fs-50,l-end/a'b/test_'_path_alt.jpg?ik-s=${signature}`
383+
);
384+
});
385+
386+
it("Signed URL with ' in filename, path and transformation as query", function () {
387+
const testURL = "https://ik.imagekit.io/test_url_endpoint/a'b/test_'_path_alt.jpg?tr=l-text%2Ci-Imagekit%27%2Cfs-50%2Cl-end";
388+
const signature = getSignature({
389+
privateKey: "test_private_key",
390+
url: testURL,
391+
urlEndpoint: "https://ik.imagekit.io/test_url_endpoint",
392+
expiryTimestamp: "9999999999",
393+
});
394+
const url = imagekit.url({
395+
path: "/a'b/test_'_path_alt.jpg",
396+
signed: true,
397+
transformation: [{ raw: "l-text,i-Imagekit',fs-50,l-end" }],
398+
transformationPosition: "query",
399+
});
400+
expect(url).equal(
401+
`https://ik.imagekit.io/test_url_endpoint/a'b/test_'_path_alt.jpg?tr=l-text%2Ci-Imagekit%27%2Cfs-50%2Cl-end&ik-s=${signature}`
402+
);
403+
});
404+
405+
336406
it('All combined', function () {
337407
const url = imagekit.url({
338408
path: "/test_path.jpg",

0 commit comments

Comments
 (0)