fix: fixes issue where a renewed session would in some cases would not save to disk, causing a reauthentication prompt to occur
This commit is contained in:
@@ -99,7 +99,12 @@ export class HttpService implements HttpServiceInterface {
|
||||
}
|
||||
|
||||
async runHttp<T>(httpRequest: HttpRequest): Promise<HttpResponse<T>> {
|
||||
if (this.inProgressRefreshSessionPromise) {
|
||||
if (this.__latencySimulatorMs) {
|
||||
await sleep(this.__latencySimulatorMs, true)
|
||||
}
|
||||
|
||||
const isRefreshRequest = httpRequest.url === joinPaths(this.host, Paths.v1.refreshSession)
|
||||
if (this.inProgressRefreshSessionPromise && !isRefreshRequest) {
|
||||
await this.inProgressRefreshSessionPromise
|
||||
|
||||
httpRequest.authentication = this.session?.accessToken.value
|
||||
@@ -107,17 +112,13 @@ export class HttpService implements HttpServiceInterface {
|
||||
|
||||
const request = this.createXmlRequest(httpRequest)
|
||||
|
||||
if (this.__latencySimulatorMs) {
|
||||
await sleep(this.__latencySimulatorMs, true)
|
||||
}
|
||||
|
||||
const response = await this.runRequest<T>(request, this.createRequestBody(httpRequest))
|
||||
|
||||
if (response.meta) {
|
||||
this.updateMetaCallback?.(response.meta)
|
||||
}
|
||||
|
||||
if (response.status === HttpStatusCode.ExpiredAccessToken) {
|
||||
if (response.status === HttpStatusCode.ExpiredAccessToken && !isRefreshRequest) {
|
||||
if (this.inProgressRefreshSessionPromise) {
|
||||
await this.inProgressRefreshSessionPromise
|
||||
} else {
|
||||
|
||||
@@ -105,6 +105,28 @@ describe('server session', function () {
|
||||
expect(sessionAfterSync.accessToken.expiresAt).to.be.greaterThan(Date.now())
|
||||
})
|
||||
|
||||
it('should not deadlock while renewing session', async function () {
|
||||
this.timeout(Factory.TwentySecondTimeout)
|
||||
|
||||
await Factory.registerUserToApplication({
|
||||
application: this.application,
|
||||
email: this.email,
|
||||
password: this.password,
|
||||
})
|
||||
|
||||
await sleepUntilSessionExpires(this.application)
|
||||
|
||||
// Apply a latency simulation so that ` this.inProgressRefreshSessionPromise = this.refreshSession()` does
|
||||
// not have the chance to complete before it is assigned to the variable. This test came along with a fix
|
||||
// where runHttp does not await a pending refreshSession promise if the request being made is itself a refreshSession request.
|
||||
this.application.httpService.__latencySimulatorMs = 1000
|
||||
await this.application.sync.sync(syncOptions)
|
||||
|
||||
const sessionAfterSync = this.application.apiService.getSession()
|
||||
|
||||
expect(sessionAfterSync.accessToken.expiresAt).to.be.greaterThan(Date.now())
|
||||
})
|
||||
|
||||
it('should succeed when a sync request is perfomed after signing into an ephemeral session', async function () {
|
||||
await Factory.registerUserToApplication({
|
||||
application: this.application,
|
||||
|
||||
Reference in New Issue
Block a user