insforge 0.3.3 → 1.3.0

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 (635) hide show
  1. package/.claude-plugin/marketplace.json +20 -0
  2. package/.dockerignore +60 -57
  3. package/.env.example +84 -49
  4. package/.github/ISSUE_TEMPLATE/bug_report.yml +36 -83
  5. package/.github/ISSUE_TEMPLATE/config.yml +11 -11
  6. package/.github/ISSUE_TEMPLATE/feature_request.yml +26 -79
  7. package/.github/PULL_REQUEST_TEMPLATE.md +7 -0
  8. package/.github/copilot-instructions.md +146 -146
  9. package/.github/workflows/build-image.yml +66 -65
  10. package/.github/workflows/ci-premerge-check.yml +23 -23
  11. package/.github/workflows/e2e.yml +63 -0
  12. package/.github/workflows/lint-and-format.yml +32 -32
  13. package/.prettierignore +64 -64
  14. package/CHANGELOG.md +44 -3
  15. package/CLAUDE_PLUGIN.md +104 -0
  16. package/CODE_OF_CONDUCT.md +128 -0
  17. package/CONTRIBUTING.md +125 -125
  18. package/Dockerfile +30 -27
  19. package/GITHUB_OAUTH_SETUP.md +49 -49
  20. package/GOOGLE_OAUTH_SETUP.md +148 -148
  21. package/LICENSE +201 -201
  22. package/README.md +182 -134
  23. package/assets/Dark.svg +23 -23
  24. package/assets/mcpInstallv2.png +0 -0
  25. package/assets/sampleResponse.png +0 -0
  26. package/auth/index.html +13 -0
  27. package/auth/package.json +28 -0
  28. package/auth/public/favicon.ico +0 -0
  29. package/auth/src/App.tsx +33 -0
  30. package/auth/src/components/ErrorCard.tsx +37 -0
  31. package/auth/src/components/Layout.tsx +13 -0
  32. package/auth/src/index.css +19 -0
  33. package/auth/src/lib/broadcastService.ts +117 -0
  34. package/auth/src/lib/utils.ts +11 -0
  35. package/auth/src/main.tsx +22 -0
  36. package/auth/src/pages/ForgotPasswordPage.tsx +11 -0
  37. package/auth/src/pages/ResetPasswordPage.tsx +11 -0
  38. package/auth/src/pages/SignInPage.tsx +60 -0
  39. package/auth/src/pages/SignUpPage.tsx +60 -0
  40. package/auth/src/pages/VerifyEmailPage.tsx +20 -0
  41. package/auth/src/vite-env.d.ts +10 -0
  42. package/auth/tsconfig.json +32 -0
  43. package/auth/tsconfig.node.json +11 -0
  44. package/auth/vite.config.ts +25 -0
  45. package/backend/package.json +78 -75
  46. package/backend/src/api/{middleware → middlewares}/auth.ts +8 -9
  47. package/backend/src/api/middlewares/rate-limiters.ts +127 -0
  48. package/backend/src/api/routes/{ai.ts → ai/index.routes.ts} +22 -26
  49. package/backend/src/api/routes/auth/index.routes.ts +667 -0
  50. package/backend/src/api/routes/auth/oauth.routes.ts +473 -0
  51. package/backend/src/api/routes/{database.advance.ts → database/advance.routes.ts} +128 -65
  52. package/backend/src/api/routes/database/index.routes.ts +90 -0
  53. package/backend/src/api/routes/{database.records.ts → database/records.routes.ts} +26 -12
  54. package/backend/src/api/routes/{database.tables.ts → database/tables.routes.ts} +6 -23
  55. package/backend/src/api/routes/docs/index.routes.ts +75 -0
  56. package/backend/src/api/routes/email/index.routes.ts +35 -0
  57. package/backend/src/api/routes/functions/index.routes.ts +194 -0
  58. package/backend/src/api/routes/{logs.ts → logs/index.routes.ts} +25 -30
  59. package/backend/src/api/routes/{metadata.ts → metadata/index.routes.ts} +33 -31
  60. package/backend/src/api/routes/realtime/channels.routes.ts +81 -0
  61. package/backend/src/api/routes/realtime/index.routes.ts +12 -0
  62. package/backend/src/api/routes/realtime/messages.routes.ts +48 -0
  63. package/backend/src/api/routes/realtime/permissions.routes.ts +19 -0
  64. package/backend/src/api/routes/{secrets.ts → secrets/index.routes.ts} +27 -22
  65. package/backend/src/api/routes/{storage.ts → storage/index.routes.ts} +48 -61
  66. package/backend/src/api/routes/usage/index.routes.ts +91 -0
  67. package/backend/src/infra/config/app.config.ts +51 -0
  68. package/backend/src/infra/database/database.manager.ts +182 -0
  69. package/backend/{migrations → src/infra/database/migrations}/000_create-base-tables.sql +141 -141
  70. package/backend/{migrations → src/infra/database/migrations}/001_create-helper-functions.sql +40 -40
  71. package/backend/{migrations → src/infra/database/migrations}/002_rename-auth-tables.sql +29 -29
  72. package/backend/{migrations → src/infra/database/migrations}/003_create-users-table.sql +55 -55
  73. package/backend/{migrations → src/infra/database/migrations}/004_add-reload-postgrest-func.sql +23 -23
  74. package/backend/{migrations → src/infra/database/migrations}/005_enable-project-admin-modify-users.sql +29 -29
  75. package/backend/{migrations → src/infra/database/migrations}/006_modify-ai-usage-table.sql +24 -24
  76. package/backend/{migrations → src/infra/database/migrations}/007_drop-metadata-table.sql +1 -1
  77. package/backend/{migrations → src/infra/database/migrations}/008_add-system-tables.sql +76 -76
  78. package/backend/{migrations → src/infra/database/migrations}/009_add-function-secrets.sql +23 -23
  79. package/backend/{migrations → src/infra/database/migrations}/010_modify-ai-config-modalities.sql +93 -93
  80. package/backend/{migrations → src/infra/database/migrations}/011_refactor-secrets-table.sql +15 -15
  81. package/backend/{migrations → src/infra/database/migrations}/012_add-storage-uploaded-by.sql +7 -7
  82. package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -0
  83. package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +8 -0
  84. package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +60 -0
  85. package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -0
  86. package/backend/src/infra/database/migrations/017_create-realtime-schema.sql +233 -0
  87. package/backend/src/infra/realtime/realtime.manager.ts +246 -0
  88. package/backend/src/infra/realtime/webhook-sender.ts +82 -0
  89. package/backend/src/{core/secrets/encryption.ts → infra/security/encryption.manager.ts} +3 -2
  90. package/backend/src/infra/security/token.manager.ts +219 -0
  91. package/backend/src/infra/socket/socket.manager.ts +522 -0
  92. package/backend/src/providers/ai/openrouter.provider.ts +380 -0
  93. package/backend/src/providers/email/base.provider.ts +38 -0
  94. package/backend/src/providers/email/cloud.provider.ts +271 -0
  95. package/backend/src/{core/logs/providers → providers/logs}/base.provider.ts +11 -11
  96. package/backend/src/{core/logs/providers → providers/logs}/cloudwatch.provider.ts +61 -38
  97. package/backend/src/providers/logs/local.provider.ts +185 -0
  98. package/backend/src/providers/oauth/apple.provider.ts +266 -0
  99. package/backend/src/providers/oauth/base.provider.ts +29 -0
  100. package/backend/src/providers/oauth/discord.provider.ts +195 -0
  101. package/backend/src/providers/oauth/facebook.provider.ts +194 -0
  102. package/backend/src/providers/oauth/github.provider.ts +208 -0
  103. package/backend/src/providers/oauth/google.provider.ts +249 -0
  104. package/backend/src/providers/oauth/index.ts +8 -0
  105. package/backend/src/providers/oauth/linkedin.provider.ts +240 -0
  106. package/backend/src/providers/oauth/microsoft.provider.ts +169 -0
  107. package/backend/src/providers/oauth/x.provider.ts +202 -0
  108. package/backend/src/providers/storage/base.provider.ts +29 -0
  109. package/backend/src/providers/storage/local.provider.ts +103 -0
  110. package/backend/src/providers/storage/s3.provider.ts +313 -0
  111. package/backend/src/server.ts +317 -288
  112. package/backend/src/{core/ai/config.ts → services/ai/ai-config.service.ts} +19 -24
  113. package/backend/src/services/ai/ai-model.service.ts +60 -0
  114. package/backend/src/{core/ai/usage.ts → services/ai/ai-usage.service.ts} +28 -35
  115. package/backend/src/{core/ai/chat.ts → services/ai/chat-completion.service.ts} +37 -24
  116. package/backend/src/services/ai/helpers.ts +64 -0
  117. package/backend/src/{core/ai/image.ts → services/ai/image-generation.service.ts} +17 -19
  118. package/backend/src/services/ai/index.ts +13 -0
  119. package/backend/src/services/auth/auth-config.service.ts +250 -0
  120. package/backend/src/services/auth/auth-otp.service.ts +424 -0
  121. package/backend/src/services/auth/auth.service.ts +1150 -0
  122. package/backend/src/services/auth/index.ts +4 -0
  123. package/backend/src/{core/auth/oauth.ts → services/auth/oauth-config.service.ts} +106 -52
  124. package/backend/src/{core/database/advance.ts → services/database/database-advance.service.ts} +97 -131
  125. package/backend/src/services/database/database-table.service.ts +802 -0
  126. package/backend/src/services/database/database.service.ts +127 -0
  127. package/backend/src/services/email/email.service.ts +73 -0
  128. package/backend/src/{core/functions/functions.ts → services/functions/function.service.ts} +95 -88
  129. package/backend/src/{core/logs/audit.ts → services/logs/audit.service.ts} +92 -75
  130. package/backend/src/services/logs/log.service.ts +73 -0
  131. package/backend/src/services/realtime/index.ts +3 -0
  132. package/backend/src/services/realtime/realtime-auth.service.ts +104 -0
  133. package/backend/src/services/realtime/realtime-channel.service.ts +237 -0
  134. package/backend/src/services/realtime/realtime-message.service.ts +260 -0
  135. package/backend/src/{core/secrets/secrets.ts → services/secrets/secret.service.ts} +48 -66
  136. package/backend/src/services/storage/storage.service.ts +617 -0
  137. package/backend/src/services/usage/usage.service.ts +149 -0
  138. package/backend/src/types/auth.ts +77 -2
  139. package/backend/src/types/email.ts +8 -0
  140. package/backend/src/types/error-constants.ts +4 -0
  141. package/backend/src/types/logs.ts +0 -29
  142. package/backend/src/types/realtime.ts +18 -0
  143. package/backend/src/{core/socket/types.ts → types/socket.ts} +11 -36
  144. package/backend/src/utils/cookies.ts +35 -0
  145. package/backend/src/utils/environment.ts +9 -3
  146. package/backend/src/utils/logger.ts +20 -2
  147. package/backend/src/utils/s3-config-loader.ts +64 -0
  148. package/backend/src/utils/seed.ts +301 -205
  149. package/backend/src/utils/sql-parser.ts +91 -1
  150. package/backend/src/utils/utils.ts +114 -0
  151. package/backend/src/utils/validations.ts +40 -4
  152. package/backend/tests/README.md +133 -133
  153. package/backend/tests/cleanup-all-test-data.sh +230 -230
  154. package/backend/tests/cloud/test-s3-multitenant.sh +131 -131
  155. package/backend/tests/local/comprehensive-curl-tests.sh +155 -155
  156. package/backend/tests/local/test-ai-config.sh +129 -0
  157. package/backend/tests/local/test-ai-usage.sh +80 -0
  158. package/backend/tests/local/test-auth-router.sh +143 -143
  159. package/backend/tests/local/test-database-router.sh +222 -222
  160. package/backend/tests/local/test-e2e.sh +240 -240
  161. package/backend/tests/local/test-fk-errors.sh +96 -96
  162. package/backend/tests/local/test-functions.sh +123 -0
  163. package/backend/tests/local/test-id-field.sh +200 -200
  164. package/backend/tests/local/test-logs.sh +132 -0
  165. package/backend/tests/local/test-public-bucket.sh +264 -264
  166. package/backend/tests/local/test-secrets.sh +249 -247
  167. package/backend/tests/local/test-serverless-functions.sh.disabled +325 -325
  168. package/backend/tests/local/test-traditional-rest.sh +208 -208
  169. package/backend/tests/manual/README.md +50 -50
  170. package/backend/tests/manual/create-large-table-simple.sql +10 -10
  171. package/backend/tests/manual/seed-large-table.sql +100 -100
  172. package/backend/tests/manual/setup-large-table-extras.sql +33 -33
  173. package/backend/tests/manual/test-bulk-upsert.sh +409 -409
  174. package/backend/tests/manual/test-database-advance.sh +296 -296
  175. package/backend/tests/manual/test-postgrest-stability.sh +191 -191
  176. package/backend/tests/manual/test-rawsql-export-import.sh +411 -411
  177. package/backend/tests/manual/test-rawsql-modes.sh +244 -0
  178. package/backend/tests/manual/test-universal-storage.sh +263 -263
  179. package/backend/tests/manual/test-users.sql +17 -17
  180. package/backend/tests/run-all-tests.sh +139 -139
  181. package/backend/tests/setup.ts +0 -0
  182. package/backend/tests/test-config.sh +338 -302
  183. package/backend/tests/unit/analyze-query.test.ts +697 -0
  184. package/backend/tests/unit/cloud-token.test.ts +48 -0
  185. package/backend/tests/unit/constant.test.ts +8 -0
  186. package/backend/tests/unit/email.test.ts +372 -0
  187. package/backend/tests/unit/environment.test.ts +59 -0
  188. package/backend/tests/unit/helpers.test.ts +63 -0
  189. package/backend/tests/unit/logger.test.ts +22 -0
  190. package/backend/tests/unit/rate-limit.test.ts +154 -0
  191. package/backend/tests/unit/response.test.ts +58 -0
  192. package/backend/tests/unit/sql-parser.test.ts +74 -0
  193. package/backend/tests/unit/uuid.test.ts +21 -0
  194. package/backend/tests/unit/validations.test.ts +80 -0
  195. package/backend/tsconfig.json +22 -22
  196. package/backend/vitest.config.ts +11 -0
  197. package/claude-plugin/.claude-plugin/plugin.json +24 -0
  198. package/claude-plugin/README.md +133 -0
  199. package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +270 -0
  200. package/docker-compose.prod.yml +204 -144
  201. package/docker-compose.yml +232 -167
  202. package/docker-init/db/db-init.sql +97 -125
  203. package/docker-init/db/jwt.sql +5 -5
  204. package/docker-init/db/postgresql.conf +16 -16
  205. package/docker-init/logs/vector.yml +236 -0
  206. package/docs/README.md +44 -0
  207. package/docs/agent-docs/real-time.md +269 -0
  208. package/docs/changelog.mdx +119 -0
  209. package/docs/core-concepts/ai/architecture.mdx +373 -0
  210. package/docs/core-concepts/ai/sdk.mdx +213 -0
  211. package/docs/core-concepts/authentication/architecture.mdx +278 -0
  212. package/docs/core-concepts/authentication/sdk.mdx +414 -0
  213. package/docs/core-concepts/authentication/ui-components/customization.mdx +529 -0
  214. package/docs/core-concepts/authentication/ui-components/nextjs.mdx +221 -0
  215. package/docs/core-concepts/authentication/ui-components/react-router.mdx +184 -0
  216. package/docs/core-concepts/authentication/ui-components/react.mdx +129 -0
  217. package/docs/core-concepts/database/architecture.mdx +256 -0
  218. package/docs/core-concepts/database/sdk.mdx +382 -0
  219. package/docs/core-concepts/email/architecture.mdx +101 -0
  220. package/docs/core-concepts/email/sdk.mdx +53 -0
  221. package/docs/core-concepts/functions/architecture.mdx +105 -0
  222. package/docs/core-concepts/functions/sdk.mdx +184 -0
  223. package/docs/core-concepts/realtime/architecture.mdx +446 -0
  224. package/docs/core-concepts/realtime/sdk.mdx +409 -0
  225. package/docs/core-concepts/storage/architecture.mdx +243 -0
  226. package/docs/core-concepts/storage/sdk.mdx +253 -0
  227. package/docs/deployment/README.md +94 -0
  228. package/docs/deployment/deploy-to-aws-ec2.md +565 -0
  229. package/docs/deployment/deploy-to-azure-virtual-machines.md +313 -0
  230. package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -0
  231. package/docs/deployment/deploy-to-render.md +441 -0
  232. package/docs/deprecated/insforge-auth-api.md +214 -214
  233. package/docs/deprecated/insforge-auth-sdk.md +99 -99
  234. package/docs/deprecated/insforge-db-api.md +358 -358
  235. package/docs/deprecated/insforge-db-sdk.md +139 -139
  236. package/docs/deprecated/insforge-debug-sdk.md +156 -156
  237. package/docs/deprecated/insforge-debug.md +64 -64
  238. package/docs/deprecated/insforge-instructions.md +123 -123
  239. package/docs/deprecated/insforge-project.md +117 -117
  240. package/docs/deprecated/insforge-storage-api.md +278 -278
  241. package/docs/deprecated/insforge-storage-sdk.md +158 -158
  242. package/docs/docs.json +232 -0
  243. package/docs/examples/framework-guides/nextjs.mdx +131 -0
  244. package/docs/examples/framework-guides/nuxt.mdx +165 -0
  245. package/docs/examples/framework-guides/react.mdx +165 -0
  246. package/docs/examples/framework-guides/svelte.mdx +153 -0
  247. package/docs/examples/framework-guides/vue.mdx +159 -0
  248. package/docs/examples/overview.mdx +67 -0
  249. package/docs/favicon.svg +19 -0
  250. package/docs/images/changelog/dec-2025/ai-integration.png +0 -0
  251. package/docs/images/changelog/dec-2025/ai-models.webp +0 -0
  252. package/docs/images/changelog/dec-2025/alipay-payment.webp +0 -0
  253. package/docs/images/changelog/dec-2025/apple-login.jpg +0 -0
  254. package/docs/images/changelog/dec-2025/mcp-installer.png +0 -0
  255. package/docs/images/changelog/dec-2025/realtime-module.jpg +0 -0
  256. package/docs/images/changelog/nov-2025/auth-components.webp +0 -0
  257. package/docs/images/changelog/nov-2025/database-metadata.webp +0 -0
  258. package/docs/images/changelog/nov-2025/quickstart-prompts.webp +0 -0
  259. package/docs/images/changelog/nov-2025/sql-editor.webp +0 -0
  260. package/docs/images/changelog/nov-2025/usage-page.webp +0 -0
  261. package/docs/images/changelog/october-2025/csv-upload.webp +0 -0
  262. package/docs/images/changelog/october-2025/logs-feature.webp +0 -0
  263. package/docs/images/changelog/october-2025/oauth-providers.webp +0 -0
  264. package/docs/images/checks-passed.png +0 -0
  265. package/docs/images/dashboard-connect-expanded.png +0 -0
  266. package/docs/images/dashboard-connect.png +0 -0
  267. package/docs/images/hero-dark.png +0 -0
  268. package/docs/images/hero-light.png +0 -0
  269. package/docs/images/icons/ai.svg +4 -0
  270. package/docs/images/icons/auth.svg +1 -0
  271. package/docs/images/icons/database.svg +1 -0
  272. package/docs/images/icons/function.svg +1 -0
  273. package/docs/images/icons/storage.svg +1 -0
  274. package/docs/images/logos/nextjs.svg +4 -0
  275. package/docs/images/logos/nuxt.svg +4 -0
  276. package/docs/images/logos/react.svg +5 -0
  277. package/docs/images/logos/svelte.svg +4 -0
  278. package/docs/images/logos/vue.svg +5 -0
  279. package/docs/images/mcp-install.png +0 -0
  280. package/docs/images/onboarding-mcp.png +0 -0
  281. package/docs/insforge-instructions-sdk.md +89 -407
  282. package/docs/introduction.mdx +45 -0
  283. package/docs/logo/dark.svg +22 -0
  284. package/docs/logo/light.svg +20 -0
  285. package/docs/partnership.mdx +652 -0
  286. package/docs/quickstart.mdx +83 -0
  287. package/docs/showcase/2048-arena.png +0 -0
  288. package/docs/showcase/framegen-cloud.png +0 -0
  289. package/docs/showcase/line-connect-race.png +0 -0
  290. package/docs/showcase/moment-vibe.png +0 -0
  291. package/docs/showcase/national-flags.png +0 -0
  292. package/docs/showcase/pokemon-vibe.png +0 -0
  293. package/docs/showcase/pure-browse-buy.png +0 -0
  294. package/docs/showcase.mdx +52 -0
  295. package/docs/snippets/sdk-installation.mdx +22 -0
  296. package/docs/snippets/service-icons.mdx +27 -0
  297. package/eslint.config.js +10 -3
  298. package/examples/oauth/frontend-oauth-example.html +250 -250
  299. package/examples/response-examples.md +443 -443
  300. package/frontend/components.json +17 -17
  301. package/frontend/package.json +69 -63
  302. package/frontend/src/App.tsx +13 -82
  303. package/frontend/src/assets/icons/checkbox_checked.svg +6 -6
  304. package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -6
  305. package/frontend/src/assets/icons/checked.svg +3 -3
  306. package/frontend/src/assets/icons/connected.svg +3 -0
  307. package/frontend/src/assets/icons/error.svg +3 -3
  308. package/frontend/src/assets/icons/loader.svg +9 -0
  309. package/frontend/src/assets/icons/pencil.svg +4 -4
  310. package/frontend/src/assets/icons/refresh.svg +4 -4
  311. package/frontend/src/assets/icons/step_active.svg +3 -3
  312. package/frontend/src/assets/icons/step_inactive.svg +11 -11
  313. package/frontend/src/assets/icons/warning.svg +3 -3
  314. package/frontend/src/assets/logos/apple.svg +4 -0
  315. package/frontend/src/assets/logos/claude_code.svg +3 -3
  316. package/frontend/src/assets/logos/cline.svg +6 -6
  317. package/frontend/src/assets/logos/cursor.svg +20 -20
  318. package/frontend/src/assets/logos/discord.svg +8 -8
  319. package/frontend/src/assets/logos/facebook.svg +3 -0
  320. package/frontend/src/assets/logos/gemini.svg +19 -19
  321. package/frontend/src/assets/logos/github.svg +5 -5
  322. package/frontend/src/assets/logos/google.svg +13 -13
  323. package/frontend/src/assets/logos/grok.svg +10 -10
  324. package/frontend/src/assets/logos/insforge_dark.svg +15 -15
  325. package/frontend/src/assets/logos/insforge_light.svg +15 -15
  326. package/frontend/src/assets/logos/instagram.svg +2 -0
  327. package/frontend/src/assets/logos/linkedin.svg +3 -0
  328. package/frontend/src/assets/logos/microsoft.svg +1 -0
  329. package/frontend/src/assets/logos/openai.svg +10 -10
  330. package/frontend/src/assets/logos/roo_code.svg +9 -9
  331. package/frontend/src/assets/logos/spotify.svg +17 -0
  332. package/frontend/src/assets/logos/tiktok.svg +6 -0
  333. package/frontend/src/assets/logos/trae.svg +3 -3
  334. package/frontend/src/assets/logos/windsurf.svg +10 -10
  335. package/frontend/src/assets/logos/x.svg +3 -0
  336. package/frontend/src/components/Checkbox.tsx +27 -29
  337. package/frontend/src/components/CodeBlock.tsx +55 -2
  338. package/frontend/src/components/CodeEditor.tsx +92 -0
  339. package/frontend/src/components/ConfirmDialog.tsx +1 -1
  340. package/frontend/src/components/ConnectCTA.tsx +38 -0
  341. package/frontend/src/components/CopyButton.tsx +52 -15
  342. package/frontend/src/components/ErrorState.tsx +1 -2
  343. package/frontend/src/components/FeatureSidebar.tsx +6 -6
  344. package/frontend/src/components/FeatureSidebarItem.tsx +2 -2
  345. package/frontend/src/components/JsonHighlight.tsx +21 -9
  346. package/frontend/src/components/ProjectInfoModal.tsx +128 -0
  347. package/frontend/src/components/PromptDialog.tsx +1 -4
  348. package/frontend/src/components/SearchInput.tsx +1 -2
  349. package/frontend/src/components/Stepper.tsx +53 -0
  350. package/frontend/src/components/ThemeToggle.tsx +3 -3
  351. package/frontend/src/components/datagrid/DataGrid.tsx +25 -32
  352. package/frontend/src/components/datagrid/cell-editors/DateCellEditor.tsx +1 -2
  353. package/frontend/src/components/datagrid/cell-editors/JsonCellEditor.tsx +2 -4
  354. package/frontend/src/components/datagrid/index.ts +23 -0
  355. package/frontend/src/components/index.ts +23 -30
  356. package/frontend/src/components/layout/AppHeader.tsx +131 -91
  357. package/frontend/src/components/layout/AppSidebar.tsx +80 -170
  358. package/frontend/src/components/layout/Layout.tsx +12 -23
  359. package/frontend/src/components/layout/PrimaryMenu.tsx +187 -0
  360. package/frontend/src/components/layout/SecondaryMenu.tsx +70 -0
  361. package/frontend/src/components/layout/index.ts +5 -0
  362. package/frontend/src/components/radix/Tooltip.tsx +24 -13
  363. package/frontend/src/components/radix/index.ts +22 -0
  364. package/frontend/src/features/ai/components/AIConfigCard.tsx +129 -83
  365. package/frontend/src/features/ai/components/AIEmptyState.tsx +12 -7
  366. package/frontend/src/features/ai/components/ModalityFilterSidebar.tsx +101 -0
  367. package/frontend/src/features/ai/components/ModelSelectionDialog.tsx +135 -0
  368. package/frontend/src/features/ai/components/ModelSelectionGrid.tsx +51 -0
  369. package/frontend/src/features/ai/components/SystemPromptDialog.tsx +118 -0
  370. package/frontend/src/features/ai/components/index.ts +6 -0
  371. package/frontend/src/features/ai/helpers.ts +57 -71
  372. package/frontend/src/features/ai/hooks/useAIConfigs.ts +39 -113
  373. package/frontend/src/features/ai/hooks/useAIUsage.ts +0 -2
  374. package/frontend/src/features/ai/pages/AIPage.tsx +166 -0
  375. package/frontend/src/features/ai/services/ai.service.ts +5 -5
  376. package/frontend/src/features/auth/components/AuthPreview.tsx +96 -0
  377. package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +54 -30
  378. package/frontend/src/features/auth/components/UserFormDialog.tsx +13 -6
  379. package/frontend/src/features/auth/components/UsersDataGrid.tsx +50 -14
  380. package/frontend/src/features/auth/components/index.ts +5 -0
  381. package/frontend/src/features/auth/helpers.tsx +208 -0
  382. package/frontend/src/features/auth/hooks/useAnonToken.ts +30 -0
  383. package/frontend/src/features/auth/hooks/useAuthConfig.ts +48 -0
  384. package/frontend/src/features/auth/hooks/useOAuthConfig.ts +14 -10
  385. package/frontend/src/features/auth/hooks/useUsers.ts +43 -5
  386. package/frontend/src/features/auth/index.ts +3 -2
  387. package/frontend/src/features/auth/pages/AuthMethodsPage.tsx +275 -0
  388. package/frontend/src/features/auth/pages/ConfigurationPage.tsx +395 -0
  389. package/frontend/src/features/auth/pages/UsersPage.tsx +257 -0
  390. package/frontend/src/features/auth/services/anonToken.service.ts +11 -0
  391. package/frontend/src/features/auth/services/config.service.ts +19 -0
  392. package/frontend/src/features/auth/services/{oauth.service.ts → oauth-config.service.ts} +4 -4
  393. package/frontend/src/features/auth/services/{auth.service.ts → user.service.ts} +7 -53
  394. package/frontend/src/features/dashboard/components/ConnectionSuccessBanner.tsx +35 -0
  395. package/frontend/src/features/dashboard/components/PromptCard.tsx +21 -0
  396. package/frontend/src/features/dashboard/components/PromptDialog.tsx +103 -0
  397. package/frontend/src/features/dashboard/components/StatsCard.tsx +50 -0
  398. package/frontend/src/features/dashboard/components/index.ts +4 -0
  399. package/frontend/src/features/dashboard/pages/DashboardPage.tsx +212 -0
  400. package/frontend/src/features/dashboard/prompts/ai-chatbot.ts +13 -0
  401. package/frontend/src/features/dashboard/prompts/crm-system.ts +13 -0
  402. package/frontend/src/features/dashboard/prompts/ecommerce-platform.ts +12 -0
  403. package/frontend/src/features/dashboard/prompts/index.ts +31 -0
  404. package/frontend/src/features/dashboard/prompts/instagram-clone.ts +11 -0
  405. package/frontend/src/features/dashboard/prompts/notion-clone.ts +14 -0
  406. package/frontend/src/features/dashboard/prompts/reddit-clone.ts +12 -0
  407. package/frontend/src/features/database/components/DatabaseDataGrid.tsx +48 -17
  408. package/frontend/src/features/database/components/ForeignKeyCell.tsx +15 -34
  409. package/frontend/src/features/database/components/ForeignKeyPopover.tsx +19 -20
  410. package/frontend/src/features/database/components/LinkRecordModal.tsx +120 -125
  411. package/frontend/src/features/database/components/RecordFormDialog.tsx +22 -33
  412. package/frontend/src/features/database/components/RecordFormField.tsx +45 -47
  413. package/frontend/src/features/database/components/SQLModal.tsx +75 -0
  414. package/frontend/src/features/database/components/TableEmptyState.tsx +6 -5
  415. package/frontend/src/features/database/components/TableForm.tsx +28 -19
  416. package/frontend/src/features/database/components/TableFormColumn.tsx +2 -3
  417. package/frontend/src/features/database/components/TableSidebar.tsx +1 -1
  418. package/frontend/src/features/database/components/TablesEmptyState.tsx +48 -0
  419. package/frontend/src/features/database/components/TemplateCard.tsx +37 -0
  420. package/frontend/src/features/database/components/TemplatePreview.tsx +92 -0
  421. package/frontend/src/features/database/components/index.ts +19 -0
  422. package/frontend/src/features/database/constants.ts +28 -2
  423. package/frontend/src/features/database/contexts/SQLEditorContext.tsx +188 -0
  424. package/frontend/src/features/database/helpers.ts +2 -2
  425. package/frontend/src/features/database/hooks/useCSVImport.ts +29 -0
  426. package/frontend/src/features/database/hooks/useDatabase.ts +66 -0
  427. package/frontend/src/features/database/hooks/useRawSQL.ts +55 -0
  428. package/frontend/src/features/database/hooks/useRecords.ts +139 -0
  429. package/frontend/src/features/database/hooks/useTables.ts +135 -0
  430. package/frontend/src/features/database/index.ts +7 -1
  431. package/frontend/src/features/database/pages/FunctionsPage.tsx +203 -0
  432. package/frontend/src/features/database/pages/IndexesPage.tsx +228 -0
  433. package/frontend/src/features/database/pages/PoliciesPage.tsx +237 -0
  434. package/frontend/src/features/database/pages/SQLEditorPage.tsx +382 -0
  435. package/frontend/src/features/database/{page/DatabasePage.tsx → pages/TablesPage.tsx} +168 -209
  436. package/frontend/src/features/database/pages/TemplatesPage.tsx +39 -0
  437. package/frontend/src/features/database/pages/TriggersPage.tsx +230 -0
  438. package/frontend/src/features/database/services/advance.service.ts +40 -0
  439. package/frontend/src/features/database/services/database.service.ts +33 -194
  440. package/frontend/src/features/database/services/record.service.ts +219 -0
  441. package/frontend/src/features/database/services/table.service.ts +58 -0
  442. package/frontend/src/features/database/templates/ai-chatbot.ts +402 -0
  443. package/frontend/src/features/database/templates/crm-system.ts +528 -0
  444. package/frontend/src/features/database/templates/ecommerce-platform.ts +553 -0
  445. package/frontend/src/features/database/templates/index.ts +34 -0
  446. package/frontend/src/features/database/templates/instagram-clone.ts +222 -0
  447. package/frontend/src/features/database/templates/notion-clone.ts +483 -0
  448. package/frontend/src/features/database/templates/reddit-clone.ts +526 -0
  449. package/frontend/src/features/functions/components/FunctionRow.tsx +2 -1
  450. package/frontend/src/features/functions/components/FunctionsSidebar.tsx +1 -1
  451. package/frontend/src/features/functions/components/SecretRow.tsx +1 -1
  452. package/frontend/src/features/functions/components/index.ts +5 -0
  453. package/frontend/src/features/functions/hooks/useFunctions.ts +4 -4
  454. package/frontend/src/features/{secrets → functions}/hooks/useSecrets.ts +5 -5
  455. package/frontend/src/features/functions/pages/FunctionsPage.tsx +148 -0
  456. package/frontend/src/features/functions/{components/SecretsContent.tsx → pages/SecretsPage.tsx} +19 -21
  457. package/frontend/src/features/functions/services/{functions.service.ts → function.service.ts} +2 -2
  458. package/frontend/src/features/{secrets/services/secrets.service.ts → functions/services/secret.service.ts} +2 -2
  459. package/frontend/src/features/login/hooks/usePartnerOrigin.ts +27 -0
  460. package/frontend/src/features/login/pages/CloudLoginPage.tsx +118 -0
  461. package/frontend/src/features/login/{page → pages}/LoginPage.tsx +16 -23
  462. package/frontend/src/features/login/services/partnership.service.ts +65 -0
  463. package/frontend/src/features/logs/components/LogsDataGrid.tsx +89 -0
  464. package/frontend/src/features/logs/components/SeverityBadge.tsx +18 -0
  465. package/frontend/src/features/logs/components/index.ts +2 -0
  466. package/frontend/src/features/logs/helpers.ts +24 -0
  467. package/frontend/src/features/logs/hooks/useAuditLogs.ts +4 -4
  468. package/frontend/src/features/logs/hooks/useLogSources.ts +137 -0
  469. package/frontend/src/features/logs/hooks/useLogs.ts +163 -0
  470. package/frontend/src/features/logs/hooks/useMcpUsage.ts +128 -0
  471. package/frontend/src/features/logs/index.ts +8 -2
  472. package/frontend/src/features/logs/{page → pages}/AuditsPage.tsx +91 -38
  473. package/frontend/src/features/logs/pages/LogsPage.tsx +152 -0
  474. package/frontend/src/features/logs/pages/MCPLogsPage.tsx +84 -0
  475. package/frontend/src/features/logs/services/audit.service.ts +63 -0
  476. package/frontend/src/features/logs/services/log.service.ts +15 -110
  477. package/frontend/src/features/logs/services/usage.service.ts +31 -0
  478. package/frontend/src/features/onboard/components/McpConnectionStatus.tsx +68 -0
  479. package/frontend/src/features/onboard/components/OnboardingModal.tsx +267 -0
  480. package/frontend/src/features/onboard/components/VideoDemoModal.tsx +38 -0
  481. package/frontend/src/features/onboard/components/index.ts +4 -0
  482. package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +2 -2
  483. package/frontend/src/features/onboard/components/mcp/{mcp-helper.tsx → helpers.tsx} +8 -8
  484. package/frontend/src/features/onboard/components/mcp/index.ts +2 -3
  485. package/frontend/src/features/onboard/index.ts +13 -3
  486. package/frontend/src/features/realtime/components/ChannelRow.tsx +83 -0
  487. package/frontend/src/features/realtime/components/EditChannelModal.tsx +246 -0
  488. package/frontend/src/features/realtime/components/MessageRow.tsx +85 -0
  489. package/frontend/src/features/realtime/components/RealtimeEmptyState.tsx +30 -0
  490. package/frontend/src/features/realtime/hooks/useRealtime.ts +218 -0
  491. package/frontend/src/features/realtime/index.ts +11 -0
  492. package/frontend/src/features/realtime/pages/RealtimeChannelsPage.tsx +172 -0
  493. package/frontend/src/features/realtime/pages/RealtimeMessagesPage.tsx +211 -0
  494. package/frontend/src/features/realtime/pages/RealtimePermissionsPage.tsx +191 -0
  495. package/frontend/src/features/realtime/services/realtime.service.ts +107 -0
  496. package/frontend/src/features/storage/components/BucketEmptyState.tsx +9 -6
  497. package/frontend/src/features/storage/components/BucketFormDialog.tsx +25 -41
  498. package/frontend/src/features/storage/components/FilePreviewDialog.tsx +20 -8
  499. package/frontend/src/features/storage/components/StorageDataGrid.tsx +4 -3
  500. package/frontend/src/features/storage/components/StorageManager.tsx +23 -34
  501. package/frontend/src/features/storage/components/index.ts +12 -0
  502. package/frontend/src/features/storage/hooks/useStorage.ts +208 -0
  503. package/frontend/src/features/storage/{page → pages}/StoragePage.tsx +41 -143
  504. package/frontend/src/features/storage/services/storage.service.ts +22 -1
  505. package/frontend/src/features/visualizer/components/AuthNode.tsx +72 -56
  506. package/frontend/src/features/visualizer/components/BucketNode.tsx +4 -4
  507. package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +108 -80
  508. package/frontend/src/features/visualizer/components/TableNode.tsx +34 -41
  509. package/frontend/src/features/visualizer/components/VisualizerSkeleton.tsx +12 -4
  510. package/frontend/src/features/visualizer/pages/VisualizerPage.tsx +97 -0
  511. package/frontend/src/index.css +1 -0
  512. package/frontend/src/lib/analytics/posthog.tsx +27 -0
  513. package/frontend/src/lib/contexts/AuthContext.tsx +38 -31
  514. package/frontend/src/lib/contexts/SocketContext.tsx +123 -80
  515. package/frontend/src/{features/metadata → lib}/hooks/useMetadata.ts +1 -1
  516. package/frontend/src/lib/hooks/useToast.tsx +6 -2
  517. package/frontend/src/lib/routing/AppRoutes.tsx +99 -0
  518. package/frontend/src/lib/routing/RequireAuth.tsx +27 -0
  519. package/frontend/src/lib/utils/cloudMessaging.ts +20 -0
  520. package/frontend/src/lib/utils/menuItems.ts +207 -0
  521. package/frontend/src/lib/utils/{validation-schemas.ts → schemaValidations.ts} +10 -5
  522. package/frontend/src/lib/utils/utils.ts +32 -1
  523. package/frontend/src/vite-env.d.ts +1 -0
  524. package/frontend/tsconfig.json +25 -25
  525. package/frontend/tsconfig.node.json +9 -9
  526. package/frontend/vite.config.ts +5 -3
  527. package/functions/deno.json +24 -24
  528. package/functions/server.ts +315 -290
  529. package/functions/worker-template.js +15 -4
  530. package/i18n/README.ar.md +130 -0
  531. package/i18n/README.de.md +130 -0
  532. package/i18n/README.es.md +154 -0
  533. package/i18n/README.fr.md +134 -0
  534. package/i18n/README.hi.md +129 -0
  535. package/i18n/README.ja.md +174 -0
  536. package/i18n/README.ko.md +137 -0
  537. package/i18n/README.pt-BR.md +131 -0
  538. package/i18n/README.ru.md +129 -0
  539. package/i18n/README.zh-CN.md +133 -0
  540. package/openapi/ai.yaml +715 -688
  541. package/openapi/auth.yaml +1244 -563
  542. package/openapi/email.yaml +158 -0
  543. package/openapi/functions.yaml +475 -475
  544. package/openapi/health.yaml +29 -29
  545. package/openapi/logs.yaml +223 -223
  546. package/openapi/metadata.yaml +177 -177
  547. package/openapi/realtime.yaml +699 -0
  548. package/openapi/records.yaml +381 -381
  549. package/openapi/secrets.yaml +370 -370
  550. package/openapi/storage.yaml +875 -875
  551. package/openapi/tables.yaml +463 -463
  552. package/package.json +97 -88
  553. package/shared-schemas/package.json +31 -31
  554. package/shared-schemas/src/ai-api.schema.ts +34 -58
  555. package/shared-schemas/src/ai.schema.ts +63 -54
  556. package/shared-schemas/src/auth-api.schema.ts +352 -193
  557. package/shared-schemas/src/auth.schema.ts +43 -7
  558. package/shared-schemas/src/cloud-events.schema.ts +57 -0
  559. package/shared-schemas/src/database-api.schema.ts +35 -4
  560. package/shared-schemas/src/database.schema.ts +40 -1
  561. package/shared-schemas/src/docs.schema.ts +26 -0
  562. package/shared-schemas/src/email-api.schema.ts +30 -0
  563. package/shared-schemas/src/index.ts +5 -0
  564. package/shared-schemas/src/logs-api.schema.ts +7 -1
  565. package/shared-schemas/src/logs.schema.ts +26 -0
  566. package/shared-schemas/src/metadata.schema.ts +18 -4
  567. package/shared-schemas/src/realtime-api.schema.ts +111 -0
  568. package/shared-schemas/src/realtime.schema.ts +143 -0
  569. package/shared-schemas/tsconfig.json +21 -21
  570. package/tsconfig.json +7 -7
  571. package/zeabur/README.md +13 -0
  572. package/zeabur/template.yml +1032 -0
  573. package/.github/workflows/deploy-aws.yml +0 -130
  574. package/backend/src/api/routes/agent.ts +0 -29
  575. package/backend/src/api/routes/auth.oauth.ts +0 -482
  576. package/backend/src/api/routes/auth.ts +0 -386
  577. package/backend/src/api/routes/docs.ts +0 -66
  578. package/backend/src/api/routes/functions.ts +0 -183
  579. package/backend/src/api/routes/openapi.ts +0 -82
  580. package/backend/src/api/routes/usage.ts +0 -96
  581. package/backend/src/core/ai/client.ts +0 -242
  582. package/backend/src/core/ai/model.ts +0 -117
  583. package/backend/src/core/auth/auth.ts +0 -780
  584. package/backend/src/core/database/manager.ts +0 -178
  585. package/backend/src/core/database/table.ts +0 -772
  586. package/backend/src/core/documentation/agent.ts +0 -689
  587. package/backend/src/core/documentation/openapi.ts +0 -856
  588. package/backend/src/core/logs/analytics.ts +0 -76
  589. package/backend/src/core/logs/providers/localdb.provider.ts +0 -246
  590. package/backend/src/core/socket/socket.ts +0 -388
  591. package/backend/src/core/storage/storage.ts +0 -923
  592. package/backend/src/utils/cloud-token.ts +0 -39
  593. package/backend/src/utils/helpers.ts +0 -49
  594. package/backend/src/utils/uuid.ts +0 -9
  595. package/backend/tests/manual/test-better-auth.sh +0 -303
  596. package/docker-init/db/logs.sql +0 -9
  597. package/frontend/README.md +0 -112
  598. package/frontend/src/components/datagrid/index.tsx +0 -20
  599. package/frontend/src/components/layout/CloudLayout.tsx +0 -95
  600. package/frontend/src/features/ai/components/AIConfigDialog.tsx +0 -76
  601. package/frontend/src/features/ai/components/AIConfigForm.tsx +0 -222
  602. package/frontend/src/features/ai/components/fields/ModalityField.tsx +0 -87
  603. package/frontend/src/features/ai/components/fields/ModelSelectionField.tsx +0 -134
  604. package/frontend/src/features/ai/components/fields/SystemPromptField.tsx +0 -33
  605. package/frontend/src/features/ai/page/AIPage.tsx +0 -178
  606. package/frontend/src/features/auth/components/AddOAuthDialog.tsx +0 -106
  607. package/frontend/src/features/auth/components/AuthMethodTab.tsx +0 -238
  608. package/frontend/src/features/auth/components/UsersTab.tsx +0 -114
  609. package/frontend/src/features/auth/page/AuthenticationPage.tsx +0 -169
  610. package/frontend/src/features/dashboard/page/DashboardPage.tsx +0 -194
  611. package/frontend/src/features/database/hooks/UseLinkModal.tsx +0 -78
  612. package/frontend/src/features/functions/components/FunctionViewer.tsx +0 -46
  613. package/frontend/src/features/functions/components/FunctionsContent.tsx +0 -88
  614. package/frontend/src/features/functions/page/FunctionsPage.tsx +0 -28
  615. package/frontend/src/features/login/components/AuthErrorBoundary.tsx +0 -87
  616. package/frontend/src/features/login/components/PrivateRoute.tsx +0 -24
  617. package/frontend/src/features/login/page/CloudLoginPage.tsx +0 -93
  618. package/frontend/src/features/logs/components/AnalyticsLogsTable.tsx +0 -313
  619. package/frontend/src/features/logs/components/LogsTable.tsx +0 -199
  620. package/frontend/src/features/logs/page/AnalyticsLogsPage.tsx +0 -530
  621. package/frontend/src/features/metadata/index.ts +0 -0
  622. package/frontend/src/features/metadata/page/MetadataPage.tsx +0 -136
  623. package/frontend/src/features/onboard/components/CompletionCard.tsx +0 -41
  624. package/frontend/src/features/onboard/components/OnboardButton.tsx +0 -84
  625. package/frontend/src/features/onboard/components/StepContent.tsx +0 -91
  626. package/frontend/src/features/onboard/components/TestConnectionStep.tsx +0 -53
  627. package/frontend/src/features/onboard/components/mcp/McpInstallation.tsx +0 -144
  628. package/frontend/src/features/onboard/page/OnBoardPage.tsx +0 -104
  629. package/frontend/src/features/onboard/types.ts +0 -8
  630. package/frontend/src/features/visualizer/page/VisualizerPage.tsx +0 -127
  631. package/frontend/src/lib/contexts/OnboardStepContext.tsx +0 -68
  632. package/frontend/src/lib/hooks/useOnboardingCompletion.ts +0 -29
  633. /package/backend/src/api/{middleware → middlewares}/error.ts +0 -0
  634. /package/backend/src/api/{middleware → middlewares}/upload.ts +0 -0
  635. /package/frontend/src/{features/metadata → lib}/services/metadata.service.ts +0 -0
