2017-11-14 11:49:19 +01:00
'use strict' ;
/ * *
* Auth . js controller
*
* @ description : A set of functions called "actions" for managing ` Auth ` .
* /
2018-04-30 18:26:56 +02:00
/* eslint-disable no-useless-escape */
2017-11-16 18:00:15 +01:00
const crypto = require ( 'crypto' ) ;
2018-04-30 18:26:56 +02:00
const _ = require ( 'lodash' ) ;
2021-11-05 10:40:11 +01:00
const utils = require ( '@strapi/utils' ) ;
2021-07-08 18:15:32 +02:00
const { getService } = require ( '../utils' ) ;
2021-10-20 17:30:05 +02:00
const {
validateCallbackBody ,
validateRegisterBody ,
validateSendEmailConfirmationBody ,
} = require ( './validation/auth' ) ;
2019-01-18 16:08:15 +01:00
2022-03-21 11:04:54 +01:00
const { getAbsoluteAdminUrl , getAbsoluteServerUrl , sanitize } = utils ;
2021-11-05 10:40:11 +01:00
const { ApplicationError , ValidationError } = utils . errors ;
2019-01-18 16:08:15 +01:00
2018-01-23 13:35:51 +01:00
const emailRegExp = /^(([^<>()\[\]\\.,;:\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,}))$/ ;
2017-11-16 14:12:03 +01:00
2021-11-04 15:47:53 +01:00
const sanitizeUser = ( user , ctx ) => {
const { auth } = ctx . state ;
const userSchema = strapi . getModel ( 'plugin::users-permissions.user' ) ;
return sanitize . contentAPI . output ( user , userSchema , { auth } ) ;
} ;
2017-11-14 11:49:19 +01:00
module . exports = {
2019-07-15 23:16:50 +02:00
async callback ( ctx ) {
2017-11-14 11:49:19 +01:00
const provider = ctx . params . provider || 'local' ;
const params = ctx . request . body ;
2022-02-23 22:51:59 +08:00
const store = strapi . store ( { type : 'plugin' , name : 'users-permissions' } ) ;
2018-02-06 13:10:43 +01:00
2017-11-14 11:49:19 +01:00
if ( provider === 'local' ) {
2019-08-21 12:10:23 +02:00
if ( ! _ . get ( await store . get ( { key : 'grant' } ) , 'email.enabled' ) ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( 'This provider is disabled' ) ;
2018-01-18 16:01:52 +01:00
}
2021-10-20 17:30:05 +02:00
await validateCallbackBody ( params ) ;
2017-11-14 11:49:19 +01:00
2020-05-08 13:50:00 +02:00
const query = { provider } ;
2017-11-14 11:49:19 +01:00
// Check if the provided identifier is an email or not.
2018-01-23 13:35:51 +01:00
const isEmail = emailRegExp . test ( params . identifier ) ;
2017-11-14 11:49:19 +01:00
// Set the identifier to the appropriate query field.
if ( isEmail ) {
2018-01-23 13:35:51 +01:00
query . email = params . identifier . toLowerCase ( ) ;
2017-11-14 11:49:19 +01:00
} else {
query . username = params . identifier ;
}
2019-08-06 00:51:27 +02:00
// Check if the user exists.
2021-08-06 18:09:49 +02:00
const user = await strapi . query ( 'plugin::users-permissions.user' ) . findOne ( { where : query } ) ;
2017-11-20 16:28:50 +01:00
if ( ! user ) {
2021-10-20 17:30:05 +02:00
throw new ValidationError ( 'Invalid identifier or password' ) ;
2018-10-23 18:44:49 +02:00
}
2017-11-20 16:28:50 +01:00
2019-04-09 12:09:03 +02:00
if (
_ . get ( await store . get ( { key : 'advanced' } ) , 'email_confirmation' ) &&
user . confirmed !== true
) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( 'Your account email is not confirmed' ) ;
2018-09-05 11:14:03 +02:00
}
2019-04-09 12:09:03 +02:00
if ( user . blocked === true ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( 'Your account has been blocked by an administrator' ) ;
2018-01-24 11:38:42 +01:00
}
2018-03-14 16:56:12 +01:00
// The user never authenticated with the `local` provider.
2017-11-20 16:28:50 +01:00
if ( ! user . password ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError (
'This user never set a local password, please login with the provider used during account creation'
2019-04-09 12:09:03 +02:00
) ;
2017-11-20 16:28:50 +01:00
}
2021-08-19 22:27:00 +02:00
const validPassword = await getService ( 'user' ) . validatePassword (
params . password ,
user . password
) ;
2017-11-20 16:28:50 +01:00
if ( ! validPassword ) {
2021-10-20 17:30:05 +02:00
throw new ValidationError ( 'Invalid identifier or password' ) ;
2017-11-20 16:28:50 +01:00
} else {
ctx . send ( {
2021-08-19 22:27:00 +02:00
jwt : getService ( 'jwt' ) . issue ( {
2019-08-13 16:31:29 +02:00
id : user . id ,
} ) ,
2021-11-04 15:47:53 +01:00
user : await sanitizeUser ( user , ctx ) ,
2017-11-20 16:28:50 +01:00
} ) ;
2017-11-14 11:49:19 +01:00
}
} else {
2019-04-09 12:09:03 +02:00
if ( ! _ . get ( await store . get ( { key : 'grant' } ) , [ provider , 'enabled' ] ) ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( 'This provider is disabled' ) ;
2018-01-29 13:12:49 +01:00
}
2020-01-10 07:40:17 -05:00
// Connect the user with the third-party provider.
2018-01-25 11:52:17 +01:00
try {
2022-02-23 22:51:59 +08:00
const user = await getService ( 'providers' ) . connect ( provider , ctx . query ) ;
ctx . send ( {
jwt : getService ( 'jwt' ) . issue ( { id : user . id } ) ,
user : await sanitizeUser ( user , ctx ) ,
} ) ;
} catch ( error ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( error . message ) ;
2018-01-25 15:04:42 +01:00
}
2017-11-14 11:49:19 +01:00
}
2017-11-16 14:12:03 +01:00
} ,
2020-03-30 15:13:27 -04:00
async resetPassword ( ctx ) {
2017-12-07 15:21:54 +01:00
const params = _ . assign ( { } , ctx . request . body , ctx . params ) ;
2017-11-16 14:12:03 +01:00
2019-04-09 12:09:03 +02:00
if (
params . password &&
params . passwordConfirmation &&
params . password === params . passwordConfirmation &&
params . code
) {
2019-07-15 23:16:50 +02:00
const user = await strapi
2021-08-06 18:09:49 +02:00
. query ( 'plugin::users-permissions.user' )
2021-07-08 18:15:32 +02:00
. findOne ( { where : { resetPasswordToken : ` ${ params . code } ` } } ) ;
2017-11-16 14:12:03 +01:00
2017-12-07 15:21:54 +01:00
if ( ! user ) {
2021-10-20 17:30:05 +02:00
throw new ValidationError ( 'Incorrect code provided' ) ;
2017-12-07 15:21:54 +01:00
}
2017-11-16 14:12:03 +01:00
2022-03-11 11:08:17 +01:00
await getService ( 'user' ) . edit ( user . id , {
resetPasswordToken : null ,
password : params . password ,
} ) ;
2017-12-07 15:21:54 +01:00
// Update the user.
2017-12-06 11:47:39 +01:00
ctx . send ( {
2021-08-19 22:27:00 +02:00
jwt : getService ( 'jwt' ) . issue ( { id : user . id } ) ,
2021-11-04 15:47:53 +01:00
user : await sanitizeUser ( user , ctx ) ,
2017-12-06 11:47:39 +01:00
} ) ;
2019-04-09 12:09:03 +02:00
} else if (
params . password &&
params . passwordConfirmation &&
params . password !== params . passwordConfirmation
) {
2021-10-20 17:30:05 +02:00
throw new ValidationError ( 'Passwords do not match' ) ;
2017-12-07 15:21:54 +01:00
} else {
2021-10-20 17:30:05 +02:00
throw new ValidationError ( 'Incorrect params provided' ) ;
2017-12-06 11:47:39 +01:00
}
2017-11-16 18:00:15 +01:00
} ,
2019-07-15 23:16:50 +02:00
async connect ( ctx , next ) {
2021-09-03 11:11:37 +02:00
const grant = require ( 'grant-koa' ) ;
2021-11-29 16:05:45 +01:00
const providers = await strapi
2021-09-13 12:03:12 +02:00
. store ( { type : 'plugin' , name : 'users-permissions' , key : 'grant' } )
2019-04-09 12:09:03 +02:00
. get ( ) ;
2021-11-29 16:05:45 +01:00
const apiPrefix = strapi . config . get ( 'api.rest.prefix' ) ;
const grantConfig = {
defaults : {
prefix : ` ${ apiPrefix } /connect ` ,
} ,
... providers ,
} ;
2020-01-15 11:18:12 +01:00
const [ requestPath ] = ctx . request . url . split ( '?' ) ;
2021-09-29 12:04:42 +02:00
const provider = requestPath . split ( '/connect/' ) [ 1 ] . split ( '/' ) [ 0 ] ;
2018-01-25 09:59:24 +01:00
2020-05-08 13:50:00 +02:00
if ( ! _ . get ( grantConfig [ provider ] , 'enabled' ) ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( 'This provider is disabled' ) ;
2018-01-25 09:59:24 +01:00
}
2020-07-22 15:30:17 +02:00
if ( ! strapi . config . server . url . startsWith ( 'http' ) ) {
strapi . log . warn (
2021-11-29 07:01:25 -08:00
'You are using a third party provider for login. Make sure to set an absolute url in config/server.js. More info here: https://docs.strapi.io/developer-docs/latest/plugins/users-permissions.html#setting-up-the-server-url'
2020-07-22 15:30:17 +02:00
) ;
}
2019-08-26 10:41:50 +04:30
// Ability to pass OAuth callback dynamically
2021-12-21 12:12:55 +01:00
grantConfig [ provider ] . callback =
_ . get ( ctx , 'query.callback' ) ||
_ . get ( ctx , 'session.grant.dynamic.callback' ) ||
grantConfig [ provider ] . callback ;
2021-08-19 22:27:00 +02:00
grantConfig [ provider ] . redirect _uri = getService ( 'providers' ) . buildRedirectUri ( provider ) ;
2020-05-08 13:50:00 +02:00
2019-06-27 18:24:04 +02:00
return grant ( grantConfig ) ( ctx , next ) ;
2018-01-25 09:59:24 +01:00
} ,
2019-07-15 23:16:50 +02:00
async forgotPassword ( ctx ) {
2019-11-26 16:03:06 +01:00
let { email } = ctx . request . body ;
// Check if the provided email is valid or not.
const isEmail = emailRegExp . test ( email ) ;
if ( isEmail ) {
email = email . toLowerCase ( ) ;
} else {
2021-10-20 17:30:05 +02:00
throw new ValidationError ( 'Please provide a valid email address' ) ;
2019-11-26 16:03:06 +01:00
}
2019-10-09 17:37:16 +02:00
2021-09-13 12:03:12 +02:00
const pluginStore = await strapi . store ( { type : 'plugin' , name : 'users-permissions' } ) ;
2017-11-16 18:00:15 +01:00
2020-01-10 07:40:17 -05:00
// Find the user by email.
2020-09-23 14:25:55 +02:00
const user = await strapi
2021-08-06 18:09:49 +02:00
. query ( 'plugin::users-permissions.user' )
2021-07-08 18:15:32 +02:00
. findOne ( { where : { email : email . toLowerCase ( ) } } ) ;
2017-11-16 18:00:15 +01:00
// User not found.
if ( ! user ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( 'This email does not exist' ) ;
2017-11-16 18:00:15 +01:00
}
2021-08-23 15:11:15 -07:00
// User blocked
if ( user . blocked ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( 'This user is disabled' ) ;
2021-08-23 15:11:15 -07:00
}
2017-11-16 18:00:15 +01:00
// Generate random token.
const resetPasswordToken = crypto . randomBytes ( 64 ) . toString ( 'hex' ) ;
2020-03-06 19:16:23 +01:00
const settings = await pluginStore . get ( { key : 'email' } ) . then ( storeEmail => {
try {
return storeEmail [ 'reset_password' ] . options ;
} catch ( error ) {
return { } ;
}
} ) ;
2019-10-09 17:37:16 +02:00
const advanced = await pluginStore . get ( {
key : 'advanced' ,
} ) ;
2019-04-09 12:09:03 +02:00
2021-11-04 15:47:53 +01:00
const userInfo = await sanitizeUser ( user , ctx ) ;
2020-06-15 10:34:59 +02:00
2021-07-08 18:15:32 +02:00
settings . message = await getService ( 'users-permissions' ) . template ( settings . message , {
URL : advanced . email _reset _password ,
2022-03-07 16:08:47 +01:00
SERVER _URL : getAbsoluteServerUrl ( strapi . config ) ,
2022-03-21 11:04:54 +01:00
ADMIN _URL : getAbsoluteAdminUrl ( strapi . config ) ,
2021-07-08 18:15:32 +02:00
USER : userInfo ,
TOKEN : resetPasswordToken ,
} ) ;
2017-12-04 14:11:00 +01:00
2021-07-08 18:15:32 +02:00
settings . object = await getService ( 'users-permissions' ) . template ( settings . object , {
USER : userInfo ,
} ) ;
2019-03-01 16:28:44 +01:00
2017-12-04 14:00:09 +01:00
try {
2018-01-15 14:50:53 +01:00
// Send an email to the user.
2021-08-19 22:27:00 +02:00
await strapi
. plugin ( 'email' )
. service ( 'email' )
. send ( {
to : user . email ,
from :
settings . from . email || settings . from . name
? ` ${ settings . from . name } < ${ settings . from . email } > `
: undefined ,
replyTo : settings . response _email ,
subject : settings . object ,
text : settings . message ,
html : settings . message ,
} ) ;
2017-12-04 14:00:09 +01:00
} catch ( err ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( err . message ) ;
2017-12-04 14:00:09 +01:00
}
2017-11-16 18:00:15 +01:00
// Update the user.
2021-07-08 18:15:32 +02:00
await strapi
2021-08-06 18:09:49 +02:00
. query ( 'plugin::users-permissions.user' )
2021-07-08 18:15:32 +02:00
. update ( { where : { id : user . id } , data : { resetPasswordToken } } ) ;
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
} ,
2019-07-15 23:16:50 +02:00
async register ( ctx ) {
2021-09-13 12:03:12 +02:00
const pluginStore = await strapi . store ( { type : 'plugin' , name : 'users-permissions' } ) ;
2018-08-23 18:28:13 +02:00
const settings = await pluginStore . get ( {
2019-04-09 12:09:03 +02:00
key : 'advanced' ,
2018-08-23 18:28:13 +02:00
} ) ;
2018-03-12 16:06:54 +01:00
if ( ! settings . allow _register ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( 'Register action is currently disabled' ) ;
2018-01-15 15:19:59 +01:00
}
2020-05-05 14:41:30 +02:00
const params = {
2020-10-16 16:53:40 +02:00
... _ . omit ( ctx . request . body , [ 'confirmed' , 'confirmationToken' , 'resetPasswordToken' ] ) ,
2019-04-09 12:09:03 +02:00
provider : 'local' ,
2020-05-05 14:41:30 +02:00
} ;
2017-11-17 11:41:23 +01:00
2021-10-20 17:30:05 +02:00
await validateRegisterBody ( params ) ;
2019-07-15 23:16:50 +02:00
2017-12-07 15:21:54 +01:00
// Throw an error if the password selected by the user
2020-09-03 09:51:38 +02:00
// contains more than three times the symbol '$'.
2021-07-08 18:15:32 +02:00
if ( getService ( 'user' ) . isHashed ( params . password ) ) {
2021-10-20 17:30:05 +02:00
throw new ValidationError (
'Your password cannot contain more than three times the symbol `$`'
2019-04-09 12:09:03 +02:00
) ;
2017-12-07 15:21:54 +01:00
}
2017-11-17 11:41:23 +01:00
2019-07-15 23:16:50 +02:00
const role = await strapi
2021-08-06 18:09:49 +02:00
. query ( 'plugin::users-permissions.role' )
2021-07-08 18:15:32 +02:00
. findOne ( { where : { type : settings . default _role } } ) ;
2018-01-17 18:50:12 +01:00
if ( ! role ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( 'Impossible to find the default role' ) ;
2017-12-07 15:21:54 +01:00
}
2017-11-17 11:41:23 +01:00
2018-07-13 20:29:41 +05:30
// Check if the provided email is valid or not.
const isEmail = emailRegExp . test ( params . email ) ;
2018-01-24 11:52:09 +01:00
2018-01-23 13:35:51 +01:00
if ( isEmail ) {
2018-07-13 20:29:41 +05:30
params . email = params . email . toLowerCase ( ) ;
2019-11-03 10:41:21 +11:00
} else {
2021-10-20 17:30:05 +02:00
throw new ValidationError ( 'Please provide a valid email address' ) ;
2018-01-23 13:35:51 +01:00
}
2018-01-24 11:52:09 +01:00
2019-08-13 16:31:29 +02:00
params . role = role . id ;
2017-12-07 15:21:54 +01:00
2021-08-06 18:09:49 +02:00
const user = await strapi . query ( 'plugin::users-permissions.user' ) . findOne ( {
2021-07-08 18:15:32 +02:00
where : { email : params . email } ,
2019-07-15 23:16:50 +02:00
} ) ;
2018-01-15 17:58:11 +01:00
if ( user && user . provider === params . provider ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( 'Email is already taken' ) ;
2018-01-15 17:58:11 +01:00
}
2018-09-03 14:19:51 +02:00
if ( user && user . provider !== params . provider && settings . unique _email ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( 'Email is already taken' ) ;
2018-01-15 17:58:11 +01:00
}
2017-12-07 15:21:54 +01:00
try {
2018-08-23 18:28:13 +02:00
if ( ! settings . email _confirmation ) {
params . confirmed = true ;
}
2022-03-10 17:51:47 +01:00
const user = await getService ( 'user' ) . add ( params ) ;
2017-11-17 11:41:23 +01:00
2021-11-04 15:47:53 +01:00
const sanitizedUser = await sanitizeUser ( user , ctx ) ;
2018-08-08 17:57:02 +02:00
if ( settings . email _confirmation ) {
try {
2021-11-04 15:47:53 +01:00
await getService ( 'user' ) . sendConfirmationEmail ( sanitizedUser ) ;
2018-08-08 17:57:02 +02:00
} catch ( err ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( err . message ) ;
2018-08-08 17:57:02 +02:00
}
2020-10-16 16:53:40 +02:00
return ctx . send ( { user : sanitizedUser } ) ;
2018-08-08 17:57:02 +02:00
}
2021-08-19 22:27:00 +02:00
const jwt = getService ( 'jwt' ) . issue ( _ . pick ( user , [ 'id' ] ) ) ;
2020-10-16 16:53:40 +02:00
return ctx . send ( {
jwt ,
user : sanitizedUser ,
2017-11-20 16:28:50 +01:00
} ) ;
2019-04-09 12:09:03 +02:00
} catch ( err ) {
2021-10-20 17:30:05 +02:00
if ( _ . includes ( err . message , 'username' ) ) {
throw new ApplicationError ( 'Username already taken' ) ;
2022-01-29 22:16:18 +01:00
} else if ( _ . includes ( err . message , 'email' ) ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( 'Email already taken' ) ;
2022-01-29 22:16:18 +01:00
} else {
strapi . log . error ( err ) ;
throw new ApplicationError ( 'An error occurred during account creation' ) ;
2021-10-20 17:30:05 +02:00
}
2017-11-17 11:41:23 +01:00
}
2018-08-08 17:57:02 +02:00
} ,
2020-04-15 21:23:14 +02:00
async emailConfirmation ( ctx , next , returnUser ) {
2020-10-16 16:53:40 +02:00
const { confirmation : confirmationToken } = ctx . query ;
2018-08-08 17:57:02 +02:00
2021-08-19 22:27:00 +02:00
const userService = getService ( 'user' ) ;
const jwtService = getService ( 'jwt' ) ;
2018-08-08 17:57:02 +02:00
2020-10-16 16:53:40 +02:00
if ( _ . isEmpty ( confirmationToken ) ) {
2021-10-20 17:30:05 +02:00
throw new ValidationError ( 'token.invalid' ) ;
2020-10-16 16:53:40 +02:00
}
2022-05-14 09:00:44 +02:00
const [ user ] = await userService . fetchAll ( { filters : { confirmationToken } } ) ;
2020-10-16 16:53:40 +02:00
if ( ! user ) {
2021-10-20 17:30:05 +02:00
throw new ValidationError ( 'token.invalid' ) ;
2020-10-16 16:53:40 +02:00
}
2022-01-05 23:54:58 +09:00
await userService . edit ( user . id , { confirmed : true , confirmationToken : null } ) ;
2018-08-08 17:57:02 +02:00
2020-05-05 14:41:30 +02:00
if ( returnUser ) {
2020-03-23 17:57:54 +01:00
ctx . send ( {
2020-10-16 16:53:40 +02:00
jwt : jwtService . issue ( { id : user . id } ) ,
2021-11-04 15:47:53 +01:00
user : await sanitizeUser ( user , ctx ) ,
2020-03-23 17:57:54 +01:00
} ) ;
} else {
const settings = await strapi
2021-09-13 12:03:12 +02:00
. store ( { type : 'plugin' , name : 'users-permissions' , key : 'advanced' } )
2020-03-23 17:57:54 +01:00
. get ( ) ;
2018-08-08 17:57:02 +02:00
2020-03-23 17:57:54 +01:00
ctx . redirect ( settings . email _confirmation _redirection || '/' ) ;
}
2019-04-09 12:09:03 +02:00
} ,
2019-11-13 18:45:23 +01:00
async sendEmailConfirmation ( ctx ) {
const params = _ . assign ( ctx . request . body ) ;
2021-10-20 17:30:05 +02:00
await validateSendEmailConfirmationBody ( params ) ;
2019-11-13 18:45:23 +01:00
const isEmail = emailRegExp . test ( params . email ) ;
if ( isEmail ) {
params . email = params . email . toLowerCase ( ) ;
} else {
2021-10-20 17:30:05 +02:00
throw new ValidationError ( 'wrong.email' ) ;
2019-11-13 18:45:23 +01:00
}
2021-08-06 18:09:49 +02:00
const user = await strapi . query ( 'plugin::users-permissions.user' ) . findOne ( {
2021-07-08 18:15:32 +02:00
where : { email : params . email } ,
2019-11-13 18:45:23 +01:00
} ) ;
2022-01-28 22:03:23 +01:00
if ( ! user ) {
2022-03-10 17:51:47 +01:00
return ctx . send ( {
email : params . email ,
2022-03-11 11:08:17 +01:00
sent : true ,
2022-03-10 17:51:47 +01:00
} ) ;
2022-01-28 22:03:23 +01:00
}
2019-11-13 18:45:23 +01:00
if ( user . confirmed ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( 'already.confirmed' ) ;
2019-11-13 18:45:23 +01:00
}
if ( user . blocked ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( 'blocked.user' ) ;
2019-11-13 18:45:23 +01:00
}
try {
2021-07-08 18:15:32 +02:00
await getService ( 'user' ) . sendConfirmationEmail ( user ) ;
2019-11-13 18:45:23 +01:00
ctx . send ( {
2020-10-16 16:53:40 +02:00
email : user . email ,
2019-11-26 16:03:06 +01:00
sent : true ,
2019-11-13 18:45:23 +01:00
} ) ;
} catch ( err ) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError ( err . message ) ;
2019-11-13 18:45:23 +01:00
}
} ,
2017-11-14 11:49:19 +01:00
} ;