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,7 +1,223 @@
|
|
|
1
1
|
import splitSqlQuery from '@databases/split-sql-query';
|
|
2
2
|
import sql from '@databases/sql';
|
|
3
|
+
import { parseSync, loadModule } from 'libpg-query';
|
|
3
4
|
import logger from './logger.js';
|
|
4
5
|
|
|
6
|
+
let initialized = false;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Initialize the SQL parser WASM module.
|
|
10
|
+
* Must be called and awaited before using analyzeQuery().
|
|
11
|
+
*/
|
|
12
|
+
export async function initSqlParser(): Promise<void> {
|
|
13
|
+
if (initialized) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
await loadModule();
|
|
17
|
+
initialized = true;
|
|
18
|
+
logger.info('SQL parser initialized');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface DatabaseResourceUpdate {
|
|
22
|
+
type: 'tables' | 'table' | 'records' | 'index' | 'trigger' | 'policy' | 'function' | 'extension';
|
|
23
|
+
name?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const STMT_TYPES: Record<string, DatabaseResourceUpdate['type']> = {
|
|
27
|
+
InsertStmt: 'records',
|
|
28
|
+
UpdateStmt: 'records',
|
|
29
|
+
DeleteStmt: 'records',
|
|
30
|
+
CreateStmt: 'tables',
|
|
31
|
+
AlterTableStmt: 'table',
|
|
32
|
+
RenameStmt: 'table',
|
|
33
|
+
IndexStmt: 'index',
|
|
34
|
+
CreateTrigStmt: 'trigger',
|
|
35
|
+
CreatePolicyStmt: 'policy',
|
|
36
|
+
AlterPolicyStmt: 'policy',
|
|
37
|
+
CreateFunctionStmt: 'function',
|
|
38
|
+
CreateExtensionStmt: 'extension',
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const DROP_TYPES: Record<string, DatabaseResourceUpdate['type']> = {
|
|
42
|
+
OBJECT_TABLE: 'tables',
|
|
43
|
+
OBJECT_INDEX: 'index',
|
|
44
|
+
OBJECT_TRIGGER: 'trigger',
|
|
45
|
+
OBJECT_POLICY: 'policy',
|
|
46
|
+
OBJECT_FUNCTION: 'function',
|
|
47
|
+
OBJECT_EXTENSION: 'extension',
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export function analyzeQuery(query: string): DatabaseResourceUpdate[] {
|
|
51
|
+
try {
|
|
52
|
+
const { stmts } = parseSync(query);
|
|
53
|
+
const changes = stmts
|
|
54
|
+
.map((s: { stmt: Record<string, unknown> }) => extractChange(s.stmt))
|
|
55
|
+
.filter((c: DatabaseResourceUpdate | null): c is DatabaseResourceUpdate => c !== null);
|
|
56
|
+
|
|
57
|
+
// Deduplicate by type+name
|
|
58
|
+
const seen = new Set<string>();
|
|
59
|
+
return changes.filter((c: DatabaseResourceUpdate) => {
|
|
60
|
+
const key = `${c.type}:${c.name ?? ''}`;
|
|
61
|
+
if (seen.has(key)) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
seen.add(key);
|
|
65
|
+
return true;
|
|
66
|
+
});
|
|
67
|
+
} catch (e) {
|
|
68
|
+
logger.warn('SQL parse error:', e);
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function extractChange(stmt: Record<string, unknown>): DatabaseResourceUpdate | null {
|
|
74
|
+
const [stmtType, data] = Object.entries(stmt)[0] as [string, Record<string, unknown>];
|
|
75
|
+
|
|
76
|
+
if (stmtType === 'DropStmt') {
|
|
77
|
+
const type = DROP_TYPES[data.removeType as string];
|
|
78
|
+
return type ? { type } : null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const type = STMT_TYPES[stmtType];
|
|
82
|
+
if (!type) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Only include name for 'table' (ALTER) and 'records' (DML)
|
|
87
|
+
if (type === 'table' || type === 'records') {
|
|
88
|
+
const name = (data.relation as Record<string, unknown>)?.relname as string;
|
|
89
|
+
return { type, name };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return { type };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Extract schema name from a relation/RangeVar node in the AST
|
|
97
|
+
*/
|
|
98
|
+
function getSchemaName(relation: Record<string, unknown> | undefined): string | null {
|
|
99
|
+
if (!relation) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Direct schemaname property (for DeleteStmt.relation)
|
|
104
|
+
if (relation.schemaname) {
|
|
105
|
+
return relation.schemaname as string;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// RangeVar structure (for TruncateStmt.relations)
|
|
109
|
+
if (relation.RangeVar) {
|
|
110
|
+
const rangeVar = relation.RangeVar as Record<string, unknown>;
|
|
111
|
+
if (rangeVar.schemaname) {
|
|
112
|
+
return rangeVar.schemaname as string;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Check if a query contains dangerous operations on the auth schema
|
|
121
|
+
* Returns an error message if blocked, null if allowed
|
|
122
|
+
*/
|
|
123
|
+
export function checkAuthSchemaOperations(query: string): string | null {
|
|
124
|
+
try {
|
|
125
|
+
const { stmts } = parseSync(query);
|
|
126
|
+
|
|
127
|
+
for (const stmtWrapper of stmts) {
|
|
128
|
+
const stmt = stmtWrapper.stmt as Record<string, unknown>;
|
|
129
|
+
const [stmtType, data] = Object.entries(stmt)[0] as [string, Record<string, unknown>];
|
|
130
|
+
|
|
131
|
+
// Check DELETE statements
|
|
132
|
+
if (stmtType === 'DeleteStmt') {
|
|
133
|
+
const relation = data.relation as Record<string, unknown> | undefined;
|
|
134
|
+
const schemaName = getSchemaName(relation);
|
|
135
|
+
if (schemaName?.toLowerCase() === 'auth') {
|
|
136
|
+
return 'DELETE operations on auth schema are not allowed. User deletion must be done through dedicated authentication APIs.';
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Check TRUNCATE statements
|
|
141
|
+
if (stmtType === 'TruncateStmt') {
|
|
142
|
+
const relations = (data.relations as Array<Record<string, unknown>>) || [];
|
|
143
|
+
for (const relation of relations) {
|
|
144
|
+
const schemaName = getSchemaName(relation);
|
|
145
|
+
if (schemaName?.toLowerCase() === 'auth') {
|
|
146
|
+
return 'TRUNCATE operations on auth schema are not allowed. This would delete all users and must be done through dedicated authentication APIs.';
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Check DROP statements
|
|
152
|
+
if (stmtType === 'DropStmt') {
|
|
153
|
+
const objects = (data.objects as Array<unknown>) || [];
|
|
154
|
+
for (const obj of objects) {
|
|
155
|
+
if (typeof obj === 'object' && obj !== null) {
|
|
156
|
+
const objRecord = obj as Record<string, unknown>;
|
|
157
|
+
let schemaName: string | null = null;
|
|
158
|
+
|
|
159
|
+
// DROP SCHEMA: direct String object
|
|
160
|
+
if (objRecord.String) {
|
|
161
|
+
const stringObj = objRecord.String as Record<string, unknown>;
|
|
162
|
+
if (stringObj.sval) {
|
|
163
|
+
schemaName = stringObj.sval as string;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// DROP TABLE/INDEX/VIEW/etc: List with [schema, name] items
|
|
167
|
+
else if (objRecord.List) {
|
|
168
|
+
const list = objRecord.List as Record<string, unknown>;
|
|
169
|
+
const items = (list.items as Array<Record<string, unknown>>) || [];
|
|
170
|
+
// First item is typically the schema name
|
|
171
|
+
if (items.length > 0) {
|
|
172
|
+
const firstItem = items[0];
|
|
173
|
+
if (firstItem.String) {
|
|
174
|
+
const stringObj = firstItem.String as Record<string, unknown>;
|
|
175
|
+
schemaName = stringObj.sval as string;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// DROP FUNCTION/PROCEDURE: ObjectWithArgs with objname array
|
|
180
|
+
else if (objRecord.ObjectWithArgs) {
|
|
181
|
+
const objectWithArgs = objRecord.ObjectWithArgs as Record<string, unknown>;
|
|
182
|
+
const objname = (objectWithArgs.objname as Array<Record<string, unknown>>) || [];
|
|
183
|
+
// First item is typically the schema name
|
|
184
|
+
if (objname.length > 0) {
|
|
185
|
+
const firstItem = objname[0];
|
|
186
|
+
if (firstItem.String) {
|
|
187
|
+
const stringObj = firstItem.String as Record<string, unknown>;
|
|
188
|
+
schemaName = stringObj.sval as string;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// DROP TYPE/DOMAIN: TypeName with names array
|
|
193
|
+
else if (objRecord.TypeName) {
|
|
194
|
+
const typeName = objRecord.TypeName as Record<string, unknown>;
|
|
195
|
+
const names = (typeName.names as Array<Record<string, unknown>>) || [];
|
|
196
|
+
// First item is typically the schema name
|
|
197
|
+
if (names.length > 0) {
|
|
198
|
+
const firstItem = names[0];
|
|
199
|
+
if (firstItem.String) {
|
|
200
|
+
const stringObj = firstItem.String as Record<string, unknown>;
|
|
201
|
+
schemaName = stringObj.sval as string;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (schemaName?.toLowerCase() === 'auth') {
|
|
207
|
+
return 'DROP operations on auth schema are not allowed. This would destroy authentication resources and break the system.';
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return null; // No dangerous operations found
|
|
215
|
+
} catch (parseError) {
|
|
216
|
+
logger.warn('SQL parse error in checkAuthSchemaOperations, letting query through:', parseError);
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
5
221
|
/**
|
|
6
222
|
* Parse a SQL string into individual statements, properly handling:
|
|
7
223
|
* - String literals with embedded semicolons
|
|
@@ -1,114 +1,114 @@
|
|
|
1
|
-
import crypto from 'crypto';
|
|
2
|
-
import { ColumnType, type AuthConfigSchema } from '@insforge/shared-schemas';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Generates a user-friendly error message listing all password requirements
|
|
6
|
-
* @param config - Authentication configuration with password requirements
|
|
7
|
-
* @returns A formatted message listing all enabled password requirements
|
|
8
|
-
*/
|
|
9
|
-
export function getPasswordRequirementsMessage(config: AuthConfigSchema): string {
|
|
10
|
-
const requirements: string[] = [];
|
|
11
|
-
|
|
12
|
-
requirements.push(`at least ${config.passwordMinLength} characters long`);
|
|
13
|
-
|
|
14
|
-
if (config.requireNumber) {
|
|
15
|
-
requirements.push('at least one number');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (config.requireLowercase) {
|
|
19
|
-
requirements.push('at least one lowercase letter');
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (config.requireUppercase) {
|
|
23
|
-
requirements.push('at least one uppercase letter');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (config.requireSpecialChar) {
|
|
27
|
-
requirements.push('at least one special character');
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return `Password must contain ${requirements.join(', ')}`;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export const convertSqlTypeToColumnType = (sqlType: string): ColumnType | string => {
|
|
34
|
-
switch (sqlType.toLowerCase()) {
|
|
35
|
-
case 'uuid':
|
|
36
|
-
return ColumnType.UUID;
|
|
37
|
-
case 'timestamptz':
|
|
38
|
-
case 'timestamp with time zone':
|
|
39
|
-
return ColumnType.DATETIME;
|
|
40
|
-
case 'date':
|
|
41
|
-
return ColumnType.DATE;
|
|
42
|
-
case 'integer':
|
|
43
|
-
case 'bigint':
|
|
44
|
-
case 'smallint':
|
|
45
|
-
case 'int':
|
|
46
|
-
case 'int2':
|
|
47
|
-
case 'int4':
|
|
48
|
-
case 'serial':
|
|
49
|
-
case 'serial2':
|
|
50
|
-
case 'serial4':
|
|
51
|
-
case 'serial8':
|
|
52
|
-
case 'smallserial':
|
|
53
|
-
case 'bigserial':
|
|
54
|
-
return ColumnType.INTEGER;
|
|
55
|
-
case 'double precision':
|
|
56
|
-
case 'real':
|
|
57
|
-
case 'numeric':
|
|
58
|
-
case 'float':
|
|
59
|
-
case 'float4':
|
|
60
|
-
case 'float8':
|
|
61
|
-
case 'decimal':
|
|
62
|
-
return ColumnType.FLOAT;
|
|
63
|
-
case 'boolean':
|
|
64
|
-
case 'bool':
|
|
65
|
-
return ColumnType.BOOLEAN;
|
|
66
|
-
case 'json':
|
|
67
|
-
case 'jsonb':
|
|
68
|
-
case 'array':
|
|
69
|
-
return ColumnType.JSON;
|
|
70
|
-
case 'text':
|
|
71
|
-
case 'varchar':
|
|
72
|
-
case 'char':
|
|
73
|
-
case 'character varying':
|
|
74
|
-
case 'character':
|
|
75
|
-
return ColumnType.STRING;
|
|
76
|
-
default:
|
|
77
|
-
return sqlType.slice(0,
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Generate a UUID v4
|
|
83
|
-
* @returns A UUID v4 string
|
|
84
|
-
*/
|
|
85
|
-
export function generateUUID(): string {
|
|
86
|
-
return crypto.randomUUID();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Generate a random numeric string of specified length
|
|
91
|
-
* @param length - The length of the numeric string to generate
|
|
92
|
-
* @returns A random string containing only digits (0-9)
|
|
93
|
-
*/
|
|
94
|
-
export function generateNumericCode(length: number): string {
|
|
95
|
-
// Generate each digit independently
|
|
96
|
-
let result = '';
|
|
97
|
-
for (let i = 0; i < length; i++) {
|
|
98
|
-
result += crypto.randomInt(0, 10).toString();
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return result;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Generate a cryptographically secure random token
|
|
106
|
-
* @param bytes - Number of random bytes to generate (default: 32)
|
|
107
|
-
* @returns Hex-encoded string (length = bytes * 2 characters)
|
|
108
|
-
* @example
|
|
109
|
-
* generateSecureToken(32) // Returns 64-character hex string (256 bits entropy)
|
|
110
|
-
* generateSecureToken(16) // Returns 32-character hex string (128 bits entropy)
|
|
111
|
-
*/
|
|
112
|
-
export function generateSecureToken(bytes: number = 32): string {
|
|
113
|
-
return crypto.randomBytes(bytes).toString('hex');
|
|
114
|
-
}
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
import { ColumnType, type AuthConfigSchema } from '@insforge/shared-schemas';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generates a user-friendly error message listing all password requirements
|
|
6
|
+
* @param config - Authentication configuration with password requirements
|
|
7
|
+
* @returns A formatted message listing all enabled password requirements
|
|
8
|
+
*/
|
|
9
|
+
export function getPasswordRequirementsMessage(config: AuthConfigSchema): string {
|
|
10
|
+
const requirements: string[] = [];
|
|
11
|
+
|
|
12
|
+
requirements.push(`at least ${config.passwordMinLength} characters long`);
|
|
13
|
+
|
|
14
|
+
if (config.requireNumber) {
|
|
15
|
+
requirements.push('at least one number');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (config.requireLowercase) {
|
|
19
|
+
requirements.push('at least one lowercase letter');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (config.requireUppercase) {
|
|
23
|
+
requirements.push('at least one uppercase letter');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (config.requireSpecialChar) {
|
|
27
|
+
requirements.push('at least one special character');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return `Password must contain ${requirements.join(', ')}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const convertSqlTypeToColumnType = (sqlType: string): ColumnType | string => {
|
|
34
|
+
switch (sqlType.toLowerCase()) {
|
|
35
|
+
case 'uuid':
|
|
36
|
+
return ColumnType.UUID;
|
|
37
|
+
case 'timestamptz':
|
|
38
|
+
case 'timestamp with time zone':
|
|
39
|
+
return ColumnType.DATETIME;
|
|
40
|
+
case 'date':
|
|
41
|
+
return ColumnType.DATE;
|
|
42
|
+
case 'integer':
|
|
43
|
+
case 'bigint':
|
|
44
|
+
case 'smallint':
|
|
45
|
+
case 'int':
|
|
46
|
+
case 'int2':
|
|
47
|
+
case 'int4':
|
|
48
|
+
case 'serial':
|
|
49
|
+
case 'serial2':
|
|
50
|
+
case 'serial4':
|
|
51
|
+
case 'serial8':
|
|
52
|
+
case 'smallserial':
|
|
53
|
+
case 'bigserial':
|
|
54
|
+
return ColumnType.INTEGER;
|
|
55
|
+
case 'double precision':
|
|
56
|
+
case 'real':
|
|
57
|
+
case 'numeric':
|
|
58
|
+
case 'float':
|
|
59
|
+
case 'float4':
|
|
60
|
+
case 'float8':
|
|
61
|
+
case 'decimal':
|
|
62
|
+
return ColumnType.FLOAT;
|
|
63
|
+
case 'boolean':
|
|
64
|
+
case 'bool':
|
|
65
|
+
return ColumnType.BOOLEAN;
|
|
66
|
+
case 'json':
|
|
67
|
+
case 'jsonb':
|
|
68
|
+
case 'array':
|
|
69
|
+
return ColumnType.JSON;
|
|
70
|
+
case 'text':
|
|
71
|
+
case 'varchar':
|
|
72
|
+
case 'char':
|
|
73
|
+
case 'character varying':
|
|
74
|
+
case 'character':
|
|
75
|
+
return ColumnType.STRING;
|
|
76
|
+
default:
|
|
77
|
+
return sqlType.slice(0, 8);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Generate a UUID v4
|
|
83
|
+
* @returns A UUID v4 string
|
|
84
|
+
*/
|
|
85
|
+
export function generateUUID(): string {
|
|
86
|
+
return crypto.randomUUID();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Generate a random numeric string of specified length
|
|
91
|
+
* @param length - The length of the numeric string to generate
|
|
92
|
+
* @returns A random string containing only digits (0-9)
|
|
93
|
+
*/
|
|
94
|
+
export function generateNumericCode(length: number): string {
|
|
95
|
+
// Generate each digit independently
|
|
96
|
+
let result = '';
|
|
97
|
+
for (let i = 0; i < length; i++) {
|
|
98
|
+
result += crypto.randomInt(0, 10).toString();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Generate a cryptographically secure random token
|
|
106
|
+
* @param bytes - Number of random bytes to generate (default: 32)
|
|
107
|
+
* @returns Hex-encoded string (length = bytes * 2 characters)
|
|
108
|
+
* @example
|
|
109
|
+
* generateSecureToken(32) // Returns 64-character hex string (256 bits entropy)
|
|
110
|
+
* generateSecureToken(16) // Returns 32-character hex string (128 bits entropy)
|
|
111
|
+
*/
|
|
112
|
+
export function generateSecureToken(bytes: number = 32): string {
|
|
113
|
+
return crypto.randomBytes(bytes).toString('hex');
|
|
114
|
+
}
|
|
@@ -100,17 +100,17 @@ export function isValidIdentifier(identifier: string): boolean {
|
|
|
100
100
|
*/
|
|
101
101
|
export function validateTableName(tableName: string): boolean {
|
|
102
102
|
validateIdentifier(tableName, 'table');
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
103
105
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Validates PostgreSQL function name for RPC calls
|
|
108
|
+
* @param functionName - The function name to validate
|
|
109
|
+
* @returns true if valid
|
|
110
|
+
* @throws AppError if invalid
|
|
111
|
+
*/
|
|
112
|
+
export function validateFunctionName(functionName: string): boolean {
|
|
113
|
+
validateIdentifier(functionName, 'function');
|
|
114
114
|
return true;
|
|
115
115
|
}
|
|
116
116
|
|