Skip to main content

Authentication

Authentication in this application is implemented using JSON Web Tokens (JWT). All authentication logic is centralized in the app/core/authentication/server folder.

Core Functions

The main authentication components are exported through index.tsx:

import { createTrpcContext } from './context'
import { getHttpContext, getHttpContextPublic } from './middleware'
import { AuthenticationRouter } from './router'
import { AuthenticationService } from './service'

export const AuthenticationServer = {
createTrpcContext,
getHttpContext,
getHttpContextPublic,
trpcRouter: AuthenticationRouter,
service: AuthenticationService,
}

The tRPC router (AuthenticationRouter) contains essential authentication functions such as login, logout, and register.

Additional functions are available to create and manage user sessions for both tRPC and HTTP calls.

Examples

Here are examples of how to use the authentication functions:

// Get user session if possible (doesn't crash if user is not logged in)
const publicContext = await AuthenticationServer.getHttpContextPublic({ request });

// Get user session (crashes if user is not logged in)
const secureContext = await AuthenticationServer.getHttpContext({ request });

Note that getHttpContextPublic will return the user session if available, while getHttpContext will throw an error if the user is not logged in.

createTrpcContext(options) performs a similar function but within a tRPC context, allowing for authentication checks in tRPC procedures.

tRPC Procedures

For tRPC, the app/core/trpc/base/index.tsx file exposes the same notion of public and protected context via tRPC procedures.

export const Trpc = {
createRouter: trpcInstance.router,
mergeRouters: trpcInstance.mergeRouters,
procedurePublic,
procedure,
createContext,
}

Examples

Here are examples of public and protected tRPC procedures:

// Public procedure (no authentication required)
const publicProcedure = Trpc.procedurePublic.query(async () => {
return { message: "This is a public endpoint" };
});

// Protected procedure (authentication required)
const protectedProcedure = Trpc.procedure.query(async ({ ctx }) => {
// ctx.session.user is guaranteed to exist here
return { message: `Hello, ${ctx.session.user.name}!` };
});

In these examples, publicProcedure can be accessed without authentication, while protectedProcedure requires a valid user session.