@strapi/admin 5.31.2 → 5.31.3

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 (150) hide show
  1. package/dist/admin/admin/src/components/GuidedTour/Steps/ContentTypeBuilderSteps.js +2 -2
  2. package/dist/admin/admin/src/components/GuidedTour/Steps/ContentTypeBuilderSteps.js.map +1 -1
  3. package/dist/admin/admin/src/components/GuidedTour/Steps/ContentTypeBuilderSteps.mjs +1 -1
  4. package/dist/admin/admin/src/components/GuidedTour/Steps/ContentTypeBuilderSteps.mjs.map +1 -1
  5. package/dist/admin/admin/src/pages/Auth/components/Register.js +2 -1
  6. package/dist/admin/admin/src/pages/Auth/components/Register.js.map +1 -1
  7. package/dist/admin/admin/src/pages/Auth/components/Register.mjs +2 -1
  8. package/dist/admin/admin/src/pages/Auth/components/Register.mjs.map +1 -1
  9. package/dist/admin/admin/src/pages/Home/HomePage.js +1 -1
  10. package/dist/admin/admin/src/pages/Home/HomePage.js.map +1 -1
  11. package/dist/admin/admin/src/pages/Home/HomePage.mjs +1 -1
  12. package/dist/admin/admin/src/pages/Home/HomePage.mjs.map +1 -1
  13. package/dist/admin/admin/src/pages/ProfilePage.js +6 -0
  14. package/dist/admin/admin/src/pages/ProfilePage.js.map +1 -1
  15. package/dist/admin/admin/src/pages/ProfilePage.mjs +6 -0
  16. package/dist/admin/admin/src/pages/ProfilePage.mjs.map +1 -1
  17. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/ActionBoundRoutes.js +2 -0
  18. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/ActionBoundRoutes.js.map +1 -1
  19. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/ActionBoundRoutes.mjs +2 -0
  20. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/ActionBoundRoutes.mjs.map +1 -1
  21. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.js +2 -1
  22. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.js.map +1 -1
  23. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.mjs +2 -1
  24. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.mjs.map +1 -1
  25. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/FormApiTokenContainer.js +4 -4
  26. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/FormApiTokenContainer.js.map +1 -1
  27. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/FormApiTokenContainer.mjs +4 -4
  28. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/FormApiTokenContainer.mjs.map +1 -1
  29. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/Permissions.js +1 -0
  30. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/Permissions.js.map +1 -1
  31. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/Permissions.mjs +1 -0
  32. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/Permissions.mjs.map +1 -1
  33. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js +5 -5
  34. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js.map +1 -1
  35. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs +5 -5
  36. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs.map +1 -1
  37. package/dist/admin/admin/src/pages/Settings/pages/PurchaseAuditLogs.js +4 -4
  38. package/dist/admin/admin/src/pages/Settings/pages/PurchaseAuditLogs.js.map +1 -1
  39. package/dist/admin/admin/src/pages/Settings/pages/PurchaseAuditLogs.mjs +4 -4
  40. package/dist/admin/admin/src/pages/Settings/pages/PurchaseAuditLogs.mjs.map +1 -1
  41. package/dist/admin/admin/src/pages/Settings/pages/PurchaseContentHistory.js +4 -4
  42. package/dist/admin/admin/src/pages/Settings/pages/PurchaseContentHistory.js.map +1 -1
  43. package/dist/admin/admin/src/pages/Settings/pages/PurchaseContentHistory.mjs +4 -4
  44. package/dist/admin/admin/src/pages/Settings/pages/PurchaseContentHistory.mjs.map +1 -1
  45. package/dist/admin/admin/src/pages/Settings/pages/PurchaseSingleSignOn.js +4 -2
  46. package/dist/admin/admin/src/pages/Settings/pages/PurchaseSingleSignOn.js.map +1 -1
  47. package/dist/admin/admin/src/pages/Settings/pages/PurchaseSingleSignOn.mjs +4 -2
  48. package/dist/admin/admin/src/pages/Settings/pages/PurchaseSingleSignOn.mjs.map +1 -1
  49. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.js +4 -2
  50. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.js.map +1 -1
  51. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.mjs +4 -2
  52. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.mjs.map +1 -1
  53. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.js +3 -1
  54. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.js.map +1 -1
  55. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.mjs +3 -1
  56. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.mjs.map +1 -1
  57. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/RoleForm.js +2 -0
  58. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/RoleForm.js.map +1 -1
  59. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/RoleForm.mjs +2 -0
  60. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/RoleForm.mjs.map +1 -1
  61. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.js +2 -1
  62. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.js.map +1 -1
  63. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.mjs +2 -1
  64. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.mjs.map +1 -1
  65. package/dist/admin/admin/src/pages/Settings/pages/Users/components/NewUserForm.js +2 -1
  66. package/dist/admin/admin/src/pages/Settings/pages/Users/components/NewUserForm.js.map +1 -1
  67. package/dist/admin/admin/src/pages/Settings/pages/Users/components/NewUserForm.mjs +2 -1
  68. package/dist/admin/admin/src/pages/Settings/pages/Users/components/NewUserForm.mjs.map +1 -1
  69. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.js +2 -0
  70. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.js.map +1 -1
  71. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.mjs +2 -0
  72. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.mjs.map +1 -1
  73. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.js +1 -0
  74. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.js.map +1 -1
  75. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.mjs +1 -0
  76. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.mjs.map +1 -1
  77. package/dist/admin/admin/src/services/auth.js +1 -12
  78. package/dist/admin/admin/src/services/auth.js.map +1 -1
  79. package/dist/admin/admin/src/services/auth.mjs +2 -11
  80. package/dist/admin/admin/src/services/auth.mjs.map +1 -1
  81. package/dist/admin/admin/src/translations/vi.json.js +772 -129
  82. package/dist/admin/admin/src/translations/vi.json.js.map +1 -1
  83. package/dist/admin/admin/src/translations/vi.json.mjs +764 -130
  84. package/dist/admin/admin/src/translations/vi.json.mjs.map +1 -1
  85. package/dist/admin/ee/admin/src/pages/AuthPage/components/SSOProviders.js +7 -0
  86. package/dist/admin/ee/admin/src/pages/AuthPage/components/SSOProviders.js.map +1 -1
  87. package/dist/admin/ee/admin/src/pages/AuthPage/components/SSOProviders.mjs +7 -0
  88. package/dist/admin/ee/admin/src/pages/AuthPage/components/SSOProviders.mjs.map +1 -1
  89. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.js +1 -1
  90. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.js.map +1 -1
  91. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.mjs +1 -1
  92. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.mjs.map +1 -1
  93. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/SingleSignOnPage.js +1 -0
  94. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/SingleSignOnPage.js.map +1 -1
  95. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/SingleSignOnPage.mjs +1 -0
  96. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/SingleSignOnPage.mjs.map +1 -1
  97. package/dist/admin/index.js +0 -2
  98. package/dist/admin/index.js.map +1 -1
  99. package/dist/admin/index.mjs +0 -1
  100. package/dist/admin/index.mjs.map +1 -1
  101. package/dist/admin/src/index.d.ts +0 -2
  102. package/dist/admin/src/services/auth.d.ts +2 -11
  103. package/dist/ee/server/src/ai/containers/ai.d.ts +4 -0
  104. package/dist/ee/server/src/ai/containers/ai.d.ts.map +1 -1
  105. package/dist/ee/server/src/ai/controllers/ai.d.ts.map +1 -1
  106. package/dist/ee/server/src/ai/routes/ai.d.ts.map +1 -1
  107. package/dist/server/ee/server/src/ai/containers/ai.js +143 -1
  108. package/dist/server/ee/server/src/ai/containers/ai.js.map +1 -1
  109. package/dist/server/ee/server/src/ai/containers/ai.mjs +143 -1
  110. package/dist/server/ee/server/src/ai/containers/ai.mjs.map +1 -1
  111. package/dist/server/ee/server/src/ai/controllers/ai.js +7 -106
  112. package/dist/server/ee/server/src/ai/controllers/ai.js.map +1 -1
  113. package/dist/server/ee/server/src/ai/controllers/ai.mjs +7 -106
  114. package/dist/server/ee/server/src/ai/controllers/ai.mjs.map +1 -1
  115. package/dist/server/ee/server/src/ai/routes/ai.js +0 -3
  116. package/dist/server/ee/server/src/ai/routes/ai.js.map +1 -1
  117. package/dist/server/ee/server/src/ai/routes/ai.mjs +0 -3
  118. package/dist/server/ee/server/src/ai/routes/ai.mjs.map +1 -1
  119. package/dist/server/server/src/controllers/authenticated-user.js +0 -15
  120. package/dist/server/server/src/controllers/authenticated-user.js.map +1 -1
  121. package/dist/server/server/src/controllers/authenticated-user.mjs +0 -15
  122. package/dist/server/server/src/controllers/authenticated-user.mjs.map +1 -1
  123. package/dist/server/server/src/routes/users.js +0 -10
  124. package/dist/server/server/src/routes/users.js.map +1 -1
  125. package/dist/server/server/src/routes/users.mjs +0 -10
  126. package/dist/server/server/src/routes/users.mjs.map +1 -1
  127. package/dist/server/server/src/services/user.js +1 -143
  128. package/dist/server/server/src/services/user.js.map +1 -1
  129. package/dist/server/server/src/services/user.mjs +1 -143
  130. package/dist/server/server/src/services/user.mjs.map +1 -1
  131. package/dist/server/src/controllers/authenticated-user.d.ts +0 -1
  132. package/dist/server/src/controllers/authenticated-user.d.ts.map +1 -1
  133. package/dist/server/src/controllers/index.d.ts +0 -1
  134. package/dist/server/src/controllers/index.d.ts.map +1 -1
  135. package/dist/server/src/index.d.ts +0 -5
  136. package/dist/server/src/index.d.ts.map +1 -1
  137. package/dist/server/src/routes/users.d.ts.map +1 -1
  138. package/dist/server/src/services/index.d.ts +0 -4
  139. package/dist/server/src/services/index.d.ts.map +1 -1
  140. package/dist/server/src/services/user.d.ts +0 -4
  141. package/dist/server/src/services/user.d.ts.map +1 -1
  142. package/dist/shared/contracts/ai.d.ts +1 -1
  143. package/dist/shared/contracts/users.d.ts +0 -32
  144. package/dist/shared/contracts/users.d.ts.map +1 -1
  145. package/package.json +9 -9
  146. package/dist/admin/admin/src/hooks/useAIAvailability.js +0 -13
  147. package/dist/admin/admin/src/hooks/useAIAvailability.js.map +0 -1
  148. package/dist/admin/admin/src/hooks/useAIAvailability.mjs +0 -11
  149. package/dist/admin/admin/src/hooks/useAIAvailability.mjs.map +0 -1
  150. package/dist/admin/src/hooks/useAIAvailability.d.ts +0 -5
