2017-11-14 11:49:19 +01:00
'use strict' ;
/ * *
* Auth . js controller
*
* @ description : A set of functions called "actions" for managing ` Auth ` .
* /
2017-11-16 14:12:03 +01:00
const _ = require ( 'lodash' ) ;
2017-11-16 18:00:15 +01:00
const crypto = require ( 'crypto' ) ;
2017-11-16 14:12:03 +01:00
2017-11-14 11:49:19 +01:00
module . exports = {
callback : async ( ctx ) => {
const provider = ctx . params . provider || 'local' ;
const params = ctx . request . body ;
const access _token = ctx . query . access _token ;
if ( provider === 'local' ) {
// The identifier is required.
if ( ! params . identifier ) {
2017-12-06 11:38:00 +01:00
return ctx . badRequest ( null , ctx . request . admin ? [ { messages : [ { id : 'Auth.form.error.email.provide' } ] } ] : 'Please provide your username or your e-mail.' ) ;
2017-11-14 11:49:19 +01:00
}
// The password is required.
if ( ! params . password ) {
2017-12-06 11:38:00 +01:00
return ctx . badRequest ( null , ctx . request . admin ? [ { messages : [ { id : 'Auth.form.error.password.provide' } ] } ] : 'Please provide your password.' ) ;
2017-11-14 11:49:19 +01:00
}
const query = { } ;
// Check if the provided identifier is an email or not.
2017-11-16 14:29:49 +01:00
const isEmail = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ . test ( params . identifier ) ;
2017-11-14 11:49:19 +01:00
// Set the identifier to the appropriate query field.
if ( isEmail ) {
query . email = params . identifier ;
} else {
query . username = params . identifier ;
}
// Check if the user exists.
2017-11-20 16:28:50 +01:00
const user = await strapi . query ( 'user' , 'users-permissions' ) . findOne ( query ) ;
if ( ! user ) {
2017-12-06 11:38:00 +01:00
return ctx . badRequest ( null , ctx . request . admin ? [ { messages : [ { id : 'Auth.form.error.invalid' } ] } ] : 'Identifier or password invalid.' ) ;
2017-11-20 16:28:50 +01:00
}
// The user never registered with the `local` provider.
if ( ! user . password ) {
2017-12-06 11:38:00 +01:00
return ctx . badRequest ( null , ctx . request . admin ? [ { messages : [ { id : 'Auth.form.error.password.local' } ] } ] : 'This user never set a local password, please login thanks to the provider used during account creation.' ) ;
2017-11-20 16:28:50 +01:00
}
const validPassword = strapi . plugins [ 'users-permissions' ] . services . user . validatePassword ( params . password , user . password ) ;
if ( ! validPassword ) {
2017-12-06 11:38:00 +01:00
return ctx . badRequest ( null , ctx . request . admin ? [ { messages : [ { id : 'Auth.form.error.invalid' } ] } ] : 'Identifier or password invalid.' ) ;
2017-11-20 16:28:50 +01:00
} else {
ctx . send ( {
jwt : strapi . plugins [ 'users-permissions' ] . services . jwt . issue ( user ) ,
2017-12-07 14:56:25 +01:00
user : _ . omit ( user . toJSON ? user . toJSON ( ) : user , [ 'password' , 'resetPasswordToken' ] )
2017-11-20 16:28:50 +01:00
} ) ;
2017-11-14 11:49:19 +01:00
}
} else {
// Connect the user thanks to the third-party provider.
2017-11-20 16:28:50 +01:00
const user = await strapi . api . user . services . grant . connect ( provider , access _token ) ;
ctx . redirect ( strapi . config . frontendUrl || strapi . config . url + '?jwt=' + strapi . api . user . services . jwt . issue ( user ) + '&user=' + JSON . stringify ( user ) ) ;
2017-11-14 11:49:19 +01:00
}
2017-11-16 14:12:03 +01:00
} ,
2017-12-07 15:21:54 +01:00
changePassword : async ( ctx ) => {
const params = _ . assign ( { } , ctx . request . body , ctx . params ) ;
2017-11-16 14:12:03 +01:00
2017-12-07 15:21:54 +01:00
if ( params . password && params . passwordConfirmation && params . password === params . passwordConfirmation && params . code ) {
const user = await strapi . query ( 'user' , 'users-permissions' ) . findOne ( { resetPasswordToken : params . code } ) ;
2017-11-16 14:12:03 +01:00
2017-12-07 15:21:54 +01:00
if ( ! user ) {
return ctx . badRequest ( null , ctx . request . admin ? [ { messages : [ { id : 'Auth.form.error.code.provide' } ] } ] : 'Incorrect code provided.' ) ;
}
2017-11-16 14:12:03 +01:00
2017-12-07 15:21:54 +01:00
// Delete the current code
user . resetPasswordToken = null ;
2017-11-16 14:12:03 +01:00
2017-12-07 15:21:54 +01:00
user . password = await strapi . plugins [ 'users-permissions' ] . services . user . hashPassword ( params ) ;
2017-11-16 14:29:49 +01:00
2017-12-07 15:21:54 +01:00
// Update the user.
await strapi . query ( 'user' , 'users-permissions' ) . update ( user ) ;
2017-12-06 11:47:39 +01:00
ctx . send ( {
jwt : strapi . plugins [ 'users-permissions' ] . services . jwt . issue ( user ) ,
2017-12-07 14:56:25 +01:00
user : _ . omit ( user . toJSON ? user . toJSON ( ) : user , [ 'password' , 'resetPasswordToken' ] )
2017-12-06 11:47:39 +01:00
} ) ;
2017-12-07 15:21:54 +01:00
} else if ( params . password && params . passwordConfirmation && params . password !== params . passwordConfirmation ) {
return ctx . badRequest ( null , ctx . request . admin ? [ { messages : [ { id : 'Auth.form.error.password.matching' } ] } ] : 'Passwords do not match.' ) ;
} else {
return ctx . badRequest ( null , ctx . request . admin ? [ { messages : [ { id : 'Auth.form.error.params.provide' } ] } ] : 'Incorrect params provided.' ) ;
2017-12-06 11:47:39 +01:00
}
2017-11-16 18:00:15 +01:00
} ,
forgotPassword : async ( ctx ) => {
2017-12-07 18:16:15 +01:00
const { email , url } = ctx . request . body ;
2017-11-16 18:00:15 +01:00
// Find the user user thanks to his email.
const user = await strapi . query ( 'user' , 'users-permissions' ) . findOne ( { email } ) ;
// User not found.
if ( ! user ) {
2017-12-06 11:38:00 +01:00
return ctx . badRequest ( null , ctx . request . admin ? [ { messages : [ { id : 'Auth.form.error.user.not-exist' } ] } ] : 'This email does not exist.' ) ;
2017-11-16 18:00:15 +01:00
}
// Generate random token.
const resetPasswordToken = crypto . randomBytes ( 64 ) . toString ( 'hex' ) ;
2017-11-17 11:41:23 +01:00
// Set the property code.
2017-11-16 18:00:15 +01:00
user . resetPasswordToken = resetPasswordToken ;
2017-12-04 14:00:09 +01:00
// Send an email to the user.
2017-12-04 14:11:00 +01:00
const template = `
< p > We heard that you lost your password . Sorry about that ! < / p >
< p > But don ’ t worry ! You can use the following link to reset your password : < / p >
< p > $ { url } ? code = $ { resetPasswordToken } < / p >
< p > Thanks . < / p >
` ;
2017-12-04 14:00:09 +01:00
try {
await strapi . plugins [ 'email' ] . services . email . send ( {
to : user . email ,
2017-12-05 12:10:08 +01:00
subject : ' Reset password 🔑 ' ,
2017-12-04 14:11:00 +01:00
text : template ,
html : template
2017-12-04 14:00:09 +01:00
} ) ;
} catch ( err ) {
return ctx . badRequest ( null , err ) ;
}
2017-11-16 18:00:15 +01:00
// Update the user.
2017-11-30 11:07:54 +01:00
await strapi . query ( 'user' , 'users-permissions' ) . update ( user ) ;
2017-11-16 18:00:15 +01:00
2017-12-04 13:40:07 +01:00
ctx . send ( { ok : true } ) ;
2017-11-17 11:41:23 +01:00
} ,
2017-12-07 15:21:54 +01:00
register : async ( ctx ) => {
const params = _ . assign ( ctx . request . body , {
provider : 'local'
} ) ;
2017-11-17 11:41:23 +01:00
2017-12-07 15:21:54 +01:00
// Password is required.
if ( ! params . password ) {
return ctx . badRequest ( null , ctx . request . admin ? [ { messages : [ { id : 'Auth.form.error.password.provide' } ] } ] : 'Please provide your password.' ) ;
}
2017-11-17 11:41:23 +01:00
2017-12-07 15:21:54 +01:00
// Throw an error if the password selected by the user
// contains more than two times the symbol '$'.
if ( strapi . plugins [ 'users-permissions' ] . services . user . isHashed ( params . password ) ) {
return ctx . badRequest ( null , ctx . request . admin ? [ { messages : [ { id : 'Auth.form.error.password.format' } ] } ] : 'Your password cannot contain more than three times the symbol `$`.' ) ;
}
2017-11-17 11:41:23 +01:00
2017-12-07 15:21:54 +01:00
// First, check if the user is the first one to register as admin.
const adminUsers = await strapi . query ( 'user' , 'users-permissions' ) . find ( strapi . utils . models . convertParams ( 'user' , { role : '0' } ) ) ;
2017-11-17 11:41:23 +01:00
2017-12-07 15:21:54 +01:00
// Check if the user is the first to register
if ( adminUsers . length === 0 ) {
params . role = '0' ;
} else {
params . role = '1' ;
}
2017-11-17 11:41:23 +01:00
2017-12-07 15:21:54 +01:00
params . password = await strapi . plugins [ 'users-permissions' ] . services . user . hashPassword ( params ) ;
try {
const user = await strapi . query ( 'user' , 'users-permissions' ) . create ( params ) ;
2017-11-17 11:41:23 +01:00
2017-11-20 16:28:50 +01:00
ctx . send ( {
jwt : strapi . plugins [ 'users-permissions' ] . services . jwt . issue ( user ) ,
2017-12-07 14:56:25 +01:00
user : _ . omit ( user . toJSON ? user . toJSON ( ) : user , [ 'password' , 'resetPasswordToken' ] )
2017-11-20 16:28:50 +01:00
} ) ;
2017-12-07 15:21:54 +01:00
} catch ( err ) {
const adminError = _ . includes ( err . message , 'username' ) ? 'Auth.form.error.username.taken' : 'Auth.form.error.email.taken' ;
ctx . badRequest ( null , ctx . request . admin ? [ { messages : [ { id : adminError } ] } ] : err . message ) ;
2017-11-17 11:41:23 +01:00
}
2017-11-14 11:49:19 +01:00
}
} ;