{"library":"remix-auth-email-link","title":"Remix Auth Email Link Strategy","description":"remix-auth-email-link provides a passwordless authentication strategy for Remix applications, leveraging 'magic links' sent via email. It is heavily inspired by the kcd strategy from Remix Auth v2. The library is actively maintained, with frequent patch and minor releases, and its current stable version is 2.1.1. A significant differentiator is its use of `crypto-js` instead of Node's built-in `crypto` module, enabling deployment on various serverless runtimes like Cloudflare Workers. It integrates with the `remix-auth` ecosystem and requires a custom `sendEmail` function to interface with any email service (e.g., Mailgun, SendGrid, AWS SES). This strategy streamlines user login by eliminating password management, offering a user-friendly and secure authentication flow.","language":"javascript","status":"active","last_verified":"Wed Apr 22","install":{"commands":["npm install remix-auth-email-link"],"cli":null},"imports":["import { EmailLinkStrategy } from 'remix-auth-email-link'","import type { SendEmailFunction } from 'remix-auth-email-link'","import { Authenticator } from 'remix-auth'"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import { Authenticator } from 'remix-auth';\nimport { EmailLinkStrategy } from 'remix-auth-email-link';\nimport { createCookieSessionStorage, redirect } from '@remix-run/node';\n\n// Minimal session storage for demonstration\nconst sessionStorage = createCookieSessionStorage({\n  cookie: {\n    name: '__session',\n    httpOnly: true,\n    path: '/',\n    sameSite: 'lax',\n    secrets: [process.env.SESSION_SECRET ?? 's3cr3t'],\n    secure: process.env.NODE_ENV === 'production',\n  },\n});\n\n// Mock user model and email service for example\ninterface User { id: string; email: string; name: string; }\nconst users: User[] = [\n  { id: '1', email: 'user@example.com', name: 'Test User' }\n];\nconst getUserByEmail = (email: string) => users.find(u => u.email === email);\nconst createUser = (email: string) => {\n  const newUser = { id: String(users.length + 1), email, name: 'New User' };\n  users.push(newUser);\n  return newUser;\n};\n\nconst sendEmail = async ({ emailAddress, magicLink, user, domainUrl, form }) => {\n  console.log(`Sending magic link to ${emailAddress}: ${magicLink}`);\n  // In a real app, integrate with an actual email service like Mailgun/SendGrid/SES\n  // e.g., await emailProvider.sendEmail(emailAddress, 'Login Link', `<a href=\"${magicLink}\">Click to login</a>`);\n};\n\nconst secret = process.env.MAGIC_LINK_SECRET ?? 'another_s3cr3t';\nif (!secret) throw new Error('Missing MAGIC_LINK_SECRET env variable.');\n\nexport const authenticator = new Authenticator<User>(sessionStorage);\n\nauthenticator.use(\n  new EmailLinkStrategy(\n    { sendEmail, secret, callbackURL: '/magic' },\n    async ({ email, form, request, magicLink, user }) => {\n      let existingUser = getUserByEmail(email);\n\n      if (!existingUser) {\n        // Create user if they don't exist\n        existingUser = createUser(email);\n      }\n\n      // Log the user in\n      return existingUser;\n    }\n  ),\n  'email-link'\n);\n\n// Example Remix loader for a magic link callback route (/magic)\nexport const loader = async ({ request }) => {\n  return await authenticator.authenticate('email-link', request, {\n    successRedirect: '/dashboard',\n    failureRedirect: '/login',\n  });\n};\n\n// Example Remix action for a login form\nexport const action = async ({ request }) => {\n  return await authenticator.authenticate('email-link', request, {\n    successRedirect: '/login?checkEmail=true', // Redirect to a page asking user to check email\n    failureRedirect: '/login',\n  });\n};\n\nconsole.log('Authenticator and strategy initialized.');\n","lang":"typescript","description":"This quickstart demonstrates how to initialize the `EmailLinkStrategy` with `remix-auth`, including mock user management and email sending functions, and how to integrate it into Remix `loader` and `action` functions for login and magic link callbacks.","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":null}