Skip to content

Commit

Permalink
feat: get access tokens from cookies
Browse files Browse the repository at this point in the history
  • Loading branch information
JGiter committed Feb 10, 2023
1 parent a4faa7e commit 9f90aee
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 33 deletions.
34 changes: 32 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: 2 additions & 0 deletions package.json
Expand Up @@ -102,6 +102,7 @@
"nats.ws": "^1.7.1",
"promise-retry": "^2.0.1",
"qs": "^6.9.4",
"set-cookie-parser": "^2.5.1",
"ts-interface-checker": "^1.0.2",
"tslib": "^2.0.3",
"uuid": "^7.0.3"
Expand All @@ -126,6 +127,7 @@
"@types/lodash.difference": "^4.5.6",
"@types/promise-retry": "^1.1.3",
"@types/qs": "^6.9.5",
"@types/set-cookie-parser": "^2.4.2",
"@types/uuid": "^8.3.0",
"@typescript-eslint/eslint-plugin": "^5.9.1",
"@typescript-eslint/parser": "^5.9.1",
Expand Down
76 changes: 45 additions & 31 deletions src/modules/cache-client/cache-client.service.ts
@@ -1,4 +1,4 @@
import axios, { AxiosInstance } from 'axios';
import axios, { AxiosInstance, AxiosResponse } from 'axios';
import { stringify } from 'qs';
import { IRoleDefinition } from '@energyweb/credential-governance';
import { IDIDDocument } from '@ew-did-registry/did-resolver-interface';
Expand All @@ -8,6 +8,7 @@ import {
VerifiableCredential,
} from '@ew-did-registry/credentials-interface';
import promiseRetry from 'promise-retry';
import setCookie from 'set-cookie-parser';
import { IApp, IOrganization, IRole } from '../domains/domains.types';
import { AssetHistory } from '../assets/assets.types';
import {
Expand Down Expand Up @@ -72,43 +73,26 @@ export class CacheClient implements ICacheClient {
* After authentication runs previously failed requests
*/
async authenticate() {
let tokens: AuthTokens | undefined = undefined;

const setTokens = () => {
if (!tokens) return;
if (!this.isBrowser) {
this._httpClient.defaults.headers.common[
'Authorization'
] = `Bearer ${tokens.token}`;
}
this.refresh_token = tokens.refreshToken;
};

// First try to refresh access token
try {
const refreshedTokens = await this.refreshToken();
tokens = refreshedTokens;
setTokens();

if (!tokens || !(await this.isAuthenticated())) {
tokens = undefined;
}
await this.refreshToken();
} catch {
getLogger().warn('[CACHE CLIENT] failed to refresh tokens');
}

// If refresh token failed or access token is not valid, then sign new identity token
if (!tokens) {
if (!(await this.isAuthenticated())) {
getLogger().info('[CACHE CLIENT] obtaining new tokens');
delete this._httpClient.defaults.headers.common['Authorization'];
const pubKeyAndIdentityToken =
await this._signerService.publicKeyAndIdentityToken(true);
const { data } = await this._httpClient.post<AuthTokens>('/login', {
const res = await this._httpClient.post<AuthTokens>('/login', {
identityToken: pubKeyAndIdentityToken.identityToken,
});
if (!this.isBrowser) {
this.setTokens(res);
}
this.pubKeyAndIdentityToken = pubKeyAndIdentityToken;
tokens = data;
setTokens();
}
getLogger().info('[CACHE CLIENT] authenticated');
}
Expand Down Expand Up @@ -681,18 +665,48 @@ export class CacheClient implements ICacheClient {
);
}

private async refreshToken(): Promise<AuthTokens | undefined> {
if (!this.refresh_token) return undefined;
private async refreshToken(): Promise<void> {
if (!this.isBrowser && !this.refresh_token) return undefined;
getLogger().info('[CACHE CLIENT] refreshing tokens');
const { data } = await this._httpClient.get<{
token: string;
refreshToken: string;
}>(
const res = await this._httpClient.get<AuthTokens>(
`/refresh_token${
this.isBrowser ? '' : `?refresh_token=${this.refresh_token}`
}`
);
getLogger().debug('[CACHE CLIENT] refreshed tokens fetched');
return data;
if (!this.isBrowser) {
this.setTokens(res);
}
}

/**
* Saves access and refresh tokens
*
* @param res Response from login request
*/
private setTokens({ headers, data }: AxiosResponse) {
let token: AuthTokens['token'] | undefined;
let refreshToken: AuthTokens['refreshToken'] | undefined;
if (headers['set-cookie']) {
const cookies = setCookie.parse(headers['set-cookie'], {
decodeValues: false,
map: true,
});
const tokenCookie = cookies['token'];
const refreshTokenCookie = cookies['refreshToken'];

if (tokenCookie && refreshTokenCookie) {
token = tokenCookie.value;
refreshToken = refreshTokenCookie.value;
}
}
if (!token || !refreshToken) {
token = data.token;
refreshToken = data.refreshToken;
}
this.refresh_token = refreshToken;
this._httpClient.defaults.headers.common[
'Authorization'
] = `Bearer ${token}`;
}
}

0 comments on commit 9f90aee

Please sign in to comment.