@@ -1 +1 @@
1
- {"version":3,"file":"ai.js","sources":["../../../../../../../ee/server/src/ai/controllers/ai.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport path from 'path';\nimport fs from 'fs';\nimport crypto from 'crypto';\nimport type { AdminUser } from '../../../../../shared/contracts/shared';\nimport { GetAiToken } from '../../../../../shared/contracts/ai';\nimport { getService } from '../../utils';\n\nexport default {\n async getAiToken(ctx: Context) {\n const ERROR_PREFIX = 'AI token request failed:';\n const USER_ERROR_MESSAGE = 'AI token request failed. Check server logs for details.';\n\n try {\n // Security check: Ensure user is authenticated and has proper permissions\n if (!ctx.state.user) {\n return ctx.unauthorized('Authentication required');\n }\n\n // Check if EE features are enabled first\n if (!strapi.ee?.isEE) {\n strapi.log.error(`${ERROR_PREFIX} Enterprise Edition features are not enabled`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get the EE license\n // First try environment variable, then try reading from file\n let eeLicense = process.env.STRAPI_LICENSE;\n\n if (!eeLicense) {\n try {\n const licensePath = path.join(strapi.dirs.app.root, 'license.txt');\n eeLicense = fs.readFileSync(licensePath).toString();\n } catch (error) {\n // License file doesn't exist or can't be read\n }\n }\n\n if (!eeLicense) {\n strapi.log.error(\n `${ERROR_PREFIX} No EE license found. Please ensure STRAPI_LICENSE environment variable is set or license.txt file exists.`\n );\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n if (!aiServerUrl) {\n strapi.log.error(\n `${ERROR_PREFIX} AI server URL not configured. Please set STRAPI_AI_URL environment variable.`\n );\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get the current user\n const user = ctx.state.user as AdminUser;\n\n // Create a secure user identifier using only user ID\n const userIdentifier = user.id.toString();\n\n // Get project ID\n const projectId = strapi.config.get('uuid');\n if (!projectId) {\n strapi.log.error(`${ERROR_PREFIX} Project ID not configured`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n strapi.log.http('Contacting AI Server for token generation');\n\n try {\n // Call the AI server's getAiJWT endpoint\n const response = await fetch(`${aiServerUrl}/auth/getAiJWT`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n // No authorization header needed for public endpoint\n // Add request ID for tracing\n 'X-Request-Id': crypto.randomUUID(),\n },\n body: JSON.stringify({\n eeLicense,\n userIdentifier,\n projectId,\n }),\n });\n\n if (!response.ok) {\n let errorData;\n let errorText;\n try {\n errorText = await response.text();\n errorData = JSON.parse(errorText);\n } catch {\n errorData = { error: errorText || 'Failed to parse error response' };\n }\n\n strapi.log.error(`${ERROR_PREFIX} ${errorData?.error || 'Unknown error'}`, {\n status: response.status,\n statusText: response.statusText,\n error: errorData,\n errorText,\n projectId,\n });\n\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n let data;\n try {\n data = (await response.json()) as {\n jwt: string;\n expiresAt?: string;\n };\n } catch (parseError) {\n strapi.log.error(`${ERROR_PREFIX} Failed to parse AI server response`, parseError);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n if (!data.jwt) {\n strapi.log.error(`${ERROR_PREFIX} Invalid response: missing JWT token`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n strapi.log.info('AI token generated successfully', {\n userId: user.id,\n expiresAt: data.expiresAt,\n });\n\n // Return the AI JWT with metadata\n // Note: Token expires in 1 hour, client should handle refresh\n ctx.body = {\n data: {\n token: data.jwt,\n expiresAt: data.expiresAt, // 1 hour from generation\n },\n } satisfies GetAiToken.Response;\n } catch (fetchError) {\n if (fetchError instanceof Error && fetchError.name === 'AbortError') {\n strapi.log.error(`${ERROR_PREFIX} Request to AI server timed out`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n throw fetchError;\n }\n } catch (error) {\n strapi.log.error(\n `${ERROR_PREFIX} ${error instanceof Error ? error.message : 'Unknown error'}`,\n error\n );\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n },\n async getAiUsage(ctx: Context) {\n const ERROR_PREFIX = 'AI usage data request failed:';\n const USER_ERROR_MESSAGE = 'AI usage data request failed. Check server logs for details.';\n // Security check: Ensure user is authenticated and has proper permissions\n if (!ctx.state.user) {\n return ctx.unauthorized('Authentication required');\n }\n\n // Check if EE features are enabled first\n if (!strapi.ee?.isEE) {\n strapi.log.error(`${ERROR_PREFIX} Enterprise Edition features are not enabled`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get the EE license\n // First try environment variable, then try reading from file\n let eeLicense = process.env.STRAPI_LICENSE;\n\n if (!eeLicense) {\n try {\n const licensePath = path.join(strapi.dirs.app.root, 'license.txt');\n eeLicense = fs.readFileSync(licensePath).toString();\n } catch (error) {\n // License file doesn't exist or can't be read\n }\n }\n\n if (!eeLicense) {\n strapi.log.error(\n `${ERROR_PREFIX} No EE license found. Please ensure STRAPI_LICENSE environment variable is set or license.txt file exists.`\n );\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n if (!aiServerUrl) {\n strapi.log.error(\n `${ERROR_PREFIX} AI server URL not configured. Please set STRAPI_AI_URL or STRAPI_AI_URL environment variable.`\n );\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get project ID\n const projectId = strapi.config.get('uuid');\n if (!projectId) {\n strapi.log.error(`${ERROR_PREFIX} Project ID not configured`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n try {\n // Call the AI server's getAiJWT endpoint\n const response = await fetch(`${aiServerUrl}/cms/ai-data`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n // No authorization header needed for public endpoint\n // Add request ID for tracing\n 'X-Request-Id': crypto.randomUUID(),\n },\n body: JSON.stringify({\n eeKey: eeLicense,\n projectId,\n }),\n });\n\n if (!response.ok) {\n let errorData;\n let errorText;\n try {\n errorText = await response.text();\n errorData = JSON.parse(errorText);\n } catch {\n errorData = { error: errorText || 'Failed to parse error response' };\n }\n\n strapi.log.error(`${ERROR_PREFIX} ${errorData?.error || 'Unknown error'}`, {\n status: response.status,\n statusText: response.statusText,\n error: errorData,\n errorText,\n projectId,\n });\n\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n let data;\n try {\n data = (await response.json()) as {\n data: {\n cmsAiCreditsUsed: number;\n };\n subscription: {\n subscriptionId: string;\n planPriceId: string;\n subscriptionStatus: string;\n isActiveSubscription: boolean;\n cmsAiEnabled: boolean;\n cmsAiCreditsBase: number;\n cmsAiCreditsMaxUsage: number;\n currentTermStart: string;\n currentTermEnd: string;\n };\n };\n } catch (parseError) {\n strapi.log.error(`${ERROR_PREFIX} Failed to parse AI server response`, parseError);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n ctx.body = {\n ...data.data,\n subscription: data.subscription,\n };\n } catch (fetchError) {\n if (fetchError instanceof Error && fetchError.name === 'AbortError') {\n strapi.log.error(`${ERROR_PREFIX} Request to AI server timed out`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n throw fetchError;\n }\n },\n async getAIFeatureConfig(ctx: Context) {\n const aiFeatureConfig = await strapi.get('ai').getAIFeatureConfig();\n\n ctx.body = {\n data: aiFeatureConfig,\n };\n },\n};\n"],"names":["getAiToken","ctx","ERROR_PREFIX","USER_ERROR_MESSAGE","state","user","unauthorized","strapi","ee","isEE","log","error","internalServerError","eeLicense","process","env","STRAPI_LICENSE","licensePath","path","join","dirs","app","root","fs","readFileSync","toString","aiServerUrl","STRAPI_AI_URL","userIdentifier","id","projectId","config","get","http","response","fetch","method","headers","crypto","randomUUID","body","JSON","stringify","ok","errorData","errorText","text","parse","status","statusText","data","json","parseError","jwt","info","userId","expiresAt","token","fetchError","Error","name","message","getAiUsage","eeKey","subscription","getAIFeatureConfig","aiFeatureConfig"],"mappings":";;;;;;AAQA,mBAAe;AACb,IAAA,MAAMA,YAAWC,GAAY,EAAA;AAC3B,QAAA,MAAMC,YAAe,GAAA,0BAAA;AACrB,QAAA,MAAMC,kBAAqB,GAAA,yDAAA;QAE3B,IAAI;;AAEF,YAAA,IAAI,CAACF,GAAAA,CAAIG,KAAK,CAACC,IAAI,EAAE;gBACnB,OAAOJ,GAAAA,CAAIK,YAAY,CAAC,yBAAA,CAAA;AAC1B;;AAGA,YAAA,IAAI,CAACC,MAAAA,CAAOC,EAAE,EAAEC,IAAM,EAAA;AACpBF,gBAAAA,MAAAA,CAAOG,GAAG,CAACC,KAAK,CAAC,CAAGT,EAAAA,YAAAA,CAAa,4CAA4C,CAAC,CAAA;gBAC9E,OAAOD,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;;;AAIA,YAAA,IAAIU,SAAYC,GAAAA,OAAAA,CAAQC,GAAG,CAACC,cAAc;AAE1C,YAAA,IAAI,CAACH,SAAW,EAAA;gBACd,IAAI;oBACF,MAAMI,WAAAA,GAAcC,IAAKC,CAAAA,IAAI,CAACZ,MAAAA,CAAOa,IAAI,CAACC,GAAG,CAACC,IAAI,EAAE,aAAA,CAAA;AACpDT,oBAAAA,SAAAA,GAAYU,EAAGC,CAAAA,YAAY,CAACP,WAAAA,CAAAA,CAAaQ,QAAQ,EAAA;AACnD,iBAAA,CAAE,OAAOd,KAAO,EAAA;;AAEhB;AACF;AAEA,YAAA,IAAI,CAACE,SAAW,EAAA;AACdN,gBAAAA,MAAAA,CAAOG,GAAG,CAACC,KAAK,CACd,CAAGT,EAAAA,YAAAA,CAAa,0GAA0G,CAAC,CAAA;gBAE7H,OAAOD,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;AAEA,YAAA,MAAMuB,WAAcZ,GAAAA,OAAAA,CAAQC,GAAG,CAACY,aAAa,IAAI,kCAAA;AAEjD,YAAA,IAAI,CAACD,WAAa,EAAA;AAChBnB,gBAAAA,MAAAA,CAAOG,GAAG,CAACC,KAAK,CACd,CAAGT,EAAAA,YAAAA,CAAa,6EAA6E,CAAC,CAAA;gBAEhG,OAAOD,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;;AAGA,YAAA,MAAME,IAAOJ,GAAAA,GAAAA,CAAIG,KAAK,CAACC,IAAI;;AAG3B,YAAA,MAAMuB,cAAiBvB,GAAAA,IAAAA,CAAKwB,EAAE,CAACJ,QAAQ,EAAA;;AAGvC,YAAA,MAAMK,SAAYvB,GAAAA,MAAAA,CAAOwB,MAAM,CAACC,GAAG,CAAC,MAAA,CAAA;AACpC,YAAA,IAAI,CAACF,SAAW,EAAA;AACdvB,gBAAAA,MAAAA,CAAOG,GAAG,CAACC,KAAK,CAAC,CAAGT,EAAAA,YAAAA,CAAa,0BAA0B,CAAC,CAAA;gBAC5D,OAAOD,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;YAEAI,MAAOG,CAAAA,GAAG,CAACuB,IAAI,CAAC,2CAAA,CAAA;YAEhB,IAAI;;AAEF,gBAAA,MAAMC,WAAW,MAAMC,KAAAA,CAAM,GAAGT,WAAY,CAAA,cAAc,CAAC,EAAE;oBAC3DU,MAAQ,EAAA,MAAA;oBACRC,OAAS,EAAA;wBACP,cAAgB,EAAA,kBAAA;;;AAGhB,wBAAA,cAAA,EAAgBC,OAAOC,UAAU;AACnC,qBAAA;oBACAC,IAAMC,EAAAA,IAAAA,CAAKC,SAAS,CAAC;AACnB7B,wBAAAA,SAAAA;AACAe,wBAAAA,cAAAA;AACAE,wBAAAA;AACF,qBAAA;AACF,iBAAA,CAAA;gBAEA,IAAI,CAACI,QAASS,CAAAA,EAAE,EAAE;oBAChB,IAAIC,SAAAA;oBACJ,IAAIC,SAAAA;oBACJ,IAAI;wBACFA,SAAY,GAAA,MAAMX,SAASY,IAAI,EAAA;wBAC/BF,SAAYH,GAAAA,IAAAA,CAAKM,KAAK,CAACF,SAAAA,CAAAA;AACzB,qBAAA,CAAE,OAAM;wBACND,SAAY,GAAA;AAAEjC,4BAAAA,KAAAA,EAAOkC,SAAa,IAAA;AAAiC,yBAAA;AACrE;oBAEAtC,MAAOG,CAAAA,GAAG,CAACC,KAAK,CAAC,CAAA,EAAGT,YAAa,CAAA,CAAC,EAAE0C,SAAAA,EAAWjC,KAAS,IAAA,eAAA,CAAA,CAAiB,EAAE;AACzEqC,wBAAAA,MAAAA,EAAQd,SAASc,MAAM;AACvBC,wBAAAA,UAAAA,EAAYf,SAASe,UAAU;wBAC/BtC,KAAOiC,EAAAA,SAAAA;AACPC,wBAAAA,SAAAA;AACAf,wBAAAA;AACF,qBAAA,CAAA;oBAEA,OAAO7B,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;gBAEA,IAAI+C,IAAAA;gBACJ,IAAI;oBACFA,IAAQ,GAAA,MAAMhB,SAASiB,IAAI,EAAA;AAI7B,iBAAA,CAAE,OAAOC,UAAY,EAAA;oBACnB7C,MAAOG,CAAAA,GAAG,CAACC,KAAK,CAAC,GAAGT,YAAa,CAAA,mCAAmC,CAAC,EAAEkD,UAAAA,CAAAA;oBACvE,OAAOnD,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;gBAEA,IAAI,CAAC+C,IAAKG,CAAAA,GAAG,EAAE;AACb9C,oBAAAA,MAAAA,CAAOG,GAAG,CAACC,KAAK,CAAC,CAAGT,EAAAA,YAAAA,CAAa,oCAAoC,CAAC,CAAA;oBACtE,OAAOD,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;AAEAI,gBAAAA,MAAAA,CAAOG,GAAG,CAAC4C,IAAI,CAAC,iCAAmC,EAAA;AACjDC,oBAAAA,MAAAA,EAAQlD,KAAKwB,EAAE;AACf2B,oBAAAA,SAAAA,EAAWN,KAAKM;AAClB,iBAAA,CAAA;;;AAIAvD,gBAAAA,GAAAA,CAAIuC,IAAI,GAAG;oBACTU,IAAM,EAAA;AACJO,wBAAAA,KAAAA,EAAOP,KAAKG,GAAG;AACfG,wBAAAA,SAAAA,EAAWN,KAAKM;AAClB;AACF,iBAAA;AACF,aAAA,CAAE,OAAOE,UAAY,EAAA;AACnB,gBAAA,IAAIA,UAAsBC,YAAAA,KAAAA,IAASD,UAAWE,CAAAA,IAAI,KAAK,YAAc,EAAA;AACnErD,oBAAAA,MAAAA,CAAOG,GAAG,CAACC,KAAK,CAAC,CAAGT,EAAAA,YAAAA,CAAa,+BAA+B,CAAC,CAAA;oBACjE,OAAOD,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;gBAEA,MAAMuD,UAAAA;AACR;AACF,SAAA,CAAE,OAAO/C,KAAO,EAAA;AACdJ,YAAAA,MAAAA,CAAOG,GAAG,CAACC,KAAK,CACd,GAAGT,YAAa,CAAA,CAAC,EAAES,KAAAA,YAAiBgD,KAAQhD,GAAAA,KAAAA,CAAMkD,OAAO,GAAG,iBAAiB,EAC7ElD,KAAAA,CAAAA;YAEF,OAAOV,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;AACF,KAAA;AACA,IAAA,MAAM2D,YAAW7D,GAAY,EAAA;AAC3B,QAAA,MAAMC,YAAe,GAAA,+BAAA;AACrB,QAAA,MAAMC,kBAAqB,GAAA,8DAAA;;AAE3B,QAAA,IAAI,CAACF,GAAAA,CAAIG,KAAK,CAACC,IAAI,EAAE;YACnB,OAAOJ,GAAAA,CAAIK,YAAY,CAAC,yBAAA,CAAA;AAC1B;;AAGA,QAAA,IAAI,CAACC,MAAAA,CAAOC,EAAE,EAAEC,IAAM,EAAA;AACpBF,YAAAA,MAAAA,CAAOG,GAAG,CAACC,KAAK,CAAC,CAAGT,EAAAA,YAAAA,CAAa,4CAA4C,CAAC,CAAA;YAC9E,OAAOD,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;;;AAIA,QAAA,IAAIU,SAAYC,GAAAA,OAAAA,CAAQC,GAAG,CAACC,cAAc;AAE1C,QAAA,IAAI,CAACH,SAAW,EAAA;YACd,IAAI;gBACF,MAAMI,WAAAA,GAAcC,IAAKC,CAAAA,IAAI,CAACZ,MAAAA,CAAOa,IAAI,CAACC,GAAG,CAACC,IAAI,EAAE,aAAA,CAAA;AACpDT,gBAAAA,SAAAA,GAAYU,EAAGC,CAAAA,YAAY,CAACP,WAAAA,CAAAA,CAAaQ,QAAQ,EAAA;AACnD,aAAA,CAAE,OAAOd,KAAO,EAAA;;AAEhB;AACF;AAEA,QAAA,IAAI,CAACE,SAAW,EAAA;AACdN,YAAAA,MAAAA,CAAOG,GAAG,CAACC,KAAK,CACd,CAAGT,EAAAA,YAAAA,CAAa,0GAA0G,CAAC,CAAA;YAE7H,OAAOD,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;AAEA,QAAA,MAAMuB,WAAcZ,GAAAA,OAAAA,CAAQC,GAAG,CAACY,aAAa,IAAI,kCAAA;AAEjD,QAAA,IAAI,CAACD,WAAa,EAAA;AAChBnB,YAAAA,MAAAA,CAAOG,GAAG,CAACC,KAAK,CACd,CAAGT,EAAAA,YAAAA,CAAa,8FAA8F,CAAC,CAAA;YAEjH,OAAOD,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;;AAGA,QAAA,MAAM2B,SAAYvB,GAAAA,MAAAA,CAAOwB,MAAM,CAACC,GAAG,CAAC,MAAA,CAAA;AACpC,QAAA,IAAI,CAACF,SAAW,EAAA;AACdvB,YAAAA,MAAAA,CAAOG,GAAG,CAACC,KAAK,CAAC,CAAGT,EAAAA,YAAAA,CAAa,0BAA0B,CAAC,CAAA;YAC5D,OAAOD,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;QAEA,IAAI;;AAEF,YAAA,MAAM+B,WAAW,MAAMC,KAAAA,CAAM,GAAGT,WAAY,CAAA,YAAY,CAAC,EAAE;gBACzDU,MAAQ,EAAA,MAAA;gBACRC,OAAS,EAAA;oBACP,cAAgB,EAAA,kBAAA;;;AAGhB,oBAAA,cAAA,EAAgBC,OAAOC,UAAU;AACnC,iBAAA;gBACAC,IAAMC,EAAAA,IAAAA,CAAKC,SAAS,CAAC;oBACnBqB,KAAOlD,EAAAA,SAAAA;AACPiB,oBAAAA;AACF,iBAAA;AACF,aAAA,CAAA;YAEA,IAAI,CAACI,QAASS,CAAAA,EAAE,EAAE;gBAChB,IAAIC,SAAAA;gBACJ,IAAIC,SAAAA;gBACJ,IAAI;oBACFA,SAAY,GAAA,MAAMX,SAASY,IAAI,EAAA;oBAC/BF,SAAYH,GAAAA,IAAAA,CAAKM,KAAK,CAACF,SAAAA,CAAAA;AACzB,iBAAA,CAAE,OAAM;oBACND,SAAY,GAAA;AAAEjC,wBAAAA,KAAAA,EAAOkC,SAAa,IAAA;AAAiC,qBAAA;AACrE;gBAEAtC,MAAOG,CAAAA,GAAG,CAACC,KAAK,CAAC,CAAA,EAAGT,YAAa,CAAA,CAAC,EAAE0C,SAAAA,EAAWjC,KAAS,IAAA,eAAA,CAAA,CAAiB,EAAE;AACzEqC,oBAAAA,MAAAA,EAAQd,SAASc,MAAM;AACvBC,oBAAAA,UAAAA,EAAYf,SAASe,UAAU;oBAC/BtC,KAAOiC,EAAAA,SAAAA;AACPC,oBAAAA,SAAAA;AACAf,oBAAAA;AACF,iBAAA,CAAA;gBAEA,OAAO7B,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;YAEA,IAAI+C,IAAAA;YACJ,IAAI;gBACFA,IAAQ,GAAA,MAAMhB,SAASiB,IAAI,EAAA;AAgB7B,aAAA,CAAE,OAAOC,UAAY,EAAA;gBACnB7C,MAAOG,CAAAA,GAAG,CAACC,KAAK,CAAC,GAAGT,YAAa,CAAA,mCAAmC,CAAC,EAAEkD,UAAAA,CAAAA;gBACvE,OAAOnD,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;AAEAF,YAAAA,GAAAA,CAAIuC,IAAI,GAAG;AACT,gBAAA,GAAGU,KAAKA,IAAI;AACZc,gBAAAA,YAAAA,EAAcd,KAAKc;AACrB,aAAA;AACF,SAAA,CAAE,OAAON,UAAY,EAAA;AACnB,YAAA,IAAIA,UAAsBC,YAAAA,KAAAA,IAASD,UAAWE,CAAAA,IAAI,KAAK,YAAc,EAAA;AACnErD,gBAAAA,MAAAA,CAAOG,GAAG,CAACC,KAAK,CAAC,CAAGT,EAAAA,YAAAA,CAAa,+BAA+B,CAAC,CAAA;gBACjE,OAAOD,GAAAA,CAAIW,mBAAmB,CAACT,kBAAAA,CAAAA;AACjC;YAEA,MAAMuD,UAAAA;AACR;AACF,KAAA;AACA,IAAA,MAAMO,oBAAmBhE,GAAY,EAAA;AACnC,QAAA,MAAMiE,kBAAkB,MAAM3D,MAAAA,CAAOyB,GAAG,CAAC,MAAMiC,kBAAkB,EAAA;AAEjEhE,QAAAA,GAAAA,CAAIuC,IAAI,GAAG;YACTU,IAAMgB,EAAAA;AACR,SAAA;AACF;AACF,CAAE;;;;"}
1
+ {"version":3,"file":"ai.js","sources":["../../../../../../../ee/server/src/ai/controllers/ai.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport path from 'path';\nimport fs from 'fs';\nimport crypto from 'crypto';\nimport { GetAiToken } from '../../../../../shared/contracts/ai';\n\nexport default {\n async getAiToken(ctx: Context) {\n try {\n // TODO: auth check is not necessary? Already protected by route middleware?\n // Security check: Ensure user is authenticated and has proper permissions\n if (!ctx.state.user) {\n return ctx.unauthorized('Authentication required');\n }\n\n const aiToken = await strapi.get('ai').getAiToken();\n\n ctx.body = {\n data: aiToken,\n } satisfies GetAiToken.Response;\n } catch (error) {\n const errorMessage = 'AI token request failed. Check server logs for details.';\n return ctx.internalServerError(errorMessage);\n }\n },\n\n async getAiUsage(ctx: Context) {\n const ERROR_PREFIX = 'AI usage data request failed:';\n const USER_ERROR_MESSAGE = 'AI usage data request failed. Check server logs for details.';\n // Security check: Ensure user is authenticated and has proper permissions\n if (!ctx.state.user) {\n return ctx.unauthorized('Authentication required');\n }\n\n // Check if EE features are enabled first\n if (!strapi.ee?.isEE) {\n strapi.log.error(`${ERROR_PREFIX} Enterprise Edition features are not enabled`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get the EE license\n // First try environment variable, then try reading from file\n let eeLicense = process.env.STRAPI_LICENSE;\n\n if (!eeLicense) {\n try {\n const licensePath = path.join(strapi.dirs.app.root, 'license.txt');\n eeLicense = fs.readFileSync(licensePath).toString();\n } catch (error) {\n // License file doesn't exist or can't be read\n }\n }\n\n if (!eeLicense) {\n strapi.log.error(\n `${ERROR_PREFIX} No EE license found. Please ensure STRAPI_LICENSE environment variable is set or license.txt file exists.`\n );\n\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n if (!aiServerUrl) {\n strapi.log.error(\n `${ERROR_PREFIX} AI server URL not configured. Please set STRAPI_AI_URL or STRAPI_AI_URL environment variable.`\n );\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get project ID\n const projectId = strapi.config.get('uuid');\n if (!projectId) {\n strapi.log.error(`${ERROR_PREFIX} Project ID not configured`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n try {\n // Call the AI server's getAiJWT endpoint\n const response = await fetch(`${aiServerUrl}/cms/ai-data`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n // No authorization header needed for public endpoint\n // Add request ID for tracing\n 'X-Request-Id': crypto.randomUUID(),\n },\n body: JSON.stringify({\n eeKey: eeLicense,\n projectId,\n }),\n });\n\n if (!response.ok) {\n let errorData;\n let errorText;\n try {\n errorText = await response.text();\n errorData = JSON.parse(errorText);\n } catch {\n errorData = { error: errorText || 'Failed to parse error response' };\n }\n\n strapi.log.error(`${ERROR_PREFIX} ${errorData?.error || 'Unknown error'}`, {\n status: response.status,\n statusText: response.statusText,\n error: errorData,\n errorText,\n projectId,\n });\n\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n let data;\n try {\n data = (await response.json()) as {\n data: {\n cmsAiCreditsUsed: number;\n };\n subscription: {\n subscriptionId: string;\n planPriceId: string;\n subscriptionStatus: string;\n isActiveSubscription: boolean;\n cmsAiEnabled: boolean;\n cmsAiCreditsBase: number;\n cmsAiCreditsMaxUsage: number;\n currentTermStart: string;\n currentTermEnd: string;\n };\n };\n } catch (parseError) {\n strapi.log.error(`${ERROR_PREFIX} Failed to parse AI server response`, parseError);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n ctx.body = {\n ...data.data,\n subscription: data.subscription,\n };\n } catch (fetchError) {\n if (fetchError instanceof Error && fetchError.name === 'AbortError') {\n strapi.log.error(`${ERROR_PREFIX} Request to AI server timed out`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n throw fetchError;\n }\n },\n async getAIFeatureConfig(ctx: Context) {\n const aiFeatureConfig = await strapi.get('ai').getAIFeatureConfig();\n\n ctx.body = {\n data: aiFeatureConfig,\n };\n },\n};\n"],"names":["getAiToken","ctx","state","user","unauthorized","aiToken","strapi","get","body","data","error","errorMessage","internalServerError","getAiUsage","ERROR_PREFIX","USER_ERROR_MESSAGE","ee","isEE","log","eeLicense","process","env","STRAPI_LICENSE","licensePath","path","join","dirs","app","root","fs","readFileSync","toString","aiServerUrl","STRAPI_AI_URL","projectId","config","response","fetch","method","headers","crypto","randomUUID","JSON","stringify","eeKey","ok","errorData","errorText","text","parse","status","statusText","json","parseError","subscription","fetchError","Error","name","getAIFeatureConfig","aiFeatureConfig"],"mappings":"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"}
@@ -4,118 +4,19 @@ import crypto from 'crypto';
4
4
 
