79 lines
2.9 KiB
TypeScript
79 lines
2.9 KiB
TypeScript
import { Inject, Injectable } from "@nestjs/common";
|
|
import { AccountService } from "./account.service";
|
|
import * as tokenService from "../contracts/services/token.service";
|
|
import * as passwordService from "../contracts/services/password.service";
|
|
import * as sessionService from "../contracts/services/session.service";
|
|
import { ISignIn } from "../contracts/models/sign.in";
|
|
|
|
@Injectable()
|
|
export class LoginService {
|
|
constructor(
|
|
@Inject("@apihub24/token_service")
|
|
private readonly tokenService: tokenService.ITokenService,
|
|
@Inject("@apihub24/password_service")
|
|
private readonly passwordService: passwordService.IPasswordService,
|
|
@Inject("@apihub24/session_service")
|
|
private readonly sessionService: sessionService.ISessionService,
|
|
@Inject(AccountService)
|
|
private readonly accountService: AccountService
|
|
) {}
|
|
|
|
/**
|
|
* This asynchronous method authenticates a user and creates a JWT token for a new session.
|
|
* It first finds an active account with the given `accountName`, verifies the password, and if successful, creates a new session and generates a signed token.
|
|
* @param signIn An `ISignIn` object containing the `accountName` and `password`.
|
|
* @param expires An optional string specifying the token's expiration duration (default: "1h").
|
|
* @param algorithm An optional string specifying the signing algorithm for the token (default: "HS512").
|
|
* @returns A Promise that resolves to a JWT token string. Returns an empty string if authentication fails.
|
|
*/
|
|
async signIn(
|
|
signIn: ISignIn,
|
|
expires: string = "1h",
|
|
algorithm: tokenService.Algorithm = "HS512"
|
|
): Promise<string> {
|
|
const accounts = await this.accountService.getBy(
|
|
(x) =>
|
|
x.accountName === signIn.accountName &&
|
|
x.active &&
|
|
!!x.passwordHash?.length
|
|
);
|
|
if (
|
|
!accounts.length ||
|
|
!(await this.passwordService.verify(
|
|
signIn.password,
|
|
accounts[0].passwordHash
|
|
))
|
|
) {
|
|
return "";
|
|
}
|
|
const session = await this.sessionService.create(accounts[0]);
|
|
const token = await this.tokenService.generate(
|
|
session,
|
|
signIn.accountName,
|
|
expires,
|
|
algorithm
|
|
);
|
|
return token;
|
|
}
|
|
|
|
/**
|
|
* This asynchronous method logs a user out by removing their active session.
|
|
* It finds the account by its `id` and then locates and removes the corresponding session.
|
|
* @param accountId The unique identifier (`id`) of the account to be logged out.
|
|
* @returns A Promise that resolves to `void` after the operation is complete.
|
|
*/
|
|
async signOut(accountId: string): Promise<void> {
|
|
const accounts = await this.accountService.getBy((x) => x.id === accountId);
|
|
if (!accounts.length) {
|
|
return;
|
|
}
|
|
const sessions = await this.sessionService.getBy(
|
|
(x) => x.id === accounts[0].id
|
|
);
|
|
if (!sessions.length) {
|
|
return;
|
|
}
|
|
await this.sessionService.remove(sessions[0].id);
|
|
}
|
|
}
|