Skip to content

Commit

Permalink
feat: use cached access token to skip auth flow
Browse files Browse the repository at this point in the history
  • Loading branch information
BugGambit committed Sep 10, 2019
1 parent a85c4a0 commit b28f506
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 8 deletions.
12 changes: 12 additions & 0 deletions guides/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ To utilize authentication in browsers using the SDK you need to use the `client.
- [Customize redirect URL](#customize-redirect-url-1)
- [Advance](#advance)
- [Manually trigger authentication](#manually-trigger-authentication)
- [Cache access tokens](#cache-access-tokens)
- [Skip authentication](#skip-authentication)
- [Combine different authentication methods](#combine-different-authentication-methods)
- [Tokens](#tokens)
Expand Down Expand Up @@ -157,6 +158,17 @@ client.loginWithOAuth({
await client.authenticate(); // this will also return a boolean based on if the user successfully authenticated or not.
```

### Cache access tokens

If you already have a valid access token you can use it to skip the authentication flow (see this [section](#tokens) on how to get hold of the token).
```js
client.loginWithOAuth({
project: 'YOUR PROJECT NAME HERE',
accessToken: 'ACCESS TOKEN FOR THE PROJECT HERE',
});
```
> `client.authenticate()` will still override this and trigger a new authentication flow.
### Skip authentication

It is possible to skip the authentication like this:
Expand Down
33 changes: 33 additions & 0 deletions src/__tests__/cogniteClient.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,39 @@ describe('CogniteClient', () => {
expect(promise401Throwed).toBe(true);
await expect(promiseAuthenticate).resolves.toBe(false);
});

describe('cached access token', () => {
test('should be able to provide an access token', async () => {
const client = setupClient(mockBaseUrl);
client.loginWithOAuth({
project,
accessToken: authTokens.accessToken,
});
nock(mockBaseUrl, {
reqheaders: {
[AUTHORIZATION_HEADER]: bearerString(authTokens.accessToken),
},
})
.get('/')
.once()
.reply(200, {});
await client.get('/');
});

test('re-authenticate on 401', async done => {
const client = setupClient(mockBaseUrl);
client.loginWithOAuth({
project,
accessToken: authTokens.accessToken,
onAuthenticate: () => done(),
});
nock(mockBaseUrl)
.get('/')
.once()
.reply(401, {});
client.get('/');
});
});
});
});
});
6 changes: 4 additions & 2 deletions src/__tests__/resources/groups.integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ describe('Groups integration test', () => {
});

test('delete', async () => {
const response = await client.groups.delete([group.id]);
expect(response).toEqual({});
await runTestWithRetryWhenFailing(async () => {
const response = await client.groups.delete([group.id]);
expect(response).toEqual({});
});
});
});
22 changes: 16 additions & 6 deletions src/cogniteClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ export const POPUP = 'POPUP';
export interface OAuthLoginOptions extends Project {
onAuthenticate?: OnAuthenticate | 'REDIRECT' | 'POPUP';
onTokens?: OnTokens;
/**
* Provide optional cached access token to skip the authentication flow (client.authenticate will still override this).
*/
accessToken?: string;
}

function validateAndReturnAPI<T>(api: T | undefined): T {
Expand Down Expand Up @@ -274,12 +278,13 @@ export default class CogniteClient {
this.projectName = project;

const onTokens = options.onTokens || (() => {});
let onAuthenticate: OnAuthenticate = onAuthenticateWithRedirect;
if (options.onAuthenticate === POPUP) {
onAuthenticate = onAuthenticateWithPopup;
} else if (isFunction(options.onAuthenticate)) {
onAuthenticate = options.onAuthenticate;
}
const onAuthenticate =
options.onAuthenticate === POPUP
? onAuthenticateWithPopup
: isFunction(options.onAuthenticate)
? options.onAuthenticate
: onAuthenticateWithRedirect;

const authenticate = createAuthenticateFunction({
project,
httpClient: this.httpClient,
Expand All @@ -292,6 +297,11 @@ export default class CogniteClient {
return didAuthenticate ? retry() : reject();
});

const { accessToken } = options;
if (accessToken) {
this.httpClient.setBearerToken(accessToken);
}

this.initAPIs();
this.authenticate = authenticate;
};
Expand Down

0 comments on commit b28f506

Please sign in to comment.