113 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import passport from 'passport';
 | 
						|
import { PassportConfigurator } from 'loopback-component-passport';
 | 
						|
import passportProviders from './passport-providers';
 | 
						|
import uuid from 'node-uuid';
 | 
						|
import { generateKey } from 'loopback-component-passport/lib/models/utils';
 | 
						|
 | 
						|
import {
 | 
						|
  setProfileFromGithub,
 | 
						|
  getSocialProvider,
 | 
						|
  getUsernameFromProvider
 | 
						|
} from './utils/auth';
 | 
						|
 | 
						|
const passportOptions = {
 | 
						|
  emailOptional: true,
 | 
						|
  profileToUser(provider, profile) {
 | 
						|
    const emails = profile.emails;
 | 
						|
    // NOTE(berks): get email or set to null.
 | 
						|
    // MongoDB indexs email but can be sparse(blank)
 | 
						|
    const email = emails && emails[0] && emails[0].value ?
 | 
						|
      emails[0].value :
 | 
						|
      null;
 | 
						|
 | 
						|
    // create random username
 | 
						|
    // username will be assigned when camper signups for Github
 | 
						|
    const username = 'fcc' + uuid.v4().slice(0, 8);
 | 
						|
    const password = generateKey('password');
 | 
						|
    let userObj = {
 | 
						|
      username: username,
 | 
						|
      password: password
 | 
						|
    };
 | 
						|
 | 
						|
    if (email) {
 | 
						|
      userObj.email = email;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!(/github/).test(provider)) {
 | 
						|
      userObj[getSocialProvider(provider)] = getUsernameFromProvider(
 | 
						|
        getSocialProvider(provider),
 | 
						|
        profile
 | 
						|
      );
 | 
						|
    } else {
 | 
						|
      userObj = setProfileFromGithub(userObj, profile, profile._json);
 | 
						|
    }
 | 
						|
    return userObj;
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
const fields = {
 | 
						|
  progressTimestamps: false,
 | 
						|
  completedChallenges: false,
 | 
						|
  challengeMap: false
 | 
						|
};
 | 
						|
 | 
						|
PassportConfigurator.prototype.init = function passportInit(noSession) {
 | 
						|
  this.app.middleware('session:after', passport.initialize());
 | 
						|
 | 
						|
  if (noSession) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  this.app.middleware('session:after', passport.session());
 | 
						|
 | 
						|
  // Serialization and deserialization is only required if passport session is
 | 
						|
  // enabled
 | 
						|
 | 
						|
  passport.serializeUser((user, done) => {
 | 
						|
    done(null, user.id);
 | 
						|
  });
 | 
						|
 | 
						|
  passport.deserializeUser((id, done) => {
 | 
						|
 | 
						|
    this.userModel.findById(id, { fields }, (err, user) => {
 | 
						|
      if (err || !user) {
 | 
						|
        return done(err, user);
 | 
						|
      }
 | 
						|
      return this.app.dataSources.db.connector
 | 
						|
        .collection('user')
 | 
						|
        .aggregate([
 | 
						|
          { $match: { _id: user.id } },
 | 
						|
          { $project: { points: { $size: '$progressTimestamps' } } }
 | 
						|
        ], function(err, [{ points = 1 } = {}]) {
 | 
						|
          if (err) { return done(err); }
 | 
						|
          user.points = points;
 | 
						|
          return done(null, user);
 | 
						|
        });
 | 
						|
    });
 | 
						|
  });
 | 
						|
};
 | 
						|
 | 
						|
export default function setupPassport(app) {
 | 
						|
  const configurator = new PassportConfigurator(app);
 | 
						|
 | 
						|
  configurator.setupModels({
 | 
						|
    userModel: app.models.user,
 | 
						|
    userIdentityModel: app.models.userIdentity,
 | 
						|
    userCredentialModel: app.models.userCredential
 | 
						|
  });
 | 
						|
 | 
						|
  configurator.init();
 | 
						|
 | 
						|
  Object.keys(passportProviders).map(function(strategy) {
 | 
						|
    var config = passportProviders[strategy];
 | 
						|
    config.session = config.session !== false;
 | 
						|
    configurator.configureProvider(
 | 
						|
      strategy,
 | 
						|
      {
 | 
						|
        ...config,
 | 
						|
        ...passportOptions
 | 
						|
      }
 | 
						|
    );
 | 
						|
  });
 | 
						|
}
 |