insforge 1.2.10 → 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/.claude-plugin/marketplace.json +20 -20
- package/.dockerignore +60 -60
- package/.env.example +83 -77
- package/.github/ISSUE_TEMPLATE/bug_report.yml +36 -36
- package/.github/ISSUE_TEMPLATE/config.yml +11 -11
- package/.github/ISSUE_TEMPLATE/feature_request.yml +26 -26
- package/.github/PULL_REQUEST_TEMPLATE.md +7 -7
- package/.github/copilot-instructions.md +146 -146
- package/.github/workflows/build-image.yml +65 -65
- package/.github/workflows/ci-premerge-check.yml +23 -23
- package/.github/workflows/e2e.yml +63 -63
- package/.github/workflows/lint-and-format.yml +32 -32
- package/.prettierignore +64 -64
- package/CHANGELOG.md +46 -44
- package/CLAUDE_PLUGIN.md +104 -104
- package/CODE_OF_CONDUCT.md +128 -128
- package/CONTRIBUTING.md +125 -125
- package/Dockerfile +30 -30
- package/GITHUB_OAUTH_SETUP.md +49 -49
- package/GOOGLE_OAUTH_SETUP.md +148 -148
- package/LICENSE +201 -201
- package/README.md +182 -182
- package/assets/Dark.svg +23 -23
- package/auth/package.json +30 -28
- package/auth/src/lib/broadcastService.ts +4 -4
- package/auth/src/lib/insforge.ts +8 -0
- package/auth/src/main.tsx +2 -4
- package/auth/src/pages/SignInPage.tsx +5 -2
- package/auth/src/pages/SignUpPage.tsx +5 -2
- package/auth/src/pages/VerifyEmailPage.tsx +18 -0
- package/auth/tsconfig.json +33 -32
- package/auth/tsconfig.node.json +11 -11
- package/backend/package.json +82 -75
- 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 +720 -570
- package/backend/src/api/routes/auth/oauth.routes.ts +478 -448
- package/backend/src/api/routes/database/advance.routes.ts +37 -16
- package/backend/src/api/routes/database/index.routes.ts +80 -1
- package/backend/src/api/routes/database/records.routes.ts +48 -184
- package/backend/src/api/routes/database/rpc.routes.ts +69 -0
- package/backend/src/api/routes/database/tables.routes.ts +0 -14
- package/backend/src/api/routes/deployments/index.routes.ts +192 -0
- package/backend/src/api/routes/docs/index.routes.ts +76 -76
- package/backend/src/api/routes/email/index.routes.ts +35 -0
- package/backend/src/api/routes/functions/index.routes.ts +21 -15
- package/backend/src/api/routes/metadata/index.routes.ts +38 -0
- package/backend/src/api/routes/realtime/channels.routes.ts +81 -0
- package/backend/src/api/routes/realtime/index.routes.ts +12 -0
- package/backend/src/api/routes/realtime/messages.routes.ts +48 -0
- package/backend/src/api/routes/realtime/permissions.routes.ts +19 -0
- package/backend/src/api/routes/storage/index.routes.ts +18 -12
- package/backend/src/api/routes/usage/index.routes.ts +6 -4
- package/backend/src/api/routes/webhooks/index.routes.ts +109 -0
- package/backend/src/infra/database/database.manager.ts +14 -11
- package/backend/src/infra/database/migrations/000_create-base-tables.sql +141 -141
- package/backend/src/infra/database/migrations/001_create-helper-functions.sql +40 -40
- package/backend/src/infra/database/migrations/002_rename-auth-tables.sql +29 -29
- package/backend/src/infra/database/migrations/003_create-users-table.sql +55 -55
- package/backend/src/infra/database/migrations/004_add-reload-postgrest-func.sql +23 -23
- package/backend/src/infra/database/migrations/005_enable-project-admin-modify-users.sql +29 -29
- package/backend/src/infra/database/migrations/006_modify-ai-usage-table.sql +24 -24
- package/backend/src/infra/database/migrations/007_drop-metadata-table.sql +1 -1
- package/backend/src/infra/database/migrations/008_add-system-tables.sql +76 -76
- package/backend/src/infra/database/migrations/009_add-function-secrets.sql +23 -23
- package/backend/src/infra/database/migrations/010_modify-ai-config-modalities.sql +93 -93
- package/backend/src/infra/database/migrations/011_refactor-secrets-table.sql +15 -15
- package/backend/src/infra/database/migrations/012_add-storage-uploaded-by.sql +7 -7
- package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -44
- package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +7 -7
- package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +59 -59
- package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -24
- package/backend/src/infra/database/migrations/017_create-realtime-schema.sql +233 -0
- 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/realtime/realtime.manager.ts +246 -0
- package/backend/src/infra/realtime/webhook-sender.ts +82 -0
- package/backend/src/infra/security/token.manager.ts +216 -125
- package/backend/src/infra/socket/socket.manager.ts +198 -64
- package/backend/src/providers/ai/openrouter.provider.ts +24 -12
- 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/providers/email/base.provider.ts +4 -7
- package/backend/src/providers/email/cloud.provider.ts +84 -0
- package/backend/src/providers/oauth/apple.provider.ts +266 -0
- package/backend/src/providers/oauth/index.ts +1 -0
- package/backend/src/server.ts +329 -284
- 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/image-generation.service.ts +3 -3
- 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 +148 -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 -94
- package/backend/src/services/database/database.service.ts +127 -0
- 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/email/email.service.ts +5 -7
- package/backend/src/services/functions/function.service.ts +61 -41
- package/backend/src/services/logs/audit.service.ts +10 -10
- package/backend/src/services/realtime/index.ts +3 -0
- package/backend/src/services/realtime/realtime-auth.service.ts +104 -0
- package/backend/src/services/realtime/realtime-channel.service.ts +237 -0
- package/backend/src/services/realtime/realtime-message.service.ts +260 -0
- 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 +16 -1
- package/backend/src/types/database.ts +2 -0
- package/backend/src/types/deployments.ts +33 -0
- package/backend/src/types/realtime.ts +18 -0
- package/backend/src/types/socket.ts +7 -31
- package/backend/src/types/storage.ts +1 -1
- package/backend/src/types/webhooks.ts +45 -0
- package/backend/src/utils/cookies.ts +34 -0
- package/backend/src/utils/environment.ts +0 -14
- package/backend/src/utils/s3-config-loader.ts +64 -0
- package/backend/src/utils/seed.ts +79 -43
- package/backend/src/utils/sql-parser.ts +216 -0
- package/backend/src/utils/utils.ts +114 -114
- package/backend/src/utils/validations.ts +10 -10
- package/backend/tests/README.md +133 -133
- package/backend/tests/cleanup-all-test-data.sh +230 -230
- package/backend/tests/cloud/test-s3-multitenant.sh +131 -131
- package/backend/tests/local/comprehensive-curl-tests.sh +155 -155
- package/backend/tests/local/test-ai-config.sh +129 -129
- package/backend/tests/local/test-ai-usage.sh +80 -80
- package/backend/tests/local/test-auth-router.sh +143 -143
- package/backend/tests/local/test-database-router.sh +222 -222
- package/backend/tests/local/test-e2e.sh +240 -240
- package/backend/tests/local/test-fk-errors.sh +96 -96
- package/backend/tests/local/test-functions.sh +123 -123
- package/backend/tests/local/test-id-field.sh +200 -200
- package/backend/tests/local/test-logs.sh +132 -132
- package/backend/tests/local/test-public-bucket.sh +264 -264
- package/backend/tests/local/test-rpc.sh +141 -0
- package/backend/tests/local/test-secrets.sh +249 -249
- package/backend/tests/local/test-serverless-functions.sh.disabled +325 -325
- package/backend/tests/local/test-traditional-rest.sh +208 -208
- package/backend/tests/manual/README.md +50 -50
- package/backend/tests/manual/create-large-table-simple.sql +10 -10
- package/backend/tests/manual/seed-large-table.sql +100 -100
- package/backend/tests/manual/setup-large-table-extras.sql +33 -33
- package/backend/tests/manual/test-ai-model-plugins.sh +258 -0
- package/backend/tests/manual/test-bulk-upsert.sh +409 -409
- package/backend/tests/manual/test-database-advance.sh +296 -296
- package/backend/tests/manual/test-postgrest-stability.sh +191 -191
- package/backend/tests/manual/test-rawsql-export-import.sh +411 -411
- package/backend/tests/manual/test-rawsql-modes.sh +244 -244
- package/backend/tests/manual/test-universal-storage.sh +263 -263
- package/backend/tests/manual/test-users.sql +17 -17
- package/backend/tests/run-all-tests.sh +139 -139
- package/backend/tests/setup.ts +0 -0
- package/backend/tests/test-config.sh +338 -338
- package/backend/tests/unit/analyze-query.test.ts +697 -0
- package/backend/tests/unit/database-advance.test.ts +326 -0
- package/backend/tests/unit/helpers.test.ts +2 -2
- package/backend/tsconfig.json +22 -22
- package/claude-plugin/.claude-plugin/plugin.json +24 -24
- package/claude-plugin/README.md +133 -133
- package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +273 -270
- package/docker-compose.prod.yml +204 -200
- package/docker-compose.yml +232 -228
- package/docker-init/db/db-init.sql +97 -97
- package/docker-init/db/jwt.sql +5 -5
- package/docker-init/db/postgresql.conf +16 -16
- package/docker-init/logs/vector.yml +236 -236
- package/docs/README.md +44 -44
- package/docs/agent-docs/deployment.md +79 -0
- package/docs/agent-docs/real-time.md +269 -0
- package/docs/changelog.mdx +212 -67
- package/docs/core-concepts/ai/architecture.mdx +350 -372
- package/docs/core-concepts/ai/sdk.mdx +238 -213
- package/docs/core-concepts/authentication/architecture.mdx +276 -278
- package/docs/core-concepts/authentication/sdk.mdx +710 -414
- package/docs/core-concepts/authentication/ui-components/customization.mdx +733 -529
- package/docs/core-concepts/authentication/ui-components/nextjs.mdx +247 -221
- package/docs/core-concepts/authentication/ui-components/react-router.mdx +183 -184
- package/docs/core-concepts/authentication/ui-components/react.mdx +136 -129
- package/docs/core-concepts/database/architecture.mdx +292 -255
- package/docs/core-concepts/database/pgvector.mdx +138 -0
- package/docs/core-concepts/database/sdk.mdx +382 -382
- package/docs/core-concepts/deployments/architecture.mdx +152 -0
- package/docs/core-concepts/email/architecture.mdx +103 -0
- package/docs/core-concepts/email/sdk.mdx +53 -0
- package/docs/core-concepts/functions/architecture.mdx +105 -105
- package/docs/core-concepts/functions/sdk.mdx +183 -184
- package/docs/core-concepts/realtime/architecture.mdx +446 -0
- package/docs/core-concepts/realtime/sdk.mdx +409 -0
- package/docs/core-concepts/storage/architecture.mdx +243 -243
- package/docs/core-concepts/storage/sdk.mdx +253 -253
- package/docs/deployment/README.md +94 -94
- package/docs/deployment/deploy-to-aws-ec2.md +564 -564
- package/docs/deployment/deploy-to-azure-virtual-machines.md +312 -312
- package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -613
- package/docs/deployment/deploy-to-render.md +441 -441
- package/docs/deprecated/insforge-auth-api.md +214 -214
- package/docs/deprecated/insforge-auth-sdk.md +99 -99
- package/docs/deprecated/insforge-db-api.md +358 -358
- package/docs/deprecated/insforge-db-sdk.md +139 -139
- package/docs/deprecated/insforge-debug-sdk.md +156 -156
- package/docs/deprecated/insforge-debug.md +64 -64
- package/docs/deprecated/insforge-instructions.md +123 -123
- package/docs/deprecated/insforge-project.md +117 -117
- package/docs/deprecated/insforge-storage-api.md +278 -278
- package/docs/deprecated/insforge-storage-sdk.md +158 -158
- package/docs/docs.json +240 -210
- package/docs/examples/framework-guides/nextjs.mdx +131 -131
- package/docs/examples/framework-guides/nuxt.mdx +165 -165
- package/docs/examples/framework-guides/react.mdx +165 -165
- package/docs/examples/framework-guides/svelte.mdx +153 -153
- package/docs/examples/framework-guides/vue.mdx +159 -159
- package/docs/examples/overview.mdx +67 -67
- package/docs/favicon.png +0 -0
- package/docs/favicon.svg +4 -19
- package/docs/images/changelog/dec-2025/ai-integration.png +0 -0
- package/docs/images/changelog/dec-2025/ai-models.webp +0 -0
- package/docs/images/changelog/dec-2025/alipay-payment.webp +0 -0
- package/docs/images/changelog/dec-2025/apple-login.jpg +0 -0
- package/docs/images/changelog/dec-2025/apple-oauth.mp4 +0 -0
- package/docs/images/changelog/dec-2025/mcp-installer.png +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/realtime-module.jpg +0 -0
- package/docs/images/changelog/dec-2025/realtime2.png +0 -0
- package/docs/images/icons/ai.svg +4 -4
- package/docs/images/logos/nextjs.svg +4 -4
- package/docs/images/logos/nuxt.svg +4 -4
- package/docs/images/logos/react.svg +5 -5
- package/docs/images/logos/svelte.svg +4 -4
- package/docs/images/logos/vue.svg +5 -5
- 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 +93 -88
- package/docs/introduction.mdx +46 -45
- package/docs/logo/dark.svg +22 -22
- package/docs/logo/light.svg +20 -20
- package/docs/mcp-setup.mdx +332 -0
- package/docs/oauth-server.mdx +563 -0
- package/docs/partnership.mdx +720 -646
- package/docs/quickstart.mdx +82 -82
- package/docs/showcase.mdx +52 -52
- package/docs/snippets/sdk-installation.mdx +21 -21
- package/docs/snippets/service-icons.mdx +27 -27
- package/docs/vscode-extension.mdx +74 -0
- package/eslint.config.js +1 -0
- package/examples/oauth/frontend-oauth-example.html +250 -250
- package/examples/response-examples.md +443 -443
- package/frontend/components.json +17 -17
- package/frontend/package.json +69 -69
- package/frontend/src/App.tsx +8 -3
- package/frontend/src/assets/icons/checkbox_checked.svg +6 -6
- package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -6
- package/frontend/src/assets/icons/checked.svg +3 -3
- package/frontend/src/assets/icons/connected.svg +3 -3
- package/frontend/src/assets/icons/error.svg +3 -3
- package/frontend/src/assets/icons/loader.svg +9 -9
- package/frontend/src/assets/icons/pencil.svg +4 -4
- package/frontend/src/assets/icons/refresh.svg +4 -4
- package/frontend/src/assets/icons/step_active.svg +3 -3
- package/frontend/src/assets/icons/step_inactive.svg +11 -11
- package/frontend/src/assets/icons/warning.svg +3 -3
- package/frontend/src/assets/logos/antigravity.svg +1 -0
- package/frontend/src/assets/logos/apple.svg +3 -3
- package/frontend/src/assets/logos/claude_code.svg +3 -3
- package/frontend/src/assets/logos/cline.svg +6 -6
- package/frontend/src/assets/logos/copilot.svg +10 -0
- package/frontend/src/assets/logos/cursor.svg +20 -20
- package/frontend/src/assets/logos/deepseek.svg +139 -0
- package/frontend/src/assets/logos/discord.svg +8 -8
- package/frontend/src/assets/logos/facebook.svg +3 -3
- package/frontend/src/assets/logos/gemini.svg +19 -19
- package/frontend/src/assets/logos/github.svg +5 -5
- package/frontend/src/assets/logos/google.svg +13 -13
- package/frontend/src/assets/logos/grok.svg +10 -10
- package/frontend/src/assets/logos/insforge_dark.svg +15 -15
- package/frontend/src/assets/logos/insforge_light.svg +15 -15
- package/frontend/src/assets/logos/instagram.svg +1 -1
- package/frontend/src/assets/logos/kiro.svg +9 -0
- package/frontend/src/assets/logos/linkedin.svg +3 -3
- package/frontend/src/assets/logos/openai.svg +10 -10
- package/frontend/src/assets/logos/qoder.svg +4 -0
- package/frontend/src/assets/logos/qwen.svg +15 -0
- package/frontend/src/assets/logos/roo_code.svg +9 -9
- package/frontend/src/assets/logos/spotify.svg +16 -16
- package/frontend/src/assets/logos/tiktok.svg +5 -5
- package/frontend/src/assets/logos/trae.svg +3 -3
- package/frontend/src/assets/logos/windsurf.svg +10 -10
- package/frontend/src/assets/logos/x.svg +3 -3
- 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 +13 -37
- 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/{page → pages}/AIPage.tsx +166 -166
- package/frontend/src/features/auth/components/AuthPreview.tsx +96 -96
- package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +1 -0
- package/frontend/src/features/auth/components/UsersDataGrid.tsx +61 -31
- package/frontend/src/features/auth/components/index.ts +5 -5
- package/frontend/src/features/auth/helpers.tsx +8 -0
- package/frontend/src/features/auth/{page → pages}/AuthMethodsPage.tsx +275 -275
- package/frontend/src/features/auth/{page → pages}/UsersPage.tsx +0 -28
- package/frontend/src/features/dashboard/{page → 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/SQLModal.tsx +75 -0
- package/frontend/src/features/database/components/TableForm.tsx +0 -4
- 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/useDatabase.ts +66 -0
- package/frontend/src/features/database/hooks/useRawSQL.ts +3 -2
- package/frontend/src/features/database/hooks/useTables.ts +30 -28
- package/frontend/src/features/database/index.ts +1 -0
- package/frontend/src/features/database/{page → pages}/FunctionsPage.tsx +29 -42
- package/frontend/src/features/database/{page → pages}/IndexesPage.tsx +34 -51
- package/frontend/src/features/database/{page → pages}/PoliciesPage.tsx +42 -58
- package/frontend/src/features/database/{page → pages}/SQLEditorPage.tsx +2 -2
- package/frontend/src/features/database/{page → pages}/TablesPage.tsx +0 -42
- package/frontend/src/features/database/{page → pages}/TriggersPage.tsx +34 -51
- package/frontend/src/features/database/services/advance.service.ts +1 -41
- package/frontend/src/features/database/services/database.service.ts +55 -0
- package/frontend/src/features/database/services/record.service.ts +4 -20
- package/frontend/src/features/database/services/table.service.ts +1 -10
- 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/{page → pages}/FunctionsPage.tsx +21 -44
- package/frontend/src/features/functions/{page → pages}/SecretsPage.tsx +118 -116
- 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/{page → 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/hooks/useMcpUsage.ts +13 -66
- package/frontend/src/features/logs/{page → 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/realtime/components/ChannelRow.tsx +83 -0
- package/frontend/src/features/realtime/components/EditChannelModal.tsx +246 -0
- package/frontend/src/features/realtime/components/MessageRow.tsx +85 -0
- package/frontend/src/features/realtime/components/RealtimeEmptyState.tsx +30 -0
- package/frontend/src/features/realtime/hooks/useRealtime.ts +218 -0
- package/frontend/src/features/realtime/index.ts +11 -0
- package/frontend/src/features/realtime/pages/RealtimeChannelsPage.tsx +172 -0
- package/frontend/src/features/realtime/pages/RealtimeMessagesPage.tsx +211 -0
- package/frontend/src/features/realtime/pages/RealtimePermissionsPage.tsx +191 -0
- package/frontend/src/features/realtime/services/realtime.service.ts +107 -0
- package/frontend/src/features/settings/pages/SettingsPage.tsx +349 -0
- package/frontend/src/features/storage/{page → pages}/StoragePage.tsx +1 -29
- package/frontend/src/features/visualizer/components/AuthNode.tsx +4 -4
- package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +24 -11
- package/frontend/src/features/visualizer/{page → pages}/VisualizerPage.tsx +11 -36
- package/frontend/src/index.css +249 -249
- package/frontend/src/lib/contexts/ModalContext.tsx +35 -0
- package/frontend/src/lib/contexts/SocketContext.tsx +119 -75
- 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 -84
- package/frontend/src/lib/services/metadata.service.ts +20 -3
- package/frontend/src/lib/utils/cloudMessaging.ts +1 -1
- package/frontend/src/lib/utils/menuItems.ts +223 -183
- package/frontend/src/lib/utils/utils.ts +196 -183
- package/frontend/tsconfig.json +25 -25
- package/frontend/tsconfig.node.json +9 -9
- package/functions/deno.json +24 -24
- package/functions/server.ts +6 -6
- package/functions/worker-template.js +1 -1
- package/i18n/README.ar.md +130 -130
- package/i18n/README.de.md +130 -130
- package/i18n/README.es.md +154 -154
- package/i18n/README.fr.md +134 -134
- package/i18n/README.hi.md +129 -129
- package/i18n/README.ja.md +174 -174
- package/i18n/README.ko.md +136 -136
- package/i18n/README.pt-BR.md +131 -131
- package/i18n/README.ru.md +129 -129
- package/i18n/README.zh-CN.md +133 -133
- package/openapi/ai.yaml +825 -715
- package/openapi/auth.yaml +1324 -1244
- package/openapi/email.yaml +158 -0
- package/openapi/functions.yaml +475 -475
- package/openapi/health.yaml +29 -29
- package/openapi/logs.yaml +221 -223
- package/openapi/metadata.yaml +175 -177
- package/openapi/realtime.yaml +699 -0
- package/openapi/records.yaml +381 -381
- package/openapi/secrets.yaml +370 -370
- package/openapi/storage.yaml +875 -875
- package/openapi/tables.yaml +462 -463
- package/package.json +97 -97
- package/shared-schemas/package.json +31 -31
- package/shared-schemas/src/ai-api.schema.ts +251 -143
- package/shared-schemas/src/ai.schema.ts +8 -4
- package/shared-schemas/src/auth-api.schema.ts +380 -339
- package/shared-schemas/src/auth.schema.ts +18 -11
- package/shared-schemas/src/cloud-events.schema.ts +26 -0
- package/shared-schemas/src/database-api.schema.ts +32 -1
- package/shared-schemas/src/database.schema.ts +39 -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 +32 -0
- package/shared-schemas/src/email-api.schema.ts +30 -0
- 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 -14
- package/shared-schemas/src/metadata.schema.ts +39 -4
- package/shared-schemas/src/realtime-api.schema.ts +111 -0
- package/shared-schemas/src/realtime.schema.ts +143 -0
- package/shared-schemas/src/secrets-api.schema.ts +44 -0
- package/shared-schemas/src/secrets.schema.ts +15 -0
- package/shared-schemas/tsconfig.json +21 -21
- package/tsconfig.json +7 -7
- package/zeabur/README.md +26 -13
- package/zeabur/template.yml +1001 -1032
- package/.cursor/rules/cursor-rules.mdc +0 -94
- package/backend/src/types/profile.ts +0 -55
- package/frontend/src/components/ProjectInfoModal.tsx +0 -128
- package/frontend/src/features/database/hooks/useFullMetadata.ts +0 -18
- package/test-gemini.sh +0 -35
- package/test-usage-admin.sh +0 -57
- package/test-usage.sh +0 -50
- /package/frontend/src/features/auth/{page → pages}/ConfigurationPage.tsx +0 -0
- /package/frontend/src/features/database/{page → pages}/TemplatesPage.tsx +0 -0
- /package/frontend/src/features/login/{page → pages}/LoginPage.tsx +0 -0
- /package/frontend/src/features/logs/{page → pages}/AuditsPage.tsx +0 -0
- /package/frontend/src/features/logs/{page → pages}/MCPLogsPage.tsx +0 -0
|
@@ -1,275 +1,275 @@
|
|
|
1
|
-
import { useState, useCallback, useMemo } from 'react';
|
|
2
|
-
import { MoreHorizontal, Plus, Trash2, Pencil, Mail, ChevronDown } from 'lucide-react';
|
|
3
|
-
import { OAuthConfigDialog, AuthPreview } from '@/features/auth/components';
|
|
4
|
-
import { useOAuthConfig } from '@/features/auth/hooks/useOAuthConfig';
|
|
5
|
-
import { useConfirm } from '@/lib/hooks/useConfirm';
|
|
6
|
-
import {
|
|
7
|
-
Button,
|
|
8
|
-
ConfirmDialog,
|
|
9
|
-
CopyButton,
|
|
10
|
-
DropdownMenu,
|
|
11
|
-
DropdownMenuContent,
|
|
12
|
-
DropdownMenuItem,
|
|
13
|
-
DropdownMenuTrigger,
|
|
14
|
-
DropdownMenuSeparator,
|
|
15
|
-
} from '@/components';
|
|
16
|
-
import type { OAuthProvidersSchema } from '@insforge/shared-schemas';
|
|
17
|
-
import {
|
|
18
|
-
oauthProviders,
|
|
19
|
-
type OAuthProviderInfo,
|
|
20
|
-
getAuthImplementationPrompt,
|
|
21
|
-
} from '@/features/auth/helpers';
|
|
22
|
-
import { getBackendUrl } from '@/lib/utils/utils';
|
|
23
|
-
|
|
24
|
-
export default function AuthMethodsPage() {
|
|
25
|
-
const [selectedProvider, setSelectedProvider] = useState<OAuthProviderInfo>();
|
|
26
|
-
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
27
|
-
const { confirm, confirmDialogProps } = useConfirm();
|
|
28
|
-
const {
|
|
29
|
-
configs,
|
|
30
|
-
isLoadingConfigs,
|
|
31
|
-
deleteConfig,
|
|
32
|
-
refetchConfigs,
|
|
33
|
-
getProviderConfig,
|
|
34
|
-
isProviderConfigured,
|
|
35
|
-
} = useOAuthConfig();
|
|
36
|
-
|
|
37
|
-
const handleConfigureProvider = (provider: OAuthProviderInfo) => {
|
|
38
|
-
setSelectedProvider(provider);
|
|
39
|
-
setIsDialogOpen(true);
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const deleteOAuthConfig = async (providerId: OAuthProvidersSchema, providerName: string) => {
|
|
43
|
-
const shouldDelete = await confirm({
|
|
44
|
-
title: `Delete ${providerName} OAuth`,
|
|
45
|
-
description: `Are you sure you want to delete the ${providerName} configuration? This action cannot be undone.`,
|
|
46
|
-
confirmText: 'Delete',
|
|
47
|
-
cancelText: 'Cancel',
|
|
48
|
-
destructive: true,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
if (shouldDelete) {
|
|
52
|
-
deleteConfig(providerId);
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const handleCloseDialog = () => {
|
|
57
|
-
setIsDialogOpen(false);
|
|
58
|
-
setSelectedProvider(undefined);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const hasAuthMethods = useMemo(() => {
|
|
62
|
-
return !!configs.length;
|
|
63
|
-
}, [configs]);
|
|
64
|
-
|
|
65
|
-
const enabledProviders = useMemo(() => {
|
|
66
|
-
const enabled: Record<OAuthProvidersSchema, boolean> = {} as Record<
|
|
67
|
-
OAuthProvidersSchema,
|
|
68
|
-
boolean
|
|
69
|
-
>;
|
|
70
|
-
oauthProviders.forEach((provider) => {
|
|
71
|
-
enabled[provider.id] = isProviderConfigured(provider.id);
|
|
72
|
-
});
|
|
73
|
-
return enabled;
|
|
74
|
-
}, [isProviderConfigured]);
|
|
75
|
-
|
|
76
|
-
// Check if all providers are enabled
|
|
77
|
-
const allProvidersEnabled = useMemo(() => {
|
|
78
|
-
return oauthProviders.every((provider) => enabledProviders[provider.id]);
|
|
79
|
-
}, [enabledProviders]);
|
|
80
|
-
|
|
81
|
-
const handleSuccess = useCallback(() => {
|
|
82
|
-
// Refresh configuration after successful update
|
|
83
|
-
void refetchConfigs();
|
|
84
|
-
}, [refetchConfigs]);
|
|
85
|
-
|
|
86
|
-
if (isLoadingConfigs) {
|
|
87
|
-
return (
|
|
88
|
-
<div className="h-full bg-slate-50 dark:bg-neutral-800 flex flex-col overflow-hidden">
|
|
89
|
-
<div className="flex-1 flex items-center justify-center">
|
|
90
|
-
<div className="text-center">
|
|
91
|
-
<div className="text-sm text-gray-500 dark:text-zinc-400">
|
|
92
|
-
Loading OAuth configuration...
|
|
93
|
-
</div>
|
|
94
|
-
</div>
|
|
95
|
-
</div>
|
|
96
|
-
</div>
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return (
|
|
101
|
-
<div className="h-full flex flex-col overflow-hidden">
|
|
102
|
-
{/* Two column layout */}
|
|
103
|
-
<div className="h-full flex overflow-hidden">
|
|
104
|
-
{/* Left Section - Auth Methods List */}
|
|
105
|
-
<div className="flex-1 bg-slate-50 dark:bg-[#2d2d2d] flex flex-col overflow-hidden">
|
|
106
|
-
{/* Header */}
|
|
107
|
-
<div className="flex items-center justify-between px-4 py-6 gap-3">
|
|
108
|
-
<h2 className="px-4 text-xl font-semibold text-gray-900 dark:text-white tracking-tight">
|
|
109
|
-
Auth Methods
|
|
110
|
-
</h2>
|
|
111
|
-
{!allProvidersEnabled && (
|
|
112
|
-
<DropdownMenu>
|
|
113
|
-
<DropdownMenuTrigger asChild>
|
|
114
|
-
<Button className="h-8 px-2 py-0 gap-2 bg-black text-white dark:bg-neutral-600 dark:text-white hover:bg-gray-800 dark:hover:bg-neutral-500 text-sm font-medium rounded">
|
|
115
|
-
<Plus className="w-5 h-5" />
|
|
116
|
-
Add Provider
|
|
117
|
-
<ChevronDown className="w-4 h-4" />
|
|
118
|
-
</Button>
|
|
119
|
-
</DropdownMenuTrigger>
|
|
120
|
-
<DropdownMenuContent align="end" className="w-80">
|
|
121
|
-
{/* Available providers (not enabled) */}
|
|
122
|
-
{oauthProviders
|
|
123
|
-
.filter((provider) => !enabledProviders[provider.id])
|
|
124
|
-
.map((provider) => (
|
|
125
|
-
<DropdownMenuItem
|
|
126
|
-
key={provider.id}
|
|
127
|
-
onClick={() => handleConfigureProvider(provider)}
|
|
128
|
-
className="py-2 px-3 flex items-center gap-3 cursor-pointer"
|
|
129
|
-
>
|
|
130
|
-
{provider.icon}
|
|
131
|
-
<span className="text-sm">{provider.name}</span>
|
|
132
|
-
</DropdownMenuItem>
|
|
133
|
-
))}
|
|
134
|
-
|
|
135
|
-
{/* Separator if there are both enabled and disabled providers */}
|
|
136
|
-
{oauthProviders.some((p) => enabledProviders[p.id]) &&
|
|
137
|
-
oauthProviders.some((p) => !enabledProviders[p.id]) && (
|
|
138
|
-
<DropdownMenuSeparator />
|
|
139
|
-
)}
|
|
140
|
-
|
|
141
|
-
{/* Enabled providers (disabled from selection) */}
|
|
142
|
-
{oauthProviders
|
|
143
|
-
.filter((provider) => enabledProviders[provider.id])
|
|
144
|
-
.map((provider) => (
|
|
145
|
-
<DropdownMenuItem
|
|
146
|
-
key={provider.id}
|
|
147
|
-
disabled
|
|
148
|
-
className="py-2 px-3 flex items-center justify-between gap-3 opacity-50 cursor-not-allowed"
|
|
149
|
-
>
|
|
150
|
-
<div className="flex items-center gap-3">
|
|
151
|
-
{provider.icon}
|
|
152
|
-
<span className="text-sm">{provider.name}</span>
|
|
153
|
-
</div>
|
|
154
|
-
<span className="text-xs px-2 py-0.5 bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-400 rounded border border-emerald-300 dark:border-emerald-700">
|
|
155
|
-
Enabled
|
|
156
|
-
</span>
|
|
157
|
-
</DropdownMenuItem>
|
|
158
|
-
))}
|
|
159
|
-
</DropdownMenuContent>
|
|
160
|
-
</DropdownMenu>
|
|
161
|
-
)}
|
|
162
|
-
</div>
|
|
163
|
-
|
|
164
|
-
{/* Auth Methods List */}
|
|
165
|
-
<div className="flex-1 overflow-y-auto p-4">
|
|
166
|
-
<div className="flex flex-col gap-3">
|
|
167
|
-
{/* Email Auth Card */}
|
|
168
|
-
<div className="flex items-center justify-between px-6 py-4 bg-white dark:bg-neutral-800 rounded-lg border border-gray-200 dark:border-transparent">
|
|
169
|
-
<div className="flex items-center gap-3">
|
|
170
|
-
<Mail className="w-6 h-6 text-gray-700 dark:text-white" />
|
|
171
|
-
<div className="text-sm font-medium text-black dark:text-white">Email Auth</div>
|
|
172
|
-
</div>
|
|
173
|
-
</div>
|
|
174
|
-
|
|
175
|
-
{/* OAuth Providers */}
|
|
176
|
-
{hasAuthMethods &&
|
|
177
|
-
oauthProviders.map((provider) => {
|
|
178
|
-
const providerConfig = getProviderConfig(provider.id);
|
|
179
|
-
if (!providerConfig) {
|
|
180
|
-
return null;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return (
|
|
184
|
-
<div
|
|
185
|
-
key={provider.id}
|
|
186
|
-
className="flex items-center justify-between px-6 py-4 bg-white dark:bg-neutral-800 rounded-lg border border-gray-200 dark:border-transparent"
|
|
187
|
-
>
|
|
188
|
-
<div className="flex items-center gap-3">
|
|
189
|
-
{provider.icon}
|
|
190
|
-
<div className="text-sm font-medium text-black dark:text-white">
|
|
191
|
-
{provider.name}
|
|
192
|
-
</div>
|
|
193
|
-
</div>
|
|
194
|
-
|
|
195
|
-
<div className="flex items-center gap-3">
|
|
196
|
-
{providerConfig.useSharedKey && (
|
|
197
|
-
<span className="px-2 py-0.5 text-xs font-medium text-neutral-500 dark:text-neutral-400 border border-neutral-500 dark:border-neutral-400 rounded">
|
|
198
|
-
Shared Keys
|
|
199
|
-
</span>
|
|
200
|
-
)}
|
|
201
|
-
|
|
202
|
-
<DropdownMenu>
|
|
203
|
-
<DropdownMenuTrigger asChild>
|
|
204
|
-
<Button
|
|
205
|
-
className="h-7 w-7 p-1 text-gray-500 dark:text-neutral-400 hover:bg-gray-100 dark:hover:bg-neutral-700"
|
|
206
|
-
variant="ghost"
|
|
207
|
-
size="sm"
|
|
208
|
-
>
|
|
209
|
-
<MoreHorizontal className="w-5 h-5" />
|
|
210
|
-
</Button>
|
|
211
|
-
</DropdownMenuTrigger>
|
|
212
|
-
<DropdownMenuContent align="end" className="w-40 py-1 px-2">
|
|
213
|
-
<DropdownMenuItem
|
|
214
|
-
onClick={() => handleConfigureProvider(provider)}
|
|
215
|
-
className="py-2 px-3 flex items-center gap-3 cursor-pointer"
|
|
216
|
-
>
|
|
217
|
-
<Pencil className="w-5 h-5" />
|
|
218
|
-
Edit
|
|
219
|
-
</DropdownMenuItem>
|
|
220
|
-
<DropdownMenuItem
|
|
221
|
-
onClick={() => void deleteOAuthConfig(provider.id, provider.name)}
|
|
222
|
-
className="py-2 px-3 flex items-center gap-3 cursor-pointer text-red-600 dark:text-red-400"
|
|
223
|
-
>
|
|
224
|
-
<Trash2 className="w-5 h-5" />
|
|
225
|
-
Delete
|
|
226
|
-
</DropdownMenuItem>
|
|
227
|
-
</DropdownMenuContent>
|
|
228
|
-
</DropdownMenu>
|
|
229
|
-
</div>
|
|
230
|
-
</div>
|
|
231
|
-
);
|
|
232
|
-
})}
|
|
233
|
-
</div>
|
|
234
|
-
</div>
|
|
235
|
-
</div>
|
|
236
|
-
|
|
237
|
-
{/* Right Section - Preview */}
|
|
238
|
-
<div className="w-[688px] bg-slate-50 dark:bg-[#2d2d2d] p-3 flex flex-col overflow-hidden">
|
|
239
|
-
<div className="h-full bg-gray-200 dark:bg-neutral-700 rounded-xl overflow-hidden flex flex-col">
|
|
240
|
-
{/* Preview Header */}
|
|
241
|
-
<div className="flex items-center justify-end px-6 py-3 gap-3">
|
|
242
|
-
<p className="text-sm font-medium text-gray-700 dark:text-white">
|
|
243
|
-
Integrate Authentication to Your Application
|
|
244
|
-
</p>
|
|
245
|
-
<CopyButton
|
|
246
|
-
text={getAuthImplementationPrompt(getBackendUrl())}
|
|
247
|
-
copyText="Copy Prompt"
|
|
248
|
-
variant="primary"
|
|
249
|
-
className="w-34"
|
|
250
|
-
/>
|
|
251
|
-
</div>
|
|
252
|
-
|
|
253
|
-
{/* Preview Content */}
|
|
254
|
-
<div className="flex-1 overflow-y-auto py-8 flex flex-col items-center justify-center gap-4">
|
|
255
|
-
<AuthPreview />
|
|
256
|
-
<p className="text-xs text-gray-500 dark:text-neutral-400 text-center">
|
|
257
|
-
Preview Mode
|
|
258
|
-
</p>
|
|
259
|
-
</div>
|
|
260
|
-
</div>
|
|
261
|
-
</div>
|
|
262
|
-
</div>
|
|
263
|
-
|
|
264
|
-
<OAuthConfigDialog
|
|
265
|
-
provider={selectedProvider}
|
|
266
|
-
isOpen={isDialogOpen}
|
|
267
|
-
onClose={handleCloseDialog}
|
|
268
|
-
onSuccess={handleSuccess}
|
|
269
|
-
/>
|
|
270
|
-
|
|
271
|
-
{/* Confirm Dialog */}
|
|
272
|
-
<ConfirmDialog {...confirmDialogProps} />
|
|
273
|
-
</div>
|
|
274
|
-
);
|
|
275
|
-
}
|
|
1
|
+
import { useState, useCallback, useMemo } from 'react';
|
|
2
|
+
import { MoreHorizontal, Plus, Trash2, Pencil, Mail, ChevronDown } from 'lucide-react';
|
|
3
|
+
import { OAuthConfigDialog, AuthPreview } from '@/features/auth/components';
|
|
4
|
+
import { useOAuthConfig } from '@/features/auth/hooks/useOAuthConfig';
|
|
5
|
+
import { useConfirm } from '@/lib/hooks/useConfirm';
|
|
6
|
+
import {
|
|
7
|
+
Button,
|
|
8
|
+
ConfirmDialog,
|
|
9
|
+
CopyButton,
|
|
10
|
+
DropdownMenu,
|
|
11
|
+
DropdownMenuContent,
|
|
12
|
+
DropdownMenuItem,
|
|
13
|
+
DropdownMenuTrigger,
|
|
14
|
+
DropdownMenuSeparator,
|
|
15
|
+
} from '@/components';
|
|
16
|
+
import type { OAuthProvidersSchema } from '@insforge/shared-schemas';
|
|
17
|
+
import {
|
|
18
|
+
oauthProviders,
|
|
19
|
+
type OAuthProviderInfo,
|
|
20
|
+
getAuthImplementationPrompt,
|
|
21
|
+
} from '@/features/auth/helpers';
|
|
22
|
+
import { getBackendUrl } from '@/lib/utils/utils';
|
|
23
|
+
|
|
24
|
+
export default function AuthMethodsPage() {
|
|
25
|
+
const [selectedProvider, setSelectedProvider] = useState<OAuthProviderInfo>();
|
|
26
|
+
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
27
|
+
const { confirm, confirmDialogProps } = useConfirm();
|
|
28
|
+
const {
|
|
29
|
+
configs,
|
|
30
|
+
isLoadingConfigs,
|
|
31
|
+
deleteConfig,
|
|
32
|
+
refetchConfigs,
|
|
33
|
+
getProviderConfig,
|
|
34
|
+
isProviderConfigured,
|
|
35
|
+
} = useOAuthConfig();
|
|
36
|
+
|
|
37
|
+
const handleConfigureProvider = (provider: OAuthProviderInfo) => {
|
|
38
|
+
setSelectedProvider(provider);
|
|
39
|
+
setIsDialogOpen(true);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const deleteOAuthConfig = async (providerId: OAuthProvidersSchema, providerName: string) => {
|
|
43
|
+
const shouldDelete = await confirm({
|
|
44
|
+
title: `Delete ${providerName} OAuth`,
|
|
45
|
+
description: `Are you sure you want to delete the ${providerName} configuration? This action cannot be undone.`,
|
|
46
|
+
confirmText: 'Delete',
|
|
47
|
+
cancelText: 'Cancel',
|
|
48
|
+
destructive: true,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
if (shouldDelete) {
|
|
52
|
+
deleteConfig(providerId);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const handleCloseDialog = () => {
|
|
57
|
+
setIsDialogOpen(false);
|
|
58
|
+
setSelectedProvider(undefined);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const hasAuthMethods = useMemo(() => {
|
|
62
|
+
return !!configs.length;
|
|
63
|
+
}, [configs]);
|
|
64
|
+
|
|
65
|
+
const enabledProviders = useMemo(() => {
|
|
66
|
+
const enabled: Record<OAuthProvidersSchema, boolean> = {} as Record<
|
|
67
|
+
OAuthProvidersSchema,
|
|
68
|
+
boolean
|
|
69
|
+
>;
|
|
70
|
+
oauthProviders.forEach((provider) => {
|
|
71
|
+
enabled[provider.id] = isProviderConfigured(provider.id);
|
|
72
|
+
});
|
|
73
|
+
return enabled;
|
|
74
|
+
}, [isProviderConfigured]);
|
|
75
|
+
|
|
76
|
+
// Check if all providers are enabled
|
|
77
|
+
const allProvidersEnabled = useMemo(() => {
|
|
78
|
+
return oauthProviders.every((provider) => enabledProviders[provider.id]);
|
|
79
|
+
}, [enabledProviders]);
|
|
80
|
+
|
|
81
|
+
const handleSuccess = useCallback(() => {
|
|
82
|
+
// Refresh configuration after successful update
|
|
83
|
+
void refetchConfigs();
|
|
84
|
+
}, [refetchConfigs]);
|
|
85
|
+
|
|
86
|
+
if (isLoadingConfigs) {
|
|
87
|
+
return (
|
|
88
|
+
<div className="h-full bg-slate-50 dark:bg-neutral-800 flex flex-col overflow-hidden">
|
|
89
|
+
<div className="flex-1 flex items-center justify-center">
|
|
90
|
+
<div className="text-center">
|
|
91
|
+
<div className="text-sm text-gray-500 dark:text-zinc-400">
|
|
92
|
+
Loading OAuth configuration...
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<div className="h-full flex flex-col overflow-hidden">
|
|
102
|
+
{/* Two column layout */}
|
|
103
|
+
<div className="h-full flex overflow-hidden">
|
|
104
|
+
{/* Left Section - Auth Methods List */}
|
|
105
|
+
<div className="flex-1 bg-slate-50 dark:bg-[#2d2d2d] flex flex-col overflow-hidden">
|
|
106
|
+
{/* Header */}
|
|
107
|
+
<div className="flex items-center justify-between px-4 py-6 gap-3">
|
|
108
|
+
<h2 className="px-4 text-xl font-semibold text-gray-900 dark:text-white tracking-tight">
|
|
109
|
+
Auth Methods
|
|
110
|
+
</h2>
|
|
111
|
+
{!allProvidersEnabled && (
|
|
112
|
+
<DropdownMenu>
|
|
113
|
+
<DropdownMenuTrigger asChild>
|
|
114
|
+
<Button className="h-8 px-2 py-0 gap-2 bg-black text-white dark:bg-neutral-600 dark:text-white hover:bg-gray-800 dark:hover:bg-neutral-500 text-sm font-medium rounded">
|
|
115
|
+
<Plus className="w-5 h-5" />
|
|
116
|
+
Add Provider
|
|
117
|
+
<ChevronDown className="w-4 h-4" />
|
|
118
|
+
</Button>
|
|
119
|
+
</DropdownMenuTrigger>
|
|
120
|
+
<DropdownMenuContent align="end" className="w-80">
|
|
121
|
+
{/* Available providers (not enabled) */}
|
|
122
|
+
{oauthProviders
|
|
123
|
+
.filter((provider) => !enabledProviders[provider.id])
|
|
124
|
+
.map((provider) => (
|
|
125
|
+
<DropdownMenuItem
|
|
126
|
+
key={provider.id}
|
|
127
|
+
onClick={() => handleConfigureProvider(provider)}
|
|
128
|
+
className="py-2 px-3 flex items-center gap-3 cursor-pointer"
|
|
129
|
+
>
|
|
130
|
+
{provider.icon}
|
|
131
|
+
<span className="text-sm">{provider.name}</span>
|
|
132
|
+
</DropdownMenuItem>
|
|
133
|
+
))}
|
|
134
|
+
|
|
135
|
+
{/* Separator if there are both enabled and disabled providers */}
|
|
136
|
+
{oauthProviders.some((p) => enabledProviders[p.id]) &&
|
|
137
|
+
oauthProviders.some((p) => !enabledProviders[p.id]) && (
|
|
138
|
+
<DropdownMenuSeparator />
|
|
139
|
+
)}
|
|
140
|
+
|
|
141
|
+
{/* Enabled providers (disabled from selection) */}
|
|
142
|
+
{oauthProviders
|
|
143
|
+
.filter((provider) => enabledProviders[provider.id])
|
|
144
|
+
.map((provider) => (
|
|
145
|
+
<DropdownMenuItem
|
|
146
|
+
key={provider.id}
|
|
147
|
+
disabled
|
|
148
|
+
className="py-2 px-3 flex items-center justify-between gap-3 opacity-50 cursor-not-allowed"
|
|
149
|
+
>
|
|
150
|
+
<div className="flex items-center gap-3">
|
|
151
|
+
{provider.icon}
|
|
152
|
+
<span className="text-sm">{provider.name}</span>
|
|
153
|
+
</div>
|
|
154
|
+
<span className="text-xs px-2 py-0.5 bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-400 rounded border border-emerald-300 dark:border-emerald-700">
|
|
155
|
+
Enabled
|
|
156
|
+
</span>
|
|
157
|
+
</DropdownMenuItem>
|
|
158
|
+
))}
|
|
159
|
+
</DropdownMenuContent>
|
|
160
|
+
</DropdownMenu>
|
|
161
|
+
)}
|
|
162
|
+
</div>
|
|
163
|
+
|
|
164
|
+
{/* Auth Methods List */}
|
|
165
|
+
<div className="flex-1 overflow-y-auto p-4">
|
|
166
|
+
<div className="flex flex-col gap-3">
|
|
167
|
+
{/* Email Auth Card */}
|
|
168
|
+
<div className="flex items-center justify-between px-6 py-4 bg-white dark:bg-neutral-800 rounded-lg border border-gray-200 dark:border-transparent">
|
|
169
|
+
<div className="flex items-center gap-3">
|
|
170
|
+
<Mail className="w-6 h-6 text-gray-700 dark:text-white" />
|
|
171
|
+
<div className="text-sm font-medium text-black dark:text-white">Email Auth</div>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
|
|
175
|
+
{/* OAuth Providers */}
|
|
176
|
+
{hasAuthMethods &&
|
|
177
|
+
oauthProviders.map((provider) => {
|
|
178
|
+
const providerConfig = getProviderConfig(provider.id);
|
|
179
|
+
if (!providerConfig) {
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return (
|
|
184
|
+
<div
|
|
185
|
+
key={provider.id}
|
|
186
|
+
className="flex items-center justify-between px-6 py-4 bg-white dark:bg-neutral-800 rounded-lg border border-gray-200 dark:border-transparent"
|
|
187
|
+
>
|
|
188
|
+
<div className="flex items-center gap-3">
|
|
189
|
+
{provider.icon}
|
|
190
|
+
<div className="text-sm font-medium text-black dark:text-white">
|
|
191
|
+
{provider.name}
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
|
|
195
|
+
<div className="flex items-center gap-3">
|
|
196
|
+
{providerConfig.useSharedKey && (
|
|
197
|
+
<span className="px-2 py-0.5 text-xs font-medium text-neutral-500 dark:text-neutral-400 border border-neutral-500 dark:border-neutral-400 rounded">
|
|
198
|
+
Shared Keys
|
|
199
|
+
</span>
|
|
200
|
+
)}
|
|
201
|
+
|
|
202
|
+
<DropdownMenu>
|
|
203
|
+
<DropdownMenuTrigger asChild>
|
|
204
|
+
<Button
|
|
205
|
+
className="h-7 w-7 p-1 text-gray-500 dark:text-neutral-400 hover:bg-gray-100 dark:hover:bg-neutral-700"
|
|
206
|
+
variant="ghost"
|
|
207
|
+
size="sm"
|
|
208
|
+
>
|
|
209
|
+
<MoreHorizontal className="w-5 h-5" />
|
|
210
|
+
</Button>
|
|
211
|
+
</DropdownMenuTrigger>
|
|
212
|
+
<DropdownMenuContent align="end" className="w-40 py-1 px-2">
|
|
213
|
+
<DropdownMenuItem
|
|
214
|
+
onClick={() => handleConfigureProvider(provider)}
|
|
215
|
+
className="py-2 px-3 flex items-center gap-3 cursor-pointer"
|
|
216
|
+
>
|
|
217
|
+
<Pencil className="w-5 h-5" />
|
|
218
|
+
Edit
|
|
219
|
+
</DropdownMenuItem>
|
|
220
|
+
<DropdownMenuItem
|
|
221
|
+
onClick={() => void deleteOAuthConfig(provider.id, provider.name)}
|
|
222
|
+
className="py-2 px-3 flex items-center gap-3 cursor-pointer text-red-600 dark:text-red-400"
|
|
223
|
+
>
|
|
224
|
+
<Trash2 className="w-5 h-5" />
|
|
225
|
+
Delete
|
|
226
|
+
</DropdownMenuItem>
|
|
227
|
+
</DropdownMenuContent>
|
|
228
|
+
</DropdownMenu>
|
|
229
|
+
</div>
|
|
230
|
+
</div>
|
|
231
|
+
);
|
|
232
|
+
})}
|
|
233
|
+
</div>
|
|
234
|
+
</div>
|
|
235
|
+
</div>
|
|
236
|
+
|
|
237
|
+
{/* Right Section - Preview */}
|
|
238
|
+
<div className="w-[688px] bg-slate-50 dark:bg-[#2d2d2d] p-3 flex flex-col overflow-hidden">
|
|
239
|
+
<div className="h-full bg-gray-200 dark:bg-neutral-700 rounded-xl overflow-hidden flex flex-col">
|
|
240
|
+
{/* Preview Header */}
|
|
241
|
+
<div className="flex items-center justify-end px-6 py-3 gap-3">
|
|
242
|
+
<p className="text-sm font-medium text-gray-700 dark:text-white">
|
|
243
|
+
Integrate Authentication to Your Application
|
|
244
|
+
</p>
|
|
245
|
+
<CopyButton
|
|
246
|
+
text={getAuthImplementationPrompt(getBackendUrl())}
|
|
247
|
+
copyText="Copy Prompt"
|
|
248
|
+
variant="primary"
|
|
249
|
+
className="w-34"
|
|
250
|
+
/>
|
|
251
|
+
</div>
|
|
252
|
+
|
|
253
|
+
{/* Preview Content */}
|
|
254
|
+
<div className="flex-1 overflow-y-auto py-8 flex flex-col items-center justify-center gap-4">
|
|
255
|
+
<AuthPreview />
|
|
256
|
+
<p className="text-xs text-gray-500 dark:text-neutral-400 text-center">
|
|
257
|
+
Preview Mode
|
|
258
|
+
</p>
|
|
259
|
+
</div>
|
|
260
|
+
</div>
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
263
|
+
|
|
264
|
+
<OAuthConfigDialog
|
|
265
|
+
provider={selectedProvider}
|
|
266
|
+
isOpen={isDialogOpen}
|
|
267
|
+
onClose={handleCloseDialog}
|
|
268
|
+
onSuccess={handleSuccess}
|
|
269
|
+
/>
|
|
270
|
+
|
|
271
|
+
{/* Confirm Dialog */}
|
|
272
|
+
<ConfirmDialog {...confirmDialogProps} />
|
|
273
|
+
</div>
|
|
274
|
+
);
|
|
275
|
+
}
|
|
@@ -18,13 +18,6 @@ import { SortColumn } from 'react-data-grid';
|
|
|
18
18
|
import { UserSchema } from '@insforge/shared-schemas';
|
|
19
19
|
import { useToast } from '@/lib/hooks/useToast';
|
|
20
20
|
import { useUsers } from '@/features/auth/hooks/useUsers';
|
|
21
|
-
import {
|
|
22
|
-
DataUpdatePayload,
|
|
23
|
-
DataUpdateResourceType,
|
|
24
|
-
ServerEvents,
|
|
25
|
-
SocketMessage,
|
|
26
|
-
useSocket,
|
|
27
|
-
} from '@/lib/contexts/SocketContext';
|
|
28
21
|
|
|
29
22
|
export default function UsersPage() {
|
|
30
23
|
const [searchQuery, setSearchQuery] = useState('');
|
|
@@ -34,8 +27,6 @@ export default function UsersPage() {
|
|
|
34
27
|
const [isRefreshing, setIsRefreshing] = useState(false);
|
|
35
28
|
const [sortColumns, setSortColumns] = useState<SortColumn[]>([]);
|
|
36
29
|
|
|
37
|
-
const { socket, isConnected } = useSocket();
|
|
38
|
-
|
|
39
30
|
const { showToast } = useToast();
|
|
40
31
|
|
|
41
32
|
// Default page size of 20 records per page
|
|
@@ -65,25 +56,6 @@ export default function UsersPage() {
|
|
|
65
56
|
return () => window.removeEventListener('refreshUsers', handleRefreshEvent);
|
|
66
57
|
}, [refetch]);
|
|
67
58
|
|
|
68
|
-
useEffect(() => {
|
|
69
|
-
if (!socket || !isConnected) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const handleDataUpdate = (message: SocketMessage<DataUpdatePayload>) => {
|
|
74
|
-
if (message.payload?.resource === DataUpdateResourceType.USERS) {
|
|
75
|
-
// Refetch data
|
|
76
|
-
void refetch();
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
socket.on(ServerEvents.DATA_UPDATE, handleDataUpdate);
|
|
81
|
-
|
|
82
|
-
return () => {
|
|
83
|
-
socket.off(ServerEvents.DATA_UPDATE, handleDataUpdate);
|
|
84
|
-
};
|
|
85
|
-
}, [socket, isConnected, refetch]);
|
|
86
|
-
|
|
87
59
|
// Clear selection when page changes or search changes
|
|
88
60
|
useEffect(() => {
|
|
89
61
|
setSelectedRows(new Set());
|
|
@@ -19,7 +19,7 @@ export default function DashboardPage() {
|
|
|
19
19
|
const { totalUsers } = useUsers();
|
|
20
20
|
const { records } = useMcpUsage();
|
|
21
21
|
|
|
22
|
-
const authCount = auth?.
|
|
22
|
+
const authCount = auth?.oAuthProviders.length ?? 0;
|
|
23
23
|
const tableCount = tables?.length ?? 0;
|
|
24
24
|
const showBanner = location.state?.showSuccessBanner === true;
|
|
25
25
|
|
|
@@ -225,10 +225,8 @@ export function convertSchemaToColumns(
|
|
|
225
225
|
onJumpToTable={onJumpToTable}
|
|
226
226
|
/>
|
|
227
227
|
);
|
|
228
|
-
// Note: editable is set in the column definition above
|
|
229
228
|
} else if (col.columnName === primaryKeyColumn) {
|
|
230
229
|
column.renderCell = cellRenderers.id;
|
|
231
|
-
// Note: editable is set in the column definition above
|
|
232
230
|
} else if (col.type === ColumnType.BOOLEAN) {
|
|
233
231
|
column.renderCell = cellRenderers.boolean;
|
|
234
232
|
column.renderEditCell = (props: RenderEditCellProps<DatabaseDataGridRow>) => (
|