mirror of
https://github.com/BradNut/boredgame
synced 2025-09-08 17:40:22 +00:00
91 lines
No EOL
3.9 KiB
TypeScript
91 lines
No EOL
3.9 KiB
TypeScript
import { inject, injectable } from 'tsyringe';
|
|
import { BadRequest } from '../common/errors';
|
|
import { DatabaseProvider } from '../providers';
|
|
import { MailerService } from './mailer.service';
|
|
import { TokensService } from './tokens.service';
|
|
import { LuciaProvider } from '../providers/lucia.provider';
|
|
import { UsersRepository } from '../repositories/users.repository';
|
|
import { CredentialsRepository } from '../repositories/credentials.repository';
|
|
import type { HonoRequest } from 'hono';
|
|
import type {SigninUsernameDto} from "$lib/dtos/signin-username.dto";
|
|
|
|
@injectable()
|
|
export class LoginRequestsService {
|
|
constructor(
|
|
@inject(LuciaProvider) private readonly lucia: LuciaProvider,
|
|
@inject(DatabaseProvider) private readonly db: DatabaseProvider,
|
|
@inject(TokensService) private readonly tokensService: TokensService,
|
|
@inject(MailerService) private readonly mailerService: MailerService,
|
|
@inject(UsersRepository) private readonly usersRepository: UsersRepository,
|
|
@inject(CredentialsRepository) private readonly credentialsRepository: CredentialsRepository,
|
|
) { }
|
|
|
|
// async create(data: RegisterEmailDto) {
|
|
// // generate a token, expiry date, and hash
|
|
// const { token, expiry, hashedToken } = await this.tokensService.generateTokenWithExpiryAndHash(15, 'm');
|
|
// // save the login request to the database - ensuring we save the hashedToken
|
|
// await this.loginRequestsRepository.create({ email: data.email, hashedToken, expiresAt: expiry });
|
|
// // send the login request email
|
|
// await this.mailerService.sendLoginRequest({
|
|
// to: data.email,
|
|
// props: { token: token }
|
|
// });
|
|
// }
|
|
|
|
async verify(data: SigninUsernameDto, req: HonoRequest) {
|
|
const requestIpAddress = req.header('x-real-ip');
|
|
const requestIpCountry = req.header('x-vercel-ip-country');
|
|
const existingUser = await this.usersRepository.findOneByUsername(data.username);
|
|
|
|
if (!existingUser) {
|
|
throw BadRequest('User not found');
|
|
}
|
|
|
|
const credential = await this.credentialsRepository.findPasswordCredentialsByUserId(existingUser.id);
|
|
|
|
if (!credential) {
|
|
throw BadRequest('Invalid credentials');
|
|
}
|
|
|
|
if (!await this.tokensService.verifyHashedToken(credential.secret_data, data.password)) {
|
|
throw BadRequest('Invalid credentials');
|
|
}
|
|
|
|
const totpCredentials = await this.credentialsRepository.findTOTPCredentialsByUserId(existingUser.id);
|
|
|
|
return this.lucia.createSession(existingUser.id, {
|
|
ip_country: requestIpCountry || 'unknown',
|
|
ip_address: requestIpAddress || 'unknown',
|
|
twoFactorAuthEnabled:
|
|
!!totpCredentials &&
|
|
totpCredentials?.secret_data !== null &&
|
|
totpCredentials?.secret_data !== '',
|
|
isTwoFactorAuthenticated: false,
|
|
});
|
|
}
|
|
|
|
// Create a new user and send a welcome email - or other onboarding process
|
|
private async handleNewUserRegistration(email: string) {
|
|
const newUser = await this.usersRepository.create({ email, verified: true })
|
|
this.mailerService.sendWelcome({ to: email, props: null });
|
|
// TODO: add whatever onboarding process or extra data you need here
|
|
return newUser
|
|
}
|
|
|
|
// Fetch a valid request from the database, verify the token and burn the request if it is valid
|
|
// private async fetchValidRequest(email: string, token: string) {
|
|
// return await this.db.transaction(async (trx) => {
|
|
// // fetch the login request
|
|
// const loginRequest = await this.loginRequestsRepository.trxHost(trx).findOneByEmail(email)
|
|
// if (!loginRequest) return null;
|
|
|
|
// // check if the token is valid
|
|
// const isValidRequest = await this.tokensService.verifyHashedToken(loginRequest.hashedToken, token);
|
|
// if (!isValidRequest) return null
|
|
|
|
// // if the token is valid, burn the request
|
|
// await this.loginRequestsRepository.trxHost(trx).deleteById(loginRequest.id);
|
|
// return loginRequest
|
|
// })
|
|
// }
|
|
} |