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

Mongo update error after logging into Facebook #244

Closed
node-monk opened this Issue Jul 18, 2016 · 7 comments

Comments

Projects
None yet
4 participants
@node-monk
Copy link

node-monk commented Jul 18, 2016

Sorry in advance for all the code posted in this, but I almost have the Facebook login working. It worked once and created a user in the mongo database, but after that it was throwing these errors in the debugger and sending me to /auth/failure.

In my setup, I have feathers as an api subfolder and its access by the '/api/v1' url so I have to do some redirection in /index.js for the auth/facebook routes.

  feathers-authentication:oauth2 Updating user: 578c46ef0a0d2d550e16aea7 +12s
  feathers-authentication:middleware An authentication error occurred. +8ms [Error: Invalid atomic update value for $__original_save. Expected an object, received function]

/api/config/default.json

{
  "host": "localhost",
  "port": 8080,
  "mongodb": "mongodb://localhost:27017/nnbbApi",
  "public": "../public/",
  "auth": {
    "shouldSetupSuccessRoute": false,
    "token": {
      "secret": "..."
    },
    "facebook": {
      "clientID": "...",
      "clientSecret": "...",
      "permissions": {
        "scope": ["public_profile", "email"]
      },
      "profileFields": ["id", "displayName", "photos", "email", "first_name", "last_name", "age_range"]
    },
    "local": {}
  }
}

/api/middleware/auth

'use strict';

const handler = require('feathers-errors/handler');
const notFound = require('./not-found-handler');
const logger = require('./logger');

module.exports = function() {
  // Add your custom middleware here. Remember, that
  // just like Express the order matters, so error
  // handling middleware should go last.
  const app = this;

  app.get('/auth/success', function(req, res) {
    res.redirect('/member/profile');
  });

  app.use(notFound());
  app.use(logger(app));
  app.use(handler());
};

/api/services/auth/index.js

'use strict';

const authentication = require('feathers-authentication');
const FacebookStrategy = require('passport-facebook').Strategy;


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

  let config = app.get('auth');
  config.facebook.strategy = FacebookStrategy;

  app.set('auth', config);

  app.configure(authentication(config));
};
'use strict';

// user-model.js - A mongoose model
//
// See http://mongoosejs.com/docs/models.html
// for more of what you can do here.

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

