new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Next.js · Guides · all subjects

authorization/dal

9 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Tainting prevents sensitive data exposure to client

Tainting should be used to prevent sensitive data from being exposed to the client by tainting data objects and/or specific values.

Data Access Layer (DAL) for centralized authorization

Create a DAL with a verifySession() function that checks if the session is valid and redirects unauthorized users. Use React's cache() API to memoize the return value during a render pass. The function should verify the session from cookies, check if userId exists, and return auth status and userId.

verifySession function with cache memoization

import 'server-only' import { cache } from 'react' import { cookies } from 'next/handlers' import { decrypt } from '@/app/lib/session' export const verifySession = cache(async () => { const cookie = (await cookies()).get('session')?.value const session = await decrypt(cookie) if (!session?.userId) { redirect('/login') } return { isAuth: true, userId: session.userId } })

getUser function in DAL with data fetching

export const getUser = cache(async () => { const session = await verifySession() if (!session) return null try { const data = await db.query.users.findMany({ where: eq(users.id, session.userId), columns: { id: true, name: true, email: true, }, }) const user = data[0] return user } catch (error) { console.log('Failed to fetch user') return null } })

Data Transfer Objects (DTO) pattern

Return only the necessary data that will be used in the application, not entire objects. Use strategies like specifying which fields are safe to expose to the client. Create functions that check permissions (e.g., canSeeUsername, canSeePhoneNumber) and conditionally return fields based on viewer permissions.

Data Access Layer pattern requirements

A Data Access Layer (DAL) should only run on the server, perform authorization checks, and return safe, minimal Data Transfer Objects (DTOs). This centralizes all data access logic to enforce consistent data access practices, reduce authorization bugs, and benefit from sharing an in-memory cache across different parts of a request.

Data Access Layer pattern for Server Action mutations

Apply the Data Access Layer pattern to mutations just as you do for reading data. Keep authentication, authorization, and database logic in a dedicated server-only module, while 'use server' actions stay thin by delegating to the DAL. This keeps mutation logic centralized and secure.

Data Access Layer for centralized session reads

Centralize session reads, validation, and user lookups in a single Data Access Layer function like getCurrentUser(). This pattern returns a narrow user object and prevents components from reading the session directly multiple times.

Keep unexported internal cached functions private

Keep cached data functions like getNotesByUserId unexported to prevent callers from requesting another user's data by passing a different id. Only export the outer function that resolves the user, ensuring safe data access.

Give your agent this brain