### Start Drop In Application (npm/pnpm) Source: https://github.com/stolinski/drop-in/blob/main/packages/docs/src/content/docs/guides/get-started.mdx This snippet demonstrates how to start the Drop In application after setup and configuration. It provides commands for both npm and pnpm users. ```sh npm run start ``` ```sh pnpm start ``` -------------------------------- ### Create New Drop In Project (npm/pnpm) Source: https://github.com/stolinski/drop-in/blob/main/packages/docs/src/content/docs/guides/get-started.mdx This snippet shows how to initiate a new Drop In project using either npm or pnpm package managers. It utilizes the `@drop-in/new` command to scaffold a new project. ```sh npx @drop-in/new ``` ```sh pnpx @drop-in/new ``` -------------------------------- ### Run Svelte Development Server Source: https://github.com/stolinski/drop-in/blob/main/packages/ramps/README.md Commands to start the development server for a Svelte project. After installing dependencies, these commands will build and serve the project locally, with an option to automatically open it in a browser. ```bash npm run dev # or start the server and open the app in a new browser tab npm run dev -- --open ``` -------------------------------- ### Drop In Project Environment Variables Source: https://github.com/stolinski/drop-in/blob/main/packages/docs/src/content/docs/guides/get-started.mdx This section details the required environment variables for a Drop In project, focusing on zero-cache server configuration, database connections, JWT secrets for authentication, and replication settings. These variables are crucial for the correct functioning of the zero-cache service and data replication. ```env # This is the server of the local zero cache server, usually will be http://127.0.0.1:4848 unless you have changed it. PUBLIC_SERVER=http://127.0.0.1:4848 # Database URL, should be your postgres database DATABASE_URL="" # * These must be the same so that zero can verify the JWT # * Generate a random string. JWT_SECRET="" ZERO_JWT_SECRET="" # * These are needed for Zero Cache # In the future we will support other types of upstreams besides PG ZERO_UPSTREAM_DB = "" # A separate Postgres database we use to store CVRs. CVRs (client view records) # keep track of which clients have which data. This is how we know what diff to # send on reconnect. It can be same database as above, but in production it # can make sense to have it be separate to scale them seperately. ZERO_CVR_DB = "" # Yet another Postgres database which we used to store a replication log. ZERO_CHANGE_DB = "" # Uniquely identifies a single instance of the zero-cache service. REPLICA_ID = "r1" # Place to store the SQLite data zero-cache maintains. This can be lost, but if # it is, zero-cache will have to re-replicate next time it starts up. ZERO_REPLICA_FILE = "/tmp/dropin-sync-replica.db" # Logging level for zero-cache service. ZERO_LOG_LEVEL = "debug" ``` -------------------------------- ### Client-Side Usage Example (Signup) Source: https://github.com/stolinski/drop-in/blob/main/packages/docs/src/content/docs/pass/reference.md Example demonstrating how to use the client-side `pass` object to handle user signup. ```APIDOC ## Client-Side Usage Example (Signup) ### Description Illustrates how to implement a signup form using the `@drop-in/pass/client` library and handle the response. ### Method N/A (Client-side Script) ### Endpoint `src/routes/(site)/auth` (Example) ### Parameters #### Code Example ```svelte ``` ### Notes - The `pass.signup()` function communicates with the server-side API route. - Ensure `z.` methods are not removed for proper UI feedback and state management. - UI components like `` are provided by `@drop-in/ramps`. ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/stolinski/drop-in/blob/main/README.md Installs the necessary project dependencies for a Drop-in application. This command should be run after creating a new project and navigating into its directory. ```bash pnpm install || npm install ``` -------------------------------- ### Set Up SvelteKit Server Hooks for Authentication Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/README.md This TypeScript example shows how to configure server-side hooks for a SvelteKit application using `@drop-in/pass`. It initializes a database connection using Drizzle ORM with PostgreSQL and integrates Drop-in's session handling and authentication routes. This setup automatically populates `event.locals.user` and manages authentication routes. ```typescript import { create_pass_routes, create_session_handle } from '@drop-in/pass'; import { sequence } from '@sveltejs/kit/hooks'; import { drizzle } from 'drizzle-orm/node-postgres'; import pg from 'pg'; import * as schema from '@drop-in/pass/schema'; const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL }); const db = drizzle(pool, { schema }); export const handle = sequence( create_session_handle(db), // Populates event.locals.user automatically create_pass_routes(db) // Handles auth routes (/api/auth/*) ); ``` -------------------------------- ### Troubleshooting `locals.user` Undefined - TypeScript Example Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/LOCALS-SETUP-GUIDE.md Provides troubleshooting steps for when `locals.user` is unexpectedly undefined in SvelteKit applications using `@drop-in/pass`. It highlights common configuration errors in `hooks.server.ts`, showing incorrect setups (missing `create_session_handle`, wrong order) and the correct sequence for initializing the authentication hooks. ```typescript // ❌ Wrong - missing create_session_handle export const handle = create_pass_routes(db); // ❌ Wrong - wrong order export const handle = sequence(create_pass_routes(db), create_session_handle(db)); // ✅ Correct export const handle = sequence(create_session_handle(db), create_pass_routes(db)); ``` -------------------------------- ### Migration Example: Old Beeper Email Configuration Source: https://github.com/stolinski/drop-in/blob/main/packages/docs/src/content/docs/pass/email-setup.md Illustrates the previous email configuration format in Drop In when using `@drop-in/beeper` directly. This shows the host, port, security, and sender address settings before the introduction of the `sendEmail` callback. ```javascript // Old configuration export default { email: { host: 'smtp.example.com', port: 587, secure: true, from: 'noreply@example.com' }, }; ``` -------------------------------- ### PNPM Commands for Starlight Development Source: https://github.com/stolinski/drop-in/blob/main/packages/docs/README.md Provides a list of essential PNPM commands for managing an Astro + Starlight project. These commands cover dependency installation, local development server, building for production, previewing builds, and running Astro CLI commands. ```bash pnpm install ``` ```bash pnpm dev ``` ```bash pnpm build ``` ```bash pnpm preview ``` ```bash pnpm astro ... ``` ```bash pnpm astro -- --help ``` -------------------------------- ### Install @drop-in/pass Package Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/README.md Installs the @drop-in/pass library using npm. This is the first step to integrate authentication into your SvelteKit application. ```bash npm install @drop-in/pass ``` -------------------------------- ### Install Beeper Package Source: https://github.com/stolinski/drop-in/blob/main/packages/docs/src/content/docs/beeper/reference.md Installs the Beeper package using npm. This is the first step to integrate Beeper into your Node.js project for email sending capabilities. ```bash npm install @drop-in/beeper ``` -------------------------------- ### Install @drop-in/decks via npm Source: https://github.com/stolinski/drop-in/blob/main/packages/decks/README.md This command installs the @drop-in/decks UI component library using npm. It does not have external dependencies or CSS framework requirements. ```bash npm install @drop-in/decks ``` -------------------------------- ### Environment Variables for Auth Configuration Source: https://github.com/stolinski/drop-in/blob/main/auth-migration-guide.md This snippet lists essential environment variables required for configuring both Better Auth and legacy authentication systems during the migration period. It includes secrets, URLs, and database connection strings. ```env # Better Auth configuration BETTER_AUTH_SECRET=your-secret-key BETTER_AUTH_URL=your-app-url # Legacy auth (during transition) DATABASE_URL=your-database-url JWT_SECRET=your-jwt-secret ``` -------------------------------- ### Create a Changeset with PNPM Source: https://github.com/stolinski/drop-in/blob/main/PUBLISHING.md This command initiates the interactive process of creating a changeset file. You will be prompted to select the packages to include in the changeset, choose a version bump type (patch, minor, or major), and provide a description for the changes. This is the first step in publishing package updates. ```bash pnpm changeset ``` -------------------------------- ### Client-side JWT Reading Migration (TypeScript) Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/SECURITY-UPGRADE.md This section contrasts the old method of reading JWTs directly from client-side code with the new approach. The 'Before' example shows deprecated functions like `get_login()`. The 'After (Server-side)' example illustrates accessing user data from `event.locals.user` within SvelteKit server contexts. The 'After (Client-side)' example shows fetching user data using the new `pass.me()` API method. ```typescript // Before: // import { get_login } from '@drop-in/pass'; // const { sub } = get_login(); ``` ```typescript // After (Server-side): // In load functions, hooks, or API routes if (event.locals.user) { const userId = event.locals.user.id; } ``` ```typescript // After (Client-side): import { pass } from '@drop-in/pass'; const { user } = await pass.me(); const userId = user.id; ``` -------------------------------- ### SvelteKit Server Hooks Setup with Drop-In Authentication Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/LOCALS-SETUP-GUIDE.md This TypeScript code configures the server-side hooks for a SvelteKit application using Drop-In authentication. It chains `create_session_handle` and `create_pass_routes` to manage user sessions and authentication routes, ensuring proper integration of the authentication middleware. ```typescript import { create_pass_routes, create_session_handle } from '@drop-in/pass'; import { sequence } from '@sveltejs/kit/hooks'; export const handle = sequence( create_session_handle(db), create_pass_routes(db) ); ``` -------------------------------- ### Email Configuration with Resend Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/README.md Example of configuring an email provider using Resend for Cloudflare Workers. ```APIDOC ## Email Configuration ### Method POST ### Endpoint `/api/emails` (Implicit via `sendEmail` function) ### Description Configures the email sending mechanism for password resets and other notifications. This example uses Resend, suitable for Cloudflare Workers. ### Request Body Example ```json { "to": "recipient@example.com", "subject": "Password Reset Request", "html": "

