TurboJet
Autentikasi

Pengguna dan sesi

Membaca sesi di API dan dengan klien Better Auth.

TurboJet mengekspos sesi lewat helper API Hono dan klien React Better Auth. Tidak ada @auth/hooks atau getSession dari modul khusus SaaS di host ini.

Sesi di API (server)

Handler API produk memakai getSessionFromHeaders dari packages/api/src/lib/session.ts. Ia memanggil auth.api.getSession, memuat hasOnboarded dari Prisma, dan mengembalikan SafeSession yang tervalidasi (atau null):

packages/api/src/lib/session.ts
import { auth } from "@repo/auth";
import { db } from "@repo/database";
import { safeSessionSchema, type SafeSession } from "@repo/validations/user";

export async function getSessionFromHeaders(
	headers: Headers,
): Promise<SafeSession | null> {
	const session = await auth.api.getSession({ headers });
	if (!session) return null;

	const userData = await db.user.findUnique({
		where: { id: session.user.id },
		select: { hasOnboarded: true },
	});
	if (!userData) return null;

	// …bangun SafeSession dan parse dengan safeSessionSchema
}

Route terautentikasi sebaiknya memakai requireAuth lalu c.get("session") — lihat Melindungi endpoint API.

Bentuk SafeSession

Dari @repo/validations/user:

type SafeUser = {
	id: string;
	name: string | null;
	email: string | null;
	emailVerified: boolean | null;
	image: string | null;
	hasOnboarded: boolean | null;
	role: "USER" | "ADMIN"; // enum Role Prisma
	createdAt: string; // datetime ISO
	updatedAt: string;
	isBanned: boolean;
};

type SafeSession = {
	expiresAt: string; // datetime ISO
	user: SafeUser;
};

Sesi di client

Klien bersama ada di packages/auth/src/client.ts:

packages/auth/src/client.ts
import { createAuthClient } from "better-auth/react";
import {
	organizationClient,
	magicLinkClient,
	emailOTPClient,
	inferAdditionalFields,
} from "better-auth/client/plugins";
import { clientEnv } from "@repo/env/client";

export const authClient = createAuthClient({
	baseURL: clientEnv.NEXT_PUBLIC_APP_URL,
	plugins: [
		organizationClient(),
		magicLinkClient(),
		emailOTPClient(),
		inferAdditionalFields({
			user: {
				hasOnboarded: { type: "boolean" },
				role: { type: "string" },
				isBanned: { type: "boolean" },
				mobile: { type: "string", required: false },
			},
		}),
	],
});

Di client component pada host SaaS, pakai hook sesi Better Auth dari klien:

const { data: session, isPending } = authClient.useSession();

if (isPending) return <div>Loading...</div>;
if (!session) return <div>Anda perlu masuk</div>;

return <div>{session.user.name}</div>;

Setelah mengubah user (misalnya mengganti nama lewat /api/me), refetch sesi klien dengan API sesi Better Auth (authClient.getSession() / invalidate query sesi). Paket ini tidak mengekspor helper reloadSession terpisah.

Melindungi halaman dan API

  • API: requireAuth / requireAdmin — Melindungi endpoint API
  • Halaman SaaS: Di kit penuh, lindungi route dasbor di proxy/layout app itu. Host marketing+docs ini tidak punya gerbang sesi.

Terkait

Di halaman ini