fork
Configure Feed
Select the types of activity you want to include in your feed.
Graphical PDS migrator for AT Protocol
fork
Configure Feed
Select the types of activity you want to include in your feed.
1import { SessionOptions as BaseSessionOptions } from "npm:iron-session";
2
3/**
4 * The session options.
5 * @type {SessionOptions}
6 * @implements {BaseSessionOptions}
7 */
8interface SessionOptions extends BaseSessionOptions {
9 lockFn?: (key: string) => Promise<() => Promise<void>>;
10}
11
12/**
13 * Create a lock using Deno KV.
14 * @param key - The key to lock
15 * @param db - The Deno KV instance for the database
16 * @returns The unlock function
17 */
18async function createLock(
19 key: string,
20 db: Deno.Kv,
21): Promise<() => Promise<void>> {
22 const lockKey = ["session_lock", key];
23 const lockValue = Date.now();
24
25 // Try to acquire lock
26 const result = await db.atomic()
27 .check({ key: lockKey, versionstamp: null }) // Only if key doesn't exist
28 .set(lockKey, lockValue, { expireIn: 5000 }) // 5 second TTL
29 .commit();
30
31 if (!result.ok) {
32 throw new Error("Failed to acquire lock");
33 }
34
35 // Return unlock function
36 return async () => {
37 await db.delete(lockKey);
38 };
39}
40
41/**
42 * The OAuth session.
43 * @type {OauthSession}
44 */
45export interface OauthSession {
46 did: string;
47}
48
49/**
50 * The credential session.
51 * @type {CredentialSession}
52 */
53export interface CredentialSession {
54 did: string;
55 handle: string;
56 service: string;
57 password: string;
58 accessJwt?: string;
59 recoveryKey?: string;
60 recoveryKeyDid?: string;
61 credentials?: {
62 rotationKeys: string[];
63 [key: string]: unknown;
64 };
65}
66
67let db: Deno.Kv;
68
69/**
70 * Create the session options.
71 * @param cookieName - The name of the iron session cookie
72 * @returns The session options for iron session
73 */
74export const createSessionOptions = async (
75 cookieName: string,
76): Promise<SessionOptions> => {
77 const cookieSecret = Deno.env.get("COOKIE_SECRET");
78 if (!cookieSecret) {
79 throw new Error("COOKIE_SECRET is not set");
80 }
81
82 if (!db) {
83 db = await Deno.openKv();
84 }
85
86 return {
87 cookieName: cookieName,
88 password: cookieSecret,
89 cookieOptions: {
90 secure: Deno.env.get("NODE_ENV") === "production" ||
91 Deno.env.get("NODE_ENV") === "staging",
92 httpOnly: true,
93 sameSite: "lax",
94 path: "/",
95 domain: undefined,
96 },
97 lockFn: (key: string) => createLock(key, db),
98 };
99};