insforge 0.3.2 → 1.2.10

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.
Files changed (507) hide show
  1. package/.claude-plugin/marketplace.json +20 -0
  2. package/.cursor/rules/cursor-rules.mdc +94 -0
  3. package/.dockerignore +3 -0
  4. package/.env.example +33 -4
  5. package/.github/ISSUE_TEMPLATE/bug_report.yml +13 -60
  6. package/.github/ISSUE_TEMPLATE/config.yml +2 -2
  7. package/.github/ISSUE_TEMPLATE/feature_request.yml +10 -63
  8. package/.github/PULL_REQUEST_TEMPLATE.md +7 -0
  9. package/.github/workflows/build-image.yml +2 -1
  10. package/.github/workflows/e2e.yml +63 -0
  11. package/CHANGELOG.md +41 -0
  12. package/CLAUDE_PLUGIN.md +104 -0
  13. package/CODE_OF_CONDUCT.md +128 -0
  14. package/CONTRIBUTING.md +1 -1
  15. package/Dockerfile +4 -1
  16. package/README.md +66 -18
  17. package/assets/mcpInstallv2.png +0 -0
  18. package/assets/sampleResponse.png +0 -0
  19. package/auth/index.html +13 -0
  20. package/auth/package.json +28 -0
  21. package/auth/public/favicon.ico +0 -0
  22. package/auth/src/App.tsx +33 -0
  23. package/auth/src/components/ErrorCard.tsx +37 -0
  24. package/auth/src/components/Layout.tsx +13 -0
  25. package/auth/src/index.css +19 -0
  26. package/auth/src/lib/broadcastService.ts +115 -0
  27. package/auth/src/lib/utils.ts +11 -0
  28. package/auth/src/main.tsx +22 -0
  29. package/auth/src/pages/ForgotPasswordPage.tsx +11 -0
  30. package/auth/src/pages/ResetPasswordPage.tsx +11 -0
  31. package/auth/src/pages/SignInPage.tsx +57 -0
  32. package/auth/src/pages/SignUpPage.tsx +57 -0
  33. package/auth/src/pages/VerifyEmailPage.tsx +20 -0
  34. package/auth/src/vite-env.d.ts +10 -0
  35. package/auth/tsconfig.json +32 -0
  36. package/auth/tsconfig.node.json +11 -0
  37. package/auth/vite.config.ts +25 -0
  38. package/backend/package.json +9 -9
  39. package/backend/src/api/{middleware → middlewares}/auth.ts +8 -9
  40. package/backend/src/api/middlewares/rate-limiters.ts +127 -0
  41. package/backend/src/api/routes/{ai.ts → ai/index.routes.ts} +20 -24
  42. package/backend/src/api/routes/auth/index.routes.ts +570 -0
  43. package/backend/src/api/routes/auth/oauth.routes.ts +448 -0
  44. package/backend/src/api/routes/{database.advance.ts → database/advance.routes.ts} +107 -65
  45. package/backend/src/api/routes/database/index.routes.ts +13 -0
  46. package/backend/src/api/routes/{database.records.ts → database/records.routes.ts} +22 -8
  47. package/backend/src/api/routes/{database.tables.ts → database/tables.routes.ts} +20 -23
  48. package/backend/src/api/routes/docs/index.routes.ts +76 -0
  49. package/backend/src/api/routes/functions/index.routes.ts +188 -0
  50. package/backend/src/api/routes/{logs.ts → logs/index.routes.ts} +25 -30
  51. package/backend/src/api/routes/{metadata.ts → metadata/index.routes.ts} +21 -31
  52. package/backend/src/api/routes/{secrets.ts → secrets/index.routes.ts} +27 -22
  53. package/backend/src/api/routes/{storage.ts → storage/index.routes.ts} +34 -53
  54. package/backend/src/api/routes/usage/index.routes.ts +89 -0
  55. package/backend/src/infra/config/app.config.ts +51 -0
  56. package/backend/src/{core/database/manager.ts → infra/database/database.manager.ts} +76 -85
  57. package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -0
  58. package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +8 -0
  59. package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +60 -0
  60. package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -0
  61. package/backend/src/{core/secrets/encryption.ts → infra/security/encryption.manager.ts} +3 -2
  62. package/backend/src/infra/security/token.manager.ts +125 -0
  63. package/backend/src/{core/socket/socket.ts → infra/socket/socket.manager.ts} +15 -15
  64. package/backend/src/providers/ai/openrouter.provider.ts +377 -0
  65. package/backend/src/providers/email/base.provider.ts +41 -0
  66. package/backend/src/providers/email/cloud.provider.ts +187 -0
  67. package/backend/src/{core/logs/providers → providers/logs}/base.provider.ts +11 -11
  68. package/backend/src/{core/logs/providers → providers/logs}/cloudwatch.provider.ts +61 -38
  69. package/backend/src/providers/logs/local.provider.ts +185 -0
  70. package/backend/src/providers/oauth/base.provider.ts +29 -0
  71. package/backend/src/providers/oauth/discord.provider.ts +195 -0
  72. package/backend/src/providers/oauth/facebook.provider.ts +194 -0
  73. package/backend/src/providers/oauth/github.provider.ts +208 -0
  74. package/backend/src/providers/oauth/google.provider.ts +249 -0
  75. package/backend/src/providers/oauth/index.ts +7 -0
  76. package/backend/src/providers/oauth/linkedin.provider.ts +240 -0
  77. package/backend/src/providers/oauth/microsoft.provider.ts +169 -0
  78. package/backend/src/providers/oauth/x.provider.ts +202 -0
  79. package/backend/src/providers/storage/base.provider.ts +29 -0
  80. package/backend/src/providers/storage/local.provider.ts +103 -0
  81. package/backend/src/providers/storage/s3.provider.ts +313 -0
  82. package/backend/src/server.ts +70 -74
  83. package/backend/src/{core/ai/config.ts → services/ai/ai-config.service.ts} +19 -24
  84. package/backend/src/services/ai/ai-model.service.ts +60 -0
  85. package/backend/src/{core/ai/usage.ts → services/ai/ai-usage.service.ts} +28 -35
  86. package/backend/src/{core/ai/chat.ts → services/ai/chat-completion.service.ts} +37 -24
  87. package/backend/src/services/ai/helpers.ts +64 -0
  88. package/backend/src/{core/ai/image.ts → services/ai/image-generation.service.ts} +17 -19
  89. package/backend/src/services/ai/index.ts +13 -0
  90. package/backend/src/services/auth/auth-config.service.ts +250 -0
  91. package/backend/src/services/auth/auth-otp.service.ts +424 -0
  92. package/backend/src/services/auth/auth.service.ts +1136 -0
  93. package/backend/src/services/auth/index.ts +4 -0
  94. package/backend/src/{core/auth/oauth.ts → services/auth/oauth-config.service.ts} +106 -52
  95. package/backend/src/{core/database/advance.ts → services/database/database-advance.service.ts} +97 -131
  96. package/backend/src/services/database/database-table.service.ts +811 -0
  97. package/backend/src/services/email/email.service.ts +75 -0
  98. package/backend/src/{core/functions/functions.ts → services/functions/function.service.ts} +95 -88
  99. package/backend/src/{core/logs/audit.ts → services/logs/audit.service.ts} +92 -75
  100. package/backend/src/services/logs/log.service.ts +73 -0
  101. package/backend/src/{core/secrets/secrets.ts → services/secrets/secret.service.ts} +48 -66
  102. package/backend/src/services/storage/storage.service.ts +617 -0
  103. package/backend/src/services/usage/usage.service.ts +149 -0
  104. package/backend/src/types/auth.ts +66 -2
  105. package/backend/src/types/email.ts +8 -0
  106. package/backend/src/types/error-constants.ts +4 -0
  107. package/backend/src/types/logs.ts +0 -29
  108. package/backend/src/{core/socket/types.ts → types/socket.ts} +5 -6
  109. package/backend/src/utils/environment.ts +9 -3
  110. package/backend/src/utils/logger.ts +20 -2
  111. package/backend/src/utils/seed.ts +150 -57
  112. package/backend/src/utils/sql-parser.ts +1 -1
  113. package/backend/src/utils/utils.ts +114 -0
  114. package/backend/src/utils/validations.ts +40 -4
  115. package/backend/tests/local/test-ai-config.sh +129 -0
  116. package/backend/tests/local/test-ai-usage.sh +80 -0
  117. package/backend/tests/local/test-auth-router.sh +1 -1
  118. package/backend/tests/local/test-e2e.sh +1 -1
  119. package/backend/tests/local/test-functions.sh +123 -0
  120. package/backend/tests/local/test-logs.sh +132 -0
  121. package/backend/tests/local/test-public-bucket.sh +3 -3
  122. package/backend/tests/local/test-secrets.sh +14 -12
  123. package/backend/tests/local/test-traditional-rest.sh +2 -2
  124. package/backend/tests/manual/test-rawsql-modes.sh +244 -0
  125. package/backend/tests/test-config.sh +37 -1
  126. package/backend/tests/unit/cloud-token.test.ts +48 -0
  127. package/backend/tests/unit/constant.test.ts +8 -0
  128. package/backend/tests/unit/email.test.ts +372 -0
  129. package/backend/tests/unit/environment.test.ts +59 -0
  130. package/backend/tests/unit/helpers.test.ts +63 -0
  131. package/backend/tests/unit/logger.test.ts +22 -0
  132. package/backend/tests/unit/rate-limit.test.ts +154 -0
  133. package/backend/tests/unit/response.test.ts +58 -0
  134. package/backend/tests/unit/sql-parser.test.ts +74 -0
  135. package/backend/tests/unit/uuid.test.ts +21 -0
  136. package/backend/tests/unit/validations.test.ts +80 -0
  137. package/backend/tsconfig.json +1 -1
  138. package/backend/vitest.config.ts +11 -0
  139. package/claude-plugin/.claude-plugin/plugin.json +24 -0
  140. package/claude-plugin/README.md +133 -0
  141. package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +270 -0
  142. package/docker-compose.prod.yml +60 -4
  143. package/docker-compose.yml +65 -4
  144. package/docker-init/db/db-init.sql +6 -34
  145. package/docker-init/logs/vector.yml +236 -0
  146. package/docs/README.md +44 -0
  147. package/docs/changelog.mdx +67 -0
  148. package/docs/core-concepts/ai/architecture.mdx +373 -0
  149. package/docs/core-concepts/ai/sdk.mdx +213 -0
  150. package/docs/core-concepts/authentication/architecture.mdx +278 -0
  151. package/docs/core-concepts/authentication/sdk.mdx +414 -0
  152. package/docs/core-concepts/authentication/ui-components/customization.mdx +529 -0
  153. package/docs/core-concepts/authentication/ui-components/nextjs.mdx +221 -0
  154. package/docs/core-concepts/authentication/ui-components/react-router.mdx +184 -0
  155. package/docs/core-concepts/authentication/ui-components/react.mdx +129 -0
  156. package/docs/core-concepts/database/architecture.mdx +256 -0
  157. package/docs/core-concepts/database/sdk.mdx +382 -0
  158. package/docs/core-concepts/functions/architecture.mdx +105 -0
  159. package/docs/core-concepts/functions/sdk.mdx +184 -0
  160. package/docs/core-concepts/storage/architecture.mdx +243 -0
  161. package/docs/core-concepts/storage/sdk.mdx +253 -0
  162. package/docs/deployment/README.md +94 -0
  163. package/docs/deployment/deploy-to-aws-ec2.md +565 -0
  164. package/docs/deployment/deploy-to-azure-virtual-machines.md +313 -0
  165. package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -0
  166. package/docs/deployment/deploy-to-render.md +441 -0
  167. package/docs/docs.json +210 -0
  168. package/docs/examples/framework-guides/nextjs.mdx +131 -0
  169. package/docs/examples/framework-guides/nuxt.mdx +165 -0
  170. package/docs/examples/framework-guides/react.mdx +165 -0
  171. package/docs/examples/framework-guides/svelte.mdx +153 -0
  172. package/docs/examples/framework-guides/vue.mdx +159 -0
  173. package/docs/examples/overview.mdx +67 -0
  174. package/docs/favicon.svg +19 -0
  175. package/docs/images/changelog/nov-2025/auth-components.webp +0 -0
  176. package/docs/images/changelog/nov-2025/database-metadata.webp +0 -0
  177. package/docs/images/changelog/nov-2025/quickstart-prompts.webp +0 -0
  178. package/docs/images/changelog/nov-2025/sql-editor.webp +0 -0
  179. package/docs/images/changelog/nov-2025/usage-page.webp +0 -0
  180. package/docs/images/changelog/october-2025/csv-upload.webp +0 -0
  181. package/docs/images/changelog/october-2025/logs-feature.webp +0 -0
  182. package/docs/images/changelog/october-2025/oauth-providers.webp +0 -0
  183. package/docs/images/checks-passed.png +0 -0
  184. package/docs/images/dashboard-connect-expanded.png +0 -0
  185. package/docs/images/dashboard-connect.png +0 -0
  186. package/docs/images/hero-dark.png +0 -0
  187. package/docs/images/hero-light.png +0 -0
  188. package/docs/images/icons/ai.svg +4 -0
  189. package/docs/images/icons/auth.svg +1 -0
  190. package/docs/images/icons/database.svg +1 -0
  191. package/docs/images/icons/function.svg +1 -0
  192. package/docs/images/icons/storage.svg +1 -0
  193. package/docs/images/logos/nextjs.svg +4 -0
  194. package/docs/images/logos/nuxt.svg +4 -0
  195. package/docs/images/logos/react.svg +5 -0
  196. package/docs/images/logos/svelte.svg +4 -0
  197. package/docs/images/logos/vue.svg +5 -0
  198. package/docs/images/mcp-install.png +0 -0
  199. package/docs/images/onboarding-mcp.png +0 -0
  200. package/docs/insforge-instructions-sdk.md +55 -374
  201. package/docs/introduction.mdx +45 -0
  202. package/docs/logo/dark.svg +22 -0
  203. package/docs/logo/light.svg +20 -0
  204. package/docs/partnership.mdx +647 -0
  205. package/docs/quickstart.mdx +83 -0
  206. package/docs/showcase/2048-arena.png +0 -0
  207. package/docs/showcase/framegen-cloud.png +0 -0
  208. package/docs/showcase/line-connect-race.png +0 -0
  209. package/docs/showcase/moment-vibe.png +0 -0
  210. package/docs/showcase/national-flags.png +0 -0
  211. package/docs/showcase/pokemon-vibe.png +0 -0
  212. package/docs/showcase/pure-browse-buy.png +0 -0
  213. package/docs/showcase.mdx +52 -0
  214. package/docs/snippets/sdk-installation.mdx +22 -0
  215. package/docs/snippets/service-icons.mdx +27 -0
  216. package/eslint.config.js +10 -3
  217. package/frontend/package.json +10 -4
  218. package/frontend/src/App.tsx +13 -82
  219. package/frontend/src/assets/icons/connected.svg +3 -0
  220. package/frontend/src/assets/icons/loader.svg +9 -0
  221. package/frontend/src/assets/logos/apple.svg +4 -0
  222. package/frontend/src/assets/logos/discord.svg +1 -1
  223. package/frontend/src/assets/logos/facebook.svg +3 -0
  224. package/frontend/src/assets/logos/instagram.svg +2 -0
  225. package/frontend/src/assets/logos/linkedin.svg +3 -0
  226. package/frontend/src/assets/logos/microsoft.svg +1 -0
  227. package/frontend/src/assets/logos/spotify.svg +17 -0
  228. package/frontend/src/assets/logos/tiktok.svg +6 -0
  229. package/frontend/src/assets/logos/x.svg +3 -0
  230. package/frontend/src/components/Checkbox.tsx +27 -29
  231. package/frontend/src/components/CodeBlock.tsx +55 -2
  232. package/frontend/src/components/CodeEditor.tsx +92 -0
  233. package/frontend/src/components/ConfirmDialog.tsx +1 -1
  234. package/frontend/src/components/ConnectCTA.tsx +38 -0
  235. package/frontend/src/components/CopyButton.tsx +52 -15
  236. package/frontend/src/components/ErrorState.tsx +1 -2
  237. package/frontend/src/components/FeatureSidebar.tsx +6 -6
  238. package/frontend/src/components/FeatureSidebarItem.tsx +2 -2
  239. package/frontend/src/components/JsonHighlight.tsx +21 -9
  240. package/frontend/src/components/ProjectInfoModal.tsx +128 -0
  241. package/frontend/src/components/PromptDialog.tsx +1 -4
  242. package/frontend/src/components/SearchInput.tsx +1 -2
  243. package/frontend/src/components/Stepper.tsx +53 -0
  244. package/frontend/src/components/ThemeToggle.tsx +3 -3
  245. package/frontend/src/components/datagrid/DataGrid.tsx +25 -32
  246. package/frontend/src/components/datagrid/cell-editors/DateCellEditor.tsx +1 -2
  247. package/frontend/src/components/datagrid/cell-editors/JsonCellEditor.tsx +2 -4
  248. package/frontend/src/components/datagrid/index.ts +23 -0
  249. package/frontend/src/components/index.ts +23 -30
  250. package/frontend/src/components/layout/AppHeader.tsx +133 -92
  251. package/frontend/src/components/layout/AppSidebar.tsx +80 -170
  252. package/frontend/src/components/layout/Layout.tsx +12 -23
  253. package/frontend/src/components/layout/PrimaryMenu.tsx +187 -0
  254. package/frontend/src/components/layout/SecondaryMenu.tsx +70 -0
  255. package/frontend/src/components/layout/index.ts +5 -0
  256. package/frontend/src/components/radix/Tooltip.tsx +24 -13
  257. package/frontend/src/components/radix/index.ts +22 -0
  258. package/frontend/src/features/ai/components/AIConfigCard.tsx +129 -83
  259. package/frontend/src/features/ai/components/AIEmptyState.tsx +12 -7
  260. package/frontend/src/features/ai/components/ModalityFilterSidebar.tsx +101 -0
  261. package/frontend/src/features/ai/components/ModelSelectionDialog.tsx +135 -0
  262. package/frontend/src/features/ai/components/ModelSelectionGrid.tsx +51 -0
  263. package/frontend/src/features/ai/components/SystemPromptDialog.tsx +118 -0
  264. package/frontend/src/features/ai/components/index.ts +6 -0
  265. package/frontend/src/features/ai/helpers.ts +57 -71
  266. package/frontend/src/features/ai/hooks/useAIConfigs.ts +39 -113
  267. package/frontend/src/features/ai/hooks/useAIUsage.ts +0 -2
  268. package/frontend/src/features/ai/page/AIPage.tsx +67 -79
  269. package/frontend/src/features/ai/services/ai.service.ts +5 -5
  270. package/frontend/src/features/auth/components/AuthPreview.tsx +96 -0
  271. package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +53 -30
  272. package/frontend/src/features/auth/components/UserFormDialog.tsx +13 -6
  273. package/frontend/src/features/auth/components/UsersDataGrid.tsx +44 -14
  274. package/frontend/src/features/auth/components/index.ts +5 -0
  275. package/frontend/src/features/auth/helpers.tsx +200 -0
  276. package/frontend/src/features/auth/hooks/useAnonToken.ts +30 -0
  277. package/frontend/src/features/auth/hooks/useAuthConfig.ts +48 -0
  278. package/frontend/src/features/auth/hooks/useOAuthConfig.ts +14 -10
  279. package/frontend/src/features/auth/hooks/useUsers.ts +43 -5
  280. package/frontend/src/features/auth/index.ts +3 -2
  281. package/frontend/src/features/auth/page/AuthMethodsPage.tsx +275 -0
  282. package/frontend/src/features/auth/page/ConfigurationPage.tsx +395 -0
  283. package/frontend/src/features/auth/page/UsersPage.tsx +285 -0
  284. package/frontend/src/features/auth/services/anonToken.service.ts +11 -0
  285. package/frontend/src/features/auth/services/config.service.ts +19 -0
  286. package/frontend/src/features/auth/services/{oauth.service.ts → oauth-config.service.ts} +4 -4
  287. package/frontend/src/features/auth/services/{auth.service.ts → user.service.ts} +7 -53
  288. package/frontend/src/features/dashboard/components/ConnectionSuccessBanner.tsx +35 -0
  289. package/frontend/src/features/dashboard/components/PromptCard.tsx +21 -0
  290. package/frontend/src/features/dashboard/components/PromptDialog.tsx +103 -0
  291. package/frontend/src/features/dashboard/components/StatsCard.tsx +50 -0
  292. package/frontend/src/features/dashboard/components/index.ts +4 -0
  293. package/frontend/src/features/dashboard/page/DashboardPage.tsx +187 -169
  294. package/frontend/src/features/dashboard/prompts/ai-chatbot.ts +13 -0
  295. package/frontend/src/features/dashboard/prompts/crm-system.ts +13 -0
  296. package/frontend/src/features/dashboard/prompts/ecommerce-platform.ts +12 -0
  297. package/frontend/src/features/dashboard/prompts/index.ts +31 -0
  298. package/frontend/src/features/dashboard/prompts/instagram-clone.ts +11 -0
  299. package/frontend/src/features/dashboard/prompts/notion-clone.ts +14 -0
  300. package/frontend/src/features/dashboard/prompts/reddit-clone.ts +12 -0
  301. package/frontend/src/features/database/components/DatabaseDataGrid.tsx +48 -17
  302. package/frontend/src/features/database/components/ForeignKeyCell.tsx +15 -34
  303. package/frontend/src/features/database/components/ForeignKeyPopover.tsx +19 -20
  304. package/frontend/src/features/database/components/LinkRecordModal.tsx +120 -125
  305. package/frontend/src/features/database/components/RecordFormDialog.tsx +22 -33
  306. package/frontend/src/features/database/components/RecordFormField.tsx +45 -47
  307. package/frontend/src/features/database/components/TableEmptyState.tsx +6 -5
  308. package/frontend/src/features/database/components/TableForm.tsx +28 -15
  309. package/frontend/src/features/database/components/TableFormColumn.tsx +2 -3
  310. package/frontend/src/features/database/components/TableSidebar.tsx +1 -1
  311. package/frontend/src/features/database/components/TablesEmptyState.tsx +48 -0
  312. package/frontend/src/features/database/components/TemplateCard.tsx +37 -0
  313. package/frontend/src/features/database/components/TemplatePreview.tsx +92 -0
  314. package/frontend/src/features/database/components/index.ts +19 -0
  315. package/frontend/src/features/database/constants.ts +28 -2
  316. package/frontend/src/features/database/contexts/SQLEditorContext.tsx +188 -0
  317. package/frontend/src/features/database/helpers.ts +2 -2
  318. package/frontend/src/features/database/hooks/useCSVImport.ts +29 -0
  319. package/frontend/src/features/database/hooks/useFullMetadata.ts +18 -0
  320. package/frontend/src/features/database/hooks/useRawSQL.ts +55 -0
  321. package/frontend/src/features/database/hooks/useRecords.ts +139 -0
  322. package/frontend/src/features/database/hooks/useTables.ts +131 -0
  323. package/frontend/src/features/database/index.ts +6 -1
  324. package/frontend/src/features/database/page/FunctionsPage.tsx +211 -0
  325. package/frontend/src/features/database/page/IndexesPage.tsx +240 -0
  326. package/frontend/src/features/database/page/PoliciesPage.tsx +248 -0
  327. package/frontend/src/features/database/page/SQLEditorPage.tsx +382 -0
  328. package/frontend/src/features/database/page/{DatabasePage.tsx → TablesPage.tsx} +186 -185
  329. package/frontend/src/features/database/page/TemplatesPage.tsx +39 -0
  330. package/frontend/src/features/database/page/TriggersPage.tsx +242 -0
  331. package/frontend/src/features/database/services/advance.service.ts +66 -0
  332. package/frontend/src/features/database/services/{database.service.ts → record.service.ts} +67 -64
  333. package/frontend/src/features/database/services/table.service.ts +64 -0
  334. package/frontend/src/features/database/templates/ai-chatbot.ts +402 -0
  335. package/frontend/src/features/database/templates/crm-system.ts +528 -0
  336. package/frontend/src/features/database/templates/ecommerce-platform.ts +553 -0
  337. package/frontend/src/features/database/templates/index.ts +34 -0
  338. package/frontend/src/features/database/templates/instagram-clone.ts +222 -0
  339. package/frontend/src/features/database/templates/notion-clone.ts +483 -0
  340. package/frontend/src/features/database/templates/reddit-clone.ts +526 -0
  341. package/frontend/src/features/functions/components/FunctionRow.tsx +2 -1
  342. package/frontend/src/features/functions/components/FunctionsSidebar.tsx +1 -1
  343. package/frontend/src/features/functions/components/SecretRow.tsx +1 -1
  344. package/frontend/src/features/functions/components/index.ts +5 -0
  345. package/frontend/src/features/functions/hooks/useFunctions.ts +4 -4
  346. package/frontend/src/features/{secrets → functions}/hooks/useSecrets.ts +5 -5
  347. package/frontend/src/features/functions/page/FunctionsPage.tsx +160 -17
  348. package/frontend/src/features/functions/{components/SecretsContent.tsx → page/SecretsPage.tsx} +8 -12
  349. package/frontend/src/features/functions/services/{functions.service.ts → function.service.ts} +2 -2
  350. package/frontend/src/features/{secrets/services/secrets.service.ts → functions/services/secret.service.ts} +2 -2
  351. package/frontend/src/features/login/hooks/usePartnerOrigin.ts +27 -0
  352. package/frontend/src/features/login/page/CloudLoginPage.tsx +79 -54
  353. package/frontend/src/features/login/page/LoginPage.tsx +16 -23
  354. package/frontend/src/features/login/services/partnership.service.ts +65 -0
  355. package/frontend/src/features/logs/components/LogsDataGrid.tsx +89 -0
  356. package/frontend/src/features/logs/components/SeverityBadge.tsx +18 -0
  357. package/frontend/src/features/logs/components/index.ts +2 -0
  358. package/frontend/src/features/logs/helpers.ts +24 -0
  359. package/frontend/src/features/logs/hooks/useAuditLogs.ts +4 -4
  360. package/frontend/src/features/logs/hooks/useLogSources.ts +137 -0
  361. package/frontend/src/features/logs/hooks/useLogs.ts +163 -0
  362. package/frontend/src/features/logs/hooks/useMcpUsage.ts +181 -0
  363. package/frontend/src/features/logs/index.ts +8 -2
  364. package/frontend/src/features/logs/page/AuditsPage.tsx +91 -38
  365. package/frontend/src/features/logs/page/LogsPage.tsx +152 -0
  366. package/frontend/src/features/logs/page/MCPLogsPage.tsx +84 -0
  367. package/frontend/src/features/logs/services/audit.service.ts +63 -0
  368. package/frontend/src/features/logs/services/log.service.ts +15 -110
  369. package/frontend/src/features/logs/services/usage.service.ts +31 -0
  370. package/frontend/src/features/onboard/components/McpConnectionStatus.tsx +68 -0
  371. package/frontend/src/features/onboard/components/OnboardingModal.tsx +267 -0
  372. package/frontend/src/features/onboard/components/VideoDemoModal.tsx +38 -0
  373. package/frontend/src/features/onboard/components/index.ts +4 -0
  374. package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +2 -2
  375. package/frontend/src/features/onboard/components/mcp/{mcp-helper.tsx → helpers.tsx} +8 -8
  376. package/frontend/src/features/onboard/components/mcp/index.ts +2 -3
  377. package/frontend/src/features/onboard/index.ts +13 -3
  378. package/frontend/src/features/storage/components/BucketEmptyState.tsx +9 -6
  379. package/frontend/src/features/storage/components/BucketFormDialog.tsx +25 -41
  380. package/frontend/src/features/storage/components/FilePreviewDialog.tsx +20 -8
  381. package/frontend/src/features/storage/components/StorageDataGrid.tsx +4 -3
  382. package/frontend/src/features/storage/components/StorageManager.tsx +23 -34
  383. package/frontend/src/features/storage/components/index.ts +12 -0
  384. package/frontend/src/features/storage/hooks/useStorage.ts +208 -0
  385. package/frontend/src/features/storage/page/StoragePage.tsx +41 -115
  386. package/frontend/src/features/storage/services/storage.service.ts +22 -1
  387. package/frontend/src/features/visualizer/components/AuthNode.tsx +72 -56
  388. package/frontend/src/features/visualizer/components/BucketNode.tsx +4 -4
  389. package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +108 -80
  390. package/frontend/src/features/visualizer/components/TableNode.tsx +34 -41
  391. package/frontend/src/features/visualizer/components/VisualizerSkeleton.tsx +12 -4
  392. package/frontend/src/features/visualizer/page/VisualizerPage.tsx +33 -29
  393. package/frontend/src/index.css +1 -0
  394. package/frontend/src/lib/analytics/posthog.tsx +27 -0
  395. package/frontend/src/lib/contexts/AuthContext.tsx +38 -31
  396. package/frontend/src/lib/contexts/SocketContext.tsx +5 -6
  397. package/frontend/src/{features/metadata → lib}/hooks/useMetadata.ts +1 -1
  398. package/frontend/src/lib/hooks/useToast.tsx +6 -2
  399. package/frontend/src/lib/routing/AppRoutes.tsx +84 -0
  400. package/frontend/src/lib/routing/RequireAuth.tsx +27 -0
  401. package/frontend/src/lib/utils/cloudMessaging.ts +20 -0
  402. package/frontend/src/lib/utils/menuItems.ts +183 -0
  403. package/frontend/src/lib/utils/{validation-schemas.ts → schemaValidations.ts} +10 -5
  404. package/frontend/src/lib/utils/utils.ts +19 -1
  405. package/frontend/src/vite-env.d.ts +1 -0
  406. package/frontend/vite.config.ts +5 -3
  407. package/functions/server.ts +28 -3
  408. package/functions/worker-template.js +15 -4
  409. package/i18n/README.ar.md +130 -0
  410. package/i18n/README.de.md +130 -0
  411. package/i18n/README.es.md +154 -0
  412. package/i18n/README.fr.md +134 -0
  413. package/i18n/README.hi.md +129 -0
  414. package/i18n/README.ja.md +174 -0
  415. package/i18n/README.ko.md +137 -0
  416. package/i18n/README.pt-BR.md +131 -0
  417. package/i18n/README.ru.md +129 -0
  418. package/i18n/README.zh-CN.md +133 -0
  419. package/openapi/ai.yaml +31 -4
  420. package/openapi/auth.yaml +827 -146
  421. package/package.json +16 -7
  422. package/shared-schemas/package.json +1 -1
  423. package/shared-schemas/src/ai-api.schema.ts +34 -58
  424. package/shared-schemas/src/ai.schema.ts +5 -0
  425. package/shared-schemas/src/auth-api.schema.ts +154 -8
  426. package/shared-schemas/src/auth.schema.ts +42 -6
  427. package/shared-schemas/src/cloud-events.schema.ts +57 -0
  428. package/shared-schemas/src/database-api.schema.ts +3 -3
  429. package/shared-schemas/src/database.schema.ts +1 -1
  430. package/shared-schemas/src/index.ts +1 -0
  431. package/shared-schemas/src/logs-api.schema.ts +7 -1
  432. package/shared-schemas/src/logs.schema.ts +26 -0
  433. package/shared-schemas/src/metadata.schema.ts +9 -4
  434. package/test-gemini.sh +35 -0
  435. package/test-usage-admin.sh +57 -0
  436. package/test-usage.sh +50 -0
  437. package/zeabur/README.md +13 -0
  438. package/zeabur/template.yml +1032 -0
  439. package/.github/workflows/deploy-aws.yml +0 -130
  440. package/backend/src/api/routes/agent.ts +0 -29
  441. package/backend/src/api/routes/auth.oauth.ts +0 -482
  442. package/backend/src/api/routes/auth.ts +0 -386
  443. package/backend/src/api/routes/docs.ts +0 -66
  444. package/backend/src/api/routes/functions.ts +0 -183
  445. package/backend/src/api/routes/openapi.ts +0 -82
  446. package/backend/src/api/routes/usage.ts +0 -96
  447. package/backend/src/core/ai/client.ts +0 -242
  448. package/backend/src/core/ai/model.ts +0 -117
  449. package/backend/src/core/auth/auth.ts +0 -781
  450. package/backend/src/core/database/table.ts +0 -772
  451. package/backend/src/core/documentation/agent.ts +0 -689
  452. package/backend/src/core/documentation/openapi.ts +0 -856
  453. package/backend/src/core/logs/analytics.ts +0 -76
  454. package/backend/src/core/logs/providers/localdb.provider.ts +0 -246
  455. package/backend/src/core/storage/storage.ts +0 -923
  456. package/backend/src/utils/cloud-token.ts +0 -39
  457. package/backend/src/utils/helpers.ts +0 -49
  458. package/backend/src/utils/uuid.ts +0 -9
  459. package/backend/tests/manual/test-better-auth.sh +0 -303
  460. package/docker-init/db/logs.sql +0 -9
  461. package/frontend/README.md +0 -112
  462. package/frontend/src/components/datagrid/index.tsx +0 -20
  463. package/frontend/src/components/layout/CloudLayout.tsx +0 -95
  464. package/frontend/src/features/ai/components/AIConfigDialog.tsx +0 -76
  465. package/frontend/src/features/ai/components/AIConfigForm.tsx +0 -222
  466. package/frontend/src/features/ai/components/fields/ModalityField.tsx +0 -87
  467. package/frontend/src/features/ai/components/fields/ModelSelectionField.tsx +0 -134
  468. package/frontend/src/features/ai/components/fields/SystemPromptField.tsx +0 -33
  469. package/frontend/src/features/auth/components/AddOAuthDialog.tsx +0 -106
  470. package/frontend/src/features/auth/components/AuthMethodTab.tsx +0 -238
  471. package/frontend/src/features/auth/components/UsersTab.tsx +0 -114
  472. package/frontend/src/features/auth/page/AuthenticationPage.tsx +0 -169
  473. package/frontend/src/features/database/hooks/UseLinkModal.tsx +0 -78
  474. package/frontend/src/features/functions/components/FunctionViewer.tsx +0 -46
  475. package/frontend/src/features/functions/components/FunctionsContent.tsx +0 -88
  476. package/frontend/src/features/login/components/AuthErrorBoundary.tsx +0 -87
  477. package/frontend/src/features/login/components/PrivateRoute.tsx +0 -24
  478. package/frontend/src/features/logs/components/AnalyticsLogsTable.tsx +0 -313
  479. package/frontend/src/features/logs/components/LogsTable.tsx +0 -199
  480. package/frontend/src/features/logs/page/AnalyticsLogsPage.tsx +0 -530
  481. package/frontend/src/features/metadata/index.ts +0 -0
  482. package/frontend/src/features/metadata/page/MetadataPage.tsx +0 -136
  483. package/frontend/src/features/onboard/components/CompletionCard.tsx +0 -41
  484. package/frontend/src/features/onboard/components/OnboardButton.tsx +0 -84
  485. package/frontend/src/features/onboard/components/StepContent.tsx +0 -91
  486. package/frontend/src/features/onboard/components/TestConnectionStep.tsx +0 -53
  487. package/frontend/src/features/onboard/components/mcp/McpInstallation.tsx +0 -144
  488. package/frontend/src/features/onboard/page/OnBoardPage.tsx +0 -104
  489. package/frontend/src/features/onboard/types.ts +0 -8
  490. package/frontend/src/lib/contexts/OnboardStepContext.tsx +0 -68
  491. package/frontend/src/lib/hooks/useOnboardingCompletion.ts +0 -29
  492. /package/backend/src/api/{middleware → middlewares}/error.ts +0 -0
  493. /package/backend/src/api/{middleware → middlewares}/upload.ts +0 -0
  494. /package/backend/{migrations → src/infra/database/migrations}/000_create-base-tables.sql +0 -0
  495. /package/backend/{migrations → src/infra/database/migrations}/001_create-helper-functions.sql +0 -0
  496. /package/backend/{migrations → src/infra/database/migrations}/002_rename-auth-tables.sql +0 -0
  497. /package/backend/{migrations → src/infra/database/migrations}/003_create-users-table.sql +0 -0
  498. /package/backend/{migrations → src/infra/database/migrations}/004_add-reload-postgrest-func.sql +0 -0
  499. /package/backend/{migrations → src/infra/database/migrations}/005_enable-project-admin-modify-users.sql +0 -0
  500. /package/backend/{migrations → src/infra/database/migrations}/006_modify-ai-usage-table.sql +0 -0
  501. /package/backend/{migrations → src/infra/database/migrations}/007_drop-metadata-table.sql +0 -0
  502. /package/backend/{migrations → src/infra/database/migrations}/008_add-system-tables.sql +0 -0
  503. /package/backend/{migrations → src/infra/database/migrations}/009_add-function-secrets.sql +0 -0
  504. /package/backend/{migrations → src/infra/database/migrations}/010_modify-ai-config-modalities.sql +0 -0
  505. /package/backend/{migrations → src/infra/database/migrations}/011_refactor-secrets-table.sql +0 -0
  506. /package/backend/{migrations → src/infra/database/migrations}/012_add-storage-uploaded-by.sql +0 -0
  507. /package/frontend/src/{features/metadata → lib}/services/metadata.service.ts +0 -0
