@indusaction/cms-auth 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts","../src/cookies.ts","../src/storage.ts","../src/createAuthClient.ts","../src/AuthProvider.tsx","../src/guards/ProtectedRoute.tsx","../src/hooks/useAutoLogout.ts","../src/components/LoginForms.tsx"],"names":["Cookies","axios","createContext","useState","useCallback","useMemo","jsx","useContext","useLocation","Navigate","Fragment","Outlet","useRef","useEffect","Form","jsxs","Typography","Input","Button"],"mappings":"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","file":"index.cjs","sourcesContent":["export type AuthRequestState = \"IDLE\" | \"PENDING\" | \"SUCCESS\" | \"ERROR\";\n\nexport interface CmsApiEnvelope<T = unknown> {\n \"status-code\": number;\n \"status-message\": string;\n errors: string;\n data: T;\n}\n\nexport interface SendOtpPayload {\n identifier: string;\n}\n\nexport interface LoginPayload {\n identifier: string;\n otp: string;\n}\n\nexport interface AuthUser {\n idx: string;\n role: string;\n user_type: string;\n first_name?: string;\n last_name?: string;\n email?: string;\n user_permissions?: string[];\n is_campaign_selected?: boolean;\n campaign_selected?: { idx: string; title: string } | null;\n is_language_selected?: boolean;\n selected_language?: string | null;\n [key: string]: unknown;\n}\n\nexport interface CookieKeyMap {\n isLoggedIn: string;\n tokenExpiry: string;\n userId: string;\n userRole: string;\n userType: string;\n userFirstName: string;\n userLastName: string;\n userPermissions: string;\n notification: string;\n}\n\nexport interface AuthPaths {\n sendOtp: string;\n login: string;\n refresh: string;\n logout: string;\n}\n\nexport interface CreateAuthClientOptions {\n /** API base URL, e.g. http://localhost:8000/ or …/api/v1/ */\n baseURL: string;\n /**\n * Cookie prefix for server-set JWT cookies (`*_cms_token`, `*_is_logged_in`).\n * Must match backend Origin → app_source (e.g. `campaign-local`, `case`).\n */\n appSource: string;\n /**\n * Prefix for FE-managed profile cookies (`*_user_id`, `*_user_role`).\n * Typically `campaign` or `case`.\n */\n profilePrefix: string;\n /** Override default auth API paths (relative to baseURL). */\n paths?: Partial<AuthPaths>;\n /** localStorage key for permissions JSON. Defaults to `${profilePrefix}_user_permissions`. */\n permissionsStorageKey?: string;\n /** Extra cookie / storage keys cleared on logout. */\n extraClearKeys?: string[];\n /** Called after session is cleared (failed refresh or explicit logout). */\n onSessionCleared?: () => void;\n /** Path to redirect to after failed refresh. Default: `/login` */\n loginPath?: string;\n}\n\nexport interface AuthSessionProfile {\n idx: string;\n role: string;\n userType: string;\n firstName?: string;\n lastName?: string;\n permissions: string[];\n}\n\nexport const DEFAULT_AUTH_PATHS: AuthPaths = {\n sendOtp: \"api/v1/users/send-otp/\",\n login: \"api/v1/auth/login/\",\n refresh: \"api/v1/auth/token/refresh/\",\n logout: \"api/v1/auth/logout/\",\n};\n\n/** Mobile / case-fe OTP path relative to a base that already includes `/api/v1/`. */\nexport const MOBILE_SEND_OTP_PATH = \"users/send-otp-mobile/\";\n","import type { CookieKeyMap } from \"./types\";\n\nexport function buildCookieKeys(\n appSource: string,\n profilePrefix: string\n): CookieKeyMap {\n return {\n isLoggedIn: `${appSource}_is_logged_in`,\n tokenExpiry: `${appSource}_cms_token_expiry`,\n userId: `${profilePrefix}_user_id`,\n userRole: `${profilePrefix}_user_role`,\n userType: `${profilePrefix}_user_type`,\n userFirstName: `${profilePrefix}_user_first_name`,\n userLastName: `${profilePrefix}_user_last_name`,\n userPermissions: `${profilePrefix}_user_permissions`,\n notification: `${profilePrefix}_notification`,\n };\n}\n\nexport function authCookieKeyList(keys: CookieKeyMap): string[] {\n return Object.values(keys);\n}\n","import Cookies from \"js-cookie\";\nimport type { AuthSessionProfile, AuthUser, CookieKeyMap } from \"./types\";\nimport { authCookieKeyList } from \"./cookies\";\n\nexport function isLoggedIn(keys: CookieKeyMap): boolean {\n return Cookies.get(keys.isLoggedIn) === \"true\";\n}\n\nexport function getTokenExpiry(keys: CookieKeyMap): number | null {\n const raw = Cookies.get(keys.tokenExpiry);\n if (!raw) return null;\n const value = Number(raw);\n return Number.isFinite(value) ? value : null;\n}\n\nexport function getSessionProfile(\n keys: CookieKeyMap,\n permissionsStorageKey: string\n): AuthSessionProfile | null {\n const idx = Cookies.get(keys.userId);\n const role = Cookies.get(keys.userRole);\n const userType = Cookies.get(keys.userType);\n\n if (!idx || !role || !userType) return null;\n\n let permissions: string[] = [];\n try {\n const raw = localStorage.getItem(permissionsStorageKey);\n if (raw) permissions = JSON.parse(raw) as string[];\n } catch {\n permissions = [];\n }\n\n return {\n idx,\n role,\n userType,\n firstName: Cookies.get(keys.userFirstName),\n lastName: Cookies.get(keys.userLastName),\n permissions,\n };\n}\n\nexport function persistSessionProfile(\n user: AuthUser,\n keys: CookieKeyMap,\n permissionsStorageKey: string\n): void {\n const permissions = user.user_permissions ?? [];\n\n localStorage.setItem(permissionsStorageKey, JSON.stringify(permissions));\n Cookies.set(keys.userId, user.idx);\n Cookies.set(keys.userRole, user.role);\n Cookies.set(keys.userType, user.user_type);\n\n if (user.first_name) Cookies.set(keys.userFirstName, user.first_name);\n if (user.last_name) Cookies.set(keys.userLastName, user.last_name);\n if (permissions.length) {\n Cookies.set(keys.userPermissions, JSON.stringify(permissions));\n }\n}\n\nexport function clearAuthStorage(\n keys: CookieKeyMap,\n permissionsStorageKey: string,\n extraClearKeys: string[] = []\n): void {\n authCookieKeyList(keys).forEach((key) => Cookies.remove(key));\n localStorage.removeItem(permissionsStorageKey);\n extraClearKeys.forEach((key) => {\n localStorage.removeItem(key);\n sessionStorage.removeItem(key);\n Cookies.remove(key);\n });\n}\n","import axios, {\n type AxiosInstance,\n type AxiosError,\n type InternalAxiosRequestConfig,\n} from \"axios\";\nimport {\n DEFAULT_AUTH_PATHS,\n type AuthPaths,\n type AuthUser,\n type CmsApiEnvelope,\n type CreateAuthClientOptions,\n type LoginPayload,\n type SendOtpPayload,\n} from \"./types\";\nimport { buildCookieKeys } from \"./cookies\";\nimport {\n clearAuthStorage,\n isLoggedIn,\n persistSessionProfile,\n getSessionProfile,\n getTokenExpiry,\n} from \"./storage\";\n\nexport interface ClearSessionOptions {\n /** When false, clears cookies/storage only (no hard redirect). Default true. */\n redirect?: boolean;\n}\n\nexport interface AuthClient {\n api: AxiosInstance;\n paths: AuthPaths;\n cookieKeys: ReturnType<typeof buildCookieKeys>;\n permissionsStorageKey: string;\n options: Required<\n Pick<\n CreateAuthClientOptions,\n | \"baseURL\"\n | \"appSource\"\n | \"profilePrefix\"\n | \"loginPath\"\n | \"extraClearKeys\"\n >\n > &\n CreateAuthClientOptions;\n sendOtp: (payload: SendOtpPayload) => Promise<CmsApiEnvelope>;\n login: (payload: LoginPayload) => Promise<AuthUser>;\n logout: (options?: ClearSessionOptions) => Promise<void>;\n refresh: () => Promise<void>;\n clearSession: (options?: ClearSessionOptions) => Promise<void>;\n isLoggedIn: () => boolean;\n getTokenExpiry: () => number | null;\n getSessionProfile: () => ReturnType<typeof getSessionProfile>;\n}\n\ntype RetriableConfig = InternalAxiosRequestConfig & { _retry?: boolean };\n\nfunction joinPath(baseURL: string, path: string): string {\n const base = baseURL.replace(/\\/+$/, \"\");\n const normalized = path.replace(/^\\/+/, \"\");\n return `${base}/${normalized}`;\n}\n\n/**\n * Creates a shared Axios client for CMS OTP + cookie JWT auth.\n *\n * Server sets HttpOnly `{appSource}_cms_token` / `_cms_refresh_token`.\n * This client uses `withCredentials` and refreshes on 401.\n */\nexport function createAuthClient(\n options: CreateAuthClientOptions\n): AuthClient {\n const paths: AuthPaths = {\n ...DEFAULT_AUTH_PATHS,\n ...options.paths,\n };\n\n const cookieKeys = buildCookieKeys(options.appSource, options.profilePrefix);\n const permissionsStorageKey =\n options.permissionsStorageKey ??\n `${options.profilePrefix}_user_permissions`;\n const extraClearKeys = options.extraClearKeys ?? [];\n const loginPath = options.loginPath ?? \"/login\";\n\n const api = axios.create({\n baseURL: options.baseURL,\n withCredentials: true,\n });\n\n let refreshPromise: Promise<void> | null = null;\n\n const refresh = async (): Promise<void> => {\n if (!refreshPromise) {\n refreshPromise = api\n .post(paths.refresh)\n .then(() => undefined)\n .finally(() => {\n refreshPromise = null;\n });\n }\n return refreshPromise;\n };\n\n const clearSession = async (\n clearOptions: ClearSessionOptions = {}\n ): Promise<void> => {\n const shouldRedirect = clearOptions.redirect !== false;\n try {\n await api.post(paths.logout);\n } catch {\n // ignore logout network errors — still clear local session\n }\n clearAuthStorage(cookieKeys, permissionsStorageKey, extraClearKeys);\n options.onSessionCleared?.();\n\n if (\n shouldRedirect &&\n typeof window !== \"undefined\" &&\n window.location.pathname !== loginPath\n ) {\n window.location.replace(loginPath);\n }\n };\n\n api.interceptors.response.use(\n (response) => response,\n async (error: AxiosError) => {\n const originalRequest = error.config as RetriableConfig | undefined;\n const status = error.response?.status;\n const url = originalRequest?.url ?? \"\";\n\n if (\n status === 401 &&\n originalRequest &&\n !originalRequest._retry &&\n !url.includes(paths.refresh)\n ) {\n originalRequest._retry = true;\n try {\n await refresh();\n return api(originalRequest);\n } catch {\n await clearSession();\n }\n }\n\n return Promise.reject(error);\n }\n );\n\n const sendOtp = async (\n payload: SendOtpPayload\n ): Promise<CmsApiEnvelope> => {\n const { data } = await api.post<CmsApiEnvelope>(paths.sendOtp, payload);\n return data;\n };\n\n const login = async (payload: LoginPayload): Promise<AuthUser> => {\n const { data } = await api.post<CmsApiEnvelope<AuthUser>>(\n paths.login,\n payload\n );\n const user = data.data;\n persistSessionProfile(user, cookieKeys, permissionsStorageKey);\n return user;\n };\n\n const logout = async (\n clearOptions: ClearSessionOptions = {}\n ): Promise<void> => {\n await clearSession(clearOptions);\n };\n\n return {\n api,\n paths,\n cookieKeys,\n permissionsStorageKey,\n options: {\n ...options,\n loginPath,\n extraClearKeys,\n },\n sendOtp,\n login,\n logout,\n refresh,\n clearSession,\n isLoggedIn: () => isLoggedIn(cookieKeys),\n getTokenExpiry: () => getTokenExpiry(cookieKeys),\n getSessionProfile: () =>\n getSessionProfile(cookieKeys, permissionsStorageKey),\n };\n}\n\nexport { joinPath };\n","import React, {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n} from \"react\";\nimport type { AuthClient } from \"./createAuthClient\";\nimport type {\n AuthRequestState,\n AuthUser,\n LoginPayload,\n SendOtpPayload,\n} from \"./types\";\n\nexport interface AuthContextValue {\n client: AuthClient;\n status: AuthRequestState;\n error: string | null;\n user: AuthUser | null;\n signIn: (payload: SendOtpPayload) => Promise<unknown>;\n verifyOtp: (payload: LoginPayload) => Promise<AuthUser>;\n logout: () => Promise<void>;\n isAuthenticated: boolean;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\nexport interface AuthProviderProps {\n client: AuthClient;\n children: React.ReactNode;\n /** Called after successful OTP verification (e.g. navigate home). */\n onLoginSuccess?: (user: AuthUser) => void | Promise<void>;\n /** Called after logout completes. */\n onLogout?: () => void | Promise<void>;\n /** Map API errors to user-facing strings. */\n mapError?: (error: unknown, phase: \"signIn\" | \"verifyOtp\" | \"logout\") => string;\n}\n\nfunction defaultMapError(\n error: unknown,\n phase: \"signIn\" | \"verifyOtp\" | \"logout\"\n): string {\n if (phase === \"verifyOtp\") return \"Invalid OTP\";\n if (phase === \"logout\") return \"Error logging out\";\n\n const err = error as {\n response?: { data?: { data?: Record<string, string[]> | string } };\n };\n const data = err?.response?.data?.data;\n if (data && typeof data === \"object\" && \"identifier\" in data) {\n const identifier = (data as { identifier?: string[] }).identifier;\n if (Array.isArray(identifier)) return identifier.join(\"\");\n }\n return \"An error occurred\";\n}\n\nexport function AuthProvider({\n client,\n children,\n onLoginSuccess,\n onLogout,\n mapError = defaultMapError,\n}: AuthProviderProps) {\n const [status, setStatus] = useState<AuthRequestState>(\"IDLE\");\n const [error, setError] = useState<string | null>(null);\n const [user, setUser] = useState<AuthUser | null>(null);\n\n const signIn = useCallback(\n async (payload: SendOtpPayload) => {\n try {\n setStatus(\"PENDING\");\n setError(null);\n const response = await client.sendOtp(payload);\n setStatus(\"SUCCESS\");\n return response;\n } catch (err) {\n const message = mapError(err, \"signIn\");\n setStatus(\"ERROR\");\n setError(message);\n throw err;\n }\n },\n [client, mapError]\n );\n\n const verifyOtp = useCallback(\n async (payload: LoginPayload) => {\n try {\n setStatus(\"PENDING\");\n setError(null);\n const nextUser = await client.login(payload);\n setUser(nextUser);\n setStatus(\"SUCCESS\");\n await onLoginSuccess?.(nextUser);\n return nextUser;\n } catch (err) {\n const message = mapError(err, \"verifyOtp\");\n setStatus(\"ERROR\");\n setError(message);\n throw err;\n }\n },\n [client, mapError, onLoginSuccess]\n );\n\n const logout = useCallback(async () => {\n try {\n setStatus(\"PENDING\");\n await client.logout();\n setUser(null);\n setStatus(\"IDLE\");\n setError(null);\n await onLogout?.();\n } catch (err) {\n const message = mapError(err, \"logout\");\n setStatus(\"ERROR\");\n setError(message);\n throw err;\n }\n }, [client, mapError, onLogout]);\n\n const value = useMemo<AuthContextValue>(\n () => ({\n client,\n status,\n error,\n user,\n signIn,\n verifyOtp,\n logout,\n isAuthenticated: client.isLoggedIn(),\n }),\n [client, status, error, user, signIn, verifyOtp, logout]\n );\n\n return (\n <AuthContext.Provider value={value}>{children}</AuthContext.Provider>\n );\n}\n\nexport function useAuth(): AuthContextValue {\n const ctx = useContext(AuthContext);\n if (!ctx) {\n throw new Error(\"useAuth must be used within an AuthProvider\");\n }\n return ctx;\n}\n","import React from \"react\";\nimport { Navigate, Outlet, useLocation } from \"react-router-dom\";\nimport type { AuthClient } from \"../createAuthClient\";\n\nexport interface ProtectedRouteProps {\n client: AuthClient;\n /** Where to send unauthenticated users. Default: client.options.loginPath */\n redirectTo?: string;\n children?: React.ReactNode;\n}\n\n/**\n * Renders children / Outlet when `{appSource}_is_logged_in` is true.\n */\nexport function ProtectedRoute({\n client,\n redirectTo,\n children,\n}: ProtectedRouteProps) {\n const location = useLocation();\n const loginPath = redirectTo ?? client.options.loginPath;\n\n if (!client.isLoggedIn()) {\n return <Navigate to={loginPath} replace state={{ from: location }} />;\n }\n\n return children ? <>{children}</> : <Outlet />;\n}\n\nexport interface GuestRouteProps {\n client: AuthClient;\n /** Where to send already-authenticated users. Default: `/` */\n redirectTo?: string;\n children?: React.ReactNode;\n}\n\n/**\n * For login pages — redirect away if already logged in.\n */\nexport function GuestRoute({\n client,\n redirectTo = \"/\",\n children,\n}: GuestRouteProps) {\n if (client.isLoggedIn()) {\n return <Navigate to={redirectTo} replace />;\n }\n\n return children ? <>{children}</> : <Outlet />;\n}\n","import React, { useEffect, useRef } from \"react\";\nimport type { AuthClient } from \"../createAuthClient\";\n\nexport interface UseAutoLogoutOptions {\n client: AuthClient;\n /** Poll interval in ms. Default: 30s */\n intervalMs?: number;\n enabled?: boolean;\n}\n\n/**\n * Logs out when `{appSource}_cms_token_expiry` (epoch ms/seconds) has passed.\n * Matches case-fe behaviour; optional for campaign-fe.\n */\nexport function useAutoLogout({\n client,\n intervalMs = 30_000,\n enabled = true,\n}: UseAutoLogoutOptions): void {\n const loggingOut = useRef(false);\n\n useEffect(() => {\n if (!enabled) return;\n\n const tick = async () => {\n if (!client.isLoggedIn() || loggingOut.current) return;\n const expiry = client.getTokenExpiry();\n if (expiry == null) return;\n\n // Backend may store seconds or milliseconds\n const expiryMs = expiry < 1e12 ? expiry * 1000 : expiry;\n if (Date.now() >= expiryMs) {\n loggingOut.current = true;\n try {\n await client.logout();\n } finally {\n loggingOut.current = false;\n }\n }\n };\n\n void tick();\n const id = window.setInterval(tick, intervalMs);\n return () => window.clearInterval(id);\n }, [client, intervalMs, enabled]);\n}\n","import React, { useEffect, useState } from \"react\";\nimport { Button, Form, Input, Typography } from \"antd\";\n\nconst headerStyle: React.CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: 4,\n marginBottom: 24,\n};\n\nconst titleStyle: React.CSSProperties = {\n margin: 0,\n textAlign: \"center\",\n fontWeight: 600,\n};\n\nconst descriptionStyle: React.CSSProperties = {\n margin: 0,\n textAlign: \"center\",\n};\n\nconst inputStyle: React.CSSProperties = {\n height: 48,\n borderRadius: 6,\n};\n\nconst formGapStyle: React.CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n};\n\nexport interface IdentifierFormValues {\n identifier: string;\n}\n\nexport interface IdentifierFormProps {\n onSubmit: (values: IdentifierFormValues) => void | Promise<void>;\n loading?: boolean;\n /** `email` | `mobile` | `either` — changes validation rules */\n mode?: \"email\" | \"mobile\" | \"either\";\n submitLabel?: string;\n title?: string;\n description?: string;\n placeholder?: string;\n initialIdentifier?: string;\n /** Field label. Hidden by default — pass a string to show one. */\n label?: React.ReactNode | null;\n}\n\nfunction defaultPlaceholder(\n mode: NonNullable<IdentifierFormProps[\"mode\"]>\n): string {\n if (mode === \"mobile\") return \"Enter Your Mobile Number\";\n if (mode === \"email\") return \"Enter Your Email\";\n return \"Enter Your Email / Phone\";\n}\n\nfunction validateIdentifier(\n mode: NonNullable<IdentifierFormProps[\"mode\"]>,\n value: string\n): Promise<void> {\n const trimmed = value.trim();\n if (!trimmed) return Promise.reject(new Error(\"Required\"));\n\n if (mode === \"mobile\") {\n if (!/^\\d{10}$/.test(trimmed)) {\n return Promise.reject(new Error(\"Enter a valid 10-digit mobile number\"));\n }\n } else if (mode === \"email\") {\n if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(trimmed)) {\n return Promise.reject(new Error(\"Enter a valid email\"));\n }\n } else {\n const isMobile = /^\\d{10}$/.test(trimmed);\n const isEmail = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(trimmed);\n if (!isMobile && !isEmail) {\n return Promise.reject(new Error(\"Enter a valid email or 10-digit mobile\"));\n }\n }\n return Promise.resolve();\n}\n\n/**\n * Presentational identifier step for OTP login (web or mobile).\n * Matches Indus Action login: centered copy, no field label, full-width CTA.\n */\nexport function IdentifierForm({\n onSubmit,\n loading = false,\n mode = \"either\",\n submitLabel = \"Continue\",\n title = \"Sign in to Indus Action\",\n description = \"Please Enter Your Email / Phone\",\n placeholder,\n initialIdentifier = \"\",\n label = null,\n}: IdentifierFormProps) {\n const [form] = Form.useForm<IdentifierFormValues>();\n const inputPlaceholder = placeholder ?? defaultPlaceholder(mode);\n\n return (\n <div style={formGapStyle}>\n {title || description ? (\n <div style={headerStyle}>\n {title ? (\n <Typography.Title level={3} style={titleStyle}>\n {title}\n </Typography.Title>\n ) : null}\n {description ? (\n <Typography.Paragraph type=\"secondary\" style={descriptionStyle}>\n {description}\n </Typography.Paragraph>\n ) : null}\n </div>\n ) : null}\n\n <Form\n form={form}\n layout=\"vertical\"\n initialValues={{ identifier: initialIdentifier }}\n onFinish={onSubmit}\n requiredMark={false}\n style={{ width: \"100%\" }}\n >\n <Form.Item\n name=\"identifier\"\n label={label ?? undefined}\n rules={[\n {\n validator: async (_, value: string) =>\n validateIdentifier(mode, value ?? \"\"),\n },\n ]}\n style={{ marginBottom: 16 }}\n >\n <Input\n size=\"large\"\n placeholder={inputPlaceholder}\n autoComplete={mode === \"mobile\" ? \"tel\" : \"username\"}\n inputMode={mode === \"mobile\" ? \"numeric\" : \"text\"}\n style={inputStyle}\n />\n </Form.Item>\n\n <Button\n type=\"primary\"\n htmlType=\"submit\"\n loading={loading}\n block\n size=\"large\"\n style={{ height: 48, borderRadius: 6 }}\n >\n {submitLabel}\n </Button>\n </Form>\n </div>\n );\n}\n\nexport interface OtpFormValues {\n otp: string;\n}\n\nexport interface OtpFormProps {\n onSubmit: (values: OtpFormValues) => void | Promise<void>;\n onResend?: () => void | Promise<void>;\n loading?: boolean;\n resendLoading?: boolean;\n /** OTP length. Default 6 */\n length?: number;\n title?: string;\n description?: string;\n submitLabel?: string;\n /** Field label. Hidden by default. */\n label?: React.ReactNode | null;\n /** Seconds until resend is enabled. Default 120 */\n resendSeconds?: number;\n}\n\n/**\n * Presentational OTP verification step — same visual language as IdentifierForm.\n */\nexport function OtpForm({\n onSubmit,\n onResend,\n loading = false,\n resendLoading = false,\n length = 6,\n title = \"Check your email / phone for a code\",\n description = \"Please enter OTP to continue to your account.\",\n submitLabel = \"Continue\",\n label = null,\n resendSeconds = 120,\n}: OtpFormProps) {\n const [form] = Form.useForm<OtpFormValues>();\n const [secondsLeft, setSecondsLeft] = useState(resendSeconds);\n\n useEffect(() => {\n if (secondsLeft <= 0) return;\n const id = window.setTimeout(() => setSecondsLeft((s) => s - 1), 1000);\n return () => window.clearTimeout(id);\n }, [secondsLeft]);\n\n const handleResend = async () => {\n if (!onResend || secondsLeft > 0) return;\n await onResend();\n setSecondsLeft(resendSeconds);\n };\n\n return (\n <div style={formGapStyle}>\n {title || description ? (\n <div style={headerStyle}>\n {title ? (\n <Typography.Title level={3} style={titleStyle}>\n {title}\n </Typography.Title>\n ) : null}\n {description ? (\n <Typography.Paragraph type=\"secondary\" style={descriptionStyle}>\n {description}\n </Typography.Paragraph>\n ) : null}\n </div>\n ) : null}\n\n <Form\n form={form}\n layout=\"vertical\"\n onFinish={onSubmit}\n requiredMark={false}\n style={{ width: \"100%\" }}\n >\n <Form.Item\n name=\"otp\"\n label={label ?? undefined}\n rules={[\n { required: true, message: \"Enter OTP\" },\n {\n len: length,\n message: `OTP must be ${length} digits`,\n },\n ]}\n style={{ marginBottom: 16 }}\n >\n <Input.OTP\n length={length}\n size=\"large\"\n style={{ display: \"flex\", width: \"100%\" }}\n />\n </Form.Item>\n\n <Button\n type=\"primary\"\n htmlType=\"submit\"\n loading={loading}\n block\n size=\"large\"\n style={{ height: 48, borderRadius: 6 }}\n >\n {submitLabel}\n </Button>\n </Form>\n\n {onResend ? (\n <Typography.Paragraph style={{ marginTop: 8, textAlign: \"center\" }}>\n {secondsLeft > 0 ? (\n <Typography.Text type=\"secondary\">\n Resend OTP in {secondsLeft}s\n </Typography.Text>\n ) : (\n <Button\n type=\"link\"\n loading={resendLoading}\n onClick={() => void handleResend()}\n >\n Resend OTP\n </Button>\n )}\n </Typography.Paragraph>\n ) : null}\n </div>\n );\n}\n"]}
@@ -0,0 +1,225 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import React from 'react';
3
+
4
+ type AuthRequestState = "IDLE" | "PENDING" | "SUCCESS" | "ERROR";
5
+ interface CmsApiEnvelope<T = unknown> {
6
+ "status-code": number;
7
+ "status-message": string;
8
+ errors: string;
9
+ data: T;
10
+ }
11
+ interface SendOtpPayload {
12
+ identifier: string;
13
+ }
14
+ interface LoginPayload {
15
+ identifier: string;
16
+ otp: string;
17
+ }
18
+ interface AuthUser {
19
+ idx: string;
20
+ role: string;
21
+ user_type: string;
22
+ first_name?: string;
23
+ last_name?: string;
24
+ email?: string;
25
+ user_permissions?: string[];
26
+ is_campaign_selected?: boolean;
27
+ campaign_selected?: {
28
+ idx: string;
29
+ title: string;
30
+ } | null;
31
+ is_language_selected?: boolean;
32
+ selected_language?: string | null;
33
+ [key: string]: unknown;
34
+ }
35
+ interface CookieKeyMap {
36
+ isLoggedIn: string;
37
+ tokenExpiry: string;
38
+ userId: string;
39
+ userRole: string;
40
+ userType: string;
41
+ userFirstName: string;
42
+ userLastName: string;
43
+ userPermissions: string;
44
+ notification: string;
45
+ }
46
+ interface AuthPaths {
47
+ sendOtp: string;
48
+ login: string;
49
+ refresh: string;
50
+ logout: string;
51
+ }
52
+ interface CreateAuthClientOptions {
53
+ /** API base URL, e.g. http://localhost:8000/ or …/api/v1/ */
54
+ baseURL: string;
55
+ /**
56
+ * Cookie prefix for server-set JWT cookies (`*_cms_token`, `*_is_logged_in`).
57
+ * Must match backend Origin → app_source (e.g. `campaign-local`, `case`).
58
+ */
59
+ appSource: string;
60
+ /**
61
+ * Prefix for FE-managed profile cookies (`*_user_id`, `*_user_role`).
62
+ * Typically `campaign` or `case`.
63
+ */
64
+ profilePrefix: string;
65
+ /** Override default auth API paths (relative to baseURL). */
66
+ paths?: Partial<AuthPaths>;
67
+ /** localStorage key for permissions JSON. Defaults to `${profilePrefix}_user_permissions`. */
68
+ permissionsStorageKey?: string;
69
+ /** Extra cookie / storage keys cleared on logout. */
70
+ extraClearKeys?: string[];
71
+ /** Called after session is cleared (failed refresh or explicit logout). */
72
+ onSessionCleared?: () => void;
73
+ /** Path to redirect to after failed refresh. Default: `/login` */
74
+ loginPath?: string;
75
+ }
76
+ interface AuthSessionProfile {
77
+ idx: string;
78
+ role: string;
79
+ userType: string;
80
+ firstName?: string;
81
+ lastName?: string;
82
+ permissions: string[];
83
+ }
84
+ declare const DEFAULT_AUTH_PATHS: AuthPaths;
85
+ /** Mobile / case-fe OTP path relative to a base that already includes `/api/v1/`. */
86
+ declare const MOBILE_SEND_OTP_PATH = "users/send-otp-mobile/";
87
+
88
+ declare function buildCookieKeys(appSource: string, profilePrefix: string): CookieKeyMap;
89
+ declare function authCookieKeyList(keys: CookieKeyMap): string[];
90
+
91
+ declare function isLoggedIn(keys: CookieKeyMap): boolean;
92
+ declare function getTokenExpiry(keys: CookieKeyMap): number | null;
93
+ declare function getSessionProfile(keys: CookieKeyMap, permissionsStorageKey: string): AuthSessionProfile | null;
94
+ declare function persistSessionProfile(user: AuthUser, keys: CookieKeyMap, permissionsStorageKey: string): void;
95
+ declare function clearAuthStorage(keys: CookieKeyMap, permissionsStorageKey: string, extraClearKeys?: string[]): void;
96
+
97
+ interface ClearSessionOptions {
98
+ /** When false, clears cookies/storage only (no hard redirect). Default true. */
99
+ redirect?: boolean;
100
+ }
101
+ interface AuthClient {
102
+ api: AxiosInstance;
103
+ paths: AuthPaths;
104
+ cookieKeys: ReturnType<typeof buildCookieKeys>;
105
+ permissionsStorageKey: string;
106
+ options: Required<Pick<CreateAuthClientOptions, "baseURL" | "appSource" | "profilePrefix" | "loginPath" | "extraClearKeys">> & CreateAuthClientOptions;
107
+ sendOtp: (payload: SendOtpPayload) => Promise<CmsApiEnvelope>;
108
+ login: (payload: LoginPayload) => Promise<AuthUser>;
109
+ logout: (options?: ClearSessionOptions) => Promise<void>;
110
+ refresh: () => Promise<void>;
111
+ clearSession: (options?: ClearSessionOptions) => Promise<void>;
112
+ isLoggedIn: () => boolean;
113
+ getTokenExpiry: () => number | null;
114
+ getSessionProfile: () => ReturnType<typeof getSessionProfile>;
115
+ }
116
+ declare function joinPath(baseURL: string, path: string): string;
117
+ /**
118
+ * Creates a shared Axios client for CMS OTP + cookie JWT auth.
119
+ *
120
+ * Server sets HttpOnly `{appSource}_cms_token` / `_cms_refresh_token`.
121
+ * This client uses `withCredentials` and refreshes on 401.
122
+ */
123
+ declare function createAuthClient(options: CreateAuthClientOptions): AuthClient;
124
+
125
+ interface AuthContextValue {
126
+ client: AuthClient;
127
+ status: AuthRequestState;
128
+ error: string | null;
129
+ user: AuthUser | null;
130
+ signIn: (payload: SendOtpPayload) => Promise<unknown>;
131
+ verifyOtp: (payload: LoginPayload) => Promise<AuthUser>;
132
+ logout: () => Promise<void>;
133
+ isAuthenticated: boolean;
134
+ }
135
+ interface AuthProviderProps {
136
+ client: AuthClient;
137
+ children: React.ReactNode;
138
+ /** Called after successful OTP verification (e.g. navigate home). */
139
+ onLoginSuccess?: (user: AuthUser) => void | Promise<void>;
140
+ /** Called after logout completes. */
141
+ onLogout?: () => void | Promise<void>;
142
+ /** Map API errors to user-facing strings. */
143
+ mapError?: (error: unknown, phase: "signIn" | "verifyOtp" | "logout") => string;
144
+ }
145
+ declare function AuthProvider({ client, children, onLoginSuccess, onLogout, mapError, }: AuthProviderProps): React.JSX.Element;
146
+ declare function useAuth(): AuthContextValue;
147
+
148
+ interface ProtectedRouteProps {
149
+ client: AuthClient;
150
+ /** Where to send unauthenticated users. Default: client.options.loginPath */
151
+ redirectTo?: string;
152
+ children?: React.ReactNode;
153
+ }
154
+ /**
155
+ * Renders children / Outlet when `{appSource}_is_logged_in` is true.
156
+ */
157
+ declare function ProtectedRoute({ client, redirectTo, children, }: ProtectedRouteProps): React.JSX.Element;
158
+ interface GuestRouteProps {
159
+ client: AuthClient;
160
+ /** Where to send already-authenticated users. Default: `/` */
161
+ redirectTo?: string;
162
+ children?: React.ReactNode;
163
+ }
164
+ /**
165
+ * For login pages — redirect away if already logged in.
166
+ */
167
+ declare function GuestRoute({ client, redirectTo, children, }: GuestRouteProps): React.JSX.Element;
168
+
169
+ interface UseAutoLogoutOptions {
170
+ client: AuthClient;
171
+ /** Poll interval in ms. Default: 30s */
172
+ intervalMs?: number;
173
+ enabled?: boolean;
174
+ }
175
+ /**
176
+ * Logs out when `{appSource}_cms_token_expiry` (epoch ms/seconds) has passed.
177
+ * Matches case-fe behaviour; optional for campaign-fe.
178
+ */
179
+ declare function useAutoLogout({ client, intervalMs, enabled, }: UseAutoLogoutOptions): void;
180
+
181
+ interface IdentifierFormValues {
182
+ identifier: string;
183
+ }
184
+ interface IdentifierFormProps {
185
+ onSubmit: (values: IdentifierFormValues) => void | Promise<void>;
186
+ loading?: boolean;
187
+ /** `email` | `mobile` | `either` — changes validation rules */
188
+ mode?: "email" | "mobile" | "either";
189
+ submitLabel?: string;
190
+ title?: string;
191
+ description?: string;
192
+ placeholder?: string;
193
+ initialIdentifier?: string;
194
+ /** Field label. Hidden by default — pass a string to show one. */
195
+ label?: React.ReactNode | null;
196
+ }
197
+ /**
198
+ * Presentational identifier step for OTP login (web or mobile).
199
+ * Matches Indus Action login: centered copy, no field label, full-width CTA.
200
+ */
201
+ declare function IdentifierForm({ onSubmit, loading, mode, submitLabel, title, description, placeholder, initialIdentifier, label, }: IdentifierFormProps): React.JSX.Element;
202
+ interface OtpFormValues {
203
+ otp: string;
204
+ }
205
+ interface OtpFormProps {
206
+ onSubmit: (values: OtpFormValues) => void | Promise<void>;
207
+ onResend?: () => void | Promise<void>;
208
+ loading?: boolean;
209
+ resendLoading?: boolean;
210
+ /** OTP length. Default 6 */
211
+ length?: number;
212
+ title?: string;
213
+ description?: string;
214
+ submitLabel?: string;
215
+ /** Field label. Hidden by default. */
216
+ label?: React.ReactNode | null;
217
+ /** Seconds until resend is enabled. Default 120 */
218
+ resendSeconds?: number;
219
+ }
220
+ /**
221
+ * Presentational OTP verification step — same visual language as IdentifierForm.
222
+ */
223
+ declare function OtpForm({ onSubmit, onResend, loading, resendLoading, length, title, description, submitLabel, label, resendSeconds, }: OtpFormProps): React.JSX.Element;
224
+
225
+ export { type AuthClient, type AuthContextValue, type AuthPaths, AuthProvider, type AuthProviderProps, type AuthRequestState, type AuthSessionProfile, type AuthUser, type ClearSessionOptions, type CmsApiEnvelope, type CookieKeyMap, type CreateAuthClientOptions, DEFAULT_AUTH_PATHS, GuestRoute, type GuestRouteProps, IdentifierForm, type IdentifierFormProps, type IdentifierFormValues, type LoginPayload, MOBILE_SEND_OTP_PATH, OtpForm, type OtpFormProps, type OtpFormValues, ProtectedRoute, type ProtectedRouteProps, type SendOtpPayload, type UseAutoLogoutOptions, authCookieKeyList, buildCookieKeys, clearAuthStorage, createAuthClient, getSessionProfile, getTokenExpiry, isLoggedIn, joinPath, persistSessionProfile, useAuth, useAutoLogout };
@@ -0,0 +1,225 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import React from 'react';
3
+
4
+ type AuthRequestState = "IDLE" | "PENDING" | "SUCCESS" | "ERROR";
5
+ interface CmsApiEnvelope<T = unknown> {
6
+ "status-code": number;
7
+ "status-message": string;
8
+ errors: string;
9
+ data: T;
10
+ }
11
+ interface SendOtpPayload {
12
+ identifier: string;
13
+ }
14
+ interface LoginPayload {
15
+ identifier: string;
16
+ otp: string;
17
+ }
18
+ interface AuthUser {
19
+ idx: string;
20
+ role: string;
21
+ user_type: string;
22
+ first_name?: string;
23
+ last_name?: string;
24
+ email?: string;
25
+ user_permissions?: string[];
26
+ is_campaign_selected?: boolean;
27
+ campaign_selected?: {
28
+ idx: string;
29
+ title: string;
30
+ } | null;
31
+ is_language_selected?: boolean;
32
+ selected_language?: string | null;
33
+ [key: string]: unknown;
34
+ }
35
+ interface CookieKeyMap {
36
+ isLoggedIn: string;
37
+ tokenExpiry: string;
38
+ userId: string;
39
+ userRole: string;
40
+ userType: string;
41
+ userFirstName: string;
42
+ userLastName: string;
43
+ userPermissions: string;
44
+ notification: string;
45
+ }
46
+ interface AuthPaths {
47
+ sendOtp: string;
48
+ login: string;
49
+ refresh: string;
50
+ logout: string;
51
+ }
52
+ interface CreateAuthClientOptions {
53
+ /** API base URL, e.g. http://localhost:8000/ or …/api/v1/ */
54
+ baseURL: string;
55
+ /**
56
+ * Cookie prefix for server-set JWT cookies (`*_cms_token`, `*_is_logged_in`).
57
+ * Must match backend Origin → app_source (e.g. `campaign-local`, `case`).
58
+ */
59
+ appSource: string;
60
+ /**
61
+ * Prefix for FE-managed profile cookies (`*_user_id`, `*_user_role`).
62
+ * Typically `campaign` or `case`.
63
+ */
64
+ profilePrefix: string;
65
+ /** Override default auth API paths (relative to baseURL). */
66
+ paths?: Partial<AuthPaths>;
67
+ /** localStorage key for permissions JSON. Defaults to `${profilePrefix}_user_permissions`. */
68
+ permissionsStorageKey?: string;
69
+ /** Extra cookie / storage keys cleared on logout. */
70
+ extraClearKeys?: string[];
71
+ /** Called after session is cleared (failed refresh or explicit logout). */
72
+ onSessionCleared?: () => void;
73
+ /** Path to redirect to after failed refresh. Default: `/login` */
74
+ loginPath?: string;
75
+ }
76
+ interface AuthSessionProfile {
77
+ idx: string;
78
+ role: string;
79
+ userType: string;
80
+ firstName?: string;
81
+ lastName?: string;
82
+ permissions: string[];
83
+ }
84
+ declare const DEFAULT_AUTH_PATHS: AuthPaths;
85
+ /** Mobile / case-fe OTP path relative to a base that already includes `/api/v1/`. */
86
+ declare const MOBILE_SEND_OTP_PATH = "users/send-otp-mobile/";
87
+
88
+ declare function buildCookieKeys(appSource: string, profilePrefix: string): CookieKeyMap;
89
+ declare function authCookieKeyList(keys: CookieKeyMap): string[];
90
+
91
+ declare function isLoggedIn(keys: CookieKeyMap): boolean;
92
+ declare function getTokenExpiry(keys: CookieKeyMap): number | null;
93
+ declare function getSessionProfile(keys: CookieKeyMap, permissionsStorageKey: string): AuthSessionProfile | null;
94
+ declare function persistSessionProfile(user: AuthUser, keys: CookieKeyMap, permissionsStorageKey: string): void;
95
+ declare function clearAuthStorage(keys: CookieKeyMap, permissionsStorageKey: string, extraClearKeys?: string[]): void;
96
+
97
+ interface ClearSessionOptions {
98
+ /** When false, clears cookies/storage only (no hard redirect). Default true. */
99
+ redirect?: boolean;
100
+ }
101
+ interface AuthClient {
102
+ api: AxiosInstance;
103
+ paths: AuthPaths;
104
+ cookieKeys: ReturnType<typeof buildCookieKeys>;
105
+ permissionsStorageKey: string;
106
+ options: Required<Pick<CreateAuthClientOptions, "baseURL" | "appSource" | "profilePrefix" | "loginPath" | "extraClearKeys">> & CreateAuthClientOptions;
107
+ sendOtp: (payload: SendOtpPayload) => Promise<CmsApiEnvelope>;
108
+ login: (payload: LoginPayload) => Promise<AuthUser>;
109
+ logout: (options?: ClearSessionOptions) => Promise<void>;
110
+ refresh: () => Promise<void>;
111
+ clearSession: (options?: ClearSessionOptions) => Promise<void>;
112
+ isLoggedIn: () => boolean;
113
+ getTokenExpiry: () => number | null;
114
+ getSessionProfile: () => ReturnType<typeof getSessionProfile>;
115
+ }
116
+ declare function joinPath(baseURL: string, path: string): string;
117
+ /**
118
+ * Creates a shared Axios client for CMS OTP + cookie JWT auth.
119
+ *
120
+ * Server sets HttpOnly `{appSource}_cms_token` / `_cms_refresh_token`.
121
+ * This client uses `withCredentials` and refreshes on 401.
122
+ */
123
+ declare function createAuthClient(options: CreateAuthClientOptions): AuthClient;
124
+
125
+ interface AuthContextValue {
126
+ client: AuthClient;
127
+ status: AuthRequestState;
128
+ error: string | null;
129
+ user: AuthUser | null;
130
+ signIn: (payload: SendOtpPayload) => Promise<unknown>;
131
+ verifyOtp: (payload: LoginPayload) => Promise<AuthUser>;
132
+ logout: () => Promise<void>;
133
+ isAuthenticated: boolean;
134
+ }
135
+ interface AuthProviderProps {
136
+ client: AuthClient;
137
+ children: React.ReactNode;
138
+ /** Called after successful OTP verification (e.g. navigate home). */
139
+ onLoginSuccess?: (user: AuthUser) => void | Promise<void>;
140
+ /** Called after logout completes. */
141
+ onLogout?: () => void | Promise<void>;
142
+ /** Map API errors to user-facing strings. */
143
+ mapError?: (error: unknown, phase: "signIn" | "verifyOtp" | "logout") => string;
144
+ }
145
+ declare function AuthProvider({ client, children, onLoginSuccess, onLogout, mapError, }: AuthProviderProps): React.JSX.Element;
146
+ declare function useAuth(): AuthContextValue;
147
+
148
+ interface ProtectedRouteProps {
149
+ client: AuthClient;
150
+ /** Where to send unauthenticated users. Default: client.options.loginPath */
151
+ redirectTo?: string;
152
+ children?: React.ReactNode;
153
+ }
154
+ /**
155
+ * Renders children / Outlet when `{appSource}_is_logged_in` is true.
156
+ */
157
+ declare function ProtectedRoute({ client, redirectTo, children, }: ProtectedRouteProps): React.JSX.Element;
158
+ interface GuestRouteProps {
159
+ client: AuthClient;
160
+ /** Where to send already-authenticated users. Default: `/` */
161
+ redirectTo?: string;
162
+ children?: React.ReactNode;
163
+ }
164
+ /**
165
+ * For login pages — redirect away if already logged in.
166
+ */
167
+ declare function GuestRoute({ client, redirectTo, children, }: GuestRouteProps): React.JSX.Element;
168
+
169
+ interface UseAutoLogoutOptions {
170
+ client: AuthClient;
171
+ /** Poll interval in ms. Default: 30s */
172
+ intervalMs?: number;
173
+ enabled?: boolean;
174
+ }
175
+ /**
176
+ * Logs out when `{appSource}_cms_token_expiry` (epoch ms/seconds) has passed.
177
+ * Matches case-fe behaviour; optional for campaign-fe.
178
+ */
179
+ declare function useAutoLogout({ client, intervalMs, enabled, }: UseAutoLogoutOptions): void;
180
+
181
+ interface IdentifierFormValues {
182
+ identifier: string;
183
+ }
184
+ interface IdentifierFormProps {
185
+ onSubmit: (values: IdentifierFormValues) => void | Promise<void>;
186
+ loading?: boolean;
187
+ /** `email` | `mobile` | `either` — changes validation rules */
188
+ mode?: "email" | "mobile" | "either";
189
+ submitLabel?: string;
190
+ title?: string;
191
+ description?: string;
192
+ placeholder?: string;
193
+ initialIdentifier?: string;
194
+ /** Field label. Hidden by default — pass a string to show one. */
195
+ label?: React.ReactNode | null;
196
+ }
197
+ /**
198
+ * Presentational identifier step for OTP login (web or mobile).
199
+ * Matches Indus Action login: centered copy, no field label, full-width CTA.
200
+ */
201
+ declare function IdentifierForm({ onSubmit, loading, mode, submitLabel, title, description, placeholder, initialIdentifier, label, }: IdentifierFormProps): React.JSX.Element;
202
+ interface OtpFormValues {
203
+ otp: string;
204
+ }
205
+ interface OtpFormProps {
206
+ onSubmit: (values: OtpFormValues) => void | Promise<void>;
207
+ onResend?: () => void | Promise<void>;
208
+ loading?: boolean;
209
+ resendLoading?: boolean;
210
+ /** OTP length. Default 6 */
211
+ length?: number;
212
+ title?: string;
213
+ description?: string;
214
+ submitLabel?: string;
215
+ /** Field label. Hidden by default. */
216
+ label?: React.ReactNode | null;
217
+ /** Seconds until resend is enabled. Default 120 */
218
+ resendSeconds?: number;
219
+ }
220
+ /**
221
+ * Presentational OTP verification step — same visual language as IdentifierForm.
222
+ */
223
+ declare function OtpForm({ onSubmit, onResend, loading, resendLoading, length, title, description, submitLabel, label, resendSeconds, }: OtpFormProps): React.JSX.Element;
224
+
225
+ export { type AuthClient, type AuthContextValue, type AuthPaths, AuthProvider, type AuthProviderProps, type AuthRequestState, type AuthSessionProfile, type AuthUser, type ClearSessionOptions, type CmsApiEnvelope, type CookieKeyMap, type CreateAuthClientOptions, DEFAULT_AUTH_PATHS, GuestRoute, type GuestRouteProps, IdentifierForm, type IdentifierFormProps, type IdentifierFormValues, type LoginPayload, MOBILE_SEND_OTP_PATH, OtpForm, type OtpFormProps, type OtpFormValues, ProtectedRoute, type ProtectedRouteProps, type SendOtpPayload, type UseAutoLogoutOptions, authCookieKeyList, buildCookieKeys, clearAuthStorage, createAuthClient, getSessionProfile, getTokenExpiry, isLoggedIn, joinPath, persistSessionProfile, useAuth, useAutoLogout };