Skip to content

Commit

Permalink
fix: shouldDoInterceptionBasedOnUrl returns true for any valid subdom…
Browse files Browse the repository at this point in the history
…ains of the url
  • Loading branch information
anku255 committed May 3, 2024
1 parent 2b3aba8 commit 2d8b55b
Show file tree
Hide file tree
Showing 13 changed files with 92 additions and 22 deletions.
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [unreleased]

## [20.0.0] - 2024-04-03

### Breaking changes

- The `shouldDoInterceptionBasedOnUrl` function now returns true if `sessionTokenBackendDomain` is a valid subdomain of the URL's domain. This aligns with the behavior of browsers when sending cookies to subdomains.

**Before:**

```javascript
shouldDoInterceptionBasedOnUrl("https://sub.api.example.com", "", "api.example.com") // false
shouldDoInterceptionBasedOnUrl("https://sub.api.example.com", "", ".api.example.com") // true
shouldDoInterceptionBasedOnUrl("https://sub.api.example.com", "", "example.com") // false
shouldDoInterceptionBasedOnUrl("https://sub.api.example.com", "", ".example.com") // true
```

**After:**

```javascript
shouldDoInterceptionBasedOnUrl("https://sub.api.example.com", "", "api.example.com") // true
shouldDoInterceptionBasedOnUrl("https://sub.api.example.com", "", ".api.example.com") // true
shouldDoInterceptionBasedOnUrl("https://sub.api.example.com", "", "example.com") // true
shouldDoInterceptionBasedOnUrl("https://sub.api.example.com", "", ".example.com") // true
```

The behavior in previous versions differed, as `shouldDoInterceptionBasedOnUrl` returned `false` unless `sessionTokenBackendDomain` had an explicit leading dot. This breaking change now assumes any subdomain is valid, making the interception consistent with browser cookie policies.

## [19.0.1] - 2024-03-18
- Fixes test server

Expand Down
2 changes: 1 addition & 1 deletion bundle/bundle.js

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions lib/build/recipeImplementation.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions lib/build/utils/index.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion lib/build/utils/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/build/version.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/build/version.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 2 additions & 6 deletions lib/ts/recipeImplementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { supported_fdi } from "./version";
import { logDebugMessage } from "./logger";
import { STGeneralError } from "./error";
import { addInterceptorsToXMLHttpRequest } from "./xmlhttprequest";
import { normaliseSessionScopeOrThrowError, normaliseURLDomainOrThrowError } from "./utils";
import { matchesDomainOrSubdomain, normaliseSessionScopeOrThrowError, normaliseURLDomainOrThrowError } from "./utils";
import DateProviderReference from "./utils/dateProvider";

export default function RecipeImplementation(recipeImplInput: {
Expand Down Expand Up @@ -303,11 +303,7 @@ export default function RecipeImplementation(recipeImplInput: {
domain = urlObj.port === "" ? domain : domain + ":" + urlObj.port;
}
}
if (sessionTokenBackendDomain.startsWith(".")) {
return ("." + domain).endsWith(normalisedsessionDomain);
} else {
return domain === normalisedsessionDomain;
}
return matchesDomainOrSubdomain(domain, normalisedsessionDomain);
}
},

Expand Down
20 changes: 20 additions & 0 deletions lib/ts/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,23 @@ export function getNormalisedUserContext(userContext?: any): any {

return userContext;
}

/**
* Checks if a given string matches any subdomain or the main domain of a specified hostname.
*
* @param {string} hostname - The hostname to derive subdomains from.
* @param {string} str - The string to compare against the subdomains.
* @returns {boolean} True if the string matches any subdomain or the main domain, otherwise false.
*/
export function matchesDomainOrSubdomain(hostname: string, str: string): boolean {
const parts = hostname.split(".");

for (let i = 0; i < parts.length; i++) {
const subdomainCandidate = parts.slice(i).join(".");
if (subdomainCandidate === str || `.${subdomainCandidate}` === str) {
return true;
}
}

return false;
}
2 changes: 1 addition & 1 deletion lib/ts/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
export const package_version = "19.0.1";
export const package_version = "20.0.0";

