@helloample/netlify-plugin-redirects
Advanced tools
Comparing version 1.1.0 to 1.1.1
@@ -14,4 +14,19 @@ const branchName = require("current-git-branch"); | ||
toString() { | ||
if (this.origin === this.destination) { | ||
const trailingChar = (str) => str.slice(-1); | ||
const hasSlash = (str) => trailingChar(str) == "/"; | ||
const hasRole = () => this.status.includes("Role"); | ||
const hasSplat = () => trailingChar(this.origin) == "*"; | ||
const hasMatch = () => this.origin === this.destination; | ||
if (hasMatch() && hasRole() && hasSplat()) { | ||
return `${this.origin}\t${this.status}`; | ||
} else if (hasMatch() && hasRole() && !hasSplat()) { | ||
// if match + role + trailing slash... strip slashes | ||
let origin = hasSlash(this.origin) | ||
? this.origin.slice(0, -1) | ||
: this.origin; | ||
let destination = hasSlash(this.destination) | ||
? this.destination.slice(0, -1) | ||
: this.destination; | ||
return `${origin}\t${destination}\t${this.status}`; | ||
} else { | ||
@@ -23,9 +38,16 @@ return `${this.origin}\t${this.destination}\t${this.status}`; | ||
scrubString(str) { | ||
return this.encodeParams(this.replaceVars(str)); | ||
str = this.replaceVars(str); | ||
if (str.slice(0, 4) !== "http" && str[0] !== "/") { | ||
str = `/${str}`; | ||
} | ||
return this.encodeParams(str); | ||
} | ||
encodeParams(str) { | ||
const encode = (str) => { | ||
return str.split("&").map(this.encodeParam).join("&"); | ||
}; | ||
const matches = str.match(/([^\?]*)\?(.*)$/); | ||
if (matches) { | ||
return `${matches[1]}?${encodeURIComponent(matches[2])}`; | ||
return `${matches[1]}?${encode(matches[2])}`; | ||
} else { | ||
@@ -36,2 +58,16 @@ return str; | ||
encodeParam(str) { | ||
return str | ||
.split("=") | ||
.map((e, i) => { | ||
if (i == 1) { | ||
const unsafe = /[^a-zA-Z0-9-:=]/g; | ||
return e.replace(unsafe, (e) => encodeURIComponent(e)); | ||
} else { | ||
return e; | ||
} | ||
}) | ||
.join("="); | ||
} | ||
replaceVars(str) { | ||
@@ -38,0 +74,0 @@ const regex = /(\$\{env\:([^\}]*)\})/; |
{ | ||
"name": "@helloample/netlify-plugin-redirects", | ||
"version": "1.1.0", | ||
"version": "1.1.1", | ||
"description": "Read a CSV file, parse the rows and write them to `_redirects` _before_ Netlify processes your build.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -34,12 +34,2 @@ "use strict"; | ||
it("should return abbreviated rule if origin & destination are equal", () => { | ||
let destination = this.redirect.destination; | ||
this.redirect.destination = this.redirect.origin; | ||
assert.equal( | ||
this.redirect.toString(), | ||
"https://www.helloample.com/*\t301!" | ||
); | ||
this.redirect.destination = destination; | ||
}); | ||
it("should encode query string parameters", () => { | ||
@@ -51,5 +41,80 @@ this.redirect.destination = this.redirect.encodeParams( | ||
this.redirect.toString(), | ||
"https://www.helloample.com/*\thttps://ample.co/:splat?everThus%3D%2Fto-deadbeats\t301!" | ||
"https://www.helloample.com/*\thttps://ample.co/:splat?everThus=%2Fto-deadbeats\t301!" | ||
); | ||
}); | ||
describe("for role-based redirect rules", () => { | ||
let origOrigin, origDestination, origStatus; | ||
beforeEach(() => { | ||
origOrigin = this.redirect.origin; | ||
origDestination = this.redirect.destination; | ||
origStatus = this.redirect.status; | ||
this.redirect.status = "200! Role=user"; | ||
}); | ||
afterEach(() => { | ||
this.redirect.origin = origOrigin; | ||
this.redirect.destination = origDestination; | ||
this.redirect.status = origStatus; | ||
}); | ||
describe("with trailing wildcard character on origin", () => { | ||
before(() => { | ||
this.redirect.origin = "/something/*"; | ||
}); | ||
describe("and matching routes", () => { | ||
before(() => { | ||
this.redirect.destination = this.redirect.origin; | ||
}); | ||
it("should abbreviate return value", () => { | ||
assert.equal( | ||
this.redirect.toString(), | ||
"/something/*\t200! Role=user" | ||
); | ||
}); | ||
}); | ||
describe("and non-matching routes", () => { | ||
it("should not abbreviate return value", () => { | ||
this.redirect.destination = "https://www.ample.co/:splat"; | ||
assert.equal( | ||
this.redirect.toString(), | ||
"/something/*\thttps://www.ample.co/:splat\t200! Role=user" | ||
); | ||
}); | ||
}); | ||
}); | ||
describe("without trailing wildcard character on origin", () => { | ||
describe("and matching routes", () => { | ||
describe("with trailing slash", () => { | ||
before(() => { | ||
this.redirect.origin = "/something/"; | ||
this.redirect.destination = "/something/"; | ||
}); | ||
it("should not abbreviate return value AND should strip trailing slash from both paths", () => { | ||
assert.equal( | ||
this.redirect.toString(), | ||
"/something\t/something\t200! Role=user" | ||
); | ||
}); | ||
}); | ||
describe("without trailing slash", () => { | ||
before(() => { | ||
this.redirect.origin = "/something"; | ||
this.redirect.destination = "/something"; | ||
}); | ||
it("should not abbreviate return value", () => { | ||
assert.equal( | ||
this.redirect.toString(), | ||
"/something\t/something\t200! Role=user" | ||
); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
@@ -66,2 +131,15 @@ | ||
describe("#encodeParam()", () => { | ||
it("should only encode certain value chars in key/value pair", () => { | ||
assert.equal( | ||
this.redirect.encodeParam("everThus=/to-deadbeats"), | ||
"everThus=%2Fto-deadbeats" | ||
); | ||
assert.equal( | ||
this.redirect.encodeParam("groupIds=:groupIds/something"), | ||
"groupIds=:groupIds%2Fsomething" | ||
); | ||
}); | ||
}); | ||
describe("#encodeParams()", () => { | ||
@@ -71,5 +149,13 @@ it("should encode query string params", () => { | ||
this.redirect.encodeParams(`https://ample.com/?everThus=/to-deadbeats`), | ||
"https://ample.com/?everThus%3D%2Fto-deadbeats" | ||
"https://ample.com/?everThus=%2Fto-deadbeats" | ||
); | ||
}); | ||
it("should not encode common characters like colon-placeholder", () => { | ||
assert.equal( | ||
this.redirect.encodeParams( | ||
`/signin?redirectUrl=/group-renew&groupIds=:groupIds` | ||
), | ||
"/signin?redirectUrl=%2Fgroup-renew&groupIds=:groupIds" | ||
); | ||
}); | ||
}); | ||
@@ -122,2 +208,26 @@ | ||
}); | ||
describe("#scrubString", () => { | ||
it("should interpolate ENV variables", () => { | ||
process.env["TEMPORARY-STRING-FOR-TESTING"] = "https://ample.co"; | ||
assert.equal( | ||
this.redirect.scrubString("${env:TEMPORARY-STRING-FOR-TESTING}"), | ||
process.env["TEMPORARY-STRING-FOR-TESTING"] | ||
); | ||
delete process.env["TEMPORARY-STRING-FOR-TESTING"]; | ||
}); | ||
it("should encode params", () => { | ||
assert.equal( | ||
this.redirect.scrubString("/path?key=/value&something=:token"), | ||
"/path?key=%2Fvalue&something=:token" | ||
); | ||
}); | ||
it("should prepend forward-slash if not absolute URL", () => { | ||
assert.equal(this.redirect.scrubString("something"), "/something"); | ||
assert.equal( | ||
this.redirect.scrubString("https://ample.co"), | ||
"https://ample.co" | ||
); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
18557
423
24