A minimal starter for ATProto logins in Astro
at main 1.4 kB view raw
1import type { AstroCookies } from 'astro' 2 3export type SessionData = { did?: string } 4 5const COOKIE_NAME = 'sid' 6 7// Simple cookie-based session using Web Crypto API 8export class Session { 9 private data: SessionData = {} 10 private cookies: AstroCookies 11 12 constructor(cookies: AstroCookies, data: SessionData = {}) { 13 this.cookies = cookies 14 this.data = data 15 } 16 17 get did() { 18 return this.data.did 19 } 20 21 set did(value: string | undefined) { 22 this.data.did = value 23 } 24 25 async save() { 26 const jsonData = JSON.stringify(this.data) 27 // For simplicity, we'll just base64 encode the data 28 // In production, you'd want proper encryption 29 const encoded = btoa(jsonData) 30 31 this.cookies.set(COOKIE_NAME, encoded, { 32 httpOnly: true, 33 secure: false, 34 sameSite: 'lax', 35 path: '/', 36 maxAge: 60 * 60 * 24 * 30, // 30 days 37 }) 38 } 39 40 destroy() { 41 this.data = {} 42 this.cookies.delete(COOKIE_NAME, { path: '/' }) 43 } 44} 45 46export function getSession(cookies: AstroCookies): Session { 47 const cookie = cookies.get(COOKIE_NAME) 48 49 if (!cookie?.value) { 50 return new Session(cookies) 51 } 52 53 try { 54 const decoded = atob(cookie.value) 55 const data = JSON.parse(decoded) as SessionData 56 return new Session(cookies, data) 57 } catch (err) { 58 console.warn('Failed to decode session:', err) 59 return new Session(cookies) 60 } 61}