this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: centralize auth session requirements

+68 -55
+16 -24
app/(creator)/actions.ts
··· 3 3 import { revalidatePath } from "next/cache"; 4 4 import { redirect } from "next/navigation"; 5 5 6 - import { getServerAuthSession } from "@/lib/auth"; 6 + import { 7 + requireServerAuthSession, 8 + requireServerSessionUserId, 9 + } from "@/lib/auth"; 7 10 import { createDraftForm } from "@/lib/forms"; 8 11 import { 9 12 createOrganization, ··· 20 23 getActiveWorkspaceForUser, 21 24 } from "@/lib/workspaces"; 22 25 23 - async function requireSessionUser() { 24 - const session = await getServerAuthSession(); 25 - 26 - if (!session?.user?.id) { 27 - redirect("/"); 28 - } 29 - 30 - return session.user.id; 31 - } 32 - 33 26 function settingsRedirectTarget( 34 27 formData: FormData, 35 28 fallback?: { organizationId?: string | null; section?: string | null }, ··· 55 48 } 56 49 57 50 export async function createFormAction() { 58 - const userId = await requireSessionUser(); 59 - const { activeWorkspace } = await getActiveWorkspaceForUser(userId); 60 - const session = await getServerAuthSession(); 51 + const session = await requireServerAuthSession(); 52 + const { activeWorkspace } = await getActiveWorkspaceForUser(session.user.id); 61 53 const form = await createDraftForm( 62 - userId, 54 + session.user.id, 63 55 activeWorkspace, 64 - session?.user.locale, 56 + session.user.locale, 65 57 ); 66 58 67 59 redirect(`/forms/${form.id}/edit`); 68 60 } 69 61 70 62 export async function setActiveWorkspaceAction(formData: FormData) { 71 - const userId = await requireSessionUser(); 63 + const userId = await requireServerSessionUserId(); 72 64 const { options } = await getActiveWorkspaceForUser(userId); 73 65 const nextValue = String(formData.get("workspace") ?? "personal"); 74 66 const isValidOption = options.some((option) => option.value === nextValue); ··· 79 71 } 80 72 81 73 export async function createOrganizationAction(formData: FormData) { 82 - const userId = await requireSessionUser(); 74 + const userId = await requireServerSessionUserId(); 83 75 const organization = await createOrganization(userId, { 84 76 name: formData.get("name"), 85 77 }); ··· 97 89 } 98 90 99 91 export async function renameOrganizationAction(formData: FormData) { 100 - const userId = await requireSessionUser(); 92 + const userId = await requireServerSessionUserId(); 101 93 const organizationId = String(formData.get("organizationId") ?? ""); 102 94 await renameOrganization(userId, organizationId, { 103 95 name: formData.get("name"), ··· 111 103 } 112 104 113 105 export async function deleteOrganizationAction(formData: FormData) { 114 - const userId = await requireSessionUser(); 106 + const userId = await requireServerSessionUserId(); 115 107 await deleteOrganization( 116 108 userId, 117 109 String(formData.get("organizationId") ?? ""), ··· 121 113 } 122 114 123 115 export async function createOrganizationInviteLinkAction(formData: FormData) { 124 - const userId = await requireSessionUser(); 116 + const userId = await requireServerSessionUserId(); 125 117 const organizationId = String(formData.get("organizationId") ?? ""); 126 118 await createOrganizationInviteLink(userId, organizationId); 127 119 redirect( ··· 133 125 } 134 126 135 127 export async function revokeOrganizationInviteLinkAction(formData: FormData) { 136 - const userId = await requireSessionUser(); 128 + const userId = await requireServerSessionUserId(); 137 129 const organizationId = String(formData.get("organizationId") ?? ""); 138 130 await revokeOrganizationInviteLink( 139 131 userId, ··· 149 141 } 150 142 151 143 export async function removeOrganizationMemberAction(formData: FormData) { 152 - const userId = await requireSessionUser(); 144 + const userId = await requireServerSessionUserId(); 153 145 const organizationId = String(formData.get("organizationId") ?? ""); 154 146 await removeOrganizationMember( 155 147 userId, ··· 165 157 } 166 158 167 159 export async function updateProfileAction(formData: FormData) { 168 - const userId = await requireSessionUser(); 160 + const userId = await requireServerSessionUserId(); 169 161 await updateProfileSettings(userId, { 170 162 firstName: formData.get("firstName"), 171 163 secondName: formData.get("secondName"),
+4 -4
app/(creator)/dashboard/page.tsx
··· 6 6 import { EmptyState } from "@/components/empty-state"; 7 7 import { PageHeader } from "@/components/ui/page-header"; 8 8 import { Button } from "@/components/ui/button"; 9 - import { getServerAuthSession } from "@/lib/auth"; 9 + import { requireServerSessionUser } from "@/lib/auth"; 10 10 import { listFormsForWorkspace } from "@/lib/forms"; 11 11 import { getRequestI18n } from "@/lib/i18n-server"; 12 12 import { getActiveWorkspaceForUser } from "@/lib/workspaces"; 13 13 import { withTitle } from "@/lib/metadata"; 14 14 15 15 async function getDashboardData() { 16 - const session = await getServerAuthSession(); 16 + const user = await requireServerSessionUser(); 17 17 const { t } = await getRequestI18n(); 18 - const workspaceState = await getActiveWorkspaceForUser(session!.user.id); 18 + const workspaceState = await getActiveWorkspaceForUser(user.id); 19 19 const forms = await listFormsForWorkspace( 20 - session!.user.id, 20 + user.id, 21 21 workspaceState.activeWorkspace, 22 22 ); 23 23 const workspaceLabel =
+3 -3
app/(creator)/forms/[id]/edit/page.tsx
··· 2 2 import { notFound } from "next/navigation"; 3 3 4 4 import { FormBuilder } from "@/components/form-builder"; 5 - import { getServerAuthSession } from "@/lib/auth"; 5 + import { requireServerSessionUser } from "@/lib/auth"; 6 6 import { AppError } from "@/lib/errors"; 7 7 import { getOwnedFormForBuilder } from "@/lib/forms"; 8 8 import { resolveTitle, withTitle } from "@/lib/metadata"; 9 9 import { getRequestI18n } from "@/lib/i18n-server"; 10 10 11 11 async function getEditableForm(id: string) { 12 - const session = await getServerAuthSession(); 12 + const user = await requireServerSessionUser(); 13 13 14 14 try { 15 - return await getOwnedFormForBuilder(session!.user.id, id); 15 + return await getOwnedFormForBuilder(user.id, id); 16 16 } catch (error) { 17 17 if (error instanceof AppError && error.status === 404) { 18 18 notFound();
+3 -3
app/(creator)/forms/[id]/responses/[responseId]/page.tsx
··· 8 8 import { Card } from "@/components/ui/card"; 9 9 import { AuthoredMarkdown } from "@/components/ui/authored-markdown"; 10 10 import { AGREEMENT_ANSWER_VALUES } from "@/lib/blocks"; 11 - import { getServerAuthSession } from "@/lib/auth"; 11 + import { requireServerSessionUser } from "@/lib/auth"; 12 12 import { AppError } from "@/lib/errors"; 13 13 import { getOwnedResponseDetail } from "@/lib/forms"; 14 14 import { getRequestI18n } from "@/lib/i18n-server"; ··· 16 16 import { formatCalendarDate, formatDate } from "@/lib/utils"; 17 17 18 18 async function getResponseData(id: string, responseId: string) { 19 - const session = await getServerAuthSession(); 19 + const user = await requireServerSessionUser(); 20 20 21 21 try { 22 - return await getOwnedResponseDetail(session!.user.id, id, responseId); 22 + return await getOwnedResponseDetail(user.id, id, responseId); 23 23 } catch (error) { 24 24 if (error instanceof AppError && error.status === 404) { 25 25 notFound();
+3 -3
app/(creator)/forms/[id]/responses/page.tsx
··· 15 15 AGREEMENT_ANSWER_VALUES, 16 16 blockTypeTranslationKeys, 17 17 } from "@/lib/blocks"; 18 - import { getServerAuthSession } from "@/lib/auth"; 18 + import { requireServerSessionUser } from "@/lib/auth"; 19 19 import { AppError } from "@/lib/errors"; 20 20 import { listResponsesForOwnedForm } from "@/lib/forms"; 21 21 import { getRequestI18n } from "@/lib/i18n-server"; ··· 24 24 import { cn, formatCalendarDate, formatDate } from "@/lib/utils"; 25 25 26 26 async function getResponsesData(id: string) { 27 - const session = await getServerAuthSession(); 27 + const user = await requireServerSessionUser(); 28 28 29 29 try { 30 - return await listResponsesForOwnedForm(session!.user.id, id); 30 + return await listResponsesForOwnedForm(user.id, id); 31 31 } catch (error) { 32 32 if (error instanceof AppError && error.status === 404) { 33 33 notFound();
+2 -6
app/(creator)/forms/new/route.ts
··· 1 1 import { redirect } from "next/navigation"; 2 2 3 - import { getServerAuthSession } from "@/lib/auth"; 3 + import { requireServerAuthSession } from "@/lib/auth"; 4 4 import { createDraftForm } from "@/lib/forms"; 5 5 import { getActiveWorkspaceForUser } from "@/lib/workspaces"; 6 6 7 7 export async function GET() { 8 - const session = await getServerAuthSession(); 9 - 10 - if (!session?.user?.id) { 11 - redirect("/"); 12 - } 8 + const session = await requireServerAuthSession(); 13 9 14 10 const { activeWorkspace } = await getActiveWorkspaceForUser(session.user.id); 15 11 const form = await createDraftForm(session.user.id, activeWorkspace);
+2 -7
app/(creator)/layout.tsx
··· 1 1 import Image from "next/image"; 2 2 import Link from "next/link"; 3 - import { redirect } from "next/navigation"; 4 3 5 4 import { AccountMenu } from "@/components/account-menu"; 6 5 import { WorkspaceSwitcher } from "@/components/workspace-switcher"; 7 - import { getServerAuthSession } from "@/lib/auth"; 6 + import { requireServerAuthSession } from "@/lib/auth"; 8 7 import { getRequestI18n } from "@/lib/i18n-server"; 9 8 import { 10 9 getActiveWorkspaceForUser, ··· 16 15 }: { 17 16 children: React.ReactNode; 18 17 }) { 19 - const session = await getServerAuthSession(); 18 + const session = await requireServerAuthSession(); 20 19 const { t } = await getRequestI18n(); 21 20 const appName = t("app.name"); 22 - 23 - if (!session?.user?.id) { 24 - redirect("/"); 25 - } 26 21 27 22 const workspaceState = await getActiveWorkspaceForUser(session.user.id); 28 23
+4 -4
app/(creator)/settings/page.tsx
··· 1 1 import type { Metadata } from "next"; 2 2 3 3 import { SettingsShell } from "@/components/settings-shell"; 4 - import { getServerAuthSession } from "@/lib/auth"; 4 + import { requireServerSessionUser } from "@/lib/auth"; 5 5 import { listOrganizationsForUser } from "@/lib/organizations"; 6 6 import { getRequestI18n } from "@/lib/i18n-server"; 7 7 import { withTitle } from "@/lib/metadata"; ··· 20 20 section?: string | string[]; 21 21 }>; 22 22 }) { 23 - const session = await getServerAuthSession(); 23 + const user = await requireServerSessionUser(); 24 24 const [organizations, profileUser] = await Promise.all([ 25 - listOrganizationsForUser(session!.user.id), 26 - getProfileSettingsUser(session!.user.id), 25 + listOrganizationsForUser(user.id), 26 + getProfileSettingsUser(user.id), 27 27 ]); 28 28 const resolvedSearchParams = await searchParams; 29 29 const initialOrganizationId = Array.isArray(resolvedSearchParams.organization)
+31 -1
lib/auth.ts
··· 1 1 import { PrismaAdapter } from "@auth/prisma-adapter"; 2 2 import type { Adapter } from "next-auth/adapters"; 3 - import { getServerSession, type NextAuthOptions } from "next-auth"; 3 + import { 4 + getServerSession, 5 + type NextAuthOptions, 6 + type Session, 7 + } from "next-auth"; 4 8 import GoogleProvider from "next-auth/providers/google"; 9 + 10 + import { redirect } from "next/navigation"; 5 11 6 12 import { db } from "@/lib/db"; 7 13 import { normalizeLocale } from "@/lib/i18n"; ··· 78 84 export function getServerAuthSession() { 79 85 return getServerSession(authOptions); 80 86 } 87 + 88 + type AuthenticatedSession = Session & { 89 + user: NonNullable<Session["user"]> & { 90 + id: string; 91 + }; 92 + }; 93 + 94 + export async function requireServerAuthSession(redirectTo = "/") { 95 + const session = await getServerAuthSession(); 96 + 97 + if (!session?.user?.id) { 98 + redirect(redirectTo); 99 + } 100 + 101 + return session as AuthenticatedSession; 102 + } 103 + 104 + export async function requireServerSessionUser(redirectTo = "/") { 105 + return (await requireServerAuthSession(redirectTo)).user; 106 + } 107 + 108 + export async function requireServerSessionUserId(redirectTo = "/") { 109 + return (await requireServerSessionUser(redirectTo)).id; 110 + }