message: fix(authentication-client): Remove access token for fatal 400 errors
diff: @@ -82,6 +82,13 @@ export class AuthenticationClient {
  })
  }
  + /**
  + * Parse the access token or authentication error from the window location hash. Will remove it from the hash
  + * if found.
  + *
  + * @param location The window location
  + * @returns The access token if available, will throw an error if found, otherwise null
  + */
  getFromLocation(location: Location) {
  const [accessToken, tokenRegex] = getMatch(location, this.options.locationKey)
  @@ -102,10 +109,21 @@ export class AuthenticationClient {
  return Promise.resolve(null)
  }
  + /**
  + * Set the access token in storage.
  + *
  + * @param accessToken The access token to set
  + * @returns
  + */
  setAccessToken(accessToken: string) {
  return this.storage.setItem(this.options.storageKey, accessToken)
  }
  + /**
  + * Returns the access token from storage or the window location hash.
  + *
  + * @returns The access token from storage or location hash
  + */
  getAccessToken(): Promise<string | null> {
  return this.storage.getItem(this.options.storageKey).then((accessToken: string) => {
  if (!accessToken && typeof window !== 'undefined' && window.location) {
  @@ -116,10 +134,19 @@ export class AuthenticationClient {
  })
  }
  + /**
  + * Remove the access token from storage
  + * @returns The removed access token
  + */
  removeAccessToken() {
  return this.storage.removeItem(this.options.storageKey)
  }
  + /**
  + * Reset the internal authentication state. Usually not necessary to call directly.
  + *
  + * @returns null
  + */
  reset() {
  this.app.set('authentication', null)
  this.authenticated = false
  @@ -128,7 +155,9 @@ export class AuthenticationClient {
  }
  handleError(error: FeathersError, type: 'authenticate' | 'logout') {
  - if (error.code === 401 || error.code === 403) {
  + // For NotAuthenticated, PaymentError, Forbidden, NotFound, MethodNotAllowed, NotAcceptable
  + // errors, remove the access token
  + if (error.code > 400 && error.code < 408) {
  const promise = this.removeAccessToken().then(() => this.reset())
  return type === 'logout' ? promise : promise.then(() => Promise.reject(error))
  @@ -137,6 +166,14 @@ export class AuthenticationClient {
  return this.reset().then(() => Promise.reject(error))
  }
  + /**
  + * Try to reauthenticate using the token from storage. Will do nothing if already authenticated unless
  + * `force` is true.
  + *
  + * @param force force reauthentication with the server
  + * @param strategy The name of the strategy to use. Defaults to `options.jwtStrategy`
  + * @returns The reauthentication result
  + */
  reAuthenticate(force = false, strategy?: string): Promise<AuthenticationResult> {
  // Either returns the authentication state or
  // tries to re-authenticate with the stored JWT and strategy
  @@ -159,6 +196,13 @@ export class AuthenticationClient {
  return authPromise
  }
  + /**
  + * Authenticate using a specific strategy and data.
  + *
  + * @param authentication The authentication data
  + * @param params Additional parameters
  + * @returns The authentication result
  + */
  authenticate(authentication?: AuthenticationRequest, params?: Params): Promise<AuthenticationResult> {
  if (!authentication) {
  return this.reAuthenticate()
  @@ -182,6 +226,12 @@ export class AuthenticationClient {
  return promise
  }
  + /**
  + * Log out the current user and remove their token. Will do nothing
  + * if not authenticated.
  + *
  + * @returns The log out result.
  + */
  logout(): Promise<AuthenticationResult | null> {
  return Promise.resolve(this.app.get('authentication'))
  .then(() =>
  