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