mirror of
https://iceshrimp.dev/limepotato/jormungandr-bite.git
synced 2025-03-04 07:18:50 -07:00
56 lines
2.1 KiB
TypeScript
56 lines
2.1 KiB
TypeScript
import { Controller, Get, Post, Body, CurrentUser, Flow } from "@iceshrimp/koa-openapi";
|
|
import type { ILocalUser } from "@/models/entities/user.js";
|
|
import { UserHandler } from "@/server/api/web/handlers/user.js";
|
|
import type { AuthRequest, AuthResponse } from "@/server/api/web/entities/auth.js";
|
|
import type { Session } from "@/models/entities/session.js";
|
|
import { RatelimitRouteMiddleware } from "@/server/api/web/middleware/rate-limit.js";
|
|
import { CurrentSession } from "@/server/api/web/misc/decorators.js";
|
|
import { Sessions, UserProfiles, Users } from "@/models/index.js";
|
|
import { unauthorized, badRequest } from "@hapi/boom";
|
|
import { comparePassword } from "@/misc/password.js";
|
|
import { IsNull } from "typeorm";
|
|
import { genId } from "@/misc/gen-id.js";
|
|
import { secureRndstr } from "@/misc/secure-rndstr.js";
|
|
|
|
@Controller('/auth')
|
|
export class AuthController {
|
|
@Get('/')
|
|
async getAuth(
|
|
@CurrentUser() me: ILocalUser | null,
|
|
@CurrentSession() session: Session | null,
|
|
): Promise<AuthResponse> {
|
|
const user = me ? await UserHandler.getUser(me, me.id) : null;
|
|
return {
|
|
authenticated: !!session?.active,
|
|
status: user && session?.active ? null : '2fa',
|
|
token: session?.token ?? null,
|
|
user: user,
|
|
};
|
|
}
|
|
|
|
@Post('/')
|
|
@Flow([RatelimitRouteMiddleware("auth", 10, 60000, true)])
|
|
async login(@Body({ required: true }) request: AuthRequest): Promise<AuthResponse> {
|
|
if (request.username == null || request.password == null) throw badRequest();
|
|
|
|
const user = await Users.findOneBy({ usernameLower: request.username.toLowerCase(), host: IsNull() });
|
|
if (!user) throw unauthorized();
|
|
|
|
const profile = await UserProfiles.findOneBy( { userId: user.id });
|
|
if (!profile || profile.password == null) throw unauthorized();
|
|
|
|
if (!await comparePassword(request.password, profile.password)) throw unauthorized();
|
|
|
|
const result = await Sessions.insert({
|
|
id: genId(),
|
|
createdAt: new Date(),
|
|
active: !profile.twoFactorEnabled,
|
|
userId: user.id,
|
|
token: secureRndstr(32),
|
|
});
|
|
|
|
const session = await Sessions.findOneByOrFail(result.identifiers[0]);
|
|
|
|
return this.getAuth(user as ILocalUser, session);
|
|
}
|
|
}
|