aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/app/.server/session.ts
blob: 0edcc356f8ec8418bf82d4e76b42121c1d82dfe9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { createCookieSessionStorage } from "react-router";

export const cookieOptions = {
	sameSite: "lax" as const,
	path: "/",
	httpOnly: true,
	secure: process.env.NODE_ENV === "production",
	secrets: [process.env.ALBATROSS_COOKIE_SECRET ?? "local"],
};

const innerSessionStorage = createCookieSessionStorage({
	cookie: {
		name: "albatross_session",
		...cookieOptions,
	},
});
type InnerSessionStorage = typeof innerSessionStorage;

// This class is used to recover from invalid sessions.
// It may occur if the session had been created before the authentication library was updated.
class RecoverableSessionStorage {
	innerStorage: InnerSessionStorage;

	constructor(innerStorage: InnerSessionStorage) {
		this.innerStorage = innerStorage;
	}

	// If the session is invalid, return a new session.
	// It may occur if the session had been created before the authentication library was updated.
	getSession(...args: Parameters<InnerSessionStorage["getSession"]>) {
		try {
			return this.innerStorage.getSession(...args);
		} catch (e) {
			void e;
			return this.innerStorage.getSession();
		}
	}

	commitSession(...args: Parameters<InnerSessionStorage["commitSession"]>) {
		return this.innerStorage.commitSession(...args);
	}

	destroySession(...args: Parameters<InnerSessionStorage["destroySession"]>) {
		return this.innerStorage.destroySession(...args);
	}
}

export const sessionStorage = new RecoverableSessionStorage(
	innerSessionStorage,
);