<commit_before>import Debug from 'debug';
import { omit } from 'lodash';
import { IncomingMessage } from 'http';
import { NotAuthenticated } from '@feathersjs/errors';
import { Params } from '@feathersjs/feathers';
// @ts-ignore
import lt from 'long-timeout';

import { AuthenticationBaseStrategy } from './strategy';
import { AuthenticationRequest, AuthenticationResult, ConnectionEvent } from './core';

const debug = Debug('@feathersjs/authentication/jwt');
const SPLIT_HEADER = /(\S+)\s+(\S+)/;

export class JWTStrategy extends AuthenticationBaseStrategy {
  expirationTimers = new WeakMap();

  get configuration () {
    const authConfig = this.authentication.configuration;
    const config = super.configuration;

    return {
      entity: authConfig.entity,
      service: authConfig.service,
      header: 'Authorization',
      schemes: [ 'Bearer', 'JWT' ],
      ...config
    };
  }

  async handleConnection (event: ConnectionEvent, connection: any, authResult?: AuthenticationResult): Promise<void> {
    const isValidLogout = event === 'logout' && connection.authentication && authResult &&
      connection.authentication.accessToken === authResult.accessToken;

    if (authResult && event === 'login') {
      const { accessToken } = authResult;
      const { exp } = await this.authentication.verifyAccessToken(accessToken);
      // The time (in ms) until the token expires
      const duration = (exp * 1000) - new Date().getTime();
      // This may have to be a `logout` event but right now we don't want
      // the whole context object lingering around until the timer is gone
      const timer = lt.setTimeout(() => this.app.emit('disconnect', connection), duration);

      debug(`Registering connection expiration timer for ${duration}ms`);
      this.expirationTimers.set(connection, timer);

      debug('Adding authentication information to connection');
      connection.authentication = {
        strategy: this.name,
        accessToken
      };
    } else if (event === 'disconnect' || isValidLogout) {
      debug('Removing authentication information and expiration timer from connection');

      delete connection.authentication;
      lt.clearTimeout(this.expirationTimers.get(connection));
    }
  }
<commit_msg>fix: check for undefined access token (#1571)<commit_after>import Debug from 'debug';
import { omit } from 'lodash';
import { IncomingMessage } from 'http';
import { NotAuthenticated } from '@feathersjs/errors';
import { Params } from '@feathersjs/feathers';
// @ts-ignore
import lt from 'long-timeout';

import { AuthenticationBaseStrategy } from './strategy';
import { AuthenticationRequest, AuthenticationResult, ConnectionEvent } from './core';

const debug = Debug('@feathersjs/authentication/jwt');
const SPLIT_HEADER = /(\S+)\s+(\S+)/;

export class JWTStrategy extends AuthenticationBaseStrategy {
  expirationTimers = new WeakMap();

  get configuration () {
    const authConfig = this.authentication.configuration;
    const config = super.configuration;

    return {
      entity: authConfig.entity,
      service: authConfig.service,
      header: 'Authorization',
      schemes: [ 'Bearer', 'JWT' ],
      ...config
    };
  }

  async handleConnection (event: ConnectionEvent, connection: any, authResult?: AuthenticationResult): Promise<void> {
    const isValidLogout = event === 'logout' && connection.authentication && authResult &&
      connection.authentication.accessToken === authResult.accessToken;

    const { accessToken } = authResult || {};

    if (accessToken && event === 'login') {
      debug('Adding authentication information to connection');
      const { exp } = await this.authentication.verifyAccessToken(accessToken);
      // The time (in ms) until the token expires
      const duration = (exp * 1000) - new Date().getTime();
      // This may have to be a `logout` event but right now we don't want
      // the whole context object lingering around until the timer is gone
      const timer = lt.setTimeout(() => this.app.emit('disconnect', connection), duration);

      debug(`Registering connection expiration timer for ${duration}ms`);
      this.expirationTimers.set(connection, timer);

      debug('Adding authentication information to connection');
      connection.authentication = {
        strategy: this.name,
        accessToken
      };
    } else if (event === 'disconnect' || isValidLogout) {
      debug('Removing authentication information and expiration timer from connection');

      delete connection.authentication;
      lt.clearTimeout(this.expirationTimers.get(connection));
    }
  }

{'fraction_non_alphanumeric': 0.11811876896402254, 'fraction_numerical': 0.002600780234070221, 'mean_word_length': 3.7430626927029804, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5430705', 'n_tokens_mistral': 1243, 'n_tokens_neox': 1204, 'n_words': 359}