Skip to content
This repository has been archived by the owner on Feb 24, 2021. It is now read-only.

Ooth local: no way to programmatically create a user #58

Closed
jonpacker opened this issue Apr 24, 2018 · 7 comments
Closed

Ooth local: no way to programmatically create a user #58

jonpacker opened this issue Apr 24, 2018 · 7 comments

Comments

@jonpacker
Copy link

jonpacker commented Apr 24, 2018

It seems like the logic for inserting an Ooth local user with hashed password is inside an express route, and this is the only place it exists. Because of the prerequisite of ooth-roles that a user has to have their role set manually to admin, it seems like there's no good way to programmatically create that first user if they don't exist and give them an admin role. I could recreate the password hashing that is going on inside ooth-local, but this seems like a really bad idea. Is there something I'm missing here?

@nickredmark
Copy link
Owner

nickredmark commented Apr 24, 2018

That is a good point. Your observation is correct. Looks like this would solve the issue: #49.

If you are in a hurry a workaround could be to create an user via http and then modify it via a command to mongodb. Both steps are ugly, I know 😁

@gferreri
Copy link

In our scenario, we'd like to build an interface where an admin user can create other users, but we're running into a host of issues, primarily stemming from a lack of a programmatic interface. Also, calls to the local strategy's register endpoint can only be made by a user who is not already logged in, which kills the ability for us to use the register endpoint from the client-side at all.

@aaronmgdr
Copy link
Contributor

I had this same issue. I ended up studying insides of ooth and creating something similar that is compatable. I have removed the application specific parts but here it is

const generator = require('generate-password');
const OothMongo = require('ooth-mongo');
const {ObjectId} = require('mongodb');
const { hashSync, genSaltSync } = require('bcrypt-nodejs');
const { randomBytes } = require('crypto');
const SALT_ROUNDS = 12;

const HOUR = 1000 * 60 * 60;


function randomToken() {
  return randomBytes(43).toString('hex');
}


function hash(pass) {
  return hashSync(pass, genSaltSync(SALT_ROUNDS));
}

class UserImporter {
  backend: {
    getUserByValue: Function,
    insertUser: Function
  }
  
  constructor(db) {
    this.backend = new OothMongo(db, ObjectId);
  }
   /// call this to create a user
  immmigrate({email, firstName, lastName, phone}) {
    if (typeof email !== 'string') {
      throw new Error(`Invalid email ${email}`);
    }
      
    return this.backend.getUserByValue(['local.email'], email).then(user => {
      if (user) {
        console.error(`This email ${email} is already registered.`);
        return
      }
      const password = generate.password()
      const verificationToken = randomToken();
    
      this.backend.insertUser({
        profile:  {
          firstName,
          lastName,
          phone
        },
        local: {
          email,
          password: hash(password),
          verificationToken: hash(verificationToken),
          verificationTokenExpiresAt: new Date(Date.now() + HOUR)
        },
        roles
      }).then(_id => {  console.info(`User ${email} imported successfully.`);
    });
  }
}

export default UserImporter

@jonpacker
Copy link
Author

jonpacker commented Apr 26, 2018 via email

@nickredmark
Copy link
Owner

nickredmark commented Apr 27, 2018

@jonpacker thanks for the feedback, what approach did you end up taking? Is there any library that was helpful to you?

@nickredmark
Copy link
Owner

For the specific case of ooth-local it is now possible to run

ooth.on('register', ({_id, email, verificationToken}) => ...))

await ooth.callMethod('local', 'register', { email, password })

The general idea is that every method registered with ooth.registerMethod can now be called like that.

@fractefactos
Copy link

For the specific case of ooth-local it is now possible to run

ooth.on('register', ({_id, email, verificationToken}) => ...))

await ooth.callMethod('local', 'register', { email, password })

The general idea is that every method registered with ooth.registerMethod can now be called like that.

What's the ooth.on event callback for "login", that exist?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants