Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ to start with Technical and let the project naturally evolve into one of the oth

### File Naming

You might notice how each file in the backend is postfixed with its architectural type(e.g. `iam.service.ts`). This allows
You might notice how each file in the backend is postfixed with its architectural type(e.g. `authentication.service.ts`). This allows
us to easily reorganize the folder structure to suite a different architecture pattern if the domain becomes more complex.

For example, if you want to group folders by domain(DDD), you simply drag and drop all related files to that folder.
Expand Down
2 changes: 1 addition & 1 deletion src/app.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ declare global {
api: ApiClient['api'];
parseApiResponse: typeof parseApiResponse;
getAuthedUser: () => Promise<Returned<User> | null>;
getAuthedUserOrThrow: (redirectTo: string) => Promise<Returned<User>>;
getAuthedUserOrThrow: (redirectTo?: string) => Promise<Returned<User>>;
}

// interface PageData {}
Expand Down
4 changes: 2 additions & 2 deletions src/hooks.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ const apiClient: Handle = async ({ event, resolve }) => {

/* ----------------------------- Auth functions ----------------------------- */
async function getAuthedUser() {
const { data } = await api.iam.me.$get().then(parseApiResponse)
const { data } = await api.auth.me.$get().then(parseApiResponse)
return data && data.user;
}

async function getAuthedUserOrThrow(redirectTo = '/') {
const { data } = await api.iam.me.$get().then(parseApiResponse);
const { data } = await api.auth.me.$get().then(parseApiResponse);
if (!data || !data.user) throw redirect(StatusCodes.TEMPORARY_REDIRECT, redirectTo);
return data?.user;
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib/server/api/common/types/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import type { BlankSchema } from "hono/types";

export abstract class Controler {
protected readonly controller: Hono<HonoTypes, BlankSchema, '/'>;

constructor() {
this.controller = new Hono();
}

abstract routes(): Hono<HonoTypes, BlankSchema, '/'>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { loginDto } from '../dtos/login.dto';
import { verifyLoginDto } from '../dtos/verify-login.dto';

@injectable()
export class IamController extends Controler {
export class AuthenticationController extends Controler {
constructor(
@inject(AuthenticationService) private authenticationService: AuthenticationService,
@inject(EmailVerificationService) private emailVerificationService: EmailVerificationService,
Expand Down
9 changes: 2 additions & 7 deletions src/lib/server/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'reflect-metadata';
import { Hono } from 'hono';
import { hc } from 'hono/client';
import { container } from 'tsyringe';
import { IamController } from './controllers/iam.controller';
import { AuthenticationController } from './controllers/authentication.controller';
import { config } from './common/config';
import { validateAuthSession, verifyOrigin } from './middlewares/auth.middleware';
import { AuthCleanupJobs } from './jobs/auth-cleanup.job';
Expand All @@ -20,8 +20,7 @@ app.use(verifyOrigin).use(validateAuthSession);
/* -------------------------------------------------------------------------- */
/* Routes */
/* -------------------------------------------------------------------------- */
const routes = app
.route('/iam', container.resolve(IamController).routes())
const routes = app.route('/auth', container.resolve(AuthenticationController).routes());

/* -------------------------------------------------------------------------- */
/* Cron Jobs */
Expand All @@ -35,7 +34,3 @@ container.resolve(AuthCleanupJobs).deleteStaleLoginRequests();
const rpc = hc<typeof routes>(config.api.origin);
export type ApiClient = typeof rpc;
export type ApiRoutes = typeof routes;




4 changes: 0 additions & 4 deletions src/lib/server/api/services/authentication.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,4 @@ export class AuthenticationService {
return loginRequest
})
}




}
80 changes: 0 additions & 80 deletions src/lib/server/api/services/iam.service.ts

This file was deleted.

6 changes: 3 additions & 3 deletions src/lib/server/api/tests/login-requests.service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { LoginRequestsRepository } from '../repositories/login-requests.reposito
import { container } from 'tsyringe';
import { LuciaService } from '../services/lucia.service';
import { DrizzleService } from '../services/drizzle.service';
import { IamService } from '../services/iam.service';
import { AuthenticationService } from '../services/authentication.service';

describe('LoginRequestService', () => {
let service: IamService;
let service: AuthenticationService;
let tokensService = vi.mocked(TokensService.prototype)
let mailerService = vi.mocked(MailerService.prototype);
let usersRepository = vi.mocked(UsersRepository.prototype);
Expand All @@ -26,7 +26,7 @@ describe('LoginRequestService', () => {
.register(LoginRequestsRepository, { useValue: loginRequestsRepository })
.register(LuciaService, { useValue: luciaService })
.register(DrizzleService, { useValue: drizzleService })
.resolve(IamService);
.resolve(AuthenticationService);
});

afterAll(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/routes/(app)/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const load = async ({ locals }) => {

export const actions = {
logout: async ({ locals }) => {
await locals.api.iam.logout.$post()
await locals.api.auth.logout.$post()
redirect(StatusCodes.SEE_OTHER, '/register')
}
}
Expand Down
5 changes: 2 additions & 3 deletions src/routes/(app)/settings/account/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@ export const actions = {
updateEmail: async ({ request, locals }) => {
const updateEmailForm = await superValidate(request, zod(updateEmailFormSchema));
if (!updateEmailForm.valid) return fail(StatusCodes.BAD_REQUEST, { updateEmailForm })
const { error } = await locals.api.iam.email.$patch({ json: updateEmailForm.data }).then(locals.parseApiResponse);
const { error } = await locals.api.auth.email.$patch({ json: updateEmailForm.data }).then(locals.parseApiResponse);
if (error) return setError(updateEmailForm, 'email', error);
return { updateEmailForm }
},
verifyEmail: async ({ request, locals }) => {
const verifyEmailForm = await superValidate(request, zod(verifyEmailFormSchema));
console.log(verifyEmailForm)
if (!verifyEmailForm.valid) return fail(StatusCodes.BAD_REQUEST, { verifyEmailForm })
const { error } = await locals.api.iam.email.verification.$post({ json: verifyEmailForm.data }).then(locals.parseApiResponse);
const { error } = await locals.api.auth.email.verify.$post({ json: verifyEmailForm.data }).then(locals.parseApiResponse);
if (error) return setError(verifyEmailForm, 'token', error);
return { verifyEmailForm }
}
Expand Down
4 changes: 2 additions & 2 deletions src/routes/(auth)/register/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ export const actions = {
register: async ({ locals, request }) => {
const emailRegisterForm = await superValidate(request, zod(registerFormSchema));
if (!emailRegisterForm.valid) return fail(StatusCodes.BAD_REQUEST, { emailRegisterForm });
const { error } = await locals.api.iam.login.$post({ json: emailRegisterForm.data }).then(locals.parseApiResponse);
const { error } = await locals.api.auth.login.$post({ json: emailRegisterForm.data }).then(locals.parseApiResponse);
if (error) return setError(emailRegisterForm, 'email', error);
return { emailRegisterForm };
},
signin: async ({ locals, request }) => {
const emailSignInForm = await superValidate(request, zod(signInFormSchema));
if (!emailSignInForm.valid) return fail(StatusCodes.BAD_REQUEST, { emailSignInForm });
const { error } = await locals.api.iam.login.verify.$post({ json: emailSignInForm.data }).then(locals.parseApiResponse)
const { error } = await locals.api.auth.login.verify.$post({ json: emailSignInForm.data }).then(locals.parseApiResponse)
if (error) return setError(emailSignInForm, 'token', error);
redirect(301, '/');
}
Expand Down