export const supported_fdi = ["1.16", "1.17", "1.18", "1.19"];
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "supertokens-website",
"version": "19.0.1",
"version": "20.0.0",
"description": "frontend sdk for website to be used for auth solution.",
"main": "index.js",
"dependencies": {
Expand Down
11 changes: 8 additions & 3 deletions test/config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,22 @@ describe("Config tests", function () {
assert(shouldDoInterceptionBasedOnUrl("api.example.com", "", "api.example.com"));
assert(shouldDoInterceptionBasedOnUrl("http://api.example.com", "", "http://api.example.com"));
assert(shouldDoInterceptionBasedOnUrl("api.example.com", "", ".example.com"));
assert(shouldDoInterceptionBasedOnUrl("api.example.com", "", "example.com"));
assert(shouldDoInterceptionBasedOnUrl("https://api.example.com", "", "http://api.example.com"));
assert(shouldDoInterceptionBasedOnUrl("https://api.example.com", "", "https://api.example.com"));
assert(shouldDoInterceptionBasedOnUrl("https://sub.api.example.com", "", ".sub.api.example.com"));
assert(shouldDoInterceptionBasedOnUrl("https://sub.api.example.com", "", "sub.api.example.com"));
assert(shouldDoInterceptionBasedOnUrl("https://sub.api.example.com", "", ".api.example.com"));
assert(shouldDoInterceptionBasedOnUrl("https://sub.api.example.com", "", "api.example.com"));
assert(shouldDoInterceptionBasedOnUrl("https://sub.api.example.com", "", ".example.com"));
assert(shouldDoInterceptionBasedOnUrl("https://sub.api.example.com", "", "example.com"));
assert(shouldDoInterceptionBasedOnUrl("https://sub.api.example.com:3000", "", ".example.com:3000"));
assert(shouldDoInterceptionBasedOnUrl("https://sub.api.example.com:3000", "", "example.com:3000"));
assert(shouldDoInterceptionBasedOnUrl("https://sub.api.example.com:3000", "", ".example.com"));
assert(shouldDoInterceptionBasedOnUrl("https://sub.api.example.com:3000", "", "example.com"));
assert(shouldDoInterceptionBasedOnUrl("https://sub.api.example.com:3000", "", "https://sub.api.example.com"));
assert(shouldDoInterceptionBasedOnUrl("https://api.example.com:3000", "", ".api.example.com"));
assert(shouldDoInterceptionBasedOnUrl("https://api.example.com:3000", "", "api.example.com"));
assert(shouldDoInterceptionBasedOnUrl("localhost:3000", "", "localhost:3000"));
assert(shouldDoInterceptionBasedOnUrl("https://localhost:3000", "", ".localhost:3000"));
assert(shouldDoInterceptionBasedOnUrl("localhost", "", "localhost"));
Expand Down Expand Up @@ -112,15 +120,12 @@ describe("Config tests", function () {

// false cases with cookieDomain
assert(!shouldDoInterceptionBasedOnUrl("https://sub.api.example.com:3000", "", ".example.com:3001"));
assert(!shouldDoInterceptionBasedOnUrl("https://sub.api.example.com:3000", "", "example.com"));
assert(!shouldDoInterceptionBasedOnUrl("https://api.example.com:3000", "", ".a.api.example.com"));
assert(!shouldDoInterceptionBasedOnUrl("https://sub.api.example.com:3000", "", "localhost"));
assert(!shouldDoInterceptionBasedOnUrl("http://127.0.0.1:3000", "", "https://127.0.0.1:3010"));
assert(!shouldDoInterceptionBasedOnUrl(window.location.hostname, "", "localhost"));
assert(!shouldDoInterceptionBasedOnUrl(window.location.hostname, "", ".localhost"));
assert(!shouldDoInterceptionBasedOnUrl(window.location.hostname, "", "localhost:2000"));
assert(!shouldDoInterceptionBasedOnUrl("https://sub.api.example.co.uk:3000", "", "api.example.co.uk"));
assert(!shouldDoInterceptionBasedOnUrl("https://sub.api.example.co.uk", "", "api.example.co.uk"));

// errors in input
try {
Expand Down

0 comments on commit 2d8b55b

Please sign in to comment.