const userSchema = new Schema({
  facebookId: {
    type: String
  },
  facebook: {
    type: Schema.Types.Mixed
  },
  // email: {
  //   type: String,
  //   required: true,
  //   unique: true
  // },
  // password: {
  //   type: String,
  //   required: true
  // },
  // Added in by Michael Watson
  profile: {
    firstname: {
      type: String
    },
    lastname: {
      type: String
    },
    locationName: {
      type: String
    },
    bio: {
      type: String
    },
    location: {
      type: {
        type: String,
        default: 'Point'
      },
      coordinates: [Number]
    },
    subscriptions: [{
      subscriptionId: {
        type: Schema.Types.ObjectId,
        ref: 'subscription'
      },
      startDate: {
        type: Date
      },
      endDate: {
        type: Date
      },
    }],
    photo: {
      type: String
    }
  },

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

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

module.exports = userModel;

/start.js

var express = require('express');
var path = require('path');

/**
 * Pull in Sub Application
 */
var feathers = require('feathers');
var api_application = require('./api/src/app');
var api = feathers().use('/', api_application);
var app = express().use('/api/v1', api);
var querystring = require('querystring');
/**
 * Load environment configuration
 */
var config = require(path.join(__dirname, 'application', 'configs', `${process.env.NODE_ENV}`));
try {
  require(path.join(__dirname, 'application', 'setup'))({
    app: app,
    config: config,
    api: api_application
  });
} catch (e) {
  console.error(e.stack);
  process.exit();
}

app.get('/auth/facebook', (req, res) => {
  console.log('rerouting to auth/facebook');
  res.redirect('/api/v1/auth/facebook');
});

app.get('/auth/success', (req, res) => {
  console.log('rerouting to api success.');
  res.redirect('/api/v1/auth/success');
});

app.get('/auth/failure', (req, res) => {
  res.redirect('/api/v1/auth/failure');
});

app.get('/auth/facebook/callback', (req, res) => {
  console.log('rerouting to callback.', req.query);

  res.redirect(`/api/v1/auth/facebook/callback?${querystring.stringify(req.query)}`);
});


/**
 * Start server
 */
const PORT = process.env.PORT || 8080;
var server = app.listen(PORT, () => {
  console.log(`NaNannyBooBoo Listening or port ${PORT}`);
});
api.setup(server);

@node-monk node-monk changed the title Mongo update error after logging in to Facebook Mongo update error after logging into Facebook Jul 18, 2016

@ekryski

This comment has been minimized.

Copy link
Member

ekryski commented Jul 19, 2016

Hmm. That's no good. We have a pretty big update coming pretty soon that may fix this (or at least will make it easier to debug).

If you can provide a link to the whole project that would be much easier for us to help debug. Nothing is standing out right away other than all the redirection seems like it might not be necessary.

Not that I think this is your issue but you just do:

var api = require('./api/src/app');
var api = feathers().use('/api/v1', api_application);

No need to include express because Feathers is Express under the hood. If you haven't already you can check out feathers-demos to see some examples of sub-apps and auth.

Auth with sub-apps doesn't really work very well. It's typically a bit better if you have your auth at the top level.

@ekryski ekryski added the Bug label Jul 19, 2016

@node-monk

This comment has been minimized.

Copy link
Author

node-monk commented Jul 20, 2016

Thanks for looking into this. I'll keep messing with it and maybe your next update will resolve it. There is not currently a url to access the project, it's still in early development on my local machine. Feathers sure has made it easy however to get up and running, and using service from the client ROCKS!!! Keep up the good work!!

@node-monk

This comment has been minimized.

Copy link
Author

node-monk commented Jul 20, 2016

Hope this helps, I was doing some digging and the issue is in the Patch method of feathers-mongoose/service.js (line 247)

return this.Model.update(params.query, data, options).lean(this.lean).exec().then(function () {

The "data" object getting passed into the update has an $__original_save property thats breaking the update because its a function not an object.

I made a simple update by having it pass the "data._doc" and the update didn't throw an error(and logged me in), but I am not sure if this is the correct solution or not. Below is the change I made

return this.Model.update(params.query, data._doc, options).lean(this.lean).exec().then(function () {

@rohit-romley

This comment has been minimized.

Copy link

rohit-romley commented Jul 20, 2016

Thanks a lot for the solution man.

@ekryski

This comment has been minimized.

Copy link
Member

ekryski commented Jul 20, 2016

Thanks for doing that digging @node-monk! Looks like toObject is not getting called or something to that effect. Going to leave this open because I think this is a legit issue.

As a side note when you initialize a Mongoose service to can set {lean: true} and all your queries will be lean so you won't need to do what you're doing.

@ekryski ekryski added this to the 0.8 milestone Aug 9, 2016

@simonjoom

This comment has been minimized.

Copy link

simonjoom commented Aug 10, 2016

hi ,
I ve got the same issue ' Invalid atomic update value'
// var data = Object.assign({}, user, data);
the problem come from Object.assign, i guess it's better to create a new object without link to old user reference (else data contain some $__original_save $__original_remove after applying Object.assign and do the problem)

//me i used that 👍 and no problem anymore
var users = JSON.parse(JSON.stringify(user )); //i clone user in other var
data = Object.assign({}, users, data);

      return app.service(options.userEndpoint).patch(id, data).then(function (updatedUser) {
@ekryski

This comment has been minimized.

Copy link
Member

ekryski commented Dec 30, 2016

This should be resolved with Auth v1.0.0. Please the migration guide.

If not, let's re-open and I will dive deeper but I haven't been able to reproduce on the new version.

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.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.