@spfn/auth 0.2.0-beta.10 → 0.2.0-beta.11
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.
- package/README.md +169 -168
- package/dist/{dto-CRlgoCP5.d.ts → authenticate-CU6_zQaa.d.ts} +182 -182
- package/dist/index.d.ts +143 -130
- package/dist/index.js +24 -1
- package/dist/index.js.map +1 -1
- package/dist/nextjs/server.js +0 -1
- package/dist/nextjs/server.js.map +1 -1
- package/dist/server.d.ts +3 -366
- package/dist/server.js +49 -466
- package/dist/server.js.map +1 -1
- package/package.json +4 -11
package/dist/nextjs/server.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/nextjs/server.ts","../../src/nextjs/guards/require-auth.tsx","../../src/nextjs/session-helpers.ts","../../src/nextjs/guards/require-role.tsx","../../src/nextjs/guards/auth-utils.ts","../../src/nextjs/guards/require-permission.tsx"],"sourcesContent":["import \"server-only\";\n\nexport { RequireAuth } from './guards/require-auth';\nexport type { RequireAuthProps } from './guards/require-auth';\n\nexport { RequireRole } from './guards/require-role';\nexport type { RequireRoleProps } from './guards/require-role';\n\nexport { RequirePermission } from './guards/require-permission';\nexport type { RequirePermissionProps } from './guards/require-permission';\n\nexport { getUserRole, getUserPermissions, hasAnyRole, hasAnyPermission } from './guards/auth-utils';\n\n// Session helpers\nexport {\n saveSession,\n getSession,\n clearSession,\n type SessionData,\n type PublicSession,\n type SaveSessionOptions\n} from './session-helpers';","/**\n * RequireAuth Guard Component\n *\n * Requires user to be authenticated\n */\n\nimport { redirect } from 'next/navigation';\nimport { getSession } from '../session-helpers';\nimport type { ReactNode } from 'react';\n\nexport interface RequireAuthProps\n{\n /**\n * Children to render if authenticated\n */\n children: ReactNode;\n\n /**\n * Path to redirect to if not authenticated\n * @default '/login'\n */\n redirectTo?: string;\n\n /**\n * Fallback UI to show instead of redirecting\n */\n fallback?: ReactNode;\n}\n\n/**\n * Require Authentication Guard\n *\n * Ensures user is logged in before rendering children\n *\n * @example\n * ```tsx\n * <RequireAuth redirectTo=\"/login\">\n * <DashboardContent />\n * </RequireAuth>\n * ```\n *\n * @example With fallback\n * ```tsx\n * <RequireAuth fallback={<LoginPrompt />}>\n * <PrivateContent />\n * </RequireAuth>\n * ```\n */\nexport async function RequireAuth({\n children,\n redirectTo = '/auth/login',\n fallback,\n}: RequireAuthProps)\n{\n const session = await getSession();\n\n if (!session)\n {\n if (fallback)\n {\n return <>{fallback}</>;\n }\n\n redirect(redirectTo);\n }\n\n return <>{children}</>;\n}","/**\n * Session helpers for Next.js\n *\n * Server-side only (uses next/headers)\n */\n\nimport { cookies } from 'next/headers.js';\nimport { sealSession, unsealSession, COOKIE_NAMES, getSessionTtl, parseDuration, type SessionData } from '@spfn/auth/server';\nimport { logger } from '@spfn/core/logger';\n\nexport type { SessionData };\n\n/**\n * Public session information (excludes sensitive data)\n */\nexport interface PublicSession\n{\n /** User ID */\n userId: string;\n}\n\n/**\n * Options for saveSession\n */\nexport interface SaveSessionOptions\n{\n /**\n * Session TTL (time to live)\n *\n * Supports:\n * - Number: seconds (e.g., 2592000)\n * - String: duration format ('30d', '12h', '45m', '3600s')\n *\n * If not provided, uses global configuration:\n * 1. Global config (configureAuth)\n * 2. Environment variable (SPFN_AUTH_SESSION_TTL)\n * 3. Default (7d)\n */\n maxAge?: number | string;\n\n /**\n * Remember me option\n *\n * When true, uses extended session duration (if configured)\n */\n remember?: boolean;\n}\n\n/**\n * Save session to HttpOnly cookie\n *\n * @param data - Session data to save\n * @param options - Session options (maxAge, remember)\n *\n * @example\n * ```typescript\n * // Use global configuration\n * await saveSession(sessionData);\n *\n * // Custom TTL with duration string\n * await saveSession(sessionData, { maxAge: '30d' });\n *\n * // Custom TTL in seconds\n * await saveSession(sessionData, { maxAge: 2592000 });\n *\n * // Remember me\n * await saveSession(sessionData, { remember: true });\n * ```\n */\nexport async function saveSession(\n data: SessionData,\n options?: SaveSessionOptions\n): Promise<void>\n{\n // Calculate maxAge\n let maxAge: number;\n\n if (options?.maxAge !== undefined)\n {\n // Custom maxAge provided\n maxAge = typeof options.maxAge === 'number'\n ? options.maxAge\n : parseDuration(options.maxAge);\n }\n else\n {\n // Use getSessionTtl for consistent configuration\n maxAge = getSessionTtl();\n }\n\n const token = await sealSession(data, maxAge);\n const cookieStore = await cookies();\n\n cookieStore.set(COOKIE_NAMES.SESSION, token, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n path: '/',\n maxAge\n });\n}\n\n/**\n * Get session from HttpOnly cookie\n *\n * Returns public session info only (excludes privateKey, algorithm, keyId)\n */\nexport async function getSession(): Promise<PublicSession | null>\n{\n const cookieStore = await cookies();\n const sessionCookie = cookieStore.get(COOKIE_NAMES.SESSION);\n\n if (!sessionCookie)\n {\n return null;\n }\n\n try\n {\n logger.debug('Validating session cookie', { cookie: sessionCookie.value });\n const session = await unsealSession(sessionCookie.value);\n // Return only public information\n return {\n userId: session.userId,\n };\n }\n catch (error)\n {\n console.error(error);\n\n // Session expired or invalid - log in dev mode\n // Note: Cannot delete cookies in Server Components (read-only)\n // Invalid cookies will be cleaned up on next login/logout via Route Handler or Server Action\n logger.debug('Session validation failed', {\n error: error instanceof Error ? error.message : String(error)\n });\n\n return null;\n }\n}\n\n/**\n * Clear session cookie\n */\nexport async function clearSession(): Promise<void>\n{\n const cookieStore = await cookies();\n cookieStore.delete(COOKIE_NAMES.SESSION);\n cookieStore.delete(COOKIE_NAMES.SESSION_KEY_ID);\n}\n","/**\n * RequireRole Guard Component\n *\n * Requires user to have at least one of the specified roles\n */\n\nimport { redirect } from 'next/navigation';\nimport { getSession } from '../session-helpers';\nimport { hasAnyRole } from './auth-utils';\nimport type { ReactNode } from 'react';\n\nexport interface RequireRoleProps\n{\n /**\n * Required role(s) - user must have at least one\n */\n roles: string | string[];\n\n /**\n * Children to render if user has required role\n */\n children: ReactNode;\n\n /**\n * Path to redirect to if user doesn't have role\n * @default '/unauthorized'\n */\n redirectTo?: string;\n\n /**\n * Fallback UI to show instead of redirecting\n */\n fallback?: ReactNode;\n}\n\n/**\n * Require Role Guard\n *\n * Ensures user has at least one of the specified roles\n *\n * @example Single role\n * ```tsx\n * <RequireRole roles=\"admin\">\n * <AdminPanel />\n * </RequireRole>\n * ```\n *\n * @example Multiple roles (OR condition)\n * ```tsx\n * <RequireRole roles={['admin', 'manager']}>\n * <ManagementDashboard />\n * </RequireRole>\n * ```\n *\n * @example With fallback\n * ```tsx\n * <RequireRole roles=\"admin\" fallback={<AccessDenied />}>\n * <AdminContent />\n * </RequireRole>\n * ```\n */\nexport async function RequireRole({\n roles,\n children,\n redirectTo = '/unauthorized',\n fallback,\n}: RequireRoleProps)\n{\n const session = await getSession();\n\n // Not authenticated\n if (!session)\n {\n if (fallback)\n {\n return <>{fallback}</>;\n }\n\n redirect('/login');\n }\n\n // Normalize to array\n const requiredRoles = Array.isArray(roles) ? roles : [roles];\n\n // Check if user has any of the required roles\n const hasRole = await hasAnyRole(requiredRoles);\n\n if (!hasRole)\n {\n if (fallback)\n {\n return <>{fallback}</>;\n }\n\n redirect(redirectTo);\n }\n\n return <>{children}</>;\n}","/**\n * Server-side auth utilities for guards\n *\n * Uses authApi to check permissions in real-time\n */\n\nimport { authApi } from '@spfn/auth';\nimport { authLogger } from '@spfn/auth/server';\n\n/**\n * Get current auth session with roles and permissions via API\n */\nasync function getAuthSessionData()\n{\n try\n {\n const session = await authApi.getAuthSession.call();\n authLogger.middleware.debug('Auth session retrieved', { name: session.role?.name });\n\n return session;\n }\n catch (error)\n {\n authLogger.middleware.error('Failed to get auth session', { error });\n return null;\n }\n}\n\n/**\n * Get user role\n */\nexport async function getUserRole(): Promise<string | null>\n{\n const session = await getAuthSessionData();\n return session?.role?.name || null;\n}\n\n/**\n * Get user permissions\n */\nexport async function getUserPermissions(): Promise<string[]>\n{\n const session = await getAuthSessionData();\n\n if (!session)\n {\n return [];\n }\n\n return session.permissions?.map((p: any) => p.name) || [];\n}\n\n/**\n * Check if user has any of the specified roles\n */\nexport async function hasAnyRole(requiredRoles: string[]): Promise<boolean>\n{\n const session = await getAuthSessionData();\n if (!session)\n {\n return false;\n }\n\n return requiredRoles.includes(session.role?.name);\n}\n\n/**\n * Check if user has any of the specified permissions\n */\nexport async function hasAnyPermission(requiredPermissions: string[]): Promise<boolean>\n{\n const session = await getAuthSessionData();\n\n if (!session)\n {\n return false;\n }\n\n const userPermissionNames = session.permissions?.map((p: any) => p.name) || [];\n return requiredPermissions.some(permission => userPermissionNames.includes(permission));\n}\n","/**\n * RequirePermission Guard Component\n *\n * Requires user to have at least one of the specified permissions\n */\n\nimport { redirect } from 'next/navigation';\nimport { getSession } from '../session-helpers';\nimport { hasAnyPermission } from './auth-utils';\nimport type { ReactNode } from 'react';\n\nexport interface RequirePermissionProps\n{\n /**\n * Required permission(s) - user must have at least one\n */\n permissions: string | string[];\n\n /**\n * Children to render if user has required permission\n */\n children: ReactNode;\n\n /**\n * Path to redirect to if user doesn't have permission\n * @default '/unauthorized'\n */\n redirectTo?: string;\n\n /**\n * Fallback UI to show instead of redirecting\n */\n fallback?: ReactNode;\n}\n\n/**\n * Require Permission Guard\n *\n * Ensures user has at least one of the specified permissions\n *\n * @example Single permission\n * ```tsx\n * <RequirePermission permissions=\"user:delete\">\n * <DeleteUserButton />\n * </RequirePermission>\n * ```\n *\n * @example Multiple permissions (OR condition)\n * ```tsx\n * <RequirePermission permissions={['user:delete', 'user:update']}>\n * <UserManagement />\n * </RequirePermission>\n * ```\n *\n * @example With fallback\n * ```tsx\n * <RequirePermission permissions=\"project:create\" fallback={<UpgradePrompt />}>\n * <CreateProject />\n * </RequirePermission>\n * ```\n */\nexport async function RequirePermission({\n permissions,\n children,\n redirectTo = '/unauthorized',\n fallback,\n}: RequirePermissionProps)\n{\n const session = await getSession();\n\n // Not authenticated\n if (!session)\n {\n if (fallback)\n {\n return <>{fallback}</>;\n }\n\n redirect('/login');\n }\n\n // Normalize to array\n const requiredPermissions = Array.isArray(permissions) ? permissions : [permissions];\n\n // Check if user has any of the required permissions\n const hasPermission = await hasAnyPermission(requiredPermissions);\n\n if (!hasPermission)\n {\n if (fallback)\n {\n return <>{fallback}</>;\n }\n\n redirect(redirectTo);\n }\n\n return <>{children}</>;\n}"],"mappings":";AAAA,OAAO;;;ACMP,SAAS,gBAAgB;;;ACAzB,SAAS,eAAe;AACxB,SAAS,aAAa,eAAe,cAAc,eAAe,qBAAuC;AACzG,SAAS,cAAc;AA6DvB,eAAsB,YAClB,MACA,SAEJ;AAEI,MAAI;AAEJ,MAAI,SAAS,WAAW,QACxB;AAEI,aAAS,OAAO,QAAQ,WAAW,WAC7B,QAAQ,SACR,cAAc,QAAQ,MAAM;AAAA,EACtC,OAEA;AAEI,aAAS,cAAc;AAAA,EAC3B;AAEA,QAAM,QAAQ,MAAM,YAAY,MAAM,MAAM;AAC5C,QAAM,cAAc,MAAM,QAAQ;AAElC,cAAY,IAAI,aAAa,SAAS,OAAO;AAAA,IACzC,UAAU;AAAA,IACV,QAAQ,QAAQ,IAAI,aAAa;AAAA,IACjC,UAAU;AAAA,IACV,MAAM;AAAA,IACN;AAAA,EACJ,CAAC;AACL;AAOA,eAAsB,aACtB;AACI,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,gBAAgB,YAAY,IAAI,aAAa,OAAO;AAE1D,MAAI,CAAC,eACL;AACI,WAAO;AAAA,EACX;AAEA,MACA;AACI,WAAO,MAAM,6BAA6B,EAAE,QAAQ,cAAc,MAAM,CAAC;AACzE,UAAM,UAAU,MAAM,cAAc,cAAc,KAAK;AAEvD,WAAO;AAAA,MACH,QAAQ,QAAQ;AAAA,IACpB;AAAA,EACJ,SACO,OACP;AACI,YAAQ,MAAM,KAAK;AAKnB,WAAO,MAAM,6BAA6B;AAAA,MACtC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IAChE,CAAC;AAED,WAAO;AAAA,EACX;AACJ;AAKA,eAAsB,eACtB;AACI,QAAM,cAAc,MAAM,QAAQ;AAClC,cAAY,OAAO,aAAa,OAAO;AACvC,cAAY,OAAO,aAAa,cAAc;AAClD;;;ADzFmB;AAZnB,eAAsB,YAAY;AAAA,EAC9B;AAAA,EACA,aAAa;AAAA,EACb;AACJ,GACA;AACI,QAAM,UAAU,MAAM,WAAW;AAEjC,MAAI,CAAC,SACL;AACI,QAAI,UACJ;AACI,aAAO,gCAAG,oBAAS;AAAA,IACvB;AAEA,aAAS,UAAU;AAAA,EACvB;AAEA,SAAO,gCAAG,UAAS;AACvB;;;AE7DA,SAAS,YAAAA,iBAAgB;;;ACAzB,SAAS,eAAe;AACxB,SAAS,kBAAkB;AAK3B,eAAe,qBACf;AACI,MACA;AACI,UAAM,UAAU,MAAM,QAAQ,eAAe,KAAK;AAClD,eAAW,WAAW,MAAM,0BAA0B,EAAE,MAAM,QAAQ,MAAM,KAAK,CAAC;AAElF,WAAO;AAAA,EACX,SACO,OACP;AACI,eAAW,WAAW,MAAM,8BAA8B,EAAE,MAAM,CAAC;AACnE,WAAO;AAAA,EACX;AACJ;AAKA,eAAsB,cACtB;AACI,QAAM,UAAU,MAAM,mBAAmB;AACzC,SAAO,SAAS,MAAM,QAAQ;AAClC;AAKA,eAAsB,qBACtB;AACI,QAAM,UAAU,MAAM,mBAAmB;AAEzC,MAAI,CAAC,SACL;AACI,WAAO,CAAC;AAAA,EACZ;AAEA,SAAO,QAAQ,aAAa,IAAI,CAAC,MAAW,EAAE,IAAI,KAAK,CAAC;AAC5D;AAKA,eAAsB,WAAW,eACjC;AACI,QAAM,UAAU,MAAM,mBAAmB;AACzC,MAAI,CAAC,SACL;AACI,WAAO;AAAA,EACX;AAEA,SAAO,cAAc,SAAS,QAAQ,MAAM,IAAI;AACpD;AAKA,eAAsB,iBAAiB,qBACvC;AACI,QAAM,UAAU,MAAM,mBAAmB;AAEzC,MAAI,CAAC,SACL;AACI,WAAO;AAAA,EACX;AAEA,QAAM,sBAAsB,QAAQ,aAAa,IAAI,CAAC,MAAW,EAAE,IAAI,KAAK,CAAC;AAC7E,SAAO,oBAAoB,KAAK,gBAAc,oBAAoB,SAAS,UAAU,CAAC;AAC1F;;;ADLmB,qBAAAC,WAAA,OAAAC,YAAA;AAdnB,eAAsB,YAAY;AAAA,EAC9B;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AACJ,GACA;AACI,QAAM,UAAU,MAAM,WAAW;AAGjC,MAAI,CAAC,SACL;AACI,QAAI,UACJ;AACI,aAAO,gBAAAA,KAAAD,WAAA,EAAG,oBAAS;AAAA,IACvB;AAEA,IAAAE,UAAS,QAAQ;AAAA,EACrB;AAGA,QAAM,gBAAgB,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAG3D,QAAM,UAAU,MAAM,WAAW,aAAa;AAE9C,MAAI,CAAC,SACL;AACI,QAAI,UACJ;AACI,aAAO,gBAAAD,KAAAD,WAAA,EAAG,oBAAS;AAAA,IACvB;AAEA,IAAAE,UAAS,UAAU;AAAA,EACvB;AAEA,SAAO,gBAAAD,KAAAD,WAAA,EAAG,UAAS;AACvB;;;AE5FA,SAAS,YAAAG,iBAAgB;AAqEN,qBAAAC,WAAA,OAAAC,YAAA;AAdnB,eAAsB,kBAAkB;AAAA,EACpC;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AACJ,GACA;AACI,QAAM,UAAU,MAAM,WAAW;AAGjC,MAAI,CAAC,SACL;AACI,QAAI,UACJ;AACI,aAAO,gBAAAA,KAAAD,WAAA,EAAG,oBAAS;AAAA,IACvB;AAEA,IAAAE,UAAS,QAAQ;AAAA,EACrB;AAGA,QAAM,sBAAsB,MAAM,QAAQ,WAAW,IAAI,cAAc,CAAC,WAAW;AAGnF,QAAM,gBAAgB,MAAM,iBAAiB,mBAAmB;AAEhE,MAAI,CAAC,eACL;AACI,QAAI,UACJ;AACI,aAAO,gBAAAD,KAAAD,WAAA,EAAG,oBAAS;AAAA,IACvB;AAEA,IAAAE,UAAS,UAAU;AAAA,EACvB;AAEA,SAAO,gBAAAD,KAAAD,WAAA,EAAG,UAAS;AACvB;","names":["redirect","Fragment","jsx","redirect","redirect","Fragment","jsx","redirect"]}
|
|
1
|
+
{"version":3,"sources":["../../src/nextjs/server.ts","../../src/nextjs/guards/require-auth.tsx","../../src/nextjs/session-helpers.ts","../../src/nextjs/guards/require-role.tsx","../../src/nextjs/guards/auth-utils.ts","../../src/nextjs/guards/require-permission.tsx"],"sourcesContent":["import \"server-only\";\n\nexport { RequireAuth } from './guards/require-auth';\nexport type { RequireAuthProps } from './guards/require-auth';\n\nexport { RequireRole } from './guards/require-role';\nexport type { RequireRoleProps } from './guards/require-role';\n\nexport { RequirePermission } from './guards/require-permission';\nexport type { RequirePermissionProps } from './guards/require-permission';\n\nexport { getUserRole, getUserPermissions, hasAnyRole, hasAnyPermission } from './guards/auth-utils';\n\n// Session helpers\nexport {\n saveSession,\n getSession,\n clearSession,\n type SessionData,\n type PublicSession,\n type SaveSessionOptions\n} from './session-helpers';","/**\n * RequireAuth Guard Component\n *\n * Requires user to be authenticated\n */\n\nimport { redirect } from 'next/navigation';\nimport { getSession } from '../session-helpers';\nimport type { ReactNode } from 'react';\n\nexport interface RequireAuthProps\n{\n /**\n * Children to render if authenticated\n */\n children: ReactNode;\n\n /**\n * Path to redirect to if not authenticated\n * @default '/login'\n */\n redirectTo?: string;\n\n /**\n * Fallback UI to show instead of redirecting\n */\n fallback?: ReactNode;\n}\n\n/**\n * Require Authentication Guard\n *\n * Ensures user is logged in before rendering children\n *\n * @example\n * ```tsx\n * <RequireAuth redirectTo=\"/login\">\n * <DashboardContent />\n * </RequireAuth>\n * ```\n *\n * @example With fallback\n * ```tsx\n * <RequireAuth fallback={<LoginPrompt />}>\n * <PrivateContent />\n * </RequireAuth>\n * ```\n */\nexport async function RequireAuth({\n children,\n redirectTo = '/auth/login',\n fallback,\n}: RequireAuthProps)\n{\n const session = await getSession();\n\n if (!session)\n {\n if (fallback)\n {\n return <>{fallback}</>;\n }\n\n redirect(redirectTo);\n }\n\n return <>{children}</>;\n}","/**\n * Session helpers for Next.js\n *\n * Server-side only (uses next/headers)\n */\n\nimport { cookies } from 'next/headers.js';\nimport { sealSession, unsealSession, COOKIE_NAMES, getSessionTtl, parseDuration, type SessionData } from '@spfn/auth/server';\nimport { logger } from '@spfn/core/logger';\n\nexport type { SessionData };\n\n/**\n * Public session information (excludes sensitive data)\n */\nexport interface PublicSession\n{\n /** User ID */\n userId: string;\n}\n\n/**\n * Options for saveSession\n */\nexport interface SaveSessionOptions\n{\n /**\n * Session TTL (time to live)\n *\n * Supports:\n * - Number: seconds (e.g., 2592000)\n * - String: duration format ('30d', '12h', '45m', '3600s')\n *\n * If not provided, uses global configuration:\n * 1. Global config (configureAuth)\n * 2. Environment variable (SPFN_AUTH_SESSION_TTL)\n * 3. Default (7d)\n */\n maxAge?: number | string;\n\n /**\n * Remember me option\n *\n * When true, uses extended session duration (if configured)\n */\n remember?: boolean;\n}\n\n/**\n * Save session to HttpOnly cookie\n *\n * @param data - Session data to save\n * @param options - Session options (maxAge, remember)\n *\n * @example\n * ```typescript\n * // Use global configuration\n * await saveSession(sessionData);\n *\n * // Custom TTL with duration string\n * await saveSession(sessionData, { maxAge: '30d' });\n *\n * // Custom TTL in seconds\n * await saveSession(sessionData, { maxAge: 2592000 });\n *\n * // Remember me\n * await saveSession(sessionData, { remember: true });\n * ```\n */\nexport async function saveSession(\n data: SessionData,\n options?: SaveSessionOptions\n): Promise<void>\n{\n // Calculate maxAge\n let maxAge: number;\n\n if (options?.maxAge !== undefined)\n {\n // Custom maxAge provided\n maxAge = typeof options.maxAge === 'number'\n ? options.maxAge\n : parseDuration(options.maxAge);\n }\n else\n {\n // Use getSessionTtl for consistent configuration\n maxAge = getSessionTtl();\n }\n\n const token = await sealSession(data, maxAge);\n const cookieStore = await cookies();\n\n cookieStore.set(COOKIE_NAMES.SESSION, token, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n path: '/',\n maxAge\n });\n}\n\n/**\n * Get session from HttpOnly cookie\n *\n * Returns public session info only (excludes privateKey, algorithm, keyId)\n */\nexport async function getSession(): Promise<PublicSession | null>\n{\n const cookieStore = await cookies();\n const sessionCookie = cookieStore.get(COOKIE_NAMES.SESSION);\n\n if (!sessionCookie)\n {\n return null;\n }\n\n try\n {\n logger.debug('Validating session cookie', { cookie: sessionCookie.value });\n const session = await unsealSession(sessionCookie.value);\n // Return only public information\n return {\n userId: session.userId,\n };\n }\n catch (error)\n {\n // Session expired or invalid\n // Note: Cannot delete cookies in Server Components (read-only)\n // Use validateSessionMiddleware() in Next.js middleware for automatic cleanup\n logger.debug('Session validation failed', {\n error: error instanceof Error ? error.message : String(error)\n });\n\n return null;\n }\n}\n\n/**\n * Clear session cookie\n */\nexport async function clearSession(): Promise<void>\n{\n const cookieStore = await cookies();\n cookieStore.delete(COOKIE_NAMES.SESSION);\n cookieStore.delete(COOKIE_NAMES.SESSION_KEY_ID);\n}\n","/**\n * RequireRole Guard Component\n *\n * Requires user to have at least one of the specified roles\n */\n\nimport { redirect } from 'next/navigation';\nimport { getSession } from '../session-helpers';\nimport { hasAnyRole } from './auth-utils';\nimport type { ReactNode } from 'react';\n\nexport interface RequireRoleProps\n{\n /**\n * Required role(s) - user must have at least one\n */\n roles: string | string[];\n\n /**\n * Children to render if user has required role\n */\n children: ReactNode;\n\n /**\n * Path to redirect to if user doesn't have role\n * @default '/unauthorized'\n */\n redirectTo?: string;\n\n /**\n * Fallback UI to show instead of redirecting\n */\n fallback?: ReactNode;\n}\n\n/**\n * Require Role Guard\n *\n * Ensures user has at least one of the specified roles\n *\n * @example Single role\n * ```tsx\n * <RequireRole roles=\"admin\">\n * <AdminPanel />\n * </RequireRole>\n * ```\n *\n * @example Multiple roles (OR condition)\n * ```tsx\n * <RequireRole roles={['admin', 'manager']}>\n * <ManagementDashboard />\n * </RequireRole>\n * ```\n *\n * @example With fallback\n * ```tsx\n * <RequireRole roles=\"admin\" fallback={<AccessDenied />}>\n * <AdminContent />\n * </RequireRole>\n * ```\n */\nexport async function RequireRole({\n roles,\n children,\n redirectTo = '/unauthorized',\n fallback,\n}: RequireRoleProps)\n{\n const session = await getSession();\n\n // Not authenticated\n if (!session)\n {\n if (fallback)\n {\n return <>{fallback}</>;\n }\n\n redirect('/login');\n }\n\n // Normalize to array\n const requiredRoles = Array.isArray(roles) ? roles : [roles];\n\n // Check if user has any of the required roles\n const hasRole = await hasAnyRole(requiredRoles);\n\n if (!hasRole)\n {\n if (fallback)\n {\n return <>{fallback}</>;\n }\n\n redirect(redirectTo);\n }\n\n return <>{children}</>;\n}","/**\n * Server-side auth utilities for guards\n *\n * Uses authApi to check permissions in real-time\n */\n\nimport { authApi } from '@spfn/auth';\nimport { authLogger } from '@spfn/auth/server';\n\n/**\n * Get current auth session with roles and permissions via API\n */\nasync function getAuthSessionData()\n{\n try\n {\n const session = await authApi.getAuthSession.call();\n authLogger.middleware.debug('Auth session retrieved', { name: session.role?.name });\n\n return session;\n }\n catch (error)\n {\n authLogger.middleware.error('Failed to get auth session', { error });\n return null;\n }\n}\n\n/**\n * Get user role\n */\nexport async function getUserRole(): Promise<string | null>\n{\n const session = await getAuthSessionData();\n return session?.role?.name || null;\n}\n\n/**\n * Get user permissions\n */\nexport async function getUserPermissions(): Promise<string[]>\n{\n const session = await getAuthSessionData();\n\n if (!session)\n {\n return [];\n }\n\n return session.permissions?.map((p: any) => p.name) || [];\n}\n\n/**\n * Check if user has any of the specified roles\n */\nexport async function hasAnyRole(requiredRoles: string[]): Promise<boolean>\n{\n const session = await getAuthSessionData();\n if (!session)\n {\n return false;\n }\n\n return requiredRoles.includes(session.role?.name);\n}\n\n/**\n * Check if user has any of the specified permissions\n */\nexport async function hasAnyPermission(requiredPermissions: string[]): Promise<boolean>\n{\n const session = await getAuthSessionData();\n\n if (!session)\n {\n return false;\n }\n\n const userPermissionNames = session.permissions?.map((p: any) => p.name) || [];\n return requiredPermissions.some(permission => userPermissionNames.includes(permission));\n}\n","/**\n * RequirePermission Guard Component\n *\n * Requires user to have at least one of the specified permissions\n */\n\nimport { redirect } from 'next/navigation';\nimport { getSession } from '../session-helpers';\nimport { hasAnyPermission } from './auth-utils';\nimport type { ReactNode } from 'react';\n\nexport interface RequirePermissionProps\n{\n /**\n * Required permission(s) - user must have at least one\n */\n permissions: string | string[];\n\n /**\n * Children to render if user has required permission\n */\n children: ReactNode;\n\n /**\n * Path to redirect to if user doesn't have permission\n * @default '/unauthorized'\n */\n redirectTo?: string;\n\n /**\n * Fallback UI to show instead of redirecting\n */\n fallback?: ReactNode;\n}\n\n/**\n * Require Permission Guard\n *\n * Ensures user has at least one of the specified permissions\n *\n * @example Single permission\n * ```tsx\n * <RequirePermission permissions=\"user:delete\">\n * <DeleteUserButton />\n * </RequirePermission>\n * ```\n *\n * @example Multiple permissions (OR condition)\n * ```tsx\n * <RequirePermission permissions={['user:delete', 'user:update']}>\n * <UserManagement />\n * </RequirePermission>\n * ```\n *\n * @example With fallback\n * ```tsx\n * <RequirePermission permissions=\"project:create\" fallback={<UpgradePrompt />}>\n * <CreateProject />\n * </RequirePermission>\n * ```\n */\nexport async function RequirePermission({\n permissions,\n children,\n redirectTo = '/unauthorized',\n fallback,\n}: RequirePermissionProps)\n{\n const session = await getSession();\n\n // Not authenticated\n if (!session)\n {\n if (fallback)\n {\n return <>{fallback}</>;\n }\n\n redirect('/login');\n }\n\n // Normalize to array\n const requiredPermissions = Array.isArray(permissions) ? permissions : [permissions];\n\n // Check if user has any of the required permissions\n const hasPermission = await hasAnyPermission(requiredPermissions);\n\n if (!hasPermission)\n {\n if (fallback)\n {\n return <>{fallback}</>;\n }\n\n redirect(redirectTo);\n }\n\n return <>{children}</>;\n}"],"mappings":";AAAA,OAAO;;;ACMP,SAAS,gBAAgB;;;ACAzB,SAAS,eAAe;AACxB,SAAS,aAAa,eAAe,cAAc,eAAe,qBAAuC;AACzG,SAAS,cAAc;AA6DvB,eAAsB,YAClB,MACA,SAEJ;AAEI,MAAI;AAEJ,MAAI,SAAS,WAAW,QACxB;AAEI,aAAS,OAAO,QAAQ,WAAW,WAC7B,QAAQ,SACR,cAAc,QAAQ,MAAM;AAAA,EACtC,OAEA;AAEI,aAAS,cAAc;AAAA,EAC3B;AAEA,QAAM,QAAQ,MAAM,YAAY,MAAM,MAAM;AAC5C,QAAM,cAAc,MAAM,QAAQ;AAElC,cAAY,IAAI,aAAa,SAAS,OAAO;AAAA,IACzC,UAAU;AAAA,IACV,QAAQ,QAAQ,IAAI,aAAa;AAAA,IACjC,UAAU;AAAA,IACV,MAAM;AAAA,IACN;AAAA,EACJ,CAAC;AACL;AAOA,eAAsB,aACtB;AACI,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,gBAAgB,YAAY,IAAI,aAAa,OAAO;AAE1D,MAAI,CAAC,eACL;AACI,WAAO;AAAA,EACX;AAEA,MACA;AACI,WAAO,MAAM,6BAA6B,EAAE,QAAQ,cAAc,MAAM,CAAC;AACzE,UAAM,UAAU,MAAM,cAAc,cAAc,KAAK;AAEvD,WAAO;AAAA,MACH,QAAQ,QAAQ;AAAA,IACpB;AAAA,EACJ,SACO,OACP;AAII,WAAO,MAAM,6BAA6B;AAAA,MACtC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IAChE,CAAC;AAED,WAAO;AAAA,EACX;AACJ;AAKA,eAAsB,eACtB;AACI,QAAM,cAAc,MAAM,QAAQ;AAClC,cAAY,OAAO,aAAa,OAAO;AACvC,cAAY,OAAO,aAAa,cAAc;AAClD;;;ADvFmB;AAZnB,eAAsB,YAAY;AAAA,EAC9B;AAAA,EACA,aAAa;AAAA,EACb;AACJ,GACA;AACI,QAAM,UAAU,MAAM,WAAW;AAEjC,MAAI,CAAC,SACL;AACI,QAAI,UACJ;AACI,aAAO,gCAAG,oBAAS;AAAA,IACvB;AAEA,aAAS,UAAU;AAAA,EACvB;AAEA,SAAO,gCAAG,UAAS;AACvB;;;AE7DA,SAAS,YAAAA,iBAAgB;;;ACAzB,SAAS,eAAe;AACxB,SAAS,kBAAkB;AAK3B,eAAe,qBACf;AACI,MACA;AACI,UAAM,UAAU,MAAM,QAAQ,eAAe,KAAK;AAClD,eAAW,WAAW,MAAM,0BAA0B,EAAE,MAAM,QAAQ,MAAM,KAAK,CAAC;AAElF,WAAO;AAAA,EACX,SACO,OACP;AACI,eAAW,WAAW,MAAM,8BAA8B,EAAE,MAAM,CAAC;AACnE,WAAO;AAAA,EACX;AACJ;AAKA,eAAsB,cACtB;AACI,QAAM,UAAU,MAAM,mBAAmB;AACzC,SAAO,SAAS,MAAM,QAAQ;AAClC;AAKA,eAAsB,qBACtB;AACI,QAAM,UAAU,MAAM,mBAAmB;AAEzC,MAAI,CAAC,SACL;AACI,WAAO,CAAC;AAAA,EACZ;AAEA,SAAO,QAAQ,aAAa,IAAI,CAAC,MAAW,EAAE,IAAI,KAAK,CAAC;AAC5D;AAKA,eAAsB,WAAW,eACjC;AACI,QAAM,UAAU,MAAM,mBAAmB;AACzC,MAAI,CAAC,SACL;AACI,WAAO;AAAA,EACX;AAEA,SAAO,cAAc,SAAS,QAAQ,MAAM,IAAI;AACpD;AAKA,eAAsB,iBAAiB,qBACvC;AACI,QAAM,UAAU,MAAM,mBAAmB;AAEzC,MAAI,CAAC,SACL;AACI,WAAO;AAAA,EACX;AAEA,QAAM,sBAAsB,QAAQ,aAAa,IAAI,CAAC,MAAW,EAAE,IAAI,KAAK,CAAC;AAC7E,SAAO,oBAAoB,KAAK,gBAAc,oBAAoB,SAAS,UAAU,CAAC;AAC1F;;;ADLmB,qBAAAC,WAAA,OAAAC,YAAA;AAdnB,eAAsB,YAAY;AAAA,EAC9B;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AACJ,GACA;AACI,QAAM,UAAU,MAAM,WAAW;AAGjC,MAAI,CAAC,SACL;AACI,QAAI,UACJ;AACI,aAAO,gBAAAA,KAAAD,WAAA,EAAG,oBAAS;AAAA,IACvB;AAEA,IAAAE,UAAS,QAAQ;AAAA,EACrB;AAGA,QAAM,gBAAgB,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAG3D,QAAM,UAAU,MAAM,WAAW,aAAa;AAE9C,MAAI,CAAC,SACL;AACI,QAAI,UACJ;AACI,aAAO,gBAAAD,KAAAD,WAAA,EAAG,oBAAS;AAAA,IACvB;AAEA,IAAAE,UAAS,UAAU;AAAA,EACvB;AAEA,SAAO,gBAAAD,KAAAD,WAAA,EAAG,UAAS;AACvB;;;AE5FA,SAAS,YAAAG,iBAAgB;AAqEN,qBAAAC,WAAA,OAAAC,YAAA;AAdnB,eAAsB,kBAAkB;AAAA,EACpC;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AACJ,GACA;AACI,QAAM,UAAU,MAAM,WAAW;AAGjC,MAAI,CAAC,SACL;AACI,QAAI,UACJ;AACI,aAAO,gBAAAA,KAAAD,WAAA,EAAG,oBAAS;AAAA,IACvB;AAEA,IAAAE,UAAS,QAAQ;AAAA,EACrB;AAGA,QAAM,sBAAsB,MAAM,QAAQ,WAAW,IAAI,cAAc,CAAC,WAAW;AAGnF,QAAM,gBAAgB,MAAM,iBAAiB,mBAAmB;AAEhE,MAAI,CAAC,eACL;AACI,QAAI,UACJ;AACI,aAAO,gBAAAD,KAAAD,WAAA,EAAG,oBAAS;AAAA,IACvB;AAEA,IAAAE,UAAS,UAAU;AAAA,EACvB;AAEA,SAAO,gBAAAD,KAAAD,WAAA,EAAG,UAAS;AACvB;","names":["redirect","Fragment","jsx","redirect","redirect","Fragment","jsx","redirect"]}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { k as AuthInitOptions, l as KeyAlgorithmType, n as InvitationStatus, f as VerificationPurpose, j as PermissionCategory, q as AuthContext } from './
|
|
2
|
-
export { B as ChangePasswordParams, w as CheckAccountExistsParams, C as CheckAccountExistsResult, X as EmailSchema, I as INVITATION_STATUSES, K as KEY_ALGORITHM, y as LoginParams, L as LoginResult, z as LogoutParams, Z as PasswordSchema, Y as PhoneSchema, x as RegisterParams, O as RegisterPublicKeyParams,
|
|
1
|
+
import { k as AuthInitOptions, l as KeyAlgorithmType, n as InvitationStatus, f as VerificationPurpose, j as PermissionCategory, q as AuthContext } from './authenticate-CU6_zQaa.js';
|
|
2
|
+
export { B as ChangePasswordParams, w as CheckAccountExistsParams, C as CheckAccountExistsResult, X as EmailSchema, I as INVITATION_STATUSES, K as KEY_ALGORITHM, y as LoginParams, L as LoginResult, z as LogoutParams, Z as PasswordSchema, Y as PhoneSchema, x as RegisterParams, O as RegisterPublicKeyParams, a as RegisterResult, T as RevokeKeyParams, Q as RotateKeyParams, b as RotateKeyResult, e as SOCIAL_PROVIDERS, F as SendVerificationCodeParams, S as SendVerificationCodeResult, p as SocialProvider, _ as TargetTypeSchema, d as USER_STATUSES, o as UserStatus, h as VERIFICATION_PURPOSES, g as VERIFICATION_TARGET_TYPES, $ as VerificationPurposeSchema, V as VerificationTargetType, G as VerifyCodeParams, H as VerifyCodeResult, m as authRouter, W as authenticate, v as changePasswordService, r as checkAccountExistsService, t as loginService, u as logoutService, J as registerPublicKeyService, s as registerService, N as revokeKeyService, M as rotateKeyService, D as sendVerificationCodeService, E as verifyCodeService } from './authenticate-CU6_zQaa.js';
|
|
3
3
|
import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
|
|
4
4
|
import { UserProfile as UserProfile$1, ProfileInfo } from '@spfn/auth';
|
|
5
5
|
import { BaseRepository } from '@spfn/core/db';
|
|
@@ -1326,369 +1326,6 @@ declare function getUserProfileService(userId: string | number | bigint): Promis
|
|
|
1326
1326
|
*/
|
|
1327
1327
|
declare function updateUserProfileService(userId: string | number | bigint, params: UpdateProfileParams): Promise<ProfileInfo>;
|
|
1328
1328
|
|
|
1329
|
-
/**
|
|
1330
|
-
* @spfn/auth - Email Template Types
|
|
1331
|
-
*
|
|
1332
|
-
* Type definitions for customizable email templates
|
|
1333
|
-
*/
|
|
1334
|
-
/**
|
|
1335
|
-
* Common template result
|
|
1336
|
-
*/
|
|
1337
|
-
interface EmailTemplateResult {
|
|
1338
|
-
subject: string;
|
|
1339
|
-
text: string;
|
|
1340
|
-
html: string;
|
|
1341
|
-
}
|
|
1342
|
-
/**
|
|
1343
|
-
* Verification code template parameters
|
|
1344
|
-
*/
|
|
1345
|
-
interface VerificationCodeParams {
|
|
1346
|
-
code: string;
|
|
1347
|
-
purpose: 'registration' | 'login' | 'password_reset' | string;
|
|
1348
|
-
expiresInMinutes?: number;
|
|
1349
|
-
appName?: string;
|
|
1350
|
-
}
|
|
1351
|
-
/**
|
|
1352
|
-
* Email template provider interface
|
|
1353
|
-
*
|
|
1354
|
-
* Implement this interface to create custom email templates
|
|
1355
|
-
*
|
|
1356
|
-
* @example
|
|
1357
|
-
* ```typescript
|
|
1358
|
-
* import { registerEmailTemplates } from '@spfn/auth/server';
|
|
1359
|
-
*
|
|
1360
|
-
* registerEmailTemplates({
|
|
1361
|
-
* verificationCode: (params) => ({
|
|
1362
|
-
* subject: 'Your Code',
|
|
1363
|
-
* text: `Code: ${params.code}`,
|
|
1364
|
-
* html: `<h1>Code: ${params.code}</h1>`,
|
|
1365
|
-
* }),
|
|
1366
|
-
* });
|
|
1367
|
-
* ```
|
|
1368
|
-
*/
|
|
1369
|
-
interface EmailTemplateProvider {
|
|
1370
|
-
/**
|
|
1371
|
-
* Verification code email template
|
|
1372
|
-
*/
|
|
1373
|
-
verificationCode?(params: VerificationCodeParams): EmailTemplateResult;
|
|
1374
|
-
/**
|
|
1375
|
-
* Welcome email template (after registration)
|
|
1376
|
-
*/
|
|
1377
|
-
welcome?(params: {
|
|
1378
|
-
email: string;
|
|
1379
|
-
appName?: string;
|
|
1380
|
-
}): EmailTemplateResult;
|
|
1381
|
-
/**
|
|
1382
|
-
* Password reset email template
|
|
1383
|
-
*/
|
|
1384
|
-
passwordReset?(params: {
|
|
1385
|
-
resetLink: string;
|
|
1386
|
-
expiresInMinutes?: number;
|
|
1387
|
-
appName?: string;
|
|
1388
|
-
}): EmailTemplateResult;
|
|
1389
|
-
/**
|
|
1390
|
-
* Invitation email template
|
|
1391
|
-
*/
|
|
1392
|
-
invitation?(params: {
|
|
1393
|
-
inviteLink: string;
|
|
1394
|
-
inviterName?: string;
|
|
1395
|
-
roleName?: string;
|
|
1396
|
-
appName?: string;
|
|
1397
|
-
}): EmailTemplateResult;
|
|
1398
|
-
}
|
|
1399
|
-
|
|
1400
|
-
/**
|
|
1401
|
-
* @spfn/auth - Email Template Registry
|
|
1402
|
-
*
|
|
1403
|
-
* Manages custom email template registration and fallback to defaults
|
|
1404
|
-
*/
|
|
1405
|
-
|
|
1406
|
-
/**
|
|
1407
|
-
* Register custom email templates
|
|
1408
|
-
*
|
|
1409
|
-
* Templates not provided will fall back to defaults
|
|
1410
|
-
*
|
|
1411
|
-
* @param templates - Custom template implementations
|
|
1412
|
-
*
|
|
1413
|
-
* @example
|
|
1414
|
-
* ```typescript
|
|
1415
|
-
* import { registerEmailTemplates } from '@spfn/auth/server';
|
|
1416
|
-
*
|
|
1417
|
-
* // Override verification code template with custom design
|
|
1418
|
-
* registerEmailTemplates({
|
|
1419
|
-
* verificationCode: ({ code, purpose, expiresInMinutes }) => ({
|
|
1420
|
-
* subject: `[MyApp] Your verification code`,
|
|
1421
|
-
* text: `Your code is: ${code}`,
|
|
1422
|
-
* html: `
|
|
1423
|
-
* <div style="font-family: Arial;">
|
|
1424
|
-
* <h1>Welcome to MyApp!</h1>
|
|
1425
|
-
* <p>Your code: <strong>${code}</strong></p>
|
|
1426
|
-
* </div>
|
|
1427
|
-
* `,
|
|
1428
|
-
* }),
|
|
1429
|
-
* });
|
|
1430
|
-
* ```
|
|
1431
|
-
*/
|
|
1432
|
-
declare function registerEmailTemplates(templates: Partial<EmailTemplateProvider>): void;
|
|
1433
|
-
/**
|
|
1434
|
-
* Get verification code template
|
|
1435
|
-
*
|
|
1436
|
-
* Uses custom template if registered, otherwise falls back to default
|
|
1437
|
-
*/
|
|
1438
|
-
declare function getVerificationCodeTemplate(params: VerificationCodeParams): EmailTemplateResult;
|
|
1439
|
-
/**
|
|
1440
|
-
* Get welcome template
|
|
1441
|
-
*/
|
|
1442
|
-
declare function getWelcomeTemplate(params: {
|
|
1443
|
-
email: string;
|
|
1444
|
-
appName?: string;
|
|
1445
|
-
}): EmailTemplateResult;
|
|
1446
|
-
/**
|
|
1447
|
-
* Get password reset template
|
|
1448
|
-
*/
|
|
1449
|
-
declare function getPasswordResetTemplate(params: {
|
|
1450
|
-
resetLink: string;
|
|
1451
|
-
expiresInMinutes?: number;
|
|
1452
|
-
appName?: string;
|
|
1453
|
-
}): EmailTemplateResult;
|
|
1454
|
-
/**
|
|
1455
|
-
* Get invitation template
|
|
1456
|
-
*/
|
|
1457
|
-
declare function getInvitationTemplate(params: {
|
|
1458
|
-
inviteLink: string;
|
|
1459
|
-
inviterName?: string;
|
|
1460
|
-
roleName?: string;
|
|
1461
|
-
appName?: string;
|
|
1462
|
-
}): EmailTemplateResult;
|
|
1463
|
-
|
|
1464
|
-
/**
|
|
1465
|
-
* @spfn/auth - Email Service Types
|
|
1466
|
-
*
|
|
1467
|
-
* Type definitions for email sending service
|
|
1468
|
-
*/
|
|
1469
|
-
/**
|
|
1470
|
-
* Parameters for sending email
|
|
1471
|
-
*/
|
|
1472
|
-
interface SendEmailParams {
|
|
1473
|
-
/**
|
|
1474
|
-
* Recipient email address
|
|
1475
|
-
*/
|
|
1476
|
-
to: string;
|
|
1477
|
-
/**
|
|
1478
|
-
* Email subject
|
|
1479
|
-
*/
|
|
1480
|
-
subject: string;
|
|
1481
|
-
/**
|
|
1482
|
-
* Plain text content
|
|
1483
|
-
*/
|
|
1484
|
-
text?: string;
|
|
1485
|
-
/**
|
|
1486
|
-
* HTML content
|
|
1487
|
-
*/
|
|
1488
|
-
html?: string;
|
|
1489
|
-
/**
|
|
1490
|
-
* Purpose of the email (for logging)
|
|
1491
|
-
*/
|
|
1492
|
-
purpose?: string;
|
|
1493
|
-
}
|
|
1494
|
-
/**
|
|
1495
|
-
* Result of sending email
|
|
1496
|
-
*/
|
|
1497
|
-
interface SendEmailResult {
|
|
1498
|
-
/**
|
|
1499
|
-
* Whether email was sent successfully
|
|
1500
|
-
*/
|
|
1501
|
-
success: boolean;
|
|
1502
|
-
/**
|
|
1503
|
-
* Message ID from email provider (if successful)
|
|
1504
|
-
*/
|
|
1505
|
-
messageId?: string;
|
|
1506
|
-
/**
|
|
1507
|
-
* Error message (if failed)
|
|
1508
|
-
*/
|
|
1509
|
-
error?: string;
|
|
1510
|
-
}
|
|
1511
|
-
/**
|
|
1512
|
-
* Email Provider Interface
|
|
1513
|
-
*
|
|
1514
|
-
* Implement this interface to create custom email providers
|
|
1515
|
-
*
|
|
1516
|
-
* @example
|
|
1517
|
-
* ```typescript
|
|
1518
|
-
* import { EmailProvider, registerEmailProvider } from '@spfn/auth/server/services/email';
|
|
1519
|
-
*
|
|
1520
|
-
* const sendgridProvider: EmailProvider = {
|
|
1521
|
-
* name: 'sendgrid',
|
|
1522
|
-
* sendEmail: async (params) => {
|
|
1523
|
-
* // Your SendGrid implementation
|
|
1524
|
-
* return { success: true, messageId: '...' };
|
|
1525
|
-
* }
|
|
1526
|
-
* };
|
|
1527
|
-
*
|
|
1528
|
-
* registerEmailProvider(sendgridProvider);
|
|
1529
|
-
* ```
|
|
1530
|
-
*/
|
|
1531
|
-
interface EmailProvider {
|
|
1532
|
-
/**
|
|
1533
|
-
* Provider name (e.g., 'aws-ses', 'sendgrid', 'custom')
|
|
1534
|
-
*/
|
|
1535
|
-
name: string;
|
|
1536
|
-
/**
|
|
1537
|
-
* Send email via this provider
|
|
1538
|
-
*
|
|
1539
|
-
* @param params - Email parameters
|
|
1540
|
-
* @returns Send result
|
|
1541
|
-
*/
|
|
1542
|
-
sendEmail(params: SendEmailParams): Promise<SendEmailResult>;
|
|
1543
|
-
}
|
|
1544
|
-
|
|
1545
|
-
/**
|
|
1546
|
-
* @spfn/auth - Email Provider Management
|
|
1547
|
-
*
|
|
1548
|
-
* Manages email provider registration and fallback behavior
|
|
1549
|
-
*/
|
|
1550
|
-
|
|
1551
|
-
/**
|
|
1552
|
-
* Register a custom email provider
|
|
1553
|
-
*
|
|
1554
|
-
* @param provider - Custom email provider implementation
|
|
1555
|
-
*
|
|
1556
|
-
* @example
|
|
1557
|
-
* ```typescript
|
|
1558
|
-
* import { registerEmailProvider } from '@spfn/auth/server/services/email';
|
|
1559
|
-
*
|
|
1560
|
-
* const sendgridProvider = {
|
|
1561
|
-
* name: 'sendgrid',
|
|
1562
|
-
* sendEmail: async (params) => {
|
|
1563
|
-
* // SendGrid implementation
|
|
1564
|
-
* return { success: true, messageId: '...' };
|
|
1565
|
-
* }
|
|
1566
|
-
* };
|
|
1567
|
-
*
|
|
1568
|
-
* registerEmailProvider(sendgridProvider);
|
|
1569
|
-
* ```
|
|
1570
|
-
*/
|
|
1571
|
-
declare function registerEmailProvider(provider: EmailProvider): void;
|
|
1572
|
-
/**
|
|
1573
|
-
* Send email using the registered provider
|
|
1574
|
-
*
|
|
1575
|
-
* Falls back to development mode (console only) if no provider is registered
|
|
1576
|
-
*
|
|
1577
|
-
* @param params - Email parameters
|
|
1578
|
-
* @returns Send result
|
|
1579
|
-
*/
|
|
1580
|
-
declare function sendEmail(params: SendEmailParams): Promise<SendEmailResult>;
|
|
1581
|
-
|
|
1582
|
-
/**
|
|
1583
|
-
* @spfn/auth - SMS Service Types
|
|
1584
|
-
*
|
|
1585
|
-
* Type definitions for SMS sending service
|
|
1586
|
-
*/
|
|
1587
|
-
/**
|
|
1588
|
-
* Parameters for sending SMS
|
|
1589
|
-
*/
|
|
1590
|
-
interface SendSMSParams {
|
|
1591
|
-
/**
|
|
1592
|
-
* Phone number in E.164 format (e.g., +821012345678)
|
|
1593
|
-
*/
|
|
1594
|
-
phone: string;
|
|
1595
|
-
/**
|
|
1596
|
-
* SMS message content
|
|
1597
|
-
*/
|
|
1598
|
-
message: string;
|
|
1599
|
-
/**
|
|
1600
|
-
* Purpose of the SMS (for logging)
|
|
1601
|
-
*/
|
|
1602
|
-
purpose?: string;
|
|
1603
|
-
}
|
|
1604
|
-
/**
|
|
1605
|
-
* Result of sending SMS
|
|
1606
|
-
*/
|
|
1607
|
-
interface SendSMSResult {
|
|
1608
|
-
/**
|
|
1609
|
-
* Whether SMS was sent successfully
|
|
1610
|
-
*/
|
|
1611
|
-
success: boolean;
|
|
1612
|
-
/**
|
|
1613
|
-
* Message ID from SMS provider (if successful)
|
|
1614
|
-
*/
|
|
1615
|
-
messageId?: string;
|
|
1616
|
-
/**
|
|
1617
|
-
* Error message (if failed)
|
|
1618
|
-
*/
|
|
1619
|
-
error?: string;
|
|
1620
|
-
}
|
|
1621
|
-
/**
|
|
1622
|
-
* SMS Provider Interface
|
|
1623
|
-
*
|
|
1624
|
-
* Implement this interface to create custom SMS providers
|
|
1625
|
-
*
|
|
1626
|
-
* @example
|
|
1627
|
-
* ```typescript
|
|
1628
|
-
* import { SMSProvider, registerSMSProvider } from '@spfn/auth/server/services/sms';
|
|
1629
|
-
*
|
|
1630
|
-
* const twilioProvider: SMSProvider = {
|
|
1631
|
-
* name: 'twilio',
|
|
1632
|
-
* sendSMS: async (params) => {
|
|
1633
|
-
* // Your Twilio implementation
|
|
1634
|
-
* return { success: true, messageId: '...' };
|
|
1635
|
-
* }
|
|
1636
|
-
* };
|
|
1637
|
-
*
|
|
1638
|
-
* registerSMSProvider(twilioProvider);
|
|
1639
|
-
* ```
|
|
1640
|
-
*/
|
|
1641
|
-
interface SMSProvider {
|
|
1642
|
-
/**
|
|
1643
|
-
* Provider name (e.g., 'aws-sns', 'twilio', 'custom')
|
|
1644
|
-
*/
|
|
1645
|
-
name: string;
|
|
1646
|
-
/**
|
|
1647
|
-
* Send SMS via this provider
|
|
1648
|
-
*
|
|
1649
|
-
* @param params - SMS parameters
|
|
1650
|
-
* @returns Send result
|
|
1651
|
-
*/
|
|
1652
|
-
sendSMS(params: SendSMSParams): Promise<SendSMSResult>;
|
|
1653
|
-
}
|
|
1654
|
-
|
|
1655
|
-
/**
|
|
1656
|
-
* @spfn/auth - SMS Provider Management
|
|
1657
|
-
*
|
|
1658
|
-
* Manages SMS provider registration and fallback behavior
|
|
1659
|
-
*/
|
|
1660
|
-
|
|
1661
|
-
/**
|
|
1662
|
-
* Register a custom SMS provider
|
|
1663
|
-
*
|
|
1664
|
-
* @param provider - Custom SMS provider implementation
|
|
1665
|
-
*
|
|
1666
|
-
* @example
|
|
1667
|
-
* ```typescript
|
|
1668
|
-
* import { registerSMSProvider } from '@spfn/auth/server/services/sms';
|
|
1669
|
-
*
|
|
1670
|
-
* const twilioProvider = {
|
|
1671
|
-
* name: 'twilio',
|
|
1672
|
-
* sendSMS: async (params) => {
|
|
1673
|
-
* // Twilio implementation
|
|
1674
|
-
* return { success: true, messageId: '...' };
|
|
1675
|
-
* }
|
|
1676
|
-
* };
|
|
1677
|
-
*
|
|
1678
|
-
* registerSMSProvider(twilioProvider);
|
|
1679
|
-
* ```
|
|
1680
|
-
*/
|
|
1681
|
-
declare function registerSMSProvider(provider: SMSProvider): void;
|
|
1682
|
-
/**
|
|
1683
|
-
* Send SMS using the registered provider
|
|
1684
|
-
*
|
|
1685
|
-
* Falls back to development mode (console only) if no provider is registered
|
|
1686
|
-
*
|
|
1687
|
-
* @param params - SMS parameters
|
|
1688
|
-
* @returns Send result
|
|
1689
|
-
*/
|
|
1690
|
-
declare function sendSMS(params: SendSMSParams): Promise<SendSMSResult>;
|
|
1691
|
-
|
|
1692
1329
|
/**
|
|
1693
1330
|
* @spfn/auth - Database Schema Definition
|
|
1694
1331
|
*
|
|
@@ -5199,4 +4836,4 @@ interface AuthLifecycleConfig {
|
|
|
5199
4836
|
*/
|
|
5200
4837
|
declare function createAuthLifecycle(options?: AuthInitOptions): AuthLifecycleConfig;
|
|
5201
4838
|
|
|
5202
|
-
export { type AuthConfig, AuthContext, COOKIE_NAMES, type
|
|
4839
|
+
export { type AuthConfig, AuthContext, COOKIE_NAMES, type Invitation, InvitationStatus, InvitationsRepository, KeyAlgorithmType, type KeyPair, KeysRepository, type NewInvitation, type NewPermission, type NewPermissionEntity, type NewRole, type NewRoleEntity, type NewRolePermission, type NewUser, type NewUserPermission, type NewUserProfile, type NewUserPublicKey, type NewUserSocialAccount, type NewVerificationCode, type Permission, type PermissionEntity, PermissionsRepository, type Role, type RoleEntity, type RoleGuardOptions, type RolePermission, RolePermissionsRepository, RolesRepository, type SessionData, type SessionPayload, type TokenPayload, type UpdateProfileParams, type User, type UserPermission, UserPermissionsRepository, type UserProfile, UserProfilesRepository, type UserPublicKey, type UserSocialAccount, UsersRepository, type VerificationCode, VerificationCodesRepository, VerificationPurpose, acceptInvitation, addPermissionToRole, authLogger, authSchema, cancelInvitation, configureAuth, createAuthLifecycle, createInvitation, createRole, decodeToken, deleteInvitation, deleteRole, expireOldInvitations, generateClientToken, generateKeyPair, generateKeyPairES256, generateKeyPairRS256, generateToken, getAllRoles, getAuth, getAuthConfig, getAuthSessionService, getInvitationByToken, getInvitationWithDetails, getKeyId, getKeySize, getRoleByName, getRolePermissions, getSessionInfo, getSessionTtl, getUser, getUserByEmailService, getUserByIdService, getUserByPhoneService, getUserId, getUserPermissions, getUserProfileService, getUserRole, hasAllPermissions, hasAnyPermission, hasAnyRole, hasPermission, hasRole, hashPassword, initializeAuth, invitationsRepository, keysRepository, listInvitations, parseDuration, permissions, permissionsRepository, removePermissionFromRole, requireAnyPermission, requirePermissions, requireRole, resendInvitation, roleGuard, rolePermissions, rolePermissionsRepository, roles, rolesRepository, sealSession, setRolePermissions, shouldRefreshSession, shouldRotateKey, unsealSession, updateLastLoginService, updateRole, updateUserProfileService, updateUserService, userInvitations, userPermissions, userPermissionsRepository, userProfiles, userProfilesRepository, userPublicKeys, userSocialAccounts, users, usersRepository, validateInvitation, validatePasswordStrength, verificationCodes, verificationCodesRepository, verifyClientToken, verifyKeyFingerprint, verifyPassword, verifyToken };
|