### Start Development Server Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/quick-start.md Run this command to start the SvelteKit development server. ```bash npm run dev ``` -------------------------------- ### Development Setup for Firebase Emulator Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/configuration.md Instructions for starting the Firebase emulator and setting the development environment variable for the auth emulator host. ```bash # Start Firebase Emulator firebase emulators:start --project # Development environment export PUBLIC_FIREBASE_AUTH_EMULATOR_HOST=localhost:9099 pnpm dev ``` -------------------------------- ### Install Node.js Adapter Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/deployment.md Install the Node.js adapter for SvelteKit. This is the first step for Node.js deployments. ```bash npm install -D @sveltejs/adapter-node ``` -------------------------------- ### Install @mierune/sveltekit-firebase-auth-ssr Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/README.md Install the package as a development dependency using npm. ```bash npm install -D @mierune/sveltekit-firebase-auth-ssr ``` -------------------------------- ### Install Dependencies Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/module-index.md Installs the necessary SvelteKit, Firebase, and authentication packages. Ensure these peer dependencies are met before proceeding. ```bash npm install @sveltejs/kit firebase firebase-auth-cloudflare-workers-x509 svelte ``` -------------------------------- ### Install Dependencies Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/quick-start.md Install the necessary packages for SvelteKit Firebase Auth SSR, Firebase, and SvelteKit. ```bash npm install -D @mierune/sveltekit-firebase-auth-ssr npm install firebase @sveltejs/kit svelte ``` -------------------------------- ### Install Vercel Adapter for SvelteKit Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/deployment.md Install the Vercel adapter as a development dependency for SvelteKit projects. ```bash npm install -D @sveltejs/adapter-vercel ``` -------------------------------- ### Environment Variables Setup Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/quick-start.md Configure your Firebase project credentials and optional emulator host in the `.env.local` file. ```bash # Get these from Firebase Console PUBLIC_FIREBASE_PROJECT_ID=your-project-id PUBLIC_FIREBASE_API_KEY=AIzaSy... # Get from Google Cloud → Service Accounts → Create Key GOOGLE_SERVICE_ACCOUNT_KEY={"type":"service_account",...} # Optional: For local development PUBLIC_FIREBASE_AUTH_EMULATOR_HOST=localhost:9099 ``` -------------------------------- ### Run Node.js Server Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/deployment.md Start the built Node.js server. Alternatively, use a process manager like PM2 for production. ```bash node build ``` ```bash pm2 start build/index.js --name "sveltekit-app" ``` -------------------------------- ### Example Usage in SvelteKit Load Function Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/api-client.md This example demonstrates how to use `makeClient` within a SvelteKit load function to fetch data from your API. It handles potential non-ok responses and returns the fetched posts. ```typescript import { makeClient } from '@mierune/sveltekit-firebase-auth-ssr'; // In a SvelteKit load function (+page.ts, +layout.server.ts) export const load = async ({ fetch }) => { const client = makeClient(fetch); const response = await client.api.posts.$get(); if (!response.ok) { return { posts: [] }; } const posts = await response.json(); return { posts }; }; ``` -------------------------------- ### Client-side Sign-In with Provider Usage Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/integration-patterns.md Example of how to initiate the sign-in process from the client-side using a Google provider. The boolean argument indicates a preference for the redirect method. ```typescript import { GoogleAuthProvider } from 'firebase/auth'; import { signInWithProvider } from '@mierune/sveltekit-firebase-auth-ssr/client'; const provider = new GoogleAuthProvider(); await signInWithProvider(provider, true); // true = prefer redirect ``` -------------------------------- ### API Posts Response Example Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/endpoints.md Example JSON structure for posts retrieved from the API. Assumes a Post interface with title and author. ```json [ { "title": "Great Article", "author": "John Doe" }, { "title": "Another Post", "author": "John Doe" } ] ``` -------------------------------- ### SvelteKit Configuration (svelte.config.js) Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/configuration.md Configures SvelteKit, specifying the adapter for deployment. This example uses the Cloudflare adapter. ```javascript import adapter from '@sveltejs/adapter-cloudflare'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; const config = { preprocess: vitePreprocess(), kit: { adapter: adapter() } }; export default config; ``` -------------------------------- ### Cloudflare Workers KV KeyStore Example Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/server.md Example implementation of the `keyStore` function using Cloudflare Workers KV for storing public keys. Falls back to `InMemoryStore` if `platform.env.KV` is not available. ```typescript import { WorkersKVStoreSingle, InMemoryStore } from '@mierune/sveltekit-firebase-auth/server'; keyStore: (platform) => { if (platform?.env?.KV) { return WorkersKVStoreSingle.getOrInitialize('pubkeys', platform.env.KV); } return new InMemoryStore(); } ``` -------------------------------- ### Server-Side Auth Handler Setup Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/README.md Create the authentication handler for the server side. Requires project ID, service account credentials, and a key store. ```typescript import { createAuthHandle, ServiceAccountCredential, InMemoryStore } from '@mierune/sveltekit-firebase-auth-ssr/server'; import { PUBLIC_FIREBASE_PROJECT_ID } from '$env/static/public'; import { env } from '$env/dynamic/private'; export const handle = createAuthHandle({ projectId: PUBLIC_FIREBASE_PROJECT_ID, serviceAccountCredential: new ServiceAccountCredential(env.GOOGLE_SERVICE_ACCOUNT_KEY), keyStore: (platform) => new InMemoryStore() }); ``` -------------------------------- ### Client-Side Auth Setup Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/README.md Configure the Firebase authentication client on the client side. Use the emulator host if running locally. ```typescript import { setupAuthClient } from '@mierune/sveltekit-firebase-auth-ssr/client'; setupAuthClient({ emulatorHost: process.env.PUBLIC_FIREBASE_AUTH_EMULATOR_HOST }); ``` -------------------------------- ### Session Endpoint Response Example Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/endpoints.md Example of a successful HTTP response from the session endpoint, including the 'Set-Cookie' header for session management. ```http HTTP/1.1 200 OK Set-Cookie: session=eyJhbGciOiJSUzI1NiIs...; Path=/; Max-Age=1209600; SameSite=Lax Content-Type: text/plain ok ``` -------------------------------- ### Sign In with Email and Password Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/README.md Perform user sign-in using email and password on the client side. Ensure the client-side setup is complete. ```typescript import { signInWithEmailAndPassword } from '@mierune/sveltekit-firebase-auth-ssr/client'; await signInWithEmailAndPassword('user@example.com', 'password'); ``` -------------------------------- ### Configure SvelteKit AuthHandleOptions Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/types.md Provides an example of configuring AuthHandleOptions for SvelteKit authentication middleware. This includes setting the projectId, serviceAccountCredential, and a keyStore function. ```typescript const options: AuthHandleOptions = { projectId: 'my-project', serviceAccountCredential: new ServiceAccountCredential(key), keyStore: (platform) => { if (platform?.env?.KV) { return WorkersKVStoreSingle.getOrInitialize('keys', platform.env.KV); } return new InMemoryStore(); } }; ``` -------------------------------- ### Payment Checkout Response Example Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/endpoints.md An example of the JSON response when a Stripe payment checkout session is successfully created. This data is used to initialize the Stripe Payment Element. ```json { "clientSecret": "pi_xxx_secret_yyy", "customerId": "cus_xxx" } ``` -------------------------------- ### Firebase Emulator Configuration (firebase.json) Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/configuration.md Sets up Firebase Emulator configurations, including ports for services like Auth and enabling the UI. Use 'firebase emulators:start --project ' to run. ```json { "emulators": { "auth": { "port": 9099 }, "ui": { "enabled": true } } } ``` -------------------------------- ### Cloudflare KV Store Initialization Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/deployment.md Example of initializing a key-value store, prioritizing Cloudflare Workers KV binding if available, otherwise falling back to an in-memory store. ```typescript keyStore: (platform) => { console.log('KV available:', !!platform?.env?.KV); if (platform?.env?.KV) { return WorkersKVStoreSingle.getOrInitialize('pubkeys', platform.env.KV); } return new InMemoryStore(); } ``` -------------------------------- ### Install Peer Dependencies for SvelteKit Firebase Auth SSR Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/README.md These are the essential packages that must be installed in your project to use SvelteKit Firebase Auth SSR. Ensure versions are compatible. ```json { "@sveltejs/kit": "^2.6.1", "firebase": "^11.0.0", "firebase-auth-cloudflare-workers-x509": "^2.0.9", "svelte": "^4.0.0 || ^5.0.0" } ``` -------------------------------- ### Example Usage of BasicPrivateUserInfo in SvelteKit Load Function Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/types.md Demonstrates how to return BasicPrivateUserInfo from a SvelteKit server load function. Ensure the user's token is available in locals. ```typescript // In +layout.server.ts export const load = async ({ locals }) => { if (locals.currentIdToken) { return { currentUser: { uid: locals.currentIdToken.uid, name: locals.currentIdToken.name, email: locals.currentIdToken.email, email_verified: locals.currentIdToken.email_verified } }; } }; ``` -------------------------------- ### Example Protected Hono API Endpoint Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/hono-api.md A complete example of a protected API endpoint using Hono. It includes authentication middleware and retrieves posts authored by the current user. Ensure `authMiddleware` and `ensureUser` are correctly imported and implemented. ```typescript import { Hono } from 'hono'; import { authMiddleware, ensureUser, type AuthVariables } from './auth'; export type Post = { title: string; author: string; }; const app = new Hono<{ Bindings: Env; Variables: AuthVariables }>() .use(authMiddleware) .get('/api/posts', async (c) => { const currentUser = ensureUser(c); const posts = Array.from({ length: 20 }, () => ({ title: 'Great Article', author: currentUser.name ?? 'Unknown' })); return c.json(posts); }); export default app; export type AppType = typeof app; ``` -------------------------------- ### Example SECRET_STRIPE_KEY Format Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/configuration.md Shows the format for the SECRET_STRIPE_KEY environment variable, used for server-side Stripe API operations. This key must be kept confidential. ```text SECRET_STRIPE_KEY=sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx ``` -------------------------------- ### Set Up API with Hono and Auth Middleware Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/quick-start.md This Hono application setup includes authentication middleware to protect API routes and ensure a user is logged in before accessing resources. ```typescript import { Hono } from 'hono'; import { authMiddleware, ensureUser } from './auth'; export type UserInfo = { uid: string; name: string; }; const app = new Hono<{ Variables: { currentUser?: UserInfo } }>() .use(authMiddleware) .get('/api/user', (c) => { const user = ensureUser(c); return c.json(user); }); export default app; export type AppType = typeof app; ``` -------------------------------- ### Client-Side Session Management Examples Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/server.md Client-side code to interact with the `/session` endpoint for creating or clearing session cookies. Uses the browser's `fetch` API. ```javascript // Automatically called by client functions await fetch('/session', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ idToken: firebaseIdToken }) }); // Sign out await fetch('/session', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ idToken: undefined }) }); ``` -------------------------------- ### Session Management Endpoint Request Example Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/server.md Demonstrates the structure of a `POST /session` request to manage user sessions. An `idToken` creates a session, while `undefined` or omitted `idToken` clears it. ```json { "idToken": "firebase_id_token_string" } ``` -------------------------------- ### Import Hono Authentication Middleware Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/module-index.md Import the necessary authentication middleware and types for Hono API routes. Ensure peer dependencies are installed. ```typescript import { authMiddleware, ensureUser, type AuthVariables } from '$lib/firebase-auth/server'; ``` -------------------------------- ### Server-Side Stripe API Usage Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/stripe-integration.md Example of using the server-side Stripe client to create a customer and a checkout session. Requires the Stripe npm package and a configured secret key. ```typescript import { stripe } from '$lib/stripe/stripe'; // Create a Stripe customer const customer = await stripe.customers.create({ email: 'user@example.com' }); // Create checkout session const session = await stripe.checkout.sessions.create({ customer: customer.id, line_items: [{ price: 'price_123', quantity: 1 }], mode: 'payment' }); ``` -------------------------------- ### Example GOOGLE_SERVICE_ACCOUNT_KEY Format Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/configuration.md Illustrates the expected JSON format for the GOOGLE_SERVICE_ACCOUNT_KEY environment variable. This key is essential for server-side Firebase authentication and should never be exposed client-side. ```json GOOGLE_SERVICE_ACCOUNT_KEY={"type":"service_account","project_id":"my-project","private_key_id":"key123","private_key":"-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----\n","client_email":"firebase-adminsdk-xxx@my-project.iam.gserviceaccount.com",...} ``` -------------------------------- ### Rate Limiting User Creation Endpoint Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/deployment.md Example of implementing rate limiting on an endpoint that creates users to prevent abuse. Requires `@upstash/ratelimit` and a Redis instance. ```typescript // Pseudo-code example import { Ratelimit } from "@upstash/ratelimit"; const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(5, "1 h") }); export async function POST({ request }) { const { success } = await ratelimit.limit(request.ip); if (!success) return new Response("Rate limited", { status: 429 }); // Create user } ``` -------------------------------- ### Build and Run Docker Container Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/deployment.md Build the Docker image and run a container, setting necessary environment variables and exposing the port. ```bash docker build -t sveltekit-app . docker run -e PUBLIC_FIREBASE_PROJECT_ID=my-project \ -e GOOGLE_SERVICE_ACCOUNT_KEY='...' \ -p 3000:3000 \ sveltekit-app ``` -------------------------------- ### Session Endpoint Request Example Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/endpoints.md Example of a JSON payload for creating or updating a user session using a Firebase ID token. ```json { "idToken": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ..." } ``` -------------------------------- ### Build SvelteKit Application Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/deployment.md Build the SvelteKit application for Node.js deployment. This command creates a 'build/' directory containing the server. ```bash npm run build ``` -------------------------------- ### setupAuthClient Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/client.md Initializes the Firebase Auth client with optional emulator configuration. This function sets up the necessary handlers and listeners for authentication flows and cookie management. ```APIDOC ## setupAuthClient() ### Description Initialize the Firebase Auth client with optional emulator configuration. ### Method Signature ```typescript function setupAuthClient(options: { emulatorHost?: string }): void ``` ### Parameters #### options (object) - Required - **emulatorHost** (string) - Optional - Firebase Auth Emulator host (e.g., `localhost:9099`) ### Behavior - Initializes Firebase Auth client using the official Firebase SDK - Sets up handler to process sign-in redirect results - Configures ID token change listener to update session cookies - Connects to Firebase Auth Emulator if `emulatorHost` is provided ### Example ```typescript import { setupAuthClient } from '@mierune/sveltekit-firebase-auth-ssr/client'; setupAuthClient({ emulatorHost: 'localhost:9099' }); ``` ``` -------------------------------- ### Deploy to Cloudflare Pages Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/deployment.md Build the SvelteKit application and deploy the output to Cloudflare Pages using the wrangler CLI. ```bash npm run build wrangler pages deploy dist ``` -------------------------------- ### Sign Out User Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/README.md Log the current user out on the client side. This function should be called after the client-side auth setup. ```typescript import { signOut } from '@mierune/sveltekit-firebase-auth-ssr/client'; await signOut(); ``` -------------------------------- ### Initialize Firebase Client Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/quick-start.md Set up the Firebase client and authentication in `src/hooks.client.ts` using environment variables. ```typescript import { initializeApp } from 'firebase/app'; import { setupAuthClient } from '@mierune/sveltekit-firebase-auth-ssr/client'; import { PUBLIC_FIREBASE_API_KEY, PUBLIC_FIREBASE_PROJECT_ID, PUBLIC_FIREBASE_AUTH_EMULATOR_HOST } from '$env/static/public'; // Setup Firebase initializeApp({ apiKey: PUBLIC_FIREBASE_API_KEY, projectId: PUBLIC_FIREBASE_PROJECT_ID }); // Setup authentication setupAuthClient({ emulatorHost: PUBLIC_FIREBASE_AUTH_EMULATOR_HOST }); ``` -------------------------------- ### Authentication Flow Overview Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/00-START-HERE.md Illustrates the sequence of events from user sign-in to data availability. ```text User signs in → Firebase Auth → ID token → Session cookie → User data available ``` -------------------------------- ### GET /api/posts Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/hono-api.md Retrieve posts authored by the current user. This endpoint requires authentication and returns a list of posts. ```APIDOC ## GET /api/posts ### Description Retrieve posts authored by the current user. ### Method GET ### Endpoint /api/posts ### Parameters #### Query Parameters None #### Request Body None ### Response #### Success Response (200) - **Array** of Post objects. Each Post object has: - **title** (string) - The title of the post. - **author** (string) - The author of the post. #### Response Example ```json [ { "title": "Great Article", "author": "User Name" } ] ``` ``` -------------------------------- ### Client-side Sign-in Usage Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/endpoints.md Demonstrates how to initiate a user sign-in process using client-side functions, which internally calls the session endpoint. ```typescript import { signInWithEmailAndPassword } from '@mierune/sveltekit-firebase-auth-ssr/client'; // Automatically calls POST /session internally await signInWithEmailAndPassword('user@example.com', 'password'); ``` -------------------------------- ### Client-side Usage for API Posts Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/endpoints.md Demonstrates how to use the `makeClient` utility to fetch posts from the API. Includes basic error handling for non-OK responses. ```typescript import { makeClient } from '@mierune/sveltekit-firebase-auth-ssr'; export const load = async ({ fetch }) => { const client = makeClient(fetch); const response = await client.api.posts.$get(); if (!response.ok) { return { posts: [] }; } const posts = await response.json(); return { posts }; }; ``` -------------------------------- ### Deploy SvelteKit Project with Vercel CLI Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/deployment.md Use the Vercel CLI to deploy your SvelteKit project. Alternatively, pushing to GitHub triggers auto-deploys. ```bash vercel ``` -------------------------------- ### Set Firebase Project ID Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/configuration.md Set the PUBLIC_FIREBASE_PROJECT_ID environment variable. This is required for both server-side authentication setup and client-side Firebase initialization. ```env PUBLIC_FIREBASE_PROJECT_ID=my-firebase-project ``` -------------------------------- ### Minimal Local Development Environment Variables Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/configuration.md Configure these variables in a .env.local file for local development. Ensure to replace placeholder values with your actual project credentials. ```bash # .env.local PUBLIC_FIREBASE_PROJECT_ID=your-project PUBLIC_FIREBASE_API_KEY=AIzaSy... GOOGLE_SERVICE_ACCOUNT_KEY={"type":"service_account",...} PUBLIC_FIREBASE_AUTH_EMULATOR_HOST=localhost:9099 PUBLIC_STRIPE_KEY=pk_test_... ``` -------------------------------- ### Post Type Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/types.md Represents the data structure for a blog post, including its title and author. This type is returned by the `GET /api/posts` endpoint. ```APIDOC ## Post Type ### Description Represents the data structure for a blog post, including its title and author. ### Type Definition ```typescript type Post = { title: string; author: string; }; ``` ### Fields | Field | Type | Description | |-------|------|-------------| | title | string | Post title | | author | string | Author name | ### Usage Returned by `GET /api/posts` endpoint. ### Example Response ```json [ { "title": "Great Article", "author": "John Doe" } ] ``` ``` -------------------------------- ### Development Commands for SvelteKit Firebase Auth SSR Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/README.md Run development commands for the package, including allowing direnv and running the development server within an emulator. ```bash direnv allow pnpm dev-in-emulator ``` -------------------------------- ### Wait for Redirect Result Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/client.md Waits for the result of a sign-in via redirect. Use this after initiating a redirect-based sign-in flow to get the user credential. ```typescript import { waitForRedirectResult } from '@mierune/sveltekit-firebase-auth-ssr/client'; const result = await waitForRedirectResult(); if (result) { console.log('User signed in:', result.user.email); } ``` -------------------------------- ### Protect API Endpoint with authMiddleware Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/hono-api.md Example of using `authMiddleware` to protect an API endpoint. It checks for the `currentUser` in the context and returns an unauthorized error if not present. ```typescript import { authMiddleware } from '$lib/firebase-auth/server'; import { Hono } from 'hono'; const app = new Hono() .use(authMiddleware) .get('/api/protected', (c) => { const user = c.get('currentUser'); if (!user) { return c.json({ error: 'Unauthorized' }, 401); } return c.json({ userId: user.uid }); }); ``` -------------------------------- ### Client-Only Exports Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/README.md Import specific authentication functions and types intended for client-side use only. This includes client setup, sign-in, sign-out, and provider sign-in. ```typescript import { setupAuthClient, signInWithEmailAndPassword, signOut, signInWithProvider } from '@mierune/sveltekit-firebase-auth-ssr/client'; ``` -------------------------------- ### Dockerfile for SvelteKit Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/deployment.md A Dockerfile for building and running a SvelteKit application. It uses a multi-stage build for optimization. ```dockerfile # Build stage FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci COPY . . RUN npm run build # Runtime stage FROM node:20-alpine WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci --omit=dev COPY --from=builder /app/build ./ ENV NODE_ENV=production EXPOSE 3000 CMD ["node", "build"] ``` -------------------------------- ### Initialize Server Middleware Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/quick-start.md Configure the server-side authentication handler in `src/hooks.server.ts` using service account credentials. ```typescript import { sequence } from '@sveltejs/kit/hooks'; import { createAuthHandle, ServiceAccountCredential, InMemoryStore } from '@mierune/sveltekit-firebase-auth-ssr/server'; import { PUBLIC_FIREBASE_PROJECT_ID } from '$env/static/public'; import { env } from '$env/dynamic/private'; const credential = new ServiceAccountCredential(env.GOOGLE_SERVICE_ACCOUNT_KEY); export const handle = sequence( createAuthHandle({ projectId: PUBLIC_FIREBASE_PROJECT_ID, serviceAccountCredential: credential, keyStore: (platform) => new InMemoryStore() }) ); ``` -------------------------------- ### Configure KeyStore for Cloudflare Workers (Production) Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/quick-start.md For production environments on Cloudflare, bind a KV namespace and use `WorkersKVStoreSingle` to initialize the key store. This ensures persistent storage for public keys. ```typescript keyStore: (platform) => { if (platform?.env?.KV) { return WorkersKVStoreSingle.getOrInitialize('pubkeys', platform.env.KV); } return new InMemoryStore(); } ``` -------------------------------- ### Configure KeyStore for Cloudflare Workers (Local Testing) Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/quick-start.md For local testing on Cloudflare Workers, use `InMemoryStore` to manage keys. This avoids issues with undefined KV namespaces during development. ```typescript keyStore: (platform) => new InMemoryStore() ``` -------------------------------- ### Production Environment Variables Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/configuration.md Use these variables for production deployment. Remove the emulator host and use production-specific Stripe keys. Store secrets securely. ```bash PUBLIC_FIREBASE_PROJECT_ID=your-project PUBLIC_FIREBASE_API_KEY=AIzaSy... GOOGLE_SERVICE_ACCOUNT_KEY={"type":"service_account",...} PUBLIC_STRIPE_KEY=pk_live_... SECRET_STRIPE_KEY=sk_live_... ``` -------------------------------- ### Sign In with Provider (Client) Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/client.md Initiates sign-in with a third-party provider. Uses redirect flow by default, falling back to popup if domains don't match. Automatically updates session cookie and invalidates SvelteKit session data. ```typescript import { GoogleAuthProvider } from 'firebase/auth'; import { signInWithProvider } from '@mierune/sveltekit-firebase-auth-ssr/client'; const provider = new GoogleAuthProvider(); await signInWithProvider(provider, true); ``` -------------------------------- ### Server-Only Exports Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/README.md Import specific authentication functions and types intended for server-side use only. This includes creating authentication handles, getting auth instances, and managing credentials/stores. ```typescript import { createAuthHandle, getAuth, ServiceAccountCredential, InMemoryStore } from '@mierune/sveltekit-firebase-auth-ssr/server'; ``` -------------------------------- ### AWS Amplify Build Configuration Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/deployment.md Define the build process for your SvelteKit application in the amplify.yml file for AWS Amplify deployments. ```yaml version: 1 build: commands: - npm ci - npm run build artifacts: baseDirectory: build files: - '**/*' cache: paths: - 'node_modules/**/*' ``` -------------------------------- ### Create Authentication Middleware Handle Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/server.md Use `createAuthHandle` to create authentication middleware for SvelteKit. It verifies session cookies, sets user information in `event.locals`, and handles authentication-related endpoints and redirects. Ensure `projectId` is provided and `keyStore` is configured for your environment. ```typescript import { createAuthHandle, ServiceAccountCredential, InMemoryStore } from '@mierune/sveltekit-firebase-auth-ssr/server'; import { PUBLIC_FIREBASE_PROJECT_ID } from '$env/static/public'; import { env } from '$env/dynamic/private'; const serviceAccountCredential = new ServiceAccountCredential( env.GOOGLE_SERVICE_ACCOUNT_KEY ); export const handle = sequence( createAuthHandle({ projectId: PUBLIC_FIREBASE_PROJECT_ID, serviceAccountCredential, keyStore: (platform) => new InMemoryStore() }) ); ``` -------------------------------- ### Client-side Request for Protected Posts Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/hono-api.md Example of how a client-side application would make a request to the protected `/api/posts` endpoint. This assumes a `makeClient` function is available for simplifying API calls. ```typescript const client = makeClient(fetch); const response = await client.api.posts.$get(); const posts = await response.json(); ``` -------------------------------- ### API Endpoints Flow Overview Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/00-START-HERE.md Outlines the steps involved in securing API endpoints using authentication middleware. ```text Client call → Auth middleware → Verify user → Execute handler → Return data ``` -------------------------------- ### Initialize Server-Side Stripe Client Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/stripe-integration.md Instantiate the Stripe client for server-side operations. Ensure the SECRET_STRIPE_KEY environment variable is configured. This singleton instance is accessible only in server-side code. ```typescript const stripe: Stripe ``` -------------------------------- ### Use ensureUser() to Protect API Endpoint Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/hono-api.md Example of using the `ensureUser` function within an API route to enforce authentication. If the user is not authenticated, `ensureUser` will throw a 401 error, preventing further execution. ```typescript import { ensureUser, authMiddleware } from '$lib/firebase-auth/server'; import { Hono } from 'hono'; const app = new Hono() .use(authMiddleware) .get('/api/posts', (c) => { const currentUser = ensureUser(c); // Throws 401 if not authenticated return c.json({ author: currentUser.name, posts: [] }); }); ``` -------------------------------- ### Authenticate API Endpoints with Hono and Middleware Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/README.md This example shows how to secure API endpoints using Hono and a custom authentication middleware. The `ensureUser` function verifies authentication, returning a 401 error if the user is not authenticated. ```typescript const app = new Hono() .use(authMiddleware) .get('/api/data', (c) => { const user = ensureUser(c); // 401 if not authenticated return c.json({ data: 'secret' }); }); ``` -------------------------------- ### createUserWithEmailAndPassword Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/client.md Create a new user account with email and password. This function automatically authenticates the new user, updates the session cookie, and triggers SvelteKit's auth:session invalidation. ```APIDOC ## createUserWithEmailAndPassword() ### Description Create a new user account with email and password. This function automatically authenticates the new user, updates the session cookie, and triggers SvelteKit's auth:session invalidation. ### Method `async` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | email | string | Yes | User email address (must be unique) | | password | string | Yes | User password (minimum 6 characters) | ### Returns `Promise` - Firebase user credential object for the newly created user. ### Throws `FirebaseError` if creation fails (email already in use, weak password, etc.) ### Example ```typescript import { createUserWithEmailAndPassword } from '@mierune/sveltekit-firebase-auth-ssr/client'; try { const credential = await createUserWithEmailAndPassword('newuser@example.com', 'securepassword'); console.log('Account created for:', credential.user.email); } catch (error) { console.error('Account creation failed:', error); } ``` ``` -------------------------------- ### Define App Types for Firebase Auth Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/quick-start.md Extend the global App namespace to include Firebase authentication-related types for server locals and page data. This setup is crucial for type safety when handling authentication tokens and user information across your SvelteKit application. ```typescript import type { BasicPrivateUserInfo } from '@mierune/sveltekit-firebase-auth-ssr'; import type { FirebaseIdToken } from 'firebase-auth-cloudflare-workers-x509'; declare global { namespace App { interface Locals { currentIdToken?: FirebaseIdToken; } interface PageData { currentIdToken?: FirebaseIdToken; currentUser?: BasicPrivateUserInfo; } } } export {}; ``` -------------------------------- ### Initialize Firebase Auth Client Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/module-index.md Sets up the Firebase authentication client for client-side operations. This should be called once when the application loads. ```typescript import { setupAuthClient } from '@mierune/sveltekit-firebase-auth-ssr/client'; setupAuthClient({ emulatorHost: process.env.PUBLIC_FIREBASE_AUTH_EMULATOR_HOST }); ``` -------------------------------- ### Redirect to Stripe Billing Portal Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/stripe-integration.md Handles GET requests to /shop/billing-portal. It checks for user authentication, retrieves or creates a Stripe customer, and then creates a billing portal session, redirecting the user to Stripe's hosted portal. The user returns to the home page upon completion. ```typescript export async function GET({ url, cookies, locals }) { if (!locals.currentIdToken) { redirect(307, '/'); } const email = locals.currentIdToken.email || ''; // Retrieve or create Stripe customer let customerId = cookies.get('customer_id'); if (!customerId) { const customer = await stripe.customers.create({ email }); customerId = customer.id; cookies.set('customer_id', customerId, { path: '/' }); } if (customerId === undefined) { throw redirect(307, '/'); } // Create Billing Portal session const billingPortalSession = await stripe.billingPortal.sessions.create({ customer: customerId, return_url: url.origin + '/' }); throw redirect(307, billingPortalSession.url); } ``` -------------------------------- ### Client-Side Sign-In Function Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/00-START-HERE.md Use this function on the client to initiate the user sign-in process with email and password. ```typescript await signInWithEmailAndPassword('user@example.com', 'password'); ``` -------------------------------- ### Secure Cookie Configuration in SvelteKit Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/deployment.md Demonstrates how to configure cookie security settings. 'lax' is recommended for better user experience, while 'strict' offers higher security but may break redirect-based sign-ins. ```typescript sameSite: 'lax' // Good httpOnly: implicit // Good (SvelteKit Cookies API) ``` ```typescript sameSite: 'strict' ``` -------------------------------- ### createAuthHandle Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/server.md Creates an authentication middleware handle for SvelteKit. This middleware verifies session cookies, sets user information in `event.locals`, handles Firebase Auth redirect requests, and manages session cookies. ```APIDOC ## createAuthHandle() ### Description Create an authentication middleware handle for SvelteKit. ### Signature ```typescript function createAuthHandle(options: AuthHandleOptions): Handle ``` ### Parameters #### options (AuthHandleOptions) - Required Configuration object for the authentication handle. - **projectId** (string) - Required - Firebase project ID. - **serviceAccountCredential** (Credential) - Optional - Firebase service account credential (required in production, optional with emulator). - **keyStore** (Function) - Required - Function that returns a KeyStorer instance based on platform. - **guardPathPattern** (RegExp) - Optional - Regular expression to guard specific paths. ### Returns - **Handle** - SvelteKit middleware function. ### AuthHandleOptions Type ```typescript type AuthHandleOptions = { projectId: string; serviceAccountCredential?: Credential; keyStore: (platform: Readonly | undefined) => KeyStorer; guardPathPattern?: RegExp; }; ``` ### Behavior - Verifies session cookies on each request. - Sets `event.locals.currentIdToken` when a user is authenticated. - Proxies Firebase Auth redirect requests to `/__/auth/` endpoints. - Handles `POST /session` endpoint for session cookie management. - Redirects authenticated users away from `/login` page. - Supports both Node.js and Cloudflare Workers environments. ### Example ```typescript import { sequence } from '@sveltejs/kit/hooks'; import { createAuthHandle, ServiceAccountCredential, InMemoryStore } from '@mierune/sveltekit-firebase-auth-ssr/server'; import { PUBLIC_FIREBASE_PROJECT_ID } from '$env/static/public'; import { env } from '$env/dynamic/private'; const serviceAccountCredential = new ServiceAccountCredential( env.GOOGLE_SERVICE_ACCOUNT_KEY ); export const handle = sequence( createAuthHandle({ projectId: PUBLIC_FIREBASE_PROJECT_ID, serviceAccountCredential, keyStore: (platform) => new InMemoryStore() }) ); ``` ``` -------------------------------- ### Client Module Imports Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/module-index.md Demonstrates a typical import statement for using client-side authentication functions from the '@mierune/sveltekit-firebase-auth-ssr/client' module. ```typescript import { setupAuthClient, signInWithEmailAndPassword, signOut } from '@mierune/sveltekit-firebase-auth-ssr/client'; ``` -------------------------------- ### Create User with Email and Password Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/client.md Use this function to create a new user account with an email and password. The new user is automatically authenticated, and the session cookie is updated. ```typescript import { createUserWithEmailAndPassword } from '@mierune/sveltekit-firebase-auth-ssr/client'; try { const credential = await createUserWithEmailAndPassword('newuser@example.com', 'securepassword'); console.log('Account created for:', credential.user.email); } catch (error) { console.error('Account creation failed:', error); } ``` -------------------------------- ### Usage in Server-Side Rendering Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/api-reference/api-client.md This snippet shows how to initialize and use the API client within a SvelteKit server-side load function (`+page.server.ts`) to fetch posts. ```typescript // +page.server.ts export const load = async ({ fetch }) => { const client = makeClient(fetch); const response = await client.api.posts.$get(); return { posts: await response.json() }; }; ``` -------------------------------- ### Configure SvelteKit for Node.js Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/deployment.md Update svelte.config.js to use the Node.js adapter. Ensure vitePreprocess is included for Svelte preprocessor. ```javascript import adapter from '@sveltejs/adapter-node'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; const config = { preprocess: vitePreprocess(), kit: { adapter: adapter() } }; export default config; ``` -------------------------------- ### Create Server Authentication Handle Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/module-index.md Initializes the authentication middleware for server-side requests. This handle is crucial for verifying user sessions on the server. ```typescript import { createAuthHandle } from '@mierune/sveltekit-firebase-auth-ssr/server'; export const handle = sequence( createAuthHandle({ projectId: PUBLIC_FIREBASE_PROJECT_ID, serviceAccountCredential, keyStore: (platform) => new InMemoryStore() }) ); ``` -------------------------------- ### Sign In with Email/Password in SvelteKit Source: https://github.com/mierune/sveltekit-firebase-auth-ssr/blob/main/_autodocs/integration-patterns.md Handles user sign-in using email and password. After successful authentication, it automatically updates the session and invalidates the auth:session data in SvelteKit. ```typescript import { signInWithEmailAndPassword } from '@mierune/sveltekit-firebase-auth-ssr/client'; // In a Svelte component async function handleSignIn(email, password) { try { const credential = await signInWithEmailAndPassword(email, password); console.log('Signed in:', credential.user.uid); // Automatic: updateSession() called, invalidates auth:session } catch (error) { console.error('Sign-in failed:', error.message); } } ```