### Project Setup and Commands Source: https://github.com/edusantosbrito/effect-auth/blob/main/CONTRIBUTING.md Run these commands to install dependencies, check code quality, run tests, and build the project. ```sh bun install ``` ```sh bun run check ``` ```sh bun run test ``` ```sh bun run build ``` -------------------------------- ### Backend Usage Example Source: https://github.com/edusantosbrito/effect-auth/blob/main/packages/effect-auth/README.md Demonstrates backend authentication setup using AuthLive.dev, providing custom storage and email layers. ```typescript import { Effect, Layer } from "effect" import { Auth, AuthLive } from "effect-auth" const AuthTestLayer = AuthLive.dev.pipe(Layer.provide(MyAuthStorage), Layer.provide(MyAuthEmail)) const program = Effect.gen(function* () { const auth = yield* Auth; const signUp = yield* auth.signUp({ email: "user@example.com", password: "correct horse battery staple", verificationCallbackUrl: "https://app.example.com/verify", }); return signUp.user; }).pipe(Effect.provide(AuthTestLayer)) ``` -------------------------------- ### Run Minimal Example Source: https://github.com/edusantosbrito/effect-auth/blob/main/packages/effect-auth/README.md Execute the minimal example to test a full authentication flow. This includes sign-up, email verification, sign-in, and session management. ```bash bun run example:minimal ``` ```bash bun run --cwd examples/minimal demo ``` -------------------------------- ### Run Minimal Example with Bun Source: https://github.com/edusantosbrito/effect-auth/blob/main/examples/minimal/README.md Execute the minimal effect-auth example using Bun from the repository root. No .env file is required. ```bash bun run example:minimal ``` -------------------------------- ### Install effect-auth and effect Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Install the necessary packages using bun or npm. ```bash bun add effect-auth effect # or npm install effect-auth effect ``` -------------------------------- ### Install effect-auth Source: https://github.com/edusantosbrito/effect-auth/blob/main/packages/effect-auth/README.md Install the effect-auth and effect packages using bun. ```bash bun add effect-auth effect ``` -------------------------------- ### Curl Example for User Sign-up Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Example using curl to perform a user sign-up via email. Requires specifying the content type, origin, and a JSON payload with email, password, and verification callback URL. ```bash # Sign up curl -X POST https://app.example.com/api/auth/sign-up/email \ -H "Content-Type: application/json" \ -H "Origin: https://app.example.com" \ -d '{"email":"alice@example.com","password":"correct horse battery staple","verificationCallbackUrl":"https://app.example.com/verify"}' ``` -------------------------------- ### Auth Service Setup and Usage Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Demonstrates how to set up the Auth service with development layers for storage and email, and how to perform a sign-up operation. ```APIDOC ## Auth Service Setup and Usage ### Description This example shows how to initialize the `Auth` service using development-ready layers for in-memory storage and a mock email service. It then demonstrates a basic sign-up flow. ### Code Example ```typescript import { Effect, Layer } from "effect"; import { Auth, AuthLive } from "effect-auth"; import { AuthStorage, AuthStorageFailure, type AuthStorageShape } from "effect-auth/storage"; import { AuthEmail, AuthEmailFailure, type AuthEmailShape } from "effect-auth/email"; // --- Minimal in-memory storage (for dev/test) --- import { DevMemoryAuthStorage } from "effect-auth/storage/dev-memory"; // --- Mock email (logs instead of sending) --- const MockEmailLayer = Layer.succeed(AuthEmail)({ sendEmailVerification: ({ to, token, callbackUrl }) => Effect.sync(() => console.log(`[email] verify ${String(to)}: ${callbackUrl}?token=${token}`), ), sendPasswordReset: ({ to, token, callbackUrl }) => Effect.sync(() => console.log(`[email] reset ${String(to)}: ${callbackUrl}?token=${token}`), ), }); const appLayer = AuthLive.dev.pipe( Layer.provide(DevMemoryAuthStorage()), Layer.provide(MockEmailLayer), ); const program = Effect.gen(function* () { const auth = yield* Auth; // Sign up const { user } = yield* auth.signUp({ email: "alice@example.com", password: "correct horse battery staple", verificationCallbackUrl: "https://app.example.com/verify", }); console.log("Signed up:", user.id, String(user.email)); }).pipe(Effect.provide(appLayer)); Effect.runPromise(program); ``` ``` -------------------------------- ### HTTP Endpoints — curl examples Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Example cURL command for signing up a user via the email endpoint. ```APIDOC ## HTTP Endpoints — curl examples ```bash # Sign up curl -X POST https://app.example.com/api/auth/sign-up/email \ -H "Content-Type: application/json" \ -H "Origin: https://app.example.com" \ -d '{"email":"alice@example.com","password":"correct horse battery staple","verificationCallbackUrl":"https://app.example.com/verify"}' ``` ``` -------------------------------- ### HTTP Usage: Application Layer Setup Source: https://github.com/edusantosbrito/effect-auth/blob/main/README.md Sets up the application layer for HTTP usage, including authentication, configuration, and custom services for storage, email, and rate limiting. Ensure to provide actual implementations for PostgresAuthStorage, ResendAuthEmail, and RedisRateLimiter. ```typescript import { Effect, Layer, Option } from "effect"; import { AuthLive, VerificationTokenConfigLive } from "effect-auth"; import { AuthHttp, AuthHttpConfig, AuthSession, CurrentAuthSession } from "effect-auth/http"; import * as HttpRouter from "effect/unstable/http/HttpRouter"; const appLayer = Layer.mergeAll( AuthLive.production, AuthHttpConfig.layer({ trustedOrigins: ["https://app.example.com"], sessionCookieName: "__Host_effect_auth_session", secureCookies: true, }), VerificationTokenConfigLive({ emailVerificationTtl: "24 hours", passwordResetTtl: "15 minutes", }), ).pipe( Layer.provide(PostgresAuthStorage), Layer.provide(ResendAuthEmail), Layer.provide(RedisRateLimiter), ); const app = HttpRouter.layer.pipe(AuthHttp.mount({ basePath: "/api/auth" })); const protectedProgram = Effect.gen(function* () { const authSession = yield* AuthSession; return authSession.user; }).pipe(AuthHttp.requireAuth); const navbarProgram = Effect.gen(function* () { const session = yield* CurrentAuthSession; return Option.match(session.current, { onNone: () => ({ signedIn: false }), onSome: ({ user }) => ({ signedIn: true, user }), }); }).pipe(AuthHttp.optionalAuth); ``` -------------------------------- ### HTTP Usage Example Source: https://github.com/edusantosbrito/effect-auth/blob/main/packages/effect-auth/README.md Sets up the HTTP layer for effect-auth, including trusted origins, session cookie configuration, and providing custom storage, email, and rate limiting services. ```typescript import { Effect, Layer, Option } from "effect" import { AuthLive, VerificationTokenConfigLive } from "effect-auth" import { AuthHttp, AuthHttpConfig, AuthSession, CurrentAuthSession } from "effect-auth/http" import * as HttpRouter from "effect/unstable/http/HttpRouter" const appLayer = Layer.mergeAll( AuthLive.production, AuthHttpConfig.layer({ trustedOrigins: ["https://app.example.com"], sessionCookieName: "__Host_effect_auth_session", secureCookies: true, }), VerificationTokenConfigLive({ emailVerificationTtl: "24 hours", passwordResetTtl: "15 minutes", }), ).pipe( Layer.provide(PostgresAuthStorage), Layer.provide(ResendAuthEmail), Layer.provide(RedisRateLimiter), ) const app = HttpRouter.layer.pipe(AuthHttp.mount({ basePath: "/api/auth" })) const protectedProgram = Effect.gen(function* () { const authSession = yield* AuthSession; return authSession.user; }).pipe(AuthHttp.requireAuth) const navbarProgram = Effect.gen(function* () { const session = yield* CurrentAuthSession; return Option.match(session.current, { onNone: () => ({ signedIn: false }), onSome: ({ user }) => ({ signedIn: true, user }), }); }).pipe(AuthHttp.optionalAuth) ``` -------------------------------- ### Initialize Auth Service with Dev Layers Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Compose the Auth service with development-specific layers for in-memory storage and mock email. This setup is suitable for development and testing environments. ```typescript import { Effect, Layer } from "effect"; import { Auth, AuthLive } from "effect-auth"; import { AuthStorage, AuthStorageFailure, type AuthStorageShape } from "effect-auth/storage"; import { AuthEmail, AuthEmailFailure, type AuthEmailShape } from "effect-auth/email"; // --- Minimal in-memory storage (for dev/test) --- import { DevMemoryAuthStorage } from "effect-auth/storage/dev-memory"; // --- Mock email (logs instead of sending) --- const MockEmailLayer = Layer.succeed(AuthEmail)({ sendEmailVerification: ({ to, token, callbackUrl }) => Effect.sync(() => console.log(`[email] verify ${String(to)}: ${callbackUrl}?token=${token}`), ), sendPasswordReset: ({ to, token, callbackUrl }) => Effect.sync(() => console.log(`[email] reset ${String(to)}: ${callbackUrl}?token=${token}`), ), }); const appLayer = AuthLive.dev.pipe( Layer.provide(DevMemoryAuthStorage()), Layer.provide(MockEmailLayer), ); const program = Effect.gen(function* () { const auth = yield* Auth; // Sign up const { user } = yield* auth.signUp({ email: "alice@example.com", password: "correct horse battery staple", verificationCallbackUrl: "https://app.example.com/verify", }); console.log("Signed up:", user.id, String(user.email)); }).pipe(Effect.provide(appLayer)); Effect.runPromise(program); ``` -------------------------------- ### AuthLive Layer Presets Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Provides preset layer compositions for the Auth service, simplifying setup for different environments. ```APIDOC ## `AuthLive` — Layer presets Three preset layer compositions control which defaults are wired. Applications always provide `AuthStorage` and `AuthEmail`; `production` additionally requires a `RateLimiter`. ### Development Layer (`devLayer`) This layer is suitable for development environments, using a permissive rate limiter and not requiring an external rate-limit service. ```typescript import { Layer } from "effect"; import { AuthLive, VerificationTokenConfigLive } from "effect-auth"; // Development: permissive rate limiter, no external rate-limit service needed const devLayer = AuthLive.dev.pipe( Layer.provide(MyAuthStorage), // Replace with your AuthStorage implementation Layer.provide(MyAuthEmail), // Replace with your AuthEmail implementation ); ``` ### Production Layer (`prodLayer`) This layer is for production environments and requires a real `RateLimiter` service. ```typescript import { Layer } from "effect"; import { AuthLive, VerificationTokenConfigLive } from "effect-auth"; // Production: real RateLimiter required const prodLayer = AuthLive.production.pipe( Layer.provide(MyAuthStorage), // Replace with your AuthStorage implementation Layer.provide(MyAuthEmail), // Replace with your AuthEmail implementation Layer.provide(MyRedisRateLimiter), // Replace with your RateLimiter implementation ); ``` ### Custom Token TTLs Layer (`withCustomTtl`) This layer allows for custom Time-To-Live (TTL) configurations for verification and reset tokens, applicable to both development and production setups. ```typescript import { Layer } from "effect"; import { AuthLive, VerificationTokenConfigLive } from "effect-auth"; // Custom token TTLs (applies to both dev and production) const withCustomTtl = AuthLive.production.pipe( Layer.provide( VerificationTokenConfigLive({ emailVerificationTtl: "48 hours", passwordResetTtl: "30 minutes", }), ), Layer.provide(MyAuthStorage), // Replace with your AuthStorage implementation Layer.provide(MyAuthEmail), // Replace with your AuthEmail implementation Layer.provide(MyRedisRateLimiter), // Replace with your RateLimiter implementation ); ``` ``` -------------------------------- ### Implement AuthStorage Service for Persistence Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Provide an `AuthStorage` layer to `AuthLive` for all persistence operations. This example shows basic implementations for user creation and finding credentials, mapping database errors to `AuthStorageFailure`. ```typescript import { Layer, Effect } from "effect"; import { AuthStorage, AuthStorageFailure } from "effect-auth/storage"; // import your DB client here (e.g., postgres, drizzle, prisma) const PostgresAuthStorage = Layer.succeed(AuthStorage)({ createUserWithEmailPasswordCredential: ({ email, passwordHash, now }) => Effect.tryPromise({ try: () => db.user.create({ data: { email: String(email), passwordHash: String(passwordHash), createdAt: now } }), catch: (e: unknown) => // map unique constraint → Conflict new AuthStorageFailure({ reason: "Conflict" }), }), findCredentialByEmail: (email) => Effect.tryPromise({ try: async () => { const cred = await db.credential.findUniqueOrThrow({ where: { email: String(email) } }); const user = await db.user.findUniqueOrThrow({ where: { id: cred.userId } }); return { user, credential: cred }; }, catch: () => new AuthStorageFailure({ reason: "NotFound" }), }), // ... implement all other AuthStorage methods storeVerificationToken: () => Effect.void, findVerificationToken: () => Effect.fail(new AuthStorageFailure({ reason: "NotFound" })), consumeVerificationToken: () => Effect.fail(new AuthStorageFailure({ reason: "NotFound" })), createSession: () => Effect.fail(new AuthStorageFailure({ reason: "BackendUnavailable" })), findSessionByTokenHash: () => Effect.fail(new AuthStorageFailure({ reason: "NotFound" })), rotateSessionToken: () => Effect.fail(new AuthStorageFailure({ reason: "NotFound" })), revokeSession: () => Effect.void, revokeOtherSessions: () => Effect.void, revokeAllUserSessions: () => Effect.void, updatePasswordHash: () => Effect.void, completePasswordReset: () => Effect.void, changePasswordSession: () => Effect.fail(new AuthStorageFailure({ reason: "NotFound" })), }); ``` -------------------------------- ### Get Current Session Source: https://github.com/edusantosbrito/effect-auth/blob/main/README.md Retrieves information about the currently authenticated user's session. ```APIDOC ## GET /api/auth/session ### Description Retrieves details about the active user session. ### Method GET ### Endpoint /api/auth/session ``` -------------------------------- ### Get Current Session Source: https://github.com/edusantosbrito/effect-auth/blob/main/packages/effect-auth/README.md Retrieves information about the currently authenticated user's session. ```APIDOC ## GET /api/auth/session ### Description Retrieves the details of the current user session. ### Method GET ### Endpoint /api/auth/session ``` -------------------------------- ### Sign up a new user with email and password Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Creates a new user account, hashes the password using Scrypt, and initiates an email verification process. Passwords must meet length requirements and not match the email address. ```typescript import { Effect, Layer } from "effect"; import { Auth, AuthLive } from "effect-auth"; import { DevMemoryAuthStorage } from "effect-auth/storage/dev-memory"; import { MockEmailLayer } from "./your-mock-email"; const program = Effect.gen(function* () { const auth = yield* Auth; const result = yield* auth.signUp({ email: "alice@example.com", password: "correct horse battery staple", verificationCallbackUrl: "https://app.example.com/auth/verify", ip: "203.0.113.1", // optional, used for rate limiting }); // result: { user: { id: "usr_1", email: "alice@example.com", createdAt: number } } console.log(result.user.id); }).pipe( Effect.provide(AuthLive.dev), Effect.provide(DevMemoryAuthStorage()), Effect.provide(MockEmailLayer), ); ``` -------------------------------- ### Sign Up with Email Source: https://github.com/edusantosbrito/effect-auth/blob/main/packages/effect-auth/README.md Initiates the user sign-up process using an email address. ```APIDOC ## POST /api/auth/sign-up/email ### Description Registers a new user with their email address. ### Method POST ### Endpoint /api/auth/sign-up/email ``` -------------------------------- ### Get Current Session API Request Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Retrieve the current user's session information using the HttpOnly cookie. ```bash curl -b cookies.txt https://app.example.com/api/auth/session ``` -------------------------------- ### Sign Up with Email Source: https://github.com/edusantosbrito/effect-auth/blob/main/README.md Registers a new user with their email address. ```APIDOC ## POST /api/auth/sign-up/email ### Description Registers a new user using their email address. ### Method POST ### Endpoint /api/auth/sign-up/email ``` -------------------------------- ### Backend Usage: Initialize Auth Service Source: https://github.com/edusantosbrito/effect-auth/blob/main/README.md Demonstrates initializing the Auth service with custom storage and email layers for development. Requires custom implementations for MyAuthStorage and MyAuthEmail. ```typescript import { Effect, Layer } from "effect"; import { Auth, AuthLive } from "effect-auth"; const AuthTestLayer = AuthLive.dev.pipe(Layer.provide(MyAuthStorage), Layer.provide(MyAuthEmail)); const program = Effect.gen(function* () { const auth = yield* Auth; const signUp = yield* auth.signUp({ email: "user@example.com", password: "correct horse battery staple", verificationCallbackUrl: "https://app.example.com/verify", }); return signUp.user; }).pipe(Effect.provide(AuthTestLayer)); ``` -------------------------------- ### auth.signUp Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Registers a new user with email and password, hashes the password, and initiates the email verification process. ```APIDOC ## auth.signUp — Register a new user with email/password ### Description Creates a new user account, hashes the password with Scrypt, and sends an email verification token. Email and password are parsed and validated at the boundary; passwords must be 12–128 characters and must not match the email address. ### Method Signature ```typescript auth.signUp({ email: string, password: string, verificationCallbackUrl: string, ip?: string // optional, used for rate limiting }): Effect ``` ### Parameters #### Request Body - **email** (string) - Required - The user's email address. - **password** (string) - Required - The user's password (12-128 characters, not matching email). - **verificationCallbackUrl** (string) - Required - The URL to send the verification token to. - **ip** (string) - Optional - The IP address of the user, used for rate limiting. ### Request Example ```typescript import { Effect, Layer } from "effect"; import { Auth, AuthLive } from "effect-auth"; import { DevMemoryAuthStorage } from "effect-auth/storage/dev-memory"; import { MockEmailLayer } from "./your-mock-email"; const program = Effect.gen(function* () { const auth = yield* Auth; const result = yield* auth.signUp({ email: "alice@example.com", password: "correct horse battery staple", verificationCallbackUrl: "https://app.example.com/auth/verify", ip: "203.0.113.1", // optional, used for rate limiting }); // result: { user: { id: "usr_1", email: "alice@example.com", createdAt: number } } console.log(result.user.id); }).pipe( Effect.provide(AuthLive.dev), Effect.provide(DevMemoryAuthStorage()), Effect.provide(MockEmailLayer), ); ``` ### Response #### Success Response - **user** ({ id: string, email: string, createdAt: number }) - The newly created user object. ``` -------------------------------- ### Run Deterministic Auth Flow with Bun Source: https://github.com/edusantosbrito/effect-auth/blob/main/examples/minimal/README.md Execute the same deterministic authentication flow directly using Bun, specifying the working directory. No .env file is required. ```bash bun run --cwd examples/minimal demo ``` -------------------------------- ### Sign In with Email Source: https://github.com/edusantosbrito/effect-auth/blob/main/README.md Authenticates a user using their email address and password. ```APIDOC ## POST /api/auth/sign-in/email ### Description Authenticates an existing user with their email and password. ### Method POST ### Endpoint /api/auth/sign-in/email ``` -------------------------------- ### Sign In with Email Source: https://github.com/edusantosbrito/effect-auth/blob/main/packages/effect-auth/README.md Authenticates a user using their email address and password. ```APIDOC ## POST /api/auth/sign-in/email ### Description Authenticates a user with their email and password. ### Method POST ### Endpoint /api/auth/sign-in/email ``` -------------------------------- ### Auth Layer Presets Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Configure `AuthLive` with preset layer compositions for development and production. Production requires a `RateLimiter`. Custom token TTLs can be applied. ```typescript import { Layer } from "effect"; import { AuthLive, VerificationTokenConfigLive } from "effect-auth"; // Development: permissive rate limiter, no external rate-limit service needed const devLayer = AuthLive.dev.pipe( Layer.provide(MyAuthStorage), Layer.provide(MyAuthEmail), ); // Production: real RateLimiter required const prodLayer = AuthLive.production.pipe( Layer.provide(MyAuthStorage), Layer.provide(MyAuthEmail), Layer.provide(MyRedisRateLimiter), ); // Custom token TTLs (applies to both dev and production) const withCustomTtl = AuthLive.production.pipe( Layer.provide( VerificationTokenConfigLive({ emailVerificationTtl: "48 hours", passwordResetTtl: "30 minutes", }), ), Layer.provide(MyAuthStorage), Layer.provide(MyAuthEmail), Layer.provide(MyRedisRateLimiter), ); ``` -------------------------------- ### BoundedDevRateLimiter Configuration Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Configures a bounded development rate limiter with specified limits and window duration. Useful for testing rate-limiting logic without external dependencies. ```typescript import { Layer, Effect, Clock } from "effect"; import { RateLimiter, RateLimitExceeded } from "effect-auth/rate-limit"; // Bounded dev rate limiter with custom limits import { BoundedDevRateLimiter } from "effect-auth/rate-limit"; const DevRateLimiterLayer = BoundedDevRateLimiter({ limit: 10, windowMillis: 60_000 }); ``` -------------------------------- ### Configure Token TTLs with VerificationTokenConfigLive Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Set custom time-to-live for email verification and password reset tokens using `VerificationTokenConfigLive`. Defaults are 24 hours for email verification and 15 minutes for password reset. ```typescript import { VerificationTokenConfigLive } from "effect-auth"; const TokenPolicyLive = VerificationTokenConfigLive({ emailVerificationTtl: "24 hours", // any Effect Duration.Input passwordResetTtl: "15 minutes", }); ``` -------------------------------- ### auth.signIn Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Authenticates a user by validating their email and password against stored credentials. If successful, it creates a 7-day server-side session and returns a session token. ```APIDOC ## `auth.signIn` — Authenticate and issue a session token ### Description Validates the email/password pair against the stored Scrypt hash, checks that the email has been verified, and creates a 7-day server-side session. Returns a `Redacted` session token for bearer/API flows; the HTTP adapter sets an HttpOnly cookie instead. ### Method Effect.gen ### Parameters #### Effect Parameters - **email** (string) - Required - The user's email address. - **password** (string) - Required - The user's password. - **ip** (string) - Required - The IP address of the client making the request. ### Response #### Success Response - **user** (object) - The authenticated user object. - **session** (object) - The session object, including expiration details. - **sessionToken** (Redacted) - The session token for API flows. ``` -------------------------------- ### Sign In Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Authenticates a user via email and password, setting an HttpOnly cookie for session management. ```APIDOC ## POST /api/auth/sign-in/email ### Description Authenticates a user by email and password. Sets an HttpOnly cookie for session management. ### Method POST ### Endpoint https://app.example.com/api/auth/sign-in/email ### Parameters #### Request Body - **email** (string) - Required - The user's email address. - **password** (string) - Required - The user's password. ### Request Example { "email": "alice@example.com", "password": "correct horse battery staple" } ### Response #### Success Response (200) - **user** (object) - The authenticated user object. - **session** (object) - The session object. - **id** (string) - The session's unique identifier. - **expiresAt** (integer) - The timestamp when the session expires. ### Response Example { "user": { "id": "usr_1", "email": "alice@example.com", "createdAt": 1700000000000 }, "session": { "id": "ses_1", "expiresAt": 1700003600000 } } ``` -------------------------------- ### Configure Token TTLs Source: https://github.com/edusantosbrito/effect-auth/blob/main/packages/effect-auth/README.md Configure Time-To-Live for verification and password reset tokens. ```typescript import { VerificationTokenConfigLive } from "effect-auth" const TokenPolicyLive = VerificationTokenConfigLive({ emailVerificationTtl: "24 hours", passwordResetTtl: "15 minutes", }) ``` -------------------------------- ### Sign In API Request Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Sign in a user with their email and password. This endpoint sets an HttpOnly cookie for session management. ```bash curl -c cookies.txt -X POST https://app.example.com/api/auth/sign-in/email \ -H "Content-Type: application/json" \ -H "Origin: https://app.example.com" \ -d '{"email":"alice@example.com","password":"correct horse battery staple"}' ``` -------------------------------- ### HTTP Adapter — AuthHttp.mount Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Mounts all authentication route handlers onto an Effect HttpRouter. It supports browser sign-in with HttpOnly cookies and configurable session cookie names. ```APIDOC ## HTTP Adapter — `AuthHttp.mount` Mounts all nine auth route handlers onto an Effect `HttpRouter` layer at a configurable base path. Browser sign-in sets an HttpOnly SameSite=Lax cookie automatically; session token is not returned in JSON for browser flows. ```typescript import { Layer } from "effect"; import { AuthLive, VerificationTokenConfigLive } from "effect-auth"; import { AuthHttp, AuthHttpConfig } from "effect-auth/http"; import * as HttpRouter from "effect/unstable/http/HttpRouter"; const appLayer = Layer.mergeAll( AuthLive.production, AuthHttpConfig.layer({ trustedOrigins: ["https://app.example.com"], sessionCookieName: "__Host_effect_auth_session", secureCookies: true, }), VerificationTokenConfigLive({ emailVerificationTtl: "24 hours", passwordResetTtl: "15 minutes", }), ).pipe( Layer.provide(PostgresAuthStorage), Layer.provide(ResendAuthEmail), Layer.provide(RedisRateLimiter), ); // Mounts routes under /api/auth/* const app = HttpRouter.layer.pipe(AuthHttp.mount({ basePath: "/api/auth" })); // Resulting endpoints: // POST /api/auth/sign-up/email // POST /api/auth/verify-email // POST /api/auth/resend-verification // POST /api/auth/sign-in/email → sets HttpOnly cookie // GET /api/auth/session // POST /api/auth/sign-out → clears cookie // POST /api/auth/password-reset/request // POST /api/auth/password-reset/complete // POST /api/auth/password/change ``` ``` -------------------------------- ### RedisRateLimiter Implementation Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Provides a production-ready rate limiter implementation backed by Redis. It checks request counts per bucket, email, or IP, and enforces limits with a configurable TTL. ```typescript import { Layer, Effect, Clock } from "effect"; import { RateLimiter, RateLimitExceeded } from "effect-auth/rate-limit"; // Production implementation backed by Redis const RedisRateLimiterLayer = Layer.succeed(RateLimiter)({ check: ({ bucket, email, ip }) => Effect.gen(function* () { const now = yield* Clock.currentTimeMillis; const key = `rate:${bucket}:${email ?? ip ?? "global"}`; const count = await redis.incr(key); if (count === 1) await redis.pexpire(key, 60_000); if (count > 10) { const ttl = await redis.pttl(key); return yield* new RateLimitExceeded({ bucket, retryAfterMillis: ttl }); } }), }); ``` -------------------------------- ### Configure Token TTLs Source: https://github.com/edusantosbrito/effect-auth/blob/main/README.md Customize Time-To-Live (TTL) for verification and password reset tokens using VerificationTokenConfigLive. ```typescript import { VerificationTokenConfigLive } from "effect-auth"; const TokenPolicyLive = VerificationTokenConfigLive({ emailVerificationTtl: "24 hours", passwordResetTtl: "15 minutes", }); ``` -------------------------------- ### Sign In and Issue Session Token Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Authenticates a user by validating email/password against Scrypt hash, checks email verification, and creates a 7-day server-side session. Returns a session token for API flows; the HTTP adapter sets an HttpOnly cookie. ```typescript import { Effect, Redacted } from "effect"; import { Auth } from "effect-auth"; const signInProgram = Effect.gen(function* () { const auth = yield* Auth; const result = yield* auth.signIn({ email: "alice@example.com", password: "correct horse battery staple", ip: "203.0.113.1", }); // result: { user, session, sessionToken: Redacted } const raw = Redacted.value(result.sessionToken); console.log("Session token (first 8):", raw.slice(0, 8)); console.log("Session expires:", new Date(result.session.expiresAt)); }); ``` -------------------------------- ### VerificationTokenConfigLive Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Configures the time-to-live (TTL) for email verification and password reset tokens. ```APIDOC ## `VerificationTokenConfigLive` — Token TTL configuration Configures the time-to-live for email verification and password reset tokens. Defaults: 24 hours for email verification, 15 minutes for password reset. ### Usage ```typescript import { VerificationTokenConfigLive } from "effect-auth"; const TokenPolicyLive = VerificationTokenConfigLive({ emailVerificationTtl: "24 hours", // any Effect Duration.Input passwordResetTtl: "15 minutes", }); ``` ### Parameters - **emailVerificationTtl** (Effect Duration.Input) - The duration for which email verification tokens are valid. Defaults to "24 hours". - **passwordResetTtl** (Effect Duration.Input) - The duration for which password reset tokens are valid. Defaults to "15 minutes". ``` -------------------------------- ### Request Password Reset API Request Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Initiate the password reset process by providing the user's email and a callback URL for the reset link. ```bash curl -X POST https://app.example.com/api/auth/password-reset/request \ -H "Content-Type: application/json" \ -H "Origin: https://app.example.com" \ -d '{"email":"alice@example.com","resetCallbackUrl":"https://app.example.com/reset"}' ``` -------------------------------- ### Verify Email API Request Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Use this endpoint to verify a user's email address using a token received via a callback URL. ```bash curl -X POST https://app.example.com/api/auth/verify-email \ -H "Content-Type: application/json" \ -H "Origin: https://app.example.com" \ -d '{"token":""}' ``` -------------------------------- ### DevMemoryAuthStorage Source: https://context7.com/edusantosbrito/effect-auth/llms.txt In-memory storage implementation for development and testing purposes. It uses Maps to store authentication data and can optionally share state between tests. ```APIDOC ## `DevMemoryAuthStorage` — In-memory storage for development/testing Drop-in in-memory `AuthStorage` implementation backed by `Map`s. Accepts an optional shared state object so multiple tests can inspect or share the store. ```typescript import { Layer, Effect } from "effect"; import { Auth, AuthLive } from "effect-auth"; import { DevMemoryAuthStorage, makeDevMemoryStorageState } from "effect-auth/storage/dev-memory"; // Shared state for inspection in tests const storageState = makeDevMemoryStorageState(); const testLayer = AuthLive.dev.pipe( Layer.provide(DevMemoryAuthStorage(storageState)), Layer.provide(MockEmailLayer), ); // Inspect after the test const userCount = storageState.users.size; ``` ``` -------------------------------- ### RateLimiter Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Rate limit service boundary for gating authentication actions. This service can be implemented with development presets or production-ready solutions like Redis. ```APIDOC ## `RateLimiter` — Rate limit service boundary Application-provided Effect service that gates each auth action by bucket. Development presets are provided; production apps supply a real implementation (e.g., Redis sliding window). ```typescript import { Layer, Effect, Clock } from "effect"; import { RateLimiter, RateLimitExceeded } from "effect-auth/rate-limit"; // Bounded dev rate limiter with custom limits import { BoundedDevRateLimiter } from "effect-auth/rate-limit"; const DevRateLimiterLayer = BoundedDevRateLimiter({ limit: 10, windowMillis: 60_000 }); // Production implementation backed by Redis const RedisRateLimiterLayer = Layer.succeed(RateLimiter)({ check: ({ bucket, email, ip }) => Effect.gen(function* () { const now = yield* Clock.currentTimeMillis; const key = `rate:${bucket}:${email ?? ip ?? "global"}`; const count = await redis.incr(key); if (count === 1) await redis.pexpire(key, 60_000); if (count > 10) { const ttl = await redis.pttl(key); return yield* new RateLimitExceeded({ bucket, retryAfterMillis: ttl }); } }), }); ``` ``` -------------------------------- ### Request Password Reset Source: https://github.com/edusantosbrito/effect-auth/blob/main/README.md Initiates the password reset process for a user. ```APIDOC ## POST /api/auth/password-reset/request ### Description Starts the password reset flow by sending a reset token or link to the user's registered email. ### Method POST ### Endpoint /api/auth/password-reset/request ``` -------------------------------- ### Complete Password Reset Source: https://github.com/edusantosbrito/effect-auth/blob/main/README.md Completes the password reset process using a token and new password. ```APIDOC ## POST /api/auth/password-reset/complete ### Description Finalizes the password reset process by accepting a reset token and a new password. ### Method POST ### Endpoint /api/auth/password-reset/complete ``` -------------------------------- ### Complete Password Reset API Request Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Complete the password reset process using a reset token and the new password. ```bash curl -X POST https://app.example.com/api/auth/password-reset/complete \ -H "Content-Type: application/json" \ -H "Origin: https://app.example.com" \ -d '{"token":"","password":"new-horse-battery-staple!"}' ``` -------------------------------- ### Complete Password Reset Source: https://github.com/edusantosbrito/effect-auth/blob/main/packages/effect-auth/README.md Completes the password reset process using a token and a new password. ```APIDOC ## POST /api/auth/password-reset/complete ### Description Completes the password reset process. ### Method POST ### Endpoint /api/auth/password-reset/complete ``` -------------------------------- ### DevMemoryAuthStorage for Development Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Provides an in-memory AuthStorage implementation using Maps, suitable for development and testing. Accepts an optional shared state object for inspecting or sharing the store across multiple tests. ```typescript import { Layer, Effect } from "effect"; import { Auth, AuthLive } from "effect-auth"; import { DevMemoryAuthStorage, makeDevMemoryStorageState } from "effect-auth/storage/dev-memory"; // Shared state for inspection in tests const storageState = makeDevMemoryStorageState(); const testLayer = AuthLive.dev.pipe( Layer.provide(DevMemoryAuthStorage(storageState)), Layer.provide(MockEmailLayer), ); // Inspect after the test const userCount = storageState.users.size; ``` -------------------------------- ### Mounting Auth HTTP Routes Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Mounts all effect-auth route handlers onto an Effect HttpRouter at a specified base path. Configures trusted origins, session cookie name, and secure cookie settings. ```typescript import { Layer } from "effect"; import { AuthLive, VerificationTokenConfigLive } from "effect-auth"; import { AuthHttp, AuthHttpConfig } from "effect-auth/http"; import * as HttpRouter from "effect/unstable/http/HttpRouter"; const appLayer = Layer.mergeAll( AuthLive.production, AuthHttpConfig.layer({ trustedOrigins: ["https://app.example.com"], sessionCookieName: "__Host_effect_auth_session", secureCookies: true, }), VerificationTokenConfigLive({ emailVerificationTtl: "24 hours", passwordResetTtl: "15 minutes", }), ).pipe( Layer.provide(PostgresAuthStorage), Layer.provide(ResendAuthEmail), Layer.provide(RedisRateLimiter), ); // Mounts routes under /api/auth/* const app = HttpRouter.layer.pipe(AuthHttp.mount({ basePath: "/api/auth" })); // Resulting endpoints: // POST /api/auth/sign-up/email // POST /api/auth/verify-email // POST /api/auth/resend-verification // POST /api/auth/sign-in/email → sets HttpOnly cookie // GET /api/auth/session // POST /api/auth/sign-out → clears cookie // POST /api/auth/password-reset/request // POST /api/auth/password-reset/complete // POST /api/auth/password/change ``` -------------------------------- ### auth.verifyEmail Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Consumes an email verification token to mark a user's email as verified. ```APIDOC ## auth.verifyEmail — Consume an email verification token ### Description Marks the user's email as verified by consuming the one-time hashed verification token. The token is extracted from the callback URL's `?token=` query parameter and decoded with `VerificationToken`. ### Method Signature ```typescript auth.verifyEmail({ token: VerificationToken }): Effect ``` ### Parameters #### Request Body - **token** (VerificationToken) - Required - The verification token. ### Request Example ```typescript import { Effect } from "effect"; import { Auth } from "effect-auth"; import { VerificationToken } from "effect-auth/token"; import { Schema } from "effect"; const decodeToken = Schema.decodeUnknownEffect(VerificationToken); const verifyEmailProgram = (rawToken: string) => Effect.gen(function* () { const auth = yield* Auth; const token = yield* decodeToken(rawToken); const { user } = yield* auth.verifyEmail({ token }); // user is now email-verified; sign-in will succeed console.log("Verified:", user.id); }); ``` ### Response #### Success Response - **user** ({ id: string, email: string, createdAt: number }) - The verified user object. ``` -------------------------------- ### Complete Password Reset Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Consumes the reset token (one-time use, 15-minute TTL), validates the new password against policy, rehashes it with Scrypt, and revokes all existing sessions for the user. The user must sign in again after this operation. ```typescript import { Effect } from "effect"; import { Auth } from "effect-auth"; import { VerificationToken } from "effect-auth/token"; import { Schema } from "effect"; const decodeToken = Schema.decodeUnknownEffect(VerificationToken); const resetPasswordProgram = (rawToken: string, newPassword: string) => Effect.gen(function* () { const auth = yield* Auth; const token = yield* decodeToken(rawToken); yield* auth.resetPassword({ token, password: newPassword }); // All previous sessions revoked; user must sign in again console.log("Password reset complete"); }); ``` -------------------------------- ### Request Password Reset Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Initiates the password reset process by sending a reset token to the user's email. ```APIDOC ## POST /api/auth/password-reset/request ### Description Requests a password reset. Sends a reset token to the user's email. ### Method POST ### Endpoint https://app.example.com/api/auth/password-reset/request ### Parameters #### Request Body - **email** (string) - Required - The user's email address. - **resetCallbackUrl** (string) - Required - The URL to redirect to after the password reset. ### Request Example { "email": "alice@example.com", "resetCallbackUrl": "https://app.example.com/reset" } ### Response #### Success Response (200) - **ok** (boolean) - Indicates if the request was successful. ### Response Example { "ok": true } ``` -------------------------------- ### AuthHttp.optionalAuth Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Middleware that conditionally authenticates a route or effect. It does not fail if no session is found, providing the session as an Option. ```APIDOC ## AuthHttp.optionalAuth ### Description Middleware that conditionally authenticates a route or effect. It never fails and provides `CurrentAuthSession` with `.current` as `Option<{ user, session }>`. Useful for pages that render differently for signed-in vs. anonymous users. ### Usage ```typescript import { Effect, Option } from "effect"; import { AuthHttp, CurrentAuthSession } from "effect-auth/http"; const navbarHandler = Effect.gen(function* () { const { current } = yield* CurrentAuthSession; return Option.match(current, { onNone: () => ({ signedIn: false }), onSome: ({ user }) => ({ signedIn: true, userId: user.id }), }); }).pipe(AuthHttp.optionalAuth); ``` ``` -------------------------------- ### Request Password Reset Source: https://github.com/edusantosbrito/effect-auth/blob/main/packages/effect-auth/README.md Initiates the password reset process by sending a reset link to the user's email. ```APIDOC ## POST /api/auth/password-reset/request ### Description Requests a password reset for the user's account. ### Method POST ### Endpoint /api/auth/password-reset/request ``` -------------------------------- ### Consume an email verification token Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Marks a user's email as verified by consuming a one-time hashed token. The token is expected in the `?token=` query parameter of a callback URL and is decoded using `VerificationToken`. ```typescript import { Effect } from "effect"; import { Auth } from "effect-auth"; import { VerificationToken } from "effect-auth/token"; import { Schema } from "effect"; const decodeToken = Schema.decodeUnknownEffect(VerificationToken); const verifyEmailProgram = (rawToken: string) => Effect.gen(function* () { const auth = yield* Auth; const token = yield* decodeToken(rawToken); const { user } = yield* auth.verifyEmail({ token }); // user is now email-verified; sign-in will succeed console.log("Verified:", user.id); }); ``` -------------------------------- ### Verify Email Source: https://github.com/edusantosbrito/effect-auth/blob/main/packages/effect-auth/README.md Verifies a user's email address, typically after a sign-up or email change. ```APIDOC ## POST /api/auth/verify-email ### Description Verifies a user's email address using a token. ### Method POST ### Endpoint /api/auth/verify-email ``` -------------------------------- ### AuthHttp.requireAuth Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Middleware that protects a route or effect, ensuring a valid session is present in the context. It fails if no valid session is found. ```APIDOC ## AuthHttp.requireAuth ### Description Middleware that resolves the session from a cookie or bearer token and provides `AuthSession` into the effect context. Fails with `AuthHttpError.MissingSessionToken` or `AuthHttpError.InvalidSessionToken` if no valid session is found. ### Usage ```typescript import { Effect, Option } from "effect"; import { AuthHttp, AuthSession, CurrentAuthSession } from "effect-auth/http"; // Protect an entire effect — AuthSession is injected into context const protectedHandler = Effect.gen(function* () { const { user, session } = yield* AuthSession; return { userId: user.id, email: String(user.email) }; }).pipe(AuthHttp.requireAuth); // With explicit extractor (bearer token only) import { AuthHttpToken } from "effect-auth/http"; const apiHandler = Effect.gen(function* () { const { user } = yield* AuthSession; return { user }; }).pipe(AuthHttp.requireAuth({ extractor: AuthHttpToken.bearer })); ``` ``` -------------------------------- ### Verify Email Source: https://github.com/edusantosbrito/effect-auth/blob/main/README.md Verifies a user's email address. ```APIDOC ## POST /api/auth/verify-email ### Description Verifies a user's email address, typically after they have received a verification code. ### Method POST ### Endpoint /api/auth/verify-email ``` -------------------------------- ### HTTP Layer Configuration Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Configure the HTTP layer for Effect Auth, including session cookie name, trusted origins for CSRF protection, and secure cookie settings. Pass this configuration to `AuthHttpConfig.layer(...)`. ```typescript import { AuthHttpConfig } from "effect-auth/http"; const HttpConfigLayer = AuthHttpConfig.layer({ trustedOrigins: ["https://app.example.com", "https://admin.example.com"], sessionCookieName: "__Host_effect_auth_session", // "__Host_" prefix recommended for production sessionCookiePath: "/", secureCookies: true, // auto-derived from NODE_ENV or baseUrl if omitted defaultTokenExtractor: undefined, // defaults to cookie; set to AuthHttpToken.bearer for APIs baseUrl: new URL("https://app.example.com"), }); ``` -------------------------------- ### Verify Email Source: https://context7.com/edusantosbrito/effect-auth/llms.txt Verifies a user's email address using a token provided in a callback URL. ```APIDOC ## POST /api/auth/verify-email ### Description Verifies a user's email address using a token. ### Method POST ### Endpoint https://app.example.com/api/auth/verify-email ### Parameters #### Request Body - **token** (string) - Required - The verification token. ### Request Example { "token": "" } ### Response #### Success Response (200) - **user** (object) - The verified user object. - **id** (string) - The user's unique identifier. - **email** (string) - The user's email address. - **createdAt** (integer) - The timestamp when the user was created. ### Response Example { "user": { "id": "usr_1", "email": "alice@example.com", "createdAt": 1700000000000 } } ```