insforge 1.3.0 → 1.4.8
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/CHANGELOG.md +2 -0
- package/auth/package.json +5 -3
- package/auth/src/lib/broadcastService.ts +115 -117
- package/auth/src/lib/insforge.ts +8 -0
- package/auth/src/main.tsx +2 -4
- package/auth/src/pages/SignInPage.tsx +60 -60
- package/auth/src/pages/SignUpPage.tsx +60 -60
- package/auth/src/pages/VerifyEmailPage.tsx +18 -0
- package/auth/tsconfig.json +2 -1
- package/backend/package.json +10 -6
- package/backend/src/api/middlewares/rate-limiters.ts +127 -127
- package/backend/src/api/routes/ai/index.routes.ts +475 -468
- package/backend/src/api/routes/auth/index.routes.ts +85 -32
- package/backend/src/api/routes/auth/oauth.routes.ts +11 -6
- package/backend/src/api/routes/database/index.routes.ts +2 -0
- package/backend/src/api/routes/database/records.routes.ts +39 -175
- package/backend/src/api/routes/database/rpc.routes.ts +69 -0
- package/backend/src/api/routes/deployments/index.routes.ts +192 -0
- package/backend/src/api/routes/docs/index.routes.ts +3 -2
- package/backend/src/api/routes/email/index.routes.ts +35 -35
- package/backend/src/api/routes/functions/index.routes.ts +3 -3
- package/backend/src/api/routes/metadata/index.routes.ts +26 -0
- package/backend/src/api/routes/webhooks/index.routes.ts +109 -0
- package/backend/src/infra/database/database.manager.ts +0 -10
- package/backend/src/infra/database/migrations/018_schema-rework.sql +441 -0
- package/backend/src/infra/database/migrations/019_create-deployments-table.sql +36 -0
- package/backend/src/infra/database/migrations/020_add-audio-modality.sql +11 -0
- package/backend/src/infra/database/migrations/bootstrap/bootstrap-migrations.js +103 -0
- package/backend/src/infra/security/token.manager.ts +1 -4
- package/backend/src/providers/ai/openrouter.provider.ts +12 -3
- package/backend/src/providers/database/base.provider.ts +39 -0
- package/backend/src/providers/database/cloud.provider.ts +159 -0
- package/backend/src/providers/deployments/vercel.provider.ts +516 -0
- package/backend/src/server.ts +19 -7
- package/backend/src/services/ai/ai-config.service.ts +6 -6
- package/backend/src/services/ai/ai-model.service.ts +60 -60
- package/backend/src/services/ai/ai-usage.service.ts +7 -7
- package/backend/src/services/ai/chat-completion.service.ts +415 -220
- package/backend/src/services/ai/helpers.ts +64 -64
- package/backend/src/services/ai/index.ts +13 -13
- package/backend/src/services/auth/auth-config.service.ts +4 -4
- package/backend/src/services/auth/auth-otp.service.ts +6 -6
- package/backend/src/services/auth/auth.service.ts +134 -74
- package/backend/src/services/auth/index.ts +4 -4
- package/backend/src/services/auth/oauth-config.service.ts +12 -12
- package/backend/src/services/database/database-advance.service.ts +19 -55
- package/backend/src/services/database/database-table.service.ts +38 -85
- package/backend/src/services/database/postgrest-proxy.service.ts +165 -0
- package/backend/src/services/deployments/deployment.service.ts +693 -0
- package/backend/src/services/functions/function.service.ts +61 -41
- package/backend/src/services/logs/audit.service.ts +10 -10
- package/backend/src/services/secrets/secret.service.ts +101 -27
- package/backend/src/services/storage/storage.service.ts +30 -30
- package/backend/src/services/usage/usage.service.ts +6 -6
- package/backend/src/types/ai.ts +8 -0
- package/backend/src/types/auth.ts +5 -1
- package/backend/src/types/database.ts +2 -0
- package/backend/src/types/deployments.ts +33 -0
- package/backend/src/types/storage.ts +1 -1
- package/backend/src/types/webhooks.ts +45 -0
- package/backend/src/utils/cookies.ts +34 -35
- package/backend/src/utils/environment.ts +0 -14
- package/backend/src/utils/s3-config-loader.ts +64 -64
- package/backend/src/utils/seed.ts +334 -301
- package/backend/src/utils/sql-parser.ts +126 -0
- package/backend/src/utils/utils.ts +114 -114
- package/backend/src/utils/validations.ts +10 -10
- package/backend/tests/local/test-rpc.sh +141 -0
- package/backend/tests/local/test-secrets.sh +1 -1
- package/backend/tests/manual/test-ai-model-plugins.sh +258 -0
- package/backend/tests/manual/test-rawsql-modes.sh +24 -24
- package/backend/tests/unit/database-advance.test.ts +326 -0
- package/backend/tests/unit/helpers.test.ts +2 -2
- package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +13 -10
- package/docker-compose.prod.yml +1 -1
- package/docker-compose.yml +1 -1
- package/docs/agent-docs/deployment.md +79 -0
- package/docs/changelog.mdx +165 -72
- package/docs/core-concepts/ai/architecture.mdx +1 -23
- package/docs/core-concepts/ai/sdk.mdx +26 -1
- package/docs/core-concepts/authentication/architecture.mdx +6 -8
- package/docs/core-concepts/authentication/sdk.mdx +387 -91
- package/docs/core-concepts/authentication/ui-components/customization.mdx +460 -256
- package/docs/core-concepts/authentication/ui-components/nextjs.mdx +50 -24
- package/docs/core-concepts/authentication/ui-components/react-router.mdx +18 -19
- package/docs/core-concepts/authentication/ui-components/react.mdx +26 -19
- package/docs/core-concepts/database/architecture.mdx +58 -21
- package/docs/core-concepts/database/pgvector.mdx +138 -0
- package/docs/core-concepts/database/sdk.mdx +17 -17
- package/docs/core-concepts/deployments/architecture.mdx +152 -0
- package/docs/core-concepts/email/architecture.mdx +4 -2
- package/docs/core-concepts/functions/architecture.mdx +1 -1
- package/docs/core-concepts/functions/sdk.mdx +0 -1
- package/docs/core-concepts/realtime/architecture.mdx +1 -1
- package/docs/core-concepts/storage/architecture.mdx +1 -1
- package/docs/core-concepts/storage/sdk.mdx +25 -25
- package/docs/docs.json +14 -6
- package/docs/favicon.png +0 -0
- package/docs/favicon.svg +3 -18
- package/docs/images/changelog/dec-2025/apple-oauth.mp4 +0 -0
- package/docs/images/changelog/dec-2025/moreModels.png +0 -0
- package/docs/images/changelog/dec-2025/multi-region.webp +0 -0
- package/docs/images/changelog/dec-2025/postgres-connection.webp +0 -0
- package/docs/images/changelog/dec-2025/realtime2.png +0 -0
- package/docs/images/mcp-setup/CC-MCP-1.mp4 +0 -0
- package/docs/images/mcp-setup/CC-MCP-2.mp4 +0 -0
- package/docs/images/mcp-setup/Cursor-MCP-1.mp4 +0 -0
- package/docs/images/mcp-setup/Cursor-MCP-2.mp4 +0 -0
- package/docs/images/mcp-setup/Cursor-MCP-3.mp4 +0 -0
- package/docs/images/mcp-setup/claude-code-connect.png +0 -0
- package/docs/images/mcp-setup/cline-1.png +0 -0
- package/docs/images/mcp-setup/cline-2.png +0 -0
- package/docs/images/mcp-setup/cline-3.png +0 -0
- package/docs/images/mcp-setup/connect-project.png +0 -0
- package/docs/images/mcp-setup/copilot-1.png +0 -0
- package/docs/images/mcp-setup/copilot-2.png +0 -0
- package/docs/images/mcp-setup/copilot-3.png +0 -0
- package/docs/images/mcp-setup/mcp-json-1.png +0 -0
- package/docs/images/mcp-setup/mcp-json-2.png +0 -0
- package/docs/images/mcp-setup/qoder-1.png +0 -0
- package/docs/images/mcp-setup/qoder-2.png +0 -0
- package/docs/images/mcp-setup/roocode-1.png +0 -0
- package/docs/images/mcp-setup/roocode-2.png +0 -0
- package/docs/images/mcp-setup/trae-1.png +0 -0
- package/docs/images/mcp-setup/trae-2.png +0 -0
- package/docs/images/mcp-setup/trae-3.png +0 -0
- package/docs/images/mcp-setup/trae-4.png +0 -0
- package/docs/images/mcp-setup/trae-5.png +0 -0
- package/docs/images/mcp-setup/windsurf-1.png +0 -0
- package/docs/images/mcp-setup/windsurf-2.png +0 -0
- package/docs/insforge-instructions-sdk.md +7 -3
- package/docs/introduction.mdx +9 -8
- package/docs/mcp-setup.mdx +332 -0
- package/docs/oauth-server.mdx +563 -0
- package/docs/partnership.mdx +79 -10
- package/docs/quickstart.mdx +1 -1
- package/docs/vscode-extension.mdx +74 -0
- package/eslint.config.js +1 -0
- package/examples/response-examples.md +1 -1
- package/frontend/package.json +1 -1
- package/frontend/src/App.tsx +8 -3
- package/frontend/src/assets/logos/antigravity.svg +1 -0
- package/frontend/src/assets/logos/copilot.svg +10 -0
- package/frontend/src/assets/logos/deepseek.svg +139 -0
- package/frontend/src/assets/logos/kiro.svg +9 -0
- package/frontend/src/assets/logos/qoder.svg +4 -0
- package/frontend/src/assets/logos/qwen.svg +15 -0
- package/frontend/src/components/CodeBlock.tsx +2 -2
- package/frontend/src/components/ConnectCTA.tsx +3 -2
- package/frontend/src/components/datagrid/DataGrid.tsx +90 -62
- package/frontend/src/components/datagrid/datagridTypes.tsx +2 -1
- package/frontend/src/components/datagrid/index.ts +1 -1
- package/frontend/src/components/index.ts +0 -1
- package/frontend/src/components/layout/AppHeader.tsx +4 -27
- package/frontend/src/components/layout/AppSidebar.tsx +85 -100
- package/frontend/src/components/layout/Layout.tsx +34 -32
- package/frontend/src/components/layout/PrimaryMenu.tsx +12 -4
- package/frontend/src/components/radix/Select.tsx +151 -151
- package/frontend/src/features/ai/components/AIConfigCard.tsx +200 -200
- package/frontend/src/features/ai/components/AIEmptyState.tsx +23 -23
- package/frontend/src/features/ai/components/ModalityFilterSidebar.tsx +102 -101
- package/frontend/src/features/ai/components/ModelSelectionDialog.tsx +135 -135
- package/frontend/src/features/ai/components/ModelSelectionGrid.tsx +51 -51
- package/frontend/src/features/ai/components/SystemPromptDialog.tsx +118 -118
- package/frontend/src/features/ai/components/index.ts +6 -6
- package/frontend/src/features/ai/helpers.ts +147 -141
- package/frontend/src/features/ai/pages/AIPage.tsx +166 -166
- package/frontend/src/features/auth/components/AuthPreview.tsx +96 -96
- package/frontend/src/features/auth/components/UsersDataGrid.tsx +55 -31
- package/frontend/src/features/auth/components/index.ts +5 -5
- package/frontend/src/features/auth/pages/AuthMethodsPage.tsx +275 -275
- package/frontend/src/features/dashboard/pages/DashboardPage.tsx +1 -1
- package/frontend/src/features/database/components/DatabaseDataGrid.tsx +0 -2
- package/frontend/src/features/database/components/ForeignKeyCell.tsx +38 -11
- package/frontend/src/features/database/components/ForeignKeyPopover.tsx +18 -8
- package/frontend/src/features/database/components/LinkRecordModal.tsx +61 -13
- package/frontend/src/features/database/components/RecordFormField.tsx +1 -1
- package/frontend/src/features/database/components/TableSidebar.tsx +0 -3
- package/frontend/src/features/database/components/TablesEmptyState.tsx +1 -1
- package/frontend/src/features/database/components/TemplatePreview.tsx +1 -2
- package/frontend/src/features/database/constants.ts +16 -28
- package/frontend/src/features/database/hooks/useCSVImport.ts +3 -2
- package/frontend/src/features/database/hooks/useRawSQL.ts +3 -2
- package/frontend/src/features/database/hooks/useTables.ts +5 -7
- package/frontend/src/features/database/pages/FunctionsPage.tsx +0 -5
- package/frontend/src/features/database/pages/IndexesPage.tsx +0 -5
- package/frontend/src/features/database/pages/PoliciesPage.tsx +0 -5
- package/frontend/src/features/database/pages/SQLEditorPage.tsx +2 -2
- package/frontend/src/features/database/pages/TriggersPage.tsx +0 -5
- package/frontend/src/features/database/services/advance.service.ts +1 -15
- package/frontend/src/features/database/services/record.service.ts +4 -20
- package/frontend/src/features/database/services/table.service.ts +1 -4
- package/frontend/src/features/database/templates/ai-chatbot.ts +6 -6
- package/frontend/src/features/database/templates/ecommerce-platform.ts +2 -2
- package/frontend/src/features/database/templates/instagram-clone.ts +10 -10
- package/frontend/src/features/database/templates/notion-clone.ts +8 -8
- package/frontend/src/features/database/templates/reddit-clone.ts +10 -10
- package/frontend/src/features/deployments/components/DeploymentRow.tsx +93 -0
- package/frontend/src/features/deployments/components/DeploymentsEmptyState.tsx +15 -0
- package/frontend/src/features/deployments/hooks/useDeployments.ts +157 -0
- package/frontend/src/features/deployments/pages/DeploymentsPage.tsx +318 -0
- package/frontend/src/features/deployments/services/deployments.service.ts +63 -0
- package/frontend/src/features/functions/components/FunctionRow.tsx +72 -72
- package/frontend/src/features/functions/components/FunctionsSidebar.tsx +56 -56
- package/frontend/src/features/functions/components/SecretRow.tsx +3 -3
- package/frontend/src/features/functions/components/index.ts +5 -5
- package/frontend/src/features/functions/hooks/useFunctions.ts +5 -4
- package/frontend/src/features/functions/hooks/useSecrets.ts +6 -9
- package/frontend/src/features/functions/pages/SecretsPage.tsx +118 -118
- package/frontend/src/features/functions/services/function.service.ts +8 -25
- package/frontend/src/features/functions/services/secret.service.ts +23 -41
- package/frontend/src/features/login/pages/CloudLoginPage.tsx +125 -118
- package/frontend/src/features/logs/components/LogDetailPanel.tsx +41 -0
- package/frontend/src/features/logs/components/LogsDataGrid.tsx +32 -1
- package/frontend/src/features/logs/components/index.ts +1 -0
- package/frontend/src/features/logs/pages/LogsPage.tsx +36 -6
- package/frontend/src/features/onboard/components/ApiCredentialsSection.tsx +59 -0
- package/frontend/src/features/onboard/components/ConnectionStringSection.tsx +180 -0
- package/frontend/src/features/onboard/components/McpConnectionSection.tsx +159 -0
- package/frontend/src/features/onboard/components/OnboardingController.tsx +68 -0
- package/frontend/src/features/onboard/components/OnboardingModal.tsx +121 -267
- package/frontend/src/features/onboard/components/ShowPasswordButton.tsx +21 -0
- package/frontend/src/features/onboard/components/index.ts +9 -4
- package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +1 -1
- package/frontend/src/features/onboard/components/mcp/QoderDeeplinkGenerator.tsx +36 -0
- package/frontend/src/features/onboard/components/mcp/helpers.tsx +123 -98
- package/frontend/src/features/onboard/components/mcp/index.ts +4 -3
- package/frontend/src/features/onboard/index.ts +17 -13
- package/frontend/src/features/settings/pages/SettingsPage.tsx +349 -0
- package/frontend/src/features/visualizer/components/AuthNode.tsx +4 -4
- package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +21 -8
- package/frontend/src/features/visualizer/pages/VisualizerPage.tsx +10 -1
- package/frontend/src/index.css +249 -249
- package/frontend/src/lib/contexts/ModalContext.tsx +35 -0
- package/frontend/src/lib/hooks/useMetadata.ts +45 -1
- package/frontend/src/lib/hooks/useModal.tsx +2 -0
- package/frontend/src/lib/routing/AppRoutes.tsx +103 -99
- package/frontend/src/lib/services/metadata.service.ts +20 -3
- package/frontend/src/lib/utils/menuItems.ts +223 -207
- package/frontend/src/lib/utils/utils.ts +196 -196
- package/functions/server.ts +315 -315
- package/functions/worker-template.js +1 -1
- package/openapi/ai.yaml +115 -5
- package/openapi/auth.yaml +97 -17
- package/openapi/logs.yaml +0 -2
- package/openapi/metadata.yaml +0 -2
- package/openapi/records.yaml +21 -21
- package/openapi/tables.yaml +1 -2
- package/package.json +1 -1
- package/shared-schemas/package.json +1 -1
- package/shared-schemas/src/ai-api.schema.ts +251 -143
- package/shared-schemas/src/ai.schema.ts +63 -63
- package/shared-schemas/src/auth-api.schema.ts +34 -6
- package/shared-schemas/src/auth.schema.ts +17 -10
- package/shared-schemas/src/cloud-events.schema.ts +26 -0
- package/shared-schemas/src/deployments-api.schema.ts +55 -0
- package/shared-schemas/src/deployments.schema.ts +30 -0
- package/shared-schemas/src/docs.schema.ts +8 -2
- package/shared-schemas/src/email-api.schema.ts +30 -30
- package/shared-schemas/src/functions-api.schema.ts +13 -4
- package/shared-schemas/src/functions.schema.ts +1 -1
- package/shared-schemas/src/index.ts +22 -18
- package/shared-schemas/src/metadata.schema.ts +30 -4
- package/shared-schemas/src/secrets-api.schema.ts +44 -0
- package/shared-schemas/src/secrets.schema.ts +15 -0
- package/zeabur/README.md +13 -0
- package/zeabur/template.yml +20 -51
- package/backend/src/types/profile.ts +0 -55
- package/frontend/src/components/ProjectInfoModal.tsx +0 -128
|
@@ -1,200 +1,38 @@
|
|
|
1
1
|
---
|
|
2
|
-
title:
|
|
3
|
-
description:
|
|
2
|
+
title: Custom Auth Pages
|
|
3
|
+
description: Build your own authentication UI using InsForge components
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
createRoot(document.getElementById('root')!).render(
|
|
23
|
-
<StrictMode>
|
|
24
|
-
<InsforgeProvider
|
|
25
|
-
baseUrl={
|
|
26
|
-
import.meta.env.VITE_INSFORGE_BASE_URL || 'https://your-app.region.insforge.app' // Replace with your InsForge backend URL
|
|
27
|
-
}
|
|
28
|
-
afterSignInUrl="/dashboard"
|
|
29
|
-
>
|
|
30
|
-
<App />
|
|
31
|
-
</InsforgeProvider>
|
|
32
|
-
</StrictMode>
|
|
33
|
-
);
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
#### Step 2: Configure Router with Custom Pages
|
|
37
|
-
|
|
38
|
-
Set `builtInAuth: false` and provide your page components:
|
|
39
|
-
|
|
40
|
-
```tsx src/App.tsx
|
|
41
|
-
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
|
42
|
-
import { getInsforgeRoutes } from '@insforge/react-router/router';
|
|
43
|
-
import Layout from './components/Layout';
|
|
44
|
-
import Home from './pages/Home';
|
|
45
|
-
import Dashboard from './pages/Dashboard';
|
|
46
|
-
// Import your custom auth pages
|
|
47
|
-
import SignInPage from './pages/auth/SignInPage';
|
|
48
|
-
import SignUpPage from './pages/auth/SignUpPage';
|
|
49
|
-
import ForgotPasswordPage from './pages/auth/ForgotPasswordPage';
|
|
50
|
-
|
|
51
|
-
const router = createBrowserRouter([
|
|
52
|
-
{
|
|
53
|
-
path: '/',
|
|
54
|
-
element: <Layout />,
|
|
55
|
-
children: [
|
|
56
|
-
{ index: true, element: <Home /> },
|
|
57
|
-
{ path: 'dashboard', element: <Dashboard /> },
|
|
58
|
-
],
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
// Custom auth routes
|
|
62
|
-
...getInsforgeRoutes({
|
|
63
|
-
baseUrl: import.meta.env.VITE_INSFORGE_BASE_URL || 'https://your-app.region.insforge.app', // Replace with your InsForge backend URL
|
|
64
|
-
afterSignInUrl: '/dashboard',
|
|
65
|
-
builtInAuth: false, // Render custom components instead of redirecting
|
|
66
|
-
pages: {
|
|
67
|
-
signIn: <SignInPage />,
|
|
68
|
-
signUp: <SignUpPage />,
|
|
69
|
-
forgotPassword: <ForgotPasswordPage />,
|
|
70
|
-
},
|
|
71
|
-
}),
|
|
72
|
-
]);
|
|
73
|
-
|
|
74
|
-
export default function App() {
|
|
75
|
-
return <RouterProvider router={router} />;
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
#### Step 3: Create Auth Page Components
|
|
80
|
-
|
|
81
|
-
Use our complete authentication components directly. These components are **full-featured page-level components** with all business logic included:
|
|
82
|
-
|
|
83
|
-
```tsx src/pages/auth/SignInPage.tsx
|
|
84
|
-
import { SignIn } from '@insforge/react-router';
|
|
85
|
-
|
|
86
|
-
export default function SignInPage() {
|
|
87
|
-
return (
|
|
88
|
-
<div className="h-screen flex items-center justify-center">
|
|
89
|
-
<SignIn
|
|
90
|
-
title="Welcome Back"
|
|
91
|
-
subtitle="Sign in to your account"
|
|
92
|
-
onError={(error) => {
|
|
93
|
-
console.error('Sign in error:', error);
|
|
94
|
-
}}
|
|
95
|
-
/>
|
|
96
|
-
</div>
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
```tsx src/pages/auth/SignUpPage.tsx
|
|
102
|
-
import { SignUp } from '@insforge/react-router';
|
|
103
|
-
|
|
104
|
-
export default function SignUpPage() {
|
|
105
|
-
return (
|
|
106
|
-
<div className="h-screen flex items-center justify-center">
|
|
107
|
-
<SignUp
|
|
108
|
-
title="Create Account"
|
|
109
|
-
subtitle="Get started for free"
|
|
110
|
-
onError={(error) => {
|
|
111
|
-
console.error('Sign up error:', error);
|
|
112
|
-
}}
|
|
113
|
-
/>
|
|
114
|
-
</div>
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
```tsx src/pages/auth/ForgotPasswordPage.tsx
|
|
120
|
-
import { ForgotPassword } from '@insforge/react-router';
|
|
121
|
-
|
|
122
|
-
export default function ForgotPasswordPage() {
|
|
123
|
-
return (
|
|
124
|
-
<div className="h-screen flex items-center justify-center">
|
|
125
|
-
<ForgotPassword
|
|
126
|
-
onError={(error) => {
|
|
127
|
-
console.error('Password reset error:', error);
|
|
128
|
-
}}
|
|
129
|
-
/>
|
|
130
|
-
</div>
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
**That's it!** The `<SignIn>`, `<SignUp>`, and `<ForgotPassword>` components are complete page-level components that include:
|
|
136
|
-
|
|
137
|
-
- Form UI with validation
|
|
138
|
-
- OAuth provider buttons (auto-detected)
|
|
139
|
-
- Error handling
|
|
140
|
-
- Loading states
|
|
141
|
-
- Password strength indicators (SignUp)
|
|
142
|
-
- All authentication logic
|
|
143
|
-
|
|
144
|
-
You only need to wrap them in your page components for layout/styling purposes.
|
|
145
|
-
|
|
146
|
-
### Key Difference from Built-in Auth
|
|
147
|
-
|
|
148
|
-
**Built-in Auth:**
|
|
149
|
-
|
|
150
|
-
- `/sign-in` → Redirects to `https://your-app.region.insforge.app/auth/sign-in`
|
|
151
|
-
- Authentication happens on hosted page
|
|
152
|
-
- Returns to your app with token
|
|
153
|
-
|
|
154
|
-
**Custom Components:**
|
|
155
|
-
|
|
156
|
-
- `/sign-in` → Renders your `<SignInPage>` component
|
|
157
|
-
- Authentication happens in your app
|
|
158
|
-
- SDK handles token management automatically
|
|
6
|
+
InsForge provides three levels of flexibility for implementing authentication in your app:
|
|
7
|
+
|
|
8
|
+
<CardGroup cols={3}>
|
|
9
|
+
<Card title="Hosted Auth" icon="bolt" href="/core-concepts/authentication/ui-components/react">
|
|
10
|
+
**Fastest setup** - Redirect to hosted login pages. Zero UI code required.
|
|
11
|
+
</Card>
|
|
12
|
+
|
|
13
|
+
<Card title="Custom Components" icon="puzzle-piece">
|
|
14
|
+
**This page** - Use pre-built components with full business logic in your app.
|
|
15
|
+
</Card>
|
|
16
|
+
|
|
17
|
+
<Card title="SDK Only" icon="code" href="/core-concepts/authentication/sdk">
|
|
18
|
+
**Maximum control** - Build 100% custom UI using SDK methods directly.
|
|
19
|
+
</Card>
|
|
20
|
+
</CardGroup>
|
|
159
21
|
|
|
160
22
|
---
|
|
161
23
|
|
|
162
|
-
##
|
|
24
|
+
## Key Difference from Hosted Auth
|
|
163
25
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
- **
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
- **Form Components**: Pure UI forms for custom logic
|
|
170
|
-
- **TypeScript**: Full type safety
|
|
26
|
+
| Aspect | Hosted Auth | Custom Components |
|
|
27
|
+
|--------|-------------|-------------------|
|
|
28
|
+
| **Sign-in route** | Redirects to `https://your-app.region.insforge.app/auth/sign-in` | Renders your `<SignIn />` component |
|
|
29
|
+
| **Where auth happens** | On hosted page | In your app |
|
|
30
|
+
| **Token management** | Returns to your app with token | SDK handles automatically |
|
|
171
31
|
|
|
172
32
|
---
|
|
173
33
|
|
|
174
34
|
## How It Works
|
|
175
35
|
|
|
176
|
-
### Built-in Auth Flow
|
|
177
|
-
|
|
178
|
-
```
|
|
179
|
-
1. User clicks "Sign In" → Visits /sign-in route
|
|
180
|
-
↓
|
|
181
|
-
2. getInsforgeRoutes() redirects → https://your-app.region.insforge.app/auth/sign-in?redirect=yourapp.com/you-defined-destination-after-sign-in
|
|
182
|
-
↓
|
|
183
|
-
3. User signs in on deployed page → Backend processes authentication
|
|
184
|
-
↓
|
|
185
|
-
4. Backend redirects → yourapp.com/you-defined-destination-after-sign-in?access_token=xxx&user_id=xxx
|
|
186
|
-
↓
|
|
187
|
-
5. InsForge SDK will:
|
|
188
|
-
- Extracts token from URL
|
|
189
|
-
- Saves to localStorage
|
|
190
|
-
- Verifies with getCurrentUser()
|
|
191
|
-
- Updates Provider state
|
|
192
|
-
↓
|
|
193
|
-
6. User sees the destination page (e.g /dashboard)
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### Custom UI Flow
|
|
197
|
-
|
|
198
36
|
```
|
|
199
37
|
1. User visits /sign-in route → Renders <SignIn> component
|
|
200
38
|
↓
|
|
@@ -209,15 +47,34 @@ You only need to wrap them in your page components for layout/styling purposes.
|
|
|
209
47
|
6. User sees authenticated UI at destination
|
|
210
48
|
```
|
|
211
49
|
|
|
212
|
-
|
|
50
|
+
---
|
|
213
51
|
|
|
214
|
-
|
|
215
|
-
- **getInsforgeRoutes()**: Creates redirect routes for built-in auth
|
|
216
|
-
- **SDK Integration**: All auth operations go through `@insforge/sdk`, which auto-detects tokens from URL
|
|
217
|
-
- **React Context**: Provides auth state to all child components
|
|
218
|
-
- **Hooks**: Easy access to auth methods and user data
|
|
52
|
+
## Before You Start
|
|
219
53
|
|
|
220
|
-
|
|
54
|
+
Make sure to create an InsForge SDK client and wrap your app in the `InsforgeProvider`:
|
|
55
|
+
|
|
56
|
+
```tsx src/lib/insforge.ts
|
|
57
|
+
import { createClient } from '@insforge/sdk';
|
|
58
|
+
|
|
59
|
+
export const insforge = createClient({
|
|
60
|
+
baseUrl: import.meta.env.VITE_INSFORGE_BASE_URL,
|
|
61
|
+
anonKey: import.meta.env.VITE_INSFORGE_ANON_KEY,
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```tsx src/main.tsx
|
|
66
|
+
import { InsforgeProvider } from '@insforge/react';
|
|
67
|
+
import { insforge } from './lib/insforge';
|
|
68
|
+
import App from './App';
|
|
69
|
+
|
|
70
|
+
createRoot(document.getElementById('root')!).render(
|
|
71
|
+
<StrictMode>
|
|
72
|
+
<InsforgeProvider client={insforge}>
|
|
73
|
+
<App />
|
|
74
|
+
</InsforgeProvider>
|
|
75
|
+
</StrictMode>
|
|
76
|
+
);
|
|
77
|
+
```
|
|
221
78
|
|
|
222
79
|
## Complete Components (with Business Logic)
|
|
223
80
|
|
|
@@ -228,16 +85,14 @@ These components include full authentication logic and work out of the box.
|
|
|
228
85
|
Complete sign-in component with email/password and OAuth:
|
|
229
86
|
|
|
230
87
|
```tsx
|
|
231
|
-
import { SignIn } from '@insforge/react
|
|
88
|
+
import { SignIn } from '@insforge/react';
|
|
232
89
|
|
|
233
90
|
function SignInPage() {
|
|
234
91
|
return (
|
|
235
92
|
<SignIn
|
|
236
93
|
title="Welcome Back"
|
|
237
94
|
subtitle="Sign in to continue"
|
|
238
|
-
onError={(error) =>
|
|
239
|
-
console.error('Error:', error);
|
|
240
|
-
}}
|
|
95
|
+
onError={(error) => console.error('Error:', error)}
|
|
241
96
|
/>
|
|
242
97
|
);
|
|
243
98
|
}
|
|
@@ -247,31 +102,43 @@ function SignInPage() {
|
|
|
247
102
|
|
|
248
103
|
- Email/password authentication
|
|
249
104
|
- OAuth provider buttons (auto-detected from backend)
|
|
105
|
+
- Email verification flow (when required)
|
|
250
106
|
- Password visibility toggle
|
|
251
|
-
- Error handling
|
|
252
|
-
- Loading states
|
|
253
|
-
- Customizable text
|
|
107
|
+
- Error handling & loading states
|
|
254
108
|
|
|
255
109
|
**Props:**
|
|
256
110
|
|
|
257
|
-
|
|
258
|
-
|
|
111
|
+
| Prop | Type | Description |
|
|
112
|
+
|------|------|-------------|
|
|
113
|
+
| `title` | `string` | Custom title text |
|
|
114
|
+
| `subtitle` | `string` | Custom subtitle text |
|
|
115
|
+
| `emailLabel` | `string` | Label for email input |
|
|
116
|
+
| `emailPlaceholder` | `string` | Placeholder for email input |
|
|
117
|
+
| `passwordLabel` | `string` | Label for password input |
|
|
118
|
+
| `passwordPlaceholder` | `string` | Placeholder for password input |
|
|
119
|
+
| `forgotPasswordText` | `string` | Text for forgot password link |
|
|
120
|
+
| `forgotPasswordUrl` | `string` | URL for forgot password page |
|
|
121
|
+
| `submitButtonText` | `string` | Text for submit button |
|
|
122
|
+
| `loadingButtonText` | `string` | Text while loading |
|
|
123
|
+
| `signUpText` | `string` | Text before sign up link |
|
|
124
|
+
| `signUpLinkText` | `string` | Text for sign up link |
|
|
125
|
+
| `signUpUrl` | `string` | URL for sign up page |
|
|
126
|
+
| `dividerText` | `string` | Text in OAuth divider |
|
|
127
|
+
| `onError` | `(error: Error) => void` | Callback on error |
|
|
259
128
|
|
|
260
129
|
### `<SignUp />`
|
|
261
130
|
|
|
262
131
|
Complete sign-up component with password strength validation:
|
|
263
132
|
|
|
264
133
|
```tsx
|
|
265
|
-
import { SignUp } from '@insforge/react
|
|
134
|
+
import { SignUp } from '@insforge/react';
|
|
266
135
|
|
|
267
136
|
function SignUpPage() {
|
|
268
137
|
return (
|
|
269
138
|
<SignUp
|
|
270
139
|
title="Create Account"
|
|
271
140
|
subtitle="Get started with your free account"
|
|
272
|
-
onError={(error) =>
|
|
273
|
-
console.error('Error:', error);
|
|
274
|
-
}}
|
|
141
|
+
onError={(error) => console.error('Error:', error)}
|
|
275
142
|
/>
|
|
276
143
|
);
|
|
277
144
|
}
|
|
@@ -281,52 +148,172 @@ function SignUpPage() {
|
|
|
281
148
|
|
|
282
149
|
- Email/password registration
|
|
283
150
|
- Real-time password strength indicator
|
|
151
|
+
- Email verification flow (when required)
|
|
284
152
|
- OAuth provider buttons
|
|
285
|
-
- Form validation
|
|
286
|
-
- Customizable text
|
|
153
|
+
- Form validation based on backend config
|
|
287
154
|
|
|
288
|
-
**Props:**
|
|
155
|
+
**Props:**
|
|
156
|
+
|
|
157
|
+
| Prop | Type | Description |
|
|
158
|
+
|------|------|-------------|
|
|
159
|
+
| `title` | `string` | Custom title text |
|
|
160
|
+
| `subtitle` | `string` | Custom subtitle text |
|
|
161
|
+
| `emailLabel` | `string` | Label for email input |
|
|
162
|
+
| `emailPlaceholder` | `string` | Placeholder for email input |
|
|
163
|
+
| `passwordLabel` | `string` | Label for password input |
|
|
164
|
+
| `passwordPlaceholder` | `string` | Placeholder for password input |
|
|
165
|
+
| `submitButtonText` | `string` | Text for submit button |
|
|
166
|
+
| `loadingButtonText` | `string` | Text while loading |
|
|
167
|
+
| `signInText` | `string` | Text before sign in link |
|
|
168
|
+
| `signInLinkText` | `string` | Text for sign in link |
|
|
169
|
+
| `signInUrl` | `string` | URL for sign in page |
|
|
170
|
+
| `dividerText` | `string` | Text in OAuth divider |
|
|
171
|
+
| `onError` | `(error: Error) => void` | Callback on error |
|
|
289
172
|
|
|
290
173
|
### `<UserButton />`
|
|
291
174
|
|
|
292
|
-
User profile dropdown with sign-out:
|
|
175
|
+
User profile dropdown with sign-out and profile management:
|
|
293
176
|
|
|
294
177
|
```tsx
|
|
295
|
-
import { UserButton } from '@insforge/react
|
|
178
|
+
import { UserButton } from '@insforge/react';
|
|
296
179
|
|
|
297
180
|
function Header() {
|
|
298
181
|
return (
|
|
299
182
|
<header>
|
|
300
183
|
<nav>{/* Your navigation */}</nav>
|
|
301
|
-
<UserButton
|
|
184
|
+
<UserButton
|
|
185
|
+
mode="detailed"
|
|
186
|
+
afterSignOutUrl="/"
|
|
187
|
+
showProfile={true}
|
|
188
|
+
onProfileError={(error) => console.error('Profile error:', error)}
|
|
189
|
+
/>
|
|
302
190
|
</header>
|
|
303
191
|
);
|
|
304
192
|
}
|
|
305
193
|
```
|
|
306
194
|
|
|
307
|
-
**
|
|
195
|
+
**Key Features:**
|
|
196
|
+
|
|
197
|
+
- Avatar with fallback to initials
|
|
198
|
+
- Dropdown menu with Profile and Sign Out options
|
|
199
|
+
- Built-in `UserProfileModal` integration
|
|
200
|
+
- Auto-positioning (opens upward/downward based on viewport)
|
|
201
|
+
|
|
202
|
+
**Props:**
|
|
203
|
+
|
|
204
|
+
| Prop | Type | Default | Description |
|
|
205
|
+
|------|------|---------|-------------|
|
|
206
|
+
| `mode` | `"detailed"` \| `"simple"` | `"simple"` | `detailed`: avatar + name + email, `simple`: avatar only |
|
|
207
|
+
| `afterSignOutUrl` | `string` | `"/"` | Redirect URL after sign out |
|
|
208
|
+
| `showProfile` | `boolean` | `true` | Show the Profile menu item |
|
|
209
|
+
| `onProfileError` | `(error: string) => void` | - | Callback when profile update fails |
|
|
210
|
+
|
|
211
|
+
### `<UserProfileModal />`
|
|
212
|
+
|
|
213
|
+
Modal for viewing and editing user profile information:
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
import { useState } from 'react';
|
|
217
|
+
import { UserProfileModal } from '@insforge/react';
|
|
218
|
+
|
|
219
|
+
function ProfileButton() {
|
|
220
|
+
const [showModal, setShowModal] = useState(false);
|
|
221
|
+
|
|
222
|
+
return (
|
|
223
|
+
<>
|
|
224
|
+
<button onClick={() => setShowModal(true)}>Edit Profile</button>
|
|
225
|
+
|
|
226
|
+
{showModal && (
|
|
227
|
+
<UserProfileModal
|
|
228
|
+
onClose={() => setShowModal(false)}
|
|
229
|
+
onError={(error) => console.error('Profile error:', error)}
|
|
230
|
+
/>
|
|
231
|
+
)}
|
|
232
|
+
</>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Key Features:**
|
|
238
|
+
|
|
239
|
+
- Displays user avatar, email, and name
|
|
240
|
+
- Edit mode for updating name
|
|
241
|
+
- Avatar fallback to initials
|
|
242
|
+
- Keyboard support (Escape to close)
|
|
243
|
+
- Portal rendering for proper z-index handling
|
|
244
|
+
|
|
245
|
+
**Props:**
|
|
246
|
+
|
|
247
|
+
| Prop | Type | Description |
|
|
248
|
+
|------|------|-------------|
|
|
249
|
+
| `onClose` | `() => void` | Called when modal is closed |
|
|
250
|
+
| `onError` | `(error: string) => void` | Called when an error occurs |
|
|
251
|
+
|
|
252
|
+
### `<SignInButton />` / `<SignUpButton />`
|
|
253
|
+
|
|
254
|
+
Simple buttons that redirect to hosted auth pages:
|
|
308
255
|
|
|
309
|
-
|
|
310
|
-
|
|
256
|
+
```tsx
|
|
257
|
+
import { SignInButton, SignUpButton } from '@insforge/react';
|
|
258
|
+
|
|
259
|
+
function LandingPage() {
|
|
260
|
+
return (
|
|
261
|
+
<div>
|
|
262
|
+
{/* Default button */}
|
|
263
|
+
<SignInButton />
|
|
264
|
+
<SignUpButton />
|
|
265
|
+
|
|
266
|
+
{/* Custom styled button */}
|
|
267
|
+
<SignInButton>
|
|
268
|
+
<button className="my-custom-button">Login</button>
|
|
269
|
+
</SignInButton>
|
|
270
|
+
</div>
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
```
|
|
311
274
|
|
|
312
275
|
**Props:**
|
|
313
276
|
|
|
314
|
-
|
|
315
|
-
|
|
277
|
+
| Prop | Type | Description |
|
|
278
|
+
|------|------|-------------|
|
|
279
|
+
| `children` | `ReactNode` | Custom button element (wraps with click handler) |
|
|
280
|
+
| `className` | `string` | CSS class for default button |
|
|
281
|
+
|
|
282
|
+
### `<SignOutButton />`
|
|
283
|
+
|
|
284
|
+
Simple button that signs out the current user:
|
|
285
|
+
|
|
286
|
+
```tsx
|
|
287
|
+
import { SignOutButton } from '@insforge/react';
|
|
288
|
+
|
|
289
|
+
function Header() {
|
|
290
|
+
return (
|
|
291
|
+
<SignOutButton afterSignOutUrl="/goodbye">
|
|
292
|
+
<button className="logout-btn">Logout</button>
|
|
293
|
+
</SignOutButton>
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Props:**
|
|
299
|
+
|
|
300
|
+
| Prop | Type | Default | Description |
|
|
301
|
+
|------|------|---------|-------------|
|
|
302
|
+
| `children` | `ReactNode` | - | Custom button element |
|
|
303
|
+
| `className` | `string` | - | CSS class for default button |
|
|
304
|
+
| `afterSignOutUrl` | `string` | `"/"` | Redirect URL after sign out |
|
|
316
305
|
|
|
317
306
|
### `<ForgotPassword />`
|
|
318
307
|
|
|
319
308
|
Complete password reset flow with automatic method detection:
|
|
320
309
|
|
|
321
310
|
```tsx
|
|
322
|
-
import { ForgotPassword } from '@insforge/react
|
|
311
|
+
import { ForgotPassword } from '@insforge/react';
|
|
323
312
|
|
|
324
313
|
function ForgotPasswordPage() {
|
|
325
314
|
return (
|
|
326
315
|
<ForgotPassword
|
|
327
|
-
onError={(error) =>
|
|
328
|
-
console.error('Error:', error);
|
|
329
|
-
}}
|
|
316
|
+
onError={(error) => console.error('Error:', error)}
|
|
330
317
|
/>
|
|
331
318
|
);
|
|
332
319
|
}
|
|
@@ -339,18 +326,99 @@ function ForgotPasswordPage() {
|
|
|
339
326
|
- **Code method**: Three-step flow (email → verify code → reset password)
|
|
340
327
|
- 60-second countdown timer for resend
|
|
341
328
|
- Built-in form validation
|
|
342
|
-
- Customizable text
|
|
343
329
|
|
|
344
330
|
**Props:**
|
|
345
331
|
|
|
346
|
-
|
|
332
|
+
| Prop | Type | Description |
|
|
333
|
+
|------|------|-------------|
|
|
334
|
+
| `onError` | `(error: Error) => void` | Callback on error |
|
|
335
|
+
|
|
336
|
+
### `<ResetPassword />`
|
|
337
|
+
|
|
338
|
+
Password reset form that reads the token from URL automatically:
|
|
339
|
+
|
|
340
|
+
```tsx
|
|
341
|
+
import { ResetPassword } from '@insforge/react';
|
|
342
|
+
|
|
343
|
+
// Used at /reset-password?token=xxxxx
|
|
344
|
+
function ResetPasswordPage() {
|
|
345
|
+
return (
|
|
346
|
+
<ResetPassword
|
|
347
|
+
onError={(error) => console.error('Error:', error)}
|
|
348
|
+
/>
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
**Key Features:**
|
|
354
|
+
|
|
355
|
+
- Automatically reads reset token from URL (`?token=xxx`)
|
|
356
|
+
- Password confirmation validation
|
|
357
|
+
- Password strength validation based on backend config
|
|
358
|
+
- Success state with completion message
|
|
359
|
+
- Error handling for invalid/missing tokens
|
|
360
|
+
|
|
361
|
+
**Props:**
|
|
362
|
+
|
|
363
|
+
| Prop | Type | Description |
|
|
364
|
+
|------|------|-------------|
|
|
365
|
+
| `title` | `string` | Custom title text |
|
|
366
|
+
| `subtitle` | `string` | Custom subtitle text |
|
|
367
|
+
| `newPasswordLabel` | `string` | Label for new password input |
|
|
368
|
+
| `newPasswordPlaceholder` | `string` | Placeholder for new password |
|
|
369
|
+
| `confirmPasswordLabel` | `string` | Label for confirm password input |
|
|
370
|
+
| `confirmPasswordPlaceholder` | `string` | Placeholder for confirm password |
|
|
371
|
+
| `submitButtonText` | `string` | Text for submit button |
|
|
372
|
+
| `loadingButtonText` | `string` | Text while loading |
|
|
373
|
+
| `onError` | `(error: Error) => void` | Callback on error |
|
|
374
|
+
|
|
375
|
+
### `<VerifyEmail />`
|
|
376
|
+
|
|
377
|
+
Email verification component with automatic token handling:
|
|
378
|
+
|
|
379
|
+
```tsx
|
|
380
|
+
import { VerifyEmail } from '@insforge/react';
|
|
381
|
+
|
|
382
|
+
function VerifyEmailPage() {
|
|
383
|
+
const token = new URLSearchParams(window.location.search).get('token');
|
|
384
|
+
|
|
385
|
+
return (
|
|
386
|
+
<VerifyEmail
|
|
387
|
+
token={token || ''}
|
|
388
|
+
onSuccess={(data) => {
|
|
389
|
+
console.log('Email verified!', data);
|
|
390
|
+
// Navigate to dashboard or close window
|
|
391
|
+
}}
|
|
392
|
+
onError={(error) => console.error('Verification failed:', error)}
|
|
393
|
+
/>
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
**Key Features:**
|
|
399
|
+
|
|
400
|
+
- Automatic verification on mount
|
|
401
|
+
- Loading, success, and error states
|
|
402
|
+
- Customizable status messages
|
|
403
|
+
|
|
404
|
+
**Props:**
|
|
405
|
+
|
|
406
|
+
| Prop | Type | Description |
|
|
407
|
+
|------|------|-------------|
|
|
408
|
+
| `token` | `string` | Verification token from URL |
|
|
409
|
+
| `verifyingTitle` | `string` | Title shown while verifying |
|
|
410
|
+
| `successTitle` | `string` | Title shown on success |
|
|
411
|
+
| `successMessage` | `string` | Message shown on success |
|
|
412
|
+
| `errorTitle` | `string` | Title shown on error |
|
|
413
|
+
| `onSuccess` | `(data) => void` | Callback on successful verification |
|
|
414
|
+
| `onError` | `(error: Error) => void` | Callback on error |
|
|
347
415
|
|
|
348
416
|
### `<Protect />`
|
|
349
417
|
|
|
350
418
|
Protected content with conditional rendering:
|
|
351
419
|
|
|
352
420
|
```tsx
|
|
353
|
-
import { Protect } from '@insforge/react
|
|
421
|
+
import { Protect } from '@insforge/react';
|
|
354
422
|
|
|
355
423
|
function Dashboard() {
|
|
356
424
|
return (
|
|
@@ -380,7 +448,7 @@ function Dashboard() {
|
|
|
380
448
|
Conditional rendering based on auth state:
|
|
381
449
|
|
|
382
450
|
```tsx
|
|
383
|
-
import { SignedIn, SignedOut } from '@insforge/react
|
|
451
|
+
import { SignedIn, SignedOut } from '@insforge/react';
|
|
384
452
|
|
|
385
453
|
function NavBar() {
|
|
386
454
|
return (
|
|
@@ -405,19 +473,18 @@ function NavBar() {
|
|
|
405
473
|
|
|
406
474
|
### `useAuth()`
|
|
407
475
|
|
|
408
|
-
Access authentication methods and state
|
|
476
|
+
Access authentication methods and state. This is an alias for `useInsforge()`.
|
|
409
477
|
|
|
410
478
|
```tsx
|
|
411
|
-
import { useAuth } from '@insforge/react
|
|
479
|
+
import { useAuth } from '@insforge/react';
|
|
412
480
|
|
|
413
481
|
function LoginButton() {
|
|
414
482
|
const { signIn, signUp, signOut, isSignedIn, isLoaded } = useAuth();
|
|
415
483
|
|
|
416
484
|
const handleSignIn = async () => {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
console.error('Sign in failed:', error);
|
|
485
|
+
const result = await signIn('user@example.com', 'password');
|
|
486
|
+
if ('error' in result) {
|
|
487
|
+
console.error('Sign in failed:', result.error);
|
|
421
488
|
}
|
|
422
489
|
};
|
|
423
490
|
|
|
@@ -433,18 +500,101 @@ function LoginButton() {
|
|
|
433
500
|
|
|
434
501
|
**Returns:**
|
|
435
502
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
503
|
+
| Property/Method | Type | Description |
|
|
504
|
+
|-----------------|------|-------------|
|
|
505
|
+
| `isLoaded` | `boolean` | Whether auth state has been initialized |
|
|
506
|
+
| `isSignedIn` | `boolean` | Whether user is currently signed in |
|
|
507
|
+
| `signIn(email, password)` | `Promise` | Sign in with email/password |
|
|
508
|
+
| `signUp(email, password)` | `Promise` | Register new user |
|
|
509
|
+
| `signOut()` | `Promise<void>` | Sign out current user |
|
|
510
|
+
|
|
511
|
+
### `useInsforge()`
|
|
512
|
+
|
|
513
|
+
Full access to all authentication methods and context. Use this when you need advanced features like OAuth or email verification.
|
|
514
|
+
|
|
515
|
+
```tsx
|
|
516
|
+
import { useInsforge } from '@insforge/react';
|
|
517
|
+
|
|
518
|
+
function CustomAuthFlow() {
|
|
519
|
+
const {
|
|
520
|
+
// State
|
|
521
|
+
user,
|
|
522
|
+
isLoaded,
|
|
523
|
+
isSignedIn,
|
|
524
|
+
|
|
525
|
+
// Core auth
|
|
526
|
+
signIn,
|
|
527
|
+
signUp,
|
|
528
|
+
signOut,
|
|
529
|
+
|
|
530
|
+
// User management
|
|
531
|
+
updateUser,
|
|
532
|
+
reloadAuth,
|
|
533
|
+
|
|
534
|
+
// Email verification
|
|
535
|
+
resendVerificationEmail,
|
|
536
|
+
verifyEmail,
|
|
537
|
+
|
|
538
|
+
// Password reset
|
|
539
|
+
sendResetPasswordEmail,
|
|
540
|
+
resetPassword,
|
|
541
|
+
exchangeResetPasswordToken,
|
|
542
|
+
|
|
543
|
+
// OAuth
|
|
544
|
+
loginWithOAuth,
|
|
545
|
+
|
|
546
|
+
// Config
|
|
547
|
+
getPublicAuthConfig,
|
|
548
|
+
baseUrl,
|
|
549
|
+
afterSignInUrl,
|
|
550
|
+
} = useInsforge();
|
|
551
|
+
|
|
552
|
+
// Example: OAuth login
|
|
553
|
+
const handleGoogleLogin = () => {
|
|
554
|
+
loginWithOAuth('google', '/dashboard');
|
|
555
|
+
};
|
|
556
|
+
|
|
557
|
+
// Example: Send password reset email
|
|
558
|
+
const handleForgotPassword = async (email: string) => {
|
|
559
|
+
const result = await sendResetPasswordEmail(email);
|
|
560
|
+
if (result?.message) {
|
|
561
|
+
console.log('Reset email sent!');
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
return <div>...</div>;
|
|
566
|
+
}
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
**Full API Reference:**
|
|
570
|
+
|
|
571
|
+
| Property/Method | Type | Description |
|
|
572
|
+
|-----------------|------|-------------|
|
|
573
|
+
| `user` | `InsforgeUser \| null` | Current user object |
|
|
574
|
+
| `userId` | `string \| null` | Current user ID |
|
|
575
|
+
| `isLoaded` | `boolean` | Auth state initialized |
|
|
576
|
+
| `isSignedIn` | `boolean` | User is signed in |
|
|
577
|
+
| `signIn(email, password)` | `Promise` | Sign in with credentials |
|
|
578
|
+
| `signUp(email, password)` | `Promise` | Register new user |
|
|
579
|
+
| `signOut()` | `Promise<void>` | Sign out user |
|
|
580
|
+
| `updateUser(profile)` | `Promise` | Update user profile |
|
|
581
|
+
| `reloadAuth()` | `Promise` | Refresh auth state from backend |
|
|
582
|
+
| `resendVerificationEmail(email)` | `Promise` | Resend email verification link or otp |
|
|
583
|
+
| `verifyEmail(otp, email?)` | `Promise` | Verify email with OTP code |
|
|
584
|
+
| `sendResetPasswordEmail(email)` | `Promise` | Send password reset email |
|
|
585
|
+
| `resetPassword(token, newPassword)` | `Promise` | Reset password with token |
|
|
586
|
+
| `exchangeResetPasswordToken(email, code)` | `Promise` | Exchange reset code for token |
|
|
587
|
+
| `loginWithOAuth(provider, redirectTo)` | `Promise<void>` | Start OAuth flow |
|
|
588
|
+
| `getPublicAuthConfig()` | `Promise` | Get auth configuration |
|
|
589
|
+
| `baseUrl` | `string` | InsForge backend URL |
|
|
590
|
+
| `afterSignInUrl` | `string` | Default redirect after sign in |
|
|
441
591
|
|
|
442
592
|
### `useUser()`
|
|
443
593
|
|
|
444
|
-
Access current user data:
|
|
594
|
+
Access current user data and update profile:
|
|
445
595
|
|
|
446
596
|
```tsx
|
|
447
|
-
import { useUser } from '@insforge/react
|
|
597
|
+
import { useUser } from '@insforge/react';
|
|
448
598
|
|
|
449
599
|
function UserProfile() {
|
|
450
600
|
const { user, isLoaded, updateUser } = useUser();
|
|
@@ -453,14 +603,17 @@ function UserProfile() {
|
|
|
453
603
|
if (!user) return <div>Not signed in</div>;
|
|
454
604
|
|
|
455
605
|
const handleUpdate = async () => {
|
|
456
|
-
await updateUser({ name: 'New Name' });
|
|
606
|
+
const result = await updateUser({ name: 'New Name' });
|
|
607
|
+
if (result?.error) {
|
|
608
|
+
console.error('Update failed:', result.error);
|
|
609
|
+
}
|
|
457
610
|
};
|
|
458
611
|
|
|
459
612
|
return (
|
|
460
613
|
<div>
|
|
461
614
|
<p>Email: {user.email}</p>
|
|
462
|
-
<p>Name: {user.name}</p>
|
|
463
|
-
<img src={user.
|
|
615
|
+
<p>Name: {user.profile.name}</p>
|
|
616
|
+
<img src={user.profile.avatar_url} alt="Avatar" />
|
|
464
617
|
<button onClick={handleUpdate}>Update Name</button>
|
|
465
618
|
</div>
|
|
466
619
|
);
|
|
@@ -469,26 +622,28 @@ function UserProfile() {
|
|
|
469
622
|
|
|
470
623
|
**Returns:**
|
|
471
624
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
625
|
+
| Property/Method | Type | Description |
|
|
626
|
+
|-----------------|------|-------------|
|
|
627
|
+
| `user` | `InsforgeUser \| null` | User object with id, email, profile |
|
|
628
|
+
| `user.profile` | `object` | Profile with name, avatar_url, and custom fields |
|
|
629
|
+
| `isLoaded` | `boolean` | Whether auth state is loaded |
|
|
630
|
+
| `updateUser(profile)` | `Promise` | Update user profile data |
|
|
475
631
|
|
|
476
632
|
### `usePublicAuthConfig()`
|
|
477
633
|
|
|
478
|
-
Get your authentication
|
|
634
|
+
Get your authentication configuration from InsForge backend:
|
|
479
635
|
|
|
480
636
|
```tsx
|
|
481
|
-
import { usePublicAuthConfig } from '@insforge/react
|
|
637
|
+
import { usePublicAuthConfig } from '@insforge/react';
|
|
482
638
|
|
|
483
|
-
function
|
|
484
|
-
const { authConfig
|
|
485
|
-
|
|
486
|
-
if (!isLoaded) return <div>Loading...</div>;
|
|
639
|
+
function CustomSignIn() {
|
|
640
|
+
const { authConfig } = usePublicAuthConfig();
|
|
487
641
|
|
|
488
642
|
return (
|
|
489
643
|
<div>
|
|
490
|
-
<p>Available OAuth: {authConfig
|
|
644
|
+
<p>Available OAuth: {authConfig?.oAuthProviders?.join(', ')}</p>
|
|
491
645
|
<p>Password min length: {authConfig?.passwordMinLength}</p>
|
|
646
|
+
<p>Require uppercase: {authConfig?.requireUppercase ? 'Yes' : 'No'}</p>
|
|
492
647
|
</div>
|
|
493
648
|
);
|
|
494
649
|
}
|
|
@@ -496,24 +651,32 @@ function SignInPage() {
|
|
|
496
651
|
|
|
497
652
|
**Returns:**
|
|
498
653
|
|
|
499
|
-
|
|
500
|
-
|
|
654
|
+
| Property | Type | Description |
|
|
655
|
+
|----------|------|-------------|
|
|
656
|
+
| `authConfig` | `object \| null` | Auth configuration from dashboard |
|
|
657
|
+
| `authConfig.oAuthProviders` | `["google", "github", "discord", "linkedin", "facebook", "instagram", "tiktok", "apple", "x", "spotify", "microsoft"]` | Enabled OAuth providers |
|
|
658
|
+
| `authConfig.passwordMinLength` | `number` | Minimum password length |
|
|
659
|
+
| `authConfig.requireUppercase` | `boolean` | Require uppercase letter |
|
|
660
|
+
| `authConfig.requireLowercase` | `boolean` | Require lowercase letter |
|
|
661
|
+
| `authConfig.requireNumber` | `boolean` | Require number |
|
|
662
|
+
| `authConfig.requireSpecialChar` | `boolean` | Require special character |
|
|
501
663
|
|
|
502
664
|
<Warning>
|
|
503
|
-
**Performance**: Only use this hook in SignIn/SignUp components
|
|
665
|
+
**Performance**: Only use this hook in SignIn/SignUp components. Using it elsewhere causes unnecessary API calls on every page load.
|
|
504
666
|
</Warning>
|
|
505
667
|
|
|
506
668
|
---
|
|
507
669
|
|
|
508
670
|
## Advanced Features
|
|
509
671
|
|
|
510
|
-
###
|
|
672
|
+
### InsforgeProvider Props
|
|
511
673
|
|
|
512
|
-
|
|
674
|
+
The provider accepts several optional props for advanced use cases:
|
|
513
675
|
|
|
514
676
|
```tsx
|
|
515
677
|
<InsforgeProvider
|
|
516
|
-
|
|
678
|
+
client={insforge}
|
|
679
|
+
afterSignInUrl="/dashboard"
|
|
517
680
|
onAuthChange={(user) => {
|
|
518
681
|
if (user) {
|
|
519
682
|
console.log('User signed in:', user.email);
|
|
@@ -523,7 +686,48 @@ Track authentication state changes:
|
|
|
523
686
|
analytics.reset();
|
|
524
687
|
}
|
|
525
688
|
}}
|
|
689
|
+
onSignIn={async (authToken, user) => {
|
|
690
|
+
// Sync token to cookies for SSR (Next.js)
|
|
691
|
+
await fetch('/api/auth/sync', {
|
|
692
|
+
method: 'POST',
|
|
693
|
+
body: JSON.stringify({ token: authToken }),
|
|
694
|
+
});
|
|
695
|
+
}}
|
|
696
|
+
onSignOut={async () => {
|
|
697
|
+
// Clear server-side session
|
|
698
|
+
await fetch('/api/auth/logout', { method: 'POST' });
|
|
699
|
+
}}
|
|
526
700
|
>
|
|
527
701
|
{children}
|
|
528
702
|
</InsforgeProvider>
|
|
529
703
|
```
|
|
704
|
+
|
|
705
|
+
**Props:**
|
|
706
|
+
|
|
707
|
+
| Prop | Type | Default | Description |
|
|
708
|
+
|------|------|---------|-------------|
|
|
709
|
+
| `client` | `InsForgeClient` | **required** | SDK client instance |
|
|
710
|
+
| `afterSignInUrl` | `string` | `"/"` | Default redirect URL after sign in |
|
|
711
|
+
| `onAuthChange` | `(user: InsforgeUser \| null) => void` | - | Callback when auth state changes |
|
|
712
|
+
| `onSignIn` | `(authToken: string, user: InsforgeUser) => Promise<void>` | - | Custom handler after sign-in (e.g., cookie sync) |
|
|
713
|
+
| `onSignOut` | `() => Promise<void>` | - | Custom handler after sign-out |
|
|
714
|
+
| `onRefresh` | `(authToken: string, user: InsforgeUser) => Promise<void>` | - | Custom handler after token refresh |
|
|
715
|
+
|
|
716
|
+
### Text Customization
|
|
717
|
+
|
|
718
|
+
All complete components support full text customization:
|
|
719
|
+
|
|
720
|
+
```tsx
|
|
721
|
+
<SignIn
|
|
722
|
+
title="Welcome Back!"
|
|
723
|
+
subtitle="We're happy to see you again"
|
|
724
|
+
emailLabel="Your Email Address"
|
|
725
|
+
emailPlaceholder="you@company.com"
|
|
726
|
+
passwordLabel="Your Password"
|
|
727
|
+
submitButtonText="Login Now"
|
|
728
|
+
loadingButtonText="Signing you in..."
|
|
729
|
+
signUpText="New to our platform?"
|
|
730
|
+
signUpLinkText="Create an account"
|
|
731
|
+
dividerText="or continue with"
|
|
732
|
+
/>
|
|
733
|
+
```
|