5
5
  var aiController = {
6
6
  async getAiToken (ctx) {
7
- const ERROR_PREFIX = 'AI token request failed:';
8
- const USER_ERROR_MESSAGE = 'AI token request failed. Check server logs for details.';
9
7
  try {
8
+ // TODO: auth check is not necessary? Already protected by route middleware?
10
9
  // Security check: Ensure user is authenticated and has proper permissions
11
10
  if (!ctx.state.user) {
12
11
  return ctx.unauthorized('Authentication required');
13
12
  }
14
- // Check if EE features are enabled first
15
- if (!strapi.ee?.isEE) {
16
- strapi.log.error(`${ERROR_PREFIX} Enterprise Edition features are not enabled`);
17
- return ctx.internalServerError(USER_ERROR_MESSAGE);
18
- }
19
- // Get the EE license
20
- // First try environment variable, then try reading from file
21
- let eeLicense = process.env.STRAPI_LICENSE;
22
- if (!eeLicense) {
23
- try {
24
- const licensePath = path.join(strapi.dirs.app.root, 'license.txt');
25
- eeLicense = fs.readFileSync(licensePath).toString();
26
- } catch (error) {
27
- // License file doesn't exist or can't be read
28
- }
29
- }
30
- if (!eeLicense) {
31
- strapi.log.error(`${ERROR_PREFIX} No EE license found. Please ensure STRAPI_LICENSE environment variable is set or license.txt file exists.`);
32
- return ctx.internalServerError(USER_ERROR_MESSAGE);
33
- }
34
- const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';
35
- if (!aiServerUrl) {
36
- strapi.log.error(`${ERROR_PREFIX} AI server URL not configured. Please set STRAPI_AI_URL environment variable.`);
37
- return ctx.internalServerError(USER_ERROR_MESSAGE);
38
- }
39
- // Get the current user
40
- const user = ctx.state.user;
41
- // Create a secure user identifier using only user ID
42
- const userIdentifier = user.id.toString();
43
- // Get project ID
44
- const projectId = strapi.config.get('uuid');
45
- if (!projectId) {
46
- strapi.log.error(`${ERROR_PREFIX} Project ID not configured`);
47
- return ctx.internalServerError(USER_ERROR_MESSAGE);
48
- }
49
- strapi.log.http('Contacting AI Server for token generation');
50
- try {
51
- // Call the AI server's getAiJWT endpoint
52
- const response = await fetch(`${aiServerUrl}/auth/getAiJWT`, {
53
- method: 'POST',
54
- headers: {
55
- 'Content-Type': 'application/json',
56
- // No authorization header needed for public endpoint
57
- // Add request ID for tracing
58
- 'X-Request-Id': crypto.randomUUID()
59
- },
60
- body: JSON.stringify({
61
- eeLicense,
62
- userIdentifier,
63
- projectId
64
- })
65
- });
66
- if (!response.ok) {
67
- let errorData;
68
- let errorText;
69
- try {
70
- errorText = await response.text();
71
- errorData = JSON.parse(errorText);
72
- } catch {
73
- errorData = {
74
- error: errorText || 'Failed to parse error response'
75
- };
76
- }
77
- strapi.log.error(`${ERROR_PREFIX} ${errorData?.error || 'Unknown error'}`, {
78
- status: response.status,
79
- statusText: response.statusText,
80
- error: errorData,
81
- errorText,
82
- projectId
83
- });
84
- return ctx.internalServerError(USER_ERROR_MESSAGE);
85
- }
86
- let data;
87
- try {
88
- data = await response.json();
89
- } catch (parseError) {
90
- strapi.log.error(`${ERROR_PREFIX} Failed to parse AI server response`, parseError);
91
- return ctx.internalServerError(USER_ERROR_MESSAGE);
92
- }
93
- if (!data.jwt) {
94
- strapi.log.error(`${ERROR_PREFIX} Invalid response: missing JWT token`);
95
- return ctx.internalServerError(USER_ERROR_MESSAGE);
96
- }
97
- strapi.log.info('AI token generated successfully', {
98
- userId: user.id,
99
- expiresAt: data.expiresAt
100
- });
101
- // Return the AI JWT with metadata
102
- // Note: Token expires in 1 hour, client should handle refresh
103
- ctx.body = {
104
- data: {
105
- token: data.jwt,
106
- expiresAt: data.expiresAt
107
- }
108
- };
109
- } catch (fetchError) {
110
- if (fetchError instanceof Error && fetchError.name === 'AbortError') {
111
- strapi.log.error(`${ERROR_PREFIX} Request to AI server timed out`);
112
- return ctx.internalServerError(USER_ERROR_MESSAGE);
113
- }
114
- throw fetchError;
115
- }
13
+ const aiToken = await strapi.get('ai').getAiToken();
14
+ ctx.body = {
15
+ data: aiToken
16
+ };
116
17
  } catch (error) {
117
- strapi.log.error(`${ERROR_PREFIX} ${error instanceof Error ? error.message : 'Unknown error'}`, error);
118
- return ctx.internalServerError(USER_ERROR_MESSAGE);
18
+ const errorMessage = 'AI token request failed. Check server logs for details.';
19
+ return ctx.internalServerError(errorMessage);
119
20
  }
120
21
  },
121
22
  async getAiUsage (ctx) {
@@ -1 +1 @@
1
- {"version":3,"file":"ai.mjs","sources":["../../../../../../../ee/server/src/ai/controllers/ai.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport path from 'path';\nimport fs from 'fs';\nimport crypto from 'crypto';\nimport type { AdminUser } from '../../../../../shared/contracts/shared';\nimport { GetAiToken } from '../../../../../shared/contracts/ai';\nimport { getService } from '../../utils';\n\nexport default {\n async getAiToken(ctx: Context) {\n const ERROR_PREFIX = 'AI token request failed:';\n const USER_ERROR_MESSAGE = 'AI token request failed. Check server logs for details.';\n\n try {\n // Security check: Ensure user is authenticated and has proper permissions\n if (!ctx.state.user) {\n return ctx.unauthorized('Authentication required');\n }\n\n // Check if EE features are enabled first\n if (!strapi.ee?.isEE) {\n strapi.log.error(`${ERROR_PREFIX} Enterprise Edition features are not enabled`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get the EE license\n // First try environment variable, then try reading from file\n let eeLicense = process.env.STRAPI_LICENSE;\n\n if (!eeLicense) {\n try {\n const licensePath = path.join(strapi.dirs.app.root, 'license.txt');\n eeLicense = fs.readFileSync(licensePath).toString();\n } catch (error) {\n // License file doesn't exist or can't be read\n }\n }\n\n if (!eeLicense) {\n strapi.log.error(\n `${ERROR_PREFIX} No EE license found. Please ensure STRAPI_LICENSE environment variable is set or license.txt file exists.`\n );\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n if (!aiServerUrl) {\n strapi.log.error(\n `${ERROR_PREFIX} AI server URL not configured. Please set STRAPI_AI_URL environment variable.`\n );\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get the current user\n const user = ctx.state.user as AdminUser;\n\n // Create a secure user identifier using only user ID\n const userIdentifier = user.id.toString();\n\n // Get project ID\n const projectId = strapi.config.get('uuid');\n if (!projectId) {\n strapi.log.error(`${ERROR_PREFIX} Project ID not configured`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n strapi.log.http('Contacting AI Server for token generation');\n\n try {\n // Call the AI server's getAiJWT endpoint\n const response = await fetch(`${aiServerUrl}/auth/getAiJWT`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n // No authorization header needed for public endpoint\n // Add request ID for tracing\n 'X-Request-Id': crypto.randomUUID(),\n },\n body: JSON.stringify({\n eeLicense,\n userIdentifier,\n projectId,\n }),\n });\n\n if (!response.ok) {\n let errorData;\n let errorText;\n try {\n errorText = await response.text();\n errorData = JSON.parse(errorText);\n } catch {\n errorData = { error: errorText || 'Failed to parse error response' };\n }\n\n strapi.log.error(`${ERROR_PREFIX} ${errorData?.error || 'Unknown error'}`, {\n status: response.status,\n statusText: response.statusText,\n error: errorData,\n errorText,\n projectId,\n });\n\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n let data;\n try {\n data = (await response.json()) as {\n jwt: string;\n expiresAt?: string;\n };\n } catch (parseError) {\n strapi.log.error(`${ERROR_PREFIX} Failed to parse AI server response`, parseError);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n if (!data.jwt) {\n strapi.log.error(`${ERROR_PREFIX} Invalid response: missing JWT token`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n strapi.log.info('AI token generated successfully', {\n userId: user.id,\n expiresAt: data.expiresAt,\n });\n\n // Return the AI JWT with metadata\n // Note: Token expires in 1 hour, client should handle refresh\n ctx.body = {\n data: {\n token: data.jwt,\n expiresAt: data.expiresAt, // 1 hour from generation\n },\n } satisfies GetAiToken.Response;\n } catch (fetchError) {\n if (fetchError instanceof Error && fetchError.name === 'AbortError') {\n strapi.log.error(`${ERROR_PREFIX} Request to AI server timed out`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n throw fetchError;\n }\n } catch (error) {\n strapi.log.error(\n `${ERROR_PREFIX} ${error instanceof Error ? error.message : 'Unknown error'}`,\n error\n );\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n },\n async getAiUsage(ctx: Context) {\n const ERROR_PREFIX = 'AI usage data request failed:';\n const USER_ERROR_MESSAGE = 'AI usage data request failed. Check server logs for details.';\n // Security check: Ensure user is authenticated and has proper permissions\n if (!ctx.state.user) {\n return ctx.unauthorized('Authentication required');\n }\n\n // Check if EE features are enabled first\n if (!strapi.ee?.isEE) {\n strapi.log.error(`${ERROR_PREFIX} Enterprise Edition features are not enabled`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get the EE license\n // First try environment variable, then try reading from file\n let eeLicense = process.env.STRAPI_LICENSE;\n\n if (!eeLicense) {\n try {\n const licensePath = path.join(strapi.dirs.app.root, 'license.txt');\n eeLicense = fs.readFileSync(licensePath).toString();\n } catch (error) {\n // License file doesn't exist or can't be read\n }\n }\n\n if (!eeLicense) {\n strapi.log.error(\n `${ERROR_PREFIX} No EE license found. Please ensure STRAPI_LICENSE environment variable is set or license.txt file exists.`\n );\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n if (!aiServerUrl) {\n strapi.log.error(\n `${ERROR_PREFIX} AI server URL not configured. Please set STRAPI_AI_URL or STRAPI_AI_URL environment variable.`\n );\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get project ID\n const projectId = strapi.config.get('uuid');\n if (!projectId) {\n strapi.log.error(`${ERROR_PREFIX} Project ID not configured`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n try {\n // Call the AI server's getAiJWT endpoint\n const response = await fetch(`${aiServerUrl}/cms/ai-data`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n // No authorization header needed for public endpoint\n // Add request ID for tracing\n 'X-Request-Id': crypto.randomUUID(),\n },\n body: JSON.stringify({\n eeKey: eeLicense,\n projectId,\n }),\n });\n\n if (!response.ok) {\n let errorData;\n let errorText;\n try {\n errorText = await response.text();\n errorData = JSON.parse(errorText);\n } catch {\n errorData = { error: errorText || 'Failed to parse error response' };\n }\n\n strapi.log.error(`${ERROR_PREFIX} ${errorData?.error || 'Unknown error'}`, {\n status: response.status,\n statusText: response.statusText,\n error: errorData,\n errorText,\n projectId,\n });\n\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n let data;\n try {\n data = (await response.json()) as {\n data: {\n cmsAiCreditsUsed: number;\n };\n subscription: {\n subscriptionId: string;\n planPriceId: string;\n subscriptionStatus: string;\n isActiveSubscription: boolean;\n cmsAiEnabled: boolean;\n cmsAiCreditsBase: number;\n cmsAiCreditsMaxUsage: number;\n currentTermStart: string;\n currentTermEnd: string;\n };\n };\n } catch (parseError) {\n strapi.log.error(`${ERROR_PREFIX} Failed to parse AI server response`, parseError);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n ctx.body = {\n ...data.data,\n subscription: data.subscription,\n };\n } catch (fetchError) {\n if (fetchError instanceof Error && fetchError.name === 'AbortError') {\n strapi.log.error(`${ERROR_PREFIX} Request to AI server timed out`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n throw fetchError;\n }\n },\n async getAIFeatureConfig(ctx: Context) {\n const aiFeatureConfig = await strapi.get('ai').getAIFeatureConfig();\n\n ctx.body = {\n data: aiFeatureConfig,\n };\n },\n};\n"],"names":["getAiToken","ctx","ERROR_PREFIX","USER_ERROR_MESSAGE","state","user","unauthorized","strapi","ee","isEE","log","error","internalServerError","eeLicense","process","env","STRAPI_LICENSE","licensePath","path","join","dirs","app","root","fs","readFileSync","toString","aiServerUrl","STRAPI_AI_URL","userIdentifier","id","projectId","config","get","http","response","fetch","method","headers","crypto","randomUUID","body","JSON","stringify","ok","errorData","errorText","text","parse","status","statusText","data","json","parseError","jwt","info","userId","expiresAt","token","fetchError","Error","name","message","getAiUsage","eeKey","subscription","getAIFeatureConfig","aiFeatureConfig"],"mappings":"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"}
1
+ {"version":3,"file":"ai.mjs","sources":["../../../../../../../ee/server/src/ai/controllers/ai.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport path from 'path';\nimport fs from 'fs';\nimport crypto from 'crypto';\nimport { GetAiToken } from '../../../../../shared/contracts/ai';\n\nexport default {\n async getAiToken(ctx: Context) {\n try {\n // TODO: auth check is not necessary? Already protected by route middleware?\n // Security check: Ensure user is authenticated and has proper permissions\n if (!ctx.state.user) {\n return ctx.unauthorized('Authentication required');\n }\n\n const aiToken = await strapi.get('ai').getAiToken();\n\n ctx.body = {\n data: aiToken,\n } satisfies GetAiToken.Response;\n } catch (error) {\n const errorMessage = 'AI token request failed. Check server logs for details.';\n return ctx.internalServerError(errorMessage);\n }\n },\n\n async getAiUsage(ctx: Context) {\n const ERROR_PREFIX = 'AI usage data request failed:';\n const USER_ERROR_MESSAGE = 'AI usage data request failed. Check server logs for details.';\n // Security check: Ensure user is authenticated and has proper permissions\n if (!ctx.state.user) {\n return ctx.unauthorized('Authentication required');\n }\n\n // Check if EE features are enabled first\n if (!strapi.ee?.isEE) {\n strapi.log.error(`${ERROR_PREFIX} Enterprise Edition features are not enabled`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get the EE license\n // First try environment variable, then try reading from file\n let eeLicense = process.env.STRAPI_LICENSE;\n\n if (!eeLicense) {\n try {\n const licensePath = path.join(strapi.dirs.app.root, 'license.txt');\n eeLicense = fs.readFileSync(licensePath).toString();\n } catch (error) {\n // License file doesn't exist or can't be read\n }\n }\n\n if (!eeLicense) {\n strapi.log.error(\n `${ERROR_PREFIX} No EE license found. Please ensure STRAPI_LICENSE environment variable is set or license.txt file exists.`\n );\n\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n if (!aiServerUrl) {\n strapi.log.error(\n `${ERROR_PREFIX} AI server URL not configured. Please set STRAPI_AI_URL or STRAPI_AI_URL environment variable.`\n );\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get project ID\n const projectId = strapi.config.get('uuid');\n if (!projectId) {\n strapi.log.error(`${ERROR_PREFIX} Project ID not configured`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n try {\n // Call the AI server's getAiJWT endpoint\n const response = await fetch(`${aiServerUrl}/cms/ai-data`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n // No authorization header needed for public endpoint\n // Add request ID for tracing\n 'X-Request-Id': crypto.randomUUID(),\n },\n body: JSON.stringify({\n eeKey: eeLicense,\n projectId,\n }),\n });\n\n if (!response.ok) {\n let errorData;\n let errorText;\n try {\n errorText = await response.text();\n errorData = JSON.parse(errorText);\n } catch {\n errorData = { error: errorText || 'Failed to parse error response' };\n }\n\n strapi.log.error(`${ERROR_PREFIX} ${errorData?.error || 'Unknown error'}`, {\n status: response.status,\n statusText: response.statusText,\n error: errorData,\n errorText,\n projectId,\n });\n\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n let data;\n try {\n data = (await response.json()) as {\n data: {\n cmsAiCreditsUsed: number;\n };\n subscription: {\n subscriptionId: string;\n planPriceId: string;\n subscriptionStatus: string;\n isActiveSubscription: boolean;\n cmsAiEnabled: boolean;\n cmsAiCreditsBase: number;\n cmsAiCreditsMaxUsage: number;\n currentTermStart: string;\n currentTermEnd: string;\n };\n };\n } catch (parseError) {\n strapi.log.error(`${ERROR_PREFIX} Failed to parse AI server response`, parseError);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n ctx.body = {\n ...data.data,\n subscription: data.subscription,\n };\n } catch (fetchError) {\n if (fetchError instanceof Error && fetchError.name === 'AbortError') {\n strapi.log.error(`${ERROR_PREFIX} Request to AI server timed out`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n throw fetchError;\n }\n },\n async getAIFeatureConfig(ctx: Context) {\n const aiFeatureConfig = await strapi.get('ai').getAIFeatureConfig();\n\n ctx.body = {\n data: aiFeatureConfig,\n };\n },\n};\n"],"names":["getAiToken","ctx","state","user","unauthorized","aiToken","strapi","get","body","data","error","errorMessage","internalServerError","getAiUsage","ERROR_PREFIX","USER_ERROR_MESSAGE","ee","isEE","log","eeLicense","process","env","STRAPI_LICENSE","licensePath","path","join","dirs","app","root","fs","readFileSync","toString","aiServerUrl","STRAPI_AI_URL","projectId","config","response","fetch","method","headers","crypto","randomUUID","JSON","stringify","eeKey","ok","errorData","errorText","text","parse","status","statusText","json","parseError","subscription","fetchError","Error","name","getAIFeatureConfig","aiFeatureConfig"],"mappings":"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"}
@@ -3,7 +3,6 @@
3
3
  var aiRoutes = {
4
4
  type: 'admin',
5
5
  routes: [
6
- // ai data usage
7
6
  {
8
7
  method: 'GET',
9
8
  path: '/ai-usage',
@@ -14,7 +13,6 @@ var aiRoutes = {
14
13
  ]
15
14
  }
16
15
  },
17
- // get ai token
18
16
  {
19
17
  method: 'GET',
20
18
  path: '/ai-token',
@@ -25,7 +23,6 @@ var aiRoutes = {
25
23
  ]
26
24
  }
27
25
  },
28
- // get ai feature settings
29
26
  {
30
27
  method: 'GET',
31
28
  path: '/ai-feature-config',
@@ -1 +1 @@
1
- {"version":3,"file":"ai.js","sources":["../../../../../../../ee/server/src/ai/routes/ai.ts"],"sourcesContent":["export default {\n type: 'admin',\n routes: [\n // ai data usage\n {\n method: 'GET',\n path: '/ai-usage',\n handler: 'ai.getAiUsage',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n // get ai token\n {\n method: 'GET',\n path: '/ai-token',\n handler: 'ai.getAiToken',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n // get ai feature settings\n {\n method: 'GET',\n path: '/ai-feature-config',\n handler: 'ai.getAIFeatureConfig',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n ],\n};\n"],"names":["type","routes","method","path","handler","config","policies"],"mappings":";;AAAA,eAAe;IACbA,IAAM,EAAA,OAAA;IACNC,MAAQ,EAAA;;AAEN,QAAA;YACEC,MAAQ,EAAA,KAAA;YACRC,IAAM,EAAA,WAAA;YACNC,OAAS,EAAA,eAAA;YACTC,MAAQ,EAAA;gBACNC,QAAU,EAAA;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;;AAEA,QAAA;YACEJ,MAAQ,EAAA,KAAA;YACRC,IAAM,EAAA,WAAA;YACNC,OAAS,EAAA,eAAA;YACTC,MAAQ,EAAA;gBACNC,QAAU,EAAA;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;;AAEA,QAAA;YACEJ,MAAQ,EAAA,KAAA;YACRC,IAAM,EAAA,oBAAA;YACNC,OAAS,EAAA,uBAAA;YACTC,MAAQ,EAAA;gBACNC,QAAU,EAAA;AAAC,oBAAA;AAA8B;AAC3C;AACF;AACD;AACH,CAAE;;;;"}
1
+ {"version":3,"file":"ai.js","sources":["../../../../../../../ee/server/src/ai/routes/ai.ts"],"sourcesContent":["export default {\n type: 'admin',\n routes: [\n {\n method: 'GET',\n path: '/ai-usage',\n handler: 'ai.getAiUsage',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-token',\n handler: 'ai.getAiToken',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-feature-config',\n handler: 'ai.getAIFeatureConfig',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n ],\n};\n"],"names":["type","routes","method","path","handler","config","policies"],"mappings":";;AAAA,eAAe;IACbA,IAAM,EAAA,OAAA;IACNC,MAAQ,EAAA;AACN,QAAA;YACEC,MAAQ,EAAA,KAAA;YACRC,IAAM,EAAA,WAAA;YACNC,OAAS,EAAA,eAAA;YACTC,MAAQ,EAAA;gBACNC,QAAU,EAAA;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAQ,EAAA,KAAA;YACRC,IAAM,EAAA,WAAA;YACNC,OAAS,EAAA,eAAA;YACTC,MAAQ,EAAA;gBACNC,QAAU,EAAA;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAQ,EAAA,KAAA;YACRC,IAAM,EAAA,oBAAA;YACNC,OAAS,EAAA,uBAAA;YACTC,MAAQ,EAAA;gBACNC,QAAU,EAAA;AAAC,oBAAA;AAA8B;AAC3C;AACF;AACD;AACH,CAAE;;;;"}
@@ -1,7 +1,6 @@
1
1
  var aiRoutes = {
2
2
  type: 'admin',
3
3
  routes: [
4
- // ai data usage
5
4
  {
6
5
  method: 'GET',
7
6
  path: '/ai-usage',
@@ -12,7 +11,6 @@ var aiRoutes = {
12
11
  ]
13
12
  }
14
13
  },
15
- // get ai token
16
14
  {
17
15
  method: 'GET',
18
16
  path: '/ai-token',
@@ -23,7 +21,6 @@ var aiRoutes = {
23
21
  ]
24
22
  }
25
23
  },
26
- // get ai feature settings
27
24
  {
28
25
  method: 'GET',
29
26
  path: '/ai-feature-config',
@@ -1 +1 @@
1
- {"version":3,"file":"ai.mjs","sources":["../../../../../../../ee/server/src/ai/routes/ai.ts"],"sourcesContent":["export default {\n type: 'admin',\n routes: [\n // ai data usage\n {\n method: 'GET',\n path: '/ai-usage',\n handler: 'ai.getAiUsage',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n // get ai token\n {\n method: 'GET',\n path: '/ai-token',\n handler: 'ai.getAiToken',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n // get ai feature settings\n {\n method: 'GET',\n path: '/ai-feature-config',\n handler: 'ai.getAIFeatureConfig',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n ],\n};\n"],"names":["type","routes","method","path","handler","config","policies"],"mappings":"AAAA,eAAe;IACbA,IAAM,EAAA,OAAA;IACNC,MAAQ,EAAA;;AAEN,QAAA;YACEC,MAAQ,EAAA,KAAA;YACRC,IAAM,EAAA,WAAA;YACNC,OAAS,EAAA,eAAA;YACTC,MAAQ,EAAA;gBACNC,QAAU,EAAA;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;;AAEA,QAAA;YACEJ,MAAQ,EAAA,KAAA;YACRC,IAAM,EAAA,WAAA;YACNC,OAAS,EAAA,eAAA;YACTC,MAAQ,EAAA;gBACNC,QAAU,EAAA;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;;AAEA,QAAA;YACEJ,MAAQ,EAAA,KAAA;YACRC,IAAM,EAAA,oBAAA;YACNC,OAAS,EAAA,uBAAA;YACTC,MAAQ,EAAA;gBACNC,QAAU,EAAA;AAAC,oBAAA;AAA8B;AAC3C;AACF;AACD;AACH,CAAE;;;;"}
1
+ {"version":3,"file":"ai.mjs","sources":["../../../../../../../ee/server/src/ai/routes/ai.ts"],"sourcesContent":["export default {\n type: 'admin',\n routes: [\n {\n method: 'GET',\n path: '/ai-usage',\n handler: 'ai.getAiUsage',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-token',\n handler: 'ai.getAiToken',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-feature-config',\n handler: 'ai.getAIFeatureConfig',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n ],\n};\n"],"names":["type","routes","method","path","handler","config","policies"],"mappings":"AAAA,eAAe;IACbA,IAAM,EAAA,OAAA;IACNC,MAAQ,EAAA;AACN,QAAA;YACEC,MAAQ,EAAA,KAAA;YACRC,IAAM,EAAA,WAAA;YACNC,OAAS,EAAA,eAAA;YACTC,MAAQ,EAAA;gBACNC,QAAU,EAAA;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAQ,EAAA,KAAA;YACRC,IAAM,EAAA,WAAA;YACNC,OAAS,EAAA,eAAA;YACTC,MAAQ,EAAA;gBACNC,QAAU,EAAA;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAQ,EAAA,KAAA;YACRC,IAAM,EAAA,oBAAA;YACNC,OAAS,EAAA,uBAAA;YACTC,MAAQ,EAAA;gBACNC,QAAU,EAAA;AAAC,oBAAA;AAA8B;AAC3C;AACF;AACD;AACH,CAAE;;;;"}
@@ -39,21 +39,6 @@ var authenticatedUser = {
39
39
  // @ts-expect-error - transform response type to sanitized permission
40
40
  data: userPermissions.map(sanitizePermission)
41
41
  };
42
- },
43
- async getAiToken (ctx) {
44
- try {
45
- // Security check: Ensure user is authenticated and has proper permissions
46
- if (!ctx.state.user) {
47
- return ctx.unauthorized('Authentication required');
48
- }
49
- const tokenData = await index.getService('user').getAiToken();
50
- ctx.body = {
51
- data: tokenData
52
- };
53
- } catch (error) {
54
- const errorMessage = 'AI token request failed. Check server logs for details.';
55
- return ctx.internalServerError(errorMessage);
56
- }
57
42
  }
58
43
  };
59
44
 
@@ -1 +1 @@
1
- {"version":3,"file":"authenticated-user.js","sources":["../../../../../server/src/controllers/authenticated-user.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport type { AdminUser } from '../../../shared/contracts/shared';\n\nimport { getService } from '../utils';\nimport { validateProfileUpdateInput } from '../validation/user';\nimport { GetMe, GetOwnPermissions, UpdateMe, GetAiToken } from '../../../shared/contracts/users';\n\nexport default {\n async getMe(ctx: Context) {\n const userInfo = getService('user').sanitizeUser(ctx.state.user as AdminUser);\n\n ctx.body = {\n data: userInfo,\n } satisfies GetMe.Response;\n },\n\n async updateMe(ctx: Context) {\n const input = ctx.request.body as UpdateMe.Request['body'];\n\n await validateProfileUpdateInput(input);\n\n const userService = getService('user');\n const authServer = getService('auth');\n\n const { currentPassword, ...userInfo } = input;\n\n if (currentPassword && userInfo.password) {\n const isValid = await authServer.validatePassword(currentPassword, ctx.state.user.password);\n\n if (!isValid) {\n return ctx.badRequest('ValidationError', {\n currentPassword: ['Invalid credentials'],\n });\n }\n }\n\n const updatedUser = await userService.updateById(ctx.state.user.id, userInfo);\n\n ctx.body = {\n data: userService.sanitizeUser(updatedUser),\n } satisfies UpdateMe.Response;\n },\n\n async getOwnPermissions(ctx: Context) {\n const { findUserPermissions, sanitizePermission } = getService('permission');\n const { user } = ctx.state;\n\n const userPermissions = await findUserPermissions(user as AdminUser);\n\n ctx.body = {\n // @ts-expect-error - transform response type to sanitized permission\n data: userPermissions.map(sanitizePermission),\n } satisfies GetOwnPermissions.Response;\n },\n\n async getAiToken(ctx: Context) {\n try {\n // Security check: Ensure user is authenticated and has proper permissions\n if (!ctx.state.user) {\n return ctx.unauthorized('Authentication required');\n }\n\n const tokenData = await getService('user').getAiToken();\n\n ctx.body = {\n data: tokenData,\n } satisfies GetAiToken.Response;\n } catch (error) {\n const errorMessage = 'AI token request failed. Check server logs for details.';\n return ctx.internalServerError(errorMessage);\n }\n },\n};\n"],"names":["getMe","ctx","userInfo","getService","sanitizeUser","state","user","body","data","updateMe","input","request","validateProfileUpdateInput","userService","authServer","currentPassword","password","isValid","validatePassword","badRequest","updatedUser","updateById","id","getOwnPermissions","findUserPermissions","sanitizePermission","userPermissions","map","getAiToken","unauthorized","tokenData","error","errorMessage","internalServerError"],"mappings":";;;;;AAOA,wBAAe;AACb,IAAA,MAAMA,OAAMC,GAAY,EAAA;QACtB,MAAMC,QAAAA,GAAWC,iBAAW,MAAQC,CAAAA,CAAAA,YAAY,CAACH,GAAII,CAAAA,KAAK,CAACC,IAAI,CAAA;AAE/DL,QAAAA,GAAAA,CAAIM,IAAI,GAAG;YACTC,IAAMN,EAAAA;AACR,SAAA;AACF,KAAA;AAEA,IAAA,MAAMO,UAASR,GAAY,EAAA;AACzB,QAAA,MAAMS,KAAQT,GAAAA,GAAAA,CAAIU,OAAO,CAACJ,IAAI;AAE9B,QAAA,MAAMK,+BAA2BF,CAAAA,KAAAA,CAAAA;AAEjC,QAAA,MAAMG,cAAcV,gBAAW,CAAA,MAAA,CAAA;AAC/B,QAAA,MAAMW,aAAaX,gBAAW,CAAA,MAAA,CAAA;AAE9B,QAAA,MAAM,EAAEY,eAAe,EAAE,GAAGb,UAAU,GAAGQ,KAAAA;QAEzC,IAAIK,eAAAA,IAAmBb,QAASc,CAAAA,QAAQ,EAAE;YACxC,MAAMC,OAAAA,GAAU,MAAMH,UAAAA,CAAWI,gBAAgB,CAACH,eAAiBd,EAAAA,GAAAA,CAAII,KAAK,CAACC,IAAI,CAACU,QAAQ,CAAA;AAE1F,YAAA,IAAI,CAACC,OAAS,EAAA;gBACZ,OAAOhB,GAAAA,CAAIkB,UAAU,CAAC,iBAAmB,EAAA;oBACvCJ,eAAiB,EAAA;AAAC,wBAAA;AAAsB;AAC1C,iBAAA,CAAA;AACF;AACF;QAEA,MAAMK,WAAAA,GAAc,MAAMP,WAAAA,CAAYQ,UAAU,CAACpB,GAAII,CAAAA,KAAK,CAACC,IAAI,CAACgB,EAAE,EAAEpB,QAAAA,CAAAA;AAEpED,QAAAA,GAAAA,CAAIM,IAAI,GAAG;YACTC,IAAMK,EAAAA,WAAAA,CAAYT,YAAY,CAACgB,WAAAA;AACjC,SAAA;AACF,KAAA;AAEA,IAAA,MAAMG,mBAAkBtB,GAAY,EAAA;AAClC,QAAA,MAAM,EAAEuB,mBAAmB,EAAEC,kBAAkB,EAAE,GAAGtB,gBAAW,CAAA,YAAA,CAAA;AAC/D,QAAA,MAAM,EAAEG,IAAI,EAAE,GAAGL,IAAII,KAAK;QAE1B,MAAMqB,eAAAA,GAAkB,MAAMF,mBAAoBlB,CAAAA,IAAAA,CAAAA;AAElDL,QAAAA,GAAAA,CAAIM,IAAI,GAAG;;YAETC,IAAMkB,EAAAA,eAAAA,CAAgBC,GAAG,CAACF,kBAAAA;AAC5B,SAAA;AACF,KAAA;AAEA,IAAA,MAAMG,YAAW3B,GAAY,EAAA;QAC3B,IAAI;;AAEF,YAAA,IAAI,CAACA,GAAAA,CAAII,KAAK,CAACC,IAAI,EAAE;gBACnB,OAAOL,GAAAA,CAAI4B,YAAY,CAAC,yBAAA,CAAA;AAC1B;AAEA,YAAA,MAAMC,SAAY,GAAA,MAAM3B,gBAAW,CAAA,MAAA,CAAA,CAAQyB,UAAU,EAAA;AAErD3B,YAAAA,GAAAA,CAAIM,IAAI,GAAG;gBACTC,IAAMsB,EAAAA;AACR,aAAA;AACF,SAAA,CAAE,OAAOC,KAAO,EAAA;AACd,YAAA,MAAMC,YAAe,GAAA,yDAAA;YACrB,OAAO/B,GAAAA,CAAIgC,mBAAmB,CAACD,YAAAA,CAAAA;AACjC;AACF;AACF,CAAE;;;;"}
1
+ {"version":3,"file":"authenticated-user.js","sources":["../../../../../server/src/controllers/authenticated-user.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport type { AdminUser } from '../../../shared/contracts/shared';\n\nimport { getService } from '../utils';\nimport { validateProfileUpdateInput } from '../validation/user';\nimport { GetMe, GetOwnPermissions, UpdateMe } from '../../../shared/contracts/users';\n\nexport default {\n async getMe(ctx: Context) {\n const userInfo = getService('user').sanitizeUser(ctx.state.user as AdminUser);\n\n ctx.body = {\n data: userInfo,\n } satisfies GetMe.Response;\n },\n\n async updateMe(ctx: Context) {\n const input = ctx.request.body as UpdateMe.Request['body'];\n\n await validateProfileUpdateInput(input);\n\n const userService = getService('user');\n const authServer = getService('auth');\n\n const { currentPassword, ...userInfo } = input;\n\n if (currentPassword && userInfo.password) {\n const isValid = await authServer.validatePassword(currentPassword, ctx.state.user.password);\n\n if (!isValid) {\n return ctx.badRequest('ValidationError', {\n currentPassword: ['Invalid credentials'],\n });\n }\n }\n\n const updatedUser = await userService.updateById(ctx.state.user.id, userInfo);\n\n ctx.body = {\n data: userService.sanitizeUser(updatedUser),\n } satisfies UpdateMe.Response;\n },\n\n async getOwnPermissions(ctx: Context) {\n const { findUserPermissions, sanitizePermission } = getService('permission');\n const { user } = ctx.state;\n\n const userPermissions = await findUserPermissions(user as AdminUser);\n\n ctx.body = {\n // @ts-expect-error - transform response type to sanitized permission\n data: userPermissions.map(sanitizePermission),\n } satisfies GetOwnPermissions.Response;\n },\n};\n"],"names":["getMe","ctx","userInfo","getService","sanitizeUser","state","user","body","data","updateMe","input","request","validateProfileUpdateInput","userService","authServer","currentPassword","password","isValid","validatePassword","badRequest","updatedUser","updateById","id","getOwnPermissions","findUserPermissions","sanitizePermission","userPermissions","map"],"mappings":";;;;;AAOA,wBAAe;AACb,IAAA,MAAMA,OAAMC,GAAY,EAAA;QACtB,MAAMC,QAAAA,GAAWC,iBAAW,MAAQC,CAAAA,CAAAA,YAAY,CAACH,GAAII,CAAAA,KAAK,CAACC,IAAI,CAAA;AAE/DL,QAAAA,GAAAA,CAAIM,IAAI,GAAG;YACTC,IAAMN,EAAAA;AACR,SAAA;AACF,KAAA;AAEA,IAAA,MAAMO,UAASR,GAAY,EAAA;AACzB,QAAA,MAAMS,KAAQT,GAAAA,GAAAA,CAAIU,OAAO,CAACJ,IAAI;AAE9B,QAAA,MAAMK,+BAA2BF,CAAAA,KAAAA,CAAAA;AAEjC,QAAA,MAAMG,cAAcV,gBAAW,CAAA,MAAA,CAAA;AAC/B,QAAA,MAAMW,aAAaX,gBAAW,CAAA,MAAA,CAAA;AAE9B,QAAA,MAAM,EAAEY,eAAe,EAAE,GAAGb,UAAU,GAAGQ,KAAAA;QAEzC,IAAIK,eAAAA,IAAmBb,QAASc,CAAAA,QAAQ,EAAE;YACxC,MAAMC,OAAAA,GAAU,MAAMH,UAAAA,CAAWI,gBAAgB,CAACH,eAAiBd,EAAAA,GAAAA,CAAII,KAAK,CAACC,IAAI,CAACU,QAAQ,CAAA;AAE1F,YAAA,IAAI,CAACC,OAAS,EAAA;gBACZ,OAAOhB,GAAAA,CAAIkB,UAAU,CAAC,iBAAmB,EAAA;oBACvCJ,eAAiB,EAAA;AAAC,wBAAA;AAAsB;AAC1C,iBAAA,CAAA;AACF;AACF;QAEA,MAAMK,WAAAA,GAAc,MAAMP,WAAAA,CAAYQ,UAAU,CAACpB,GAAII,CAAAA,KAAK,CAACC,IAAI,CAACgB,EAAE,EAAEpB,QAAAA,CAAAA;AAEpED,QAAAA,GAAAA,CAAIM,IAAI,GAAG;YACTC,IAAMK,EAAAA,WAAAA,CAAYT,YAAY,CAACgB,WAAAA;AACjC,SAAA;AACF,KAAA;AAEA,IAAA,MAAMG,mBAAkBtB,GAAY,EAAA;AAClC,QAAA,MAAM,EAAEuB,mBAAmB,EAAEC,kBAAkB,EAAE,GAAGtB,gBAAW,CAAA,YAAA,CAAA;AAC/D,QAAA,MAAM,EAAEG,IAAI,EAAE,GAAGL,IAAII,KAAK;QAE1B,MAAMqB,eAAAA,GAAkB,MAAMF,mBAAoBlB,CAAAA,IAAAA,CAAAA;AAElDL,QAAAA,GAAAA,CAAIM,IAAI,GAAG;;YAETC,IAAMkB,EAAAA,eAAAA,CAAgBC,GAAG,CAACF,kBAAAA;AAC5B,SAAA;AACF;AACF,CAAE;;;;"}
@@ -37,21 +37,6 @@ var authenticatedUser = {
37
37
  // @ts-expect-error - transform response type to sanitized permission
38
38
  data: userPermissions.map(sanitizePermission)
39
39
  };
40
- },
41
- async getAiToken (ctx) {
42
- try {
43
- // Security check: Ensure user is authenticated and has proper permissions
44
- if (!ctx.state.user) {
45
- return ctx.unauthorized('Authentication required');
46
- }
47
- const tokenData = await getService('user').getAiToken();
48
- ctx.body = {
49
- data: tokenData
50
- };
51
- } catch (error) {
52
- const errorMessage = 'AI token request failed. Check server logs for details.';
53
- return ctx.internalServerError(errorMessage);
54
- }
55
40
  }
56
41
  };
