Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

user fails to signup with facebook if there is also local auth #168

Closed
DenJohX opened this Issue Apr 20, 2016 · 2 comments

Comments

Projects
None yet
2 participants
@DenJohX
Copy link

DenJohX commented Apr 20, 2016

Im using a yeoman generated feathers app, with local and facebook authentication enabled.

The authentication service is as follows:

    const authentication = require('feathers-authentication');

    const FacebookStrategy = require('passport-facebook').Strategy;
    const FacebookTokenStrategy = require('passport-facebook-token');
    const LinkedinStrategy = require('passport-linkedin-oauth2').Strategy;
    const LinkedinTokenStrategy = require('passport-linkedin-token-oauth2').Strategy;

    module.exports = function() {
      const app = this;

      let config = app.get('auth');

      config.facebook.strategy = FacebookStrategy;
      config.facebook.tokenStrategy = FacebookTokenStrategy;
      config.linkedin.strategy = LinkedinStrategy;
      config.linkedin.tokenStrategy = LinkedinTokenStrategy;

      app.set('auth', config);
      app.configure(authentication(config));
    };

The user model:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

export const niveles = [
    {nombre: 'superadmin', nivel: 10},
    {nombre: 'owner', nivel: 3},
    {nombre: 'admin', nivel: 2},
    {nombre: 'user', nivel: 1}
];

const userSchema = new Schema({
  facebookId: { type: String },
  facebook: { type: Schema.Types.Mixed },
  linkedinId: { type: String },
  linkedin: { type: Schema.Types.Mixed },
  email: {type: String, required: true, unique: true},
  password: { type: String, required: true },
  nivel: { type: String, enum: niveles.map(n => n.nombre), required: true, default: 'owner'},

  createdAt: { type: Date, 'default': Date.now },
  updatedAt: { type: Date, 'default': Date.now }
});

const userModel = mongoose.model('user', userSchema);

export default userModel;

The local authentication works fine, but facebook does not, When the callback its called, the new user does not gets created because the validation fails with:

[BadRequest: user validation failed]
  type: 'FeathersError',
  name: 'BadRequest',
  code: 400,
  className: 'bad-request',
  data: undefined,
  errors: 
   { password: 
      { [ValidatorError: Path `password` is required.]
        message: 'Path `password` is required.',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'password',
        value: undefined },
     email: 
      { [ValidatorError: Path `email` is required.]
        message: 'Path `email` is required.',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'email',
        value: undefined } } }

The validation is there for new local user accounts, but should not work with facebook or others.
Is there a way to configure this behavior? perhaps using the adquired email from facebook and a random generated password to create the new accounts.

@ekryski

This comment has been minimized.

Copy link
Member

ekryski commented Apr 21, 2016

@DenJohX You either have to do your validation in hooks (which is what we prefer because it keeps you datastore agnostic) or write custom mongoose validations that are conditional. If you simply want to bring the email from the facebook profile top level then you always add a before hook to your user service create method.

We might make a change to the generator so that email and password aren't required by default but this is where the generator naturally starts to fall down. It's too hard to anticipate the requirements for every app so it'll probably have to be manual changes from here (ie. hooks or custom validators).

Changing you validations should allow you to continue on so I'm going to close this. If it doesn't work out then we can re-open and revisit. Thanks for reporting! 😄

@ekryski ekryski closed this Apr 21, 2016

@DenJohX

This comment has been minimized.

Copy link
Author

DenJohX commented Apr 21, 2016

Thanks for the guidance.

I'd ended up doing it all in a pre-save hook: obtaining the email from facebook and inserting it on the user, also generating a random password.

I'd leave the validation at model level, but yes, validation at service level seems to be the ideal.

Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.