work-timer/app/session.server.ts

111 lines
2.7 KiB
TypeScript
Raw Normal View History

import { createCookieSessionStorage, redirect } from '@remix-run/node';
import invariant from 'tiny-invariant';
2023-02-11 03:14:14 +01:00
import type { User } from '~/models/user.server';
import { getUserById } from '~/models/user.server';
2023-02-11 03:14:14 +01:00
invariant(process.env.SESSION_SECRET, 'SESSION_SECRET must be set');
const SESSION_SECRET = process.env.SESSION_SECRET;
2023-02-11 03:14:14 +01:00
export const sessionStorage = createCookieSessionStorage({
cookie: {
name: 'wta__session',
2023-02-11 03:14:14 +01:00
httpOnly: true,
path: '/',
sameSite: 'lax',
secrets: [SESSION_SECRET],
secure: process.env.NODE_ENV === 'production'
}
});
2023-02-11 03:14:14 +01:00
const USER_SESSION_KEY = 'userId';
2023-02-11 03:14:14 +01:00
export async function getSession(request: Request) {
const cookie = request.headers.get('Cookie');
return sessionStorage.getSession(cookie);
2023-02-11 03:14:14 +01:00
}
export async function getUserId(
request: Request
): Promise<User['id'] | undefined> {
const session = await getSession(request);
const userId = session.get(USER_SESSION_KEY);
return userId;
2023-02-11 03:14:14 +01:00
}
export async function getUser(request: Request) {
const userId = await getUserId(request);
if (userId === undefined) return null;
2023-02-11 03:14:14 +01:00
const user = await getUserById(userId);
if (user) return user;
2023-02-11 03:14:14 +01:00
throw await logout(request);
2023-02-11 03:14:14 +01:00
}
export async function requireUserId(
request: Request,
redirectTo: string = new URL(request.url).pathname
) {
const userId = await getUserId(request);
2023-02-11 03:14:14 +01:00
if (!userId) {
const searchParams = new URLSearchParams([['redirectTo', redirectTo]]);
throw redirect(`/login?${searchParams}`);
2023-02-11 03:14:14 +01:00
}
return userId;
2023-02-11 03:14:14 +01:00
}
2023-06-22 13:11:03 +02:00
export async function requireAdminUserId(
request: Request,
redirectTo: string = new URL(request.url).pathname
) {
const user = await getUser(request);
if (!user || !user.admin) {
const searchParams = new URLSearchParams([['redirectTo', redirectTo]]);
throw redirect(`/login?${searchParams}`);
}
return user.id;
}
2023-02-11 03:14:14 +01:00
export async function requireUser(request: Request) {
const userId = await requireUserId(request);
2023-02-11 03:14:14 +01:00
const user = await getUserById(userId);
if (user) return user;
2023-02-11 03:14:14 +01:00
throw await logout(request);
2023-02-11 03:14:14 +01:00
}
export async function createUserSession({
request,
userId,
remember,
redirectTo
}: {
request: Request;
userId: string;
remember: boolean;
redirectTo: string;
2023-02-11 03:14:14 +01:00
}) {
const session = await getSession(request);
session.set(USER_SESSION_KEY, userId);
2023-02-11 03:14:14 +01:00
return redirect(redirectTo, {
headers: {
'Set-Cookie': await sessionStorage.commitSession(session, {
maxAge: remember
? 60 * 60 * 24 * 14 // 14 days
: undefined
})
}
});
2023-02-11 03:14:14 +01:00
}
export async function logout(request: Request) {
const session = await getSession(request);
2023-02-11 03:14:14 +01:00
return redirect('/', {
headers: {
'Set-Cookie': await sessionStorage.destroySession(session)
}
});
2023-02-11 03:14:14 +01:00
}