Add traps; user registration

This commit is contained in:
garrettmills
2020-05-20 09:56:03 -05:00
parent 7663cea2ea
commit ea77402750
19 changed files with 493 additions and 24 deletions

View File

@@ -1,11 +1,70 @@
const { Controller } = require('libflitter')
const zxcvbn = require('zxcvbn')
const email_validator = require('email-validator')
class AuthController extends Controller {
static get services() {
return [...super.services, 'models', 'auth', 'MFA', 'output', 'configs', 'utility']
}
async registration(req, res, next) {
const User = this.models.get('auth:User')
const required_fields = ['first_name', 'last_name', 'uid', 'email']
const unique_fields = ['uid', 'email']
for ( const field of required_fields ) {
if ( !req.body[field] )
return res.status(400)
.message(`Missing required field: ${field}`)
.api()
}
if ( !req.body.uid.match(/^([A-Z]|[a-z]|[0-9]|_|-|\.)+$/) )
return res.status(400)
.message('Invalid field: uid (should be alphanumeric with "_", "-", and "." allowed)')
.api()
if ( !email_validator.validate(req.body.email) )
return res.status(400)
.message('Invalid field: email')
.api()
for ( const field of unique_fields ) {
const params = {}
params[field] = req.body[field]
const match_user = await User.findOne(params)
if ( match_user )
return res.status(400)
.message(`A user already exists with that ${field}.`)
.api()
}
const user = new User({
first_name: req.body.first_name,
last_name: req.body.last_name,
uid: req.body.uid,
email: req.body.email,
trap: 'password_reset', // Force user to reset password
})
user.promote('base_user')
await user.save()
// Log in the user automatically
await this.auth.get_provider().session(req, user)
return res.api(await user.to_api())
}
async validate_email(req, res, next) {
let is_valid = !!req.body.email
if ( is_valid ) {
is_valid = email_validator.validate(req.body.email)
}
return res.api({ is_valid })
}
async get_users(req, res, next) {
const User = this.models.get('auth:User')
const users = await User.find()
@@ -346,6 +405,34 @@ class AuthController extends Controller {
return res.api({ is_valid })
}
async user_exists(req, res, next) {
const User = this.models.get('auth:User')
if ( !req.body.username && !req.body.email )
return res.status(400)
.message('Please provide one of: username, email')
.api()
const data = {}
if ( req.body.username ) {
const existing_user = await User.findOne({
uid: req.body.username,
})
data.username_taken = !!existing_user
}
if ( req.body.email ) {
const existing_user = await User.findOne({
email: req.body.email,
})
data.email_taken = !!existing_user
}
return res.api(data)
}
// TODO XSRF Token
/*
* Request Params:

View File

@@ -86,6 +86,7 @@ class PasswordController extends Controller {
// Create the password reset
const reset = await req.user.reset_password(req.body.password)
await req.user.save()
if ( req.trap.has_trap() && req.trap.get_trap() === 'password_reset' ) await req.trap.end()
// invalidate existing tokens and other logins
const flitter = await this.auth.get_provider('flitter')

View File

@@ -7,13 +7,22 @@ const FormController = require('flitter-auth/controllers/Forms')
*/
class Forms extends FormController {
static get services() {
return [...super.services, 'Vue']
return [...super.services, 'Vue', 'models']
}
async registration_provider_get(req, res, next) {
return res.page('auth:register', {
...this.Vue.data({})
})
}
async login_provider_get(req, res, next) {
const Setting = this.models.get('Setting')
return res.page('auth:login', {
...this.Vue.data({
login_message: req.session?.auth?.message || 'Please sign-in to continue.'
login_message: req.session?.auth?.message || 'Please sign-in to continue.',
registration_enabled: await Setting.get('auth.allow_registration')
}),
})
}