Please click the link to reset your password: ...

", "from": "noreply@yourdomain.com" } ``` ### Response Example (Success) ```json { "messageId": "msg_abc123" } ``` ### Response Example (Error) ```json { "message": "Failed to send email: Unauthorized" } ``` ### Notes - Password reset links include `email`, `key` (token), and `expire` (timestamp) query parameters. - Default expiration for reset links is 24 hours. - The reset endpoint expects these parameters. - See [Email Configuration Guide](https://your-docs-url/pass/email-setup) for more examples. ``` -------------------------------- ### Apply Version Bumps in Monorepo with PNPM Changesets Source: https://github.com/stolinski/drop-in/blob/main/PUBLISHING.md This command applies the version bumps defined in your changesets to the respective `package.json` files within the monorepo. It updates the versions and dependencies according to the changeset information, preparing the packages for publication. ```bash pnpm changeset:version ``` -------------------------------- ### Build and Publish Monorepo Packages with PNPM Source: https://github.com/stolinski/drop-in/blob/main/PUBLISHING.md This script automates the build process for changed packages within the monorepo and then publishes them. It ensures that all necessary build artifacts are generated before the packages are published to the npm registry. This is typically the final step after creating and previewing changesets. ```bash pnpm run release ``` -------------------------------- ### Cloudflare Workers Email Sending with Resend API Source: https://github.com/stolinski/drop-in/blob/main/packages/docs/src/content/docs/pass/email-setup.md Implements email sending for Cloudflare Workers using the Resend API. This example demonstrates making a POST request to the Resend API with necessary authentication and email content. ```javascript // drop-in.config.js const sendEmail = async ({ to, subject, html, from }) => { const response = await fetch('https://api.resend.com/emails', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.RESEND_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ to, subject, html, from }), }); if (!response.ok) { throw new Error(`Failed to send email: ${response.statusText}`); } }; export default { email: { from: 'noreply@yourdomain.com', sendEmail, }, // ... }; ``` -------------------------------- ### SvelteKit Server Hook Setup for @drop-in/pass Source: https://github.com/stolinski/drop-in/blob/main/packages/docs/src/content/docs/pass/reference.md This code snippet shows how to set up the necessary server hooks in a SvelteKit application to enable @drop-in/pass authentication. It uses `sequence` to combine the `pass_routes` hook for authentication endpoints and `drop_hook` to apply global Drop In configurations. ```typescript import { sequence } from '@sveltejs/kit/hooks'; import { pass_routes } from '@drop-in/pass'; import { drop_hook } from '@drop-in/plugin/hook'; // ? What's up with the two hooks? // Pass Routes is the hook for auth authentication, it includes the routes where auth is handeled. // Drop hook adds a global so our drop-in.config.js is read and applied to globals export const handle = sequence(pass_routes, drop_hook); ``` -------------------------------- ### Client-Side Authentication with @drop-in/pass Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/README.md These JavaScript examples illustrate how to perform common authentication actions directly in the client-side of a web application using the `@drop-in/pass/client` module. It covers user sign-up, login, retrieving the current user's session, and logging out. Error handling is included for each operation. ```javascript import { pass } from '@drop-in/pass/client'; // Sign up try { const result = await pass.signup('user@example.com', 'securepassword'); console.log('Signed up successfully!', result.user); } catch (error) { console.error('Signup failed:', error.message); } // Login try { const result = await pass.login('user@example.com', 'securepassword'); console.log('Logged in successfully!', result.user); } catch (error) { console.error('Login failed:', error.message); } // Get current user try { const { user } = await pass.me(); console.log('Current user:', user); } catch (error) { console.log('Not authenticated'); } // Logout await pass.logout(); ``` -------------------------------- ### Side Effects and DOM Wiring with $effect Source: https://github.com/stolinski/drop-in/blob/main/packages/decks/planning/phases/phase_1.md Shows how to handle side effects and DOM manipulation using the `$effect` rune. It includes a basic example of setting up an effect and returning a cleanup function to prevent memory leaks. ```typescript $effect(() => { // DOM manipulation or side effect logic console.log('Effect ran'); return () => { // Cleanup logic for the effect console.log('Effect cleaned up'); }; }); ``` -------------------------------- ### Preview Monorepo Release Changes with PNPM Source: https://github.com/stolinski/drop-in/blob/main/PUBLISHING.md This script allows you to preview the intended package version bumps and publications without actually performing the release. It's a crucial step for verifying that only the intended packages will be updated and published, helping to prevent accidental releases or incorrect versioning. ```bash pnpm run release:preview ``` -------------------------------- ### SQL Queries for Auth Migration Progress Source: https://github.com/stolinski/drop-in/blob/main/auth-migration-guide.md These SQL queries help monitor the progress of user authentication migration by tracking the distribution of authentication providers, identifying users still needing detection, and calculating the overall migration completion percentage. ```sql -- Check current distribution of auth providers SELECT auth_provider, COUNT(*) as user_count FROM user GROUP BY auth_provider; -- Find users who still need detection SELECT COUNT(*) as unknown_users FROM user WHERE auth_provider = 'unknown'; -- Check migration completion percentage SELECT (COUNT(CASE WHEN auth_provider IN ('better-auth', 'native-better-auth') THEN 1 END) * 100.0 / COUNT(*)) as migration_percentage FROM user; ``` -------------------------------- ### Send Email with Beeper (JavaScript) Source: https://github.com/stolinski/drop-in/blob/main/packages/docs/src/content/docs/beeper/reference.md Provides an example of how to use the `beeper.send()` method to send an email. This function takes an options object with recipient, subject, HTML content, and an optional sender address. ```javascript await beeper.send({ to: 'user@example.com', subject: 'Welcome!', html: '

