a a vibe-coded abomination experiment of a fragrance review platform built on the atmosphere. drydown.social
at main 151 lines 3.7 kB view raw view rendered
1# Existing Code Reference 2 3**Related Documents**: 4- [Architecture Overview](../architecture/overview.md) - System design 5- CLAUDE.md (project root) - Project overview 6 7## Current Codebase (🟢 Implemented) 8 9### Authentication Module 10 11**File**: `/src/auth.ts` 12 13**Key Functions**: 14- `getClient()` - Returns singleton BrowserOAuthClient instance 15- `initAuth()` - Initializes OAuth and checks for existing sessions 16- `login(handle)` - Initiates OAuth sign-in flow with Bluesky handle 17 18**OAuth Configuration**: 19- `client_id`: Special format using localhost with encoded redirect_uri 20- `redirect_uris`: `['http://127.0.0.1:5173']` 21- `handleResolver`: `'https://bsky.social'` 22- **CRITICAL**: Must run on `127.0.0.1:5173` (not `localhost`) 23 24**Example Usage**: 25```typescript 26// Initialize on app mount 27useEffect(() => { 28 initAuth().then(session => { 29 if (session) setSession(session) 30 }) 31}, []) 32 33// Login 34const handleLogin = async (handle: string) => { 35 await login(handle) // Redirects to Bluesky OAuth 36} 37``` 38 39--- 40 41### App Component 42 43**File**: `/src/app.tsx` 44 45**Responsibilities**: 46- Session state management (`session: OAuthSession | null`) 47- Loading state during auth initialization 48- Conditional rendering: LoginForm vs authenticated UI 49- Sign out action 50 51**State**: 52```typescript 53const [session, setSession] = useState<OAuthSession | null>(null) 54const [isInitializing, setIsInitializing] = useState(true) 55``` 56 57**Flow**: 581. App mounts → call `initAuth()` 592. If session exists → show authenticated UI 603. If no session → show LoginForm 61 62--- 63 64### LoginForm Component 65 66**File**: `/src/components/LoginForm.tsx` 67 68**Features**: 69- Text input for Bluesky handle (placeholder: "alice.bsky.social") 70- Loading state during OAuth redirect 71- Error message display 72- Form submission handling 73 74**Example**: 75```typescript 76<form onSubmit={handleSubmit}> 77 <input 78 type="text" 79 placeholder="alice.bsky.social" 80 value={handle} 81 onChange={(e) => setHandle(e.target.value)} 82 /> 83 <button type="submit" disabled={loading}> 84 {loading ? 'Signing in...' : 'Sign In'} 85 </button> 86 {error && <div class="error">{error}</div>} 87</form> 88``` 89 90--- 91 92### Development Server Configuration 93 94**File**: `/vite.config.ts` 95 96**Key Settings**: 97- Server host: `127.0.0.1` (NOT `localhost`) 98- Server port: `5173` 99- This is REQUIRED for OAuth to work 100 101```typescript 102export default defineConfig({ 103 plugins: [preact()], 104 server: { 105 host: '127.0.0.1', 106 port: 5173 107 } 108}) 109``` 110 111--- 112 113### Known Limitations 114 115**Logout Implementation** (`/src/app.tsx`): 116- Currently only clears UI state (`setSession(null)`) 117- Does NOT revoke OAuth tokens 118- Does NOT clear browser storage 119- SDK limitation: `BrowserOAuthClient` doesn't expose token revocation 120 121**Future Improvement**: Investigate SDK updates for proper logout 122 123--- 124 125## Project Structure 126 127``` 128/src 129├── main.tsx # App entry point 130├── app.tsx # Main App component (session mgmt) 131├── auth.ts # OAuth client singleton 132├── index.css # Global styles 133├── app.css # App-specific styles 134└── components/ 135 └── LoginForm.tsx # Login form component 136 137/public 138├── vite.svg # Vite logo 139└── client-metadata.json # OAuth metadata (served statically) 140 141index.html # HTML entry point 142vite.config.ts # Vite config (127.0.0.1:5173) 143CLAUDE.md # Project documentation 144``` 145 146--- 147 148**Related Documents**: 149- [Architecture Overview](../architecture/overview.md) - Where new code will fit 150- [Implementation Roadmap](../implementation/overview.md) - What to build next 151- CLAUDE.md - Original project overview