OAuth login and the constraint of accepting terms


#1

Hi there

In our app we have a two-step registration process. First the user needs to enter and verify his email, then he will need to set some additional data like his name and a password.
Also, and this is important, he need to accept our terms and conditions by checking the corresponding checkbox.

That’s working fine!

Now I want to add registration / login with Google and Facebook (using the official packages accounts-*). Login works just fine. But in case the user logs in the very first time (= sign up) we also need to force the user to accept our terms and conditions before using the app.

In contrast to the normal registration process the user gets logged in immediately. The only solution I came up with would be to not let him use the app until he accepted the terms. But in that case I need to check this condition on every single action of the user, client and server side. I can’t just rely on the logged in state anymore.

Does anyone has an idea how to solve that elegantly? I didn’t find a reasonable solution.


#3

At client side, you can do something like that at route level (exemple with Iron Router):

// Utility function
function userLogged(controller) {
  if (!Meteor.userId()) {
    controller.redirect('/login')
    return false

  } else if(your_condition_here) {
    controller.redirect('/accept_terms')
    return false
  }
  return true
}

// Your route to secure
Router.route('/inbox', function() {
  if (userLogged(this)) { // This route need the user to logged in and accept terms
    
    [...] // Import template and layout and display them
    
  }
}

Server side, I think there is no choice that to check the condition at each and every Meteor method (as you should be doing anyway for verifying that the user is logged on). Exemple:

// exportable utility function so it can be imported every where I need it
export const validateUserLoggedIn = (uid) => {
  if (!uid) {
    throw new Meteor.Error(403, 'Error.You must be logged in')
  }
  if (your_condition_here) {
    throw new Meteor.Error(XXX, 'Error.You must accept terms before doing this')
  }
  return uid
}

export const mySecureMethod = new ValidatedMethod({
  name: 'MySecuredMethod',

  validate: new SimpleSchema({
    param1: {type: String,  max: 24}}).validator(),

  run({param1}) {

    // Check user is logged in
    const uid = validateUserLoggedIn(this.userId)

   [...] // Do stuff here

  }
})


#4

Ok, I see. Seems to be the way to go.

I’ll probably create a single parent “/app” route which checks the login state. And for the server your approach look good.
I know that I would have to check for “this.userId” anyway. So this wouldn’t make it more complicated then.