[backend/web-api] Move auth code into handler

This commit is contained in:
Laura Hausmann 2023-12-11 23:09:33 +01:00
parent ba76c5e67b
commit a168e4ec03
Signed by: zotan
GPG key ID: D044E84C5BE01605
2 changed files with 48 additions and 34 deletions

View file

@ -1,16 +1,10 @@
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";
import { AuthHandler } from "@/server/api/web/handlers/auth.js";
@Controller('/auth')
export class AuthController {
@ -19,37 +13,12 @@ export class AuthController {
@CurrentUser() me: ILocalUser | null,
@CurrentSession() session: Session | null,
): Promise<AuthResponse> {
const user = me ? await UserHandler.getUser(me, me.id) : null;
return {
status: !user ? 'guest' : session?.active ? 'authenticated' : '2fa',
token: session?.token ?? null,
user: user,
};
return AuthHandler.getAuthStatus(me, session);
}
@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("Missing username or password");
const user = await Users.findOneBy({ usernameLower: request.username.toLowerCase(), host: IsNull() });
if (!user) throw unauthorized("Invalid username or password");
const profile = await UserProfiles.findOneBy( { userId: user.id });
if (!profile || profile.password == null) throw unauthorized("Invalid username or password");
if (!await comparePassword(request.password, profile.password)) throw unauthorized("Invalid username or password");
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.getAuthStatus(user as ILocalUser, session);
return AuthHandler.login(request);
}
}

View file

@ -0,0 +1,45 @@
import { ILocalUser } from "@/models/entities/user.js";
import { Session } from "@/models/entities/session.js";
import { AuthRequest, AuthResponse } from "@/server/api/web/entities/auth.js";
import { UserHandler } from "@/server/api/web/handlers/user.js";
import { Sessions, UserProfiles, Users } from "@/models/index.js";
import { comparePassword } from "@/misc/password.js";
import { genId } from "@/misc/gen-id.js";
import { secureRndstr } from "@/misc/secure-rndstr.js";
import { unauthorized, badRequest } from "@hapi/boom";
import { IsNull } from "typeorm";
export class AuthHandler {
public static async getAuthStatus(me: ILocalUser | null, session: Session | null): Promise<AuthResponse> {
const user = me ? await UserHandler.getUser(me, me.id) : null;
return {
status: !user ? 'guest' : session?.active ? 'authenticated' : '2fa',
token: session?.token ?? null,
user: user,
};
}
public static async login(request: AuthRequest): Promise<AuthResponse> {
if (request.username == null || request.password == null) throw badRequest("Missing username or password");
const user = await Users.findOneBy({ usernameLower: request.username.toLowerCase(), host: IsNull() });
if (!user) throw unauthorized("Invalid username or password");
const profile = await UserProfiles.findOneBy( { userId: user.id });
if (!profile || profile.password == null) throw unauthorized("Invalid username or password");
if (!await comparePassword(request.password, profile.password)) throw unauthorized("Invalid username or password");
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.getAuthStatus(user as ILocalUser, session);
}
}