Skip to content

Commit

Permalink
fix: PR changes
Browse files Browse the repository at this point in the history
  • Loading branch information
anku255 committed Jun 4, 2024
1 parent 2434230 commit 6756e33
Show file tree
Hide file tree
Showing 14 changed files with 133 additions and 42 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changes

- Fixed the session refresh loop in all the request interceptors that occurred when an API returned a 401 response despite a valid session. Interceptors now attempt to refresh the session a maximum of three times before returning the last API response. The retry limit is configurable via the `maxRetryAttemptsForSessionRefresh` option.
- Fixed the session refresh loop in all the request interceptors that occurred when an API returned a 401 response despite a valid session. Interceptors now attempt to refresh the session a maximum of ten times before throwing an error. The retry limit is configurable via the `maxRetryAttemptsForSessionRefresh` option.

## [20.0.1] - 2024-05-24

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

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion lib/build/axios.js

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

13 changes: 12 additions & 1 deletion lib/build/fetch.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/types.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/utils/index.js

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

27 changes: 21 additions & 6 deletions lib/build/xmlhttprequest.js

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

5 changes: 4 additions & 1 deletion lib/ts/axios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,10 @@ export default class AuthHttpRequest {
logDebugMessage(
`doRequest: Maximum session refresh attempts reached. sessionRefreshAttempts: ${config.__supertokensSessionRefreshAttempts}, maxRetryAttemptsForSessionRefresh: ${AuthHttpRequestFetch.config.maxRetryAttemptsForSessionRefresh}`
);
return response;

const errorMessage = `Received a 401 response from ${url}. Attempted to refresh the session and retry the request with the updated session tokens ${AuthHttpRequestFetch.config.maxRetryAttemptsForSessionRefresh} times, but each attempt resulted in a 401 error. The maximum session refresh limit has been reached. Please investigate your API. To increase the session refresh attempts, update maxRetryAttemptsForSessionRefresh in the config.`;
console.error(errorMessage);
throw new Error(errorMessage);
}

const refreshResult = await onUnauthorisedResponse(preRequestLSS);
Expand Down
5 changes: 4 additions & 1 deletion lib/ts/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,10 @@ export default class AuthHttpRequest {
logDebugMessage(
`doRequest: Maximum session refresh attempts reached. sessionRefreshAttempts: ${sessionRefreshAttempts}, maxRetryAttemptsForSessionRefresh: ${AuthHttpRequest.config.maxRetryAttemptsForSessionRefresh}`
);
return response;

const errorMessage = `Received a 401 response from ${url}. Attempted to refresh the session and retry the request with the updated session tokens ${AuthHttpRequest.config.maxRetryAttemptsForSessionRefresh} times, but each attempt resulted in a 401 error. The maximum session refresh limit has been reached. Please investigate your API. To increase the session refresh attempts, update maxRetryAttemptsForSessionRefresh in the config.`;
console.error(errorMessage);
throw new Error(errorMessage);
}

let retry = await onUnauthorisedResponse(preRequestLSS);
Expand Down
2 changes: 1 addition & 1 deletion lib/ts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export type InputType = {
* This specifies the maximum number of times the interceptor will attempt to refresh
* the session when a 401 Unauthorized response is received. If the number of retries
* exceeds this limit, no further attempts will be made to refresh the session, and
* the last response will be returned to the caller.
* and an error will be thrown.
*/
maxRetryAttemptsForSessionRefresh?: number;
tokenTransferMethod?: "cookie" | "header";
Expand Down
2 changes: 1 addition & 1 deletion lib/ts/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export function validateAndNormaliseInputOrThrowError(options: InputType): Norma
sessionTokenBackendDomain = normaliseSessionScopeOrThrowError(options.sessionTokenBackendDomain);
}

