npm.io
2.1.441 • Published 3d ago

@djangocfg/api

Licence
MIT
Version
2.1.441
Deps
0
Size
3.9 MB
Vulns
0
Weekly
1.3K

@djangocfg/api

Type-safe API client and auth system for DjangoCFG applications.

Install

pnpm add @djangocfg/api

Entry Points

Entry Import Description
Main @djangocfg/api API classes, types, fetchers, schemas
Auth @djangocfg/api/auth Auth providers, hooks, utilities
Auth Server @djangocfg/api/auth/server Next.js proxy middleware
Clients @djangocfg/api/clients Pre-configured API instances

Generated API Classes

One class per OpenAPI tag. Import directly and call static methods:

import {
  CfgAccounts,          // OTP login
  CfgAccountsProfile,   // Profile CRUD
  CfgAccountsOauth,     // GitHub OAuth
  CfgAccountsAuth,      // Token refresh
  CfgAccountsApiKey,    // API key management
  CfgTotp,              // TOTP devices / disable
  CfgTotpSetup,         // TOTP setup / confirm
  CfgTotpVerify,        // TOTP verify / backup
  CfgTotpBackupCodes,   // Backup codes
  CfgCentrifugo,        // Centrifugo token
} from '@djangocfg/api';

// OTP login
const result = await CfgAccounts.cfgAccountsOtpVerifyCreate({
  body: { identifier, otp },
});

// Profile
const profile = await CfgAccountsProfile.cfgAccountsProfileRetrieve();

// Token refresh
const tokens = await CfgAccountsAuth.cfgAccountsTokenRefreshCreate({
  body: { refresh },
});

Auth Module

import { AuthProvider, useAuth } from '@djangocfg/api/auth';

// Provider
<AuthProvider config={{ routes: { auth: '/auth', defaultCallback: '/dashboard' } }}>
  {children}
</AuthProvider>

// Hook
const { user, isAuthenticated, requestOTP, verifyOTP, logout } = useAuth();
Auth Hooks
import {
  useAuth,              // Main auth context
  useAuthGuard,         // Route protection
  useAuthForm,          // OTP form state machine
  useGithubAuth,        // GitHub OAuth
  useTwoFactor,         // 2FA verification
  useTwoFactorSetup,    // 2FA setup flow
  useTwoFactorStatus,   // 2FA status / disable
  useDeleteAccount,     // Account deletion
} from '@djangocfg/api/auth';

Token storage & DPoP

The token lives in the shared auth store (localStorage by default, switchable to cookie):

import { auth } from '@djangocfg/api';

auth.getToken();              // current access token
auth.setStorageMode('cookie'); // SSR-readable cookie instead of localStorage
DPoP (RFC 9449) — sender-constrained tokens

When enabled, the generated client holds a non-extractable P-256 key (IndexedDB) and attaches a fresh DPoP proof to every request, so a stolen token can't be replayed. No BFF/proxy required.

import { dpopEnabled } from '@djangocfg/api';
// true when NEXT_PUBLIC_DPOP_ENABLED==='true'
// (set it via createBaseNextConfig({ dpop: true }) in @djangocfg/nextjs)

Backend pairing: JWTConfig(dpop_enabled=True). Full guide: @djangocfg/nextjs/@docs/DPOP.md. The token is still readable via auth.getToken() — DPoP protects by binding to the key, not by hiding the token.

Logging — role-aware verbosity

All @djangocfg/* consola loggers read one global runtime level so the console is clean for end users and verbose for admins/devs — like big SaaS apps.

import { applyRoleLogPolicy, setLogLevel } from '@djangocfg/api';

// Usually automatic: AuthProvider calls this on login/logout.
// admin (is_staff/is_superuser) or dev → debug; prod regular user → errors only.
applyRoleLogPolicy({ isAdmin: user?.is_staff || user?.is_superuser });

// Manual override (0 silent · 1 error · 2 warn · 3 info · 4 debug · 5 trace):
setLogLevel(0);

Errors still flow to @djangocfg/monitor regardless of console level, so prod incidents stay diagnosable.

Env flags

@djangocfg/api is the lowest shared package, so env flags live here (single source of truth):

import { isDev, isProd, isBrowser, isStaticBuild, dpopEnabled } from '@djangocfg/api';

Type Namespaces

import type { AccountsTypes, TotpTypes, CentrifugoTypes } from '@djangocfg/api';

type User = AccountsTypes.User;
type Device = TotpTypes.TotpDevice;

Server Middleware

// middleware.ts
import { proxyMiddleware } from '@djangocfg/api/auth/server';

export function middleware(request: NextRequest) {
  return proxyMiddleware(request);
}

export const config = {
  matcher: ['/media/:path*', '/api/:path*'],
};

Environment

NEXT_PUBLIC_API_URL=http://localhost:8000

Regenerate Client

# From django solution directory
make api

Keywords