boredgame/src/lib/server/api/controllers/iam.controller.ts

65 lines
2.6 KiB
TypeScript
Raw Normal View History

import { Hono } from 'hono'
import { inject, injectable } from 'tsyringe'
import { setCookie } from 'hono/cookie'
import { zValidator } from '@hono/zod-validator'
import type { HonoTypes } from '../types'
import { requireAuth } from '../middleware/auth.middleware'
import type { Controller } from '$lib/server/api/interfaces/controller.interface'
import { IamService } from '$lib/server/api/services/iam.service'
import { LuciaProvider } from '$lib/server/api/providers'
import { limiter } from '$lib/server/api/middleware/rate-limiter.middleware'
import { updateProfileDto } from '$lib/dtos/update-profile.dto'
import { updateEmailDto } from '$lib/dtos/update-email.dto'
import { StatusCodes } from '$lib/constants/status-codes'
2024-07-21 19:05:48 +00:00
@injectable()
export class IamController implements Controller {
controller = new Hono<HonoTypes>()
2024-07-21 19:05:48 +00:00
constructor(
@inject(IamService) private readonly iamService: IamService,
@inject(LuciaProvider) private lucia: LuciaProvider,
) {}
routes() {
return this.controller
.get('/', requireAuth, async (c) => {
const user = c.var.user
return c.json({ user })
2024-08-15 23:46:58 +00:00
})
.put('/update/profile', requireAuth, zValidator('json', updateProfileDto), limiter({ limit: 30, minutes: 60 }), async (c) => {
const user = c.var.user
const { firstName, lastName, username } = c.req.valid('json')
const updatedUser = await this.iamService.updateProfile(user.id, { firstName, lastName, username })
if (!updatedUser) {
return c.json("Username already in use", StatusCodes.BAD_REQUEST);
}
return c.json({ user: updatedUser }, StatusCodes.OK)
})
.post('/update/email', requireAuth, zValidator('json', updateEmailDto), limiter({ limit: 10, minutes: 60 }), async (c) => {
const user = c.var.user
const { email } = c.req.valid('json')
const updatedUser = await this.iamService.updateEmail(user.id, { email })
if (!updatedUser) {
return c.json("Email already in use", StatusCodes.BAD_REQUEST);
}
return c.json({ user: updatedUser }, StatusCodes.OK)
})
2024-08-15 23:46:58 +00:00
.post('/logout', requireAuth, async (c) => {
const sessionId = c.var.session.id
await this.iamService.logout(sessionId)
const sessionCookie = this.lucia.createBlankSessionCookie()
2024-08-15 23:46:58 +00:00
setCookie(c, sessionCookie.name, sessionCookie.value, {
path: sessionCookie.attributes.path,
maxAge: sessionCookie.attributes.maxAge,
domain: sessionCookie.attributes.domain,
sameSite: sessionCookie.attributes.sameSite as any,
secure: sessionCookie.attributes.secure,
httpOnly: sessionCookie.attributes.httpOnly,
expires: sessionCookie.attributes.expires,
})
return c.json({ status: 'success' })
})
}
}