@@ -0,0 +1,275 @@
1
+ import { useState, useCallback, useMemo } from 'react';
2
+ import { MoreHorizontal, Plus, Trash2, Pencil, Mail, ChevronDown } from 'lucide-react';
3
+ import { OAuthConfigDialog, AuthPreview } from '@/features/auth/components';
4
+ import { useOAuthConfig } from '@/features/auth/hooks/useOAuthConfig';
5
+ import { useConfirm } from '@/lib/hooks/useConfirm';
6
+ import {
7
+ Button,
8
+ ConfirmDialog,
9
+ CopyButton,
10
+ DropdownMenu,
11
+ DropdownMenuContent,
12
+ DropdownMenuItem,
13
+ DropdownMenuTrigger,
14
+ DropdownMenuSeparator,
15
+ } from '@/components';
16
+ import type { OAuthProvidersSchema } from '@insforge/shared-schemas';
17
+ import {
18
+ oauthProviders,
19
+ type OAuthProviderInfo,
20
+ getAuthImplementationPrompt,
21
+ } from '@/features/auth/helpers';
22
+ import { getBackendUrl } from '@/lib/utils/utils';
23
+
24
+ export default function AuthMethodsPage() {
25
+ const [selectedProvider, setSelectedProvider] = useState<OAuthProviderInfo>();
26
+ const [isDialogOpen, setIsDialogOpen] = useState(false);
27
+ const { confirm, confirmDialogProps } = useConfirm();
28
+ const {
29
+ configs,
30
+ isLoadingConfigs,
31
+ deleteConfig,
32
+ refetchConfigs,
33
+ getProviderConfig,
34
+ isProviderConfigured,
35
+ } = useOAuthConfig();
36
+
37
+ const handleConfigureProvider = (provider: OAuthProviderInfo) => {
38
+ setSelectedProvider(provider);
39
+ setIsDialogOpen(true);
40
+ };
41
+
42
+ const deleteOAuthConfig = async (providerId: OAuthProvidersSchema, providerName: string) => {
43
+ const shouldDelete = await confirm({
44
+ title: `Delete ${providerName} OAuth`,
45
+ description: `Are you sure you want to delete the ${providerName} configuration? This action cannot be undone.`,
46
+ confirmText: 'Delete',
47
+ cancelText: 'Cancel',
48
+ destructive: true,
49
+ });
50
+
51
+ if (shouldDelete) {
52
+ deleteConfig(providerId);
53
+ }
54
+ };
55
+
56
+ const handleCloseDialog = () => {
57
+ setIsDialogOpen(false);
58
+ setSelectedProvider(undefined);
59
+ };
60
+
61
+ const hasAuthMethods = useMemo(() => {
62
+ return !!configs.length;
63
+ }, [configs]);
64
+
65
+ const enabledProviders = useMemo(() => {
66
+ const enabled: Record<OAuthProvidersSchema, boolean> = {} as Record<
67
+ OAuthProvidersSchema,
68
+ boolean
69
+ >;
70
+ oauthProviders.forEach((provider) => {
71
+ enabled[provider.id] = isProviderConfigured(provider.id);
72
+ });
73
+ return enabled;
74
+ }, [isProviderConfigured]);
75
+
76
+ // Check if all providers are enabled
77
+ const allProvidersEnabled = useMemo(() => {
78
+ return oauthProviders.every((provider) => enabledProviders[provider.id]);
79
+ }, [enabledProviders]);
80
+
81
+ const handleSuccess = useCallback(() => {
82
+ // Refresh configuration after successful update
83
+ void refetchConfigs();
84
+ }, [refetchConfigs]);
85
+
86
+ if (isLoadingConfigs) {
87
+ return (
88
+ <div className="h-full bg-slate-50 dark:bg-neutral-800 flex flex-col overflow-hidden">
89
+ <div className="flex-1 flex items-center justify-center">
90
+ <div className="text-center">
91
+ <div className="text-sm text-gray-500 dark:text-zinc-400">
92
+ Loading OAuth configuration...
93
+ </div>
94
+ </div>
95
+ </div>
96
+ </div>
97
+ );
98
+ }
99
+
100
+ return (
101
+ <div className="h-full flex flex-col overflow-hidden">
102
+ {/* Two column layout */}
103
+ <div className="h-full flex overflow-hidden">
104
+ {/* Left Section - Auth Methods List */}
105
+ <div className="flex-1 bg-slate-50 dark:bg-[#2d2d2d] flex flex-col overflow-hidden">
106
+ {/* Header */}
107
+ <div className="flex items-center justify-between px-4 py-6 gap-3">
108
+ <h2 className="px-4 text-xl font-semibold text-gray-900 dark:text-white tracking-tight">
109
+ Auth Methods
110
+ </h2>
111
+ {!allProvidersEnabled && (
112
+ <DropdownMenu>
113
+ <DropdownMenuTrigger asChild>
114
+ <Button className="h-8 px-2 py-0 gap-2 bg-black text-white dark:bg-neutral-600 dark:text-white hover:bg-gray-800 dark:hover:bg-neutral-500 text-sm font-medium rounded">
115
+ <Plus className="w-5 h-5" />
116
+ Add Provider
117
+ <ChevronDown className="w-4 h-4" />
118
+ </Button>
119
+ </DropdownMenuTrigger>
120
+ <DropdownMenuContent align="end" className="w-80">
121
+ {/* Available providers (not enabled) */}
122
+ {oauthProviders
123
+ .filter((provider) => !enabledProviders[provider.id])
124
+ .map((provider) => (
125
+ <DropdownMenuItem
126
+ key={provider.id}
127
+ onClick={() => handleConfigureProvider(provider)}
128
+ className="py-2 px-3 flex items-center gap-3 cursor-pointer"
129
+ >
130
+ {provider.icon}
131
+ <span className="text-sm">{provider.name}</span>
132
+ </DropdownMenuItem>
133
+ ))}
134
+
135
+ {/* Separator if there are both enabled and disabled providers */}
136
+ {oauthProviders.some((p) => enabledProviders[p.id]) &&
137
+ oauthProviders.some((p) => !enabledProviders[p.id]) && (
138
+ <DropdownMenuSeparator />
139
+ )}
140
+
141
+ {/* Enabled providers (disabled from selection) */}
142
+ {oauthProviders
143
+ .filter((provider) => enabledProviders[provider.id])
144
+ .map((provider) => (
145
+ <DropdownMenuItem
146
+ key={provider.id}
147
+ disabled
148
+ className="py-2 px-3 flex items-center justify-between gap-3 opacity-50 cursor-not-allowed"
149
+ >
150
+ <div className="flex items-center gap-3">
151
+ {provider.icon}
152
+ <span className="text-sm">{provider.name}</span>
153
+ </div>
154
+ <span className="text-xs px-2 py-0.5 bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-400 rounded border border-emerald-300 dark:border-emerald-700">
155
+ Enabled
156
+ </span>
157
+ </DropdownMenuItem>
158
+ ))}
159
+ </DropdownMenuContent>
160
+ </DropdownMenu>
161
+ )}
162
+ </div>
163
+
164
+ {/* Auth Methods List */}
165
+ <div className="flex-1 overflow-y-auto p-4">
166
+ <div className="flex flex-col gap-3">
167
+ {/* Email Auth Card */}
168
+ <div className="flex items-center justify-between px-6 py-4 bg-white dark:bg-neutral-800 rounded-lg border border-gray-200 dark:border-transparent">
169
+ <div className="flex items-center gap-3">
170
+ <Mail className="w-6 h-6 text-gray-700 dark:text-white" />
171
+ <div className="text-sm font-medium text-black dark:text-white">Email Auth</div>
172
+ </div>
173
+ </div>
174
+
175
+ {/* OAuth Providers */}
176
+ {hasAuthMethods &&
177
+ oauthProviders.map((provider) => {
178
+ const providerConfig = getProviderConfig(provider.id);
179
+ if (!providerConfig) {
180
+ return null;
181
+ }
182
+
183
+ return (
184
+ <div
185
+ key={provider.id}
186
+ className="flex items-center justify-between px-6 py-4 bg-white dark:bg-neutral-800 rounded-lg border border-gray-200 dark:border-transparent"
187
+ >
188
+ <div className="flex items-center gap-3">
189
+ {provider.icon}
190
+ <div className="text-sm font-medium text-black dark:text-white">
191
+ {provider.name}
192
+ </div>
193
+ </div>
194
+
195
+ <div className="flex items-center gap-3">
196
+ {providerConfig.useSharedKey && (
197
+ <span className="px-2 py-0.5 text-xs font-medium text-neutral-500 dark:text-neutral-400 border border-neutral-500 dark:border-neutral-400 rounded">
198
+ Shared Keys
199
+ </span>
200
+ )}
201
+
202
+ <DropdownMenu>
203
+ <DropdownMenuTrigger asChild>
204
+ <Button
205
+ className="h-7 w-7 p-1 text-gray-500 dark:text-neutral-400 hover:bg-gray-100 dark:hover:bg-neutral-700"
206
+ variant="ghost"
207
+ size="sm"
208
+ >
209
+ <MoreHorizontal className="w-5 h-5" />
210
+ </Button>
211
+ </DropdownMenuTrigger>
212
+ <DropdownMenuContent align="end" className="w-40 py-1 px-2">
213
+ <DropdownMenuItem
214
+ onClick={() => handleConfigureProvider(provider)}
215
+ className="py-2 px-3 flex items-center gap-3 cursor-pointer"
216
+ >
217
+ <Pencil className="w-5 h-5" />
218
+ Edit
219
+ </DropdownMenuItem>
220
+ <DropdownMenuItem
221
+ onClick={() => void deleteOAuthConfig(provider.id, provider.name)}
222
+ className="py-2 px-3 flex items-center gap-3 cursor-pointer text-red-600 dark:text-red-400"
223
+ >
224
+ <Trash2 className="w-5 h-5" />
225
+ Delete
226
+ </DropdownMenuItem>
227
+ </DropdownMenuContent>
228
+ </DropdownMenu>
229
+ </div>
230
+ </div>
231
+ );
232
+ })}
233
+ </div>
234
+ </div>
235
+ </div>
236
+
237
+ {/* Right Section - Preview */}
238
+ <div className="w-[688px] bg-slate-50 dark:bg-[#2d2d2d] p-3 flex flex-col overflow-hidden">
239
+ <div className="h-full bg-gray-200 dark:bg-neutral-700 rounded-xl overflow-hidden flex flex-col">
240
+ {/* Preview Header */}
241
+ <div className="flex items-center justify-end px-6 py-3 gap-3">
242
+ <p className="text-sm font-medium text-gray-700 dark:text-white">
243
+ Integrate Authentication to Your Application
244
+ </p>
245
+ <CopyButton
246
+ text={getAuthImplementationPrompt(getBackendUrl())}
247
+ copyText="Copy Prompt"
248
+ variant="primary"
249
+ className="w-34"
250
+ />
251
+ </div>
252
+
253
+ {/* Preview Content */}
254
+ <div className="flex-1 overflow-y-auto py-8 flex flex-col items-center justify-center gap-4">
255
+ <AuthPreview />
256
+ <p className="text-xs text-gray-500 dark:text-neutral-400 text-center">
257
+ Preview Mode
258
+ </p>
259
+ </div>
260
+ </div>
261
+ </div>
262
+ </div>
263
+
264
+ <OAuthConfigDialog
265
+ provider={selectedProvider}
266
+ isOpen={isDialogOpen}
267
+ onClose={handleCloseDialog}
268
+ onSuccess={handleSuccess}
269
+ />
270
+
271
+ {/* Confirm Dialog */}
272
+ <ConfirmDialog {...confirmDialogProps} />
273
+ </div>
274
+ );
275
+ }
@@ -0,0 +1,395 @@
1
+ import { useEffect } from 'react';
2
+ import { useForm, Controller } from 'react-hook-form';
3
+ import { zodResolver } from '@hookform/resolvers/zod';
4
+ import {
5
+ Button,
6
+ Input,
7
+ Switch,
8
+ Checkbox,
9
+ Select,
10
+ SelectContent,
11
+ SelectItem,
12
+ SelectTrigger,
13
+ } from '@/components';
14
+ import {
15
+ updateAuthConfigRequestSchema,
16
+ type UpdateAuthConfigRequest,
17
+ } from '@insforge/shared-schemas';
18
+ import { useAuthConfig } from '@/features/auth/hooks/useAuthConfig';
19
+ import { isInsForgeCloudProject } from '@/lib/utils/utils';
20
+
21
+ export default function ConfigurationPage() {
22
+ const { config, isLoading, isUpdating, updateConfig } = useAuthConfig();
23
+
24
+ const form = useForm<UpdateAuthConfigRequest>({
25
+ resolver: zodResolver(updateAuthConfigRequestSchema),
26
+ defaultValues: {
27
+ requireEmailVerification: false,
28
+ passwordMinLength: 6,
29
+ requireNumber: false,
30
+ requireLowercase: false,
31
+ requireUppercase: false,
32
+ requireSpecialChar: false,
33
+ verifyEmailMethod: 'code',
34
+ resetPasswordMethod: 'code',
35
+ signInRedirectTo: null,
36
+ },
37
+ });
38
+
39
+ // Load configuration when config changes
40
+ useEffect(() => {
41
+ if (config) {
42
+ form.reset({
43
+ requireEmailVerification: config.requireEmailVerification,
44
+ passwordMinLength: config.passwordMinLength,
45
+ requireNumber: config.requireNumber,
46
+ requireLowercase: config.requireLowercase,
47
+ requireUppercase: config.requireUppercase,
48
+ requireSpecialChar: config.requireSpecialChar,
49
+ verifyEmailMethod: config.verifyEmailMethod,
50
+ resetPasswordMethod: config.resetPasswordMethod,
51
+ signInRedirectTo: config.signInRedirectTo ?? null,
52
+ });
53
+ }
54
+ }, [config, form]);
55
+
56
+ const handleSubmitData = (data: UpdateAuthConfigRequest) => {
57
+ updateConfig(data);
58
+ };
59
+
60
+ const handleSubmit = () => {
61
+ void form.handleSubmit(handleSubmitData)();
62
+ };
63
+
64
+ const handleReset = () => {
65
+ if (config) {
66
+ form.reset({
67
+ requireEmailVerification: config.requireEmailVerification,
68
+ passwordMinLength: config.passwordMinLength,
69
+ requireNumber: config.requireNumber,
70
+ requireLowercase: config.requireLowercase,
71
+ requireUppercase: config.requireUppercase,
72
+ requireSpecialChar: config.requireSpecialChar,
73
+ verifyEmailMethod: config.verifyEmailMethod,
74
+ resetPasswordMethod: config.resetPasswordMethod,
75
+ signInRedirectTo: config.signInRedirectTo ?? null,
76
+ });
77
+ }
78
+ };
79
+
80
+ if (isLoading) {
81
+ return (
82
+ <div className="h-full bg-slate-50 dark:bg-neutral-800 flex flex-col overflow-hidden">
83
+ <div className="flex-1 flex items-center justify-center">
84
+ <div className="text-center">
85
+ <div className="text-sm text-gray-500 dark:text-zinc-400">Loading configuration...</div>
86
+ </div>
87
+ </div>
88
+ </div>
89
+ );
90
+ }
91
+
92
+ return (
93
+ <div className="h-full bg-slate-50 dark:bg-neutral-800 flex flex-col overflow-hidden">
94
+ <div className="flex-1 flex flex-col overflow-y-auto">
95
+ <div className="p-6 w-full max-w-[1080px] mx-auto">
96
+ <div className="flex flex-col gap-8">
97
+ <div>
98
+ <h2 className="text-2xl font-semibold text-gray-900 dark:text-white">
99
+ Configuration
100
+ </h2>
101
+ </div>
102
+
103
+ <form onSubmit={(e) => e.preventDefault()} className="flex flex-col gap-8">
104
+ {/* Sign In Redirect URL */}
105
+ <div className="space-y-6">
106
+ <div className="bg-white dark:bg-[#333333] rounded-lg p-6 flex items-center gap-10">
107
+ <div className="w-100 flex flex-col gap-1">
108
+ <label className="text-sm font-medium text-gray-900 dark:text-white">
109
+ Redirect URL After Sign In
110
+ </label>
111
+ <span className="text-xs text-zinc-500 dark:text-neutral-400">
112
+ Your app url after successful authentication
113
+ </span>
114
+ </div>
115
+ <div className="w-full max-w-[320px]">
116
+ <Input
117
+ type="url"
118
+ placeholder="https://yourapp.com/dashboard"
119
+ {...form.register('signInRedirectTo')}
120
+ className={`bg-white dark:bg-neutral-900 dark:placeholder:text-neutral-400 dark:border-neutral-700 dark:text-white ${
121
+ form.formState.errors.signInRedirectTo
122
+ ? 'border-red-500 dark:border-red-500'
123
+ : ''
124
+ }`}
125
+ />
126
+ {form.formState.errors.signInRedirectTo && (
127
+ <span className="text-xs text-red-500">
128
+ {form.formState.errors.signInRedirectTo.message ||
129
+ 'Please enter a valid URL'}
130
+ </span>
131
+ )}
132
+ </div>
133
+ </div>
134
+ </div>
135
+
136
+ {isInsForgeCloudProject() && (
137
+ <div className="space-y-6">
138
+ <div>
139
+ <h3 className="text-lg font-medium text-gray-900 dark:text-white mb-3">
140
+ Email Verification
141
+ </h3>
142
+ </div>
143
+
144
+ <div className="bg-white dark:bg-[#333333] rounded-lg p-6 space-y-6">
145
+ {/* Email Verification Toggle */}
146
+ <div className="flex items-center gap-10">
147
+ <div className="w-100 flex flex-col gap-1">
148
+ <span className="text-sm font-medium text-gray-900 dark:text-white">
149
+ Require Email Verification
150
+ </span>
151
+ <span className="text-xs text-zinc-500 dark:text-neutral-400">
152
+ Users must verify their email address before they can sign in
153
+ </span>
154
+ </div>
155
+ <Controller
156
+ name="requireEmailVerification"
157
+ control={form.control}
158
+ render={({ field }) => (
159
+ <div className="w-full max-w-[320px]">
160
+ <Switch
161
+ checked={field.value}
162
+ onCheckedChange={(value) => {
163
+ field.onChange(value);
164
+ }}
165
+ />
166
+ </div>
167
+ )}
168
+ />
169
+ </div>
170
+
171
+ {/* Verify Email Method - Only shown when email verification is enabled */}
172
+ {form.watch('requireEmailVerification') && (
173
+ <div className="flex items-center gap-10">
174
+ <div className="w-100 flex flex-col gap-1">
175
+ <label className="text-sm font-medium text-gray-900 dark:text-white">
176
+ Email Verification Method
177
+ </label>
178
+ <span className="text-xs text-zinc-500 dark:text-neutral-400">
179
+ Choose between 6-digit verification code or verification link
180
+ </span>
181
+ </div>
182
+ <Controller
183
+ name="verifyEmailMethod"
184
+ control={form.control}
185
+ render={({ field }) => (
186
+ <Select
187
+ value={field.value}
188
+ onValueChange={(value) => {
189
+ if (value) {
190
+ field.onChange(value);
191
+ }
192
+ }}
193
+ >
194
+ <SelectTrigger className="w-full max-w-[320px] dark:bg-neutral-700 dark:border-neutral-700">
195
+ <span className="text-black dark:text-white">
196
+ {field.value === 'code' ? 'Code' : 'Link'}
197
+ </span>
198
+ </SelectTrigger>
199
+ <SelectContent>
200
+ <SelectItem value="code">Code</SelectItem>
201
+ <SelectItem value="link">Link</SelectItem>
202
+ </SelectContent>
203
+ </Select>
204
+ )}
205
+ />
206
+ </div>
207
+ )}
208
+ </div>
209
+ </div>
210
+ )}
211
+
212
+ {/* Password Requirements Section */}
213
+ <div className="space-y-6">
214
+ <div>
215
+ <h3 className="text-lg font-medium text-gray-900 dark:text-white mb-3">
216
+ Password Requirements
217
+ </h3>
218
+ </div>
219
+
220
+ <div className="bg-white dark:bg-[#333333] rounded-lg p-6 space-y-6">
221
+ {/* Password Length */}
222
+ <div className="flex items-center gap-10">
223
+ <div className="w-100 flex flex-col gap-1">
224
+ <label className="text-sm font-medium text-gray-900 dark:text-white">
225
+ Minimum Password Length
226
+ </label>
227
+ <span className="text-xs text-zinc-500 dark:text-neutral-400">
228
+ Must be between 4 and 128 characters
229
+ </span>
230
+ </div>
231
+ <div className="w-full max-w-[320px]">
232
+ <Input
233
+ type="number"
234
+ min="4"
235
+ max="128"
236
+ {...form.register('passwordMinLength', { valueAsNumber: true })}
237
+ className={`bg-white dark:bg-neutral-900 dark:placeholder:text-neutral-400 dark:border-neutral-700 dark:text-white ${
238
+ form.formState.errors.passwordMinLength
239
+ ? 'border-red-500 dark:border-red-500'
240
+ : ''
241
+ }`}
242
+ />
243
+ {form.formState.errors.passwordMinLength && (
244
+ <span className="text-xs text-red-500">
245
+ {form.formState.errors.passwordMinLength.message ||
246
+ 'Must be between 4 and 128 characters'}
247
+ </span>
248
+ )}
249
+ </div>
250
+ </div>
251
+
252
+ {/* Password Strength Checkboxes */}
253
+ <div className="flex items-start gap-10">
254
+ <div className="w-100 flex flex-col gap-1 justify-center">
255
+ <label className="text-sm font-medium text-gray-900 dark:text-white">
256
+ Password Strength Requirements
257
+ </label>
258
+ </div>
259
+ <div className="w-full max-w-[320px] flex flex-col gap-3 justify-center">
260
+ <Controller
261
+ name="requireNumber"
262
+ control={form.control}
263
+ render={({ field }) => (
264
+ <label className="flex items-center gap-2 cursor-pointer">
265
+ <Checkbox
266
+ checked={field.value ?? false}
267
+ onChange={(checked) => field.onChange(checked)}
268
+ />
269
+ <span className="text-sm text-gray-700 dark:text-white">
270
+ At least 1 number
271
+ </span>
272
+ </label>
273
+ )}
274
+ />
275
+
276
+ <Controller
277
+ name="requireSpecialChar"
278
+ control={form.control}
279
+ render={({ field }) => (
280
+ <label className="flex items-center gap-2 cursor-pointer">
281
+ <Checkbox
282
+ checked={field.value ?? false}
283
+ onChange={(checked) => field.onChange(checked)}
284
+ />
285
+ <span className="text-sm text-gray-700 dark:text-white">
286
+ At least 1 special character
287
+ </span>
288
+ </label>
289
+ )}
290
+ />
291
+
292
+ <Controller
293
+ name="requireLowercase"
294
+ control={form.control}
295
+ render={({ field }) => (
296
+ <label className="flex items-center gap-2 cursor-pointer">
297
+ <Checkbox
298
+ checked={field.value ?? false}
299
+ onChange={(checked) => field.onChange(checked)}
300
+ />
301
+ <span className="text-sm text-gray-700 dark:text-white">
302
+ At least 1 lowercase character
303
+ </span>
304
+ </label>
305
+ )}
306
+ />
307
+
308
+ <Controller
309
+ name="requireUppercase"
310
+ control={form.control}
311
+ render={({ field }) => (
312
+ <label className="flex items-center gap-2 cursor-pointer">
313
+ <Checkbox
314
+ checked={field.value ?? false}
315
+ onChange={(checked) => field.onChange(checked)}
316
+ />
317
+ <span className="text-sm text-gray-700 dark:text-white">
318
+ At least 1 uppercase character
319
+ </span>
320
+ </label>
321
+ )}
322
+ />
323
+ </div>
324
+ </div>
325
+
326
+ {/* Reset Password Method */}
327
+ {isInsForgeCloudProject() && (
328
+ <div className="flex items-center gap-10">
329
+ <div className="w-100 flex flex-col gap-1">
330
+ <label className="text-sm font-medium text-gray-900 dark:text-white">
331
+ Password Reset Method
332
+ </label>
333
+ <span className="text-xs text-zinc-500 dark:text-neutral-400">
334
+ Choose between 6-digit reset code or reset link
335
+ </span>
336
+ </div>
337
+ <Controller
338
+ name="resetPasswordMethod"
339
+ control={form.control}
340
+ render={({ field }) => (
341
+ <Select
342
+ value={field.value}
343
+ onValueChange={(value) => {
344
+ if (value) {
345
+ field.onChange(value);
346
+ }
347
+ }}
348
+ >
349
+ <SelectTrigger className="w-full max-w-[320px] dark:bg-neutral-700 dark:border-neutral-700">
350
+ <span className="text-black dark:text-white">
351
+ {field.value === 'code' ? 'Code' : 'Link'}
352
+ </span>
353
+ </SelectTrigger>
354
+ <SelectContent>
355
+ <SelectItem value="code">Code</SelectItem>
356
+ <SelectItem value="link">Link</SelectItem>
357
+ </SelectContent>
358
+ </Select>
359
+ )}
360
+ />
361
+ </div>
362
+ )}
363
+ </div>
364
+ </div>
365
+
366
+ {/* Action Buttons - Reserve space even when hidden */}
367
+ <div className="flex justify-end gap-3 min-h-10">
368
+ {form.formState.isDirty && (
369
+ <>
370
+ <Button
371
+ type="button"
372
+ onClick={handleReset}
373
+ disabled={isUpdating}
374
+ className="h-10 px-6 bg-white border border-zinc-200 shadow-[0px_1px_2px_0px_rgba(0,0,0,0.1)] text-zinc-950 hover:bg-zinc-50 dark:bg-neutral-600 dark:border-neutral-600 dark:text-white dark:hover:bg-neutral-700"
375
+ >
376
+ Cancel
377
+ </Button>
378
+ <Button
379
+ type="button"
380
+ onClick={handleSubmit}
381
+ disabled={isUpdating}
382
+ className="h-10 px-6 dark:bg-emerald-300 dark:text-black dark:hover:bg-emerald-400"
383
+ >
384
+ {isUpdating ? 'Saving...' : 'Save Changes'}
385
+ </Button>
386
+ </>
387
+ )}
388
+ </div>
389
+ </form>
390
+ </div>
391
+ </div>
392
+ </div>
393
+ </div>
394
+ );
395
+ }