diff --git a/src/db/schema/user.schema.ts b/src/db/schema/user.schema.ts index d6c6dd349c680eaf7dbe2ee7065b6fc0f9457c8d..f0b89c6411745c0d49d4c9a958e6d109e77258b8 100644 --- a/src/db/schema/user.schema.ts +++ b/src/db/schema/user.schema.ts @@ -54,8 +54,7 @@ const userInputSchema = createInsertSchema(userTable) password: true, email: true, birthday: true, - cpf: true, - user_stats_id: true + cpf: true }) const userModelSchema = createSelectSchema(userTable) const userDtoSchema = createSelectSchema(userTable).omit({ diff --git a/src/index.ts b/src/index.ts index 5f9c51395795753ba85bfc86c4c915a627b64b95..0e8f3a5ee5132bb4ca80c614aee172875eaaf332 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,7 +12,7 @@ import { userStatsRouter } from './routes/user-stats.route' import { publicResourceRouter, resourceRouter } from './routes/resource.route' import { publicResourceStatsRouter, resourceStatsRouter } from './routes/resource-stats.route' import { collectionsRouter, getCollections } from './routes/collections.route' -import { signUpRouter, userRouter } from './routes/user.route' +import { userRouter } from './routes/user.route' import { uploaderRouter } from './routes/uploader.route' import { collectionsStatsRouter, getCollectionsStats } from './routes/collection-stats.route' import { publicSubjectsRouter, subjectsRouter } from './routes/subjects.route' @@ -20,7 +20,6 @@ import { submissionRouter } from './routes/submission.route' import { licenseRouter, publicLicenseRouter } from './routes/license.route' import { languageRouter, publicLanguageRouter } from './routes/language.route' import { educationalStageRouter, publicEducationalStageRouter } from './routes/educational-stage.route' -import { passRouter } from './routes/password.route' import { objectTypeRouter, publicObjectTypeRouter } from './routes/object-type.route' import { roleRouter } from './routes/role.route' import { complaintsRouter } from './routes/complaints.route' @@ -77,8 +76,6 @@ app.get('/', (c) => c.json({ message: 'sv running on /api' })) app .basePath('/public') .route('/auth', authRouter) - .route('/signup', signUpRouter) - .route('/reset-password', passRouter) .route('/resource', publicResourceRouter) .route('/statsResource', publicResourceStatsRouter) .route('/subjects', publicSubjectsRouter) diff --git a/src/routes/auth.route.ts b/src/routes/auth.route.ts index f3d0c2f8c45198dba32680542651ef62f9d53a79..ce9b45b747d1b6e2dbc63aeb434385df61dbaffc 100644 --- a/src/routes/auth.route.ts +++ b/src/routes/auth.route.ts @@ -1,20 +1,29 @@ import { authSchema } from '@/db/repo/auth.repo' -import { AuhtService } from '@/services/auth.service' +import type { PasswordRecoveryModel } from '@/db/schema/password-recovery.schema' +import { userStatsSchemas } from '@/db/schema/user-stats.schema' +import { userSchemas } from '@/db/schema/user.schema' +import { AuthService } from '@/services/auth.service' import { HttpStatus, createApexError } from '@/services/error.service' +import { PasswordRecoveryService } from '@/services/password.service' +import { UserStatsService } from '@/services/user-stats.service' +import { UserService } from '@/services/user.service' import { zValidator } from '@hono/zod-validator' import { Hono } from 'hono' import Container from 'typedi' -const service = Container.get(AuhtService) +const authService = Container.get(AuthService) +const userService = Container.get(UserService) +const userStatsService = Container.get(UserStatsService) +const passwordRecoveryService = Container.get(PasswordRecoveryService) export const authRouter = new Hono().post( - '/', + '/signin', zValidator('json', authSchema), async (c) => { try { const input = await c.req.valid('json') - const token = await service.login(input) + const token = await authService.login(input) return c.json({ token }) } catch (e) { @@ -31,3 +40,131 @@ export const authRouter = new Hono().post( } } ) +.post('/signup', + zValidator('json', userSchemas.userInputSchema), + async (c) => { + try { + const input = await c.req.valid('json') + + const userStats = userStatsSchemas.dto.parse(await userStatsService.create()) + input.user_stats_id = userStats.id + const user = userSchemas.userDtoSchema.parse( + await userService.create(input) + ) + + return c.json({ user, userStats }) + } catch (e) { + return c.text('could not create') + } +}) +.post('/request/:email', + async (c) => { + try{ + const email: string = c.req.param('email') + const user = userSchemas.userDtoSchema.parse( + await userService.findByEmail(email) + ) + + /* + * When a ticket is generated, the last one is deleted + */ + const ticketList = await passwordRecoveryService.findByUserId(user.id) + if(ticketList?.length != 0){ + const lastTicket = ticketList![ticketList!.length - 1] + if(lastTicket.validToken){ + await passwordRecoveryService.delete(lastTicket.id) + } + + } + const resetTicket = await passwordRecoveryService.create(user) + return c.json(resetTicket) + + /** + * To-do: send email + * const subject = "Plataforma MEC de Recursos Educacionais - Redefinição de senha" + * + * const content = passwordRecoveryService.emailTemplatePasswordRecovery(resetTicket); + * await emailService.sendEmail(user.email, subject, content) + * return c.json({ + * message: { + * status: 'success', + * message: 'email sent successfully', + * code: HttpStatus.OK + * } + * }) + */ + } catch (e) { + return c.json( + createApexError({ + status: 'error', + message: 'could not send recovery password email', + code: HttpStatus.BAD_REQUEST, + path: c.req.routePath, + suggestion: 'check the input and try again', + }), + HttpStatus.BAD_REQUEST + ) + } +}) +.post( + '/reset', +//url preview: reset?email=admin%40admin.com&token=xEakn2HpEaH8Xvyz8fsntYvmHip8IVP0NZu7bWpjkEY&password= + async (c) => { + try { + /* + * Variable declaration section + */ + const email = c.req.queries('email') + const password = c.req.queries('password') + const token = c.req.queries('token') + if(email == null || password == null|| token == null) + throw new Error(); + const user = await userService.findByEmail(email[0]) + if(user == null) + throw new Error(); + + const resetTickets = await passwordRecoveryService.findByUserId(user.id) + if(resetTickets == null) + throw new Error(); + + /* + * Find reset ticket in database + */ + let resetTicket: PasswordRecoveryModel | any = null + resetTickets.forEach(element => { + if(element.tokenHash == token[0]) + resetTicket = element + }); + + /* + * Check if the ticket is valid (expired, used, new ticket generated) + */ + if(passwordRecoveryService.isNotValidTicket(resetTicket)) + throw new Error(); + + /* + * Set user new password and update it + */ + user.password = password[0] + + const ret = userSchemas.userDtoSchema.parse( + await userService.update(user) + ) + + await passwordRecoveryService.delete(resetTicket.id) + + return c.json({ user: ret }) + } catch (e) { + return c.json( + createApexError({ + status: 'error', + message: 'could not send recovery password email', + code: HttpStatus.BAD_REQUEST, + path: c.req.routePath, + suggestion: 'check the input and try again', + }), + HttpStatus.BAD_REQUEST + ) + } + } +) \ No newline at end of file diff --git a/src/routes/password.route.ts b/src/routes/password.route.ts deleted file mode 100644 index 3e0753a33f7cda83dd655f43b242abd220772ee9..0000000000000000000000000000000000000000 --- a/src/routes/password.route.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { Hono } from "hono"; -import { userSchemas } from "@/db/schema/user.schema"; -import { UserService } from "@/services/user.service"; -import { PasswordRecoveryService } from "@/services/password.service"; -import { HttpStatus, createApexError } from "@/services/error.service"; -import Container from "typedi"; -import type { PasswordRecoveryModel } from "@/db/schema/password-recovery.schema"; - -const userService = Container.get(UserService) -const passwordRecoveryService = Container.get(PasswordRecoveryService) - -export const passRouter = new Hono() -.post( - '/reset', -//url preview: reset?email=admin%40admin.com&token=xEakn2HpEaH8Xvyz8fsntYvmHip8IVP0NZu7bWpjkEY&password= - async (c) => { - try { - /* - * Variable declaration section - */ - const email = c.req.queries('email') - const password = c.req.queries('password') - const token = c.req.queries('token') - if(email == null || password == null|| token == null) - throw new Error(); - const user = await userService.findByEmail(email[0]) - if(user == null) - throw new Error(); - - const resetTickets = await passwordRecoveryService.findByUserId(user.id) - if(resetTickets == null) - throw new Error(); - - /* - * Find reset ticket in database - */ - let resetTicket: PasswordRecoveryModel | any = null - resetTickets.forEach(element => { - if(element.tokenHash == token[0]) - resetTicket = element - }); - - /* - * Check if the ticket is valid (expired, used, new ticket generated) - */ - if(passwordRecoveryService.isNotValidTicket(resetTicket)) - throw new Error(); - - /* - * Set user new password and update it - */ - user.password = password[0] - - const ret = userSchemas.userDtoSchema.parse( - await userService.update(user) - ) - - await passwordRecoveryService.delete(resetTicket.id) - - return c.json({ ret }) - } catch (e) { - return c.json( - createApexError({ - status: 'error', - message: 'could not send recovery password email', - code: HttpStatus.BAD_REQUEST, - path: c.req.routePath, - suggestion: 'check the input and try again', - }), - HttpStatus.BAD_REQUEST - ) - } - } -) -.post('/:email', - async (c) => { - try{ - const email = c.req.param('email') - const user = userSchemas.userDtoSchema.parse( - await userService.findByEmail(email) - ) - - /* - * When a ticket is generated, the last one is deleted - */ - const ticketList = await passwordRecoveryService.findByUserId(user.id) - if(ticketList?.length != 0){ - const lastTicket = ticketList![ticketList!.length - 1] - if(lastTicket.validToken){ - await passwordRecoveryService.delete(lastTicket.id) - } - - } - const resetTicket = await passwordRecoveryService.create(user) - return c.json(resetTicket) - - /** - * To-do: send email - * const subject = "Plataforma MEC de Recursos Educacionais - Redefinição de senha" - * - * const content = passwordRecoveryService.emailTemplatePasswordRecovery(resetTicket); - * await emailService.sendEmail(user.email, subject, content) - * return c.json({ - * message: { - * status: 'success', - * message: 'email sent successfully', - * code: HttpStatus.OK - * } - * }) - */ - } catch (e) { - return c.json( - createApexError({ - status: 'error', - message: 'could not send recovery password email', - code: HttpStatus.BAD_REQUEST, - path: c.req.routePath, - suggestion: 'check the input and try again', - }), - HttpStatus.BAD_REQUEST - ) - } - }) - \ No newline at end of file diff --git a/src/routes/user.route.ts b/src/routes/user.route.ts index 20948f434403db2a381d97f08bd4c3a321ee9826..c817ccd3e7a22d3be09233b66b4282612f83898f 100644 --- a/src/routes/user.route.ts +++ b/src/routes/user.route.ts @@ -4,36 +4,15 @@ import { Container } from 'typedi' import { z } from 'zod' import { zValidator } from '@hono/zod-validator' import { honoWithJwt } from '..' -import { Hono } from 'hono' import { createApexError, HttpStatus } from '@/services/error.service' import { followRelationSchemas } from '@/db/relations/followers.relation' import { UserStatsService } from '@/services/user-stats.service' import { FollowRelationService } from '@/services/follow.relation.service' -import { userStatsSchemas } from '@/db/schema/user-stats.schema' const service = Container.get(UserService) const followService = Container.get(FollowRelationService) const userStatsService = Container.get(UserStatsService) -export const signUpRouter = new Hono() - .post('/', - zValidator('json', userSchemas.userInputSchema), - async (c) => { - try { - const input = await c.req.valid('json') - - const userStats = userStatsSchemas.dto.parse(await userStatsService.create()) - input.user_stats_id = userStats.id - const user = userSchemas.userDtoSchema.parse( - await service.create(input) - ) - - return c.json({ user }) - } catch (e) { - return c.text('could not create') - } - }) - export const userRouter = honoWithJwt() .post('/follow', zValidator('json', followRelationSchemas.input), diff --git a/src/services/auth.service.ts b/src/services/auth.service.ts index 6f7bcaa9c4f15a75fe4e2be032a0a79257fa42c4..bf01c8bca738d3e6f296c2c1a31070d00e8bf759 100644 --- a/src/services/auth.service.ts +++ b/src/services/auth.service.ts @@ -10,7 +10,7 @@ import { } from '@/db/repo/auth.repo' @Service() -export class AuhtService { +export class AuthService { @Inject() private readonly userService: UserService