{"_id":"@codenificient/passkey-auth","name":"@codenificient/passkey-auth","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@codenificient/passkey-auth","version":"1.0.0","description":"A comprehensive WebAuthn/Passkey authentication library for Next.js applications","main":"dist/index.js","module":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"import":"./dist/index.js","require":"./dist/index.js","types":"./dist/index.d.ts"},"./client":{"import":"./dist/client/passkey-client.js","require":"./dist/client/passkey-client.js","types":"./dist/client/passkey-client.d.ts"},"./server":{"import":"./dist/server/passkey-server.js","require":"./dist/server/passkey-server.js","types":"./dist/server/passkey-server.d.ts"}},"scripts":{"build":"tsc","dev":"tsc --watch","prepublishOnly":"npm run build","test":"jest"},"keywords":["webauthn","passkey","authentication","nextjs","typescript","fido2","biometric"],"author":{"name":"Codenificient","email":"codenificient@gmail.com"},"license":"MIT","peerDependencies":{"next":">=13.0.0","react":">=18.0.0","react-dom":">=18.0.0"},"dependencies":{"jose":"^5.0.0"},"devDependencies":{"@types/node":"^20.0.0","@types/react":"^18.0.0","@types/react-dom":"^18.0.0","typescript":"^5.0.0","jest":"^29.0.0","@types/jest":"^29.0.0"},"repository":{"type":"git","url":"git+https://github.com/codenificient/passkey-auth.git"},"bugs":{"url":"https://github.com/codenificient/passkey-auth/issues"},"homepage":"https://github.com/codenificient/passkey-auth#readme","_id":"@codenificient/passkey-auth@1.0.0","gitHead":"f2d952352f626ab7cdb5e7f58c311148fadd4850","_nodeVersion":"24.6.0","_npmVersion":"11.5.1","dist":{"integrity":"sha512-3/EKj3rW2V8tnA8TiLLAOwm/ctVRCf6mzwRXOaXa93KgK9gbbPt9o3qK5r2dK7QABIaTh0eruBQZwLmn+/5CZA==","shasum":"e74e4e4665c0f1fb9ddb0dfd0fa7ed3b37894544","tarball":"https://registry.npmjs.org/@codenificient/passkey-auth/-/passkey-auth-1.0.0.tgz","fileCount":23,"unpackedSize":60002,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDGbhVTTBimGPrDpTb1d1tPjEoB1EZYBj4ES1Mxbd9MpQIhAIxuvb+wDEZnozFYiHJ5g2JKFuI+8gv9cLz7vdC33j/G"}]},"_npmUser":{"name":"codenificient","email":"codenificient@tutanota.com"},"directories":{},"maintainers":[{"name":"codenificient","email":"codenificient@tutanota.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/passkey-auth_1.0.0_1759092279528_0.17219668399102162"},"_hasShrinkwrap":false}},"time":{"created":"2025-09-28T20:44:39.434Z","1.0.0":"2025-09-28T20:44:39.760Z","modified":"2025-09-28T20:44:40.071Z"},"maintainers":[{"name":"codenificient","email":"codenificient@tutanota.com"}],"description":"A comprehensive WebAuthn/Passkey authentication library for Next.js applications","homepage":"https://github.com/codenificient/passkey-auth#readme","keywords":["webauthn","passkey","authentication","nextjs","typescript","fido2","biometric"],"repository":{"type":"git","url":"git+https://github.com/codenificient/passkey-auth.git"},"author":{"name":"Codenificient","email":"codenificient@gmail.com"},"bugs":{"url":"https://github.com/codenificient/passkey-auth/issues"},"license":"MIT","readme":"# @your-org/passkey-auth\n\nA comprehensive WebAuthn/Passkey authentication library for Next.js applications. This package provides both client-side and server-side utilities for implementing secure, passwordless authentication using WebAuthn standards.\n\n## Features\n\n- 🔐 **WebAuthn/Passkey Support**: Full implementation of WebAuthn standards\n- 🚀 **Next.js Ready**: Optimized for Next.js 13+ with App Router\n- 📱 **Cross-Platform**: Works on desktop, mobile, and tablets\n- 🔒 **Secure**: Built-in challenge verification and origin validation\n- 🎯 **TypeScript**: Full TypeScript support with comprehensive types\n- 🧩 **Modular**: Use only what you need - client, server, or both\n- 🔄 **Database Agnostic**: Works with any database via adapter pattern\n\n## Installation\n\n```bash\nnpm install @your-org/passkey-auth\n# or\nyarn add @your-org/passkey-auth\n# or\npnpm add @your-org/passkey-auth\n```\n\n## Quick Start\n\n### 1. Client-Side Usage\n\n```tsx\nimport { usePasskeyAuth } from \"@your-org/passkey-auth\";\n\nfunction LoginPage() {\n  const { register, login, logout, isSupported } = usePasskeyAuth();\n\n  const handleRegister = async () => {\n    const result = await register(\"John Doe\", \"john@example.com\");\n    if (result.success) {\n      console.log(\"Registration successful!\");\n      // Redirect to dashboard\n    } else {\n      console.error(\"Registration failed:\", result.error);\n    }\n  };\n\n  const handleLogin = async () => {\n    const result = await login(\"john@example.com\");\n    if (result.success) {\n      console.log(\"Login successful!\", result.user);\n      // Redirect to dashboard\n    } else {\n      console.error(\"Login failed:\", result.error);\n    }\n  };\n\n  if (!isSupported()) {\n    return <div>Passkeys are not supported on this device</div>;\n  }\n\n  return (\n    <div>\n      <button onClick={handleRegister}>Register with Passkey</button>\n      <button onClick={handleLogin}>Login with Passkey</button>\n      <button onClick={logout}>Logout</button>\n    </div>\n  );\n}\n```\n\n### 2. Server-Side Usage\n\n```typescript\nimport { createPasskeyServer, DatabaseAdapter } from \"@your-org/passkey-auth\";\n\n// Implement your database adapter\nclass MyDatabaseAdapter implements DatabaseAdapter {\n  async createUser(name: string, email: string) {\n    // Your database implementation\n  }\n\n  async getUserByEmail(email: string) {\n    // Your database implementation\n  }\n\n  // ... implement other required methods\n}\n\n// Create server instance\nconst passkeyServer = createPasskeyServer({\n  jwtSecret: process.env.JWT_SECRET!,\n  database: new MyDatabaseAdapter(),\n  rpName: \"My App\",\n  rpId: \"myapp.com\",\n  origin: \"https://myapp.com\",\n});\n\n// In your API routes\nexport async function POST(request: Request) {\n  const { name, email } = await request.json();\n\n  try {\n    const result = await passkeyServer.startRegistration(name, email);\n    return Response.json(result);\n  } catch (error) {\n    return Response.json({ error: error.message }, { status: 400 });\n  }\n}\n```\n\n## API Reference\n\n### Client API\n\n#### `usePasskeyAuth(baseUrl?: string)`\n\nReact hook for passkey authentication.\n\n**Returns:**\n\n- `register(name: string, email: string)`: Register a new user\n- `login(email: string)`: Login with existing user\n- `logout()`: Logout current user\n- `isSupported()`: Check if passkeys are supported\n\n#### `PasskeyClient`\n\nClass-based client for non-React environments.\n\n```typescript\nimport { PasskeyClient } from \"@your-org/passkey-auth\";\n\nconst client = new PasskeyClient(\"https://myapp.com\");\nawait client.register(\"John Doe\", \"john@example.com\");\n```\n\n### Server API\n\n#### `createPasskeyServer(config: PasskeyAuthConfig)`\n\nCreate a server instance for handling authentication.\n\n**Configuration:**\n\n```typescript\ninterface PasskeyAuthConfig {\n  jwtSecret: string;\n  database: DatabaseAdapter;\n  rpName?: string;\n  rpId?: string;\n  origin?: string;\n}\n```\n\n**Methods:**\n\n- `startRegistration(name: string, email: string)`: Start user registration\n- `verifyRegistration(credential: WebAuthnCredential, challenge: number[])`: Verify registration\n- `startLogin(email: string)`: Start user login\n- `verifyLogin(credential: WebAuthnCredential, challenge: number[])`: Verify login\n- `createToken(user: User)`: Create JWT token\n- `verifyToken(token: string)`: Verify JWT token\n\n### Database Adapter\n\nImplement the `DatabaseAdapter` interface to work with your database:\n\n```typescript\ninterface DatabaseAdapter {\n  // User operations\n  createUser(name: string, email: string): Promise<User>;\n  getUserById(id: string): Promise<User | null>;\n  getUserByEmail(email: string): Promise<User | null>;\n\n  // Passkey operations\n  savePasskey(\n    userId: string,\n    credentialId: string,\n    publicKey: Uint8Array,\n    counter: number,\n    deviceType?: string,\n    backedUp?: boolean,\n    transports?: string[]\n  ): Promise<void>;\n  getPasskeyByCredentialId(credentialId: string): Promise<Passkey | null>;\n  updatePasskeyCounter(credentialId: string, counter: number): Promise<void>;\n\n  // Challenge operations\n  saveChallenge(challenge: string, userId?: string): Promise<void>;\n  getChallenge(challenge: string): Promise<{ userId?: string } | null>;\n  deleteChallenge(challenge: string): Promise<void>;\n}\n```\n\n## Complete Next.js Example\n\n### 1. Install Dependencies\n\n```bash\nnpm install @your-org/passkey-auth jose\n```\n\n### 2. Create Database Adapter\n\n```typescript\n// lib/database-adapter.ts\nimport {\n  DatabaseAdapter,\n  User,\n  Passkey,\n  AuthChallenge,\n} from \"@your-org/passkey-auth\";\n\nexport class PrismaDatabaseAdapter implements DatabaseAdapter {\n  // Implement all required methods using your ORM\n  async createUser(name: string, email: string): Promise<User> {\n    // Your implementation\n  }\n\n  // ... other methods\n}\n```\n\n### 3. Create API Routes\n\n```typescript\n// app/api/auth/register/route.ts\nimport { createPasskeyServer } from \"@your-org/passkey-auth\";\nimport { PrismaDatabaseAdapter } from \"@/lib/database-adapter\";\n\nconst passkeyServer = createPasskeyServer({\n  jwtSecret: process.env.JWT_SECRET!,\n  database: new PrismaDatabaseAdapter(),\n  rpName: \"My App\",\n  rpId: process.env.RP_ID || \"localhost\",\n  origin: process.env.ORIGIN || \"http://localhost:3000\",\n});\n\nexport async function POST(request: Request) {\n  const { name, email } = await request.json();\n\n  try {\n    const result = await passkeyServer.startRegistration(name, email);\n    return Response.json(result);\n  } catch (error) {\n    return Response.json({ error: error.message }, { status: 400 });\n  }\n}\n```\n\n### 4. Create Client Component\n\n```tsx\n// components/auth-form.tsx\n\"use client\";\nimport { usePasskeyAuth } from \"@your-org/passkey-auth\";\nimport { useState } from \"react\";\n\nexport function AuthForm() {\n  const { register, login, isSupported } = usePasskeyAuth();\n  const [email, setEmail] = useState(\"\");\n  const [name, setName] = useState(\"\");\n  const [isLogin, setIsLogin] = useState(true);\n\n  const handleAuth = async () => {\n    if (isLogin) {\n      const result = await login(email);\n      if (result.success) {\n        window.location.href = \"/dashboard\";\n      }\n    } else {\n      const result = await register(name, email);\n      if (result.success) {\n        window.location.href = \"/dashboard\";\n      }\n    }\n  };\n\n  if (!isSupported()) {\n    return <div>Passkeys are not supported on this device</div>;\n  }\n\n  return (\n    <form\n      onSubmit={(e) => {\n        e.preventDefault();\n        handleAuth();\n      }}\n    >\n      {!isLogin && (\n        <input\n          type=\"text\"\n          placeholder=\"Name\"\n          value={name}\n          onChange={(e) => setName(e.target.value)}\n          required\n        />\n      )}\n      <input\n        type=\"email\"\n        placeholder=\"Email\"\n        value={email}\n        onChange={(e) => setEmail(e.target.value)}\n        required\n      />\n      <button type=\"submit\">{isLogin ? \"Login\" : \"Register\"}</button>\n      <button type=\"button\" onClick={() => setIsLogin(!isLogin)}>\n        {isLogin ? \"Need an account?\" : \"Have an account?\"}\n      </button>\n    </form>\n  );\n}\n```\n\n## Security Considerations\n\n1. **JWT Secret**: Use a strong, random JWT secret\n2. **HTTPS**: Always use HTTPS in production\n3. **Origin Validation**: Ensure origin validation is properly configured\n4. **Challenge Expiry**: Challenges expire after 5 minutes by default\n5. **Database Security**: Secure your database and use proper encryption for sensitive data\n\n## Browser Support\n\n- Chrome 67+\n- Firefox 60+\n- Safari 14+\n- Edge 79+\n\n## Contributing\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## Support\n\n- 📖 [Documentation](https://github.com/your-username/passkey-auth#readme)\n- 🐛 [Report Issues](https://github.com/your-username/passkey-auth/issues)\n- 💬 [Discussions](https://github.com/your-username/passkey-auth/discussions)\n","readmeFilename":"README.md","_rev":"1-3aa2cc81a6cffd34f94a56895ad7315d"}