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

80 lines
3.7 KiB
TypeScript
Raw Normal View History

import { setCookie } from 'hono/cookie';
2024-05-25 06:02:26 +00:00
import { inject, injectable } from 'tsyringe';
import { zValidator } from '@hono/zod-validator';
2024-08-07 15:13:36 +00:00
import { limiter } from '../middlewares/rate-limiter.middlware';
2024-09-04 03:18:38 +00:00
import { requireAuth } from '../middlewares/require-auth.middleware';
2024-09-02 04:36:41 +00:00
import { Controler } from '../common/types/controller';
2024-09-01 21:32:50 +00:00
import { updateEmailDto } from '$lib/server/api/dtos/update-email.dto';
import { verifyEmailDto } from '$lib/server/api/dtos/verify-email.dto';
2024-09-02 04:36:41 +00:00
import { LuciaService } from '../services/lucia.service';
2024-09-04 03:18:38 +00:00
import { AuthenticationService } from '../services/authentication.service';
import { EmailVerificationService } from '../services/email-verification.service';
import { loginDto } from '../dtos/login.dto';
import { verifyLoginDto } from '../dtos/verify-login.dto';
2024-05-25 06:02:26 +00:00
@injectable()
2024-09-02 04:36:41 +00:00
export class IamController extends Controler {
2024-05-25 06:02:26 +00:00
constructor(
2024-09-04 03:18:38 +00:00
@inject(AuthenticationService) private authenticationService: AuthenticationService,
@inject(EmailVerificationService) private emailVerificationService: EmailVerificationService,
2024-09-02 04:36:41 +00:00
@inject(LuciaService) private luciaService: LuciaService,
2024-08-31 17:54:31 +00:00
) {
super();
}
2024-05-25 06:02:26 +00:00
routes() {
return this.controller
2024-09-04 03:18:38 +00:00
.get('/me', async (c) => {
const user = c.var.user;
return c.json({ user: user });
})
2024-09-04 03:18:38 +00:00
.post('/login', zValidator('json', loginDto), limiter({ limit: 10, minutes: 60 }), async (c) => {
2024-05-25 06:02:26 +00:00
const { email } = c.req.valid('json');
2024-09-04 03:18:38 +00:00
await this.authenticationService.createLoginRequest({ email });
2024-05-25 06:02:26 +00:00
return c.json({ message: 'Verification email sent' });
})
2024-09-04 03:18:38 +00:00
.post('/login/verify', zValidator('json', verifyLoginDto), limiter({ limit: 10, minutes: 60 }), async (c) => {
const { email, token } = c.req.valid('json');
2024-09-04 03:18:38 +00:00
const session = await this.authenticationService.verifyLoginRequest({ email, token });
2024-09-02 04:36:41 +00:00
const sessionCookie = this.luciaService.lucia.createSessionCookie(session.id);
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({ message: 'ok' });
})
2024-09-04 03:18:38 +00:00
.patch('/email', requireAuth, zValidator('json', updateEmailDto), limiter({ limit: 10, minutes: 60 }), async (c) => {
const json = c.req.valid('json');
await this.emailVerificationService.create(c.var.user.id, json.email);
return c.json({ message: 'Verification email sent' });
})
// this could also be named to use custom methods, aka /email#verify
// https://cloud.google.com/apis/design/custom_methods
.post('/email/verify', requireAuth, zValidator('json', verifyEmailDto), limiter({ limit: 10, minutes: 60 }), async (c) => {
const json = c.req.valid('json');
await this.emailVerificationService.verify(c.var.user.id, json.token);
return c.json({ message: 'Verified and updated' });
})
.post('/logout', requireAuth, async (c) => {
const sessionId = c.var.session.id;
2024-09-04 03:18:38 +00:00
await this.authenticationService.logout(sessionId);
2024-09-02 04:36:41 +00:00
const sessionCookie = this.luciaService.lucia.createBlankSessionCookie();
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' });
})
2024-05-25 06:02:26 +00:00
}
}