refactor: integrate Better-Auth for authentication and remove Supabase dependencies
This commit is contained in:
@@ -10,10 +10,10 @@ type ComplexIdParams = { complexId: string };
|
||||
export async function createAdminBookingHandler(c: AppContext) {
|
||||
const { complexId } = c.req.valid('param' as never) as ComplexIdParams;
|
||||
const payload = c.req.valid('json' as never) as CreateAdminBookingInput;
|
||||
const appUserId = c.get('appUserId');
|
||||
const user = c.get('user');
|
||||
|
||||
try {
|
||||
const booking = await createAdminBooking(appUserId, complexId, payload);
|
||||
const booking = await createAdminBooking(user.id, complexId, payload);
|
||||
return c.json(booking, 201);
|
||||
} catch (error) {
|
||||
if (error instanceof AdminBookingServiceError) {
|
||||
|
||||
@@ -10,10 +10,10 @@ type ComplexIdParams = { complexId: string };
|
||||
export async function listAdminBookingsHandler(c: AppContext) {
|
||||
const { complexId } = c.req.valid('param' as never) as ComplexIdParams;
|
||||
const query = c.req.valid('query' as never) as ListAdminBookingsQuery;
|
||||
const appUserId = c.get('appUserId');
|
||||
const user = c.get('user');
|
||||
|
||||
try {
|
||||
const response = await listAdminBookings(appUserId, complexId, query);
|
||||
const response = await listAdminBookings(user.id, complexId, query);
|
||||
return c.json(response);
|
||||
} catch (error) {
|
||||
if (error instanceof AdminBookingServiceError) {
|
||||
|
||||
@@ -10,10 +10,10 @@ type BookingIdParams = { id: string };
|
||||
export async function updateAdminBookingStatusHandler(c: AppContext) {
|
||||
const { id } = c.req.valid('param' as never) as BookingIdParams;
|
||||
const payload = c.req.valid('json' as never) as UpdateAdminBookingStatusInput;
|
||||
const appUserId = c.get('appUserId');
|
||||
const user = c.get('user');
|
||||
|
||||
try {
|
||||
const booking = await updateAdminBookingStatus(appUserId, id, payload);
|
||||
const booking = await updateAdminBookingStatus(user.id, id, payload);
|
||||
return c.json(booking);
|
||||
} catch (error) {
|
||||
if (error instanceof AdminBookingServiceError) {
|
||||
|
||||
@@ -126,12 +126,12 @@ function buildSlots(
|
||||
return slots;
|
||||
}
|
||||
|
||||
async function ensureComplexAccess(complexId: string, appUserId: string) {
|
||||
async function ensureComplexAccess(complexId: string, userId: string) {
|
||||
const complexUser = await db.complexUser.findUnique({
|
||||
where: {
|
||||
complexId_userId: {
|
||||
complexId,
|
||||
userId: appUserId,
|
||||
userId,
|
||||
},
|
||||
},
|
||||
include: {
|
||||
@@ -205,11 +205,11 @@ function mapBookingResponse(booking: {
|
||||
}
|
||||
|
||||
export async function listAdminBookings(
|
||||
appUserId: string,
|
||||
userId: string,
|
||||
complexId: string,
|
||||
query: ListAdminBookingsQuery
|
||||
) {
|
||||
await ensureComplexAccess(complexId, appUserId);
|
||||
await ensureComplexAccess(complexId, userId);
|
||||
const fromDate = parseIsoDate(query.fromDate);
|
||||
|
||||
const bookings = await db.courtBooking.findMany({
|
||||
@@ -253,11 +253,11 @@ export async function listAdminBookings(
|
||||
}
|
||||
|
||||
export async function createAdminBooking(
|
||||
appUserId: string,
|
||||
userId: string,
|
||||
complexId: string,
|
||||
input: CreateAdminBookingInput
|
||||
) {
|
||||
const complex = await ensureComplexAccess(complexId, appUserId);
|
||||
const complex = await ensureComplexAccess(complexId, userId);
|
||||
const bookingDate = parseIsoDate(input.date);
|
||||
const dayOfWeek = getDayOfWeek(bookingDate);
|
||||
|
||||
@@ -436,7 +436,7 @@ export async function createAdminBooking(
|
||||
}
|
||||
|
||||
export async function updateAdminBookingStatus(
|
||||
appUserId: string,
|
||||
userId: string,
|
||||
bookingId: string,
|
||||
input: UpdateAdminBookingStatusInput
|
||||
) {
|
||||
@@ -447,7 +447,7 @@ export async function updateAdminBookingStatus(
|
||||
complex: {
|
||||
users: {
|
||||
some: {
|
||||
userId: appUserId,
|
||||
userId,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Hono } from "hono";
|
||||
import { auth } from "@/lib/auth";
|
||||
import { AppEnv } from "@/types/hono";
|
||||
import { auth } from '@/lib/auth';
|
||||
import { AppEnv } from '@/types/hono';
|
||||
import { Hono } from 'hono';
|
||||
|
||||
export const authRoutes = new Hono<AppEnv>();
|
||||
|
||||
authRoutes.on(["POST", "GET"], "/api/auth/*", (c) => {
|
||||
return auth.handler(c.req.raw);
|
||||
authRoutes.on(['POST', 'GET'], '/api/auth/*', (c) => {
|
||||
return auth.handler(c.req.raw);
|
||||
});
|
||||
|
||||
@@ -5,8 +5,8 @@ import type { CreateComplexInput } from '@repo/api-contract';
|
||||
export async function createComplexHandler(c: AppContext) {
|
||||
const payload = c.req.valid('json' as never) as CreateComplexInput;
|
||||
|
||||
const authUser = c.get('authUser');
|
||||
const adminEmail = authUser.email;
|
||||
const user = c.get('user');
|
||||
const adminEmail = user.email;
|
||||
|
||||
if (!adminEmail) {
|
||||
return c.json({ message: 'El usuario autenticado no tiene email.' }, 400);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { listMyComplexes } from '@/modules/complex/services/complex.service';
|
||||
import type { AppContext } from '@/types/hono';
|
||||
|
||||
export async function listMyComplexesHandler(c: AppContext) {
|
||||
const appUserId = c.get('appUserId');
|
||||
const complexes = await listMyComplexes(appUserId);
|
||||
const user = c.get('user');
|
||||
const complexes = await listMyComplexes(user.id);
|
||||
return c.json(complexes);
|
||||
}
|
||||
|
||||
@@ -93,9 +93,9 @@ export async function getComplexBySlug(slug: string) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function listMyComplexes(appUserId: string) {
|
||||
export async function listMyComplexes(userId: string) {
|
||||
const complexUsers = await db.complexUser.findMany({
|
||||
where: { userId: appUserId },
|
||||
where: { userId },
|
||||
include: {
|
||||
complex: true,
|
||||
},
|
||||
|
||||
@@ -7,10 +7,10 @@ type ComplexIdParams = { complexId: string };
|
||||
export async function createCourtHandler(c: AppContext) {
|
||||
const { complexId } = c.req.valid('param' as never) as ComplexIdParams;
|
||||
const payload = c.req.valid('json' as never) as CreateCourtInput;
|
||||
const appUserId = c.get('appUserId');
|
||||
const user = c.get('user');
|
||||
|
||||
try {
|
||||
const court = await createCourt(appUserId, complexId, payload);
|
||||
const court = await createCourt(user.id, complexId, payload);
|
||||
return c.json(court, 201);
|
||||
} catch (error) {
|
||||
if (error instanceof CourtServiceError) {
|
||||
|
||||
@@ -5,10 +5,10 @@ type ComplexIdParams = { complexId: string };
|
||||
|
||||
export async function listCourtsByComplexHandler(c: AppContext) {
|
||||
const { complexId } = c.req.valid('param' as never) as ComplexIdParams;
|
||||
const appUserId = c.get('appUserId');
|
||||
const user = c.get('user');
|
||||
|
||||
try {
|
||||
const courts = await listCourtsByComplex(complexId, appUserId);
|
||||
const courts = await listCourtsByComplex(complexId, user.id);
|
||||
return c.json(courts);
|
||||
} catch (error) {
|
||||
if (error instanceof CourtServiceError) {
|
||||
|
||||
@@ -7,10 +7,10 @@ type CourtIdParams = { id: string };
|
||||
export async function updateCourtHandler(c: AppContext) {
|
||||
const { id } = c.req.valid('param' as never) as CourtIdParams;
|
||||
const payload = c.req.valid('json' as never) as UpdateCourtInput;
|
||||
const appUserId = c.get('appUserId');
|
||||
const user = c.get('user');
|
||||
|
||||
try {
|
||||
const court = await updateCourt(appUserId, id, payload);
|
||||
const court = await updateCourt(user.id, id, payload);
|
||||
return c.json(court);
|
||||
} catch (error) {
|
||||
if (error instanceof CourtServiceError) {
|
||||
|
||||
@@ -61,12 +61,12 @@ function assertAvailabilityRanges(
|
||||
}
|
||||
}
|
||||
|
||||
async function ensureComplexAccess(complexId: string, appUserId: string) {
|
||||
async function ensureComplexAccess(complexId: string, userId: string) {
|
||||
const complexUser = await db.complexUser.findUnique({
|
||||
where: {
|
||||
complexId_userId: {
|
||||
complexId,
|
||||
userId: appUserId,
|
||||
userId,
|
||||
},
|
||||
},
|
||||
include: {
|
||||
@@ -137,14 +137,14 @@ async function enforcePlanCourtLimit(complexId: string) {
|
||||
}
|
||||
}
|
||||
|
||||
async function getCourtByIdForUser(courtId: string, appUserId: string) {
|
||||
async function getCourtByIdForUser(courtId: string, userId: string) {
|
||||
return db.court.findFirst({
|
||||
where: {
|
||||
id: courtId,
|
||||
complex: {
|
||||
users: {
|
||||
some: {
|
||||
userId: appUserId,
|
||||
userId,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -195,8 +195,8 @@ function mapCourtResponse(court: CourtWithRelations) {
|
||||
};
|
||||
}
|
||||
|
||||
export async function listCourtsByComplex(complexId: string, appUserId: string) {
|
||||
await ensureComplexAccess(complexId, appUserId);
|
||||
export async function listCourtsByComplex(complexId: string, userId: string) {
|
||||
await ensureComplexAccess(complexId, userId);
|
||||
|
||||
const courts = await db.court.findMany({
|
||||
where: { complexId },
|
||||
@@ -218,8 +218,8 @@ export async function listCourtsByComplex(complexId: string, appUserId: string)
|
||||
return courts.map((court) => mapCourtResponse(court));
|
||||
}
|
||||
|
||||
export async function createCourt(appUserId: string, complexId: string, input: CreateCourtInput) {
|
||||
await ensureComplexAccess(complexId, appUserId);
|
||||
export async function createCourt(userId: string, complexId: string, input: CreateCourtInput) {
|
||||
await ensureComplexAccess(complexId, userId);
|
||||
await ensureActiveSport(input.sportId);
|
||||
await enforcePlanCourtLimit(complexId);
|
||||
assertAvailabilityRanges(input.availability);
|
||||
@@ -249,7 +249,7 @@ export async function createCourt(appUserId: string, complexId: string, input: C
|
||||
return court;
|
||||
});
|
||||
|
||||
const court = await getCourtByIdForUser(createdCourt.id, appUserId);
|
||||
const court = await getCourtByIdForUser(createdCourt.id, userId);
|
||||
|
||||
if (!court) {
|
||||
throw new CourtServiceError('No se pudo obtener la cancha creada.', 404);
|
||||
@@ -258,8 +258,8 @@ export async function createCourt(appUserId: string, complexId: string, input: C
|
||||
return mapCourtResponse(court);
|
||||
}
|
||||
|
||||
export async function updateCourt(appUserId: string, courtId: string, input: UpdateCourtInput) {
|
||||
const existingCourt = await getCourtByIdForUser(courtId, appUserId);
|
||||
export async function updateCourt(userId: string, courtId: string, input: UpdateCourtInput) {
|
||||
const existingCourt = await getCourtByIdForUser(courtId, userId);
|
||||
|
||||
if (!existingCourt) {
|
||||
throw new CourtServiceError('Cancha no encontrada.', 404);
|
||||
@@ -305,7 +305,7 @@ export async function updateCourt(appUserId: string, courtId: string, input: Upd
|
||||
}
|
||||
});
|
||||
|
||||
const updatedCourt = await getCourtByIdForUser(courtId, appUserId);
|
||||
const updatedCourt = await getCourtByIdForUser(courtId, userId);
|
||||
|
||||
if (!updatedCourt) {
|
||||
throw new CourtServiceError('Cancha no encontrada.', 404);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createHash, randomInt } from 'node:crypto';
|
||||
import { auth } from '@/lib/auth';
|
||||
import { sendMail } from '@/lib/mailer';
|
||||
import { db } from '@/lib/prisma';
|
||||
import { getSupabaseAdminClient } from '@/lib/supabase-admin';
|
||||
@@ -10,7 +11,6 @@ import type {
|
||||
} from '@repo/api-contract';
|
||||
import type { User as SupabaseAuthUser } from '@supabase/supabase-js';
|
||||
import { v7 as uuidv7 } from 'uuid';
|
||||
import { auth } from '@/lib/auth';
|
||||
|
||||
const OTP_LENGTH = 6;
|
||||
const OTP_TTL_MINUTES = Number(Bun.env.ONBOARDING_OTP_TTL_MINUTES ?? 10);
|
||||
@@ -441,7 +441,6 @@ export async function completeOnboarding(input: OnboardingCompleteInput) {
|
||||
const complexSlug = await buildUniqueComplexSlug(input.complexName);
|
||||
|
||||
const result = await db.$transaction(async (tx) => {
|
||||
|
||||
const complex = await tx.complex.create({
|
||||
data: {
|
||||
id: uuidv7(),
|
||||
|
||||
@@ -2,7 +2,7 @@ import { getUserProfile } from '@/modules/user/services/user.service';
|
||||
import type { AppContext } from '@/types/hono';
|
||||
|
||||
export function getUserProfileHandler(c: AppContext) {
|
||||
const authUser = c.get('authUser');
|
||||
const profile = getUserProfile(authUser);
|
||||
const user = c.get('user');
|
||||
const profile = getUserProfile(user);
|
||||
return c.json(profile);
|
||||
}
|
||||
|
||||
@@ -1,23 +1,13 @@
|
||||
import type { AuthUser } from '@/types/auth-user';
|
||||
import type { User } from '@/lib/auth';
|
||||
import type { UserProfile } from '@repo/api-contract';
|
||||
|
||||
export function getUserProfile(user: AuthUser): UserProfile {
|
||||
const fullName =
|
||||
(typeof user.user_metadata?.full_name === 'string' && user.user_metadata.full_name) ||
|
||||
(typeof user.user_metadata?.name === 'string' && user.user_metadata.name) ||
|
||||
(user.email ?? 'Usuario');
|
||||
|
||||
const role = (typeof user.app_metadata?.role === 'string' && user.app_metadata.role) || 'member';
|
||||
|
||||
const avatarUrl =
|
||||
(typeof user.user_metadata?.avatar_url === 'string' && user.user_metadata.avatar_url) || null;
|
||||
|
||||
export function getUserProfile(user: User): UserProfile {
|
||||
return {
|
||||
id: user.id,
|
||||
fullName,
|
||||
email: user.email ?? null,
|
||||
role,
|
||||
avatarUrl,
|
||||
createdAt: user.created_at,
|
||||
fullName: user.name,
|
||||
email: user.email,
|
||||
role: (user as any).role || 'member',
|
||||
avatarUrl: user.image || null,
|
||||
createdAt: user.createdAt,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user