Skip to content

Commit

Permalink
feat(ApplicationSession): only allow 1 pending request for a new toke…
Browse files Browse the repository at this point in the history
…n at a time

AFFECTS PACKAGES:
@esri/arcgis-rest-auth
  • Loading branch information
patrickarlt committed Sep 25, 2017
1 parent a6406d4 commit 4e6f9e2
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
15 changes: 14 additions & 1 deletion packages/arcgis-rest-auth/src/ApplicationSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ export class ApplicationSession implements IAuthenticationManager {
private portal: string;
private duration: number;

/**
* Internal object to keep track of pending token requests. Used to prevent
* duplicate token requests.
*/
private _pendingTokenRequest: Promise<string>;

constructor(options: IApplicationSessionOptions) {
this.clientId = options.clientId;
this.clientSecret = options.clientSecret;
Expand All @@ -54,7 +60,13 @@ export class ApplicationSession implements IAuthenticationManager {
return Promise.resolve(this.token);
}

return this.refreshToken();
if (this._pendingTokenRequest) {
return this._pendingTokenRequest;
}

this._pendingTokenRequest = this.refreshToken();

return this._pendingTokenRequest;
}

refreshToken(): Promise<string> {
Expand All @@ -63,6 +75,7 @@ export class ApplicationSession implements IAuthenticationManager {
client_secret: this.clientSecret,
grant_type: "client_credentials"
}).then(response => {
this._pendingTokenRequest = null;
this.token = response.token;
this.expires = response.expires;
return response.token;
Expand Down
35 changes: 35 additions & 0 deletions packages/arcgis-rest-auth/test/ApplicationSession.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,41 @@ describe("ApplicationSession", () => {
fail(e);
});
});

it("should not make multiple refresh requests while a refresh is pending", done => {
const session = new ApplicationSession({
clientId: "id",
clientSecret: "secret",
token: "token",
expires: YESTERDAY
});

fetchMock.mock(
"https://www.arcgis.com/sharing/rest/oauth2/token/",
{
access_token: "new",
expires_in: 1800
},
{ method: "POST", times: 1 }
);

Promise.all([
session.getToken("https://www.arcgis.com/sharing/rest/portals/self"),
session.getToken("https://www.arcgis.com/sharing/rest/portals/self")
])
.then(([token1, token2]) => {
expect(token1).toBe("new");
expect(token2).toBe("new");
expect(
fetchMock.calls("https://www.arcgis.com/sharing/rest/oauth2/token/")
.length
).toBe(1);
done();
})
.catch(e => {
fail(e);
});
});
});

it("should provide a method to refresh a session", done => {
Expand Down

0 comments on commit 4e6f9e2

Please sign in to comment.