57
42
 
@@ -1 +1 @@
1
- {"version":3,"file":"authenticated-user.mjs","sources":["../../../../../server/src/controllers/authenticated-user.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport type { AdminUser } from '../../../shared/contracts/shared';\n\nimport { getService } from '../utils';\nimport { validateProfileUpdateInput } from '../validation/user';\nimport { GetMe, GetOwnPermissions, UpdateMe, GetAiToken } from '../../../shared/contracts/users';\n\nexport default {\n async getMe(ctx: Context) {\n const userInfo = getService('user').sanitizeUser(ctx.state.user as AdminUser);\n\n ctx.body = {\n data: userInfo,\n } satisfies GetMe.Response;\n },\n\n async updateMe(ctx: Context) {\n const input = ctx.request.body as UpdateMe.Request['body'];\n\n await validateProfileUpdateInput(input);\n\n const userService = getService('user');\n const authServer = getService('auth');\n\n const { currentPassword, ...userInfo } = input;\n\n if (currentPassword && userInfo.password) {\n const isValid = await authServer.validatePassword(currentPassword, ctx.state.user.password);\n\n if (!isValid) {\n return ctx.badRequest('ValidationError', {\n currentPassword: ['Invalid credentials'],\n });\n }\n }\n\n const updatedUser = await userService.updateById(ctx.state.user.id, userInfo);\n\n ctx.body = {\n data: userService.sanitizeUser(updatedUser),\n } satisfies UpdateMe.Response;\n },\n\n async getOwnPermissions(ctx: Context) {\n const { findUserPermissions, sanitizePermission } = getService('permission');\n const { user } = ctx.state;\n\n const userPermissions = await findUserPermissions(user as AdminUser);\n\n ctx.body = {\n // @ts-expect-error - transform response type to sanitized permission\n data: userPermissions.map(sanitizePermission),\n } satisfies GetOwnPermissions.Response;\n },\n\n async getAiToken(ctx: Context) {\n try {\n // Security check: Ensure user is authenticated and has proper permissions\n if (!ctx.state.user) {\n return ctx.unauthorized('Authentication required');\n }\n\n const tokenData = await getService('user').getAiToken();\n\n ctx.body = {\n data: tokenData,\n } satisfies GetAiToken.Response;\n } catch (error) {\n const errorMessage = 'AI token request failed. Check server logs for details.';\n return ctx.internalServerError(errorMessage);\n }\n },\n};\n"],"names":["getMe","ctx","userInfo","getService","sanitizeUser","state","user","body","data","updateMe","input","request","validateProfileUpdateInput","userService","authServer","currentPassword","password","isValid","validatePassword","badRequest","updatedUser","updateById","id","getOwnPermissions","findUserPermissions","sanitizePermission","userPermissions","map","getAiToken","unauthorized","tokenData","error","errorMessage","internalServerError"],"mappings":";;;AAOA,wBAAe;AACb,IAAA,MAAMA,OAAMC,GAAY,EAAA;QACtB,MAAMC,QAAAA,GAAWC,WAAW,MAAQC,CAAAA,CAAAA,YAAY,CAACH,GAAII,CAAAA,KAAK,CAACC,IAAI,CAAA;AAE/DL,QAAAA,GAAAA,CAAIM,IAAI,GAAG;YACTC,IAAMN,EAAAA;AACR,SAAA;AACF,KAAA;AAEA,IAAA,MAAMO,UAASR,GAAY,EAAA;AACzB,QAAA,MAAMS,KAAQT,GAAAA,GAAAA,CAAIU,OAAO,CAACJ,IAAI;AAE9B,QAAA,MAAMK,0BAA2BF,CAAAA,KAAAA,CAAAA;AAEjC,QAAA,MAAMG,cAAcV,UAAW,CAAA,MAAA,CAAA;AAC/B,QAAA,MAAMW,aAAaX,UAAW,CAAA,MAAA,CAAA;AAE9B,QAAA,MAAM,EAAEY,eAAe,EAAE,GAAGb,UAAU,GAAGQ,KAAAA;QAEzC,IAAIK,eAAAA,IAAmBb,QAASc,CAAAA,QAAQ,EAAE;YACxC,MAAMC,OAAAA,GAAU,MAAMH,UAAAA,CAAWI,gBAAgB,CAACH,eAAiBd,EAAAA,GAAAA,CAAII,KAAK,CAACC,IAAI,CAACU,QAAQ,CAAA;AAE1F,YAAA,IAAI,CAACC,OAAS,EAAA;gBACZ,OAAOhB,GAAAA,CAAIkB,UAAU,CAAC,iBAAmB,EAAA;oBACvCJ,eAAiB,EAAA;AAAC,wBAAA;AAAsB;AAC1C,iBAAA,CAAA;AACF;AACF;QAEA,MAAMK,WAAAA,GAAc,MAAMP,WAAAA,CAAYQ,UAAU,CAACpB,GAAII,CAAAA,KAAK,CAACC,IAAI,CAACgB,EAAE,EAAEpB,QAAAA,CAAAA;AAEpED,QAAAA,GAAAA,CAAIM,IAAI,GAAG;YACTC,IAAMK,EAAAA,WAAAA,CAAYT,YAAY,CAACgB,WAAAA;AACjC,SAAA;AACF,KAAA;AAEA,IAAA,MAAMG,mBAAkBtB,GAAY,EAAA;AAClC,QAAA,MAAM,EAAEuB,mBAAmB,EAAEC,kBAAkB,EAAE,GAAGtB,UAAW,CAAA,YAAA,CAAA;AAC/D,QAAA,MAAM,EAAEG,IAAI,EAAE,GAAGL,IAAII,KAAK;QAE1B,MAAMqB,eAAAA,GAAkB,MAAMF,mBAAoBlB,CAAAA,IAAAA,CAAAA;AAElDL,QAAAA,GAAAA,CAAIM,IAAI,GAAG;;YAETC,IAAMkB,EAAAA,eAAAA,CAAgBC,GAAG,CAACF,kBAAAA;AAC5B,SAAA;AACF,KAAA;AAEA,IAAA,MAAMG,YAAW3B,GAAY,EAAA;QAC3B,IAAI;;AAEF,YAAA,IAAI,CAACA,GAAAA,CAAII,KAAK,CAACC,IAAI,EAAE;gBACnB,OAAOL,GAAAA,CAAI4B,YAAY,CAAC,yBAAA,CAAA;AAC1B;AAEA,YAAA,MAAMC,SAAY,GAAA,MAAM3B,UAAW,CAAA,MAAA,CAAA,CAAQyB,UAAU,EAAA;AAErD3B,YAAAA,GAAAA,CAAIM,IAAI,GAAG;gBACTC,IAAMsB,EAAAA;AACR,aAAA;AACF,SAAA,CAAE,OAAOC,KAAO,EAAA;AACd,YAAA,MAAMC,YAAe,GAAA,yDAAA;YACrB,OAAO/B,GAAAA,CAAIgC,mBAAmB,CAACD,YAAAA,CAAAA;AACjC;AACF;AACF,CAAE;;;;"}
1
+ {"version":3,"file":"authenticated-user.mjs","sources":["../../../../../server/src/controllers/authenticated-user.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport type { AdminUser } from '../../../shared/contracts/shared';\n\nimport { getService } from '../utils';\nimport { validateProfileUpdateInput } from '../validation/user';\nimport { GetMe, GetOwnPermissions, UpdateMe } from '../../../shared/contracts/users';\n\nexport default {\n async getMe(ctx: Context) {\n const userInfo = getService('user').sanitizeUser(ctx.state.user as AdminUser);\n\n ctx.body = {\n data: userInfo,\n } satisfies GetMe.Response;\n },\n\n async updateMe(ctx: Context) {\n const input = ctx.request.body as UpdateMe.Request['body'];\n\n await validateProfileUpdateInput(input);\n\n const userService = getService('user');\n const authServer = getService('auth');\n\n const { currentPassword, ...userInfo } = input;\n\n if (currentPassword && userInfo.password) {\n const isValid = await authServer.validatePassword(currentPassword, ctx.state.user.password);\n\n if (!isValid) {\n return ctx.badRequest('ValidationError', {\n currentPassword: ['Invalid credentials'],\n });\n }\n }\n\n const updatedUser = await userService.updateById(ctx.state.user.id, userInfo);\n\n ctx.body = {\n data: userService.sanitizeUser(updatedUser),\n } satisfies UpdateMe.Response;\n },\n\n async getOwnPermissions(ctx: Context) {\n const { findUserPermissions, sanitizePermission } = getService('permission');\n const { user } = ctx.state;\n\n const userPermissions = await findUserPermissions(user as AdminUser);\n\n ctx.body = {\n // @ts-expect-error - transform response type to sanitized permission\n data: userPermissions.map(sanitizePermission),\n } satisfies GetOwnPermissions.Response;\n },\n};\n"],"names":["getMe","ctx","userInfo","getService","sanitizeUser","state","user","body","data","updateMe","input","request","validateProfileUpdateInput","userService","authServer","currentPassword","password","isValid","validatePassword","badRequest","updatedUser","updateById","id","getOwnPermissions","findUserPermissions","sanitizePermission","userPermissions","map"],"mappings":";;;AAOA,wBAAe;AACb,IAAA,MAAMA,OAAMC,GAAY,EAAA;QACtB,MAAMC,QAAAA,GAAWC,WAAW,MAAQC,CAAAA,CAAAA,YAAY,CAACH,GAAII,CAAAA,KAAK,CAACC,IAAI,CAAA;AAE/DL,QAAAA,GAAAA,CAAIM,IAAI,GAAG;YACTC,IAAMN,EAAAA;AACR,SAAA;AACF,KAAA;AAEA,IAAA,MAAMO,UAASR,GAAY,EAAA;AACzB,QAAA,MAAMS,KAAQT,GAAAA,GAAAA,CAAIU,OAAO,CAACJ,IAAI;AAE9B,QAAA,MAAMK,0BAA2BF,CAAAA,KAAAA,CAAAA;AAEjC,QAAA,MAAMG,cAAcV,UAAW,CAAA,MAAA,CAAA;AAC/B,QAAA,MAAMW,aAAaX,UAAW,CAAA,MAAA,CAAA;AAE9B,QAAA,MAAM,EAAEY,eAAe,EAAE,GAAGb,UAAU,GAAGQ,KAAAA;QAEzC,IAAIK,eAAAA,IAAmBb,QAASc,CAAAA,QAAQ,EAAE;YACxC,MAAMC,OAAAA,GAAU,MAAMH,UAAAA,CAAWI,gBAAgB,CAACH,eAAiBd,EAAAA,GAAAA,CAAII,KAAK,CAACC,IAAI,CAACU,QAAQ,CAAA;AAE1F,YAAA,IAAI,CAACC,OAAS,EAAA;gBACZ,OAAOhB,GAAAA,CAAIkB,UAAU,CAAC,iBAAmB,EAAA;oBACvCJ,eAAiB,EAAA;AAAC,wBAAA;AAAsB;AAC1C,iBAAA,CAAA;AACF;AACF;QAEA,MAAMK,WAAAA,GAAc,MAAMP,WAAAA,CAAYQ,UAAU,CAACpB,GAAII,CAAAA,KAAK,CAACC,IAAI,CAACgB,EAAE,EAAEpB,QAAAA,CAAAA;AAEpED,QAAAA,GAAAA,CAAIM,IAAI,GAAG;YACTC,IAAMK,EAAAA,WAAAA,CAAYT,YAAY,CAACgB,WAAAA;AACjC,SAAA;AACF,KAAA;AAEA,IAAA,MAAMG,mBAAkBtB,GAAY,EAAA;AAClC,QAAA,MAAM,EAAEuB,mBAAmB,EAAEC,kBAAkB,EAAE,GAAGtB,UAAW,CAAA,YAAA,CAAA;AAC/D,QAAA,MAAM,EAAEG,IAAI,EAAE,GAAGL,IAAII,KAAK;QAE1B,MAAMqB,eAAAA,GAAkB,MAAMF,mBAAoBlB,CAAAA,IAAAA,CAAAA;AAElDL,QAAAA,GAAAA,CAAIM,IAAI,GAAG;;YAETC,IAAMkB,EAAAA,eAAAA,CAAgBC,GAAG,CAACF,kBAAAA;AAC5B,SAAA;AACF;AACF,CAAE;;;;"}
@@ -31,16 +31,6 @@ var users = [
31
31
  ]
