Files
nixi-api/src/domain/account/controller/AccountController.ts
qpismont aaa0ca5a54 feat: add accounts and movies tables in migrations
- Created migration for accounts table with fields: id, username, password, role_id, created_at, updated_at.
- Created migration for movies table with fields: id, title, overview, poster_path, backdrop_path, release_date, tmdb_id.

refactor: update package.json scripts and dependencies

- Changed dev script to use bun instead of tsx.
- Added build:migrate script for migration.
- Updated devDependencies for bun and oxlint.

fix: refactor database connection and migration execution

- Updated PgDatabase to use SQL from bun.
- Refactored migration execution logic to read SQL files and execute them.

feat: implement account creation and validation logic

- Updated AccountEntity to use username instead of email.
- Added validation for username format and password strength.
- Implemented account repository methods for finding by username and inserting accounts.

test: add tests for account entity, repository, and service

- Created tests for AccountEntity to validate username and password.
- Added tests for AccountRepository to ensure correct database interactions.
- Implemented tests for AccountService to validate registration and login logic.

chore: remove outdated tests and files

- Deleted old tests related to email-based account management.
- Cleaned up unused imports and files to streamline the codebase.
2025-10-02 20:54:41 +00:00

72 lines
1.8 KiB
TypeScript

import { Hono } from "hono";
import { validator } from "hono/validator";
import type { AccountServiceInterface } from "../service/AccountServiceInterface";
import { loginSchema, registerSchema } from "../validation/AccountValidation";
import { BadSchemaError } from "../../../errors";
import { createRateLimit } from "../../../middleware/rateLimiter";
const loginRateLimit = createRateLimit({
windowMs: 15 * 60 * 1000,
maxAttempts: 5,
keyGenerator: (c) => {
const ip =
c.req.header("x-forwarded-for") ||
c.req.header("x-real-ip") ||
"127.0.0.1";
return `login:${ip}`;
},
});
export default function toRoutes(
accountService: AccountServiceInterface,
): Hono {
const app = new Hono();
app.post(
"/login",
loginRateLimit,
validator("json", (value) => {
const parsed = loginSchema.safeParse(value);
if (!parsed.success) {
throw new BadSchemaError(parsed.error.message);
}
return parsed.data;
}),
async (ctx) => {
const { username, password } = ctx.req.valid("json");
const account = await accountService.login(username, password);
return ctx.json({
success: true,
accountId: account.id,
username: account.username,
});
},
);
app.post(
"/register",
validator("json", (value) => {
const parsed = registerSchema.safeParse(value);
if (!parsed.success) {
throw new BadSchemaError(parsed.error.message);
}
return parsed.data;
}),
async (ctx) => {
const { username, password } = ctx.req.valid("json");
const account = await accountService.register(username, password);
return ctx.json({
success: true,
accountId: account.id,
username: account.username,
});
},
);
return app;
}