@cdmbase/wiki-browser 12.0.18-alpha.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 (367) hide show
  1. package/LICENSE +21 -0
  2. package/lib/components/Logo.d.ts +4 -0
  3. package/lib/components/Logo.d.ts.map +1 -0
  4. package/lib/components/Logo.js +16 -0
  5. package/lib/components/Logo.js.map +1 -0
  6. package/lib/components/help/SidebarSearch.d.ts +8 -0
  7. package/lib/components/help/SidebarSearch.d.ts.map +1 -0
  8. package/lib/components/help/SidebarSearch.js +111 -0
  9. package/lib/components/help/SidebarSearch.js.map +1 -0
  10. package/lib/components/help/index.d.ts +2 -0
  11. package/lib/components/help/index.d.ts.map +1 -0
  12. package/lib/components/landing/FeatureCard.d.ts +13 -0
  13. package/lib/components/landing/FeatureCard.d.ts.map +1 -0
  14. package/lib/components/landing/FeatureCard.js +85 -0
  15. package/lib/components/landing/FeatureCard.js.map +1 -0
  16. package/lib/components/landing/QuickLinkCard.d.ts +8 -0
  17. package/lib/components/landing/QuickLinkCard.d.ts.map +1 -0
  18. package/lib/components/landing/QuickLinkCard.js +26 -0
  19. package/lib/components/landing/QuickLinkCard.js.map +1 -0
  20. package/lib/components/landing/SearchInput.d.ts +10 -0
  21. package/lib/components/landing/SearchInput.d.ts.map +1 -0
  22. package/lib/components/landing/SearchInput.js +223 -0
  23. package/lib/components/landing/SearchInput.js.map +1 -0
  24. package/lib/components/landing/index.d.ts +4 -0
  25. package/lib/components/landing/index.d.ts.map +1 -0
  26. package/lib/components/welcome.d.ts +3 -0
  27. package/lib/components/welcome.d.ts.map +1 -0
  28. package/lib/compute.d.ts +4 -0
  29. package/lib/compute.d.ts.map +1 -0
  30. package/lib/compute.js +96 -0
  31. package/lib/compute.js.map +1 -0
  32. package/lib/config/env-config.d.ts +4 -0
  33. package/lib/config/env-config.d.ts.map +1 -0
  34. package/lib/config/env-config.js +7 -0
  35. package/lib/config/env-config.js.map +1 -0
  36. package/lib/docs.config.d.ts +48 -0
  37. package/lib/docs.config.d.ts.map +1 -0
  38. package/lib/index.d.ts +4 -0
  39. package/lib/index.d.ts.map +1 -0
  40. package/lib/index.js +2 -0
  41. package/lib/index.js.map +1 -0
  42. package/lib/loaders/search.d.ts +1 -0
  43. package/lib/loaders/search.d.ts.map +1 -0
  44. package/lib/module.d.ts +4 -0
  45. package/lib/module.d.ts.map +1 -0
  46. package/lib/module.js +11 -0
  47. package/lib/module.js.map +1 -0
  48. package/lib/pages/ArticlePage/ArticlePage.d.ts +4 -0
  49. package/lib/pages/ArticlePage/ArticlePage.d.ts.map +1 -0
  50. package/lib/pages/ArticlePage/ArticlePage.js +222 -0
  51. package/lib/pages/ArticlePage/ArticlePage.js.map +1 -0
  52. package/lib/pages/ArticlePage/index.d.ts +3 -0
  53. package/lib/pages/ArticlePage/index.d.ts.map +1 -0
  54. package/lib/pages/ArticlePage/index.js +3 -0
  55. package/lib/pages/ArticlePage/index.js.map +1 -0
  56. package/lib/pages/CategoryCollection/CategoryCollection.d.ts +4 -0
  57. package/lib/pages/CategoryCollection/CategoryCollection.d.ts.map +1 -0
  58. package/lib/pages/CategoryCollection/CategoryCollection.js +103 -0
  59. package/lib/pages/CategoryCollection/CategoryCollection.js.map +1 -0
  60. package/lib/pages/CategoryCollection/index.d.ts +3 -0
  61. package/lib/pages/CategoryCollection/index.d.ts.map +1 -0
  62. package/lib/pages/CategoryCollection/index.js +3 -0
  63. package/lib/pages/CategoryCollection/index.js.map +1 -0
  64. package/lib/pages/Help/HelpIndex.d.ts +4 -0
  65. package/lib/pages/Help/HelpIndex.d.ts.map +1 -0
  66. package/lib/pages/Help/HelpIndex.js +44 -0
  67. package/lib/pages/Help/HelpIndex.js.map +1 -0
  68. package/lib/pages/Help/index.d.ts +4 -0
  69. package/lib/pages/Help/index.d.ts.map +1 -0
  70. package/lib/pages/Help/index.js +226 -0
  71. package/lib/pages/Help/index.js.map +1 -0
  72. package/lib/pages/Landing/index.d.ts +3 -0
  73. package/lib/pages/Landing/index.d.ts.map +1 -0
  74. package/lib/pages/Landing/index.js +281 -0
  75. package/lib/pages/Landing/index.js.map +1 -0
  76. package/lib/routes.json +2533 -0
  77. package/lib/seo.d.ts +22 -0
  78. package/lib/seo.d.ts.map +1 -0
  79. package/lib/slot-fill/FooterFill.d.ts +3 -0
  80. package/lib/slot-fill/FooterFill.d.ts.map +1 -0
  81. package/lib/slot-fill/FooterFill.js +18 -0
  82. package/lib/slot-fill/FooterFill.js.map +1 -0
  83. package/lib/slot-fill/LogoFill.d.ts +5 -0
  84. package/lib/slot-fill/LogoFill.d.ts.map +1 -0
  85. package/lib/slot-fill/LogoFill.js +74 -0
  86. package/lib/slot-fill/LogoFill.js.map +1 -0
  87. package/lib/slot-fill/consts.d.ts +5 -0
  88. package/lib/slot-fill/consts.d.ts.map +1 -0
  89. package/lib/slot-fill/consts.js +1 -0
  90. package/lib/slot-fill/consts.js.map +1 -0
  91. package/lib/slot-fill/index.d.ts +4 -0
  92. package/lib/slot-fill/index.d.ts.map +1 -0
  93. package/lib/templates/assets/images/add-link-frontend.png +0 -0
  94. package/lib/templates/assets/images/add-package-backend.png +0 -0
  95. package/lib/templates/assets/images/add-to-backend-module.png +0 -0
  96. package/lib/templates/assets/images/add-upload-client-frontend.png +0 -0
  97. package/lib/templates/assets/images/additional-parameters.png +0 -0
  98. package/lib/templates/assets/images/aeh-implementation.png +0 -0
  99. package/lib/templates/assets/images/aeh-usage.png +0 -0
  100. package/lib/templates/assets/images/apollo-client/recommendation_cache_mgmt.png +0 -0
  101. package/lib/templates/assets/images/app-deploy-new-version/jenkins1.PNG +0 -0
  102. package/lib/templates/assets/images/app-deploy-new-version/jenkins2.PNG +0 -0
  103. package/lib/templates/assets/images/auth-wrapper-code.png +0 -0
  104. package/lib/templates/assets/images/cdebase.png +0 -0
  105. package/lib/templates/assets/images/cdm-locales-directory.png +0 -0
  106. package/lib/templates/assets/images/client-settings.png +0 -0
  107. package/lib/templates/assets/images/codegen_file_update.png +0 -0
  108. package/lib/templates/assets/images/configuration.png +0 -0
  109. package/lib/templates/assets/images/copy-plugin.png +0 -0
  110. package/lib/templates/assets/images/docusaurus.png +0 -0
  111. package/lib/templates/assets/images/error-link.png +0 -0
  112. package/lib/templates/assets/images/error-sample.png +0 -0
  113. package/lib/templates/assets/images/extension copy.png +0 -0
  114. package/lib/templates/assets/images/extension.png +0 -0
  115. package/lib/templates/assets/images/graphql/graphql-folder-backend.png +0 -0
  116. package/lib/templates/assets/images/graphql/graphql-folder-with-gql.png +0 -0
  117. package/lib/templates/assets/images/i18n-config.png +0 -0
  118. package/lib/templates/assets/images/image.png +0 -0
  119. package/lib/templates/assets/images/logo.svg +10 -0
  120. package/lib/templates/assets/images/logo1.svg +1 -0
  121. package/lib/templates/assets/images/modify-upload-false-server.png +0 -0
  122. package/lib/templates/assets/images/navigation-auth-enabled.png +0 -0
  123. package/lib/templates/assets/images/org-dashboard-navigation.png +0 -0
  124. package/lib/templates/assets/images/org-navigation.png +0 -0
  125. package/lib/templates/assets/images/preferences_graphql_type.png +0 -0
  126. package/lib/templates/assets/images/provider.png +0 -0
  127. package/lib/templates/assets/images/route-config.png +0 -0
  128. package/lib/templates/assets/images/service-accounts.png +0 -0
  129. package/lib/templates/assets/images/source-code/source-code-environments.png +0 -0
  130. package/lib/templates/assets/images/source-code/source-code-organization.png +0 -0
  131. package/lib/templates/assets/images/spin-clone-develop-deployment/jenkins-changes.png +0 -0
  132. package/lib/templates/assets/images/spin-clone-develop-deployment/lerna-changes.png +0 -0
  133. package/lib/templates/assets/images/spin-clone-develop-deployment/root-package-json-changes.png +0 -0
  134. package/lib/templates/assets/images/spin-clone-develop-deployment/values-dev-changes.png +0 -0
  135. package/lib/templates/assets/images/sso-mappers.png +0 -0
  136. package/lib/templates/assets/images/sso-picture-mapper.png +0 -0
  137. package/lib/templates/assets/images/sso-settings.png +0 -0
  138. package/lib/templates/assets/images/timesheet_apollo_cache.png +0 -0
  139. package/lib/templates/assets/images/timesheet_query.png +0 -0
  140. package/lib/templates/assets/images/tutorial/docsVersionDropdown.png +0 -0
  141. package/lib/templates/assets/images/tutorial/localeDropdown.png +0 -0
  142. package/lib/templates/assets/images/unauthenticated.png +0 -0
  143. package/lib/templates/assets/images/undraw_docusaurus_mountain.svg +170 -0
  144. package/lib/templates/assets/images/undraw_docusaurus_react.svg +169 -0
  145. package/lib/templates/assets/images/undraw_docusaurus_tree.svg +1 -0
  146. package/lib/templates/assets/images/vite-plugin-config.png +0 -0
  147. package/lib/templates/content/docs/Generators/Project/generate-fullproject.md +12 -0
  148. package/lib/templates/content/docs/LLM/Logger.llm.md +194 -0
  149. package/lib/templates/content/docs/LLM/backend-proxies-services-llm.md +2687 -0
  150. package/lib/templates/content/docs/LLM/backend-service-llm.md +3384 -0
  151. package/lib/templates/content/docs/LLM/db_migration_llm.md +954 -0
  152. package/lib/templates/content/docs/LLM/frontend/REMIX-15.3-upgrade-llm.md +1245 -0
  153. package/lib/templates/content/docs/LLM/inngest/INNGEST_FUNCTION_DEVELOPMENT_GUIDE_LLM.md +1241 -0
  154. package/lib/templates/content/docs/LLM/inngest/INNGEST_NAMESPACE_LLM.md +384 -0
  155. package/lib/templates/content/docs/LLM/llm_workflow_namespace.md +384 -0
  156. package/lib/templates/content/docs/LLM/organization-components-form-llm.md +1395 -0
  157. package/lib/templates/content/docs/LLM/page-component-llm.md +173 -0
  158. package/lib/templates/content/docs/LLM/preferences-settings-llm.md +2781 -0
  159. package/lib/templates/content/docs/LLM/tailwind-css-llm.md +502 -0
  160. package/lib/templates/content/docs/UI/SchemaBasedUI.md +334 -0
  161. package/lib/templates/content/docs/UI/SlotFillComponent.md +334 -0
  162. package/lib/templates/content/docs/adminide-modules/account/auth0-login.md +31 -0
  163. package/lib/templates/content/docs/adminide-modules/account/index.md +14 -0
  164. package/lib/templates/content/docs/adminide-modules/account/keycloak-remix-setup.md +86 -0
  165. package/lib/templates/content/docs/adminide-modules/account/remix-auth-setup.md +79 -0
  166. package/lib/templates/content/docs/adminide-modules/account/various-auth-qatest.md +157 -0
  167. package/lib/templates/content/docs/adminide-modules/api-builders/graphql.md +906 -0
  168. package/lib/templates/content/docs/adminide-modules/billing/payments/index.md +14 -0
  169. package/lib/templates/content/docs/adminide-modules/billing/payments/stripe/index.md +14 -0
  170. package/lib/templates/content/docs/adminide-modules/billing/payments/stripe/settingup-stripe-locally.md +25 -0
  171. package/lib/templates/content/docs/adminide-modules/billing/tier-config.md +293 -0
  172. package/lib/templates/content/docs/adminide-modules/connectors/Connector.md +207 -0
  173. package/lib/templates/content/docs/adminide-modules/file-upload/index.md +16 -0
  174. package/lib/templates/content/docs/adminide-modules/file-upload/setup.md +435 -0
  175. package/lib/templates/content/docs/adminide-modules/file-upload/upload-file-using-signed-url.md +161 -0
  176. package/lib/templates/content/docs/adminide-modules/preferences/AddAdditionalPermissions.md +151 -0
  177. package/lib/templates/content/docs/adminide-modules/preferences/Configuration.md +241 -0
  178. package/lib/templates/content/docs/adminide-modules/preferences/Policy-Configuration.md +61 -0
  179. package/lib/templates/content/docs/adminide-modules/preferences/UI-components/ResourceSettingsLoader.md +319 -0
  180. package/lib/templates/content/docs/adminide-modules/preferences/contribute_scope_target.md +280 -0
  181. package/lib/templates/content/docs/adminide-modules/preferences/generate-urii.md +94 -0
  182. package/lib/templates/content/docs/adminide-modules/preferences/index.md +28 -0
  183. package/lib/templates/content/docs/adminide-modules/preferences/machine-configuration.md +157 -0
  184. package/lib/templates/content/docs/adminide-modules/preferences/pageSettings/generateCdecodeUri.md +1289 -0
  185. package/lib/templates/content/docs/adminide-modules/preferences/pageSettings/migratingFromUseSettings.md +215 -0
  186. package/lib/templates/content/docs/adminide-modules/preferences/permissions/Roles-Permissions.md +72 -0
  187. package/lib/templates/content/docs/adminide-modules/preferences/permissions/settingUserPermissions.md +139 -0
  188. package/lib/templates/content/docs/adminide-modules/preferences/preference-dependency.md +138 -0
  189. package/lib/templates/content/docs/adminide-modules/preferences/route-based-configuration.md +41 -0
  190. package/lib/templates/content/docs/adminide-modules/preferences/schema-configuration.md +71 -0
  191. package/lib/templates/content/docs/adminide-modules/preferences/supported.md +24 -0
  192. package/lib/templates/content/docs/adminide-modules/preferences/useSettingsLoader.md +248 -0
  193. package/lib/templates/content/docs/adminide-modules/project-tools/auth-providers.md +1317 -0
  194. package/lib/templates/content/docs/adminide-modules/project-tools/keycloak-guide.md +543 -0
  195. package/lib/templates/content/docs/adminide-modules/project-tools/tenant-management/tenant-based-authentication.md +846 -0
  196. package/lib/templates/content/docs/adminide-modules/project-tools/tenant-management/tenant-management.md +708 -0
  197. package/lib/templates/content/docs/adminide-modules/project-tools/tenant-management/tenants.md +1117 -0
  198. package/lib/templates/content/docs/chrome-extension/index.md +14 -0
  199. package/lib/templates/content/docs/chrome-extension/setup.md +30 -0
  200. package/lib/templates/content/docs/contributing/adding-package.md +23 -0
  201. package/lib/templates/content/docs/contributing/adding_new_modules.md +99 -0
  202. package/lib/templates/content/docs/contributing/architecture-updates.md +19 -0
  203. package/lib/templates/content/docs/contributing/avoid-using-promises-ui.md +116 -0
  204. package/lib/templates/content/docs/contributing/coding-guidelines.md +111 -0
  205. package/lib/templates/content/docs/contributing/do-and-dont.md +42 -0
  206. package/lib/templates/content/docs/contributing/faq.md +22 -0
  207. package/lib/templates/content/docs/contributing/folder-setup/browser.md +12 -0
  208. package/lib/templates/content/docs/contributing/folder-setup/config.md +12 -0
  209. package/lib/templates/content/docs/contributing/folder-setup/containers-server.md +12 -0
  210. package/lib/templates/content/docs/contributing/folder-setup/core.md +12 -0
  211. package/lib/templates/content/docs/contributing/folder-setup/graphql.md +12 -0
  212. package/lib/templates/content/docs/contributing/folder-setup/index.md +30 -0
  213. package/lib/templates/content/docs/contributing/folder-setup/module.md +12 -0
  214. package/lib/templates/content/docs/contributing/folder-setup/server.md +12 -0
  215. package/lib/templates/content/docs/contributing/folder-setup/services.md +12 -0
  216. package/lib/templates/content/docs/contributing/folder-setup/store.md +12 -0
  217. package/lib/templates/content/docs/contributing/frontend-coding.md +30 -0
  218. package/lib/templates/content/docs/contributing/git-subtree-sharing.md +73 -0
  219. package/lib/templates/content/docs/contributing/graphql-subscriptions.md +69 -0
  220. package/lib/templates/content/docs/contributing/how-to-contribute.md +30 -0
  221. package/lib/templates/content/docs/contributing/how_to_check_pure_esm.md +29 -0
  222. package/lib/templates/content/docs/contributing/index.md +60 -0
  223. package/lib/templates/content/docs/contributing/installation-issues.md +23 -0
  224. package/lib/templates/content/docs/contributing/keyboard-shortcut.md +131 -0
  225. package/lib/templates/content/docs/contributing/language/locale-support.md +12 -0
  226. package/lib/templates/content/docs/contributing/lerna-build-tools.md +516 -0
  227. package/lib/templates/content/docs/contributing/lerna-yarn-workspaces.md +95 -0
  228. package/lib/templates/content/docs/contributing/lint-and-formatter.md +20 -0
  229. package/lib/templates/content/docs/contributing/mobile-setup.md +16 -0
  230. package/lib/templates/content/docs/contributing/project-setup.md +233 -0
  231. package/lib/templates/content/docs/contributing/react/index.md +14 -0
  232. package/lib/templates/content/docs/contributing/react/lazy-component.md +70 -0
  233. package/lib/templates/content/docs/contributing/run-various-options.md +124 -0
  234. package/lib/templates/content/docs/contributing/schema-first-graphql-types.md +37 -0
  235. package/lib/templates/content/docs/contributing/source-code-organization.md +57 -0
  236. package/lib/templates/content/docs/contributing/staging-docker.md +88 -0
  237. package/lib/templates/content/docs/contributing/third-party/apollo-client-v3-tutorials.md +28 -0
  238. package/lib/templates/content/docs/contributing/third-party/index.md +18 -0
  239. package/lib/templates/content/docs/contributing/typescript-contribution.md +16 -0
  240. package/lib/templates/content/docs/devops/app-deploy-new-version.md +30 -0
  241. package/lib/templates/content/docs/devops/index.md +14 -0
  242. package/lib/templates/content/docs/devops/mobile-jenkins-build.md +40 -0
  243. package/lib/templates/content/docs/devops/versioning-the-project.md +128 -0
  244. package/lib/templates/content/docs/error-handler/application-error-handler.md +40 -0
  245. package/lib/templates/content/docs/error-handler/error-handling.md +26 -0
  246. package/lib/templates/content/docs/error-handler/index.md +16 -0
  247. package/lib/templates/content/docs/error-handler/logging-errors.md +14 -0
  248. package/lib/templates/content/docs/feature-api/copy-operation.md +427 -0
  249. package/lib/templates/content/docs/feature-api/feature-browser/assets.md +46 -0
  250. package/lib/templates/content/docs/feature-api/feature-browser/auth-permissions.md +12 -0
  251. package/lib/templates/content/docs/feature-api/feature-browser/feature.md +131 -0
  252. package/lib/templates/content/docs/feature-api/feature-browser/index.md +22 -0
  253. package/lib/templates/content/docs/feature-api/feature-browser/routes-menu.md +110 -0
  254. package/lib/templates/content/docs/feature-api/feature-browser/routing-convention.md +124 -0
  255. package/lib/templates/content/docs/feature-api/feature-browser/routing.md +338 -0
  256. package/lib/templates/content/docs/feature-api/feature-mobile/auth-permissions.md +20 -0
  257. package/lib/templates/content/docs/feature-api/feature-mobile/feature.md +130 -0
  258. package/lib/templates/content/docs/feature-api/feature-mobile/index.md +18 -0
  259. package/lib/templates/content/docs/feature-api/feature-mobile/navigation.md +187 -0
  260. package/lib/templates/content/docs/feature-api/feature-server/Scheduling.md +44 -0
  261. package/lib/templates/content/docs/feature-api/feature-server/dataloader.md +320 -0
  262. package/lib/templates/content/docs/feature-api/feature-server/dependency-injection.md +81 -0
  263. package/lib/templates/content/docs/feature-api/feature-server/feature.md +65 -0
  264. package/lib/templates/content/docs/feature-api/feature-server/generic-dataloader.md +135 -0
  265. package/lib/templates/content/docs/feature-api/feature-server/index.md +40 -0
  266. package/lib/templates/content/docs/feature-api/feature-server/migration.md +127 -0
  267. package/lib/templates/content/docs/feature-api/feature-server/mongo-model.md +72 -0
  268. package/lib/templates/content/docs/feature-api/feature-server/permissions.md +12 -0
  269. package/lib/templates/content/docs/feature-api/feature-server/policies.md +57 -0
  270. package/lib/templates/content/docs/feature-api/feature-server/preferences.md +57 -0
  271. package/lib/templates/content/docs/feature-api/feature-server/repositories.md +114 -0
  272. package/lib/templates/content/docs/feature-api/feature-server/resolvers.md +126 -0
  273. package/lib/templates/content/docs/feature-api/feature-server/rules.md +132 -0
  274. package/lib/templates/content/docs/feature-api/feature-server/schema.md +12 -0
  275. package/lib/templates/content/docs/feature-api/feature-server/services.md +102 -0
  276. package/lib/templates/content/docs/feature-api/feature-server/setup-resource-crud.md +359 -0
  277. package/lib/templates/content/docs/feature-api/index.md +18 -0
  278. package/lib/templates/content/docs/graphql/apolloClient-mutation.md +94 -0
  279. package/lib/templates/content/docs/graphql/index.md +14 -0
  280. package/lib/templates/content/docs/graphql/scalars.md +15 -0
  281. package/lib/templates/content/docs/help/index.md +14 -0
  282. package/lib/templates/content/docs/help/intro.md +16 -0
  283. package/lib/templates/content/docs/intl/ant-design-menu-translation.md +74 -0
  284. package/lib/templates/content/docs/intl/intl-namespace.md +129 -0
  285. package/lib/templates/content/docs/intl/vite-plugin-intl.md +87 -0
  286. package/lib/templates/content/docs/intl/webpack-plugin-intl.md +12 -0
  287. package/lib/templates/content/docs/intro.md +18 -0
  288. package/lib/templates/content/docs/knowledge/basic-fullstack.md +238 -0
  289. package/lib/templates/content/docs/mailing/index.md +14 -0
  290. package/lib/templates/content/docs/mailing/mailing-template.md +148 -0
  291. package/lib/templates/content/docs/mobile/App-navigation-generator.md +410 -0
  292. package/lib/templates/content/docs/mobile/MobileTestCases.md +264 -0
  293. package/lib/templates/content/docs/mobile/eas-profile-build.md +107 -0
  294. package/lib/templates/content/docs/mobile/expo-push-notification-setup.md +216 -0
  295. package/lib/templates/content/docs/mobile/index.md +14 -0
  296. package/lib/templates/content/docs/mobile/routes.md +83 -0
  297. package/lib/templates/content/docs/organization/adding-account-context.md +116 -0
  298. package/lib/templates/content/docs/organization/adding-org-mobile-navigation.md +22 -0
  299. package/lib/templates/content/docs/organization/adding-org-web-navigation.md +12 -0
  300. package/lib/templates/content/docs/organization/index.md +20 -0
  301. package/lib/templates/content/docs/organization/initialization.md +20 -0
  302. package/lib/templates/content/docs/organization/organization-resource-vs-resource.md +112 -0
  303. package/lib/templates/content/docs/remix/configuration/component-structure-best-practices.md +152 -0
  304. package/lib/templates/content/docs/remix/configuration/configurations.md +218 -0
  305. package/lib/templates/content/docs/remix/configuration/css-import-and-stylesheets.md +142 -0
  306. package/lib/templates/content/docs/remix/configuration/dont-subcomponent-network.md +166 -0
  307. package/lib/templates/content/docs/remix/configuration/generated-data-loaders.md +122 -0
  308. package/lib/templates/content/docs/remix/configuration/generated-resource-loaders.md +257 -0
  309. package/lib/templates/content/docs/remix/configuration/query-params-generator.md +216 -0
  310. package/lib/templates/content/docs/remix/configuration/routes-extra-icons.md +103 -0
  311. package/lib/templates/content/docs/remix/configuration/routes-json-advanced.md +86 -0
  312. package/lib/templates/content/docs/remix/configuration/routes-json-auth.md +113 -0
  313. package/lib/templates/content/docs/remix/configuration/routes-json-best-practices.md +55 -0
  314. package/lib/templates/content/docs/remix/configuration/routes-json-fields.md +79 -0
  315. package/lib/templates/content/docs/remix/configuration/routes-json-graphql.md +79 -0
  316. package/lib/templates/content/docs/remix/configuration/routes-json-index.md +112 -0
  317. package/lib/templates/content/docs/remix/configuration/routes-json-loaders.md +165 -0
  318. package/lib/templates/content/docs/remix/configuration/routes-json-middleware.md +196 -0
  319. package/lib/templates/content/docs/remix/configuration/routes-json-overview.md +53 -0
  320. package/lib/templates/content/docs/remix/data-loaders.md +43 -0
  321. package/lib/templates/content/docs/remix/devtools/remix-devtools.md +58 -0
  322. package/lib/templates/content/docs/remix/examples/changes-using-servercode.md +79 -0
  323. package/lib/templates/content/docs/remix/extra-icons.md +62 -0
  324. package/lib/templates/content/docs/remix/extra-links.md +65 -0
  325. package/lib/templates/content/docs/remix/generated-data-loaders.md +114 -0
  326. package/lib/templates/content/docs/remix/queryParamsGenerator.md +89 -0
  327. package/lib/templates/content/docs/remix/resources.md +16 -0
  328. package/lib/templates/content/docs/remix/styles.md +132 -0
  329. package/lib/templates/content/docs/remix/wiki.md +12 -0
  330. package/lib/templates/content/docs/security/auth-wrapper/auth-wrapper.md +24 -0
  331. package/lib/templates/content/docs/security/index.md +18 -0
  332. package/lib/templates/content/docs/security/secure-button-mobilenative.md +88 -0
  333. package/lib/templates/content/docs/security/secure-button-web.md +89 -0
  334. package/lib/templates/content/docs/server-side/account-customization.md +82 -0
  335. package/lib/templates/content/docs/server-side/apollo/caching.md +164 -0
  336. package/lib/templates/content/docs/server-side/backend-architecture/FINAL-DECISION.md +209 -0
  337. package/lib/templates/content/docs/server-side/backend-architecture/TRUE-FINAL-ARCHITECTURE.md +603 -0
  338. package/lib/templates/content/docs/server-side/backend-architecture/index1.md +0 -0
  339. package/lib/templates/content/docs/server-side/backend-coding.md +839 -0
  340. package/lib/templates/content/docs/server-side/e2b/manageing-template.md +197 -0
  341. package/lib/templates/content/docs/server-side/index.md +14 -0
  342. package/lib/templates/content/docs/server-side/inngest-functions-module.md +309 -0
  343. package/lib/templates/content/docs/server-side/listen-stripe-events.md +43 -0
  344. package/lib/templates/content/docs/server-side/slug-service.md +323 -0
  345. package/lib/templates/content/docs/tests/index.md +18 -0
  346. package/lib/templates/content/docs/tests/jest-test-debug-vscode.md +40 -0
  347. package/lib/templates/content/docs/tests/known-errors.md +116 -0
  348. package/lib/templates/content/docs/tests/service-test-template.md +118 -0
  349. package/lib/templates/content/docs/tests/test-setup.md +93 -0
  350. package/lib/templates/content/docs/xstate.md +23 -0
  351. package/lib/types.d.ts +37 -0
  352. package/lib/types.d.ts.map +1 -0
  353. package/lib/utils/docsNavigation.d.ts +9 -0
  354. package/lib/utils/docsNavigation.d.ts.map +1 -0
  355. package/lib/utils/docsNavigation.js +37 -0
  356. package/lib/utils/docsNavigation.js.map +1 -0
  357. package/lib/utils/helpCenterUtils.d.ts +26 -0
  358. package/lib/utils/helpCenterUtils.d.ts.map +1 -0
  359. package/lib/utils/index.d.ts +3 -0
  360. package/lib/utils/index.d.ts.map +1 -0
  361. package/lib/utils/index.js +3 -0
  362. package/lib/utils/index.js.map +1 -0
  363. package/lib/utils/markdownLoader.d.ts +36 -0
  364. package/lib/utils/markdownLoader.d.ts.map +1 -0
  365. package/lib/utils/markdownLoader.js +2242 -0
  366. package/lib/utils/markdownLoader.js.map +1 -0
  367. package/package.json +71 -0
