Skip to content

Commit

Permalink
chore: update release process
Browse files Browse the repository at this point in the history
  • Loading branch information
cirocfc committed Feb 14, 2022
1 parent 90e93cf commit 771153b
Show file tree
Hide file tree
Showing 9 changed files with 910 additions and 172 deletions.
Binary file removed .DS_Store
Binary file not shown.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v16
v14
1 change: 1 addition & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('@ca-tools-front/prettier-config');
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "A url sanitizer",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"author": "",
"author": "DOMPhysis <[email protected]>",
"files": [
"dist/*",
"src/index.ts",
Expand All @@ -28,8 +28,8 @@
},
"homepage": "https://github.com/contaazul/sanitize-url#readme",
"devDependencies": {
"@ca-tools-front/release-it-plugin-build": "^2.4.8",
"@ca-tools-front/release-it-plugin-sonar": "^2.4.8",
"@ca-tools-front/prettier-config": "^3.0.0",
"@ca-tools-front/release-it-config": "^3.1.2",
"@rollup/plugin-typescript": "^8.3.0",
"@types/jest": "^27.4.0",
"@typescript-eslint/eslint-plugin": "^5.9.0",
Expand Down
26 changes: 4 additions & 22 deletions release-it.config.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,4 @@
/* eslint-disable no-template-curly-in-string */
module.exports = {
git: {
tagName: "v${version}",
commitMessage: "chore: version ${version}",
pushRepo: "[email protected]:ContaAzul/ca-components.git",
requireCleanWorkingDir: false, // for now
requireUpstream: false,
},
github: {
release: true,
releaseName: "v${version}",
tokenRef: "GITHUB_TOKEN",
},
npm: {
publish: false,
},
plugins: {
"@ca-tools-front/release-it-plugin-build": {},
"@ca-tools-front/release-it-plugin-sonar": {},
},
};
/* eslint-disable @typescript-eslint/no-var-requires */
const { config } = require('@ca-tools-front/release-it-config');

module.exports = config({ commitPreset: 'compact' });
18 changes: 9 additions & 9 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { terser } from "rollup-plugin-terser";
import typescript from "@rollup/plugin-typescript";
import { terser } from 'rollup-plugin-terser';
import typescript from '@rollup/plugin-typescript';

export default {
input: "src/index.ts",
input: 'src/index.ts',
output: [
{
compact: true,
file: "dist/index.js",
format: "umd",
name: "sanitize-url",
file: 'dist/index.js',
format: 'umd',
name: 'sanitize-url',
},
{
compact: true,
file: "dist/index.min.js",
format: "umd",
name: "sanitize-url",
file: 'dist/index.min.js',
format: 'umd',
name: 'sanitize-url',
plugins: [terser()],
},
],
Expand Down
150 changes: 57 additions & 93 deletions src/__tests__/test.ts
Original file line number Diff line number Diff line change
@@ -1,174 +1,138 @@
/* eslint-disable no-script-url */
import { sanitizeUrl } from "..";
import { sanitizeUrl } from '..';

describe("sanitizeUrl", () => {
it("does not alter http URLs with alphanumeric characters", () => {
expect(sanitizeUrl("http://example.com/path/to:something")).toBe(
"http://example.com/path/to:something"
);
describe('sanitizeUrl', () => {
it('does not alter http URLs with alphanumeric characters', () => {
expect(sanitizeUrl('http://example.com/path/to:something')).toBe('http://example.com/path/to:something');
});

it("does not alter http URLs with ports with alphanumeric characters", () => {
expect(sanitizeUrl("http://example.com:4567/path/to:something")).toBe(
"http://example.com:4567/path/to:something"
);
it('does not alter http URLs with ports with alphanumeric characters', () => {
expect(sanitizeUrl('http://example.com:4567/path/to:something')).toBe('http://example.com:4567/path/to:something');
});

it("does not alter https URLs with alphanumeric characters", () => {
expect(sanitizeUrl("https://example.com")).toBe("https://example.com");
it('does not alter https URLs with alphanumeric characters', () => {
expect(sanitizeUrl('https://example.com')).toBe('https://example.com');
});

it("does not alter https URLs with ports with alphanumeric characters", () => {
expect(sanitizeUrl("https://example.com:4567/path/to:something")).toBe(
"https://example.com:4567/path/to:something"
it('does not alter https URLs with ports with alphanumeric characters', () => {
expect(sanitizeUrl('https://example.com:4567/path/to:something')).toBe(
'https://example.com:4567/path/to:something',
);
});

it("does not alter relative-path reference URLs with alphanumeric characters", () => {
expect(sanitizeUrl("./path/to/my.json")).toBe("./path/to/my.json");
it('does not alter relative-path reference URLs with alphanumeric characters', () => {
expect(sanitizeUrl('./path/to/my.json')).toBe('./path/to/my.json');
});

it("does not alter absolute-path reference URLs with alphanumeric characters", () => {
expect(sanitizeUrl("/path/to/my.json")).toBe("/path/to/my.json");
it('does not alter absolute-path reference URLs with alphanumeric characters', () => {
expect(sanitizeUrl('/path/to/my.json')).toBe('/path/to/my.json');
});

it("does not alter protocol-less network-path URLs with alphanumeric characters", () => {
expect(sanitizeUrl("//google.com/robots.txt")).toBe(
"//google.com/robots.txt"
);
it('does not alter protocol-less network-path URLs with alphanumeric characters', () => {
expect(sanitizeUrl('//google.com/robots.txt')).toBe('//google.com/robots.txt');
});

it("does not alter protocol-less URLs with alphanumeric characters", () => {
expect(sanitizeUrl("www.example.com")).toBe("www.example.com");
it('does not alter protocol-less URLs with alphanumeric characters', () => {
expect(sanitizeUrl('www.example.com')).toBe('www.example.com');
});

it("does not alter deep-link urls with alphanumeric characters", () => {
expect(sanitizeUrl("com.braintreepayments.demo://example")).toBe(
"com.braintreepayments.demo://example"
);
it('does not alter deep-link urls with alphanumeric characters', () => {
expect(sanitizeUrl('com.braintreepayments.demo://example')).toBe('com.braintreepayments.demo://example');
});

it("does not alter mailto urls with alphanumeric characters", () => {
expect(sanitizeUrl("mailto:[email protected]?subject=hello+world")).toBe(
"mailto:[email protected]?subject=hello+world"
it('does not alter mailto urls with alphanumeric characters', () => {
expect(sanitizeUrl('mailto:[email protected]?subject=hello+world')).toBe(
'mailto:[email protected]?subject=hello+world',
);
});

it("does not alter urls with accented characters", () => {
expect(sanitizeUrl("www.example.com/with-áccêntš")).toBe(
"www.example.com/with-áccêntš"
);
it('does not alter urls with accented characters', () => {
expect(sanitizeUrl('www.example.com/with-áccêntš')).toBe('www.example.com/with-áccêntš');
});

it("does not strip harmless unicode characters", () => {
expect(sanitizeUrl("www.example.com/лот.рфшишкиü–")).toBe(
"www.example.com/лот.рфшишкиü–"
);
it('does not strip harmless unicode characters', () => {
expect(sanitizeUrl('www.example.com/лот.рфшишкиü–')).toBe('www.example.com/лот.рфшишкиü–');
});

it("strips out ctrl chars", () => {
expect(
sanitizeUrl("www.example.com/\u200D\u0000\u001F\x00\x1F\uFEFFfoo")
).toBe("www.example.com/foo");
it('strips out ctrl chars', () => {
expect(sanitizeUrl('www.example.com/\u200D\u0000\u001F\x00\x1F\uFEFFfoo')).toBe('www.example.com/foo');
});

it("replaces blank urls with about:blank", () => {
expect(sanitizeUrl("")).toBe("about:blank");
it('replaces blank urls with about:blank', () => {
expect(sanitizeUrl('')).toBe('about:blank');
});

it("replaces null values with about:blank", () => {
it('replaces null values with about:blank', () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
expect(sanitizeUrl(null)).toBe("about:blank");
expect(sanitizeUrl(null)).toBe('about:blank');
});

it("replaces undefined values with about:blank", () => {
expect(sanitizeUrl()).toBe("about:blank");
it('replaces undefined values with about:blank', () => {
expect(sanitizeUrl()).toBe('about:blank');
});

it("removes whitespace from urls", () => {
expect(sanitizeUrl(" http://example.com/path/to:something ")).toBe(
"http://example.com/path/to:something"
);
it('removes whitespace from urls', () => {
expect(sanitizeUrl(' http://example.com/path/to:something ')).toBe('http://example.com/path/to:something');
});

describe("invalid protocols", () => {
describe.each(["javascript", "data", "vbscript"])("%s", (protocol) => {
describe('invalid protocols', () => {
describe.each(['javascript', 'data', 'vbscript'])('%s', protocol => {
it(`replaces ${protocol} urls with about:blank`, () => {
expect(sanitizeUrl(`${protocol}:alert(document.domain)`)).toBe(
"about:blank"
);
expect(sanitizeUrl(`${protocol}:alert(document.domain)`)).toBe('about:blank');
});

it(`allows ${protocol} urls that start with a letter prefix`, () => {
expect(sanitizeUrl(`not_${protocol}:alert(document.domain)`)).toBe(
`not_${protocol}:alert(document.domain)`
);
expect(sanitizeUrl(`not_${protocol}:alert(document.domain)`)).toBe(`not_${protocol}:alert(document.domain)`);
});

it(`disallows ${protocol} urls that start with non-\w characters as a suffix for the protocol`, () => {
expect(sanitizeUrl(`&!*${protocol}:alert(document.domain)`)).toBe(
"about:blank"
);
expect(sanitizeUrl(`&!*${protocol}:alert(document.domain)`)).toBe('about:blank');
});

it(`disregards capitalization for ${protocol} urls`, () => {
// upper case every other letter in protocol name
const mixedCapitalizationProtocol = protocol
.split("")
.split('')
.map((character, index) => {
if (index % 2 === 0) {
return character.toUpperCase();
}
return character;
})
.join("");
.join('');

expect(
sanitizeUrl(`${mixedCapitalizationProtocol}:alert(document.domain)`)
).toBe("about:blank");
expect(sanitizeUrl(`${mixedCapitalizationProtocol}:alert(document.domain)`)).toBe('about:blank');
});

it(`ignores invisible ctrl characters in ${protocol} urls`, () => {
const protocolWithControlCharacters = protocol
.split("")
.split('')
.map((character, index) => {
if (index === 1) {
return character + "%EF%BB%BF%EF%BB%BF";
return character + '%EF%BB%BF%EF%BB%BF';
} else if (index === 2) {
return character + "%e2%80%8b";
return character + '%e2%80%8b';
}
return character;
})
.join("");

expect(
sanitizeUrl(
decodeURIComponent(
`${protocolWithControlCharacters}:alert(document.domain)`
)
)
).toBe("about:blank");
.join('');

expect(sanitizeUrl(decodeURIComponent(`${protocolWithControlCharacters}:alert(document.domain)`))).toBe(
'about:blank',
);
});

it(`replaces ${protocol} urls with about:blank when url begins with %20`, () => {
expect(
sanitizeUrl(
decodeURIComponent(`%20%20%20%20${protocol}:alert(document.domain)`)
)
).toBe("about:blank");
expect(sanitizeUrl(decodeURIComponent(`%20%20%20%20${protocol}:alert(document.domain)`))).toBe('about:blank');
});

it(`replaces ${protocol} urls with about:blank when ${protocol} url begins with spaces`, () => {
expect(sanitizeUrl(` ${protocol}:alert(document.domain)`)).toBe(
"about:blank"
);
expect(sanitizeUrl(` ${protocol}:alert(document.domain)`)).toBe('about:blank');
});

it(`does not replace ${protocol}: if it is not in the scheme of the URL`, () => {
expect(sanitizeUrl(`http://example.com#${protocol}:foo`)).toBe(
`http://example.com#${protocol}:foo`
);
expect(sanitizeUrl(`http://example.com#${protocol}:foo`)).toBe(`http://example.com#${protocol}:foo`);
});
});
});
Expand Down
11 changes: 5 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
const invalidProtocolRegex = /^([^\w]*)(javascript|data|vbscript)/im;
const ctrlCharactersRegex =
/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim;
const ctrlCharactersRegex = /[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim;
const urlSchemeRegex = /^([^:]+):/gm;
const relativeFirstCharacters = [".", "/"];
const relativeFirstCharacters = ['.', '/'];

function isRelativeUrlWithoutProtocol(url: string): boolean {
return relativeFirstCharacters.indexOf(url[0]) > -1;
}

export function sanitizeUrl(url?: string): string {
if (!url) {
return "about:blank";
return 'about:blank';
}

const sanitizedUrl = url.replace(ctrlCharactersRegex, "").trim();
const sanitizedUrl = url.replace(ctrlCharactersRegex, '').trim();

if (isRelativeUrlWithoutProtocol(sanitizedUrl)) {
return sanitizedUrl;
Expand All @@ -28,7 +27,7 @@ export function sanitizeUrl(url?: string): string {
const urlScheme = urlSchemeParseResults[0];

if (invalidProtocolRegex.test(urlScheme)) {
return "about:blank";
return 'about:blank';
}

return sanitizedUrl;
Expand Down
Loading

0 comments on commit 771153b

Please sign in to comment.