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
|
@@ -54,7 +54,7 @@ export class UsageService {
|
|
|
54
54
|
async recordMCPUsage(toolName: string, success: boolean = true): Promise<{ created_at: string }> {
|
|
55
55
|
try {
|
|
56
56
|
const result = await this.getPool().query(
|
|
57
|
-
`INSERT INTO
|
|
57
|
+
`INSERT INTO system.mcp_usage (tool_name, success)
|
|
58
58
|
VALUES ($1, $2)
|
|
59
59
|
RETURNING created_at`,
|
|
60
60
|
[toolName, success]
|
|
@@ -75,7 +75,7 @@ export class UsageService {
|
|
|
75
75
|
try {
|
|
76
76
|
const result = await this.getPool().query(
|
|
77
77
|
`SELECT tool_name, success, created_at
|
|
78
|
-
FROM
|
|
78
|
+
FROM system.mcp_usage
|
|
79
79
|
WHERE success = $1
|
|
80
80
|
ORDER BY created_at DESC
|
|
81
81
|
LIMIT $2`,
|
|
@@ -98,7 +98,7 @@ export class UsageService {
|
|
|
98
98
|
// Get MCP tool usage count
|
|
99
99
|
const mcpResult = await this.getPool().query(
|
|
100
100
|
`SELECT COUNT(*) as count
|
|
101
|
-
FROM
|
|
101
|
+
FROM system.mcp_usage
|
|
102
102
|
WHERE success = true
|
|
103
103
|
AND created_at >= $1
|
|
104
104
|
AND created_at < $2`,
|
|
@@ -112,7 +112,7 @@ export class UsageService {
|
|
|
112
112
|
|
|
113
113
|
// Get total storage size
|
|
114
114
|
const storageResult = await this.getPool().query(
|
|
115
|
-
`SELECT COALESCE(SUM(size), 0) as total_size FROM
|
|
115
|
+
`SELECT COALESCE(SUM(size), 0) as total_size FROM storage.objects`
|
|
116
116
|
);
|
|
117
117
|
|
|
118
118
|
// Get AI usage breakdown by model (only billable metrics)
|
|
@@ -122,8 +122,8 @@ export class UsageService {
|
|
|
122
122
|
COALESCE(SUM(u.input_tokens), 0) as total_input_tokens,
|
|
123
123
|
COALESCE(SUM(u.output_tokens), 0) as total_output_tokens,
|
|
124
124
|
COALESCE(SUM(u.image_count), 0) as total_images
|
|
125
|
-
FROM
|
|
126
|
-
LEFT JOIN
|
|
125
|
+
FROM ai.usage u
|
|
126
|
+
LEFT JOIN ai.configs c ON u.config_id = c.id
|
|
127
127
|
WHERE u.created_at >= $1 AND u.created_at < $2
|
|
128
128
|
GROUP BY COALESCE(u.model_id, c.model_id)
|
|
129
129
|
ORDER BY (COALESCE(SUM(u.input_tokens), 0) + COALESCE(SUM(u.output_tokens), 0)) DESC`,
|
package/backend/src/types/ai.ts
CHANGED
|
@@ -11,6 +11,14 @@ export interface OpenRouterImageMessage {
|
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
export interface OpenRouterAudioMessage {
|
|
15
|
+
type: 'input_audio';
|
|
16
|
+
input_audio: {
|
|
17
|
+
data: string; // Base64-encoded audio data
|
|
18
|
+
format: string; // wav, mp3, aiff, aac, ogg, flac, m4a
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
14
22
|
// ============= OpenRouter API Types =============
|
|
15
23
|
|
|
16
24
|
export interface RawOpenRouterModel {
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
// Type definitions for database user records
|
|
2
|
+
|
|
2
3
|
export interface UserRecord {
|
|
3
4
|
id: string;
|
|
4
5
|
email: string;
|
|
5
|
-
|
|
6
|
+
profile: Record<string, unknown> | null;
|
|
7
|
+
metadata: Record<string, unknown> | null;
|
|
6
8
|
email_verified: boolean;
|
|
9
|
+
is_project_admin: boolean;
|
|
10
|
+
is_anonymous: boolean;
|
|
7
11
|
created_at: string;
|
|
8
12
|
updated_at: string;
|
|
9
13
|
password?: string;
|
|
@@ -135,6 +139,16 @@ export interface XUserInfo {
|
|
|
135
139
|
created_at?: string;
|
|
136
140
|
}
|
|
137
141
|
|
|
142
|
+
export interface AppleUserInfo {
|
|
143
|
+
sub: string;
|
|
144
|
+
email: string;
|
|
145
|
+
email_verified?: boolean;
|
|
146
|
+
is_private_email?: boolean;
|
|
147
|
+
name?: string;
|
|
148
|
+
given_name?: string;
|
|
149
|
+
family_name?: string;
|
|
150
|
+
}
|
|
151
|
+
|
|
138
152
|
// Generic OAuth user data returned by provider services
|
|
139
153
|
export interface OAuthUserData {
|
|
140
154
|
provider: string;
|
|
@@ -150,5 +164,6 @@ export interface OAuthUserData {
|
|
|
150
164
|
| FacebookUserInfo
|
|
151
165
|
| MicrosoftUserInfo
|
|
152
166
|
| XUserInfo
|
|
167
|
+
| AppleUserInfo
|
|
153
168
|
| Record<string, unknown>;
|
|
154
169
|
}
|
|
@@ -102,6 +102,7 @@ export type ForeignKeyInfo = ForeignKeySchema & {
|
|
|
102
102
|
export interface ForeignKeyRow {
|
|
103
103
|
constraint_name: string;
|
|
104
104
|
from_column: string;
|
|
105
|
+
foreign_schema: string;
|
|
105
106
|
foreign_table: string;
|
|
106
107
|
foreign_column: string;
|
|
107
108
|
on_delete: string;
|
|
@@ -112,6 +113,7 @@ export interface ForeignKeyRow {
|
|
|
112
113
|
export interface ColumnInfo {
|
|
113
114
|
column_name: string;
|
|
114
115
|
data_type: string;
|
|
116
|
+
udt_name: string;
|
|
115
117
|
is_nullable: string;
|
|
116
118
|
column_default: string | null;
|
|
117
119
|
character_maximum_length: number | null;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Backend-only types for deployments
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Deployment status constants
|
|
5
|
+
* WAITING -> UPLOADING -> (Vercel statuses: QUEUED/BUILDING/READY/ERROR/CANCELED)
|
|
6
|
+
*/
|
|
7
|
+
export const DeploymentStatus = {
|
|
8
|
+
// InsForge internal statuses
|
|
9
|
+
WAITING: 'WAITING', // Record created, waiting for client to upload zip to S3
|
|
10
|
+
UPLOADING: 'UPLOADING', // Server is downloading from S3 and uploading to Vercel
|
|
11
|
+
// Vercel statuses (stored directly)
|
|
12
|
+
QUEUED: 'QUEUED',
|
|
13
|
+
BUILDING: 'BUILDING',
|
|
14
|
+
READY: 'READY',
|
|
15
|
+
ERROR: 'ERROR',
|
|
16
|
+
CANCELED: 'CANCELED',
|
|
17
|
+
} as const;
|
|
18
|
+
|
|
19
|
+
export type DeploymentStatusType = (typeof DeploymentStatus)[keyof typeof DeploymentStatus];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Internal deployment record with Date objects (database returns Date, not string)
|
|
23
|
+
*/
|
|
24
|
+
export interface DeploymentRecord {
|
|
25
|
+
id: string;
|
|
26
|
+
providerDeploymentId: string | null; // Provider's deployment ID, null until deployment starts
|
|
27
|
+
provider: string;
|
|
28
|
+
status: DeploymentStatusType;
|
|
29
|
+
url: string | null;
|
|
30
|
+
metadata: Record<string, unknown> | null;
|
|
31
|
+
createdAt: Date;
|
|
32
|
+
updatedAt: Date;
|
|
33
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Realtime feature types - Backend-only types
|
|
3
|
+
*
|
|
4
|
+
* Shared types should be imported directly from @insforge/shared-schemas.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Backend-Only Types (Internal Use)
|
|
9
|
+
// ============================================================================
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Delivery statistics after message processing
|
|
13
|
+
*/
|
|
14
|
+
export interface DeliveryResult {
|
|
15
|
+
wsAudienceCount: number;
|
|
16
|
+
whAudienceCount: number;
|
|
17
|
+
whDeliveredCount: number;
|
|
18
|
+
}
|
|
@@ -10,24 +10,18 @@ export enum ServerEvents {
|
|
|
10
10
|
NOTIFICATION = 'notification',
|
|
11
11
|
DATA_UPDATE = 'data:update',
|
|
12
12
|
MCP_CONNECTED = 'mcp:connected',
|
|
13
|
+
// Realtime events
|
|
14
|
+
REALTIME_ERROR = 'realtime:error',
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* Client-to-Server events
|
|
17
19
|
*/
|
|
18
20
|
export enum ClientEvents {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Generic message interface
|
|
25
|
-
*/
|
|
26
|
-
export interface SocketMessage<T = unknown> {
|
|
27
|
-
type: string;
|
|
28
|
-
payload?: T;
|
|
29
|
-
timestamp: number;
|
|
30
|
-
id?: string;
|
|
21
|
+
// Realtime events
|
|
22
|
+
REALTIME_SUBSCRIBE = 'realtime:subscribe',
|
|
23
|
+
REALTIME_UNSUBSCRIBE = 'realtime:unsubscribe',
|
|
24
|
+
REALTIME_PUBLISH = 'realtime:publish',
|
|
31
25
|
}
|
|
32
26
|
|
|
33
27
|
/**
|
|
@@ -43,27 +37,9 @@ export interface NotificationPayload {
|
|
|
43
37
|
export enum DataUpdateResourceType {
|
|
44
38
|
DATABASE = 'database',
|
|
45
39
|
USERS = 'users',
|
|
46
|
-
RECORDS = 'records',
|
|
47
40
|
BUCKETS = 'buckets',
|
|
48
41
|
FUNCTIONS = 'functions',
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
export interface DataUpdatePayload {
|
|
52
|
-
resource: DataUpdateResourceType;
|
|
53
|
-
action: 'created' | 'updated' | 'deleted';
|
|
54
|
-
data: unknown;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Client event payloads
|
|
59
|
-
*/
|
|
60
|
-
export interface SubscribePayload {
|
|
61
|
-
channel: string;
|
|
62
|
-
filters?: Record<string, unknown>;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export interface UnsubscribePayload {
|
|
66
|
-
channel: string;
|
|
42
|
+
REALTIME = 'realtime',
|
|
67
43
|
}
|
|
68
44
|
|
|
69
45
|
/**
|
|
@@ -10,7 +10,7 @@ export interface StorageRecord {
|
|
|
10
10
|
uploaded_at: string;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
// Bucket record from
|
|
13
|
+
// Bucket record from storage.buckets table
|
|
14
14
|
export type BucketRecord = Omit<StorageBucketSchema, 'created_at'>;
|
|
15
15
|
|
|
16
16
|
// Form field types for file uploads
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Webhook types for external integrations
|
|
2
|
+
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// Vercel Webhooks
|
|
5
|
+
// ============================================================================
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Vercel webhook event types we handle for deployments
|
|
9
|
+
*/
|
|
10
|
+
export type VercelDeploymentEventType =
|
|
11
|
+
| 'deployment.created'
|
|
12
|
+
| 'deployment.succeeded'
|
|
13
|
+
| 'deployment.error'
|
|
14
|
+
| 'deployment.canceled';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Map Vercel webhook event types to our deployment status
|
|
18
|
+
*/
|
|
19
|
+
export const VERCEL_EVENT_TO_STATUS: Record<VercelDeploymentEventType, string> = {
|
|
20
|
+
'deployment.created': 'BUILDING',
|
|
21
|
+
'deployment.succeeded': 'READY',
|
|
22
|
+
'deployment.error': 'ERROR',
|
|
23
|
+
'deployment.canceled': 'CANCELED',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Vercel webhook payload structure for deployment events
|
|
28
|
+
*/
|
|
29
|
+
export interface VercelWebhookPayload {
|
|
30
|
+
type: string;
|
|
31
|
+
id: string;
|
|
32
|
+
createdAt: string;
|
|
33
|
+
payload: {
|
|
34
|
+
team?: { id: string };
|
|
35
|
+
user?: { id: string };
|
|
36
|
+
deployment: {
|
|
37
|
+
id: string;
|
|
38
|
+
url: string;
|
|
39
|
+
name: string;
|
|
40
|
+
meta?: Record<string, unknown>;
|
|
41
|
+
};
|
|
42
|
+
target?: string;
|
|
43
|
+
project?: { id: string };
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Request, Response } from 'express';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cookie names
|
|
5
|
+
*/
|
|
6
|
+
export const REFRESH_TOKEN_COOKIE_NAME = 'insforge_refresh_token';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Set an auth cookie on response
|
|
10
|
+
* @param name - Cookie name
|
|
11
|
+
* @param value - Cookie value
|
|
12
|
+
*/
|
|
13
|
+
export function setAuthCookie(req: Request, res: Response, name: string, value: string): void {
|
|
14
|
+
res.cookie(name, value, {
|
|
15
|
+
httpOnly: true,
|
|
16
|
+
secure: req.secure,
|
|
17
|
+
sameSite: 'none',
|
|
18
|
+
path: '/api/auth',
|
|
19
|
+
maxAge: 7 * 24 * 60 * 60 * 1000, // 7 days
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Clear an auth cookie on response
|
|
25
|
+
* IMPORTANT: Must use the same options (especially path) as when setting the cookie
|
|
26
|
+
*/
|
|
27
|
+
export function clearAuthCookie(req: Request, res: Response, name: string): void {
|
|
28
|
+
res.clearCookie(name, {
|
|
29
|
+
httpOnly: true,
|
|
30
|
+
secure: req.secure,
|
|
31
|
+
sameSite: 'none',
|
|
32
|
+
path: '/api/auth',
|
|
33
|
+
});
|
|
34
|
+
}
|
|
@@ -18,20 +18,6 @@ export function isOAuthSharedKeysAvailable(): boolean {
|
|
|
18
18
|
return isCloudEnvironment();
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
/**
|
|
22
|
-
* Check if running in development mode
|
|
23
|
-
*/
|
|
24
|
-
export function isDevelopment(): boolean {
|
|
25
|
-
return process.env.NODE_ENV === 'development' || !process.env.NODE_ENV;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Check if running in production mode
|
|
30
|
-
*/
|
|
31
|
-
export function isProduction(): boolean {
|
|
32
|
-
return process.env.NODE_ENV === 'production';
|
|
33
|
-
}
|
|
34
|
-
|
|
35
21
|
/**
|
|
36
22
|
* Get the API base URL from environment variable or default to localhost
|
|
37
23
|
* @returns The API base URL
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';
|
|
2
|
+
import logger from '@/utils/logger.js';
|
|
3
|
+
|
|
4
|
+
// TODO: make these configurable in env variables in cloud backend
|
|
5
|
+
const CONFIG_BUCKET = process.env.AWS_CONFIG_BUCKET || 'insforge-config';
|
|
6
|
+
const CONFIG_REGION = process.env.AWS_CONFIG_REGION || 'us-east-2';
|
|
7
|
+
|
|
8
|
+
let s3Client: S3Client | null = null;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Get or create S3 client for config loading
|
|
12
|
+
*/
|
|
13
|
+
function getS3Client(): S3Client {
|
|
14
|
+
if (s3Client) {
|
|
15
|
+
return s3Client;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const s3Config: {
|
|
19
|
+
region: string;
|
|
20
|
+
credentials?: { accessKeyId: string; secretAccessKey: string };
|
|
21
|
+
} = {
|
|
22
|
+
region: CONFIG_REGION,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Use explicit credentials if provided, otherwise IAM role
|
|
26
|
+
if (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) {
|
|
27
|
+
s3Config.credentials = {
|
|
28
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
29
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
s3Client = new S3Client(s3Config);
|
|
34
|
+
return s3Client;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Fetches a JSON config file from the S3 config bucket
|
|
39
|
+
* @param key - The S3 object key (e.g., 'default-ai-models.json')
|
|
40
|
+
* @returns Parsed JSON content or null if fetch fails
|
|
41
|
+
*/
|
|
42
|
+
export async function fetchS3Config<T>(key: string): Promise<T | null> {
|
|
43
|
+
try {
|
|
44
|
+
const command = new GetObjectCommand({
|
|
45
|
+
Bucket: CONFIG_BUCKET,
|
|
46
|
+
Key: key,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const response = await getS3Client().send(command);
|
|
50
|
+
const body = await response.Body?.transformToString();
|
|
51
|
+
|
|
52
|
+
if (!body) {
|
|
53
|
+
logger.warn(`Empty config file from S3: ${key}`);
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return JSON.parse(body) as T;
|
|
58
|
+
} catch (error) {
|
|
59
|
+
logger.warn(`Failed to fetch config from S3: ${key}`, {
|
|
60
|
+
error: error instanceof Error ? error.message : String(error),
|
|
61
|
+
});
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import bcrypt from 'bcryptjs';
|
|
1
2
|
import { DatabaseManager } from '@/infra/database/database.manager.js';
|
|
2
3
|
import { TokenManager } from '@/infra/security/token.manager.js';
|
|
3
4
|
import { AIConfigService } from '@/services/ai/ai-config.service.js';
|
|
@@ -5,55 +6,96 @@ import { isCloudEnvironment } from '@/utils/environment.js';
|
|
|
5
6
|
import logger from '@/utils/logger.js';
|
|
6
7
|
import { SecretService } from '@/services/secrets/secret.service.js';
|
|
7
8
|
import { OAuthConfigService } from '@/services/auth/oauth-config.service.js';
|
|
8
|
-
import { OAuthProvidersSchema } from '@insforge/shared-schemas';
|
|
9
|
+
import { OAuthProvidersSchema, aiConfigurationInputSchema } from '@insforge/shared-schemas';
|
|
10
|
+
import { z } from 'zod';
|
|
9
11
|
import { AuthConfigService } from '@/services/auth/auth-config.service.js';
|
|
12
|
+
import { fetchS3Config } from '@/utils/s3-config-loader.js';
|
|
13
|
+
import { ADMIN_ID } from '@/utils/constants.js';
|
|
10
14
|
|
|
11
15
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
16
|
+
* Seeds the admin user if it doesn't exist in the database
|
|
17
|
+
* Creates an admin user with is_project_admin = true
|
|
14
18
|
*/
|
|
15
|
-
function
|
|
16
|
-
if (adminEmail
|
|
17
|
-
logger.info(`✅ Admin configured: ${adminEmail}`);
|
|
18
|
-
} else {
|
|
19
|
+
async function seedAdminUser(adminEmail: string, adminPassword: string): Promise<void> {
|
|
20
|
+
if (!adminEmail || !adminPassword) {
|
|
19
21
|
logger.warn('⚠️ Admin credentials not configured - check ADMIN_EMAIL and ADMIN_PASSWORD');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const dbManager = DatabaseManager.getInstance();
|
|
26
|
+
const pool = dbManager.getPool();
|
|
27
|
+
const client = await pool.connect();
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
// Check if admin user already exists
|
|
31
|
+
const existingAdmin = await client.query('SELECT id FROM auth.users WHERE id = $1', [ADMIN_ID]);
|
|
32
|
+
|
|
33
|
+
if (existingAdmin.rows.length > 0) {
|
|
34
|
+
logger.info(`✅ Admin configured: ${adminEmail}`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Hash password and create admin user
|
|
39
|
+
const hashedPassword = await bcrypt.hash(adminPassword, 10);
|
|
40
|
+
const profile = JSON.stringify({ name: 'Administrator' });
|
|
41
|
+
|
|
42
|
+
await client.query(
|
|
43
|
+
`INSERT INTO auth.users (id, email, password, profile, email_verified, is_project_admin, is_anonymous, created_at, updated_at)
|
|
44
|
+
VALUES ($1, $2, $3, $4::jsonb, true, true, false, NOW(), NOW())
|
|
45
|
+
ON CONFLICT (id) DO NOTHING`,
|
|
46
|
+
[ADMIN_ID, adminEmail, hashedPassword, profile]
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
logger.info(`✅ Admin user seeded: ${adminEmail}`);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
logger.error('Failed to seed admin user', {
|
|
52
|
+
error: error instanceof Error ? error.message : String(error),
|
|
53
|
+
});
|
|
54
|
+
// Don't throw - this is not critical for app startup if admin already exists
|
|
55
|
+
} finally {
|
|
56
|
+
client.release();
|
|
20
57
|
}
|
|
21
58
|
}
|
|
22
59
|
|
|
23
60
|
/**
|
|
24
|
-
* Seeds default AI configurations
|
|
61
|
+
* Seeds default AI configurations from S3 config
|
|
25
62
|
*/
|
|
26
63
|
async function seedDefaultAIConfigs(): Promise<void> {
|
|
27
|
-
|
|
28
|
-
|
|
64
|
+
const aiConfigService = AIConfigService.getInstance();
|
|
65
|
+
|
|
66
|
+
const existingConfigs = await aiConfigService.findAll();
|
|
67
|
+
if (existingConfigs.length) {
|
|
29
68
|
return;
|
|
30
69
|
}
|
|
31
70
|
|
|
32
|
-
const
|
|
71
|
+
const defaultModels =
|
|
72
|
+
await fetchS3Config<z.infer<typeof aiConfigurationInputSchema>[]>('default-ai-models.json');
|
|
33
73
|
|
|
34
|
-
|
|
35
|
-
|
|
74
|
+
if (!defaultModels || defaultModels.length === 0) {
|
|
75
|
+
logger.warn('⚠️ No default AI models configured - add via dashboard or check S3 config');
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
36
78
|
|
|
37
|
-
|
|
79
|
+
const parsed = aiConfigurationInputSchema.array().safeParse(defaultModels);
|
|
80
|
+
if (!parsed.success) {
|
|
81
|
+
logger.error('❌ Invalid AI models configuration from S3', {
|
|
82
|
+
error: parsed.error.message,
|
|
83
|
+
});
|
|
38
84
|
return;
|
|
39
85
|
}
|
|
40
86
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
'google/gemini-3-pro-image-preview'
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
logger.info('✅ Default AI models configured (cloud environment)');
|
|
87
|
+
const validatedModels = parsed.data;
|
|
88
|
+
for (const model of validatedModels) {
|
|
89
|
+
await aiConfigService.create(
|
|
90
|
+
model.inputModality,
|
|
91
|
+
model.outputModality,
|
|
92
|
+
model.provider,
|
|
93
|
+
model.modelId,
|
|
94
|
+
model.systemPrompt
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
logger.info(`✅ Default AI models configured (${validatedModels.length} models)`);
|
|
57
99
|
}
|
|
58
100
|
|
|
59
101
|
/**
|
|
@@ -67,7 +109,7 @@ async function seedDefaultAuthConfig(): Promise<void> {
|
|
|
67
109
|
const client = await pool.connect();
|
|
68
110
|
|
|
69
111
|
try {
|
|
70
|
-
const result = await client.query('SELECT COUNT(*) as count FROM
|
|
112
|
+
const result = await client.query('SELECT COUNT(*) as count FROM auth.configs');
|
|
71
113
|
const hasConfig = result.rows.length > 0 && Number(result.rows[0].count) > 0;
|
|
72
114
|
|
|
73
115
|
if (hasConfig) {
|
|
@@ -81,10 +123,8 @@ async function seedDefaultAuthConfig(): Promise<void> {
|
|
|
81
123
|
}
|
|
82
124
|
|
|
83
125
|
// Table is empty - this is first startup, insert default cloud configuration
|
|
84
|
-
// Note: Migration 016 will add verify_email_method, reset_password_method, sign_in_redirect_to
|
|
85
|
-
// so we only insert fields that exist in migration 015
|
|
86
126
|
await client.query(
|
|
87
|
-
`INSERT INTO
|
|
127
|
+
`INSERT INTO auth.configs (
|
|
88
128
|
require_email_verification,
|
|
89
129
|
password_min_length,
|
|
90
130
|
require_number,
|
|
@@ -222,8 +262,8 @@ export async function seedBackend(): Promise<void> {
|
|
|
222
262
|
try {
|
|
223
263
|
logger.info(`\n🚀 Insforge Backend Starting...`);
|
|
224
264
|
|
|
225
|
-
//
|
|
226
|
-
|
|
265
|
+
// Seed admin user if not exists
|
|
266
|
+
await seedAdminUser(adminEmail, adminPassword);
|
|
227
267
|
|
|
228
268
|
// Initialize API key (from env or generate)
|
|
229
269
|
const apiKey = await secretService.initializeApiKey();
|
|
@@ -242,15 +282,11 @@ export async function seedBackend(): Promise<void> {
|
|
|
242
282
|
logger.info(`✅ Found ${tables.length} user tables`);
|
|
243
283
|
}
|
|
244
284
|
|
|
245
|
-
// seed
|
|
246
|
-
await seedDefaultAIConfigs();
|
|
247
|
-
|
|
248
|
-
// Enable email verification in cloud environment
|
|
249
|
-
await seedDefaultAuthConfig();
|
|
250
|
-
|
|
251
|
-
// add default OAuth configs in Cloud hosting
|
|
285
|
+
// seed default configs for cloud environment
|
|
252
286
|
if (isCloudEnvironment()) {
|
|
253
287
|
await seedDefaultOAuthConfigs();
|
|
288
|
+
await seedDefaultAIConfigs();
|
|
289
|
+
await seedDefaultAuthConfig();
|
|
254
290
|
} else {
|
|
255
291
|
await seedLocalOAuthConfigs();
|
|
256
292
|
}
|