{"id":28398,"library":"toctoc-auth","title":"TocToc Auth","description":"TocToc Auth (v1.1.9) is a React authentication library with JWT access/refresh token lifecycle, encrypted local storage (AES-256-CBC, PBKDF2, HMAC), browser fingerprinting, and automatic token refresh with exponential backoff. Built for React 19, it ships TypeScript types and integrates via context providers and hooks. Differentiators include refresh deduplication, environment-aware logging, input sanitization, and open redirect protection. Released under active development.","status":"active","version":"1.1.9","language":"javascript","source_language":"en","source_url":"https://github.com/LibardiFelipe/toctoc-auth","tags":["javascript","auth","react","jwt","authentication","authorization","typescript"],"install":[{"cmd":"npm install toctoc-auth","lang":"bash","label":"npm"},{"cmd":"yarn add toctoc-auth","lang":"bash","label":"yarn"},{"cmd":"pnpm add toctoc-auth","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency for React components and hooks","package":"react","optional":false},{"reason":"Peer dependency for DOM rendering","package":"react-dom","optional":false},{"reason":"Peer dependency for routing and protected routes","package":"react-router-dom","optional":false}],"imports":[{"note":"Named export, not default. Since v1.0.","wrong":"import TocTocAuthProvider from 'toctoc-auth'","symbol":"TocTocAuthProvider","correct":"import { TocTocAuthProvider } from 'toctoc-auth'"},{"note":"Hook must be used inside a TocTocAuthProvider context. Named export.","symbol":"useTocTocAuth","correct":"import { useTocTocAuth } from 'toctoc-auth'"},{"note":"Utility function exported from main package. Not a subpath.","wrong":"import { isTokenExpired } from 'toctoc-auth/utils'","symbol":"isTokenExpired","correct":"import { isTokenExpired } from 'toctoc-auth'"}],"quickstart":{"code":"import { TocTocAuthProvider, useTocTocAuth } from 'toctoc-auth';\nimport { BrowserRouter } from 'react-router-dom';\n\nconst authConfig = {\n  apiBaseUrl: process.env.AUTH_API_URL ?? 'http://localhost:4000',\n  encryptionKey: process.env.ENCRYPTION_KEY ?? 'default-dev-key-32chars!!',\n  providers: {\n    credentials: {\n      signUpApiRoute: '/auth/register',\n      signInApiRoute: '/auth/login',\n      refreshTokenApiRoute: '/auth/refresh',\n      signInAfterSignUp: false,\n      redirectClientRoutes: {\n        afterSignUp: '/dashboard',\n        afterSignIn: '/dashboard',\n        afterSignOut: '/login'\n      },\n      signInJsonResponseAccessTokenLocation: ['accessToken'],\n      signInJsonResponseRefreshTokenLocation: ['refreshToken'],\n      signInJsonResponseUser: {\n        location: ['user'],\n        roleLocation: ['role']\n      }\n    }\n  }\n};\n\nfunction App() {\n  return (\n    <BrowserRouter>\n      <TocTocAuthProvider config={authConfig}>\n        <YourApp />\n      </TocTocAuthProvider>\n    </BrowserRouter>\n  );\n}\n\nfunction LoginForm() {\n  const { signInWithCredentialsAsync, isAuthenticating, user } = useTocTocAuth();\n  const handleSubmit = async (e: React.FormEvent) => {\n    e.preventDefault();\n    const res = await signInWithCredentialsAsync({ email: 'a@b.com', password: 'secret' });\n    if (res.isSuccess) console.log('Logged in');\n    else console.error(res.responseBody);\n  };\n  return (\n    <form onSubmit={handleSubmit}>\n      <button disabled={isAuthenticating}>Sign In</button>\n    </form>\n  );\n}","lang":"typescript","description":"Minimal setup: wrap app with TocTocAuthProvider, then use useTocTocAuth hook for credentials-based sign-in."},"warnings":[{"fix":"Ensure package.json includes react@^19.0.0, react-dom@^19.0.0, react-router-dom@^7.0.0.","message":"Peer dependencies require React 19 and react-router-dom 7. Using older versions may cause runtime errors.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Set encryptionKey to a 32-character string in authConfig.","message":"Encryption key must be exactly 32 characters for AES-256. Using a different length silently degrades encryption.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Align sign-in API to accept the same payload as sign-up, or set signInAfterSignUp to false.","message":"When signInAfterSignUp is true, the sign-in endpoint must accept the same request body as sign-up. Mismatched fields cause auth failures.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-05-09T00:00:00.000Z","next_check":"2026-08-07T00:00:00.000Z","problems":[{"fix":"Wrap the component tree with <TocTocAuthProvider config={...}> at the root.","cause":"Component not wrapped in TocTocAuthProvider, or useTocTocAuth called outside provider.","error":"Cannot read properties of undefined (reading 'signInWithCredentialsAsync')"},{"fix":"Use import { useTocTocAuth } from 'toctoc-auth' instead of import useTocTocAuth from 'toctoc-auth'.","cause":"Default import instead of named import.","error":"TypeError: (0 , toctoc_auth.useTocTocAuth) is not a function"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}