remix-demo

react router (remix) demo

git clone https://9o.is/git/remix-demo.git

session.server.ts

(2522B)


      1 import { Role } from "@prisma/client";
      2 import { createCookieSessionStorage, redirect } from "@remix-run/node";
      3 import { json } from "remix-utils";
      4 import invariant from "tiny-invariant";
      5 
      6 import type { User } from "~/models/user.server";
      7 import { getUserById } from "~/models/user.server";
      8 
      9 invariant(process.env.SESSION_SECRET, "SESSION_SECRET must be set");
     10 
     11 export const sessionStorage = createCookieSessionStorage({
     12   cookie: {
     13     name: "__session",
     14     httpOnly: true,
     15     path: "/",
     16     sameSite: "lax",
     17     secrets: [process.env.SESSION_SECRET],
     18     secure: process.env.NODE_ENV === "production",
     19   },
     20 });
     21 
     22 const USER_SESSION_KEY = "userId";
     23 
     24 export async function getSession(request: Request) {
     25   const cookie = request.headers.get("Cookie");
     26   return sessionStorage.getSession(cookie);
     27 }
     28 
     29 export async function getUserId(
     30   request: Request
     31 ): Promise<User["id"] | undefined> {
     32   const session = await getSession(request);
     33   return session.get(USER_SESSION_KEY);
     34 }
     35 
     36 export async function getUser(request: Request) {
     37   const userId = await getUserId(request);
     38   if (userId === undefined) return null;
     39 
     40   const user = await getUserById(userId);
     41 
     42   if (user) return user;
     43   throw await destroyUserSession(request);
     44 }
     45 
     46 export async function requireUserId(request: Request) {
     47   const userId = await getUserId(request);
     48   if (!userId) {
     49     const path = new URL(request.url).pathname;
     50 
     51     if (path.startsWith("/api")) {
     52       throw json({ error: "Unauthorized" }, { status: 401 });
     53     }
     54 
     55     throw redirect(`/login`);
     56   }
     57   return userId;
     58 }
     59 
     60 export async function requireUser(request: Request) {
     61   const userId = await requireUserId(request);
     62 
     63   const user = await getUserById(userId);
     64   if (user) return user;
     65 
     66   throw await destroyUserSession(request);
     67 }
     68 
     69 export async function requireAdmin(request: Request) {
     70   const user = await requireUser(request);
     71 
     72   if (user.role !== Role.ADMIN) {
     73     throw json({ error: "Forbidden" }, { status: 403 });
     74   }
     75 
     76   return user;
     77 }
     78 
     79 export async function createUserSession({
     80   request,
     81   userId,
     82 }: {
     83   request: Request;
     84   userId: string;
     85 }) {
     86   const session = await getSession(request);
     87   session.set(USER_SESSION_KEY, userId);
     88   return redirect("/", {
     89     headers: {
     90       "Set-Cookie": await sessionStorage.commitSession(session),
     91     },
     92   });
     93 }
     94 
     95 export async function destroyUserSession(request: Request) {
     96   const session = await getSession(request);
     97   return redirect("/", {
     98     headers: {
     99       "Set-Cookie": await sessionStorage.destroySession(session),
    100     },
    101   });
    102 }