@@ -0,0 +1,1317 @@
1
+ # Auth Provider Management System - Comprehensive Documentation
2
+
3
+ ## Table of Contents
4
+
5
+ 1. [Overview](#overview)
6
+ 2. [What This Functionality Is About](#what-this-functionality-is-about)
7
+ 3. [How to Execute the Functionality](#how-to-execute-the-functionality)
8
+ 4. [Implementation Details](#implementation-details)
9
+ 5. [State Management](#state-management)
10
+ 6. [GraphQL Integration](#graphql-integration)
11
+ 7. [Backend Architecture & Inngest Integration](#backend-architecture--inngest-integration)
12
+ 8. [Important Notes and Best Practices](#important-notes-and-best-practices)
13
+
14
+ ---
15
+
16
+ ## Overview
17
+
18
+ The Auth Provider Management System enables organizations to configure and manage authentication providers (Keycloak and Auth0) for their tenants. It provides a comprehensive interface for creating, updating, testing, and managing authentication configurations with support for both managed and self-hosted Keycloak instances.
19
+
20
+ **Primary Entry Point:** `AuthProvidersManagement.tsx`
21
+
22
+ ---
23
+
24
+ ## What This Functionality Is About
25
+
26
+ ### Core Purpose
27
+
28
+ The Auth Provider Management System enables organizations to:
29
+
30
+ 1. **Configure Authentication Providers**: Set up Keycloak or Auth0 authentication for tenants
31
+ 2. **Manage Provider Settings**: Configure realms, clients, redirect URIs, and identity providers
32
+ 3. **Test Credentials**: Verify authentication provider configurations work correctly
33
+ 4. **Support Multiple Deployment Types**: Handle both managed and self-hosted Keycloak instances
34
+ 5. **Tenant Association**: Link authentication providers to specific tenants within an organization
35
+
36
+ ### Key Features
37
+
38
+ - ✅ **Multi-Provider Support**: Keycloak (managed/self-hosted) and Auth0
39
+ - ✅ **Realm Management**: Create and configure Keycloak realms
40
+ - ✅ **Client Configuration**: Manage OAuth2/OIDC clients with redirect URIs
41
+ - ✅ **Identity Provider Integration**: Configure social login providers (Google, GitHub, etc.)
42
+ - ✅ **Credential Testing**: Test authentication provider credentials before saving
43
+ - ✅ **Secret Management**: Secure storage of admin credentials and client secrets
44
+ - ✅ **Environment-Based Configuration**: Associate providers with environment tags
45
+ - ✅ **State Machine Management**: Predictable state transitions using XState
46
+
47
+ ---
48
+
49
+ ## How to Execute the Functionality
50
+
51
+ ### Accessing the Auth Provider Management
52
+
53
+ 1. **Navigate to the Route**: Access via organization route with `orgName` parameter
54
+ 2. **Prerequisites**:
55
+ - User must be authenticated
56
+ - User must have appropriate permissions for the organization
57
+ - At least one tenant must exist in the organization
58
+
59
+ ### Creating a New Auth Provider
60
+
61
+ 1. **Click "Create New Auth Provider" Button**: Located in the header
62
+ 2. **Select Tenant**: Choose a tenant from the modal (only tenants without existing providers are recommended)
63
+ 3. **Choose Provider Type**: Select Keycloak or Auth0
64
+ 4. **Configure Settings**:
65
+ - **Keycloak**: Realm name, redirect URIs, signup settings, identity providers
66
+ - **Auth0**: Domain, client ID, client secret, redirect URI
67
+ 5. **Test Credentials** (Optional): Click "Test" to verify configuration
68
+ 6. **Submit**: Click "Save" to create the provider
69
+ 7. **Result**: Provider is created, modal closes, list refreshes
70
+
71
+ ### Viewing Auth Provider Details
72
+
73
+ 1. **Expand Provider**: Click on any provider card to expand and view details
74
+ 2. **View Configuration**: See realm name, client ID, domain, and other settings
75
+ 3. **View Identity Providers**: See configured social login providers (for Keycloak)
76
+
77
+ ### Editing an Auth Provider
78
+
79
+ 1. **Click "Edit" Button**: Located in the action buttons for each provider
80
+ 2. **Modify Settings**: Update realm name, redirect URIs, identity providers, etc.
81
+ 3. **Test Credentials** (Optional): Verify changes work
82
+ 4. **Submit**: Click "Save" to update
83
+ 5. **Result**: Provider is updated, modal closes, list refreshes
84
+
85
+ ### Testing Credentials
86
+
87
+ 1. **Click "Test" Button**: Located in the action buttons
88
+ 2. **Wait for Result**: System attempts to obtain OAuth2 token
89
+ 3. **View Result**: Success or error message displayed inline
90
+ 4. **Interpret Results**:
91
+ - **Success**: Green notification with token details
92
+ - **Failure**: Red notification with error details
93
+
94
+ ### Viewing Configuration Details
95
+
96
+ 1. **Click "Configuration" Button**: Opens modal with saved configuration
97
+ 2. **View Secrets**: See Realm Name, Client ID, Client Secret, Keycloak URL
98
+ 3. **Copy to Clipboard**: Click 📋 button to copy any field
99
+
100
+ ### Deleting an Auth Provider
101
+
102
+ 1. **Click "Delete" Button**: Located in the action buttons
103
+ 2. **Confirm**: Confirm deletion in the modal
104
+ 3. **Result**: Provider is deleted, Keycloak realm removed (if managed), secrets cleaned up
105
+
106
+ ---
107
+
108
+ ## Implementation Details
109
+
110
+ ### Component Hierarchy
111
+
112
+ ```
113
+ AuthProvidersManagement (Main Container)
114
+ ├── Auth Providers List (Collapsible Cards)
115
+ │ ├── Provider Header (Expandable)
116
+ │ ├── Provider Details (Expanded View)
117
+ │ └── Action Buttons (Edit, Test, Delete, Configuration)
118
+ ├── Tenant Selection Modal
119
+ │ └── Tenant List with Provider Status
120
+ ├── Create Auth Provider Modal
121
+ │ └── AuthProvidersComponent
122
+ │ ├── Tenant Selector (if not hidden)
123
+ │ ├── Provider Type Selector
124
+ │ ├── KeycloakBasicConfigForm
125
+ │ ├── KeycloakIdentityProvidersForm
126
+ │ └── Auth0Form
127
+ ├── Edit Auth Provider Modal
128
+ │ └── AuthProvidersComponent (pre-populated)
129
+ └── Configuration Modal (View Saved Details)
130
+ ```
131
+
132
+ ### Key Components
133
+
134
+ #### 1. AuthProvidersManagement (`AuthProvidersManagement.tsx`)
135
+
136
+ **Purpose**: Main orchestrator component for auth provider management.
137
+
138
+ **Responsibilities**:
139
+
140
+ - Organization context management
141
+ - Tenant list loading
142
+ - Auth provider list management
143
+ - Modal state management
144
+ - Credential testing orchestration
145
+
146
+ **Key Features**:
147
+
148
+ - Fetches tenants to determine organization ID
149
+ - Loads auth providers by organization ID
150
+ - Manages multiple modals (create, edit, config, tenant selection)
151
+ - Handles credential testing with inline results
152
+ - Provides collapsible provider cards
153
+
154
+ **State Management**:
155
+
156
+ ```typescript
157
+ const [showCreateModal, setShowCreateModal] = useState(false);
158
+ const [showEditModal, setShowEditModal] = useState(false);
159
+ const [showConfigModal, setShowConfigModal] = useState(false);
160
+ const [showTenantSelection, setShowTenantSelection] = useState(false);
161
+ const [expandedProviderId, setExpandedProviderId] = useState<string | null>(null);
162
+ const [testingCredentials, setTestingCredentials] = useState<string | null>(null);
163
+ ```
164
+
165
+ #### 2. AuthProvidersComponent (`AuthProvidersComponent.tsx`)
166
+
167
+ **Purpose**: Reusable form component for creating and editing auth providers.
168
+
169
+ **Features**:
170
+
171
+ - Multi-step form with XState machine
172
+ - Provider type selection (Keycloak/Auth0)
173
+ - Tenant selection (optional, can be hidden)
174
+ - Dynamic form steps based on provider type
175
+ - Pre-population for edit mode
176
+
177
+ **Form Steps**:
178
+
179
+ 1. **Tenant Selection** (if not hidden)
180
+ 2. **Provider Type Selection**
181
+ 3. **Basic Configuration** (Keycloak realm/Auth0 domain)
182
+ 4. **Identity Providers** (Keycloak only)
183
+ 5. **Review & Submit**
184
+
185
+ **Key Behaviors**:
186
+
187
+ - Auto-loads existing config when `tenantId` prop is provided
188
+ - Validates required fields before submission
189
+ - Handles both create and update operations
190
+ - Integrates with XState machine for state management
191
+
192
+ #### 3. KeycloakBasicConfigForm (`KeycloakBasicConfigForm.tsx`)
193
+
194
+ **Purpose**: Form for Keycloak basic configuration.
195
+
196
+ **Fields**:
197
+
198
+ - Realm Name (required)
199
+ - Redirect URIs (required, array)
200
+ - Allowed New Users (checkbox)
201
+ - Confirm Email (checkbox)
202
+ - Self-Hosted toggle
203
+ - Self-Hosted Config (domain, admin credentials) - if self-hosted
204
+
205
+ **Validation**:
206
+
207
+ - Realm name must be unique
208
+ - At least one redirect URI required
209
+ - Self-hosted requires domain and admin credentials
210
+
211
+ #### 4. KeycloakIdentityProvidersForm (`KeycloakIdentityProvidersForm.tsx`)
212
+
213
+ **Purpose**: Form for configuring social identity providers.
214
+
215
+ **Supported Providers**:
216
+
217
+ - Google
218
+ - GitHub
219
+ - Facebook
220
+ - Microsoft
221
+ - And more...
222
+
223
+ **Configuration per Provider**:
224
+
225
+ - Client ID
226
+ - Client Secret
227
+ - Enabled/Disabled toggle
228
+
229
+ #### 5. Auth0Form (`Auth0Authentication.tsx`)
230
+
231
+ **Purpose**: Form for Auth0 configuration.
232
+
233
+ **Fields**:
234
+
235
+ - Auth0 Domain (required)
236
+ - Client ID (required)
237
+ - Client Secret (required)
238
+ - Redirect URI (required)
239
+ - Auth0 URL (auto-generated)
240
+
241
+ ---
242
+
243
+ ## State Management
244
+
245
+ ### XState Machine (`authProvidersMachine.ts`)
246
+
247
+ The auth provider management uses XState for multi-step form state management.
248
+
249
+ #### Machine Context
250
+
251
+ ```typescript
252
+ interface AuthProviderMachineContext {
253
+ tenant?: ITenant;
254
+ providerType?: AuthProviderName;
255
+ keycloakConfig?: IKeycloakConfig;
256
+ auth0Config?: IAuth0Config;
257
+ currentStep: StepType;
258
+ hideTenantSelector: boolean;
259
+ authProviderConfig?: IAuthProvider;
260
+ }
261
+ ```
262
+
263
+ #### Machine States
264
+
265
+ 1. **tenantSelection**: Selecting tenant (if not hidden)
266
+ 2. **providerSelection**: Choosing provider type
267
+ 3. **keycloakBasicConfig**: Keycloak basic settings
268
+ 4. **keycloakIdentityProviders**: Keycloak social providers
269
+ 5. **auth0Config**: Auth0 configuration
270
+ 6. **review**: Review before submission
271
+
272
+ #### Key Events
273
+
274
+ - `SET_TENANT`: Set selected tenant
275
+ - `SET_PROVIDER_TYPE`: Set provider type (Keycloak/Auth0)
276
+ - `SET_KEYCLOAK_CONFIG`: Update Keycloak configuration
277
+ - `SET_AUTH0_CONFIG`: Update Auth0 configuration
278
+ - `NEXT_STEP`: Move to next step
279
+ - `PREVIOUS_STEP`: Move to previous step
280
+ - `SET_AUTH_PROVIDER_CONFIG`: Load existing config for editing
281
+ - `SET_HIDE_TENANT_SELECTOR`: Hide tenant selector
282
+
283
+ ---
284
+
285
+ ## GraphQL Integration
286
+
287
+ ### Queries
288
+
289
+ #### FetchAuthProvidersByOrganizationId
290
+
291
+ ```graphql
292
+ query FetchAuthProvidersByOrganizationId($organizationId: ID!) {
293
+ fetchAuthProvidersByOrganizationId(organizationId: $organizationId) {
294
+ id
295
+ provider
296
+ tenant {
297
+ id
298
+ tenantId
299
+ }
300
+ keycloak {
301
+ realmName
302
+ clientId
303
+ redirectUris
304
+ identityProviders {
305
+ key
306
+ enabled
307
+ }
308
+ selfHosted
309
+ selfHostedConfig {
310
+ domain
311
+ }
312
+ }
313
+ auth0 {
314
+ auth0Domain
315
+ clientId
316
+ auth0Url
317
+ }
318
+ environmentTag {
319
+ id
320
+ name
321
+ }
322
+ }
323
+ }
324
+ ```
325
+
326
+ #### FetchAuthProviderByTenantId
327
+
328
+ ```graphql
329
+ query FetchAuthProviderByTenantId($tenantId: ID!) {
330
+ fetchAuthProviderByTenantId(tenantId: $tenantId) {
331
+ ...AuthProviderFragment
332
+ }
333
+ }
334
+ ```
335
+
336
+ ### Mutations
337
+
338
+ #### CreateAuthProvider
339
+
340
+ ```graphql
341
+ mutation CreateAuthProvider($input: AuthProviderInput!) {
342
+ createAuthProvider(input: $input) {
343
+ ...AuthProviderFragment
344
+ }
345
+ }
346
+ ```
347
+
348
+ **Input Structure**:
349
+
350
+ ```typescript
351
+ {
352
+ tenant: string; // tenantId (UUID string)
353
+ environmentTag: string; // Environment tag ID
354
+ project: string; // Project ID
355
+ organization?: string; // Organization ID (optional)
356
+ provider: AuthProviderName; // 'keycloak' or 'auth0'
357
+ keycloak?: {
358
+ realmName: string;
359
+ redirectUris: string[];
360
+ allowedNewUsers: boolean;
361
+ confirmEmail: boolean;
362
+ identityProviders?: Array<{
363
+ key: string;
364
+ clientId: string;
365
+ clientSecret: string;
366
+ enabled: boolean;
367
+ }>;
368
+ selfHosted: boolean;
369
+ selfHostedConfig?: {
370
+ domain: string;
371
+ adminUsername: string;
372
+ adminPassword: string;
373
+ realmName: string;
374
+ adminClientId: string;
375
+ clientSecret: string;
376
+ };
377
+ authFlow: AuthFlow; // 'pkce' or 'implicit'
378
+ };
379
+ auth0?: {
380
+ clientId: string;
381
+ clientSecret: string;
382
+ redirectUri: string;
383
+ auth0Url: string;
384
+ auth0Domain: string;
385
+ };
386
+ }
387
+ ```
388
+
389
+ #### UpdateAuthProvider
390
+
391
+ ```graphql
392
+ mutation UpdateAuthProvider($id: ID!, $input: AuthProviderInput!) {
393
+ updateAuthProvider(id: $id, input: $input) {
394
+ ...AuthProviderFragment
395
+ }
396
+ }
397
+ ```
398
+
399
+ #### DeleteAuthProvider
400
+
401
+ ```graphql
402
+ mutation DeleteAuthProvider($id: ID!) {
403
+ deleteAuthProvider(id: $id)
404
+ }
405
+ ```
406
+
407
+ #### TestAuthProviderCredentials
408
+
409
+ ```graphql
410
+ mutation TestAuthProviderCredentials($authProviderId: ID!) {
411
+ testAuthProviderCredentials(authProviderId: $authProviderId) {
412
+ success
413
+ message
414
+ details
415
+ }
416
+ }
417
+ ```
418
+
419
+ ### Apollo Client Configuration
420
+
421
+ - **Fetch Policy**: `network-only` for queries (always fetch fresh data)
422
+ - **Refetch Queries**: Automatic refetch after mutations
423
+ - **Error Handling**: Centralized via `onError` callbacks
424
+
425
+ ---
426
+
427
+ ## Backend Architecture & Inngest Integration
428
+
429
+ ### Overview
430
+
431
+ The Auth Provider Management System uses an **event-driven architecture** with **Inngest** for asynchronous Keycloak configuration. The backend service handles immediate database operations and secret storage, while Inngest functions handle Keycloak realm/client creation and configuration.
432
+
433
+ ### Architecture Pattern
434
+
435
+ 1. **Service Layer** (`AuthProviderService`): Handles database operations and triggers Inngest events
436
+ 2. **Inngest Functions**: Handle Keycloak API operations (realm creation, client configuration, identity providers)
437
+ 3. **Secret Management**: Environment service stores sensitive credentials securely
438
+
439
+ ### Backend Service Layer
440
+
441
+ #### AuthProviderService (`AuthProviderService.ts`)
442
+
443
+ **Purpose**: Core service for auth provider CRUD operations.
444
+
445
+ **Key Methods**:
446
+
447
+ ##### `createAuthProvider(input: IAuthProviderInput)`
448
+
449
+ **Flow**:
450
+
451
+ 1. Resolves tenant ID using `defaultTenantIdMapper`
452
+ 2. Finds tenant by `tenantId` to get MongoDB `id`
453
+ 3. Generates unique `clientId` and `clientSecret` for Keycloak
454
+ 4. Stores secrets in environment service (for self-hosted Keycloak or Auth0)
455
+ 5. Creates auth provider record in MongoDB
456
+ 6. **Triggers Inngest Event**: `AUTH_MGMT_CONFIGURE_KEYCLOAK_SETTINGS_EVENT` (for Keycloak only)
457
+ - **Condition**: Only triggers if `input.provider === AuthProviderName.Keycloak`
458
+ - **Event Sending**:
459
+ ```typescript
460
+ await this.inngestClient.send({
461
+ name: WorkflowNamespace.AUTH_MGMT_CONFIGURE_KEYCLOAK_SETTINGS_EVENT,
462
+ data: updatedInput, // Full IAuthProviderInput with generated clientId/clientSecret
463
+ });
464
+ ```
465
+ - **Timing**: Event is sent **after** database record is created
466
+ - **Non-blocking**: Service doesn't wait for Inngest function to complete
467
+ 7. Returns created auth provider immediately
468
+
469
+ **Inngest Event Payload**:
470
+
471
+ ```typescript
472
+ {
473
+ name: 'auth-mgmt/configure-keycloak-settings-trigger',
474
+ data: {
475
+ tenant: string, // tenantId (UUID)
476
+ provider: 'keycloak',
477
+ keycloak: {
478
+ realmName: string,
479
+ clientId: string, // Generated unique ID
480
+ clientSecret: string, // Generated unique secret
481
+ redirectUris: string[],
482
+ allowedNewUsers: boolean,
483
+ confirmEmail: boolean,
484
+ identityProviders: Array<{
485
+ key: string,
486
+ clientId: string,
487
+ clientSecret: string,
488
+ enabled: boolean
489
+ }>,
490
+ selfHosted: boolean,
491
+ selfHostedConfig?: { ... },
492
+ authFlow: 'pkce' | 'implicit'
493
+ },
494
+ environmentTag: string,
495
+ project: string,
496
+ organization?: string
497
+ }
498
+ }
499
+ ```
500
+
501
+ **Important**:
502
+
503
+ - Auth0 providers **do not** trigger Inngest events (no Keycloak configuration needed)
504
+ - Event is queued by Inngest and processed asynchronously
505
+ - Service method returns immediately, Keycloak configuration happens in background
506
+
507
+ ##### `updateAuthProvider(id: string, input: IAuthProviderInput)`
508
+
509
+ **Flow**:
510
+
511
+ 1. Finds existing auth provider
512
+ 2. Resolves tenant ID and finds tenant
513
+ 3. Updates secrets in environment service (if changed)
514
+ 4. **Detects Auth Flow Change**:
515
+ - Compares existing `authFlow` with new `authFlow`
516
+ - Sets `flowChanged` flag if different
517
+ - Stores `previousAuthFlow` for reference
518
+ 5. Updates auth provider record in MongoDB
519
+ 6. **Triggers Inngest Event**: `AUTH_MGMT_UPDATE_KEYCLOAK_SETTINGS_EVENT` (for Keycloak only)
520
+ - **Condition**: Only triggers if `input.provider === AuthProviderName.Keycloak`
521
+ - **Event Sending**:
522
+ ```typescript
523
+ await this.inngestClient.send({
524
+ name: WorkflowNamespace.AUTH_MGMT_UPDATE_KEYCLOAK_SETTINGS_EVENT,
525
+ data: {
526
+ ...existingAuthProvider,
527
+ ...input,
528
+ flowChanged: boolean,
529
+ previousAuthFlow: AuthFlow,
530
+ },
531
+ });
532
+ ```
533
+ - **Timing**: Event is sent **after** database record is updated
534
+ - **Non-blocking**: Service doesn't wait for Inngest function to complete
535
+ 7. Returns updated auth provider immediately
536
+
537
+ **Inngest Event Payload**:
538
+
539
+ ```typescript
540
+ {
541
+ name: 'auth-mgmt/update-keycloak-settings-trigger',
542
+ data: {
543
+ // Existing auth provider fields
544
+ id: string,
545
+ tenant: string,
546
+ provider: 'keycloak',
547
+ keycloak: {
548
+ // Merged: existing + new values
549
+ realmName: string,
550
+ clientId: string,
551
+ clientSecret: string,
552
+ redirectUris: string[],
553
+ allowedNewUsers: boolean,
554
+ confirmEmail: boolean,
555
+ identityProviders: Array<{ ... }>,
556
+ selfHosted: boolean,
557
+ selfHostedConfig?: { ... },
558
+ authFlow: 'pkce' | 'implicit' // New auth flow
559
+ },
560
+ // Additional metadata
561
+ flowChanged: boolean, // true if auth flow changed
562
+ previousAuthFlow: 'pkce' | 'implicit' // Previous flow value
563
+ }
564
+ }
565
+ ```
566
+
567
+ **Important**:
568
+
569
+ - `flowChanged` flag determines if client needs to be deleted/recreated
570
+ - Event contains merged data (existing + new values)
571
+ - Inngest function uses this to determine which steps to execute
572
+
573
+ ##### `deleteAuthProvider(id: string)`
574
+
575
+ **Flow**:
576
+
577
+ 1. Finds auth provider
578
+ 2. **For Managed Keycloak**: Deletes realm via `KeycloakInternalAdminService`
579
+ 3. Deletes secrets from environment service
580
+ 4. Deletes auth provider record from MongoDB
581
+ 5. Returns success boolean
582
+
583
+ **Note**: Self-hosted Keycloak realms are not deleted (user manages them).
584
+
585
+ ##### `getAuthProviderByTenantId(tenantId: string)`
586
+
587
+ **Flow**:
588
+
589
+ 1. Resolves tenant ID and finds tenant
590
+ 2. Finds auth provider by tenant MongoDB `id`
591
+ 3. Fetches secrets from environment service
592
+ 4. **For Keycloak**: Fetches identity providers and client secret from Keycloak API
593
+ 5. Formats response with all secrets merged
594
+ 6. Returns formatted auth provider
595
+
596
+ **Secret Fetching**:
597
+
598
+ - Self-hosted Keycloak: Uses `KeycloakTenantAdminService` with admin credentials
599
+ - Managed Keycloak: Uses `KeycloakInternalAdminService`
600
+ - Auth0: Fetches from environment service
601
+
602
+ ##### `testAuthProviderCredentials(authProviderId: string)`
603
+
604
+ **Purpose**: Tests authentication provider credentials by attempting OAuth2 token exchange.
605
+
606
+ **Flow for Keycloak**:
607
+
608
+ 1. Fetches auth provider
609
+ 2. Determines Keycloak URL (managed vs self-hosted)
610
+ 3. Fetches client secret from Keycloak API
611
+ 4. Calls token endpoint: `POST /realms/{realm}/protocol/openid-connect/token`
612
+ 5. Uses `client_credentials` grant type
613
+ 6. Returns success/failure with details
614
+
615
+ **Flow for Auth0**:
616
+
617
+ 1. Fetches auth provider
618
+ 2. Fetches client secret from environment service
619
+ 3. Calls token endpoint: `POST https://{domain}/oauth/token`
620
+ 4. Uses `client_credentials` grant type with audience
621
+ 5. Returns success/failure with details
622
+
623
+ #### Secret Management
624
+
625
+ **Environment Service Integration**:
626
+
627
+ Secrets are stored in environment service with keys:
628
+
629
+ - `KeycloakAdminUsername`: Admin username (self-hosted)
630
+ - `KeycloakAdminPassword`: Admin password (self-hosted)
631
+ - `KeycloakAdminClientSecret`: Admin client secret (self-hosted)
632
+ - `Auth0ClientSecret`: Auth0 client secret
633
+
634
+ **Secret Keys Structure**:
635
+
636
+ ```typescript
637
+ {
638
+ tenantId: string; // MongoDB ObjectId
639
+ environmentTag: string; // Environment tag ID
640
+ projectId: string; // Project ID
641
+ }
642
+ ```
643
+
644
+ ### Inngest Event-Driven Workflow
645
+
646
+ #### Overview
647
+
648
+ Inngest handles all asynchronous Keycloak API operations. When an auth provider is created or updated, the service immediately returns success to the frontend, while Inngest processes the Keycloak configuration in the background. This ensures fast user experience while handling potentially slow Keycloak API calls.
649
+
650
+ #### Event Namespace
651
+
652
+ **Trigger Events** (what functions listen for):
653
+
654
+ - `AUTH_MGMT_CONFIGURE_KEYCLOAK_SETTINGS_EVENT`: Configure new Keycloak provider
655
+ - `AUTH_MGMT_UPDATE_KEYCLOAK_SETTINGS_EVENT`: Update existing Keycloak provider
656
+
657
+ **Function IDs**:
658
+
659
+ - `AUTH_MGMT_CONFIGURE_KEYCLOAK_SETTINGS`: Function for initial configuration
660
+ - `AUTH_MGMT_UPDATE_KEYCLOAK_SETTINGS`: Function for updates
661
+
662
+ **Event Payload Structure**:
663
+
664
+ ```typescript
665
+ // For CREATE
666
+ {
667
+ name: 'auth-mgmt/configure-keycloak-settings-trigger',
668
+ data: IAuthProviderInput {
669
+ tenant: string,
670
+ provider: 'keycloak',
671
+ keycloak: {
672
+ realmName: string,
673
+ clientId: string,
674
+ clientSecret: string,
675
+ redirectUris: string[],
676
+ allowedNewUsers: boolean,
677
+ confirmEmail: boolean,
678
+ identityProviders: Array<{
679
+ key: string, // 'google', 'github', etc.
680
+ clientId: string,
681
+ clientSecret: string,
682
+ enabled: boolean
683
+ }>,
684
+ selfHosted: boolean,
685
+ selfHostedConfig?: {
686
+ domain: string,
687
+ adminUsername: string,
688
+ adminPassword: string,
689
+ realmName: string,
690
+ adminClientId: string,
691
+ clientSecret: string
692
+ },
693
+ authFlow: 'pkce' | 'implicit'
694
+ }
695
+ }
696
+ }
697
+
698
+ // For UPDATE
699
+ {
700
+ name: 'auth-mgmt/update-keycloak-settings-trigger',
701
+ data: IAuthProviderInput & {
702
+ flowChanged?: boolean,
703
+ previousAuthFlow?: AuthFlow
704
+ }
705
+ }
706
+ ```
707
+
708
+ #### Inngest Functions
709
+
710
+ ##### 1. `configureKeycloakAuthSettingFunction`
711
+
712
+ **Purpose**: Creates Keycloak realm and client for new auth provider.
713
+
714
+ **Trigger**: `AUTH_MGMT_CONFIGURE_KEYCLOAK_SETTINGS_EVENT`
715
+
716
+ **Function Registration**:
717
+
718
+ ```typescript
719
+ inngest.createFunction(
720
+ { id: 'auth-mgmt-configure-keycloak-settings' },
721
+ { event: 'auth-mgmt/configure-keycloak-settings-trigger' },
722
+ async ({ event, step }) => { ... }
723
+ )
724
+ ```
725
+
726
+ **Detailed Workflow Steps**:
727
+
728
+ 1. **Data Extraction & Preparation**
729
+ - Extracts `keycloakConfiguration` from event data
730
+ - Parses realm name, client ID, client secret, redirect URIs
731
+ - Extracts identity providers array
732
+ - Determines if self-hosted or managed
733
+
734
+ 2. **Web Origins Extraction** (Before any Keycloak calls)
735
+ - Iterates through `redirectUris` array
736
+ - For each redirect URI:
737
+ - Parses URL using `new URL(redirectUri)`
738
+ - Extracts `origin` (protocol + domain + port)
739
+ - Adds to `webOrigins` array (deduplicated)
740
+ - **Purpose**: Web origins are required for CORS configuration in Keycloak
741
+ - **Example**: `https://example.com/callback` → `https://example.com`
742
+
743
+ 3. **Step: `create-realm-and-client`** (Managed Keycloak only)
744
+ - **Condition**: Only executes if `selfHosted === false`
745
+ - **Operation**: Calls `KeycloakInternalAdminService.Instance.createRealmAndClient()`
746
+ - **Parameters**:
747
+ ```typescript
748
+ {
749
+ realm: realmName, // Realm name
750
+ clientId: clientId, // Generated client ID
751
+ clientSecret: clientSecret, // Generated client secret
752
+ redirectUris: redirectUris || [], // Array of redirect URIs
753
+ webOrigins: webOrigins, // Extracted web origins
754
+ signupSetting: {
755
+ allowNewUsers: allowedNewUsers, // Boolean
756
+ confirmEmail: confirmEmail // Boolean
757
+ },
758
+ authFlow: authFlow || AuthFlow.Pkce // 'pkce' or 'implicit'
759
+ }
760
+ ```
761
+ - **What Happens**:
762
+ - Creates new Keycloak realm with specified name
763
+ - Creates OAuth2/OIDC client within the realm
764
+ - Configures client with redirect URIs and web origins
765
+ - Sets up signup settings (user registration, email confirmation)
766
+ - Configures authentication flow (PKCE or Implicit)
767
+ - Assigns realm management roles to the client
768
+ - **Error Handling**: If this step fails, entire function fails (realm creation is critical)
769
+
770
+ 4. **Step: `configure-identity-providers`** (Both managed and self-hosted)
771
+ - **Condition**: Executes if `identityProviders?.length > 0`
772
+ - **Process**: Iterates through each identity provider in the array
773
+ - **For Each Provider**:
774
+ - **Managed Keycloak**:
775
+ - Uses `KeycloakInternalAdminService.Instance.configureIdentityProviderInternal()`
776
+ - **Parameters**:
777
+ ```typescript
778
+ {
779
+ realm: realmName,
780
+ idpAlias: provider.key, // 'google', 'github', etc.
781
+ providerId: provider.key, // Same as alias
782
+ enabled: provider.enabled, // Boolean
783
+ identityProvidersConfig: {
784
+ clientId: provider.clientId,
785
+ clientSecret: provider.clientSecret
786
+ }
787
+ }
788
+ ```
789
+ - **Self-Hosted Keycloak**:
790
+ - Creates `KeycloakTenantAdminService` instance from self-hosted config
791
+ - Uses admin credentials from `selfHostedConfig`
792
+ - Calls `configureIdentityProvider()` with same parameters
793
+ - **Service Creation**:
794
+ ```typescript
795
+ KeycloakTenantAdminService.fromSelfHostedConfig({
796
+ domain: selfHostedConfig.domain,
797
+ adminClientId: selfHostedConfig.adminClientId,
798
+ adminUsername: selfHostedConfig.adminUsername,
799
+ adminPassword: selfHostedConfig.adminPassword,
800
+ realmName: selfHostedConfig.realmName,
801
+ clientSecret: selfHostedConfig.clientSecret,
802
+ });
803
+ ```
804
+ - **Error Handling**:
805
+ - Individual provider failures are **logged but don't stop the process**
806
+ - Each provider is processed independently
807
+ - Errors logged as: `❌ Failed to process provider {key}: {error}`
808
+ - Success logged as: `✅ Provider processed: {key} (enabled: {enabled})`
809
+ - **Result**: All enabled identity providers are configured in Keycloak
810
+
811
+ **Return Value**:
812
+
813
+ ```typescript
814
+ { status: 'success', realm: realmName }
815
+ ```
816
+
817
+ **Important Notes**:
818
+
819
+ - Self-hosted Keycloak **skips** realm/client creation (assumes realm exists)
820
+ - Identity provider configuration happens for both managed and self-hosted
821
+ - Web origins are automatically derived from redirect URIs
822
+ - Individual identity provider failures don't fail the entire operation
823
+
824
+ ##### 2. `updateKeycloakAuthSettingFunction`
825
+
826
+ **Purpose**: Updates existing Keycloak configuration.
827
+
828
+ **Trigger**: `AUTH_MGMT_UPDATE_KEYCLOAK_SETTINGS_EVENT`
829
+
830
+ **Function Registration**:
831
+
832
+ ```typescript
833
+ inngest.createFunction(
834
+ { id: 'auth-mgmt-update-keycloak-settings' },
835
+ { event: 'auth-mgmt/update-keycloak-settings-trigger' },
836
+ async ({ event, step }) => { ... }
837
+ )
838
+ ```
839
+
840
+ **Detailed Workflow Steps**:
841
+
842
+ 1. **Data Extraction & Preparation**
843
+ - Extracts `keycloakConfiguration` from event data
844
+ - Checks `flowChanged` flag (indicates if auth flow changed)
845
+ - Extracts `previousAuthFlow` if available
846
+ - Determines new auth flow: `authFlow || AuthFlow.Pkce`
847
+
848
+ 2. **Web Origins Extraction** (Same as configure function)
849
+ - Extracts web origins from redirect URIs
850
+ - Used for client updates
851
+
852
+ 3. **Service Instance Creation** (Self-hosted only)
853
+ - If `selfHosted === true`:
854
+ - Creates `KeycloakTenantAdminService` instance
855
+ - Uses credentials from `selfHostedConfig`
856
+ - Instance used for all self-hosted operations
857
+
858
+ 4. **Step: `update-realm-settings`** (Conditional)
859
+ - **Condition**: Executes if signup settings have non-null values
860
+ - **Signup Settings**:
861
+ ```typescript
862
+ {
863
+ allowNewUsers: allowedNewUsers, // Boolean or null
864
+ confirmEmail: confirmEmail // Boolean or null
865
+ }
866
+ ```
867
+ - **Managed Keycloak**:
868
+ - Calls `KeycloakInternalAdminService.Instance.updateRealmSettings()`
869
+ - **Parameters**: `{ realm: realmName, signupSettings }`
870
+ - **Self-Hosted Keycloak**:
871
+ - Calls `KeycloakTenantAdminServiceInstance.updateRealmSettings()`
872
+ - **Parameters**: `{ realm: selfHostedConfig.realmName, signupSettings }`
873
+ - **What Happens**: Updates realm-level settings for user registration and email confirmation
874
+ - **Error Handling**: Throws error if update fails (critical operation)
875
+
876
+ 5. **Step: `delete-and-recreate-client`** (Conditional - Auth Flow Changed)
877
+ - **Condition**: Executes if:
878
+ - `authFlowChanged === true`
879
+ - `selfHosted === false` (only for managed Keycloak)
880
+ - `clientId` exists
881
+ - **Why**: Auth flow (PKCE vs Implicit) requires different client configuration. Cannot be changed on existing client.
882
+ - **Process**:
883
+ 1. **Delete Existing Client**:
884
+ - Calls `KeycloakInternalAdminService.Instance.deleteClientInternal(realmName, clientId)`
885
+ - Removes old client with old flow configuration
886
+ 2. **Create New Client**:
887
+ - Calls `KeycloakInternalAdminService.Instance.createClientAndAssignRealmManagementRoles()`
888
+ - **Parameters**:
889
+ ```typescript
890
+ {
891
+ realm: realmName,
892
+ clientId: clientId, // Same client ID
893
+ clientSecret: clientSecret, // Same client secret
894
+ redirectUris: redirectUris || [],
895
+ webOrigins: webOrigins,
896
+ authFlow: newAuthFlow // New flow (PKCE or Implicit)
897
+ }
898
+ ```
899
+ - Creates new client with new flow configuration
900
+ - Assigns realm management roles
901
+ - **Error Handling**: Throws error if deletion or creation fails
902
+
903
+ 6. **Step: `update-client-settings`** (Conditional - Auth Flow Unchanged)
904
+ - **Condition**: Executes if:
905
+ - `authFlowChanged === false` (flow didn't change)
906
+ - `redirectUris?.length > 0 || webOrigins.length > 0` (has redirect URIs)
907
+ - `clientId` exists
908
+ - `selfHosted === false` (only for managed Keycloak)
909
+ - **Operation**: Calls `KeycloakInternalAdminService.Instance.updateClientInternal()`
910
+ - **Parameters**:
911
+ ```typescript
912
+ {
913
+ realm: realmName,
914
+ clientId: clientId,
915
+ redirectUris: redirectUris || [],
916
+ webOrigins: webOrigins
917
+ }
918
+ ```
919
+ - **What Happens**: Updates existing client's redirect URIs and web origins
920
+ - **Error Handling**: Throws error if update fails
921
+
922
+ 7. **Step: `configure-identity-providers`** (Always executes if providers exist)
923
+ - **Process**: Iterates through `identityProviders` array
924
+ - **For Each Provider**:
925
+ - **Managed Keycloak**:
926
+ - Uses `KeycloakInternalAdminService.Instance.configureIdentityProviderInternal()`
927
+ - Updates or creates identity provider configuration
928
+ - **Self-Hosted Keycloak**:
929
+ - Uses `KeycloakTenantAdminServiceInstance.configureIdentityProviderInternal()`
930
+ - Updates or creates identity provider configuration
931
+ - **Parameters** (same as configure function):
932
+ ```typescript
933
+ {
934
+ realm: realmName,
935
+ idpAlias: provider.key,
936
+ providerId: provider.key,
937
+ enabled: provider.enabled,
938
+ identityProvidersConfig: {
939
+ clientId: provider.clientId,
940
+ clientSecret: provider.clientSecret
941
+ }
942
+ }
943
+ ```
944
+ - **Error Handling**:
945
+ - **Important**: Unlike configure function, errors here **throw and stop the process**
946
+ - Each provider error throws: `new Error('Failed to process provider', err)`
947
+ - This ensures all identity providers are successfully updated
948
+
949
+ **Return Value**:
950
+
951
+ ```typescript
952
+ { status: 'success', realm: realmName }
953
+ ```
954
+
955
+ **Important Notes**:
956
+
957
+ - Auth flow changes require client deletion and recreation (cannot be updated in place)
958
+ - Self-hosted Keycloak skips client operations (user manages clients)
959
+ - Identity provider updates are atomic (all must succeed)
960
+ - Realm settings update is optional (only if values provided)
961
+
962
+ #### Inngest Function Registration
963
+
964
+ **Location**: `packages-modules/user-auth0/server/src/modules/user-auth/inngest/functions.ts`
965
+
966
+ **Registration**:
967
+
968
+ ```typescript
969
+ export const inngestFunctionsFactory = (args: { container: Container; inngest: Inngest }) => [
970
+ configureKeycloakAuthSettingFunction(args.inngest),
971
+ updateKeycloakAuthSettingFunction(args.inngest),
972
+ // ... other functions
973
+ ];
974
+ ```
975
+
976
+ **When Functions Execute**:
977
+
978
+ - Functions are registered at server startup
979
+ - Inngest listens for events matching the function's event pattern
980
+ - When service sends event, Inngest queues the function execution
981
+ - Functions execute asynchronously in background
982
+
983
+ #### Error Handling in Inngest Functions
984
+
985
+ **Configure Function**:
986
+
987
+ - Realm/client creation failure: **Function fails** (critical)
988
+ - Identity provider failure: **Logged, continues** (non-critical)
989
+
990
+ **Update Function**:
991
+
992
+ - Realm settings failure: **Function fails** (critical)
993
+ - Client deletion/recreation failure: **Function fails** (critical)
994
+ - Client update failure: **Function fails** (critical)
995
+ - Identity provider failure: **Function fails** (all must succeed)
996
+
997
+ **Retry Behavior**:
998
+
999
+ - Inngest automatically retries failed functions
1000
+ - Retry strategy: Exponential backoff
1001
+ - Maximum retries: Configurable in Inngest dashboard
1002
+
1003
+ #### Performance Considerations
1004
+
1005
+ **Async Processing**:
1006
+
1007
+ - Service methods return immediately after triggering Inngest events
1008
+ - Keycloak API operations happen asynchronously
1009
+ - Frontend doesn't wait for Keycloak configuration to complete
1010
+
1011
+ **Step Isolation**:
1012
+
1013
+ - Each `step.run()` is isolated and can be retried independently
1014
+ - Inngest tracks step execution state
1015
+ - Failed steps can be retried without re-running successful steps
1016
+
1017
+ **Idempotency**:
1018
+
1019
+ - Functions are designed to be safely retried
1020
+ - Identity provider configuration is idempotent (can be called multiple times)
1021
+ - Client creation checks for existing client before creating
1022
+
1023
+ ### Complete Data Flow
1024
+
1025
+ #### Creating an Auth Provider
1026
+
1027
+ ```
1028
+ 1. Frontend: User submits auth provider form
1029
+
1030
+ 2. GraphQL Mutation: createAuthProvider(input)
1031
+
1032
+ 3. AuthProviderService.createAuthProvider()
1033
+ ├── Resolves tenant ID
1034
+ ├── Generates clientId/clientSecret
1035
+ ├── Stores secrets in environment service
1036
+ ├── Creates auth provider in MongoDB
1037
+ └── Triggers Inngest Event: AUTH_MGMT_CONFIGURE_KEYCLOAK_SETTINGS_EVENT
1038
+
1039
+ 4. Returns auth provider to frontend
1040
+
1041
+ 5. Inngest Function: configureKeycloakAuthSettingFunction
1042
+ ├── Step 1: Create realm and client (managed only)
1043
+ └── Step 2: Configure identity providers
1044
+
1045
+ 6. Keycloak realm and client created
1046
+ ```
1047
+
1048
+ #### Updating an Auth Provider
1049
+
1050
+ ```
1051
+ 1. Frontend: User updates auth provider form
1052
+
1053
+ 2. GraphQL Mutation: updateAuthProvider(id, input)
1054
+
1055
+ 3. AuthProviderService.updateAuthProvider()
1056
+ ├── Updates secrets in environment service
1057
+ ├── Updates auth provider in MongoDB
1058
+ └── Triggers Inngest Event: AUTH_MGMT_UPDATE_KEYCLOAK_SETTINGS_EVENT
1059
+
1060
+ 4. Returns updated auth provider to frontend
1061
+
1062
+ 5. Inngest Function: updateKeycloakAuthSettingFunction
1063
+ ├── Step 1: Update realm settings
1064
+ ├── Step 2: Delete/recreate client (if flow changed)
1065
+ ├── Step 3: Update client settings (if flow unchanged)
1066
+ └── Step 4: Configure identity providers
1067
+ ```
1068
+
1069
+ #### Testing Credentials
1070
+
1071
+ ```
1072
+ 1. Frontend: User clicks "Test" button
1073
+
1074
+ 2. GraphQL Mutation: testAuthProviderCredentials(authProviderId)
1075
+
1076
+ 3. AuthProviderService.testAuthProviderCredentials()
1077
+ ├── Fetches auth provider
1078
+ ├── Fetches client secret (from Keycloak API or environment)
1079
+ ├── Calls OAuth2 token endpoint
1080
+ └── Returns success/failure with details
1081
+
1082
+ 4. Frontend displays result inline
1083
+ ```
1084
+
1085
+ ### Keycloak Integration
1086
+
1087
+ #### Managed Keycloak
1088
+
1089
+ **Service**: `KeycloakInternalAdminService.Instance`
1090
+
1091
+ **Operations**:
1092
+
1093
+ - `createRealmAndClient()`: Creates realm and OAuth2 client
1094
+ - `updateRealmSettings()`: Updates realm signup settings
1095
+ - `updateClientInternal()`: Updates client redirect URIs
1096
+ - `deleteClientInternal()`: Deletes client
1097
+ - `configureIdentityProviderInternal()`: Configures social login providers
1098
+ - `getClientSecretInternal()`: Fetches client secret
1099
+ - `deleteRealmInternal()`: Deletes entire realm
1100
+
1101
+ #### Self-Hosted Keycloak
1102
+
1103
+ **Service**: `KeycloakTenantAdminService.fromSelfHostedConfig()`
1104
+
1105
+ **Configuration**:
1106
+
1107
+ - Domain: Keycloak server URL
1108
+ - Admin credentials: Username, password, client ID, client secret
1109
+ - Realm name: Target realm
1110
+
1111
+ **Operations**:
1112
+
1113
+ - `configureIdentityProvider()`: Configures social login providers
1114
+ - `updateRealmSettings()`: Updates realm settings
1115
+ - `getClientSecret()`: Fetches client secret
1116
+
1117
+ ### Auth Flow Types
1118
+
1119
+ **PKCE (Authorization Code Flow with PKCE)**:
1120
+
1121
+ - Recommended for web and mobile apps
1122
+ - More secure than implicit flow
1123
+ - Uses code verifier/challenge
1124
+
1125
+ **Implicit Flow**:
1126
+
1127
+ - Legacy flow
1128
+ - Less secure
1129
+ - Direct token return
1130
+
1131
+ **Flow Change Handling**:
1132
+
1133
+ - When auth flow changes, old client is deleted and new one created
1134
+ - This ensures proper configuration for the new flow type
1135
+
1136
+ ### Error Handling
1137
+
1138
+ #### Service Layer Errors
1139
+
1140
+ - **Database Errors**: Thrown immediately
1141
+ - **Keycloak API Errors**: Logged, may not fail entire operation
1142
+ - **Secret Storage Errors**: Logged, operation continues
1143
+
1144
+ #### Inngest Function Errors
1145
+
1146
+ - **Realm Creation Failures**: Logged, operation fails
1147
+ - **Identity Provider Failures**: Logged individually, doesn't stop other providers
1148
+ - **Client Update Failures**: Logged, operation fails
1149
+
1150
+ ### Security Considerations
1151
+
1152
+ 1. **Secret Storage**: All secrets stored in environment service, not in database
1153
+ 2. **Client Secret Generation**: Unique secrets generated for each provider
1154
+ 3. **Admin Credentials**: Only stored for self-hosted Keycloak, in environment service
1155
+ 4. **Token Testing**: Uses OAuth2 client credentials flow (secure)
1156
+ 5. **Realm Isolation**: Each tenant gets its own realm (managed Keycloak)
1157
+
1158
+ ---
1159
+
1160
+ ## Important Notes and Best Practices
1161
+
1162
+ ### 1. Tenant ID Resolution
1163
+
1164
+ **Critical Distinction**:
1165
+
1166
+ - `tenantId`: UUID string (used in API calls)
1167
+ - `tenant.id`: MongoDB ObjectId (stored in AuthProvider.tenant)
1168
+
1169
+ **Usage**:
1170
+
1171
+ ```typescript
1172
+ // Frontend passes tenantId (UUID)
1173
+ // Backend resolves to MongoDB id for storage
1174
+ const tenant = await tenantRepository.find({ tenantId });
1175
+ authProvider.tenant = tenant.id; // MongoDB ObjectId
1176
+ ```
1177
+
1178
+ ### 2. One Provider Per Tenant
1179
+
1180
+ **Important**: Each tenant can have only one auth provider. The system:
1181
+
1182
+ - Checks for existing provider when creating
1183
+ - Shows warning if provider already exists
1184
+ - Allows editing existing provider instead
1185
+
1186
+ ### 3. Self-Hosted vs Managed Keycloak
1187
+
1188
+ **Managed Keycloak**:
1189
+
1190
+ - Realm is created automatically
1191
+ - Realm is deleted when provider is deleted
1192
+ - Uses internal admin service
1193
+
1194
+ **Self-Hosted Keycloak**:
1195
+
1196
+ - Realm must exist before configuration
1197
+ - Realm is not deleted when provider is deleted
1198
+ - Requires admin credentials
1199
+ - Uses tenant admin service
1200
+
1201
+ ### 4. Secret Management
1202
+
1203
+ **Storage**:
1204
+
1205
+ - Secrets stored in environment service, not database
1206
+ - Retrieved on-demand when needed
1207
+ - Never logged or exposed in responses
1208
+
1209
+ **Keycloak Client Secret**:
1210
+
1211
+ - Fetched from Keycloak API (not stored)
1212
+ - Regenerated deterministically if needed
1213
+ - Different for managed vs self-hosted
1214
+
1215
+ ### 5. Identity Provider Configuration
1216
+
1217
+ **Supported Providers**:
1218
+
1219
+ - Google, GitHub, Facebook, Microsoft, etc.
1220
+ - Each requires client ID and secret from provider
1221
+ - Can be enabled/disabled per provider
1222
+
1223
+ **Configuration**:
1224
+
1225
+ - Configured asynchronously via Inngest
1226
+ - Individual provider failures don't stop others
1227
+ - Updates require full provider array
1228
+
1229
+ ### 6. Auth Flow Changes
1230
+
1231
+ **Important**: Changing auth flow (PKCE ↔ Implicit) requires:
1232
+
1233
+ - Deleting old client
1234
+ - Creating new client with new flow
1235
+ - This is handled automatically by Inngest
1236
+
1237
+ ### 7. Credential Testing
1238
+
1239
+ **Purpose**: Verify configuration before saving or after changes.
1240
+
1241
+ **Process**:
1242
+
1243
+ - Uses OAuth2 client credentials flow
1244
+ - Attempts to obtain access token
1245
+ - Returns success/failure with details
1246
+
1247
+ **Best Practice**: Always test credentials after configuration changes.
1248
+
1249
+ ### 8. Redirect URI Validation
1250
+
1251
+ **Format**: Must be valid URLs
1252
+
1253
+ - `https://example.com/callback`
1254
+ - `http://localhost:3000/callback` (development)
1255
+
1256
+ **Web Origins**: Automatically extracted from redirect URIs
1257
+
1258
+ - Used for CORS configuration
1259
+ - Must match redirect URI origins
1260
+
1261
+ ### 9. Error Recovery
1262
+
1263
+ **Keycloak API Failures**:
1264
+
1265
+ - Logged but may not fail entire operation
1266
+ - Identity provider failures are non-blocking
1267
+ - Realm/client creation failures are blocking
1268
+
1269
+ **Retry Strategy**:
1270
+
1271
+ - Inngest functions can be retried
1272
+ - Service operations are idempotent where possible
1273
+
1274
+ ### 10. Type Safety
1275
+
1276
+ **Key Interfaces**:
1277
+
1278
+ - `IAuthProvider`: Auth provider data structure
1279
+ - `IAuthProviderInput`: Input for create/update
1280
+ - `IKeycloakConfig`: Keycloak configuration
1281
+ - `IAuth0Config`: Auth0 configuration
1282
+
1283
+ **Type Guards**:
1284
+
1285
+ - Always check provider type before accessing config
1286
+ - Handle undefined/null cases gracefully
1287
+
1288
+ ---
1289
+
1290
+ ## Summary
1291
+
1292
+ The Auth Provider Management System provides a comprehensive interface for managing authentication providers (Keycloak and Auth0) for tenants. It leverages React, XState for form state management, GraphQL for data operations, and Inngest for asynchronous Keycloak configuration.
1293
+
1294
+ **Key Takeaways**:
1295
+
1296
+ **Frontend**:
1297
+
1298
+ - ✅ Multi-step form with XState machine
1299
+ - ✅ Support for Keycloak (managed/self-hosted) and Auth0
1300
+ - ✅ Credential testing before saving
1301
+ - ✅ Configuration details viewing
1302
+ - ✅ One provider per tenant constraint
1303
+
1304
+ **Backend**:
1305
+
1306
+ - ✅ Event-driven architecture with Inngest
1307
+ - ✅ Keycloak realm and client management
1308
+ - ✅ Identity provider configuration
1309
+ - ✅ Secure secret management via environment service
1310
+ - ✅ Support for both managed and self-hosted Keycloak
1311
+ - ✅ Auth flow change handling (PKCE ↔ Implicit)
1312
+
1313
+ ## Testing
1314
+
1315
+ For testing keycloak authentication using PKCE and Implicit flow follow this example
1316
+
1317
+ https://github.com/huzaifaali14/keycloak-auth