@@ -1,780 +0,0 @@
1
- import jwt from 'jsonwebtoken';
2
- import bcrypt from 'bcryptjs';
3
- import crypto from 'crypto';
4
- import axios from 'axios';
5
- import { OAuth2Client } from 'google-auth-library';
6
- import dotenv from 'dotenv';
7
- import { verifyCloudToken } from '@/utils/cloud-token.js';
8
- import path from 'path';
9
- import fs from 'fs';
10
- import { fileURLToPath } from 'url';
11
- import { DatabaseManager } from '@/core/database/manager.js';
12
- import logger from '@/utils/logger.js';
13
- import type {
14
- UserSchema,
15
- CreateUserResponse,
16
- CreateSessionResponse,
17
- CreateAdminSessionResponse,
18
- TokenPayloadSchema,
19
- AuthMetadataSchema,
20
- } from '@insforge/shared-schemas';
21
- import { OAuthConfigService } from './oauth';
22
- import { GitHubEmailInfo, GitHubUserInfo, GoogleUserInfo, UserRecord } from '@/types/auth';
23
- import { ADMIN_ID } from '@/utils/constants';
24
-
25
- const JWT_SECRET = () => process.env.JWT_SECRET ?? '';
26
- const JWT_EXPIRES_IN = '7d';
27
-
28
- /**
29
- * Simplified JWT-based auth service
30
- * Handles all authentication operations including OAuth
31
- */
32
- export class AuthService {
33
- private static instance: AuthService;
34
- private adminEmail: string;
35
- private adminPassword: string;
36
- private db;
37
- private processedCodes: Set<string>;
38
- private tokenCache: Map<string, { access_token: string; id_token: string }>;
39
-
40
- private constructor() {
41
- // Load .env file if not already loaded
42
- if (!process.env.JWT_SECRET) {
43
- const __filename = fileURLToPath(import.meta.url);
44
- const __dirname = path.dirname(__filename);
45
- const envPath = path.resolve(__dirname, '../../../../.env');
46
- if (fs.existsSync(envPath)) {
47
- dotenv.config({ path: envPath });
48
- } else {
49
- logger.warn('No .env file found, using default environment variables.');
50
- dotenv.config();
51
- }
52
- }
53
-
54
- if (!process.env.JWT_SECRET) {
55
- throw new Error('JWT_SECRET environment variable is required');
56
- }
57
-
58
- this.adminEmail = process.env.ADMIN_EMAIL ?? '';
59
- this.adminPassword = process.env.ADMIN_PASSWORD ?? '';
60
-
61
- if (!this.adminEmail || !this.adminPassword) {
62
- throw new Error('ADMIN_EMAIL and ADMIN_PASSWORD environment variables are required');
63
- }
64
-
65
- const dbManager = DatabaseManager.getInstance();
66
- this.db = dbManager.getDb();
67
-
68
- // Initialize OAuth helpers
69
- this.processedCodes = new Set();
70
- this.tokenCache = new Map();
71
-
72
- logger.info('AuthService initialized');
73
- }
74
-
75
- public static getInstance(): AuthService {
76
- if (!AuthService.instance) {
77
- AuthService.instance = new AuthService();
78
- }
79
- return AuthService.instance;
80
- }
81
-
82
- /**
83
- * Transform database user to API format (snake_case to camelCase)
84
- */
85
- private dbUserToApiUser(dbUser: UserRecord): UserSchema {
86
- return {
87
- id: dbUser.id,
88
- email: dbUser.email,
89
- name: dbUser.name,
90
- emailVerified: dbUser.email_verified,
91
- createdAt: dbUser.created_at,
92
- updatedAt: dbUser.updated_at,
93
- };
94
- }
95
-
96
- /**
97
- * Generate JWT token for users and admins
98
- */
99
- generateToken(payload: TokenPayloadSchema): string {
100
- return jwt.sign(payload, JWT_SECRET(), {
101
- algorithm: 'HS256',
102
- expiresIn: JWT_EXPIRES_IN,
103
- });
104
- }
105
-
106
- /**
107
- * Generate anonymous JWT token (never expires)
108
- */
109
- generateAnonToken(): string {
110
- const payload = {
111
- sub: 'anonymous',
112
- email: 'anon@insforge.com',
113
- role: 'anon',
114
- };
115
- return jwt.sign(payload, JWT_SECRET(), {
116
- algorithm: 'HS256',
117
- // No expiresIn means token never expires
118
- });
119
- }
120
-
121
- /**
122
- * Verify JWT token
123
- */
124
- verifyToken(token: string): TokenPayloadSchema {
125
- try {
126
- const decoded = jwt.verify(token, JWT_SECRET()) as TokenPayloadSchema;
127
- return {
128
- sub: decoded.sub,
129
- email: decoded.email,
130
- role: decoded.role || 'authenticated',
131
- };
132
- } catch {
133
- throw new Error('Invalid token');
134
- }
135
- }
136
-
137
- /**
138
- * User registration
139
- */
140
- async register(email: string, password: string, name?: string): Promise<CreateUserResponse> {
141
- const existingUser = await this.db
142
- .prepare('SELECT id FROM _accounts WHERE email = ?')
143
- .get(email);
144
-
145
- if (existingUser) {
146
- throw new Error('User already exists');
147
- }
148
-
149
- const hashedPassword = await bcrypt.hash(password, 10);
150
- const userId = crypto.randomUUID();
151
-
152
- await this.db
153
- .prepare(
154
- `
155
- INSERT INTO _accounts (id, email, password, name, email_verified, created_at, updated_at)
156
- VALUES (?, ?, ?, ?, ?, NOW(), NOW())
157
- `
158
- )
159
- .run(userId, email, hashedPassword, name || null, false);
160
-
161
- await this.db
162
- .prepare(
163
- `
164
- INSERT INTO users (id, nickname, created_at, updated_at)
165
- VALUES (?, ?, NOW(), NOW())
166
- `
167
- )
168
- .run(userId, name || null);
169
-
170
- const dbUser = await this.db
171
- .prepare(
172
- 'SELECT id, email, name, email_verified, created_at, updated_at FROM _accounts WHERE id = ?'
173
- )
174
- .get(userId);
175
- const user = this.dbUserToApiUser(dbUser);
176
- const accessToken = this.generateToken({ sub: userId, email, role: 'authenticated' });
177
-
178
- return { user, accessToken };
179
- }
180
-
181
- /**
182
- * User login
183
- */
184
- async login(email: string, password: string): Promise<CreateSessionResponse> {
185
- const dbUser = await this.db.prepare('SELECT * FROM _accounts WHERE email = ?').get(email);
186
-
187
- if (!dbUser || !dbUser.password) {
188
- throw new Error('Invalid credentials');
189
- }
190
-
191
- const validPassword = await bcrypt.compare(password, dbUser.password);
192
- if (!validPassword) {
193
- throw new Error('Invalid credentials');
194
- }
195
-
196
- const user = this.dbUserToApiUser(dbUser);
197
- const accessToken = this.generateToken({
198
- sub: dbUser.id,
199
- email: dbUser.email,
200
- role: 'authenticated',
201
- });
202
-
203
- return { user, accessToken };
204
- }
205
-
206
- /**
207
- * Admin login (validates against env variables only)
208
- */
209
- adminLogin(email: string, password: string): CreateAdminSessionResponse {
210
- // Simply validate against environment variables
211
- if (email !== this.adminEmail || password !== this.adminPassword) {
212
- throw new Error('Invalid admin credentials');
213
- }
214
-
215
- // Use a fixed admin ID for the system administrator
216
-
217
- // Return admin user with JWT token - no database interaction
218
- const accessToken = this.generateToken({ sub: ADMIN_ID, email, role: 'project_admin' });
219
-
220
- return {
221
- user: {
222
- id: ADMIN_ID,
223
- email: email,
224
- name: 'Administrator',
225
- emailVerified: true,
226
- createdAt: new Date().toISOString(),
227
- updatedAt: new Date().toISOString(),
228
- },
229
- accessToken,
230
- };
231
- }
232
-
233
- /**
234
- * Admin login with authorization token (validates JWT from external issuer)
235
- */
236
- async adminLoginWithAuthorizationCode(code: string): Promise<CreateAdminSessionResponse> {
237
- try {
238
- // Use the helper function to verify cloud token
239
- const { payload } = await verifyCloudToken(code);
240
-
241
- // If verification succeeds, extract user info and generate internal token
242
- const email = payload['email'] || payload['sub'] || 'admin@insforge.local';
243
-
244
- // Generate internal access token
245
- const accessToken = this.generateToken({
246
- sub: ADMIN_ID,
247
- email: email as string,
248
- role: 'project_admin',
249
- });
250
-
251
- return {
252
- user: {
253
- id: ADMIN_ID,
254
- email: email as string,
255
- name: 'Administrator',
256
- emailVerified: true,
257
- createdAt: new Date().toISOString(),
258
- updatedAt: new Date().toISOString(),
259
- },
260
- accessToken,
261
- };
262
- } catch (error) {
263
- logger.error('Admin token verification failed:', error);
264
- throw new Error('Invalid admin credentials');
265
- }
266
- }
267
-
268
- /**
269
- * Find or create third-party user (main OAuth user handler)
270
- * Adapted from 3-table to 2-table structure
271
- */
272
- async findOrCreateThirdPartyUser(
273
- provider: string,
274
- providerId: string,
275
- email: string,
276
- userName: string,
277
- avatarUrl: string,
278
- identityData: GoogleUserInfo | GitHubUserInfo | Record<string, unknown>
279
- ): Promise<CreateSessionResponse> {
280
- // First, try to find existing user by provider ID in _account_providers table
281
- const account = await this.db
282
- .prepare('SELECT * FROM _account_providers WHERE provider = ? AND provider_account_id = ?')
283
- .get(provider, providerId);
284
-
285
- if (account) {
286
- // Found existing OAuth user, update last login time
287
- await this.db
288
- .prepare(
289
- 'UPDATE _account_providers SET updated_at = CURRENT_TIMESTAMP WHERE provider = ? AND provider_account_id = ?'
290
- )
291
- .run(provider, providerId);
292
-
293
- const dbUser = await this.db
294
- .prepare(
295
- 'SELECT id, email, name, email_verified, created_at, updated_at FROM _accounts WHERE id = ?'
296
- )
297
- .get(account.user_id);
298
-
299
- const user = this.dbUserToApiUser(dbUser);
300
- const accessToken = this.generateToken({
301
- sub: user.id,
302
- email: user.email,
303
- role: 'authenticated',
304
- });
305
-
306
- return { user, accessToken };
307
- }
308
-
309
- // If not found by provider_id, try to find by email in _user table
310
- const existingUser = await this.db
311
- .prepare('SELECT * FROM _accounts WHERE email = ?')
312
- .get(email);
313
-
314
- if (existingUser) {
315
- // Found existing user by email, create _account_providers record to link OAuth
316
- await this.db
317
- .prepare(
318
- `
319
- INSERT INTO _account_providers (
320
- user_id, provider, provider_account_id,
321
- provider_data, created_at, updated_at
322
- )
323
- VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
324
- `
325
- )
326
- .run(existingUser.id, provider, providerId, JSON.stringify(identityData));
327
-
328
- const user = this.dbUserToApiUser(existingUser);
329
- const accessToken = this.generateToken({
330
- sub: existingUser.id,
331
- email: existingUser.email,
332
- role: 'authenticated',
333
- });
334
-
335
- return { user, accessToken };
336
- }
337
-
338
- // Create new user with OAuth data
339
- return this.createThirdPartyUser(
340
- provider,
341
- userName,
342
- email,
343
- providerId,
344
- identityData,
345
- avatarUrl
346
- );
347
- }
348
-
349
- /**
350
- * Create new third-party user
351
- */
352
- private async createThirdPartyUser(
353
- provider: string,
354
- userName: string,
355
- email: string,
356
- providerId: string,
357
- identityData: GoogleUserInfo | GitHubUserInfo | Record<string, unknown>,
358
- avatarUrl: string
359
- ): Promise<CreateSessionResponse> {
360
- const userId = crypto.randomUUID();
361
-
362
- await this.db.exec('BEGIN');
363
-
364
- try {
365
- // Create user record (without password for OAuth users)
366
- await this.db
367
- .prepare(
368
- `
369
- INSERT INTO _accounts (id, email, name, email_verified, created_at, updated_at)
370
- VALUES (?, ?, ?, true, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
371
- `
372
- )
373
- .run(userId, email, userName);
374
-
375
- await this.db
376
- .prepare(
377
- `
378
- INSERT INTO users (id, nickname, avatar_url, created_at, updated_at)
379
- VALUES (?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
380
- `
381
- )
382
- .run(userId, userName, avatarUrl);
383
-
384
- // Create _account_providers record
385
- await this.db
386
- .prepare(
387
- `
388
- INSERT INTO _account_providers (
389
- user_id, provider, provider_account_id,
390
- provider_data, created_at, updated_at
391
- )
392
- VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
393
- `
394
- )
395
- .run(
396
- userId,
397
- provider,
398
- providerId,
399
- JSON.stringify({ ...identityData, avatar_url: avatarUrl })
400
- );
401
-
402
- await this.db.exec('COMMIT');
403
-
404
- const user: UserSchema = {
405
- id: userId,
406
- email,
407
- name: userName,
408
- emailVerified: true,
409
- createdAt: new Date().toISOString(),
410
- updatedAt: new Date().toISOString(),
411
- };
412
-
413
- const accessToken = this.generateToken({
414
- sub: userId,
415
- email,
416
- role: 'authenticated',
417
- });
418
-
419
- return { user, accessToken };
420
- } catch (error) {
421
- await this.db.exec('ROLLBACK');
422
- throw error;
423
- }
424
- }
425
-
426
- /**
427
- * Generate Google OAuth authorization URL
428
- */
429
- async generateGoogleAuthUrl(state?: string): Promise<string | undefined> {
430
- const oauthConfigService = OAuthConfigService.getInstance();
431
- const config = await oauthConfigService.getConfigByProvider('google');
432
-
433
- if (!config) {
434
- throw new Error('Google OAuth not configured');
435
- }
436
-
437
- const selfBaseUrl = process.env.API_BASE_URL || 'http://localhost:7130';
438
-
439
- if (config?.useSharedKey) {
440
- if (!state) {
441
- logger.warn('Shared Google OAuth called without state parameter');
442
- throw new Error('State parameter is required for shared Google OAuth');
443
- }
444
- // Use shared keys if configured
445
- const cloudBaseUrl = process.env.CLOUD_API_HOST || 'https://api.insforge.dev';
446
- const redirectUri = `${selfBaseUrl}/api/auth/oauth/shared/callback/${state}`;
447
- const authUrl = await fetch(
448
- `${cloudBaseUrl}/auth/v1/shared/google?redirect_uri=${encodeURIComponent(redirectUri)}`,
449
- {
450
- method: 'GET',
451
- headers: {
452
- 'Content-Type': 'application/json',
453
- },
454
- }
455
- );
456
- if (!authUrl.ok) {
457
- logger.error('Failed to fetch Google auth URL:', {
458
- status: authUrl.status,
459
- statusText: authUrl.statusText,
460
- });
461
- throw new Error(`Failed to fetch Google auth URL: ${authUrl.statusText}`);
462
- }
463
- const responseData = (await authUrl.json()) as { auth_url?: string; url?: string };
464
- return responseData.auth_url || responseData.url || '';
465
- }
466
-
467
- logger.debug('Google OAuth Config (fresh from DB):', {
468
- clientId: config.clientId ? 'SET' : 'NOT SET',
469
- });
470
-
471
- const authUrl = new URL('https://accounts.google.com/o/oauth2/v2/auth');
472
- authUrl.searchParams.set('client_id', config.clientId ?? '');
473
- authUrl.searchParams.set('redirect_uri', `${selfBaseUrl}/api/auth/oauth/google/callback`);
474
- authUrl.searchParams.set('response_type', 'code');
475
- authUrl.searchParams.set(
476
- 'scope',
477
- config.scopes ? config.scopes.join(' ') : 'openid email profile'
478
- );
479
- authUrl.searchParams.set('access_type', 'offline');
480
- if (state) {
481
- authUrl.searchParams.set('state', state);
482
- }
483
-
484
- return authUrl.toString();
485
- }
486
-
487
- /**
488
- * Generate GitHub OAuth authorization URL - ALWAYS reads fresh from DB
489
- */
490
- async generateGitHubAuthUrl(state?: string): Promise<string> {
491
- const oauthConfigService = OAuthConfigService.getInstance();
492
- const config = await oauthConfigService.getConfigByProvider('github');
493
-
494
- if (!config) {
495
- throw new Error('GitHub OAuth not configured');
496
- }
497
-
498
- const selfBaseUrl = process.env.API_BASE_URL || 'http://localhost:7130';
499
-
500
- if (config?.useSharedKey) {
501
- if (!state) {
502
- logger.warn('Shared GitHub OAuth called without state parameter');
503
- throw new Error('State parameter is required for shared GitHub OAuth');
504
- }
505
- // Use shared keys if configured
506
- const cloudBaseUrl = process.env.CLOUD_API_HOST || 'https://api.insforge.dev';
507
- const redirectUri = `${selfBaseUrl}/api/auth/oauth/shared/callback/${state}`;
508
- const authUrl = await fetch(
509
- `${cloudBaseUrl}/auth/v1/shared/github?redirect_uri=${encodeURIComponent(redirectUri)}`,
510
- {
511
- method: 'GET',
512
- headers: {
513
- 'Content-Type': 'application/json',
514
- },
515
- }
516
- );
517
- if (!authUrl.ok) {
518
- logger.error('Failed to fetch GitHub auth URL:', {
519
- status: authUrl.status,
520
- statusText: authUrl.statusText,
521
- });
522
- throw new Error(`Failed to fetch GitHub auth URL: ${authUrl.statusText}`);
523
- }
524
- const responseData = (await authUrl.json()) as { auth_url?: string; url?: string };
525
- return responseData.auth_url || responseData.url || '';
526
- }
527
-
528
- logger.debug('GitHub OAuth Config (fresh from DB):', {
529
- clientId: config.clientId ? 'SET' : 'NOT SET',
530
- });
531
-
532
- const authUrl = new URL('https://github.com/login/oauth/authorize');
533
- authUrl.searchParams.set('client_id', config.clientId ?? '');
534
- authUrl.searchParams.set('redirect_uri', `${selfBaseUrl}/api/auth/oauth/github/callback`);
535
- authUrl.searchParams.set('scope', config.scopes ? config.scopes.join(' ') : 'user:email');
536
- if (state) {
537
- authUrl.searchParams.set('state', state);
538
- }
539
-
540
- return authUrl.toString();
541
- }
542
-
543
- /**
544
- * Exchange Google code for tokens
545
- */
546
- async exchangeCodeToTokenByGoogle(
547
- code: string
548
- ): Promise<{ access_token: string; id_token: string }> {
549
- // Check cache first
550
- if (this.processedCodes.has(code)) {
551
- const cachedTokens = this.tokenCache.get(code);
552
- if (cachedTokens) {
553
- logger.debug('Returning cached tokens for already processed code.');
554
- return cachedTokens;
555
- }
556
- throw new Error('Authorization code is currently being processed.');
557
- }
558
-
559
- const oauthConfigService = OAuthConfigService.getInstance();
560
- const config = await oauthConfigService.getConfigByProvider('google');
561
-
562
- if (!config) {
563
- throw new Error('Google OAuth not configured');
564
- }
565
-
566
- try {
567
- this.processedCodes.add(code);
568
-
569
- logger.info('Exchanging Google code for tokens', {
570
- hasCode: !!code,
571
- clientId: config.clientId?.substring(0, 10) + '...',
572
- });
573
-
574
- const clientSecret = await oauthConfigService.getClientSecretByProvider('google');
575
- const selfBaseUrl = process.env.API_BASE_URL || 'http://localhost:7130';
576
- const response = await axios.post('https://oauth2.googleapis.com/token', {
577
- code,
578
- client_id: config.clientId,
579
- client_secret: clientSecret,
580
- redirect_uri: `${selfBaseUrl}/api/auth/oauth/google/callback`,
581
- grant_type: 'authorization_code',
582
- });
583
-
584
- if (!response.data.access_token || !response.data.id_token) {
585
- throw new Error('Failed to get tokens from Google');
586
- }
587
-
588
- const result = {
589
- access_token: response.data.access_token,
590
- id_token: response.data.id_token,
591
- };
592
-
593
- // Cache the successful token exchange
594
- this.tokenCache.set(code, result);
595
-
596
- // Set a timeout to clear the code and cache to prevent memory leaks
597
- setTimeout(() => {
598
- this.processedCodes.delete(code);
599
- this.tokenCache.delete(code);
600
- }, 60000); // 1 minute timeout
601
-
602
- return result;
603
- } catch (error) {
604
- // If the request fails, remove the code immediately to allow for a retry
605
- this.processedCodes.delete(code);
606
-
607
- if (axios.isAxiosError(error) && error.response) {
608
- logger.error('Google token exchange failed', {
609
- status: error.response.status,
610
- error: error.response.data,
611
- });
612
- throw new Error(`Google OAuth error: ${JSON.stringify(error.response.data)}`);
613
- }
614
- throw error;
615
- }
616
- }
617
-
618
- /**
619
- * Verify Google ID token and get user info
620
- */
621
- async verifyGoogleToken(idToken: string) {
622
- const oauthConfigService = OAuthConfigService.getInstance();
623
- const config = await oauthConfigService.getConfigByProvider('google');
624
-
625
- if (!config) {
626
- throw new Error('Google OAuth not configured');
627
- }
628
-
629
- const clientSecret = await oauthConfigService.getClientSecretByProvider('google');
630
-
631
- if (!clientSecret) {
632
- throw new Error('Google Client Secret not conifgured.');
633
- }
634
-
635
- // Create OAuth2Client with fresh config
636
- const googleClient = new OAuth2Client(config.clientId, clientSecret, config.redirectUri);
637
-
638
- try {
639
- // Properly verify the ID token with Google's servers
640
- const ticket = await googleClient.verifyIdToken({
641
- idToken,
642
- audience: config.clientId,
643
- });
644
-
645
- const payload = ticket.getPayload();
646
- if (!payload) {
647
- throw new Error('Invalid Google token payload');
648
- }
649
-
650
- return {
651
- sub: payload.sub,
652
- email: payload.email || '',
653
- email_verified: payload.email_verified || false,
654
- name: payload.name || '',
655
- picture: payload.picture || '',
656
- given_name: payload.given_name || '',
657
- family_name: payload.family_name || '',
658
- locale: payload.locale || '',
659
- };
660
- } catch (error) {
661
- logger.error('Google token verification failed:', error);
662
- throw new Error(`Google token verification failed: ${error}`);
663
- }
664
- }
665
-
666
- /**
667
- * Find or create Google user
668
- */
669
- async findOrCreateGoogleUser(googleUserInfo: GoogleUserInfo): Promise<CreateSessionResponse> {
670
- const userName = googleUserInfo.name || googleUserInfo.email.split('@')[0];
671
- return this.findOrCreateThirdPartyUser(
672
- 'google',
673
- googleUserInfo.sub,
674
- googleUserInfo.email,
675
- userName,
676
- googleUserInfo.picture || '',
677
- googleUserInfo
678
- );
679
- }
680
-
681
- /**
682
- * Exchange GitHub code for access token
683
- */
684
- async exchangeGitHubCodeForToken(code: string): Promise<string> {
685
- const oauthConfigService = OAuthConfigService.getInstance();
686
- const config = await oauthConfigService.getConfigByProvider('github');
687
-
688
- if (!config) {
689
- throw new Error('GitHub OAuth not configured');
690
- }
691
-
692
- const clientSecret = await oauthConfigService.getClientSecretByProvider('github');
693
- const selfBaseUrl = process.env.API_BASE_URL || 'http://localhost:7130';
694
- const response = await axios.post(
695
- 'https://github.com/login/oauth/access_token',
696
- {
697
- client_id: config.clientId,
698
- client_secret: clientSecret,
699
- code,
700
- redirect_uri: `${selfBaseUrl}/api/auth/oauth/github/callback`,
701
- },
702
- {
703
- headers: {
704
- Accept: 'application/json',
705
- },
706
- }
707
- );
708
-
709
- if (!response.data.access_token) {
710
- throw new Error('Failed to get access token from GitHub');
711
- }
712
-
713
- return response.data.access_token;
714
- }
715
-
716
- /**
717
- * Get GitHub user info
718
- */
719
- async getGitHubUserInfo(accessToken: string) {
720
- const userResponse = await axios.get('https://api.github.com/user', {
721
- headers: {
722
- Authorization: `Bearer ${accessToken}`,
723
- },
724
- });
725
-
726
- // GitHub doesn't always return email in user endpoint
727
- let email = userResponse.data.email;
728
-
729
- if (!email) {
730
- const emailResponse = await axios.get('https://api.github.com/user/emails', {
731
- headers: {
732
- Authorization: `Bearer ${accessToken}`,
733
- },
734
- });
735
-
736
- const primaryEmail = emailResponse.data.find((e: GitHubEmailInfo) => e.primary);
737
- email = primaryEmail ? primaryEmail.email : emailResponse.data[0]?.email;
738
- }
739
-
740
- return {
741
- id: userResponse.data.id,
742
- login: userResponse.data.login,
743
- name: userResponse.data.name,
744
- email: email || `${userResponse.data.login}@users.noreply.github.com`,
745
- avatar_url: userResponse.data.avatar_url,
746
- };
747
- }
748
-
749
- /**
750
- * Find or create GitHub user
751
- */
752
- async findOrCreateGitHubUser(githubUserInfo: GitHubUserInfo): Promise<CreateSessionResponse> {
753
- const userName = githubUserInfo.name || githubUserInfo.login;
754
- const email = githubUserInfo.email || `${githubUserInfo.login}@users.noreply.github.com`;
755
-
756
- return this.findOrCreateThirdPartyUser(
757
- 'github',
758
- githubUserInfo.id.toString(),
759
- email,
760
- userName,
761
- githubUserInfo.avatar_url || '',
762
- githubUserInfo
763
- );
764
- }
765
-
766
- async getMetadata(): Promise<AuthMetadataSchema> {
767
- const oAuthConfigService = OAuthConfigService.getInstance();
768
- const oAuthConfigs = await oAuthConfigService.getAllConfigs();
769
- return {
770
- oauths: oAuthConfigs,
771
- };
772
- }
773
-
774
- /**
775
- * Get database instance for direct queries
776
- */
777
- getDb() {
778
- return this.db;
779
- }
780
- }