{"id":18444,"library":"ideal-auth","title":"ideal-auth","description":"Auth primitives for the JS ecosystem — stateless encrypted sessions, password hashing, and two-factor support. Zero framework dependencies; inspired by Laravel's Auth and Hash facades. Current stable version is 1.2.0, released monthly. Key differentiators: uses iron-session for AES-256-CBC + HMAC encrypted cookies, supports two session modes (resolveUser for DB-backed, sessionFields for zero DB calls), built-in TOTP for 2FA, and per-request autoTouch override for frameworks like Next.js. Ships TypeScript types, requires Node >=18, and has optional bcryptjs peer dependency.","status":"active","version":"1.2.0","language":"javascript","source_language":"en","source_url":"https://github.com/ramonmalcolm10/ideal-auth","tags":["javascript","auth","authentication","session","cookie","login","password","bcrypt","argon2","typescript"],"install":[{"cmd":"npm install ideal-auth","lang":"bash","label":"npm"},{"cmd":"yarn add ideal-auth","lang":"bash","label":"yarn"},{"cmd":"pnpm add ideal-auth","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Optional peer dependency, required only for createHash() password hashing","package":"bcryptjs","optional":true},{"reason":"Peer dependency for type definitions","package":"typescript","optional":true}],"imports":[{"note":"Default export not available; named export only.","wrong":"import createAuth from 'ideal-auth'","symbol":"createAuth","correct":"import { createAuth } from 'ideal-auth'"},{"note":"Named export; bcryptjs must be installed as peer dependency if used.","symbol":"createHash","correct":"import { createHash } from 'ideal-auth'"},{"note":"Utility function for consistent string normalization before hashing.","symbol":"prehash","correct":"import { prehash } from 'ideal-auth'"}],"quickstart":{"code":"import { createAuth, createHash } from 'ideal-auth';\nimport { cookies } from 'next/headers';\nimport { db } from '@/lib/db';\n\nconst hash = createHash({ rounds: 12 });\n\nexport const auth = createAuth({\n  secret: process.env.IDEAL_AUTH_SECRET ?? '',\n  cookie: {\n    get: async (name) => (await cookies()).get(name)?.value,\n    set: async (name, value, opts) => (await cookies()).set(name, value, opts),\n    delete: async (name) => (await cookies()).delete(name),\n  },\n  hash,\n  resolveUser: async (id) => db.user.findUnique({ where: { id } }),\n  resolveUserByCredentials: async (creds) => db.user.findUnique({ where: { email: creds.email } }),\n});\n\n// In a server action:\nconst session = auth();\nawait session.attempt({ email: 'user@example.com', password: 's3cret' });\nconst user = await session.user();\nawait session.logout();","lang":"typescript","description":"Shows setup with createAuth and createHash, cookie bridge for Next.js, and basic login/check/logout flow."},"warnings":[{"fix":"Update to createAuth<SessionUser>({ ... }) — remove the second type argument.","message":"v1.0.0: createAuth now requires a single type parameter TUser; removed previous dual-generic signature.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Migrate to single generic: createAuth<SessionUser>({ ... }).","message":"v0.7.0: Simplified type system — createAuth takes only TUser, not TFields.","severity":"breaking","affected_versions":">=0.7.0 <1.0.0"},{"fix":"Rename environment variable to IDEAL_AUTH_SECRET.","message":"v0.5.0: Session secret environment variable renamed from IDEAL_AUTH_SESSION_SECRET to IDEAL_AUTH_SECRET.","severity":"deprecated","affected_versions":">=0.5.0"},{"fix":"Upgrade to v1.2.0 or later to use auth({ autoTouch: true }).","message":"Per-request autoTouch override is only available in v1.2.0+; earlier versions ignore per-request options.","severity":"gotcha","affected_versions":"<1.2.0"},{"fix":"Install bcryptjs as a dependency if using createHash() or provide a custom HashInstance.","message":"bcryptjs is optional but createHash() fails at runtime if not installed; no clear error message.","severity":"gotcha","affected_versions":">=0.4.0"},{"fix":"Use 'as const' when defining sessionFields array.","message":"sessionFields must be declared with 'as const' to get narrow types; otherwise user() returns generic type.","severity":"gotcha","affected_versions":">=0.6.0"},{"fix":"Generate a 32+ character secret via 'bunx ideal-auth secret'.","message":"secret must be at least 32 characters; shorter values throw an error at runtime.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-25T00:00:00.000Z","next_check":"2026-07-24T00:00:00.000Z","problems":[{"fix":"Generate a 32+ character secret: bunx ideal-auth secret, then add to .env.","cause":"IDEAL_AUTH_SECRET is too short in environment variables.","error":"Error: Secret must be at least 32 characters long"},{"fix":"Run: npm install bcryptjs or provide a custom HashInstance.","cause":"bcryptjs not installed but createHash() is used.","error":"Cannot find module 'bcryptjs'"},{"fix":"Add 'as const' to the sessionFields array: const sessionFields = ['email', 'name'] as const;","cause":"sessionFields array not declared with 'as const' causing TypeScript to infer string[].","error":"Type 'undefined' is not assignable to type 'string'"},{"fix":"Ensure auth() is called with await: const session = await auth();","cause":"Attempting to call auth() without awaiting in an async context incorrectly.","error":"Type 'typeof auth' is not a valid async function"},{"fix":"Regenerate IDEAL_AUTH_SECRET and clear all session cookies.","cause":"Corrupted session cookie or mismatched secret.","error":"Error: iron-session cookie parsing failed"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}