Thanks for signing up!

', from: 'noreply@example.com' }); ``` -------------------------------- ### Publish Changed Monorepo Packages with PNPM Changesets Source: https://github.com/stolinski/drop-in/blob/main/PUBLISHING.md This command specifically handles the publication of packages that have been marked for release via changesets. It will publish only the packages that have been updated and version-bumped, ensuring a targeted release process within the monorepo. ```bash pnpm changeset:publish ``` -------------------------------- ### TypeScript for Auth Migration Monitoring and Metrics Source: https://github.com/stolinski/drop-in/blob/main/auth-migration-guide.md This TypeScript code defines metrics for tracking authentication migration progress and provides functions to retrieve migration status from the database and log detection events. It is designed for application-level monitoring. ```typescript // Enhanced metrics to track detection and migration const migrationMetrics = { totalUsers: 0, unknownUsers: 0, // Users still with 'unknown' auth_provider legacySha256Users: 0, // Users detected as legacy-sha256 legacyBcryptUsers: 0, // Users detected as legacy-bcrypt betterAuthUsers: 0, // Users migrated to better-auth nativeBetterAuthUsers: 0, // Users created with better-auth migrationFailures: 0, detectionFailures: 0, // Users who failed both legacy methods }; // Function to get current migration status async function getMigrationStatus() { const counts = await db .select({ auth_provider: userTable.auth_provider, count: sql`count(*)`, }) .from(userTable) .groupBy(userTable.auth_provider); return counts.reduce((acc, row) => { acc[row.auth_provider] = parseInt(row.count); return acc; }, {}); } // Log detection events function logDetectionEvent(userId: string, detectedMethod: string, success: boolean) { console.log(`Detection Event: User ${userId} - Method: ${detectedMethod} - Success: ${success}`); // Send to your monitoring system (DataDog, etc.) } ``` -------------------------------- ### Hybrid Login Logic Flow Source: https://github.com/stolinski/drop-in/blob/main/auth-migration-guide.md Implements the core logic for hybrid login, prioritizing Better Auth for already migrated users. For legacy users, it attempts verification using @drop-in/pass and initiates migration upon successful authentication. ```typescript async function hybridLogin(email: string, password: string) { const user = await getUserByEmail(email); if (!user) { return { success: false, error: 'User not found' }; } // If already migrated to Better Auth, use it directly if (user.auth_provider === 'better-auth' || user.auth_provider === 'native-better-auth') { return await betterAuth.signIn.email({ email, password }); } // Legacy user - try @drop-in/pass verification const legacyAuthResult = await verifyLegacyPassword(email, password, user); if (legacyAuthResult.success) { // Migrate to Better Auth await migrateToBetterAuth(user, password); return legacyAuthResult; } return { success: false, error: 'Invalid credentials' }; } ``` -------------------------------- ### Configure Email Sending with Beeper Source: https://github.com/stolinski/drop-in/blob/main/packages/docs/src/content/docs/pass/email-setup.md This JavaScript snippet demonstrates a new configuration for email sending using the '@drop-in/beeper' module. It exports a default configuration object with an 'email' property that includes sender information and an asynchronous 'sendEmail' function. This setup allows for easy swapping of email providers in the future. ```javascript // New configuration import { beeper } from '@drop-in/beeper'; export default { email: { from: 'noreply@example.com', sendEmail: async (options) => { await beeper.send(options); }, }, }; ``` -------------------------------- ### Secure API Route with User Authentication - TypeScript Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/LOCALS-SETUP-GUIDE.md Illustrates creating a protected API route (`/api/protected`) in SvelteKit that requires user authentication. The `GET` handler checks if `locals.user` is present; if not, it returns a `401` error. If authenticated, it returns a JSON response including a personalized greeting and the user's ID, utilizing the data populated by the server hooks. ```typescript // src/routes/api/protected/+server.ts import { json, error } from '@sveltejs/kit'; export async function GET({ locals }) { if (!locals.user) { error(401, 'Not authenticated'); } return json({ message: `Hello ${locals.user.email}!`, userId: locals.user.id }); } ``` -------------------------------- ### Configure Server Hooks for User Data - TypeScript Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/LOCALS-SETUP-GUIDE.md Updates the `hooks.server.ts` file to include `create_session_handle` and `create_pass_routes` from `@drop-in/pass`. This ensures `event.locals.user` is populated with authenticated user data. The order of these functions is critical: `create_session_handle(db)` must precede `create_pass_routes(db)`. This setup is essential for the new HttpOnly JWT implementation. ```typescript // src/hooks.server.ts import { create_pass_routes, create_session_handle } from '@drop-in/pass'; import { sequence } from '@sveltejs/kit/hooks'; export const handle = sequence( create_session_handle(db), // 🔥 THIS IS REQUIRED - populates event.locals.user create_pass_routes(db) // Handles auth routes (/api/auth/*) ); ``` -------------------------------- ### Build Specific Package in PNPM Monorepo Source: https://github.com/stolinski/drop-in/blob/main/PUBLISHING.md This command is used to build a specific package within a PNPM monorepo. By using the `-F` flag, you can target a particular package (e.g., `@drop-in/pass`) and execute its build script. This is helpful for isolating build issues or for verifying build integrity before publishing. ```bash pnpm -F @drop-in/pass build ``` -------------------------------- ### Complete Hybrid Login Flow Source: https://github.com/stolinski/drop-in/blob/main/auth-migration-guide.md Handles user login by detecting the authentication method. It supports users already migrated to Better Auth, known legacy users with bcrypt or sha256 hashes, and unknown users requiring detection. It aims to migrate users to Better Auth upon successful legacy authentication. ```typescript async function hybridLogin(email: string, password: string) { const user = await getUserByEmail(email); if (!user) { return { success: false, error: 'User not found' }; } // Route 1: Better Auth users (already migrated) if (user.auth_provider === 'better-auth' || user.auth_provider === 'native-better-auth') { return await betterAuth.signIn.email({ email, password }); } // Route 2: Known legacy users if (user.auth_provider === 'legacy-sha256' || user.auth_provider === 'legacy-bcrypt') { const authResult = await verifyKnownLegacyUser(user, password); if (authResult.success) { await migrateToBetterAuth(user, password); } return authResult; } // Route 3: Unknown users (need detection) if (user.auth_provider === 'unknown') { const detectionResult = await detectAndSetAuthMethod(user, password); if (detectionResult.success) { await migrateToBetterAuth(user, password); } return detectionResult; } return { success: false, error: 'Invalid auth provider state' }; } ``` -------------------------------- ### Migrate User to Better Auth Source: https://github.com/stolinski/drop-in/blob/main/auth-migration-guide.md Handles the process of migrating a user from a legacy authentication system to Better Auth. It involves creating a new user record in Better Auth and updating the user's `auth_provider` field in the database. ```typescript async function migrateToBetterAuth(user: User, plainPassword: string) { try { // Create Better Auth user record await betterAuth.api.signUp({ email: user.email, password: plainPassword, // Preserve other user data }); // Update auth provider await db .update(userTable) .set({ auth_provider: 'better-auth' }) .where(eq(userTable.id, user.id)); console.log(`User ${user.email} successfully migrated to Better Auth`); return { success: true }; } catch (error) { console.error(`Failed to migrate user ${user.email}:`, error); // Don't fail the login - user can still use legacy auth return { success: false, error }; } } ``` -------------------------------- ### Test Specific Package in PNPM Monorepo Source: https://github.com/stolinski/drop-in/blob/main/PUBLISHING.md This command allows you to run tests for a specific package within a PNPM monorepo. It uses the `-F` flag (filter) to target the desired package, ensuring that tests are executed only for the relevant code, which is useful during development and before creating changesets. ```bash pnpm -F @drop-in/pass test ``` -------------------------------- ### TypeScript for Migration Progress Tracking Source: https://github.com/stolinski/drop-in/blob/main/auth-migration-guide.md This TypeScript snippet defines a basic structure for migration metrics, including counts for total users, migrated users, users on legacy methods, users on the current method, and migration failures. It's intended for tracking progress during the authentication migration. ```typescript // Add logging to monitor migration const migrationMetrics = { totalUsers: 0, migratedUsers: 0, legacyMethodUsers: 0, currentMethodUsers: 0, migrationFailures: 0, }; ``` -------------------------------- ### Session Helper: populate_user_session() (TypeScript) Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/SECURITY-UPGRADE.md This code snippet illustrates the manual population of a user session using the `populate_user_session` function from `@drop-in/pass`. It's an alternative to `create_session_handle` when direct control over session population is needed. The example shows calling the function with a database instance and the SvelteKit event object, then logging the populated `event.locals.user`. ```typescript import { populate_user_session } from '@drop-in/pass'; // Manual session population (if not using create_session_handle) await populate_user_session(db, event); console.log(event.locals.user); // User data or undefined ``` -------------------------------- ### Create Starlight Project with PNPM Source: https://github.com/stolinski/drop-in/blob/main/packages/docs/README.md This command initializes a new Astro project with the Starlight template using the PNPM package manager. It's the first step in setting up a new documentation site with Starlight. ```bash pnpm create astro@latest -- --template starlight ``` -------------------------------- ### Access User Data in Server Load Functions - TypeScript Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/LOCALS-SETUP-GUIDE.md Demonstrates how to access the `locals.user` object within server-side load functions in SvelteKit. The `load` function in `+layout.server.ts` directly returns `locals.user`. In `+page.server.ts` for `/dashboard`, it shows an example of checking for authentication (`!locals.user`) and redirecting if the user is not logged in, otherwise logging user details. ```typescript // src/routes/+layout.server.ts export async function load({ locals }) { return { user: locals.user // Automatically populated by create_session_handle(db) }; } ``` ```typescript // src/routes/dashboard/+page.server.ts import { redirect } from '@sveltejs/kit'; export async function load({ locals }) { // Check authentication if (!locals.user) { redirect(302, '/login'); } // User is authenticated console.log('User ID:', locals.user.id); console.log('User Email:', locals.user.email); return { user: locals.user, // other data... }; } ``` -------------------------------- ### Configure Email Provider - Old vs New (JavaScript) Source: https://github.com/stolinski/drop-in/blob/main/RELEASE_NOTES.md Demonstrates the evolution of email configuration for @drop-in/pass. The old configuration relied on a hardcoded SMTP setup, while the new approach requires defining a `sendEmail` async function within `drop-in.config.js`, allowing for various providers like the included `@drop-in/beeper` or external services like Resend. ```javascript // This no longer works export default { email: { host: 'smtp.example.com', port: 587, secure: true, from: 'noreply@example.com' } }; ``` ```javascript // Option 1: Continue using beeper (Node.js) import { beeper } from '@drop-in/beeper'; export default { email: { from: 'noreply@example.com', sendEmail: async (options) => await beeper.send(options), } }; ``` ```javascript // Option 2: Use Resend (Cloudflare Workers) export default { email: { from: 'noreply@example.com', sendEmail: async ({ to, subject, html, from }) => { const response = await fetch('https://api.resend.com/emails', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.RESEND_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ to, subject, html, from }), }); if (!response.ok) throw new Error(`Failed to send email: ${response.statusText}`); }, } }; ``` -------------------------------- ### Build, Preview, and Development Server Commands Source: https://github.com/stolinski/drop-in/blob/main/packages/decks/AGENTS.md Instructions for building, previewing, and running the development server for the `@drop-in/decks` package using pnpm. ```shell pnpm -F @drop-in/decks build pnpm -F @drop-in/decks preview pnpm -F @drop-in/decks dev ``` -------------------------------- ### Starlight Project Structure Overview Source: https://github.com/stolinski/drop-in/blob/main/packages/docs/README.md Illustrates the typical directory and file structure of an Astro project utilizing Starlight. It highlights key directories like `public/` for static assets and `src/content/docs/` for documentation files. ```tree . ├── public/ ├── src/ │ ├── assets/ │ ├── content/ │ │ ├── docs/ │ └── content.config.ts ├── astro.config.mjs ├── package.json └── tsconfig.json ``` -------------------------------- ### Build Svelte Showcase App Source: https://github.com/stolinski/drop-in/blob/main/packages/ramps/README.md Command to create a production-ready build of the showcase application. This optimizes the assets and code for deployment. ```bash npm run build ``` -------------------------------- ### Authentication Check Migration (TypeScript) Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/SECURITY-UPGRADE.md This code demonstrates how to update authentication checks. The 'Before' example uses the deprecated `get_jwt()` function. The 'After (Server-side)' example shows checking for the existence of `event.locals.user` in server contexts. The 'After (Client-side)' example shows how to check login status by attempting to fetch user data via `pass.me()` and handling potential errors. ```typescript // Before: // import { get_jwt } from '@drop-in/pass'; // const isLoggedIn = !!get_jwt(); ``` ```typescript // After (Server-side): const isLoggedIn = !!event.locals.user; ``` ```typescript // After (Client-side): try { await pass.me(); const isLoggedIn = true; } catch { const isLoggedIn = false; } ``` -------------------------------- ### Create New Svelte Project Source: https://github.com/stolinski/drop-in/blob/main/packages/ramps/README.md Command to create a new Svelte project. It can be run in the current directory or a specified subdirectory. This step initializes the project structure and necessary files. ```bash npx sv create # create a new project in my-app npx sv create my-app ``` -------------------------------- ### Code Formatting with pnpm Source: https://github.com/stolinski/drop-in/blob/main/packages/decks/AGENTS.md Command to format code within the `@drop-in/decks` package using Prettier. ```shell pnpm -F @drop-in/decks format ``` -------------------------------- ### Publish Svelte Library to npm Source: https://github.com/stolinski/drop-in/blob/main/packages/ramps/README.md Command to publish the built Svelte library to the npm registry. Before running this, ensure the `package.json` is configured with the correct name and license information. ```bash npm publish ``` -------------------------------- ### GET /api/auth/me Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/SECURITY-UPGRADE.md Retrieves the currently authenticated user's information. This endpoint uses HttpOnly cookies for authentication and is designed to be called from both server-side and client-side. ```APIDOC ## GET /api/auth/me ### Description Retrieves the current user's information. Authentication is handled via HttpOnly cookies. ### Method GET ### Endpoint /api/auth/me ### Parameters #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **user** (object) - Contains user details including id, email, verified status, and timestamps. - **id** (string) - The unique identifier for the user. - **email** (string) - The user's email address. - **verified** (boolean) - Indicates if the user's email has been verified. - **created_at** (string) - The timestamp when the user account was created. - **updated_at** (string) - The timestamp when the user account was last updated. #### Error Response (401) - **error** (string) - "Not authenticated" if the user is not logged in. #### Response Example (200) ```json { "user": { "id": "user_123", "email": "user@example.com", "verified": true, "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" } } ``` #### Response Example (401) ```json { "error": "Not authenticated" } ``` ``` -------------------------------- ### Client-side `pass.me()` Method Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/SECURITY-UPGRADE.md A client-side helper function that calls the `GET /api/auth/me` endpoint to fetch user data. It simplifies fetching user information in the browser. ```APIDOC ## Client-side `pass.me()` Method ### Description This client-side method provides a convenient way to fetch the current user's data by calling the `GET /api/auth/me` endpoint. It handles potential authentication errors. ### Method Asynchronous Function Call ### Endpoint Called GET /api/auth/me ### Parameters None ### Request Example ```typescript import { pass } from '@drop-in/pass'; try { const { user } = await pass.me(); console.log('Logged in as:', user.email); } catch (error) { console.log('Not authenticated'); } ``` ### Response #### Success Response - **user** (object) - Contains user details as returned by the `GET /api/auth/me` endpoint. #### Error Response Throws an error if authentication fails (e.g., user is not logged in). ``` -------------------------------- ### Testing Database Connectivity with Drop-In Authentication Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/LOCALS-SETUP-GUIDE.md This TypeScript snippet demonstrates how to test your database connectivity within a SvelteKit application using the `authenticate_user` function from the `@drop-in/pass` library. It logs the authentication result, which can help diagnose issues related to database access during the user authentication process. ```typescript import { authenticate_user } from '@drop-in/pass'; export async function load({ cookies }) { const auth = await authenticate_user(db, cookies); console.log('Auth result:', auth); return {}; } ``` -------------------------------- ### Create New Drop-in App Source: https://github.com/stolinski/drop-in/blob/main/README.md Initializes a new Drop-in project with the specified application name. This command is the first step in setting up a new local-first application using the Drop-in framework. ```bash npx @drop-in/new your-app-name || pnpx @drop-in/new your-app-name ``` -------------------------------- ### Hybrid User Registration Source: https://github.com/stolinski/drop-in/blob/main/auth-migration-guide.md Handles the registration of new users, exclusively using Better Auth. Upon successful registration, the user's `auth_provider` is set to 'native-better-auth' in the database. ```typescript async function hybridRegister(email: string, password: string) { // Always use Better Auth for new users const result = await betterAuth.signUp.email({ email, password }); if (result.success) { // Mark as native Better Auth user await db .update(userTable) .set({ auth_provider: 'native-better-auth' }) .where(eq(userTable.email, email)); } return result; } ``` -------------------------------- ### Integrate User Store in Svelte Layout - Svelte Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/LOCALS-SETUP-GUIDE.md Shows how to integrate the `userStore` into a Svelte layout component (`+layout.svelte`). It uses `onMount` to initialize the client-side `userStore` with data from server-side props (`data.user`) or by fetching it if not available. The layout then conditionally renders navigation elements (welcome message, logout button, or login link) based on the `userStore.user` state. ```svelte
{@render children()}
``` -------------------------------- ### Verify Legacy Password Source: https://github.com/stolinski/drop-in/blob/main/auth-migration-guide.md Verifies a legacy password against two potential schemes: direct bcrypt comparison or bcrypt comparison of a sha256 hash of the password. This function is used during the migration process. ```typescript async function verifyLegacyPassword(email: string, password: string, user: User) { // Try current method first: bcrypt(password) const currentMatch = await bcrypt.compare(password, user.password_hash); if (currentMatch) { return { success: true, method: 'current', user }; } // Try legacy method: bcrypt(sha256(password)) const sha256Hash = crypto.createHash('sha256').update(password).digest('hex'); const legacyMatch = await bcrypt.compare(sha256Hash, user.password_hash); if (legacyMatch) { return { success: true, method: 'legacy', user }; } return { success: false }; } ``` -------------------------------- ### ESLint Configuration Source: https://github.com/stolinski/drop-in/blob/main/packages/decks/AGENTS.md Configuration details for ESLint, utilizing a flat config structure with various plugins and disabling rules that conflict with Prettier. Specifies ignored directories. ```javascript { "extends": [ "@eslint/js", "plugin:@typescript-eslint/recommended", "plugin:svelte/recommended", "plugin:prettier/recommended" ], "parserOptions": { "ecmaVersion": "latest", "sourceType": "module" }, "plugins": [ "@typescript-eslint", "svelte" ], "rules": { // Prettier rules handled by plugin:prettier/recommended }, "overrides": [ { "files": ["*.svelte"], "parser": "@typescript-eslint/parser", "parserOptions": { "extraFileExtensions": [".svelte"] }, "plugins": ["svelte"], "rules": { "import/first": "off", "import/no-mutable-exports": "off", "prettier/prettier": "error", "svelte/compiler-options": { "css": true }, "svelte/immutable-data-affects-store": "error", "svelte/no-dom-manipulation": "warn", "svelte/no-dupe-else-options": "error", "svelte/no-dupe-class-suffix": "error", "svelte/no-dupe-style-attrs": "error", "svelte/no-inner-declarations": "error", "svelte/no-not-equal-null-comparison": "error", "svelte/no-object-literal-type-aliases": "error", "svelte/no-prop-mutation": "error", "svelte/no-reactive-functions": "error", "svelte/no-run-null-assertion-in-methods": "error", "svelte/no-target-html-static-classnames": "warn", "svelte/no-undef-components": "error", "svelte/no-undef-directives": "error", "svelte/no-undef-key": "error", "svelte/require-store-reactive-access": "error", "svelte/require-svelte-type-checker-ignore-code": "warn", "svelte/valid-compile-options": "error" } } ], "ignorePatterns": ["build/", ".svelte-kit/", "dist/"] } ``` -------------------------------- ### TypeScript Configuration Source: https://github.com/stolinski/drop-in/blob/main/packages/decks/AGENTS.md Key TypeScript compiler options emphasizing strictness, module resolution for ESM, and explicit file extensions for relative imports under NodeNext. ```json { "compilerOptions": { "target": "ESNext", "module": "NodeNext", "moduleResolution": "NodeNext", "allowJs": true, "checkJs": false, "jsx": "preserve", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "isolatedModules": true, "outDir": "./dist", "declaration": true, "paths": { "@/*": ["src/*"] } }, "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], "exclude": ["node_modules", "build", "dist"] } ``` -------------------------------- ### Run Tests and Build (npm) Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/TESTING-DOCUMENTATION-REPORT.md Common npm commands for running tests, executing tests in watch mode, and building the TypeScript project. These are essential for local development and CI/CD pipelines. ```bash npm test # Run all tests npm run test:watch # Watch mode for development npm run build # Build and verify TypeScript ``` -------------------------------- ### Build Svelte Library Source: https://github.com/stolinski/drop-in/blob/main/packages/ramps/README.md Command to build the Svelte library. This command compiles the code in `src/lib` into a distributable format, typically for publishing to package managers like npm. ```bash npm run package ``` -------------------------------- ### Publish npm Packages using npm CLI Source: https://github.com/stolinski/drop-in/blob/main/PUBLISH_CHECKLIST.md Commands to publish @drop-in/pass and @drop-in/beeper packages to npm. It's recommended to publish 'pass' first due to potential interdependencies. ```bash cd packages/pass npm publish cd ../beeper npm publish ``` -------------------------------- ### SQL: Add Auth Provider Column to User Table Source: https://github.com/stolinski/drop-in/blob/main/auth-migration-guide.md Adds a new VARCHAR column named 'auth_provider' to the 'user' table to track the user's authentication method. It defaults to 'unknown' for existing users. ```sql ALTER TABLE user ADD COLUMN auth_provider VARCHAR(50) DEFAULT 'unknown'; ``` -------------------------------- ### Enable Debug Logging for Drop-in Source: https://github.com/stolinski/drop-in/blob/main/packages/pass/README.md This command enables debug logging for the drop-in project when running in development mode. It's useful for troubleshooting and understanding the internal workings of the application. Ensure you have npm installed and the project dependencies set up. ```bash DEBUG=drop-in:* npm run dev ``` -------------------------------- ### Running Tests with Vitest Source: https://github.com/stolinski/drop-in/blob/main/packages/decks/AGENTS.md Commands for running tests in the repository using Vitest. This includes running all tests in a specific package (`@drop-in/pass`), a single test file, or a test by name. ```shell pnpm -F @drop-in/pass test pnpm -F @drop-in/pass vitest run src/login.test.ts pnpm -F @drop-in/pass vitest run src/login.test.ts -t "name" ```