@strapi/admin 5.58.0 → 5.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/admin/src/StrapiApp.js.map +1 -1
- package/dist/admin/admin/src/StrapiApp.mjs.map +1 -1
- package/dist/admin/admin/src/components/ConfirmDialog.js +10 -9
- package/dist/admin/admin/src/components/ConfirmDialog.js.map +1 -1
- package/dist/admin/admin/src/components/ConfirmDialog.mjs +10 -9
- package/dist/admin/admin/src/components/ConfirmDialog.mjs.map +1 -1
- package/dist/admin/admin/src/components/Filters.js +57 -12
- package/dist/admin/admin/src/components/Filters.js.map +1 -1
- package/dist/admin/admin/src/components/Filters.mjs +57 -12
- package/dist/admin/admin/src/components/Filters.mjs.map +1 -1
- package/dist/admin/admin/src/components/Form.js +3 -1
- package/dist/admin/admin/src/components/Form.js.map +1 -1
- package/dist/admin/admin/src/components/Form.mjs +3 -1
- package/dist/admin/admin/src/components/Form.mjs.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Enumeration.js +2 -1
- package/dist/admin/admin/src/components/FormInputs/Enumeration.js.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs +2 -1
- package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs.map +1 -1
- package/dist/admin/admin/src/components/LeftMenu.js +5 -1
- package/dist/admin/admin/src/components/LeftMenu.js.map +1 -1
- package/dist/admin/admin/src/components/LeftMenu.mjs +5 -1
- package/dist/admin/admin/src/components/LeftMenu.mjs.map +1 -1
- package/dist/admin/admin/src/components/PageHelpers.js +2 -1
- package/dist/admin/admin/src/components/PageHelpers.js.map +1 -1
- package/dist/admin/admin/src/components/PageHelpers.mjs +2 -1
- package/dist/admin/admin/src/components/PageHelpers.mjs.map +1 -1
- package/dist/admin/admin/src/components/Pagination.js +7 -6
- package/dist/admin/admin/src/components/Pagination.js.map +1 -1
- package/dist/admin/admin/src/components/Pagination.mjs +7 -6
- package/dist/admin/admin/src/components/Pagination.mjs.map +1 -1
- package/dist/admin/admin/src/components/RelativeTime.js +2 -1
- package/dist/admin/admin/src/components/RelativeTime.js.map +1 -1
- package/dist/admin/admin/src/components/RelativeTime.mjs +2 -1
- package/dist/admin/admin/src/components/RelativeTime.mjs.map +1 -1
- package/dist/admin/admin/src/components/SubNav.js +6 -12
- package/dist/admin/admin/src/components/SubNav.js.map +1 -1
- package/dist/admin/admin/src/components/SubNav.mjs +7 -13
- package/dist/admin/admin/src/components/SubNav.mjs.map +1 -1
- package/dist/admin/admin/src/components/Table.js +3 -1
- package/dist/admin/admin/src/components/Table.js.map +1 -1
- package/dist/admin/admin/src/components/Table.mjs +3 -1
- package/dist/admin/admin/src/components/Table.mjs.map +1 -1
- package/dist/admin/admin/src/components/UpsellBanner.js.map +1 -1
- package/dist/admin/admin/src/components/UpsellBanner.mjs.map +1 -1
- package/dist/admin/admin/src/components/WidgetRoot.js.map +1 -1
- package/dist/admin/admin/src/components/WidgetRoot.mjs.map +1 -1
- package/dist/admin/admin/src/constants.js.map +1 -1
- package/dist/admin/admin/src/constants.mjs.map +1 -1
- package/dist/admin/admin/src/core/apis/Plugin.js.map +1 -1
- package/dist/admin/admin/src/core/apis/Plugin.mjs.map +1 -1
- package/dist/admin/admin/src/features/Auth.js +2 -1
- package/dist/admin/admin/src/features/Auth.js.map +1 -1
- package/dist/admin/admin/src/features/Auth.mjs +2 -1
- package/dist/admin/admin/src/features/Auth.mjs.map +1 -1
- package/dist/admin/admin/src/features/StrapiApp.js.map +1 -1
- package/dist/admin/admin/src/features/StrapiApp.mjs.map +1 -1
- package/dist/admin/admin/src/features/Tracking.js.map +1 -1
- package/dist/admin/admin/src/features/Tracking.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Home/components/FreeTrialEndedModal.js.map +1 -1
- package/dist/admin/admin/src/pages/Home/components/FreeTrialEndedModal.mjs.map +1 -1
- package/dist/admin/admin/src/pages/ProfilePage.js +2 -2
- package/dist/admin/admin/src/pages/ProfilePage.js.map +1 -1
- package/dist/admin/admin/src/pages/ProfilePage.mjs +2 -2
- package/dist/admin/admin/src/pages/ProfilePage.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/SettingsNav.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/SettingsNav.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormApiTokenContainer.js +4 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormApiTokenContainer.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormApiTokenContainer.mjs +4 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormApiTokenContainer.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.js +3 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.mjs +3 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenTypeSelect.js +2 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenTypeSelect.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenTypeSelect.mjs +2 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenTypeSelect.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/BoundRoute.js +6 -5
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/BoundRoute.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/BoundRoute.mjs +6 -5
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/BoundRoute.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.js +2 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.mjs +2 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/utils/transformPermissionsData.js +4 -4
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/utils/transformPermissionsData.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/utils/transformPermissionsData.mjs +4 -4
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/utils/transformPermissionsData.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js +1 -2
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs +1 -2
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.js +9 -4
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.mjs +9 -4
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.js +15 -9
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.mjs +15 -9
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.js +5 -2
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.mjs +5 -2
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.js +2 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.mjs +2 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.js +2 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.mjs +2 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.js +2 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.mjs +2 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/hooks/usePermissionsDataManager.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/hooks/usePermissionsDataManager.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.js +3 -1
- package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.mjs +3 -1
- package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Users/ListPage.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Users/ListPage.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Users/components/NewUserForm.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Users/components/NewUserForm.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/Events.js +4 -1
- package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/Events.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/Events.mjs +4 -1
- package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/Events.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.js +18 -3
- package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.mjs +18 -3
- package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.mjs.map +1 -1
- package/dist/admin/admin/src/router.js.map +1 -1
- package/dist/admin/admin/src/router.mjs.map +1 -1
- package/dist/admin/admin/src/services/users.js.map +1 -1
- package/dist/admin/admin/src/services/users.mjs.map +1 -1
- package/dist/admin/admin/src/translations/eu.json.js +1 -1
- package/dist/admin/admin/src/translations/eu.json.mjs +1 -1
- package/dist/admin/admin/src/utils/cookies.js +7 -6
- package/dist/admin/admin/src/utils/cookies.js.map +1 -1
- package/dist/admin/admin/src/utils/cookies.mjs +7 -6
- package/dist/admin/admin/src/utils/cookies.mjs.map +1 -1
- package/dist/admin/admin/tests/utils.js +2 -1
- package/dist/admin/admin/tests/utils.js.map +1 -1
- package/dist/admin/admin/tests/utils.mjs +2 -1
- package/dist/admin/admin/tests/utils.mjs.map +1 -1
- package/dist/admin/shared/utils/auth-cookie-path.js +13 -10
- package/dist/admin/shared/utils/auth-cookie-path.js.map +1 -1
- package/dist/admin/shared/utils/auth-cookie-path.mjs +13 -10
- package/dist/admin/shared/utils/auth-cookie-path.mjs.map +1 -1
- package/dist/admin/shared/utils/get-project-type.js +3 -3
- package/dist/admin/shared/utils/get-project-type.js.map +1 -1
- package/dist/admin/shared/utils/get-project-type.mjs +3 -3
- package/dist/admin/shared/utils/get-project-type.mjs.map +1 -1
- package/dist/admin/src/components/Filters.d.ts +1 -1
- package/dist/admin/src/components/Form.d.ts +1 -1
- package/dist/admin/src/pages/Settings/pages/ApiTokens/EditView/components/BoundRoute.d.ts +1 -1
- package/dist/admin/src/utils/cookies.d.ts +7 -6
- package/dist/ee/server/src/services/seat-enforcement.d.ts.map +1 -1
- package/dist/ee/server/src/validation/role.d.ts.map +1 -1
- package/dist/server/ee/server/src/audit-logs/utils/csv.js +3 -3
- package/dist/server/ee/server/src/audit-logs/utils/csv.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/utils/csv.mjs +3 -3
- package/dist/server/ee/server/src/audit-logs/utils/csv.mjs.map +1 -1
- package/dist/server/ee/server/src/services/seat-enforcement.js.map +1 -1
- package/dist/server/ee/server/src/services/seat-enforcement.mjs.map +1 -1
- package/dist/server/ee/server/src/validation/role.js +4 -2
- package/dist/server/ee/server/src/validation/role.js.map +1 -1
- package/dist/server/ee/server/src/validation/role.mjs +4 -2
- package/dist/server/ee/server/src/validation/role.mjs.map +1 -1
- package/dist/server/server/src/ai/services/ai.js.map +1 -1
- package/dist/server/server/src/ai/services/ai.mjs.map +1 -1
- package/dist/server/server/src/controllers/admin.js +11 -12
- package/dist/server/server/src/controllers/admin.js.map +1 -1
- package/dist/server/server/src/controllers/admin.mjs +11 -12
- package/dist/server/server/src/controllers/admin.mjs.map +1 -1
- package/dist/server/server/src/domain/permission/index.js.map +1 -1
- package/dist/server/server/src/domain/permission/index.mjs.map +1 -1
- package/dist/server/server/src/services/api-token.js +4 -8
- package/dist/server/server/src/services/api-token.js.map +1 -1
- package/dist/server/server/src/services/api-token.mjs +4 -8
- package/dist/server/server/src/services/api-token.mjs.map +1 -1
- package/dist/server/server/src/services/constants.js +4 -0
- package/dist/server/server/src/services/constants.js.map +1 -1
- package/dist/server/server/src/services/constants.mjs +4 -0
- package/dist/server/server/src/services/constants.mjs.map +1 -1
- package/dist/server/server/src/services/permission/rename-fields.js.map +1 -1
- package/dist/server/server/src/services/permission/rename-fields.mjs.map +1 -1
- package/dist/server/server/src/services/permission/sections-builder/handlers.js.map +1 -1
- package/dist/server/server/src/services/permission/sections-builder/handlers.mjs.map +1 -1
- package/dist/server/server/src/services/role.js +8 -5
- package/dist/server/server/src/services/role.js.map +1 -1
- package/dist/server/server/src/services/role.mjs +8 -5
- package/dist/server/server/src/services/role.mjs.map +1 -1
- package/dist/server/server/src/validation/admin-tokens.js +4 -4
- package/dist/server/server/src/validation/admin-tokens.js.map +1 -1
- package/dist/server/server/src/validation/admin-tokens.mjs +4 -4
- package/dist/server/server/src/validation/admin-tokens.mjs.map +1 -1
- package/dist/server/server/src/validation/api-tokens.js +4 -4
- package/dist/server/server/src/validation/api-tokens.js.map +1 -1
- package/dist/server/server/src/validation/api-tokens.mjs +4 -4
- package/dist/server/server/src/validation/api-tokens.mjs.map +1 -1
- package/dist/server/server/src/validation/role.js +6 -4
- package/dist/server/server/src/validation/role.js.map +1 -1
- package/dist/server/server/src/validation/role.mjs +6 -4
- package/dist/server/server/src/validation/role.mjs.map +1 -1
- package/dist/server/server/src/validation/transfer/token.js +4 -4
- package/dist/server/server/src/validation/transfer/token.js.map +1 -1
- package/dist/server/server/src/validation/transfer/token.mjs +4 -4
- package/dist/server/server/src/validation/transfer/token.mjs.map +1 -1
- package/dist/server/shared/utils/auth-cookie-path.js +13 -10
- package/dist/server/shared/utils/auth-cookie-path.js.map +1 -1
- package/dist/server/shared/utils/auth-cookie-path.mjs +13 -10
- package/dist/server/shared/utils/auth-cookie-path.mjs.map +1 -1
- package/dist/server/shared/utils/get-project-type.js +3 -3
- package/dist/server/shared/utils/get-project-type.js.map +1 -1
- package/dist/server/shared/utils/get-project-type.mjs +3 -3
- package/dist/server/shared/utils/get-project-type.mjs.map +1 -1
- package/dist/server/shared/utils/session-auth.js +70 -3
- package/dist/server/shared/utils/session-auth.js.map +1 -1
- package/dist/server/shared/utils/session-auth.mjs +70 -4
- package/dist/server/shared/utils/session-auth.mjs.map +1 -1
- package/dist/server/src/ai/services/ai.d.ts.map +1 -1
- package/dist/server/src/controllers/admin.d.ts.map +1 -1
- package/dist/server/src/domain/permission/index.d.ts.map +1 -1
- package/dist/server/src/services/constants.d.ts +2 -0
- package/dist/server/src/services/constants.d.ts.map +1 -1
- package/dist/server/src/services/permission/rename-fields.d.ts.map +1 -1
- package/dist/server/src/services/permission/sections-builder/handlers.d.ts.map +1 -1
- package/dist/server/src/services/role.d.ts.map +1 -1
- package/dist/server/src/validation/role.d.ts.map +1 -1
- package/dist/shared/contracts/transfer.d.ts.map +1 -1
- package/dist/shared/utils/auth-cookie-path.d.ts +13 -10
- package/dist/shared/utils/auth-cookie-path.d.ts.map +1 -1
- package/dist/shared/utils/session-auth.d.ts +16 -0
- package/dist/shared/utils/session-auth.d.ts.map +1 -1
- package/package.json +7 -7
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
};
|
|
26
26
|
// The statuses a license can be in once it has been read. `none` (never licensed) is left out
|
|
27
27
|
// on purpose, and so is a missing status, which a mixed-version install can produce.
|
|
28
|
-
const LICENSED_STATUSES = [
|
|
28
|
+
const LICENSED_STATUSES = new Set([
|
|
29
29
|
'active',
|
|
30
30
|
'expired',
|
|
31
31
|
'unknown'
|
|
32
|
-
];
|
|
32
|
+
]);
|
|
33
33
|
/**
|
|
34
34
|
* Resolves the plan a license was issued for, including one that has lapsed or can no longer
|
|
35
35
|
* be read, so Support links, the Plan card and the debug dump can still name it. It unlocks
|
|
@@ -40,7 +40,7 @@ const LICENSED_STATUSES = [
|
|
|
40
40
|
* type is stored, and with no price id `getProjectType` would fall through to Enterprise, so
|
|
41
41
|
* both conditions are required. Every caller that derives a plan should go through here.
|
|
42
42
|
*/ const getLicensedPlan = ({ licenseStatus, type, planPriceId })=>getProjectType({
|
|
43
|
-
isEE: Boolean(type) && LICENSED_STATUSES.
|
|
43
|
+
isEE: Boolean(type) && LICENSED_STATUSES.has(licenseStatus ?? ''),
|
|
44
44
|
planPriceId: planPriceId ?? undefined
|
|
45
45
|
});
|
|
46
46
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-project-type.js","sources":["../../../../shared/utils/get-project-type.ts"],"sourcesContent":["type ProjectType = 'Community' | 'Growth' | 'Enterprise';\n\n/**\n * Resolves the plan label from the license information returned by the\n * `/admin/project-type` endpoint (browser) or `strapi.ee` (server).\n *\n * This labels the edition that is running: it follows `isEE`, so a lapsed license reads\n * Community. Browser tracking and NPS report this label and the startup table applies the same\n * rule; server metrics also label the running edition, but never say Growth. For the plan a\n * license was issued for, lapsed or not (the Plan card, the Support card and the debug dump),\n * use `getLicensedPlan` below.\n *\n * The label is intentionally limited to three values:\n * - `Community` when there is no license (Community Edition).\n * - `Growth` when the licensed plan price id contains \"growth\".\n * - `Enterprise` for any other licensed plan.\n */\nconst getProjectType = ({\n isEE,\n planPriceId,\n}: {\n isEE: boolean;\n planPriceId?: string;\n}): ProjectType => {\n if (!isEE) {\n return 'Community';\n }\n\n if (planPriceId?.toLowerCase().includes('growth')) {\n return 'Growth';\n }\n\n return 'Enterprise';\n};\n\n// The statuses a license can be in once it has been read. `none` (never licensed) is left out\n// on purpose, and so is a missing status, which a mixed-version install can produce.\nconst LICENSED_STATUSES:
|
|
1
|
+
{"version":3,"file":"get-project-type.js","sources":["../../../../shared/utils/get-project-type.ts"],"sourcesContent":["type ProjectType = 'Community' | 'Growth' | 'Enterprise';\n\n/**\n * Resolves the plan label from the license information returned by the\n * `/admin/project-type` endpoint (browser) or `strapi.ee` (server).\n *\n * This labels the edition that is running: it follows `isEE`, so a lapsed license reads\n * Community. Browser tracking and NPS report this label and the startup table applies the same\n * rule; server metrics also label the running edition, but never say Growth. For the plan a\n * license was issued for, lapsed or not (the Plan card, the Support card and the debug dump),\n * use `getLicensedPlan` below.\n *\n * The label is intentionally limited to three values:\n * - `Community` when there is no license (Community Edition).\n * - `Growth` when the licensed plan price id contains \"growth\".\n * - `Enterprise` for any other licensed plan.\n */\nconst getProjectType = ({\n isEE,\n planPriceId,\n}: {\n isEE: boolean;\n planPriceId?: string;\n}): ProjectType => {\n if (!isEE) {\n return 'Community';\n }\n\n if (planPriceId?.toLowerCase().includes('growth')) {\n return 'Growth';\n }\n\n return 'Enterprise';\n};\n\n// The statuses a license can be in once it has been read. `none` (never licensed) is left out\n// on purpose, and so is a missing status, which a mixed-version install can produce.\nconst LICENSED_STATUSES: ReadonlySet<string> = new Set(['active', 'expired', 'unknown']);\n\n/**\n * Resolves the plan a license was issued for, including one that has lapsed or can no longer\n * be read, so Support links, the Plan card and the debug dump can still name it. It unlocks\n * nothing: feature gating stays on `isEE`.\n *\n * A plan is only reported when a type was verified at some point (live, or retained once the\n * license lapsed) AND the status is licensed. A corrupt license file sets `unknown` before any\n * type is stored, and with no price id `getProjectType` would fall through to Enterprise, so\n * both conditions are required. Every caller that derives a plan should go through here.\n */\nconst getLicensedPlan = ({\n licenseStatus,\n type,\n planPriceId,\n}: {\n licenseStatus: string | null | undefined;\n type: string | null | undefined;\n planPriceId?: string | null;\n}): ProjectType =>\n getProjectType({\n isEE: Boolean(type) && LICENSED_STATUSES.has(licenseStatus ?? ''),\n planPriceId: planPriceId ?? undefined,\n });\n\nexport { getLicensedPlan, getProjectType };\nexport type { ProjectType };\n"],"names":["getProjectType","isEE","planPriceId","toLowerCase","includes","LICENSED_STATUSES","Set","getLicensedPlan","licenseStatus","type","Boolean","has","undefined"],"mappings":";;AAEA;;;;;;;;;;;;;;AAcC,UACKA,cAAAA,GAAiB,CAAC,EACtBC,IAAI,EACJC,WAAW,EAIZ,GAAA;AACC,IAAA,IAAI,CAACD,IAAAA,EAAM;QACT,OAAO,WAAA;AACT,IAAA;IAEA,IAAIC,WAAAA,EAAaC,WAAAA,EAAAA,CAAcC,QAAAA,CAAS,QAAA,CAAA,EAAW;QACjD,OAAO,QAAA;AACT,IAAA;IAEA,OAAO,YAAA;AACT;AAEA;AACA;AACA,MAAMC,iBAAAA,GAAyC,IAAIC,GAAAA,CAAI;AAAC,IAAA,QAAA;AAAU,IAAA,SAAA;AAAW,IAAA;AAAU,CAAA,CAAA;AAEvF;;;;;;;;;IAUA,MAAMC,eAAAA,GAAkB,CAAC,EACvBC,aAAa,EACbC,IAAI,EACJP,WAAW,EAKZ,GACCF,cAAAA,CAAe;AACbC,QAAAA,IAAAA,EAAMS,OAAAA,CAAQD,IAAAA,CAAAA,IAASJ,iBAAAA,CAAkBM,GAAG,CAACH,aAAAA,IAAiB,EAAA,CAAA;AAC9DN,QAAAA,WAAAA,EAAaA,WAAAA,IAAeU;AAC9B,KAAA;;;;;"}
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
};
|
|
24
24
|
// The statuses a license can be in once it has been read. `none` (never licensed) is left out
|
|
25
25
|
// on purpose, and so is a missing status, which a mixed-version install can produce.
|
|
26
|
-
const LICENSED_STATUSES = [
|
|
26
|
+
const LICENSED_STATUSES = new Set([
|
|
27
27
|
'active',
|
|
28
28
|
'expired',
|
|
29
29
|
'unknown'
|
|
30
|
-
];
|
|
30
|
+
]);
|
|
31
31
|
/**
|
|
32
32
|
* Resolves the plan a license was issued for, including one that has lapsed or can no longer
|
|
33
33
|
* be read, so Support links, the Plan card and the debug dump can still name it. It unlocks
|
|
@@ -38,7 +38,7 @@ const LICENSED_STATUSES = [
|
|
|
38
38
|
* type is stored, and with no price id `getProjectType` would fall through to Enterprise, so
|
|
39
39
|
* both conditions are required. Every caller that derives a plan should go through here.
|
|
40
40
|
*/ const getLicensedPlan = ({ licenseStatus, type, planPriceId })=>getProjectType({
|
|
41
|
-
isEE: Boolean(type) && LICENSED_STATUSES.
|
|
41
|
+
isEE: Boolean(type) && LICENSED_STATUSES.has(licenseStatus ?? ''),
|
|
42
42
|
planPriceId: planPriceId ?? undefined
|
|
43
43
|
});
|
|
44
44
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-project-type.mjs","sources":["../../../../shared/utils/get-project-type.ts"],"sourcesContent":["type ProjectType = 'Community' | 'Growth' | 'Enterprise';\n\n/**\n * Resolves the plan label from the license information returned by the\n * `/admin/project-type` endpoint (browser) or `strapi.ee` (server).\n *\n * This labels the edition that is running: it follows `isEE`, so a lapsed license reads\n * Community. Browser tracking and NPS report this label and the startup table applies the same\n * rule; server metrics also label the running edition, but never say Growth. For the plan a\n * license was issued for, lapsed or not (the Plan card, the Support card and the debug dump),\n * use `getLicensedPlan` below.\n *\n * The label is intentionally limited to three values:\n * - `Community` when there is no license (Community Edition).\n * - `Growth` when the licensed plan price id contains \"growth\".\n * - `Enterprise` for any other licensed plan.\n */\nconst getProjectType = ({\n isEE,\n planPriceId,\n}: {\n isEE: boolean;\n planPriceId?: string;\n}): ProjectType => {\n if (!isEE) {\n return 'Community';\n }\n\n if (planPriceId?.toLowerCase().includes('growth')) {\n return 'Growth';\n }\n\n return 'Enterprise';\n};\n\n// The statuses a license can be in once it has been read. `none` (never licensed) is left out\n// on purpose, and so is a missing status, which a mixed-version install can produce.\nconst LICENSED_STATUSES:
|
|
1
|
+
{"version":3,"file":"get-project-type.mjs","sources":["../../../../shared/utils/get-project-type.ts"],"sourcesContent":["type ProjectType = 'Community' | 'Growth' | 'Enterprise';\n\n/**\n * Resolves the plan label from the license information returned by the\n * `/admin/project-type` endpoint (browser) or `strapi.ee` (server).\n *\n * This labels the edition that is running: it follows `isEE`, so a lapsed license reads\n * Community. Browser tracking and NPS report this label and the startup table applies the same\n * rule; server metrics also label the running edition, but never say Growth. For the plan a\n * license was issued for, lapsed or not (the Plan card, the Support card and the debug dump),\n * use `getLicensedPlan` below.\n *\n * The label is intentionally limited to three values:\n * - `Community` when there is no license (Community Edition).\n * - `Growth` when the licensed plan price id contains \"growth\".\n * - `Enterprise` for any other licensed plan.\n */\nconst getProjectType = ({\n isEE,\n planPriceId,\n}: {\n isEE: boolean;\n planPriceId?: string;\n}): ProjectType => {\n if (!isEE) {\n return 'Community';\n }\n\n if (planPriceId?.toLowerCase().includes('growth')) {\n return 'Growth';\n }\n\n return 'Enterprise';\n};\n\n// The statuses a license can be in once it has been read. `none` (never licensed) is left out\n// on purpose, and so is a missing status, which a mixed-version install can produce.\nconst LICENSED_STATUSES: ReadonlySet<string> = new Set(['active', 'expired', 'unknown']);\n\n/**\n * Resolves the plan a license was issued for, including one that has lapsed or can no longer\n * be read, so Support links, the Plan card and the debug dump can still name it. It unlocks\n * nothing: feature gating stays on `isEE`.\n *\n * A plan is only reported when a type was verified at some point (live, or retained once the\n * license lapsed) AND the status is licensed. A corrupt license file sets `unknown` before any\n * type is stored, and with no price id `getProjectType` would fall through to Enterprise, so\n * both conditions are required. Every caller that derives a plan should go through here.\n */\nconst getLicensedPlan = ({\n licenseStatus,\n type,\n planPriceId,\n}: {\n licenseStatus: string | null | undefined;\n type: string | null | undefined;\n planPriceId?: string | null;\n}): ProjectType =>\n getProjectType({\n isEE: Boolean(type) && LICENSED_STATUSES.has(licenseStatus ?? ''),\n planPriceId: planPriceId ?? undefined,\n });\n\nexport { getLicensedPlan, getProjectType };\nexport type { ProjectType };\n"],"names":["getProjectType","isEE","planPriceId","toLowerCase","includes","LICENSED_STATUSES","Set","getLicensedPlan","licenseStatus","type","Boolean","has","undefined"],"mappings":"AAEA;;;;;;;;;;;;;;AAcC,UACKA,cAAAA,GAAiB,CAAC,EACtBC,IAAI,EACJC,WAAW,EAIZ,GAAA;AACC,IAAA,IAAI,CAACD,IAAAA,EAAM;QACT,OAAO,WAAA;AACT,IAAA;IAEA,IAAIC,WAAAA,EAAaC,WAAAA,EAAAA,CAAcC,QAAAA,CAAS,QAAA,CAAA,EAAW;QACjD,OAAO,QAAA;AACT,IAAA;IAEA,OAAO,YAAA;AACT;AAEA;AACA;AACA,MAAMC,iBAAAA,GAAyC,IAAIC,GAAAA,CAAI;AAAC,IAAA,QAAA;AAAU,IAAA,SAAA;AAAW,IAAA;AAAU,CAAA,CAAA;AAEvF;;;;;;;;;IAUA,MAAMC,eAAAA,GAAkB,CAAC,EACvBC,aAAa,EACbC,IAAI,EACJP,WAAW,EAKZ,GACCF,cAAAA,CAAe;AACbC,QAAAA,IAAAA,EAAMS,OAAAA,CAAQD,IAAAA,CAAAA,IAASJ,iBAAAA,CAAkBM,GAAG,CAACH,aAAAA,IAAiB,EAAA,CAAA;AAC9DN,QAAAA,WAAAA,EAAaA,WAAAA,IAAeU;AAC9B,KAAA;;;;"}
|
|
@@ -91,6 +91,6 @@ interface BlockerProps {
|
|
|
91
91
|
onProceed?: () => void;
|
|
92
92
|
onCancel?: () => void;
|
|
93
93
|
}
|
|
94
|
-
declare const Blocker: ({ onProceed, onCancel }: BlockerProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
94
|
+
declare const Blocker: ({ onProceed, onCancel, }: BlockerProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
95
95
|
export { Form, Blocker, useField, useForm, getYupValidationErrors };
|
|
96
96
|
export type { FormErrors, FormHelpers, FormProps, FormValues, FormContextValue, FormState, FieldValue, InputProps, };
|
|
@@ -6,5 +6,5 @@ interface BoundRouteProps {
|
|
|
6
6
|
path: string;
|
|
7
7
|
};
|
|
8
8
|
}
|
|
9
|
-
export declare const BoundRoute: ({ route
|
|
9
|
+
export declare const BoundRoute: ({ route }: BoundRouteProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
10
|
export {};
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export declare const AUTH_COOKIE_NAME: string;
|
|
6
6
|
/**
|
|
7
|
-
* Resolved once at module load: the build inlines `admin.auth.cookie.path
|
|
8
|
-
* into the bundle as
|
|
7
|
+
* Resolved once at module load: the build inlines `admin.auth.cookie.path`,
|
|
8
|
+
* or the path the panel is served from when it is unset, into the bundle as
|
|
9
|
+
* `STRAPI_ADMIN_AUTH_COOKIE_PATH`.
|
|
9
10
|
*/
|
|
10
11
|
export declare const AUTH_COOKIE_PATH: string;
|
|
11
12
|
/**
|
|
@@ -23,10 +24,10 @@ export declare const AUTH_COOKIE_DOMAIN: string | undefined;
|
|
|
23
24
|
export declare const getCookieValue: (name: string) => string | null;
|
|
24
25
|
/**
|
|
25
26
|
* Sets a cookie with the given name, value, and optional expiration time.
|
|
26
|
-
* Uses
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
27
|
+
* Uses the access cookie path and `admin.auth.cookie.domain` (both inlined at
|
|
28
|
+
* build time) so the cookie lands on the same path and domain as the EE SSO
|
|
29
|
+
* access cookie written by the server. The cookie is marked `Secure` whenever
|
|
30
|
+
* the page is served over TLS.
|
|
30
31
|
*
|
|
31
32
|
* @param name - The name of the cookie.
|
|
32
33
|
* @param value - The value of the cookie.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seat-enforcement.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/services/seat-enforcement.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAIrE,KAAK,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,GAAG,UAAU,CAAC,CAAC;;;+BAKjB,OAAO,CAAC,YAAY,EAAE,CAAC;;
|
|
1
|
+
{"version":3,"file":"seat-enforcement.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/services/seat-enforcement.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAIrE,KAAK,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,GAAG,UAAU,CAAC,CAAC;;;+BAKjB,OAAO,CAAC,YAAY,EAAE,CAAC;;AAwG7D,wBAGE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"role.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/validation/role.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAqB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"role.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/validation/role.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAqB,MAAM,eAAe,CAAC;AA8DvD,eAAO,MAAM,uBAAuB;;;IAAsC,CAAC;AAC3E,eAAO,MAAM,wBAAwB;;IAAuC,CAAC;AAC7E,eAAO,MAAM,uBAAuB,wDAAsC,CAAC;;;;;;;;;;;AAE3E,wBAIE"}
|
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
const CSV_LINE_SEPARATOR = '\r\n';
|
|
4
4
|
const CSV_BOM = '\uFEFF';
|
|
5
|
-
const FORMULA_TRIGGER_CHARACTERS = [
|
|
5
|
+
const FORMULA_TRIGGER_CHARACTERS = new Set([
|
|
6
6
|
'=',
|
|
7
7
|
'+',
|
|
8
8
|
'-',
|
|
9
9
|
'@',
|
|
10
10
|
'\t',
|
|
11
11
|
'\r'
|
|
12
|
-
];
|
|
12
|
+
]);
|
|
13
13
|
const escapeCsvValue = (value)=>{
|
|
14
14
|
if (value === null || value === undefined) {
|
|
15
15
|
return '';
|
|
16
16
|
}
|
|
17
17
|
let stringValue = typeof value === 'string' ? value : String(value);
|
|
18
|
-
if (typeof value === 'string' && FORMULA_TRIGGER_CHARACTERS.
|
|
18
|
+
if (typeof value === 'string' && FORMULA_TRIGGER_CHARACTERS.has(stringValue.charAt(0))) {
|
|
19
19
|
stringValue = `'${stringValue}`;
|
|
20
20
|
}
|
|
21
21
|
if (/[",\r\n]/.test(stringValue)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csv.js","sources":["../../../../../../../ee/server/src/audit-logs/utils/csv.ts"],"sourcesContent":["const CSV_LINE_SEPARATOR = '\\r\\n';\nconst CSV_BOM = '\\uFEFF';\nconst FORMULA_TRIGGER_CHARACTERS = ['=', '+', '-', '@', '\\t', '\\r'];\n\nconst escapeCsvValue = (value: unknown): string => {\n if (value === null || value === undefined) {\n return '';\n }\n\n let stringValue = typeof value === 'string' ? value : String(value);\n\n if (typeof value === 'string' && FORMULA_TRIGGER_CHARACTERS.
|
|
1
|
+
{"version":3,"file":"csv.js","sources":["../../../../../../../ee/server/src/audit-logs/utils/csv.ts"],"sourcesContent":["const CSV_LINE_SEPARATOR = '\\r\\n';\nconst CSV_BOM = '\\uFEFF';\nconst FORMULA_TRIGGER_CHARACTERS = new Set(['=', '+', '-', '@', '\\t', '\\r']);\n\nconst escapeCsvValue = (value: unknown): string => {\n if (value === null || value === undefined) {\n return '';\n }\n\n let stringValue = typeof value === 'string' ? value : String(value);\n\n if (typeof value === 'string' && FORMULA_TRIGGER_CHARACTERS.has(stringValue.charAt(0))) {\n stringValue = `'${stringValue}`;\n }\n\n if (/[\",\\r\\n]/.test(stringValue)) {\n return `\"${stringValue.replace(/\"/g, '\"\"')}\"`;\n }\n\n return stringValue;\n};\n\nconst serializeCsvLine = (values: unknown[]): string => {\n return values.map(escapeCsvValue).join(',') + CSV_LINE_SEPARATOR;\n};\n\nexport { escapeCsvValue, serializeCsvLine, CSV_BOM };\n"],"names":["CSV_LINE_SEPARATOR","CSV_BOM","FORMULA_TRIGGER_CHARACTERS","Set","escapeCsvValue","value","undefined","stringValue","String","has","charAt","test","replace","serializeCsvLine","values","map","join"],"mappings":";;AAAA,MAAMA,kBAAAA,GAAqB,MAAA;AAC3B,MAAMC,OAAAA,GAAU;AAChB,MAAMC,0BAAAA,GAA6B,IAAIC,GAAAA,CAAI;AAAC,IAAA,GAAA;AAAK,IAAA,GAAA;AAAK,IAAA,GAAA;AAAK,IAAA,GAAA;AAAK,IAAA,IAAA;AAAM,IAAA;AAAK,CAAA,CAAA;AAE3E,MAAMC,iBAAiB,CAACC,KAAAA,GAAAA;IACtB,IAAIA,KAAAA,KAAU,IAAA,IAAQA,KAAAA,KAAUC,SAAAA,EAAW;QACzC,OAAO,EAAA;AACT,IAAA;AAEA,IAAA,IAAIC,WAAAA,GAAc,OAAOF,KAAAA,KAAU,QAAA,GAAWA,QAAQG,MAAAA,CAAOH,KAAAA,CAAAA;IAE7D,IAAI,OAAOA,UAAU,QAAA,IAAYH,0BAAAA,CAA2BO,GAAG,CAACF,WAAAA,CAAYG,MAAM,CAAC,CAAA,CAAA,CAAA,EAAK;QACtFH,WAAAA,GAAc,CAAC,CAAC,EAAEA,WAAAA,CAAAA,CAAa;AACjC,IAAA;IAEA,IAAI,UAAA,CAAWI,IAAI,CAACJ,WAAAA,CAAAA,EAAc;QAChC,OAAO,CAAC,CAAC,EAAEA,WAAAA,CAAYK,OAAO,CAAC,IAAA,EAAM,IAAA,CAAA,CAAM,CAAC,CAAC;AAC/C,IAAA;IAEA,OAAOL,WAAAA;AACT;AAEA,MAAMM,mBAAmB,CAACC,MAAAA,GAAAA;AACxB,IAAA,OAAOA,OAAOC,GAAG,CAACX,cAAAA,CAAAA,CAAgBY,IAAI,CAAC,GAAA,CAAA,GAAOhB,kBAAAA;AAChD;;;;;;"}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
const CSV_LINE_SEPARATOR = '\r\n';
|
|
2
2
|
const CSV_BOM = '\uFEFF';
|
|
3
|
-
const FORMULA_TRIGGER_CHARACTERS = [
|
|
3
|
+
const FORMULA_TRIGGER_CHARACTERS = new Set([
|
|
4
4
|
'=',
|
|
5
5
|
'+',
|
|
6
6
|
'-',
|
|
7
7
|
'@',
|
|
8
8
|
'\t',
|
|
9
9
|
'\r'
|
|
10
|
-
];
|
|
10
|
+
]);
|
|
11
11
|
const escapeCsvValue = (value)=>{
|
|
12
12
|
if (value === null || value === undefined) {
|
|
13
13
|
return '';
|
|
14
14
|
}
|
|
15
15
|
let stringValue = typeof value === 'string' ? value : String(value);
|
|
16
|
-
if (typeof value === 'string' && FORMULA_TRIGGER_CHARACTERS.
|
|
16
|
+
if (typeof value === 'string' && FORMULA_TRIGGER_CHARACTERS.has(stringValue.charAt(0))) {
|
|
17
17
|
stringValue = `'${stringValue}`;
|
|
18
18
|
}
|
|
19
19
|
if (/[",\r\n]/.test(stringValue)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csv.mjs","sources":["../../../../../../../ee/server/src/audit-logs/utils/csv.ts"],"sourcesContent":["const CSV_LINE_SEPARATOR = '\\r\\n';\nconst CSV_BOM = '\\uFEFF';\nconst FORMULA_TRIGGER_CHARACTERS = ['=', '+', '-', '@', '\\t', '\\r'];\n\nconst escapeCsvValue = (value: unknown): string => {\n if (value === null || value === undefined) {\n return '';\n }\n\n let stringValue = typeof value === 'string' ? value : String(value);\n\n if (typeof value === 'string' && FORMULA_TRIGGER_CHARACTERS.
|
|
1
|
+
{"version":3,"file":"csv.mjs","sources":["../../../../../../../ee/server/src/audit-logs/utils/csv.ts"],"sourcesContent":["const CSV_LINE_SEPARATOR = '\\r\\n';\nconst CSV_BOM = '\\uFEFF';\nconst FORMULA_TRIGGER_CHARACTERS = new Set(['=', '+', '-', '@', '\\t', '\\r']);\n\nconst escapeCsvValue = (value: unknown): string => {\n if (value === null || value === undefined) {\n return '';\n }\n\n let stringValue = typeof value === 'string' ? value : String(value);\n\n if (typeof value === 'string' && FORMULA_TRIGGER_CHARACTERS.has(stringValue.charAt(0))) {\n stringValue = `'${stringValue}`;\n }\n\n if (/[\",\\r\\n]/.test(stringValue)) {\n return `\"${stringValue.replace(/\"/g, '\"\"')}\"`;\n }\n\n return stringValue;\n};\n\nconst serializeCsvLine = (values: unknown[]): string => {\n return values.map(escapeCsvValue).join(',') + CSV_LINE_SEPARATOR;\n};\n\nexport { escapeCsvValue, serializeCsvLine, CSV_BOM };\n"],"names":["CSV_LINE_SEPARATOR","CSV_BOM","FORMULA_TRIGGER_CHARACTERS","Set","escapeCsvValue","value","undefined","stringValue","String","has","charAt","test","replace","serializeCsvLine","values","map","join"],"mappings":"AAAA,MAAMA,kBAAAA,GAAqB,MAAA;AAC3B,MAAMC,OAAAA,GAAU;AAChB,MAAMC,0BAAAA,GAA6B,IAAIC,GAAAA,CAAI;AAAC,IAAA,GAAA;AAAK,IAAA,GAAA;AAAK,IAAA,GAAA;AAAK,IAAA,GAAA;AAAK,IAAA,IAAA;AAAM,IAAA;AAAK,CAAA,CAAA;AAE3E,MAAMC,iBAAiB,CAACC,KAAAA,GAAAA;IACtB,IAAIA,KAAAA,KAAU,IAAA,IAAQA,KAAAA,KAAUC,SAAAA,EAAW;QACzC,OAAO,EAAA;AACT,IAAA;AAEA,IAAA,IAAIC,WAAAA,GAAc,OAAOF,KAAAA,KAAU,QAAA,GAAWA,QAAQG,MAAAA,CAAOH,KAAAA,CAAAA;IAE7D,IAAI,OAAOA,UAAU,QAAA,IAAYH,0BAAAA,CAA2BO,GAAG,CAACF,WAAAA,CAAYG,MAAM,CAAC,CAAA,CAAA,CAAA,EAAK;QACtFH,WAAAA,GAAc,CAAC,CAAC,EAAEA,WAAAA,CAAAA,CAAa;AACjC,IAAA;IAEA,IAAI,UAAA,CAAWI,IAAI,CAACJ,WAAAA,CAAAA,EAAc;QAChC,OAAO,CAAC,CAAC,EAAEA,WAAAA,CAAYK,OAAO,CAAC,IAAA,EAAM,IAAA,CAAA,CAAM,CAAC,CAAC;AAC/C,IAAA;IAEA,OAAOL,WAAAA;AACT;AAEA,MAAMM,mBAAmB,CAACC,MAAAA,GAAAA;AACxB,IAAA,OAAOA,OAAOC,GAAG,CAACX,cAAAA,CAAAA,CAAgBY,IAAI,CAAC,GAAA,CAAA,GAAOhB,kBAAAA;AAChD;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seat-enforcement.js","sources":["../../../../../../ee/server/src/services/seat-enforcement.ts"],"sourcesContent":["import { pick, take, drop } from 'lodash';\n\nimport { getService } from '../utils';\nimport constants from '../../../../server/src/services/constants';\nimport type { AdminUser } from '../../../../shared/contracts/shared';\n\nconst { SUPER_ADMIN_CODE } = constants;\n\ntype DisabledUser = Pick<AdminUser, 'id' | 'isActive'>;\n\n/**\n * Returns users disabled by seat enforcement, or an empty list when none are stored.\n */\nconst getDisabledUserList = async (): Promise<DisabledUser[]> => {\n const disabledUsers = (await strapi.store.get({ type: 'ee', key: 'disabled_users' })) as\n
|
|
1
|
+
{"version":3,"file":"seat-enforcement.js","sources":["../../../../../../ee/server/src/services/seat-enforcement.ts"],"sourcesContent":["import { pick, take, drop } from 'lodash';\n\nimport { getService } from '../utils';\nimport constants from '../../../../server/src/services/constants';\nimport type { AdminUser } from '../../../../shared/contracts/shared';\n\nconst { SUPER_ADMIN_CODE } = constants;\n\ntype DisabledUser = Pick<AdminUser, 'id' | 'isActive'>;\n\n/**\n * Returns users disabled by seat enforcement, or an empty list when none are stored.\n */\nconst getDisabledUserList = async (): Promise<DisabledUser[]> => {\n const disabledUsers = (await strapi.store.get({ type: 'ee', key: 'disabled_users' })) as\n DisabledUser[] | null | undefined;\n\n return disabledUsers ?? [];\n};\n\nconst enableMaximumUserCount = async (numberOfUsersToEnable: number) => {\n const disabledUsers = await getDisabledUserList();\n const orderedDisabledUsers = [...disabledUsers].reverse();\n\n const usersToEnable = take(orderedDisabledUsers, numberOfUsersToEnable);\n\n await strapi.db.query('admin::user').updateMany({\n where: { id: usersToEnable.map((user) => user?.id) },\n data: { isActive: true },\n });\n\n const remainingDisabledUsers = drop(orderedDisabledUsers, numberOfUsersToEnable);\n\n await strapi.store.set({\n type: 'ee',\n key: 'disabled_users',\n value: remainingDisabledUsers,\n });\n};\n\nconst disableUsersAboveLicenseLimit = async (numberOfUsersToDisable: number) => {\n const currentlyDisabledUsers = await getDisabledUserList();\n\n const usersToDisable = [];\n const nonSuperAdminUsersToDisable = await strapi.db.query('admin::user').findMany({\n where: {\n isActive: true,\n roles: {\n code: { $ne: SUPER_ADMIN_CODE },\n },\n },\n orderBy: { createdAt: 'DESC' },\n limit: numberOfUsersToDisable,\n });\n\n usersToDisable.push(...nonSuperAdminUsersToDisable);\n\n if (nonSuperAdminUsersToDisable.length < numberOfUsersToDisable) {\n const superAdminUsersToDisable = await strapi.db.query('admin::user').findMany({\n where: {\n isActive: true,\n roles: { code: SUPER_ADMIN_CODE },\n },\n orderBy: { createdAt: 'DESC' },\n limit: numberOfUsersToDisable - nonSuperAdminUsersToDisable.length,\n });\n\n usersToDisable.push(...superAdminUsersToDisable);\n }\n\n await strapi.db.query('admin::user').updateMany({\n where: { id: usersToDisable.map((user) => user?.id) },\n data: { isActive: false },\n });\n\n await strapi.store.set({\n type: 'ee',\n key: 'disabled_users',\n value: currentlyDisabledUsers.concat(\n usersToDisable.map((user) => pick(user, ['id', 'isActive']))\n ),\n });\n};\n\nconst syncDisabledUserRecords = async () => {\n const disabledUsers = await getDisabledUserList();\n\n if (disabledUsers.length === 0) {\n return;\n }\n\n await strapi.db.query('admin::user').updateMany({\n where: { id: Array.from(disabledUsers, (user) => user?.id) },\n data: { isActive: false },\n });\n};\n\nconst seatEnforcementWorkflow = async () => {\n const adminSeats = strapi.ee.seats;\n if (adminSeats == null) {\n return;\n }\n\n // TODO: we need to make sure an admin can decide to disable specific user and reactivate others\n await syncDisabledUserRecords();\n\n const currentActiveUserCount = await getService('user').getCurrentActiveUserCount();\n\n const adminSeatsLeft = adminSeats - currentActiveUserCount;\n\n if (adminSeatsLeft > 0) {\n await enableMaximumUserCount(adminSeatsLeft);\n } else if (adminSeatsLeft < 0) {\n await disableUsersAboveLicenseLimit(-adminSeatsLeft);\n }\n};\n\nexport default {\n seatEnforcementWorkflow,\n getDisabledUserList,\n};\n"],"names":["SUPER_ADMIN_CODE","constants","getDisabledUserList","disabledUsers","strapi","store","get","type","key","enableMaximumUserCount","numberOfUsersToEnable","orderedDisabledUsers","reverse","usersToEnable","take","db","query","updateMany","where","id","map","user","data","isActive","remainingDisabledUsers","drop","set","value","disableUsersAboveLicenseLimit","numberOfUsersToDisable","currentlyDisabledUsers","usersToDisable","nonSuperAdminUsersToDisable","findMany","roles","code","$ne","orderBy","createdAt","limit","push","length","superAdminUsersToDisable","concat","pick","syncDisabledUserRecords","Array","from","seatEnforcementWorkflow","adminSeats","ee","seats","currentActiveUserCount","getService","getCurrentActiveUserCount","adminSeatsLeft"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seat-enforcement.mjs","sources":["../../../../../../ee/server/src/services/seat-enforcement.ts"],"sourcesContent":["import { pick, take, drop } from 'lodash';\n\nimport { getService } from '../utils';\nimport constants from '../../../../server/src/services/constants';\nimport type { AdminUser } from '../../../../shared/contracts/shared';\n\nconst { SUPER_ADMIN_CODE } = constants;\n\ntype DisabledUser = Pick<AdminUser, 'id' | 'isActive'>;\n\n/**\n * Returns users disabled by seat enforcement, or an empty list when none are stored.\n */\nconst getDisabledUserList = async (): Promise<DisabledUser[]> => {\n const disabledUsers = (await strapi.store.get({ type: 'ee', key: 'disabled_users' })) as\n
|
|
1
|
+
{"version":3,"file":"seat-enforcement.mjs","sources":["../../../../../../ee/server/src/services/seat-enforcement.ts"],"sourcesContent":["import { pick, take, drop } from 'lodash';\n\nimport { getService } from '../utils';\nimport constants from '../../../../server/src/services/constants';\nimport type { AdminUser } from '../../../../shared/contracts/shared';\n\nconst { SUPER_ADMIN_CODE } = constants;\n\ntype DisabledUser = Pick<AdminUser, 'id' | 'isActive'>;\n\n/**\n * Returns users disabled by seat enforcement, or an empty list when none are stored.\n */\nconst getDisabledUserList = async (): Promise<DisabledUser[]> => {\n const disabledUsers = (await strapi.store.get({ type: 'ee', key: 'disabled_users' })) as\n DisabledUser[] | null | undefined;\n\n return disabledUsers ?? [];\n};\n\nconst enableMaximumUserCount = async (numberOfUsersToEnable: number) => {\n const disabledUsers = await getDisabledUserList();\n const orderedDisabledUsers = [...disabledUsers].reverse();\n\n const usersToEnable = take(orderedDisabledUsers, numberOfUsersToEnable);\n\n await strapi.db.query('admin::user').updateMany({\n where: { id: usersToEnable.map((user) => user?.id) },\n data: { isActive: true },\n });\n\n const remainingDisabledUsers = drop(orderedDisabledUsers, numberOfUsersToEnable);\n\n await strapi.store.set({\n type: 'ee',\n key: 'disabled_users',\n value: remainingDisabledUsers,\n });\n};\n\nconst disableUsersAboveLicenseLimit = async (numberOfUsersToDisable: number) => {\n const currentlyDisabledUsers = await getDisabledUserList();\n\n const usersToDisable = [];\n const nonSuperAdminUsersToDisable = await strapi.db.query('admin::user').findMany({\n where: {\n isActive: true,\n roles: {\n code: { $ne: SUPER_ADMIN_CODE },\n },\n },\n orderBy: { createdAt: 'DESC' },\n limit: numberOfUsersToDisable,\n });\n\n usersToDisable.push(...nonSuperAdminUsersToDisable);\n\n if (nonSuperAdminUsersToDisable.length < numberOfUsersToDisable) {\n const superAdminUsersToDisable = await strapi.db.query('admin::user').findMany({\n where: {\n isActive: true,\n roles: { code: SUPER_ADMIN_CODE },\n },\n orderBy: { createdAt: 'DESC' },\n limit: numberOfUsersToDisable - nonSuperAdminUsersToDisable.length,\n });\n\n usersToDisable.push(...superAdminUsersToDisable);\n }\n\n await strapi.db.query('admin::user').updateMany({\n where: { id: usersToDisable.map((user) => user?.id) },\n data: { isActive: false },\n });\n\n await strapi.store.set({\n type: 'ee',\n key: 'disabled_users',\n value: currentlyDisabledUsers.concat(\n usersToDisable.map((user) => pick(user, ['id', 'isActive']))\n ),\n });\n};\n\nconst syncDisabledUserRecords = async () => {\n const disabledUsers = await getDisabledUserList();\n\n if (disabledUsers.length === 0) {\n return;\n }\n\n await strapi.db.query('admin::user').updateMany({\n where: { id: Array.from(disabledUsers, (user) => user?.id) },\n data: { isActive: false },\n });\n};\n\nconst seatEnforcementWorkflow = async () => {\n const adminSeats = strapi.ee.seats;\n if (adminSeats == null) {\n return;\n }\n\n // TODO: we need to make sure an admin can decide to disable specific user and reactivate others\n await syncDisabledUserRecords();\n\n const currentActiveUserCount = await getService('user').getCurrentActiveUserCount();\n\n const adminSeatsLeft = adminSeats - currentActiveUserCount;\n\n if (adminSeatsLeft > 0) {\n await enableMaximumUserCount(adminSeatsLeft);\n } else if (adminSeatsLeft < 0) {\n await disableUsersAboveLicenseLimit(-adminSeatsLeft);\n }\n};\n\nexport default {\n seatEnforcementWorkflow,\n getDisabledUserList,\n};\n"],"names":["SUPER_ADMIN_CODE","constants","getDisabledUserList","disabledUsers","strapi","store","get","type","key","enableMaximumUserCount","numberOfUsersToEnable","orderedDisabledUsers","reverse","usersToEnable","take","db","query","updateMany","where","id","map","user","data","isActive","remainingDisabledUsers","drop","set","value","disableUsersAboveLicenseLimit","numberOfUsersToDisable","currentlyDisabledUsers","usersToDisable","nonSuperAdminUsersToDisable","findMany","roles","code","$ne","orderBy","createdAt","limit","push","length","superAdminUsersToDisable","concat","pick","syncDisabledUserRecords","Array","from","seatEnforcementWorkflow","adminSeats","ee","seats","currentActiveUserCount","getService","getCurrentActiveUserCount","adminSeatsLeft"],"mappings":"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"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var utils = require('@strapi/utils');
|
|
4
|
+
var constants = require('../../../../server/src/services/constants.js');
|
|
4
5
|
|
|
6
|
+
const { ROLE_TEXT_MAX_LENGTH } = constants;
|
|
5
7
|
const roleCreateSchema = utils.yup.object().shape({
|
|
6
|
-
name: utils.yup.string().min(1).required(),
|
|
7
|
-
description: utils.yup.string().nullable()
|
|
8
|
+
name: utils.yup.string().min(1).max(ROLE_TEXT_MAX_LENGTH).required(),
|
|
9
|
+
description: utils.yup.string().max(ROLE_TEXT_MAX_LENGTH).nullable()
|
|
8
10
|
}).noUnknown();
|
|
9
11
|
const rolesDeleteSchema = utils.yup.object().shape({
|
|
10
12
|
ids: utils.yup.array().of(utils.yup.strapiID()).min(1).required().test('roles-deletion-checks', 'Roles deletion checks have failed', async function rolesDeletionChecks(ids) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"role.js","sources":["../../../../../../ee/server/src/validation/role.ts"],"sourcesContent":["import { yup, validateYupSchema } from '@strapi/utils';\n\nconst roleCreateSchema = yup\n .object()\n .shape({\n name: yup.string().min(1).required(),\n description: yup.string().nullable(),\n })\n .noUnknown();\n\nconst rolesDeleteSchema = yup\n .object()\n .shape({\n ids: yup\n .array()\n .of(yup.strapiID())\n .min(1)\n .required()\n .test(\n 'roles-deletion-checks',\n 'Roles deletion checks have failed',\n async function rolesDeletionChecks(ids) {\n try {\n await strapi.service('admin::role').checkRolesIdForDeletion(ids);\n\n if (strapi.ee.features.isEnabled('sso')) {\n await strapi.service('admin::role').ssoCheckRolesIdForDeletion(ids);\n }\n } catch (e: any) {\n return this.createError({ path: 'ids', message: e.message });\n }\n\n return true;\n }\n ),\n })\n .noUnknown();\n\nconst roleDeleteSchema = yup\n .strapiID()\n .required()\n .test(\n 'no-admin-single-delete',\n 'Role deletion checks have failed',\n async function noAdminSingleDelete(id) {\n try {\n await strapi.service('admin::role').checkRolesIdForDeletion([id]);\n\n if (strapi.ee.features.isEnabled('sso')) {\n await strapi.service('admin::role').ssoCheckRolesIdForDeletion([id]);\n }\n } catch (e: any) {\n return this.createError({ path: 'id', message: e.message });\n }\n\n return true;\n }\n );\n\nexport const validateRoleCreateInput = validateYupSchema(roleCreateSchema);\nexport const validateRolesDeleteInput = validateYupSchema(rolesDeleteSchema);\nexport const validateRoleDeleteInput = validateYupSchema(roleDeleteSchema);\n\nexport default {\n validateRoleCreateInput,\n validateRolesDeleteInput,\n validateRoleDeleteInput,\n};\n"],"names":["roleCreateSchema","yup","object","shape","name","string","min","required","description","nullable","noUnknown","rolesDeleteSchema","ids","array","of","strapiID","test","rolesDeletionChecks","strapi","service","checkRolesIdForDeletion","ee","features","isEnabled","ssoCheckRolesIdForDeletion","e","createError","path","message","roleDeleteSchema","noAdminSingleDelete","id","validateRoleCreateInput","validateYupSchema","validateRolesDeleteInput","validateRoleDeleteInput"],"mappings":"
|
|
1
|
+
{"version":3,"file":"role.js","sources":["../../../../../../ee/server/src/validation/role.ts"],"sourcesContent":["import { yup, validateYupSchema } from '@strapi/utils';\nimport constants from '../../../../server/src/services/constants';\n\nconst { ROLE_TEXT_MAX_LENGTH } = constants;\n\nconst roleCreateSchema = yup\n .object()\n .shape({\n name: yup.string().min(1).max(ROLE_TEXT_MAX_LENGTH).required(),\n description: yup.string().max(ROLE_TEXT_MAX_LENGTH).nullable(),\n })\n .noUnknown();\n\nconst rolesDeleteSchema = yup\n .object()\n .shape({\n ids: yup\n .array()\n .of(yup.strapiID())\n .min(1)\n .required()\n .test(\n 'roles-deletion-checks',\n 'Roles deletion checks have failed',\n async function rolesDeletionChecks(ids) {\n try {\n await strapi.service('admin::role').checkRolesIdForDeletion(ids);\n\n if (strapi.ee.features.isEnabled('sso')) {\n await strapi.service('admin::role').ssoCheckRolesIdForDeletion(ids);\n }\n } catch (e: any) {\n return this.createError({ path: 'ids', message: e.message });\n }\n\n return true;\n }\n ),\n })\n .noUnknown();\n\nconst roleDeleteSchema = yup\n .strapiID()\n .required()\n .test(\n 'no-admin-single-delete',\n 'Role deletion checks have failed',\n async function noAdminSingleDelete(id) {\n try {\n await strapi.service('admin::role').checkRolesIdForDeletion([id]);\n\n if (strapi.ee.features.isEnabled('sso')) {\n await strapi.service('admin::role').ssoCheckRolesIdForDeletion([id]);\n }\n } catch (e: any) {\n return this.createError({ path: 'id', message: e.message });\n }\n\n return true;\n }\n );\n\nexport const validateRoleCreateInput = validateYupSchema(roleCreateSchema);\nexport const validateRolesDeleteInput = validateYupSchema(rolesDeleteSchema);\nexport const validateRoleDeleteInput = validateYupSchema(roleDeleteSchema);\n\nexport default {\n validateRoleCreateInput,\n validateRolesDeleteInput,\n validateRoleDeleteInput,\n};\n"],"names":["ROLE_TEXT_MAX_LENGTH","constants","roleCreateSchema","yup","object","shape","name","string","min","max","required","description","nullable","noUnknown","rolesDeleteSchema","ids","array","of","strapiID","test","rolesDeletionChecks","strapi","service","checkRolesIdForDeletion","ee","features","isEnabled","ssoCheckRolesIdForDeletion","e","createError","path","message","roleDeleteSchema","noAdminSingleDelete","id","validateRoleCreateInput","validateYupSchema","validateRolesDeleteInput","validateRoleDeleteInput"],"mappings":";;;;;AAGA,MAAM,EAAEA,oBAAoB,EAAE,GAAGC,SAAAA;AAEjC,MAAMC,gBAAAA,GAAmBC,SAAAA,CACtBC,MAAM,EAAA,CACNC,KAAK,CAAC;IACLC,IAAAA,EAAMH,SAAAA,CAAII,MAAM,EAAA,CAAGC,GAAG,CAAC,CAAA,CAAA,CAAGC,GAAG,CAACT,oBAAAA,CAAAA,CAAsBU,QAAQ,EAAA;AAC5DC,IAAAA,WAAAA,EAAaR,UAAII,MAAM,EAAA,CAAGE,GAAG,CAACT,sBAAsBY,QAAQ;AAC9D,CAAA,CAAA,CACCC,SAAS,EAAA;AAEZ,MAAMC,iBAAAA,GAAoBX,SAAAA,CACvBC,MAAM,EAAA,CACNC,KAAK,CAAC;AACLU,IAAAA,GAAAA,EAAKZ,UACFa,KAAK,EAAA,CACLC,EAAE,CAACd,SAAAA,CAAIe,QAAQ,EAAA,CAAA,CACfV,GAAG,CAAC,CAAA,CAAA,CACJE,QAAQ,GACRS,IAAI,CACH,yBACA,mCAAA,EACA,eAAeC,oBAAoBL,GAAG,EAAA;QACpC,IAAI;AACF,YAAA,MAAMM,MAAAA,CAAOC,OAAO,CAAC,aAAA,CAAA,CAAeC,uBAAuB,CAACR,GAAAA,CAAAA;AAE5D,YAAA,IAAIM,OAAOG,EAAE,CAACC,QAAQ,CAACC,SAAS,CAAC,KAAA,CAAA,EAAQ;AACvC,gBAAA,MAAML,MAAAA,CAAOC,OAAO,CAAC,aAAA,CAAA,CAAeK,0BAA0B,CAACZ,GAAAA,CAAAA;AACjE,YAAA;AACF,QAAA,CAAA,CAAE,OAAOa,CAAAA,EAAQ;YACf,OAAO,IAAI,CAACC,WAAW,CAAC;gBAAEC,IAAAA,EAAM,KAAA;AAAOC,gBAAAA,OAAAA,EAASH,EAAEG;AAAQ,aAAA,CAAA;AAC5D,QAAA;QAEA,OAAO,IAAA;AACT,IAAA,CAAA;AAEN,CAAA,CAAA,CACClB,SAAS,EAAA;AAEZ,MAAMmB,gBAAAA,GAAmB7B,SAAAA,CACtBe,QAAQ,EAAA,CACRR,QAAQ,EAAA,CACRS,IAAI,CACH,wBAAA,EACA,kCAAA,EACA,eAAec,mBAAAA,CAAoBC,EAAE,EAAA;IACnC,IAAI;AACF,QAAA,MAAMb,MAAAA,CAAOC,OAAO,CAAC,aAAA,CAAA,CAAeC,uBAAuB,CAAC;AAACW,YAAAA;AAAG,SAAA,CAAA;AAEhE,QAAA,IAAIb,OAAOG,EAAE,CAACC,QAAQ,CAACC,SAAS,CAAC,KAAA,CAAA,EAAQ;AACvC,YAAA,MAAML,MAAAA,CAAOC,OAAO,CAAC,aAAA,CAAA,CAAeK,0BAA0B,CAAC;AAACO,gBAAAA;AAAG,aAAA,CAAA;AACrE,QAAA;AACF,IAAA,CAAA,CAAE,OAAON,CAAAA,EAAQ;QACf,OAAO,IAAI,CAACC,WAAW,CAAC;YAAEC,IAAAA,EAAM,IAAA;AAAMC,YAAAA,OAAAA,EAASH,EAAEG;AAAQ,SAAA,CAAA;AAC3D,IAAA;IAEA,OAAO,IAAA;AACT,CAAA,CAAA;AAGG,MAAMI,uBAAAA,GAA0BC,uBAAAA,CAAkBlC,gBAAAA;AAClD,MAAMmC,wBAAAA,GAA2BD,uBAAAA,CAAkBtB,iBAAAA;AACnD,MAAMwB,uBAAAA,GAA0BF,uBAAAA,CAAkBJ,gBAAAA;;;;;;"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { yup, validateYupSchema } from '@strapi/utils';
|
|
2
|
+
import constants from '../../../../server/src/services/constants.mjs';
|
|
2
3
|
|
|
4
|
+
const { ROLE_TEXT_MAX_LENGTH } = constants;
|
|
3
5
|
const roleCreateSchema = yup.object().shape({
|
|
4
|
-
name: yup.string().min(1).required(),
|
|
5
|
-
description: yup.string().nullable()
|
|
6
|
+
name: yup.string().min(1).max(ROLE_TEXT_MAX_LENGTH).required(),
|
|
7
|
+
description: yup.string().max(ROLE_TEXT_MAX_LENGTH).nullable()
|
|
6
8
|
}).noUnknown();
|
|
7
9
|
const rolesDeleteSchema = yup.object().shape({
|
|
8
10
|
ids: yup.array().of(yup.strapiID()).min(1).required().test('roles-deletion-checks', 'Roles deletion checks have failed', async function rolesDeletionChecks(ids) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"role.mjs","sources":["../../../../../../ee/server/src/validation/role.ts"],"sourcesContent":["import { yup, validateYupSchema } from '@strapi/utils';\n\nconst roleCreateSchema = yup\n .object()\n .shape({\n name: yup.string().min(1).required(),\n description: yup.string().nullable(),\n })\n .noUnknown();\n\nconst rolesDeleteSchema = yup\n .object()\n .shape({\n ids: yup\n .array()\n .of(yup.strapiID())\n .min(1)\n .required()\n .test(\n 'roles-deletion-checks',\n 'Roles deletion checks have failed',\n async function rolesDeletionChecks(ids) {\n try {\n await strapi.service('admin::role').checkRolesIdForDeletion(ids);\n\n if (strapi.ee.features.isEnabled('sso')) {\n await strapi.service('admin::role').ssoCheckRolesIdForDeletion(ids);\n }\n } catch (e: any) {\n return this.createError({ path: 'ids', message: e.message });\n }\n\n return true;\n }\n ),\n })\n .noUnknown();\n\nconst roleDeleteSchema = yup\n .strapiID()\n .required()\n .test(\n 'no-admin-single-delete',\n 'Role deletion checks have failed',\n async function noAdminSingleDelete(id) {\n try {\n await strapi.service('admin::role').checkRolesIdForDeletion([id]);\n\n if (strapi.ee.features.isEnabled('sso')) {\n await strapi.service('admin::role').ssoCheckRolesIdForDeletion([id]);\n }\n } catch (e: any) {\n return this.createError({ path: 'id', message: e.message });\n }\n\n return true;\n }\n );\n\nexport const validateRoleCreateInput = validateYupSchema(roleCreateSchema);\nexport const validateRolesDeleteInput = validateYupSchema(rolesDeleteSchema);\nexport const validateRoleDeleteInput = validateYupSchema(roleDeleteSchema);\n\nexport default {\n validateRoleCreateInput,\n validateRolesDeleteInput,\n validateRoleDeleteInput,\n};\n"],"names":["roleCreateSchema","yup","object","shape","name","string","min","required","description","nullable","noUnknown","rolesDeleteSchema","ids","array","of","strapiID","test","rolesDeletionChecks","strapi","service","checkRolesIdForDeletion","ee","features","isEnabled","ssoCheckRolesIdForDeletion","e","createError","path","message","roleDeleteSchema","noAdminSingleDelete","id","validateRoleCreateInput","validateYupSchema","validateRolesDeleteInput","validateRoleDeleteInput"],"mappings":"
|
|
1
|
+
{"version":3,"file":"role.mjs","sources":["../../../../../../ee/server/src/validation/role.ts"],"sourcesContent":["import { yup, validateYupSchema } from '@strapi/utils';\nimport constants from '../../../../server/src/services/constants';\n\nconst { ROLE_TEXT_MAX_LENGTH } = constants;\n\nconst roleCreateSchema = yup\n .object()\n .shape({\n name: yup.string().min(1).max(ROLE_TEXT_MAX_LENGTH).required(),\n description: yup.string().max(ROLE_TEXT_MAX_LENGTH).nullable(),\n })\n .noUnknown();\n\nconst rolesDeleteSchema = yup\n .object()\n .shape({\n ids: yup\n .array()\n .of(yup.strapiID())\n .min(1)\n .required()\n .test(\n 'roles-deletion-checks',\n 'Roles deletion checks have failed',\n async function rolesDeletionChecks(ids) {\n try {\n await strapi.service('admin::role').checkRolesIdForDeletion(ids);\n\n if (strapi.ee.features.isEnabled('sso')) {\n await strapi.service('admin::role').ssoCheckRolesIdForDeletion(ids);\n }\n } catch (e: any) {\n return this.createError({ path: 'ids', message: e.message });\n }\n\n return true;\n }\n ),\n })\n .noUnknown();\n\nconst roleDeleteSchema = yup\n .strapiID()\n .required()\n .test(\n 'no-admin-single-delete',\n 'Role deletion checks have failed',\n async function noAdminSingleDelete(id) {\n try {\n await strapi.service('admin::role').checkRolesIdForDeletion([id]);\n\n if (strapi.ee.features.isEnabled('sso')) {\n await strapi.service('admin::role').ssoCheckRolesIdForDeletion([id]);\n }\n } catch (e: any) {\n return this.createError({ path: 'id', message: e.message });\n }\n\n return true;\n }\n );\n\nexport const validateRoleCreateInput = validateYupSchema(roleCreateSchema);\nexport const validateRolesDeleteInput = validateYupSchema(rolesDeleteSchema);\nexport const validateRoleDeleteInput = validateYupSchema(roleDeleteSchema);\n\nexport default {\n validateRoleCreateInput,\n validateRolesDeleteInput,\n validateRoleDeleteInput,\n};\n"],"names":["ROLE_TEXT_MAX_LENGTH","constants","roleCreateSchema","yup","object","shape","name","string","min","max","required","description","nullable","noUnknown","rolesDeleteSchema","ids","array","of","strapiID","test","rolesDeletionChecks","strapi","service","checkRolesIdForDeletion","ee","features","isEnabled","ssoCheckRolesIdForDeletion","e","createError","path","message","roleDeleteSchema","noAdminSingleDelete","id","validateRoleCreateInput","validateYupSchema","validateRolesDeleteInput","validateRoleDeleteInput"],"mappings":";;;AAGA,MAAM,EAAEA,oBAAoB,EAAE,GAAGC,SAAAA;AAEjC,MAAMC,gBAAAA,GAAmBC,GAAAA,CACtBC,MAAM,EAAA,CACNC,KAAK,CAAC;IACLC,IAAAA,EAAMH,GAAAA,CAAII,MAAM,EAAA,CAAGC,GAAG,CAAC,CAAA,CAAA,CAAGC,GAAG,CAACT,oBAAAA,CAAAA,CAAsBU,QAAQ,EAAA;AAC5DC,IAAAA,WAAAA,EAAaR,IAAII,MAAM,EAAA,CAAGE,GAAG,CAACT,sBAAsBY,QAAQ;AAC9D,CAAA,CAAA,CACCC,SAAS,EAAA;AAEZ,MAAMC,iBAAAA,GAAoBX,GAAAA,CACvBC,MAAM,EAAA,CACNC,KAAK,CAAC;AACLU,IAAAA,GAAAA,EAAKZ,IACFa,KAAK,EAAA,CACLC,EAAE,CAACd,GAAAA,CAAIe,QAAQ,EAAA,CAAA,CACfV,GAAG,CAAC,CAAA,CAAA,CACJE,QAAQ,GACRS,IAAI,CACH,yBACA,mCAAA,EACA,eAAeC,oBAAoBL,GAAG,EAAA;QACpC,IAAI;AACF,YAAA,MAAMM,MAAAA,CAAOC,OAAO,CAAC,aAAA,CAAA,CAAeC,uBAAuB,CAACR,GAAAA,CAAAA;AAE5D,YAAA,IAAIM,OAAOG,EAAE,CAACC,QAAQ,CAACC,SAAS,CAAC,KAAA,CAAA,EAAQ;AACvC,gBAAA,MAAML,MAAAA,CAAOC,OAAO,CAAC,aAAA,CAAA,CAAeK,0BAA0B,CAACZ,GAAAA,CAAAA;AACjE,YAAA;AACF,QAAA,CAAA,CAAE,OAAOa,CAAAA,EAAQ;YACf,OAAO,IAAI,CAACC,WAAW,CAAC;gBAAEC,IAAAA,EAAM,KAAA;AAAOC,gBAAAA,OAAAA,EAASH,EAAEG;AAAQ,aAAA,CAAA;AAC5D,QAAA;QAEA,OAAO,IAAA;AACT,IAAA,CAAA;AAEN,CAAA,CAAA,CACClB,SAAS,EAAA;AAEZ,MAAMmB,gBAAAA,GAAmB7B,GAAAA,CACtBe,QAAQ,EAAA,CACRR,QAAQ,EAAA,CACRS,IAAI,CACH,wBAAA,EACA,kCAAA,EACA,eAAec,mBAAAA,CAAoBC,EAAE,EAAA;IACnC,IAAI;AACF,QAAA,MAAMb,MAAAA,CAAOC,OAAO,CAAC,aAAA,CAAA,CAAeC,uBAAuB,CAAC;AAACW,YAAAA;AAAG,SAAA,CAAA;AAEhE,QAAA,IAAIb,OAAOG,EAAE,CAACC,QAAQ,CAACC,SAAS,CAAC,KAAA,CAAA,EAAQ;AACvC,YAAA,MAAML,MAAAA,CAAOC,OAAO,CAAC,aAAA,CAAA,CAAeK,0BAA0B,CAAC;AAACO,gBAAAA;AAAG,aAAA,CAAA;AACrE,QAAA;AACF,IAAA,CAAA,CAAE,OAAON,CAAAA,EAAQ;QACf,OAAO,IAAI,CAACC,WAAW,CAAC;YAAEC,IAAAA,EAAM,IAAA;AAAMC,YAAAA,OAAAA,EAASH,EAAEG;AAAQ,SAAA,CAAA;AAC3D,IAAA;IAEA,OAAO,IAAA;AACT,CAAA,CAAA;AAGG,MAAMI,uBAAAA,GAA0BC,iBAAAA,CAAkBlC,gBAAAA;AAClD,MAAMmC,wBAAAA,GAA2BD,iBAAAA,CAAkBtB,iBAAAA;AACnD,MAAMwB,uBAAAA,GAA0BF,iBAAAA,CAAkBJ,gBAAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai.js","sources":["../../../../../../server/src/ai/services/ai.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { AdminUser } from '../../../../shared/contracts/shared';\n\nconst STRAPI_MANAGED_AI_LICENSE_FEATURE = 'cms-ai';\nconst CUSTOM_AI_PROVIDER_LICENSE_FEATURE = 'cms-byok-ai';\n\nconst createAiAdminService = ({ strapi }: { strapi: Core.Strapi }) => {\n /**\n * In-memory cache for AI tokens\n * Key format: `${projectId}:${userId}`\n */\n const aiTokenCache = new Map<\n string,\n {\n token: string;\n expiresAt?: string;\n expiresAtMs?: number;\n }\n >();\n\n let isCustomProviderRejected = false;\n\n const isConfigEnabled = (): boolean => strapi.config.get('admin.ai.enabled', true) === true;\n\n const isAvailable = (): boolean =>\n isConfigEnabled() && strapi.ee?.isEE === true && !isCustomProviderRejected;\n\n const isStrapiManagedAiEnabled = (): boolean =>\n isConfigEnabled() &&\n !isCustomProviderRejected &&\n strapi.ee?.features?.isEnabled(STRAPI_MANAGED_AI_LICENSE_FEATURE) === true;\n\n const authorizeCustomProvider = (): boolean => {\n if (!isConfigEnabled()) {\n strapi.log.info(\n 'A custom AI provider was ignored: AI is disabled by the \"admin.ai.enabled\" config.'\n );\n return false;\n }\n\n if (strapi.ee?.features?.isEnabled(CUSTOM_AI_PROVIDER_LICENSE_FEATURE) === true) {\n return true;\n }\n\n isCustomProviderRejected = true;\n strapi.log.warn(\n `A custom AI provider was rejected: the Strapi license does not include the \"${CUSTOM_AI_PROVIDER_LICENSE_FEATURE}\" feature. All AI features are disabled.`\n );\n return false;\n };\n\n const isPluginAiFeatureConfigured = async (plugin: string, service: string): Promise<boolean> => {\n const aiService = strapi.plugin(plugin)?.service(service) as\n | { isEnabled?: () => Promise<boolean> | boolean }\n | undefined;\n\n if (typeof aiService?.isEnabled !== 'function') {\n return false;\n }\n\n return (await aiService.isEnabled()) === true;\n };\n\n const getAiFeatureConfig = async () => {\n if (!isAvailable()) {\n return {\n isAiI18nConfigured: false,\n isAiMediaLibraryConfigured: false,\n };\n }\n\n const [isAiI18nConfigured, isAiMediaLibraryConfigured] = await Promise.all([\n isPluginAiFeatureConfigured('i18n', 'ai-localizations'),\n isPluginAiFeatureConfigured('upload', 'aiMetadata'),\n ]);\n\n return { isAiI18nConfigured, isAiMediaLibraryConfigured };\n };\n\n /**\n * Resolves the shared context required by both getAiToken and getAiUsage:\n * EE license, project ID, and AI server URL.\n */\n const resolveAiContext = (errorPrefix: string) => {\n if (!isStrapiManagedAiEnabled()) {\n strapi.log.error(`${errorPrefix} AI is not enabled`);\n throw new Error(`${errorPrefix.replace(/:$/, '')}. Check server logs for details.`);\n }\n\n if (!strapi.ee?.isEE) {\n strapi.log.error(`${errorPrefix} Enterprise Edition features are not enabled`);\n throw new Error(`${errorPrefix.replace(/:$/, '')}. Check server logs for details.`);\n }\n\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 {\n // License file doesn't exist or can't be read\n }\n }\n\n if (!eeLicense) {\n strapi.log.error(\n `${errorPrefix} No EE license found. Please ensure STRAPI_LICENSE environment variable is set or license.txt file exists.`\n );\n throw new Error(`${errorPrefix.replace(/:$/, '')}. Check server logs for details.`);\n }\n\n const projectId = strapi.config.get('uuid');\n if (!projectId) {\n strapi.log.error(`${errorPrefix} Project ID not configured`);\n throw new Error(`${errorPrefix.replace(/:$/, '')}. Check server logs for details.`);\n }\n\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n return { eeLicense, projectId, aiServerUrl };\n };\n\n const getAiToken = async () => {\n const ERROR_PREFIX = 'AI token request failed:';\n\n const { eeLicense, projectId, aiServerUrl } = resolveAiContext(ERROR_PREFIX);\n\n // Get the current user\n const user = strapi.requestContext.get()?.state?.user as AdminUser | undefined;\n if (!user) {\n strapi.log.error(`${ERROR_PREFIX} No authenticated user in request context`);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n // Create a secure user identifier using only user ID\n const userIdentifier = user.id.toString();\n\n // Check cache for existing valid token\n const cacheKey = `${projectId}:${userIdentifier}`;\n const cachedToken = aiTokenCache.get(cacheKey);\n\n if (cachedToken) {\n const now = Date.now();\n // Check if token is still valid (with buffer so it has time to be used)\n const bufferMs = 2 * 60 * 1000; // 2 minutes\n\n if (cachedToken.expiresAtMs && cachedToken.expiresAtMs - bufferMs > now) {\n strapi.log.info('Using cached AI token');\n\n return {\n token: cachedToken.token,\n expiresAt: cachedToken.expiresAt,\n };\n }\n\n // Token expired or will expire soon, remove from cache\n aiTokenCache.delete(cacheKey);\n }\n\n strapi.log.http('Contacting AI Server for token generation');\n\n try {\n const response = await fetch(`${aiServerUrl}/auth/getAiJWT`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\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 throw new Error('AI token request failed. Check server logs for details.');\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 throw new Error('AI token request failed. Check server logs for details.');\n }\n\n if (!data.jwt) {\n strapi.log.error(`${ERROR_PREFIX} Invalid response: missing JWT token`);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n strapi.log.info('AI token generated successfully', {\n userId: user.id,\n expiresAt: data.expiresAt,\n });\n\n // Cache the token if it has an expiration time\n if (data.expiresAt) {\n const expiresAtMs = new Date(data.expiresAt).getTime();\n aiTokenCache.set(cacheKey, {\n token: data.jwt,\n expiresAt: data.expiresAt,\n expiresAtMs,\n });\n }\n\n // Note: Token expires in 1 hour, client should handle refresh\n return {\n token: data.jwt,\n expiresAt: data.expiresAt,\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 throw new Error('AI token request failed. Check server logs for details.');\n }\n\n throw fetchError;\n }\n };\n\n const getAiUsage = async () => {\n const ERROR_PREFIX = 'AI usage data request failed:';\n\n const { eeLicense, projectId, aiServerUrl } = resolveAiContext(ERROR_PREFIX);\n\n strapi.log.http('Contacting AI Server for usage data');\n\n try {\n const response = await fetch(`${aiServerUrl}/cms/ai-data`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\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 throw new Error('AI usage data request failed. Check server logs for details.');\n }\n\n let data;\n try {\n data = (await response.json()) as {\n data: { cmsAiCreditsUsed: number };\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 throw new Error('AI usage data request failed. Check server logs for details.');\n }\n\n return {\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 throw new Error('AI usage data request failed. Check server logs for details.');\n }\n\n throw fetchError;\n }\n };\n\n return {\n /* Requires `ai.enabled=true` + license + no failed AI provider registration */\n isAvailable,\n /* `true` only when the license has the `cms-ai` entitlement to globally enable AI features.\n TODO: once all AI features are migrated to the providers architecture, consider removing this flag */\n isStrapiManagedAiEnabled,\n authorizeCustomProvider,\n /* Returns the status of each AI feature, flagging which are enabled. */\n getAiFeatureConfig,\n getAiToken,\n getAiUsage,\n };\n};\n\nexport { createAiAdminService };\n"],"names":["STRAPI_MANAGED_AI_LICENSE_FEATURE","CUSTOM_AI_PROVIDER_LICENSE_FEATURE","createAiAdminService","strapi","aiTokenCache","Map","isCustomProviderRejected","isConfigEnabled","config","get","isAvailable","ee","isEE","isStrapiManagedAiEnabled","features","isEnabled","authorizeCustomProvider","log","info","warn","isPluginAiFeatureConfigured","plugin","service","aiService","getAiFeatureConfig","isAiI18nConfigured","isAiMediaLibraryConfigured","Promise","all","resolveAiContext","errorPrefix","error","Error","replace","eeLicense","process","env","STRAPI_LICENSE","licensePath","path","join","dirs","app","root","fs","readFileSync","toString","projectId","aiServerUrl","STRAPI_AI_URL","getAiToken","ERROR_PREFIX","user","requestContext","state","userIdentifier","id","cacheKey","cachedToken","now","Date","bufferMs","expiresAtMs","token","expiresAt","delete","http","response","fetch","method","headers","crypto","randomUUID","body","JSON","stringify","ok","errorData","errorText","text","parse","status","statusText","data","json","parseError","jwt","userId","getTime","set","fetchError","name","getAiUsage","eeKey","subscription"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai.js","sources":["../../../../../../server/src/ai/services/ai.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { AdminUser } from '../../../../shared/contracts/shared';\n\nconst STRAPI_MANAGED_AI_LICENSE_FEATURE = 'cms-ai';\nconst CUSTOM_AI_PROVIDER_LICENSE_FEATURE = 'cms-byok-ai';\n\nconst createAiAdminService = ({ strapi }: { strapi: Core.Strapi }) => {\n /**\n * In-memory cache for AI tokens\n * Key format: `${projectId}:${userId}`\n */\n const aiTokenCache = new Map<\n string,\n {\n token: string;\n expiresAt?: string;\n expiresAtMs?: number;\n }\n >();\n\n let isCustomProviderRejected = false;\n\n const isConfigEnabled = (): boolean => strapi.config.get('admin.ai.enabled', true) === true;\n\n const isAvailable = (): boolean =>\n isConfigEnabled() && strapi.ee?.isEE === true && !isCustomProviderRejected;\n\n const isStrapiManagedAiEnabled = (): boolean =>\n isConfigEnabled() &&\n !isCustomProviderRejected &&\n strapi.ee?.features?.isEnabled(STRAPI_MANAGED_AI_LICENSE_FEATURE) === true;\n\n const authorizeCustomProvider = (): boolean => {\n if (!isConfigEnabled()) {\n strapi.log.info(\n 'A custom AI provider was ignored: AI is disabled by the \"admin.ai.enabled\" config.'\n );\n return false;\n }\n\n if (strapi.ee?.features?.isEnabled(CUSTOM_AI_PROVIDER_LICENSE_FEATURE) === true) {\n return true;\n }\n\n isCustomProviderRejected = true;\n strapi.log.warn(\n `A custom AI provider was rejected: the Strapi license does not include the \"${CUSTOM_AI_PROVIDER_LICENSE_FEATURE}\" feature. All AI features are disabled.`\n );\n return false;\n };\n\n const isPluginAiFeatureConfigured = async (plugin: string, service: string): Promise<boolean> => {\n const aiService = strapi.plugin(plugin)?.service(service) as\n { isEnabled?: () => Promise<boolean> | boolean } | undefined;\n\n if (typeof aiService?.isEnabled !== 'function') {\n return false;\n }\n\n return (await aiService.isEnabled()) === true;\n };\n\n const getAiFeatureConfig = async () => {\n if (!isAvailable()) {\n return {\n isAiI18nConfigured: false,\n isAiMediaLibraryConfigured: false,\n };\n }\n\n const [isAiI18nConfigured, isAiMediaLibraryConfigured] = await Promise.all([\n isPluginAiFeatureConfigured('i18n', 'ai-localizations'),\n isPluginAiFeatureConfigured('upload', 'aiMetadata'),\n ]);\n\n return { isAiI18nConfigured, isAiMediaLibraryConfigured };\n };\n\n /**\n * Resolves the shared context required by both getAiToken and getAiUsage:\n * EE license, project ID, and AI server URL.\n */\n const resolveAiContext = (errorPrefix: string) => {\n if (!isStrapiManagedAiEnabled()) {\n strapi.log.error(`${errorPrefix} AI is not enabled`);\n throw new Error(`${errorPrefix.replace(/:$/, '')}. Check server logs for details.`);\n }\n\n if (!strapi.ee?.isEE) {\n strapi.log.error(`${errorPrefix} Enterprise Edition features are not enabled`);\n throw new Error(`${errorPrefix.replace(/:$/, '')}. Check server logs for details.`);\n }\n\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 {\n // License file doesn't exist or can't be read\n }\n }\n\n if (!eeLicense) {\n strapi.log.error(\n `${errorPrefix} No EE license found. Please ensure STRAPI_LICENSE environment variable is set or license.txt file exists.`\n );\n throw new Error(`${errorPrefix.replace(/:$/, '')}. Check server logs for details.`);\n }\n\n const projectId = strapi.config.get('uuid');\n if (!projectId) {\n strapi.log.error(`${errorPrefix} Project ID not configured`);\n throw new Error(`${errorPrefix.replace(/:$/, '')}. Check server logs for details.`);\n }\n\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n return { eeLicense, projectId, aiServerUrl };\n };\n\n const getAiToken = async () => {\n const ERROR_PREFIX = 'AI token request failed:';\n\n const { eeLicense, projectId, aiServerUrl } = resolveAiContext(ERROR_PREFIX);\n\n // Get the current user\n const user = strapi.requestContext.get()?.state?.user as AdminUser | undefined;\n if (!user) {\n strapi.log.error(`${ERROR_PREFIX} No authenticated user in request context`);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n // Create a secure user identifier using only user ID\n const userIdentifier = user.id.toString();\n\n // Check cache for existing valid token\n const cacheKey = `${projectId}:${userIdentifier}`;\n const cachedToken = aiTokenCache.get(cacheKey);\n\n if (cachedToken) {\n const now = Date.now();\n // Check if token is still valid (with buffer so it has time to be used)\n const bufferMs = 2 * 60 * 1000; // 2 minutes\n\n if (cachedToken.expiresAtMs && cachedToken.expiresAtMs - bufferMs > now) {\n strapi.log.info('Using cached AI token');\n\n return {\n token: cachedToken.token,\n expiresAt: cachedToken.expiresAt,\n };\n }\n\n // Token expired or will expire soon, remove from cache\n aiTokenCache.delete(cacheKey);\n }\n\n strapi.log.http('Contacting AI Server for token generation');\n\n try {\n const response = await fetch(`${aiServerUrl}/auth/getAiJWT`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\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 throw new Error('AI token request failed. Check server logs for details.');\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 throw new Error('AI token request failed. Check server logs for details.');\n }\n\n if (!data.jwt) {\n strapi.log.error(`${ERROR_PREFIX} Invalid response: missing JWT token`);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n strapi.log.info('AI token generated successfully', {\n userId: user.id,\n expiresAt: data.expiresAt,\n });\n\n // Cache the token if it has an expiration time\n if (data.expiresAt) {\n const expiresAtMs = new Date(data.expiresAt).getTime();\n aiTokenCache.set(cacheKey, {\n token: data.jwt,\n expiresAt: data.expiresAt,\n expiresAtMs,\n });\n }\n\n // Note: Token expires in 1 hour, client should handle refresh\n return {\n token: data.jwt,\n expiresAt: data.expiresAt,\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 throw new Error('AI token request failed. Check server logs for details.');\n }\n\n throw fetchError;\n }\n };\n\n const getAiUsage = async () => {\n const ERROR_PREFIX = 'AI usage data request failed:';\n\n const { eeLicense, projectId, aiServerUrl } = resolveAiContext(ERROR_PREFIX);\n\n strapi.log.http('Contacting AI Server for usage data');\n\n try {\n const response = await fetch(`${aiServerUrl}/cms/ai-data`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\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 throw new Error('AI usage data request failed. Check server logs for details.');\n }\n\n let data;\n try {\n data = (await response.json()) as {\n data: { cmsAiCreditsUsed: number };\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 throw new Error('AI usage data request failed. Check server logs for details.');\n }\n\n return {\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 throw new Error('AI usage data request failed. Check server logs for details.');\n }\n\n throw fetchError;\n }\n };\n\n return {\n /* Requires `ai.enabled=true` + license + no failed AI provider registration */\n isAvailable,\n /* `true` only when the license has the `cms-ai` entitlement to globally enable AI features.\n TODO: once all AI features are migrated to the providers architecture, consider removing this flag */\n isStrapiManagedAiEnabled,\n authorizeCustomProvider,\n /* Returns the status of each AI feature, flagging which are enabled. */\n getAiFeatureConfig,\n getAiToken,\n getAiUsage,\n };\n};\n\nexport { createAiAdminService };\n"],"names":["STRAPI_MANAGED_AI_LICENSE_FEATURE","CUSTOM_AI_PROVIDER_LICENSE_FEATURE","createAiAdminService","strapi","aiTokenCache","Map","isCustomProviderRejected","isConfigEnabled","config","get","isAvailable","ee","isEE","isStrapiManagedAiEnabled","features","isEnabled","authorizeCustomProvider","log","info","warn","isPluginAiFeatureConfigured","plugin","service","aiService","getAiFeatureConfig","isAiI18nConfigured","isAiMediaLibraryConfigured","Promise","all","resolveAiContext","errorPrefix","error","Error","replace","eeLicense","process","env","STRAPI_LICENSE","licensePath","path","join","dirs","app","root","fs","readFileSync","toString","projectId","aiServerUrl","STRAPI_AI_URL","getAiToken","ERROR_PREFIX","user","requestContext","state","userIdentifier","id","cacheKey","cachedToken","now","Date","bufferMs","expiresAtMs","token","expiresAt","delete","http","response","fetch","method","headers","crypto","randomUUID","body","JSON","stringify","ok","errorData","errorText","text","parse","status","statusText","data","json","parseError","jwt","userId","getTime","set","fetchError","name","getAiUsage","eeKey","subscription"],"mappings":"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"}
|