32
32
  }
33
33
  },
34
- {
35
- method: 'GET',
36
- path: '/users/me/ai-token',
37
- handler: 'authenticated-user.getAiToken',
38
- config: {
39
- policies: [
40
- 'admin::isAuthenticatedAdmin'
41
- ]
42
- }
43
- },
44
34
  {
45
35
  method: 'POST',
46
36
  path: '/users',
@@ -1 +1 @@
1
- {"version":3,"file":"users.js","sources":["../../../../../server/src/routes/users.ts"],"sourcesContent":["export default [\n {\n method: 'GET',\n path: '/users/me',\n handler: 'authenticated-user.getMe',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'PUT',\n path: '/users/me',\n handler: 'authenticated-user.updateMe',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/users/me/permissions',\n handler: 'authenticated-user.getOwnPermissions',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/users/me/ai-token',\n handler: 'authenticated-user.getAiToken',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'POST',\n path: '/users',\n handler: 'user.create',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.create'] } },\n ],\n },\n },\n {\n method: 'GET',\n path: '/users',\n handler: 'user.find',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.read'] } },\n ],\n },\n },\n {\n method: 'GET',\n path: '/users/:id',\n handler: 'user.findOne',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.read'] } },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/users/:id',\n handler: 'user.update',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.update'] } },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/users/:id',\n handler: 'user.deleteOne',\n config: {\n policies: [{ name: 'admin::hasPermissions', config: { actions: ['admin::users.delete'] } }],\n },\n },\n {\n method: 'POST',\n path: '/users/batch-delete',\n handler: 'user.deleteMany',\n config: {\n policies: [{ name: 'admin::hasPermissions', config: { actions: ['admin::users.delete'] } }],\n },\n },\n];\n"],"names":["method","path","handler","config","policies","name","actions"],"mappings":";;AAAA,YAAe;AACb,IAAA;QACEA,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,WAAA;QACNC,OAAS,EAAA,0BAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;AAA8B;AAC3C;AACF,KAAA;AACA,IAAA;QACEJ,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,WAAA;QACNC,OAAS,EAAA,6BAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;AAA8B;AAC3C;AACF,KAAA;AACA,IAAA;QACEJ,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,uBAAA;QACNC,OAAS,EAAA,sCAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;AAA8B;AAC3C;AACF,KAAA;AACA,IAAA;QACEJ,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,oBAAA;QACNC,OAAS,EAAA,+BAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;AAA8B;AAC3C;AACF,KAAA;AACA,IAAA;QACEJ,MAAQ,EAAA,MAAA;QACRC,IAAM,EAAA,QAAA;QACNC,OAAS,EAAA,aAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAC/E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,QAAA;QACNC,OAAS,EAAA,WAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAoB;AAAC;AAAE;AAC7E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,YAAA;QACNC,OAAS,EAAA,cAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAoB;AAAC;AAAE;AAC7E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,YAAA;QACNC,OAAS,EAAA,aAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAC/E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,QAAA;QACRC,IAAM,EAAA,YAAA;QACNC,OAAS,EAAA,gBAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAAE;AAC7F;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,MAAA;QACRC,IAAM,EAAA,qBAAA;QACNC,OAAS,EAAA,iBAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAAE;AAC7F;AACF;CACD;;;;"}
1
+ {"version":3,"file":"users.js","sources":["../../../../../server/src/routes/users.ts"],"sourcesContent":["export default [\n {\n method: 'GET',\n path: '/users/me',\n handler: 'authenticated-user.getMe',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'PUT',\n path: '/users/me',\n handler: 'authenticated-user.updateMe',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/users/me/permissions',\n handler: 'authenticated-user.getOwnPermissions',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'POST',\n path: '/users',\n handler: 'user.create',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.create'] } },\n ],\n },\n },\n {\n method: 'GET',\n path: '/users',\n handler: 'user.find',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.read'] } },\n ],\n },\n },\n {\n method: 'GET',\n path: '/users/:id',\n handler: 'user.findOne',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.read'] } },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/users/:id',\n handler: 'user.update',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.update'] } },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/users/:id',\n handler: 'user.deleteOne',\n config: {\n policies: [{ name: 'admin::hasPermissions', config: { actions: ['admin::users.delete'] } }],\n },\n },\n {\n method: 'POST',\n path: '/users/batch-delete',\n handler: 'user.deleteMany',\n config: {\n policies: [{ name: 'admin::hasPermissions', config: { actions: ['admin::users.delete'] } }],\n },\n },\n];\n"],"names":["method","path","handler","config","policies","name","actions"],"mappings":";;AAAA,YAAe;AACb,IAAA;QACEA,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,WAAA;QACNC,OAAS,EAAA,0BAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;AAA8B;AAC3C;AACF,KAAA;AACA,IAAA;QACEJ,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,WAAA;QACNC,OAAS,EAAA,6BAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;AAA8B;AAC3C;AACF,KAAA;AACA,IAAA;QACEJ,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,uBAAA;QACNC,OAAS,EAAA,sCAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;AAA8B;AAC3C;AACF,KAAA;AACA,IAAA;QACEJ,MAAQ,EAAA,MAAA;QACRC,IAAM,EAAA,QAAA;QACNC,OAAS,EAAA,aAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAC/E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,QAAA;QACNC,OAAS,EAAA,WAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAoB;AAAC;AAAE;AAC7E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,YAAA;QACNC,OAAS,EAAA,cAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAoB;AAAC;AAAE;AAC7E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,YAAA;QACNC,OAAS,EAAA,aAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAC/E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,QAAA;QACRC,IAAM,EAAA,YAAA;QACNC,OAAS,EAAA,gBAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAAE;AAC7F;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,MAAA;QACRC,IAAM,EAAA,qBAAA;QACNC,OAAS,EAAA,iBAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAAE;AAC7F;AACF;CACD;;;;"}
@@ -29,16 +29,6 @@ var users = [
29
29
  ]
30
30
  }
