diff --git a/CHANGELOG.md b/CHANGELOG.md index 98487db4d..1f4e4c212 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [unreleased] -## [0.39.2] - 2024-04-10 +## [0.40.0] - 2024-04-15 ### Changes diff --git a/lib/build/genericComponentOverrideContext.js b/lib/build/genericComponentOverrideContext.js index 39bdd5968..c18ce954a 100644 --- a/lib/build/genericComponentOverrideContext.js +++ b/lib/build/genericComponentOverrideContext.js @@ -265,7 +265,7 @@ var SSR_ERROR = * License for the specific language governing permissions and limitations * under the License. */ -var package_version = "0.39.2"; +var package_version = "0.40.0"; /* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved. * diff --git a/lib/build/multifactorauth-shared.js b/lib/build/multifactorauth-shared.js index 649f695c2..4efa33a43 100644 --- a/lib/build/multifactorauth-shared.js +++ b/lib/build/multifactorauth-shared.js @@ -143,6 +143,11 @@ function compareRedirectionURLToCurrentURL(redirectURL) { // if the url is a full, valid url, we can use that fullRedirectURL = redirectURL; } catch (_a) { + // If we get here, we know it's not full url + // We check if it's an absolute path, because if it's not we know the redirection should always result in a new URL + if (!redirectURL.startsWith("/")) { + return false; + } var appInfo = genericComponentOverrideContext.SuperTokens.getInstanceOrThrow().appInfo; // otherwise we prepend the websiteDomain fullRedirectURL = "".concat(appInfo.websiteDomain.getAsStringDangerous()).concat(redirectURL); diff --git a/lib/build/version.d.ts b/lib/build/version.d.ts index 63e23b3b6..6dc2e7779 100644 --- a/lib/build/version.d.ts +++ b/lib/build/version.d.ts @@ -1 +1 @@ -export declare const package_version = "0.39.2"; +export declare const package_version = "0.40.0"; diff --git a/lib/ts/recipe/session/utils.ts b/lib/ts/recipe/session/utils.ts index 3f4f59733..b20350205 100644 --- a/lib/ts/recipe/session/utils.ts +++ b/lib/ts/recipe/session/utils.ts @@ -101,6 +101,11 @@ export function compareRedirectionURLToCurrentURL(redirectURL: string): boolean // if the url is a full, valid url, we can use that fullRedirectURL = redirectURL; } catch { + // If we get here, we know it's not full url + // We check if it's an absolute path, because if it's not we know the redirection should always result in a new URL + if (!redirectURL.startsWith("/")) { + return false; + } const appInfo = SuperTokens.getInstanceOrThrow().appInfo; // otherwise we prepend the websiteDomain fullRedirectURL = `${appInfo.websiteDomain.getAsStringDangerous()}${redirectURL}`; diff --git a/lib/ts/version.ts b/lib/ts/version.ts index 394138156..ec81fec84 100644 --- a/lib/ts/version.ts +++ b/lib/ts/version.ts @@ -12,4 +12,4 @@ * License for the specific language governing permissions and limitations * under the License. */ -export const package_version = "0.39.2"; +export const package_version = "0.40.0"; diff --git a/package-lock.json b/package-lock.json index 96216b711..293345c30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "supertokens-auth-react", - "version": "0.39.2", + "version": "0.40.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "supertokens-auth-react", - "version": "0.39.2", + "version": "0.40.0", "license": "Apache-2.0", "dependencies": { "intl-tel-input": "^17.0.19", diff --git a/package.json b/package.json index 54791b744..80e0c0d5d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "supertokens-auth-react", - "version": "0.39.2", + "version": "0.40.0", "description": "ReactJS SDK that provides login functionality with SuperTokens.", "main": "./index.js", "engines": { diff --git a/test/end-to-end/signin-rrdv6.test.js b/test/end-to-end/signin-rrdv6.test.js index bb424572e..108d0be9c 100644 --- a/test/end-to-end/signin-rrdv6.test.js +++ b/test/end-to-end/signin-rrdv6.test.js @@ -608,6 +608,36 @@ describe("SuperTokens SignIn with react router dom v6", function () { ]); }); + it("Should redirect to onFailureRedirections result if it's a relative path", async function () { + await Promise.all([ + page.goto( + `${TEST_CLIENT_BASE_URL}/auth?redirectToPath=${encodeURIComponent("/dashboard?test=value#asdf")}` + ), + page.waitForNavigation({ waitUntil: "networkidle0" }), + ]); + + // Set correct values. + await setInputValues(page, [ + { name: "email", value: "john.doe@supertokens.io" }, + { name: "password", value: "Str0ngP@ssw0rd" }, + ]); + await Promise.all([ + submitFormReturnRequestAndResponse(page, SIGN_IN_API), + page.waitForNavigation({ waitUntil: "networkidle0" }), + ]); + + await page.evaluate(() => { + const validator = window.UserRoleClaim.validators.includes("admin"); + validator.onFailureRedirection = () => "second-factor"; + window.setClaimValidators([validator]); + }); + + await page.waitForNavigation({ waitUntil: "networkidle0" }); + + let href = await page.evaluate(() => window.location.pathname); + assert.strictEqual(href, "/dashboard/second-factor"); + }); + it("Should redirect to onFailureRedirections result if it's on another domain", async function () { await Promise.all([ page.goto(`${TEST_CLIENT_BASE_URL}/auth`),