Skip to content

Commit 13a8758

Browse files
authored
fix: Only remove token on NotAuthenticated error in authentication client and handle error better (#1525)
1 parent 6d723e8 commit 13a8758

File tree

2 files changed

+42
-23
lines changed

2 files changed

+42
-23
lines changed

packages/authentication-client/src/core.ts

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { NotAuthenticated } from '@feathersjs/errors';
1+
import { NotAuthenticated, FeathersError } from '@feathersjs/errors';
22
import { Application } from '@feathersjs/feathers';
33
import { AuthenticationRequest, AuthenticationResult } from '@feathersjs/authentication';
44
import { Storage, StorageWrapper } from './storage';
@@ -118,6 +118,16 @@ export class AuthenticationClient {
118118
return Promise.resolve(null);
119119
}
120120

121+
handleError (error: FeathersError, type: 'authenticate'|'logout') {
122+
if (error.code === 401 || error.code === 403) {
123+
const promise = this.removeAccessToken().then(() => this.reset());
124+
125+
return type === 'logout' ? promise : promise.then(() => Promise.reject(error));
126+
}
127+
128+
return Promise.reject(error);
129+
}
130+
121131
reAuthenticate (force: boolean = false): Promise<AuthenticationResult> {
122132
// Either returns the authentication state or
123133
// tries to re-authenticate with the stored JWT and strategy
@@ -133,9 +143,7 @@ export class AuthenticationClient {
133143
strategy: this.options.jwtStrategy,
134144
accessToken
135145
});
136-
}).catch((error: Error) =>
137-
this.removeAccessToken().then(() => Promise.reject(error))
138-
);
146+
});
139147
}
140148

141149
return authPromise;
@@ -155,8 +163,8 @@ export class AuthenticationClient {
155163
this.app.emit('authenticated', authResult);
156164

157165
return this.setAccessToken(accessToken).then(() => authResult);
158-
}).catch((error: Error) =>
159-
this.reset().then(() => Promise.reject(error))
166+
}).catch((error: FeathersError) =>
167+
this.handleError(error, 'authenticate')
160168
);
161169

162170
this.app.set('authentication', promise);
@@ -166,20 +174,17 @@ export class AuthenticationClient {
166174

167175
logout () {
168176
return Promise.resolve(this.app.get('authentication'))
169-
.then(auth => {
170-
if (!auth) {
171-
return null;
172-
}
173-
174-
return this.service.remove(null)
175-
.then((authResult: AuthenticationResult) => this.removeAccessToken()
176-
.then(() => this.reset())
177-
.then(() => {
178-
this.app.emit('logout', authResult);
179-
180-
return authResult;
181-
})
182-
);
183-
});
177+
.then(() => this.service.remove(null)
178+
.then((authResult: AuthenticationResult) => this.removeAccessToken()
179+
.then(() => this.reset())
180+
.then(() => {
181+
this.app.emit('logout', authResult);
182+
183+
return authResult;
184+
})
185+
))
186+
.catch((error: FeathersError) =>
187+
this.handleError(error, 'logout')
188+
);
184189
}
185190
}

packages/authentication-client/test/index.test.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import assert from 'assert';
22
import feathers, { Application } from '@feathersjs/feathers';
33

44
import client, { AuthenticationClient } from '../src';
5+
import { NotAuthenticated } from '@feathersjs/errors';
56

67
describe('@feathersjs/authentication-client', () => {
78
const accessToken = 'testing';
@@ -15,7 +16,11 @@ describe('@feathersjs/authentication-client', () => {
1516

1617
app.configure(client());
1718
app.use('/authentication', {
18-
create (data) {
19+
create (data: any) {
20+
if (data.error) {
21+
return Promise.reject(new Error('Did not work'));
22+
}
23+
1924
return Promise.resolve({
2025
accessToken,
2126
data,
@@ -25,7 +30,7 @@ describe('@feathersjs/authentication-client', () => {
2530

2631
remove (id) {
2732
if (!app.get('authentication')) {
28-
throw new Error('Not logged in');
33+
throw new NotAuthenticated('Not logged in');
2934
}
3035

3136
return Promise.resolve({ id });
@@ -135,6 +140,15 @@ describe('@feathersjs/authentication-client', () => {
135140
});
136141
});
137142

143+
it('does not remove AccessToken on other errors', () => {
144+
return app.authenticate({
145+
strategy: 'testing'
146+
}).then(() => app.authenticate({
147+
strategy: 'testing'
148+
})).then(() => app.authentication.getAccessToken())
149+
.then(at => assert.strictEqual(at, accessToken));
150+
});
151+
138152
it('logout when not logged in without error', async () => {
139153
const result = await app.logout();
140154

0 commit comments

Comments
 (0)