<commit_before>import Debug from 'debug';
import errors from 'feathers-errors';
import passport from 'passport';
import { exposeConnectMiddleware } from '../../middleware';
import { successfulLogin } from '../../middleware';

const debug = Debug('feathers-authentication:oauth2');

// Provider specific config
const defaults = {
  passReqToCallback: true,
  callbackSuffix: 'callback',
  permissions: {
    state: true,
    session: false
  }
};

export class Service {
  constructor(options = {}) {
    this.options = options;
  }

  oauthCallback(req, accessToken, refreshToken, profile, done) {
    let app = this.app;
    const options = this.options;
    const params = {
      query: {
        // facebookId: profile.id
        [`${options.provider}Id`]: profile.id
      }
    };

    // Find or create the user since they could have signed up via facebook.
    app.service(options.userEndpoint)
      .find(params)
      .then(users => {
        // Paginated services return the array of results in the data attribute.
        let user = users[0] || users.data && users.data[0];

        // TODO (EK): This is where we should look at req.user and see if we
        // can consolidate profiles. We might want to give the developer a hook
        // so that they can control the consolidation strategy.
        profile._json.accessToken = accessToken;

        let data = Object.assign({
          [`${options.provider}Id`]: profile.id,
          [`${options.provider}`]: profile._json
        });

        // If user found update and return them
        if (user) {
          const id = user[options.idField];

          // Merge existing user data with new profile data
          // TODO (EK): If stored profile data has been altered this might
          // just overwrite the whole `<provider>` field when it should do a
          // deep merge.
          data = Object.assign({}, user, data);

          debug(`Updating user: ${id}`);

          return app.service(options.userEndpoint).patch(id, data).then(updatedUser => {
            return done(null, updatedUser);
          }).catch(done);
        }

        debug(`Creating new user with ${options.provider}Id: ${profile.id}`);

        // No user found so we need to create one.
        return app.service(options.userEndpoint).create(data).then(user => {
          debug(`Created new user: ${user[options.idField]}`);

          return done(null, user);
        }).catch(done);
      }).catch(done);
  }<commit_msg>properly handle optional `_json` property (#197)<commit_after>import Debug from 'debug';
import errors from 'feathers-errors';
import passport from 'passport';
import { exposeConnectMiddleware } from '../../middleware';
import { successfulLogin } from '../../middleware';

const debug = Debug('feathers-authentication:oauth2');

// Provider specific config
const defaults = {
  passReqToCallback: true,
  callbackSuffix: 'callback',
  permissions: {
    state: true,
    session: false
  }
};

export class Service {
  constructor(options = {}) {
    this.options = options;
  }

  oauthCallback(req, accessToken, refreshToken, profile, done) {
    let app = this.app;
    const options = this.options;
    const params = {
      query: {
        // facebookId: profile.id
        [`${options.provider}Id`]: profile.id
      }
    };

    // Find or create the user since they could have signed up via facebook.
    app.service(options.userEndpoint)
      .find(params)
      .then(users => {
        // Paginated services return the array of results in the data attribute.
        let user = users[0] || users.data && users.data[0];

        // TODO (EK): This is where we should look at req.user and see if we
        // can consolidate profiles. We might want to give the developer a hook
        // so that they can control the consolidation strategy.
        const providerData = Object.assign({}, profile._json, {accessToken});

        let data = Object.assign({
          [`${options.provider}Id`]: profile.id,
          [`${options.provider}`]: providerData
        });

        // If user found update and return them
        if (user) {
          const id = user[options.idField];

          // Merge existing user data with new profile data
          // TODO (EK): If stored profile data has been altered this might
          // just overwrite the whole `<provider>` field when it should do a
          // deep merge.
          data = Object.assign({}, user, data);

          debug(`Updating user: ${id}`);

          return app.service(options.userEndpoint).patch(id, data).then(updatedUser => {
            return done(null, updatedUser);
          }).catch(done);
        }

        debug(`Creating new user with ${options.provider}Id: ${profile.id}`);

        // No user found so we need to create one.
        return app.service(options.userEndpoint).create(data).then(user => {
          debug(`Created new user: ${user[options.idField]}`);

          return done(null, user);
        }).catch(done);
      }).catch(done);
  }
{'fraction_non_alphanumeric': 0.12408033406243786, 'fraction_numerical': 0.001789620202823623, 'mean_word_length': 2.431105047748977, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, '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': '3075321', 'n_tokens_mistral': 1368, 'n_tokens_neox': 1349, 'n_words': 448}