let maxRetryAttemptsForSessionRefresh = 3;
let maxRetryAttemptsForSessionRefresh = 10;
if (options.maxRetryAttemptsForSessionRefresh !== undefined) {
if (options.maxRetryAttemptsForSessionRefresh < 0) {
throw new Error("maxRetryAttemptsForSessionRefresh must be greater than or equal to 0.");
Expand Down
17 changes: 15 additions & 2 deletions lib/ts/xmlhttprequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,15 @@ export function addInterceptorsToXMLHttpRequest() {
logDebugMessage(
`XHRInterceptor.handleRetryPostRefreshing: Maximum session refresh attempts reached. sessionRefreshAttempts: ${sessionRefreshAttempts}, maxRetryAttemptsForSessionRefresh: ${AuthHttpRequestFetch.config.maxRetryAttemptsForSessionRefresh}`
);
return true;

// We set these values to prevent XHR from returning any response in this case. This simulates a network error in XHR.
customGetterValues["status"] = 0;
customGetterValues["statusText"] = "";
customGetterValues["responseType"] = "";

const errorMessage = `Received a 401 response from ${url}. Attempted to refresh the session and retry the request with the updated session tokens ${AuthHttpRequestFetch.config.maxRetryAttemptsForSessionRefresh} times, but each attempt resulted in a 401 error. The maximum session refresh limit has been reached. Please investigate your API. To increase the session refresh attempts, update maxRetryAttemptsForSessionRefresh in the config.`;
console.error(errorMessage);
throw new Error(errorMessage);
}

const refreshResult = await onUnauthorisedResponse(preRequestLSS);
Expand Down Expand Up @@ -240,7 +248,12 @@ export function addInterceptorsToXMLHttpRequest() {
} else {
// Here we only need to handle fetch related errors, from the refresh endpoint called by the retry
// So we should only get network level errors here
redispatchEvent("error", new Event("error"));

const ev = new Event("error");
(ev as any).error = err;
self.dispatchEvent(ev);

redispatchEvent("error", ev);
}
return true;
}
Expand Down
71 changes: 49 additions & 22 deletions test/cross.auto_refresh.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,12 @@ addTestCases((name, transferMethod, setupFunc, setupArgs = []) => {
await startST();
await setup();
await page.setRequestInterception(true);

let consoleLogs = [];
page.on("console", message => {
consoleLogs.push(message.text());
});

let count = 0;
page.on("request", req => {
const url = req.url();
Expand Down Expand Up @@ -704,24 +710,33 @@ addTestCases((name, transferMethod, setupFunc, setupArgs = []) => {
//check that the number of times the refreshAPI was called is 0
assert.strictEqual(await getNumberOfTimesRefreshCalled(), 0);

let getResponse = await toTest({ url: `${BASE_URL}/` });

assert.strictEqual(getResponse.statusCode, 401);
await assert.rejects(async () => {
await toTest({ url: `${BASE_URL}/` });
});

const numRefreshCalled = await getNumberOfTimesRefreshCalled();
assert.strictEqual(numRefreshCalled, 10);
});

assert.strictEqual(numRefreshCalled, 3);
assert(
consoleLogs.includes(
"Received a 401 response from http://localhost.org:8080/. Attempted to refresh the session and retry the request with the updated session tokens 10 times, but each attempt resulted in a 401 error. The maximum session refresh limit has been reached. Please investigate your API. To increase the session refresh attempts, update maxRetryAttemptsForSessionRefresh in the config."
)
);

// Check that the last response was returned
assert.strictEqual(JSON.parse(getResponse.responseText).count, numRefreshCalled + 1);
});
await page.setRequestInterception(false);
});

it("should break out of session refresh loop after configured maxRetryAttemptsForSessionRefresh value", async function () {
await startST();
await setup();
await page.setRequestInterception(true);

let consoleLogs = [];
page.on("console", message => {
consoleLogs.push(message.text());
});

let count = 0;
page.on("request", req => {
const url = req.url();
Expand All @@ -740,7 +755,7 @@ addTestCases((name, transferMethod, setupFunc, setupArgs = []) => {
await page.evaluate(async () => {
supertokens.init({
apiDomain: BASE_URL,
maxRetryAttemptsForSessionRefresh: 10
maxRetryAttemptsForSessionRefresh: 5
});

const userId = "testing-supertokens-website";
Expand All @@ -760,24 +775,33 @@ addTestCases((name, transferMethod, setupFunc, setupArgs = []) => {
//check that the number of times the refreshAPI was called is 0
assert.strictEqual(await getNumberOfTimesRefreshCalled(), 0);

let getResponse = await toTest({ url: `${BASE_URL}/` });

assert.strictEqual(getResponse.statusCode, 401);
await assert.rejects(async () => {
await toTest({ url: `${BASE_URL}/` });
});

const numRefreshCalled = await getNumberOfTimesRefreshCalled();
assert.strictEqual(numRefreshCalled, 5);
});

assert.strictEqual(numRefreshCalled, 10);
assert(
consoleLogs.includes(
"Received a 401 response from http://localhost.org:8080/. Attempted to refresh the session and retry the request with the updated session tokens 5 times, but each attempt resulted in a 401 error. The maximum session refresh limit has been reached. Please investigate your API. To increase the session refresh attempts, update maxRetryAttemptsForSessionRefresh in the config."
)
);

// Check that the last response was returned
assert.strictEqual(JSON.parse(getResponse.responseText).count, numRefreshCalled + 1);
});
await page.setRequestInterception(false);
});

it("should not do session refresh if maxRetryAttemptsForSessionRefresh is 0", async function () {
await startST();
await setup();
await page.setRequestInterception(true);

let consoleLogs = [];
page.on("console", message => {
consoleLogs.push(message.text());
});

let count = 0;
page.on("request", req => {
const url = req.url();
Expand Down Expand Up @@ -816,17 +840,20 @@ addTestCases((name, transferMethod, setupFunc, setupArgs = []) => {
//check that the number of times the refreshAPI was called is 0
assert.strictEqual(await getNumberOfTimesRefreshCalled(), 0);

let getResponse = await toTest({ url: `${BASE_URL}/` });

assert.strictEqual(getResponse.statusCode, 401);
await assert.rejects(async () => {
await toTest({ url: `${BASE_URL}/` });
});

const numRefreshCalled = await getNumberOfTimesRefreshCalled();

assert.strictEqual(numRefreshCalled, 0);

// Check that the last response was returned
assert.strictEqual(JSON.parse(getResponse.responseText).count, numRefreshCalled + 1);
});

assert(
consoleLogs.includes(
"Received a 401 response from http://localhost.org:8080/. Attempted to refresh the session and retry the request with the updated session tokens 0 times, but each attempt resulted in a 401 error. The maximum session refresh limit has been reached. Please investigate your API. To increase the session refresh attempts, update maxRetryAttemptsForSessionRefresh in the config."
)
);

await page.setRequestInterception(false);
});
});
Expand Down
Loading

0 comments on commit 6756e33

Please sign in to comment.