const Controller = require('libflitter/controller/Controller')
/**
* @module flitter-auth/controllers/Forms
*/
/**
* Controller for displaying and processing registrations/logins/etc.
* @extends module:libflitter/controller/Controller~Controller
*/
class Forms extends Controller {
/**
* Specify the services required by this controller.
* The configs service is loaded automatically.
* @returns {Array<string>}
*/
static get services() {
return [...super.services, 'configs']
}
/**
* Show the registration page specific to a provider.
* @param {express/request} req - the incoming request
* @param {express/response} res - the outgoing response
* @param {function} next - callback handler for errors, etc.
* @return {Promise<*>}
*/
async registration_provider_get(req, res, next){
return req.auth_provider.handle_register_get(req, res, next)
}
/**
* Do the action to create a new user with the request body.
* This is a middleware that should not send a response.
* @param {express/request} req - the request
* @param {express/response} res - the response
* @param {function} next - the next function in the stack
* @returns {Promise<*>}
*/
async registration_provider_create_user(req, res, next) {
const errors = await req.auth_provider.validate_registration(req.body)
// If there are validation errors, display the form with errors.
if ( errors && errors.length > 0 ){
res.status(400)
return res.page(req.auth_provider.registration_view(), {
errors,
title: 'Register',
heading_text: 'Hi, there. Register to continue:',
form_data: req.body,
provider_name: req.auth_provider.config.name,
})
}
const user_data = await req.auth_provider.get_registration_args(req.body)
const user = req.auth_provider.register.apply(req.auth_provider, user_data)
return next()
}
/**
* Presents a view showing that the user has registered successfully.
* @param {express/request} req - the request
* @param {express/response} res - the response
* @param {function} next - the next function in the stack
* @returns {Promise<*>}
*/
async registration_provider_present_user_created(req, res, next) {
return res.page('auth:form_page', {
title: 'Success!',
message: 'Thanks for registering. You\'ll now be redirected to login with your new account.',
button_text: 'Login',
button_link: './login',
provider_name: req.auth_provider.config.name,
})
}
/**
* Handle a GET request to the login page. Usually displays the login form.
* Calls the 'handle_login_get' method on the auth provider.
* @param {express/request} req - the request
* @param {express/response} res - the response
* @param {function} next - the next function in the stack
* @returns {Promise<*>}
*/
async login_provider_get(req, res, next){
return req.auth_provider.handle_login_get(req, res, next)
}
/**
* Middleware that attempts to authenticate a user. If the authentication
* via the auth provider succeeds, the auth session is created and the next
* handler in the stack is called. Otherwise, the login view is returned with
* the error object.
* @param {express/request} req - the request
* @param {express/response} res - the response
* @param {function} next - the next function in the stack
* @returns {Promise<*>}
*/
async login_provider_authenticate_user(req, res, next) {
const errors = await req.auth_provider.validate_login(req.body)
if ( errors && errors.length > 0 ){
res.status(400)
return res.page(req.auth_provider.login_view(), {
errors,
title: 'Login',
heading_text: 'Hi, there. Login to continue:',
provider_name: req.auth_provider.config.name,
})
}
const login_args = await req.auth_provider.get_login_args(req.body)
const user = await req.auth_provider.login.apply(req.auth_provider, login_args)
if ( !user ){
return res.page(req.auth_provider.login_view(), {
title: 'Login',
heading_text: 'Hi, there. Login to continue:',
errors: ['Invalid username or password.'],
provider_name: req.auth_provider.config.name,
})
}
await req.auth_provider.session(req, user)
next()
}
/**
* Sends the response for a successful login authentication.
* @param {express/request} req - the request
* @param {express/response} res - the response
* @param {function} next - the next function in the stack
* @returns {Promise<*>}
*/
async login_provider_present_success(req, res, next) {
if ( req.session.auth.flow ){
const destination = req.session.auth.flow
req.session.auth.flow = false
return res.redirect(destination)
} else {
return res.redirect(this.configs.get('auth.default_login_route'))
}
}
/**
* Cleans the auth session on a logout request. This is a middleware
* that shouldn't return a response if everything is successful.
* @param {express/request} req - the request
* @param {express/response} res - the response
* @param {function} next - the next function in the stack
* @returns {Promise<*>}
*/
async logout_provider_clean_session(req, res, next) {
await req.auth_provider.logout(req)
return next()
}
/**
* Returns the response signifying a successful logout.
* @param {express/request} req - the request
* @param {express/response} res - the response
* @param {function} next - the next function in the stack
* @returns {Promise<*>}
*/
async logout_provider_present_success(req, res, next) {
return res.page(req.auth_provider.logout_view(), {
title: 'Good-Bye',
message: 'You\'ve been successfully logged-out. Come back soon!',
button_text: 'Continue',
button_link: '/',
provider_name: req.auth_provider.config.name,
})
}
}
module.exports = exports = Forms