Skip to content

Commit

Permalink
fix: login as different account issus
Browse files Browse the repository at this point in the history
When logout in as a separate account was using old cookies.
So check that if publicKey is there so that if not, redo login to cache-server
  • Loading branch information
jrhender committed May 15, 2021
1 parent 90a4dd0 commit 5f75176
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 20 deletions.
3 changes: 2 additions & 1 deletion src/cacheServerClient/ICacheServerClient.ts
Expand Up @@ -17,7 +17,8 @@ import {

export interface ICacheServerClient {
pubKeyAndIdentityToken: IPubKeyAndIdentityToken | undefined;
login: () => Promise<void>;
testLogin: () => Promise<void>;
login: () => Promise<{ pubKeyAndIdentityToken: IPubKeyAndIdentityToken, token: string, refreshToken: string }>;
isAuthEnabled: () => boolean;
getRoleDefinition: ({ namespace }: { namespace: string }) => Promise<IRoleDefinition>;
getOrgDefinition: ({ namespace }: { namespace: string }) => Promise<IOrganizationDefinition>;
Expand Down
23 changes: 12 additions & 11 deletions src/cacheServerClient/cacheServerClient.ts
Expand Up @@ -95,38 +95,39 @@ export class CacheServerClient implements ICacheServerClient {
return Promise.reject(error);
};

async login() {
public async testLogin(): Promise<void> {
// Simple test to check if logged in or no. TODO: have dedicated endpoint on the cache-server
// If receive unauthorized response, expect that refreshToken() will be called
await this.getRoleDefinition({ namespace: "testing.if.logged.in" });
}

private async performlogin(identityToken: string) {
public async login(): Promise<{ pubKeyAndIdentityToken: IPubKeyAndIdentityToken, token: string, refreshToken: string }> {
const pubKeyAndIdentityToken = await getPublicKeyAndIdentityToken(this.signer);
const {
data: { refreshToken, token }
} = await this.httpClient.post<{ token: string; refreshToken: string }>("/login", {
identityToken
identityToken: pubKeyAndIdentityToken.identityToken
});

if (!this.isBrowser) {
this.httpClient.defaults.headers.common["Authorization"] = `Bearer ${token}`;
this.refresh_token = refreshToken;
}
return { token, refreshToken };
return { pubKeyAndIdentityToken, token, refreshToken };
}

private async refreshToken() {
let data: { token: string, refreshToken: string };
private async refreshToken(): Promise<{ token: string, refreshToken: string }> {
try {
({ data } = await this.httpClient.get<{ token: string; refreshToken: string }>(
const { data } = await this.httpClient.get<{ token: string; refreshToken: string }>(
`/refresh_token${this.isBrowser ? "" : `?refresh_token=${this.refresh_token}`}`
));
);
return data;
}
catch {
this.pubKeyAndIdentityToken = await getPublicKeyAndIdentityToken(this.signer);
data = await this.performlogin(this.pubKeyAndIdentityToken.identityToken);
const loginResult = await this.login();
this.pubKeyAndIdentityToken = loginResult.pubKeyAndIdentityToken;
return loginResult;
}
return data;
}

async getRoleDefinition({ namespace }: { namespace: string }) {
Expand Down
23 changes: 15 additions & 8 deletions src/iam/iam-base.ts
Expand Up @@ -166,9 +166,8 @@ export class IAMBase {
let identityToken: string | undefined;
let publicKey: string | undefined;

// Login to the cache-server may require signature of identityToken
// from which we can derive a publicKey
const fromCacheLogin = await this.loginToCacheServer();
const savedPublicKey = localStorage.getItem(PUBLIC_KEY);
const fromCacheLogin = await this.loginToCacheServer(savedPublicKey);
publicKey = fromCacheLogin?.publicKey;
identityToken = fromCacheLogin?.identityToken;

Expand All @@ -177,7 +176,6 @@ export class IAMBase {
if (!publicKey && this._runningInBrowser) {
// Check local storage.
// This is to that publicKey can be reused when refreshing the page
const savedPublicKey = localStorage.getItem(PUBLIC_KEY);
if (savedPublicKey) {
publicKey = savedPublicKey;
}
Expand Down Expand Up @@ -349,11 +347,20 @@ export class IAMBase {
this._signer = undefined;
}

private async loginToCacheServer(): Promise<IPubKeyAndIdentityToken | undefined> {
private async loginToCacheServer(savedPublicKey: string | null): Promise<IPubKeyAndIdentityToken | undefined> {
if (this._signer && this._cacheClient && this._cacheClient.isAuthEnabled()) {
await this._cacheClient.login();
// Expect that if login generated pubKey&IdToken, then will be accessible as property
return this._cacheClient.pubKeyAndIdentityToken;
// If no saved publicKey then assume that user has never signed in or has signed out
if (!savedPublicKey) {
const { pubKeyAndIdentityToken } = await this._cacheClient.login();
return pubKeyAndIdentityToken;
}
// publicKey is there so maybe user has signed in before.
// Test cache-server login to confirm that their tokens (in the http-only cookies) are still valid
else {
await this._cacheClient.testLogin();
// Expect that if login generated pubKey&IdToken, then will be accessible as property of cacheClient
return this._cacheClient.pubKeyAndIdentityToken;
}
}
return undefined;
}
Expand Down

0 comments on commit 5f75176

Please sign in to comment.