diff --git a/app/controllers/auth_controller.ts b/app/controllers/auth_controller.ts index 847682b..7e80c7b 100644 --- a/app/controllers/auth_controller.ts +++ b/app/controllers/auth_controller.ts @@ -31,7 +31,6 @@ export default class AuthController { const expiresIn = '15 minutes' const payload = await this.authService.generateCode(email, expiresIn) - // Send email await mail .send((message) => { message @@ -62,7 +61,6 @@ export default class AuthController { }) } - // Find user by id const user = await User.findBy('email', email) if (!user) { // If the user does not exist, return a token for registration @@ -75,59 +73,83 @@ export default class AuthController { } } - // Perform login await auth.use('web').login(user, true) // true for remember me return { success: true, - user, } } + // GET /auth/autocomplete + async listNames({ request }: HttpContext) { + const { className } = request.qs() + if (!className) { + return { + success: false, + message: 'Veuillez spécifier une classe', + } + } + + return User.query() + .select('firstName', 'lastName') + .where('className', className) + .orderBy('lastName', 'asc') + .then((users) => { + return { + success: true, + data: users.map((user) => ({ + value: `${user.firstName}::${user.lastName}`, + label: user.fullName, + })), + } + }) + } + // POST /auth/register async register({ request, response, auth }: HttpContext) { - const { firstName, lastName, className, token } = await request.validateUsing(registerValidator) + const { name, className, token } = await request.validateUsing(registerValidator) // Validate token const { success, email } = this.authService.validateToken(token) - if (!success || !email) { + const [firstName, lastName] = name.split('::') + if (!success || !email || !firstName || !lastName) { return response.badRequest({ success: false, message: 'Votre lien de connexion est invalide ou a expiré.', }) } - // Check if user already exists - const existingUser = await User.findBy('email', email) - if (existingUser) { - // If user already exists, perform login - await auth.use('web').login(existingUser, true) // true for remember me - return { - success: true, - user: existingUser, - } + const user = await User.query() + .where('firstName', firstName) + .where('lastName', lastName) + .where('className', className) + .first() + if (!user) { + return response.badRequest({ + success: false, + message: 'Utilisateur non trouvé. Veuillez vérifier vos informations.', + }) } - // TODO: Check if className is allowed (else redirect for account giving) + if (user.email && user.email.toLowerCase() !== email.toLowerCase()) { + return response.badRequest({ + success: false, + message: + "L'email associé à votre compte ne correspond pas à celui utilisé pour la connexion.", + }) + } + + user.email = email.toLowerCase() // Update email if necessary + await user.save() - // TODO: Rewrite user creation (NEVER CREATE USER - use string similarity) - // Create new user - const user = await User.create({ - firstName, - lastName, - className, - email, - }) // Perform login await auth.use('web').login(user, true) // true for remember me return { success: true, - user, } } // POST /auth/logout async logout({ auth }: HttpContext) { - // Logout user await auth.use('web').logout() return { success: true, diff --git a/app/models/user.ts b/app/models/user.ts index f397fe0..56d5170 100644 --- a/app/models/user.ts +++ b/app/models/user.ts @@ -11,10 +11,10 @@ export default class User extends BaseModel { @column() declare className: string - @column() + @column({ serializeAs: null}) declare firstName: string - @column() + @column({ serializeAs: null}) declare lastName: string @computed() diff --git a/app/validators/auth.ts b/app/validators/auth.ts index 47235e9..72653f6 100644 --- a/app/validators/auth.ts +++ b/app/validators/auth.ts @@ -19,16 +19,9 @@ export const verifyCodeValidator = vine.compile( }) ) -function toTitleCase(value: string) { - return value.replace(/\w\S*/g, (txt) => { - return txt.charAt(0).toUpperCase() + txt.substring(1).toLowerCase() - }) -} - export const registerValidator = vine.compile( vine.object({ - firstName: vine.string().minLength(2).maxLength(50).trim().transform(toTitleCase), - lastName: vine.string().minLength(2).maxLength(50).trim().toUpperCase(), + name: vine.string().minLength(2).maxLength(50).trim(), className: vine.string().minLength(2).maxLength(50), token: vine.string(), }) diff --git a/start/routes.ts b/start/routes.ts index f6708bd..81e0e3f 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -22,6 +22,7 @@ router.group(() => { router.post('/auth/verify', [AuthController, 'verifyCode']).use(throttle) router.post('/auth/register', [AuthController, 'register']).use(throttle) router.post('/auth/logout', [AuthController, 'logout']) + router.get('/auth/autocomplete', [AuthController, 'listNames']).use(throttle) // TODO: Magic link login // router.get('/auth/magic-link', 'AuthController.magicLink').use(throttle) // router.get('/auth/listen', 'AuthController.listen')