Closed jonpacker closed 6 years ago
That is a good point. Your observation is correct. Looks like this would solve the issue: https://github.com/nmaro/ooth/issues/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 :grin:
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.
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
Yeah, the lack of programmatic interface ended up being the reason we had to switch from using Ooth too. Seems like it’s got a bit of work to go before it’s ready for production. Looking forward to when it matures a bit more though!
- apr. 2018 kl. 18:15 skrev Adam Boe notifications@github.com:
what is the roles variable?
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.
@jonpacker thanks for the feedback, what approach did you end up taking? Is there any library that was helpful to you?
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.
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?
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 insideooth-local
, but this seems like a really bad idea. Is there something I'm missing here?