{"_id":"@dieudonne_munganga/id-sdk","_rev":"2-72c36a63129b1bf27fa85c73425b0eb0","name":"@dieudonne_munganga/id-sdk","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@dieudonne_munganga/id-sdk","version":"0.1.0","keywords":["fikiri","oidc","sso","oauth2","authentication"],"license":"MIT","_id":"@dieudonne_munganga/id-sdk@0.1.0","maintainers":[{"name":"tictacflow_solutions","email":"dieudonneishara@gmail.com"}],"dist":{"shasum":"9ec48055b304a0afd924e15143616b0930c06792","tarball":"https://registry.npmjs.org/@dieudonne_munganga/id-sdk/-/id-sdk-0.1.0.tgz","fileCount":15,"integrity":"sha512-gHEEEycl2Nazs57KnhA+47qJ6BbRvUgO1pye+p8S2W9fn/hV9a0Zb2lIXuEmk7Hm+nw12gMUnu6yo4dLlxNZUw==","signatures":[{"sig":"MEQCIAF2tbwyFoUVFCtvGX9B6QMbOzkMtqaJS1kMi4YpoHzpAiBC8UZNiOfM5zW5khiOz+ZNSl3pKijTUS5qWBaH3+fWLA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":48107},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.js"},"./express":{"types":"./dist/express.d.ts","import":"./dist/express.mjs","require":"./dist/express.js"}},"gitHead":"5a67f05732f226d6ababd0ac0e9a09a288a08ef8","scripts":{"dev":"tsup src/index.ts src/express.ts src/react.ts --format cjs,esm --dts --watch","build":"tsup src/index.ts src/express.ts src/react.ts --format cjs,esm --dts --clean"},"_npmUser":{"name":"tictacflow_solutions","email":"dieudonneishara@gmail.com"},"_npmVersion":"10.8.2","description":"SDK officiel FikiriID — intégration SSO OIDC pour plateformes JavaScript/TypeScript","directories":{},"_nodeVersion":"20.20.2","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.4.0","@types/react":"^18.3.0","@types/express":"^4.17.21"},"peerDependencies":{"react":">=18","express":">=4"},"peerDependenciesMeta":{"react":{"optional":true},"express":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/id-sdk_0.1.0_1783024664554_0.8053928713643663","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@dieudonne_munganga/id-sdk","version":"0.1.1","description":"SDK officiel FikiriID — intégration SSO OIDC pour plateformes JavaScript/TypeScript","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./express":{"types":"./dist/express.d.ts","import":"./dist/express.mjs","require":"./dist/express.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.js"}},"scripts":{"build":"tsup src/index.ts src/express.ts src/react.ts --format cjs,esm --dts --clean","dev":"tsup src/index.ts src/express.ts src/react.ts --format cjs,esm --dts --watch"},"keywords":["fikiri","oidc","sso","oauth2","authentication"],"license":"MIT","peerDependencies":{"express":">=4","react":">=18"},"peerDependenciesMeta":{"express":{"optional":true},"react":{"optional":true}},"devDependencies":{"@types/express":"^4.17.21","@types/react":"^18.3.0","tsup":"^8.0.0","typescript":"^5.4.0"},"_id":"@dieudonne_munganga/id-sdk@0.1.1","gitHead":"d5257d8bc89ebf3c245b08fd983b4a47ebb4a195","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-XiP96VbMVwCHJFZPXVuKzkUWDvfhWbes4SbWofCsGVnD71yjKP59yIsaryn7/0iZwGM6dQ8K9kt49ECpTgdUmQ==","shasum":"a8642265c414c449aa996f5c4d612d24b0adee85","tarball":"https://registry.npmjs.org/@dieudonne_munganga/id-sdk/-/id-sdk-0.1.1.tgz","fileCount":15,"unpackedSize":48227,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICtZFekRPRJLDWJEIWl2iDjPZUB2SK4++Sbg5XafuQrtAiEAhhBGLi5oQ0qhLqOCwxmzomf1c7FmMN1q26Fq0GtMJ/g="}]},"_npmUser":{"name":"tictacflow_solutions","email":"dieudonneishara@gmail.com"},"directories":{},"maintainers":[{"name":"tictacflow_solutions","email":"dieudonneishara@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/id-sdk_0.1.1_1783025193326_0.22447480249497787"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-02T20:37:44.418Z","modified":"2026-07-02T20:46:33.592Z","0.1.0":"2026-07-02T20:37:44.692Z","0.1.1":"2026-07-02T20:46:33.465Z"},"license":"MIT","keywords":["fikiri","oidc","sso","oauth2","authentication"],"description":"SDK officiel FikiriID — intégration SSO OIDC pour plateformes JavaScript/TypeScript","maintainers":[{"name":"tictacflow_solutions","email":"dieudonneishara@gmail.com"}],"readme":"# @dieudonne_munganga/id-sdk\n\nSDK officiel FikiriID pour JavaScript et TypeScript. Intègre le flow OAuth2 Authorization Code + PKCE (RFC 7636) avec adaptateurs pour Express et React.\n\n## Installation\n\n```bash\nnpm install @dieudonne_munganga/id-sdk\n```\n\n## Usage de base\n\n```typescript\nimport { FikiriIDClient } from '@dieudonne_munganga/id-sdk'\n\nconst fikiri = new FikiriIDClient({\n  baseUrl: 'http://77.42.72.129:8094',\n  clientId: 'fikiri-AbCdEfGhIj',\n  clientSecret: 'votre_secret',        // backend uniquement\n  redirectUri: 'https://market.fikiri.cd/callback',\n  scopes: ['openid', 'profile', 'email', 'kyc:status'],\n})\n```\n\n---\n\n## SPA (navigateur)\n\n```typescript\n// Page login — démarre le flow PKCE\nawait fikiri.startLogin()\n\n// Page callback — échange le code\nconst tokens = await fikiri.handleCallback()\nconst user   = await fikiri.getUserInfo(tokens.access_token)\nconsole.log(user.fikiri_id, user.kyc_verified)\n```\n\n---\n\n## Express (serveur Node.js)\n\n```typescript\nimport express from 'express'\nimport { FikiriIDClient } from '@dieudonne_munganga/id-sdk'\nimport {\n  createFikiriMiddleware,\n  requireFikiriAuth,\n  requireKyc,\n} from '@dieudonne_munganga/id-sdk/express'\n\nconst app = express()\nconst fikiri = new FikiriIDClient({ ... })\n\n// Middleware global — injecte req.fikiriUser sur chaque requête avec un Bearer valide\napp.use(createFikiriMiddleware(fikiri))\n\n// Route protégée — 401 si pas de token\napp.get('/me', requireFikiriAuth, (req, res) => {\n  res.json({ fikiri_id: req.fikiriUser!.fikiri_id })\n})\n\n// Route protégée + KYC vérifié\napp.post('/transfert', requireFikiriAuth, requireKyc('verifie'), (req, res) => {\n  res.json({ ok: true })\n})\n\n// Route OAuth callback — échange le code côté serveur\napp.get('/callback', async (req, res) => {\n  const { code, state } = req.query as Record<string, string>\n  // Récupérer code_verifier depuis la session serveur\n  const codeVerifier = req.session.codeVerifier\n  const tokens = await fikiri.exchangeCode(code, codeVerifier)\n  // Stocker tokens en session ou cookie\n  res.redirect('/dashboard')\n})\n```\n\n---\n\n## React (SPA)\n\n```tsx\nimport { FikiriIDClient } from '@dieudonne_munganga/id-sdk'\nimport { useFikiriCallback, useUserInfo, useKycStatus } from '@dieudonne_munganga/id-sdk/react'\n\nconst fikiri = new FikiriIDClient({\n  baseUrl: 'http://77.42.72.129:8094',\n  clientId: 'fikiri-AbCdEfGhIj',\n  redirectUri: 'https://market.fikiri.cd/callback',\n  // Pas de clientSecret côté navigateur !\n})\n\n// Page login\nfunction LoginPage() {\n  return <button onClick={() => fikiri.startLogin()}>Se connecter avec FikiriID</button>\n}\n\n// Page callback\nfunction CallbackPage() {\n  const { tokens, loading, error } = useFikiriCallback(fikiri)\n  if (loading) return <p>Connexion en cours…</p>\n  if (error)   return <p>Erreur : {error}</p>\n  // Stocker tokens.access_token et utiliser useUserInfo\n  return <p>Connecté !</p>\n}\n\n// Profil\nfunction ProfileCard({ accessToken }: { accessToken: string }) {\n  const { user, loading } = useUserInfo(fikiri, accessToken)\n  if (loading) return <p>Chargement…</p>\n  return (\n    <div>\n      <p>{user?.name}</p>\n      <p>FIKIRI ID : {user?.fikiri_id}</p>\n      <p>KYC : {user?.kyc_status}</p>\n    </div>\n  )\n}\n\n// KYC guard\nfunction ProtectedFeature({ accessToken }: { accessToken: string }) {\n  const { kycVerified, loading } = useKycStatus(fikiri, accessToken)\n  if (loading)     return <p>Vérification…</p>\n  if (!kycVerified) return <p>Cette fonctionnalité requiert un KYC vérifié.</p>\n  return <p>Accès autorisé !</p>\n}\n```\n\n---\n\n## Next.js (BFF pattern)\n\n```typescript\n// app/api/auth/callback/route.ts\nimport { NextRequest, NextResponse } from 'next/server'\nimport { FikiriIDClient } from '@dieudonne_munganga/id-sdk'\n\nconst fikiri = new FikiriIDClient({\n  baseUrl: process.env.FIKIRI_BASE_URL!,\n  clientId: process.env.FIKIRI_CLIENT_ID!,\n  clientSecret: process.env.FIKIRI_CLIENT_SECRET!,\n  redirectUri: `${process.env.NEXT_PUBLIC_APP_URL}/api/auth/callback`,\n})\n\nexport async function GET(req: NextRequest) {\n  const { searchParams } = new URL(req.url)\n  const code = searchParams.get('code')!\n  const codeVerifier = req.cookies.get('fikiri_verifier')?.value!\n\n  const tokens = await fikiri.exchangeCode(code, codeVerifier)\n  // Stocker access_token en cookie httpOnly sécurisé\n  const res = NextResponse.redirect(new URL('/dashboard', req.url))\n  res.cookies.set('fikiri_at', tokens.access_token, { httpOnly: true, secure: true })\n  return res\n}\n```\n\n---\n\n## Référence API\n\n### `FikiriIDClient`\n\n| Méthode | Description |\n|---------|-------------|\n| `getAuthorizationUrl(pkce, state)` | URL d'autorisation (côté serveur) |\n| `startLogin()` | Génère PKCE + redirige (navigateur) |\n| `handleCallback()` | Échange le code depuis l'URL (navigateur) |\n| `exchangeCode(code, codeVerifier)` | Échange code → tokens (serveur) |\n| `getUserInfo(accessToken)` | Profil utilisateur |\n| `introspect(token)` | Validation token RFC 7662 |\n| `refreshAccessToken(refreshToken)` | Renouvelle l'access token |\n| `revokeToken(token)` | Révoque un token |\n| `generatePKCE()` | Génère une paire PKCE S256 |\n\n### Express helpers (`@dieudonne_munganga/id-sdk/express`)\n\n| Export | Description |\n|--------|-------------|\n| `createFikiriMiddleware(client)` | Middleware global — injecte `req.fikiriUser` |\n| `requireFikiriAuth` | Guard — 401 si pas de token |\n| `requireKyc(level)` | Guard KYC — 403 si niveau insuffisant |\n\n### React hooks (`@dieudonne_munganga/id-sdk/react`)\n\n| Hook | Description |\n|------|-------------|\n| `useFikiriCallback(client)` | Traite le callback OAuth, retourne `{ tokens, loading, error }` |\n| `useUserInfo(client, accessToken)` | Profil utilisateur, retourne `{ user, loading, error, refetch }` |\n| `useKycStatus(client, accessToken)` | Niveau KYC, retourne `{ kycStatus, kycVerified, loading }` |\n\n---\n\nServeur live : **http://77.42.72.129:8094** · [Swagger UI](http://77.42.72.129:8094/docs) · [Guide d'intégration](../../docs/integration.md)\n","readmeFilename":"README.md"}