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

verifyToken and others are empty #141

Closed
jbatx opened this issue May 12, 2020 · 6 comments
Closed

verifyToken and others are empty #141

jbatx opened this issue May 12, 2020 · 6 comments

Comments

@jbatx
Copy link

jbatx commented May 12, 2020

I followed this guide to set things up https://hackernoon.com/setting-up-email-verification-in-feathersjs-ce764907e4f2. email works, so, that's good. Now I'm working toward generating the verifyToken url. The part that's not working is setting the token in the URL. The tokens are not on the user by the time the url is generated.

Admittedly, I'm tired. Hopefully I'm just missing something simple.

note: I'm hitting users.create from another service called signup sign up has no auth on it. signup.create keeps a record of the sign up and any other details that may not be involved in the actual user model. Organization name, for example.

I can see that the tokens are getting created and added to the object in verifyHooks.addVerification(). Here's a screenshot of the state of hook just before it's returned. https://www.evernote.com/l/ADodJylat31J77RtYMYJpF4i6K8rwet-DtY

As you can see, the verifyToken is there. Here is the list of user before create hooks:

create: [hashPassword('password'), authenticate('jwt'), userCreateValidator(), verifyHooks.addVerification()],

I have stripped this down to hashPassword('password'), verifyHooks.addVerification() and tested. The behavior is the same.

Here is the state of context.data just before triggering the resendVerifySignup case in notifier.js https://www.evernote.com/l/ADoginovCKxK7KnbCiYHrYXP6y_m1UPVNQI

As you can see, they're on the context.data object.

Then, in the notifier.js, the values are gone. Here's another screenshot: https://www.evernote.com/l/ADpZVElyGWJNb5kjyo511XLsYUJHJwAtqnI

Here are the user after create hooks: create: [ addUserToOrg(), addUserToGroup(), context => { accountService(context.app).notifier('resendVerifySignup', context.result); }, verifyHooks.removeVerification()],

I have stripped this down to only context => { accountService(context.app).notifier('resendVerifySignup', context.result); }, verifyHooks.removeVerification() and tested. The behavior is the same.

other details...

`
node v12.16.3

"dependencies": {
"@feathersjs/authentication": "^4.5.3",
"@feathersjs/authentication-local": "^4.5.3",
"@feathersjs/authentication-oauth": "^4.5.3",
"@feathersjs/configuration": "^4.5.3",
"@feathersjs/errors": "^4.5.3",
"@feathersjs/express": "^4.5.3",
"@feathersjs/feathers": "^4.5.3",
"@feathersjs/socketio": "^4.5.3",
"@feathersjs/transport-commons": "^4.5.3",
"aws-sdk": "^2.673.0",
"compression": "^1.7.4",
"cors": "^2.8.5",
"feathers-authentication-management": "^2.0.1",
"feathers-hooks-common": "^5.0.3",
"feathers-mailer": "^3.0.1",
"feathers-sequelize": "^6.1.0",
"helmet": "^3.22.0",
"jwt-decode": "^2.2.0",
"node-redshift": "^0.1.5",
"nodemailer-smtp-transport": "^2.7.4",
"pg": "^8.0.3",
"sequelize": "^5.21.7",
"serve-favicon": "^2.5.0",
"winston": "^3.2.1"
},`

@claustres
Copy link
Collaborator

I wonder if the problem is not in the way you wrote the hook with the notifier, if you use brackets then you should use a return statement on the promise from the notifier, otherwise don't use brackets: context => accountService(context.app).notifier('resendVerifySignup', context.result). Indeed I guess the hook chain does not await the async notifier call so that the removeVerification hook is run before the actual processing of the notifier.

By the way in case you did not notice the removeVerification should also be used as an after get/find hook, the goal is to avoid getting the tokens on the client side.

@jbatx
Copy link
Author

jbatx commented May 13, 2020

Hi @claustres, I think I see the issue. While addVerification adds the tokens to hook.data, the notifier is passed context.result which has no tokens. I suppose what is happening it that the user is getting created prior to the tokens existing in the data object - perhaps. This might be related to how I'm calling users.create from the signup service.

debugger screenshot: https://www.evernote.com/l/ADolpWZziz9FwIN8F9YV-vabZKOqE-67ps4

I removed the removed the removeVerification hook completely and retested. The same behavior persists.

re the removeVerification hook - thanks for the heads up. I had not finished the article yet. I'll add them there too.

@claustres
Copy link
Collaborator

This is a strange behavior, hook.result is what is returned by the DB adapter after the create so that if hook.data contains the tokens then it should as well, unless it is removed by another process.

@jbatx
Copy link
Author

jbatx commented May 13, 2020

sequelize is building the insert like this INSERT INTO "users" ("id","email","password","createdAt","updatedAt") VALUES (DEFAULT,$1,$2,$3,$4)

after addVerification has returned.

My users model looks like this and the columns are in the table

`
const Sequelize = require('sequelize');
const DataTypes = Sequelize.DataTypes;

module.exports = function (app) {
const sequelizeClient = app.get('sequelizeClient');
const users = sequelizeClient.define('users', {

email: {
  type: DataTypes.STRING,
  allowNull: false,
  unique: true
},
password: {
  type: DataTypes.STRING,
  allowNull: false
},
googleId: { type: DataTypes.STRING },
githubId: { type: DataTypes.STRING },
isVerified: { type: DataTypes.BOOLEAN },
verifyToken: { type: DataTypes.STRING },
verifyExpires: { type: DataTypes.DATE },
verifyChanges: { type: DataTypes.JSON },
resetToken: { type: DataTypes.STRING },
resetExpires: { type: DataTypes.DATE },

}, {
hooks: {
beforeCount(options) {
options.raw = true;
}
}
});

users.associate = function (models) {
users.belongsToMany(models.organizations,{through: 'users_to_organizations'});
users.belongsToMany(models.groups, {through: 'users_to_groups'});
};

return users;
};
`

This is the signup after hook that creates the user

`module.exports = (options = {}) => {
return async context => {

const users = context.app.service('users');
const password = 'supersecret';
const user = {
  'email': context.data.email,
  'password': password,
};
users.create(user)
  .then()
  .catch((error) => {
    console.log(error);
  });

return context;

};
};
`

@jbatx
Copy link
Author

jbatx commented May 13, 2020

I bypassed signup and posted a new user with

{
	"email": "emaily@email.com",
	"password": "supersecret"
}

The same behavior persisted

@jbatx
Copy link
Author

jbatx commented May 13, 2020

solved... user error

I had some junk in the users.class.js that was changing the data object.

@jbatx jbatx closed this as completed May 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants