refactored controller and jobs

This commit is contained in:
rykuno 2024-08-31 12:54:31 -05:00
parent 0dc94ad1cb
commit ed50dc25f3
8 changed files with 87 additions and 33 deletions

View file

@ -11,7 +11,7 @@ services:
envVars: envVars:
- key: DATABASE_URL - key: DATABASE_URL
fromDatabase: fromDatabase:
name: tarostack name: tofustack
property: connectionString property: connectionString
- key: REDIS_URL - key: REDIS_URL
fromService: fromService:
@ -29,5 +29,5 @@ services:
databases: databases:
- name: db - name: db
databaseName: tarostack databaseName: tofustack
ipAllowList: [] ipAllowList: []

View file

@ -0,0 +1,11 @@
import { Hono } from "hono";
import type { HonoTypes } from "../types/hono.type";
import type { BlankSchema, Env, Schema } from "hono/types";
export abstract class Controler {
protected readonly controller: Hono<HonoTypes, BlankSchema, '/'>;
constructor() {
this.controller = new Hono();
}
abstract routes(): Hono<HonoTypes, BlankSchema, '/'>;
}

View file

@ -2,7 +2,6 @@ import { Hono } from 'hono';
import type { BlankSchema } from 'hono/types'; import type { BlankSchema } from 'hono/types';
import type { HonoTypes } from '../types/hono.type'; import type { HonoTypes } from '../types/hono.type';
export interface Controller { // export interface Controller {
// controller: Hono<HonoTypes, BlankSchema, '/'>; // routes()
routes(): Hono<HonoTypes, BlankSchema, '/'>; // }
}

View file

@ -1,4 +1,4 @@
import { Hono } from 'hono'; import { Hono, type Schema } from 'hono';
import { setCookie } from 'hono/cookie'; import { setCookie } from 'hono/cookie';
import { inject, injectable } from 'tsyringe'; import { inject, injectable } from 'tsyringe';
import { zValidator } from '@hono/zod-validator'; import { zValidator } from '@hono/zod-validator';
@ -8,19 +8,18 @@ import { signInEmailDto } from '../../../dtos/signin-email.dto';
import { updateEmailDto } from '../../../dtos/update-email.dto'; import { updateEmailDto } from '../../../dtos/update-email.dto';
import { verifyEmailDto } from '../../../dtos/verify-email.dto'; import { verifyEmailDto } from '../../../dtos/verify-email.dto';
import { registerEmailDto } from '../../../dtos/register-email.dto'; import { registerEmailDto } from '../../../dtos/register-email.dto';
import type { HonoTypes } from '../common/types/hono.type';
import type { Controller } from '../common/inferfaces/controller.interface';
import { limiter } from '../middlewares/rate-limiter.middlware'; import { limiter } from '../middlewares/rate-limiter.middlware';
import { requireAuth } from '../middlewares/auth.middleware'; import { requireAuth } from '../middlewares/auth.middleware';
import { Controler } from '../common/classes/controller.class';
@injectable() @injectable()
export class IamController implements Controller { export class IamController extends Controler {
private controller = new Hono<HonoTypes>();
constructor( constructor(
@inject(IamService) private iamService: IamService, @inject(IamService) private iamService: IamService,
@inject(LuciaProvider) private lucia: LuciaProvider, @inject(LuciaProvider) private lucia: LuciaProvider,
) { } ) {
super();
}
routes() { routes() {
return this.controller return this.controller

View file

@ -5,36 +5,37 @@ import { container } from 'tsyringe';
import { IamController } from './controllers/iam.controller'; import { IamController } from './controllers/iam.controller';
import { env } from './configs/envs.config'; import { env } from './configs/envs.config';
import { validateAuthSession, verifyOrigin } from './middlewares/auth.middleware'; import { validateAuthSession, verifyOrigin } from './middlewares/auth.middleware';
// import { TestJob } from './jobs/test.job'; import { AuthCleanupJobs } from './jobs/auth-cleanup.job';
import { glob, globSync } from 'glob';
import path from 'path';
console.log('API SERVER STARTED'); /* -------------------------------------------------------------------------- */
/* ----------------------------------- Api ---------------------------------- */ /* App */
const app = new Hono().basePath('/api'); /* -------------------------------------------------------------------------- */
export const app = new Hono().basePath('/api');
/* --------------------------- Global Middlewares --------------------------- */ /* -------------------------------------------------------------------------- */
/* Global Middlewares */
/* -------------------------------------------------------------------------- */
app.use(verifyOrigin).use(validateAuthSession); app.use(verifyOrigin).use(validateAuthSession);
/* --------------------------------- Routes --------------------------------- */ /* -------------------------------------------------------------------------- */
/* Routes */
/* -------------------------------------------------------------------------- */
const routes = app const routes = app
.route('/iam', container.resolve(IamController).routes()) .route('/iam', container.resolve(IamController).routes())
/* -------------------------------------------------------------------------- */
/* Cron Jobs */
/* -------------------------------------------------------------------------- */
container.resolve(AuthCleanupJobs).deleteStaleEmailVerificationRequests();
container.resolve(AuthCleanupJobs).deleteStaleLoginRequests();
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Exports */ /* Exports */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
export const rpc = hc<typeof routes>(env.ORIGIN); const rpc = hc<typeof routes>(env.ORIGIN);
export type ApiClient = typeof rpc; export type ApiClient = typeof rpc;
export type ApiRoutes = typeof routes; export type ApiRoutes = typeof routes;
export { app };
async function resolveJobs() {
const jobFiles = globSync('**/*.job.*');
for (const file of jobFiles) {
const module = await import(path.resolve(file));
container.resolve(module.default)
}
}
resolveJobs();

View file

@ -0,0 +1,44 @@
import { inject, injectable } from "tsyringe";
import { JobsService } from "../services/jobs.service";
@injectable()
export class AuthCleanupJobs {
private queue;
constructor(
@inject(JobsService) private jobsService: JobsService,
) {
/* ------------------------------ Create Queue ------------------------------ */
this.queue = this.jobsService.createQueue('test')
/* ---------------------------- Register Workers ---------------------------- */
this.worker();
}
async deleteStaleEmailVerificationRequests() {
this.queue.add('delete_stale_email_verifiactions', null, {
repeat: {
pattern: '0 0 * * 0' // Runs once a week at midnight on Sunday
}
})
}
async deleteStaleLoginRequests() {
this.queue.add('delete_stale_login_requests', null, {
repeat: {
pattern: '0 0 * * 0' // Runs once a week at midnight on Sunday
}
})
}
private async worker() {
return this.jobsService.createWorker(this.queue.name, async (job) => {
if (job.name === "delete_stale_email_verifiactions") {
// delete stale email verifications
}
if (job.name === "delete_stale_login_requests") {
// delete stale email verifications
}
})
}
}

View file

@ -1,4 +1,3 @@
import { container } from 'tsyringe';
import { Lucia } from 'lucia'; import { Lucia } from 'lucia';
import { DrizzlePostgreSQLAdapter } from '@lucia-auth/adapter-drizzle'; import { DrizzlePostgreSQLAdapter } from '@lucia-auth/adapter-drizzle';
import { sessionsTable, usersTable } from '../databases/tables'; import { sessionsTable, usersTable } from '../databases/tables';

View file

@ -4,7 +4,8 @@ import { RedisProvider } from "../providers/redis.provider";
@injectable() @injectable()
export class JobsService { export class JobsService {
constructor(@inject(RedisProvider) private readonly redis: RedisProvider) { } constructor(@inject(RedisProvider) private readonly redis: RedisProvider) {
}
createQueue(name: string) { createQueue(name: string) {
return new Queue(name, { connection: this.redis }) return new Queue(name, { connection: this.redis })