31
31
  },
32
- {
33
- method: 'GET',
34
- path: '/users/me/ai-token',
35
- handler: 'authenticated-user.getAiToken',
36
- config: {
37
- policies: [
38
- 'admin::isAuthenticatedAdmin'
39
- ]
40
- }
41
- },
42
32
  {
43
33
  method: 'POST',
44
34
  path: '/users',
@@ -1 +1 @@
1
- {"version":3,"file":"users.mjs","sources":["../../../../../server/src/routes/users.ts"],"sourcesContent":["export default [\n {\n method: 'GET',\n path: '/users/me',\n handler: 'authenticated-user.getMe',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'PUT',\n path: '/users/me',\n handler: 'authenticated-user.updateMe',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/users/me/permissions',\n handler: 'authenticated-user.getOwnPermissions',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/users/me/ai-token',\n handler: 'authenticated-user.getAiToken',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'POST',\n path: '/users',\n handler: 'user.create',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.create'] } },\n ],\n },\n },\n {\n method: 'GET',\n path: '/users',\n handler: 'user.find',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.read'] } },\n ],\n },\n },\n {\n method: 'GET',\n path: '/users/:id',\n handler: 'user.findOne',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.read'] } },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/users/:id',\n handler: 'user.update',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.update'] } },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/users/:id',\n handler: 'user.deleteOne',\n config: {\n policies: [{ name: 'admin::hasPermissions', config: { actions: ['admin::users.delete'] } }],\n },\n },\n {\n method: 'POST',\n path: '/users/batch-delete',\n handler: 'user.deleteMany',\n config: {\n policies: [{ name: 'admin::hasPermissions', config: { actions: ['admin::users.delete'] } }],\n },\n },\n];\n"],"names":["method","path","handler","config","policies","name","actions"],"mappings":"AAAA,YAAe;AACb,IAAA;QACEA,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,WAAA;QACNC,OAAS,EAAA,0BAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;AAA8B;AAC3C;AACF,KAAA;AACA,IAAA;QACEJ,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,WAAA;QACNC,OAAS,EAAA,6BAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;AAA8B;AAC3C;AACF,KAAA;AACA,IAAA;QACEJ,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,uBAAA;QACNC,OAAS,EAAA,sCAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;AAA8B;AAC3C;AACF,KAAA;AACA,IAAA;QACEJ,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,oBAAA;QACNC,OAAS,EAAA,+BAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;AAA8B;AAC3C;AACF,KAAA;AACA,IAAA;QACEJ,MAAQ,EAAA,MAAA;QACRC,IAAM,EAAA,QAAA;QACNC,OAAS,EAAA,aAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAC/E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,QAAA;QACNC,OAAS,EAAA,WAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAoB;AAAC;AAAE;AAC7E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,YAAA;QACNC,OAAS,EAAA,cAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAoB;AAAC;AAAE;AAC7E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,YAAA;QACNC,OAAS,EAAA,aAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAC/E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,QAAA;QACRC,IAAM,EAAA,YAAA;QACNC,OAAS,EAAA,gBAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAAE;AAC7F;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,MAAA;QACRC,IAAM,EAAA,qBAAA;QACNC,OAAS,EAAA,iBAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAAE;AAC7F;AACF;CACD;;;;"}
1
+ {"version":3,"file":"users.mjs","sources":["../../../../../server/src/routes/users.ts"],"sourcesContent":["export default [\n {\n method: 'GET',\n path: '/users/me',\n handler: 'authenticated-user.getMe',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'PUT',\n path: '/users/me',\n handler: 'authenticated-user.updateMe',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/users/me/permissions',\n handler: 'authenticated-user.getOwnPermissions',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'POST',\n path: '/users',\n handler: 'user.create',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.create'] } },\n ],\n },\n },\n {\n method: 'GET',\n path: '/users',\n handler: 'user.find',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.read'] } },\n ],\n },\n },\n {\n method: 'GET',\n path: '/users/:id',\n handler: 'user.findOne',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.read'] } },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/users/:id',\n handler: 'user.update',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n { name: 'admin::hasPermissions', config: { actions: ['admin::users.update'] } },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/users/:id',\n handler: 'user.deleteOne',\n config: {\n policies: [{ name: 'admin::hasPermissions', config: { actions: ['admin::users.delete'] } }],\n },\n },\n {\n method: 'POST',\n path: '/users/batch-delete',\n handler: 'user.deleteMany',\n config: {\n policies: [{ name: 'admin::hasPermissions', config: { actions: ['admin::users.delete'] } }],\n },\n },\n];\n"],"names":["method","path","handler","config","policies","name","actions"],"mappings":"AAAA,YAAe;AACb,IAAA;QACEA,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,WAAA;QACNC,OAAS,EAAA,0BAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;AAA8B;AAC3C;AACF,KAAA;AACA,IAAA;QACEJ,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,WAAA;QACNC,OAAS,EAAA,6BAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;AAA8B;AAC3C;AACF,KAAA;AACA,IAAA;QACEJ,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,uBAAA;QACNC,OAAS,EAAA,sCAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;AAA8B;AAC3C;AACF,KAAA;AACA,IAAA;QACEJ,MAAQ,EAAA,MAAA;QACRC,IAAM,EAAA,QAAA;QACNC,OAAS,EAAA,aAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAC/E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,QAAA;QACNC,OAAS,EAAA,WAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAoB;AAAC;AAAE;AAC7E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,YAAA;QACNC,OAAS,EAAA,cAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAoB;AAAC;AAAE;AAC7E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,KAAA;QACRC,IAAM,EAAA,YAAA;QACNC,OAAS,EAAA,aAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AACR,gBAAA,6BAAA;AACA,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAC/E;AACH;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,QAAA;QACRC,IAAM,EAAA,YAAA;QACNC,OAAS,EAAA,gBAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAAE;AAC7F;AACF,KAAA;AACA,IAAA;QACEN,MAAQ,EAAA,MAAA;QACRC,IAAM,EAAA,qBAAA;QACNC,OAAS,EAAA,iBAAA;QACTC,MAAQ,EAAA;YACNC,QAAU,EAAA;AAAC,gBAAA;oBAAEC,IAAM,EAAA,uBAAA;oBAAyBF,MAAQ,EAAA;wBAAEG,OAAS,EAAA;AAAC,4BAAA;AAAsB;AAAC;AAAE;AAAE;AAC7F;AACF;CACD;;;;"}