@localazy/strapi-plugin 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +30 -0
  2. package/dist/_chunks/{FetchIdentity-Cor4ooZv.mjs → FetchIdentity-Bm7bc5bS.mjs} +36 -44
  3. package/dist/_chunks/{FetchIdentity-BpFOT163.js → FetchIdentity-CcEjakiz.js} +24 -32
  4. package/dist/_chunks/{LanguagesSelector-BbrMKwQY.mjs → LanguagesSelector-B1rwN7-Y.mjs} +4 -3
  5. package/dist/_chunks/{LanguagesSelector-CC1ecWnc.js → LanguagesSelector-DejYCwBl.js} +3 -2
  6. package/dist/_chunks/{LocalazyApp-DpFR8p10.mjs → LocalazyApp-C4kbsnQh.mjs} +70 -34
  7. package/dist/_chunks/{LocalazyApp-D0JGRQeF.js → LocalazyApp-jPO7Yr1S.js} +75 -39
  8. package/dist/_chunks/{LocalazyContentTransferSetup-Dael1Q4w.mjs → LocalazyContentTransferSetup-C1wDD9hA.mjs} +58 -22
  9. package/dist/_chunks/{LocalazyContentTransferSetup-Cr7D-BUi.js → LocalazyContentTransferSetup-DZh4ZdSi.js} +62 -26
  10. package/dist/_chunks/{LocalazyGlobalSettings-D3nG4zl7.js → LocalazyGlobalSettings-D76it6rn.js} +56 -25
  11. package/dist/_chunks/{LocalazyGlobalSettings-DzBI5M-K.mjs → LocalazyGlobalSettings-DOW5rjLn.mjs} +56 -25
  12. package/dist/_chunks/{LocalazyPanel-W6j8N1WC.mjs → LocalazyPanel-C_Z4W49T.mjs} +12 -6
  13. package/dist/_chunks/{LocalazyPanel-KQPLxTDz.js → LocalazyPanel-D2LQpqii.js} +14 -8
  14. package/dist/_chunks/{LocalazyStatusColumn-CrhsCjgp.mjs → LocalazyStatusColumn-C_ZCd_s7.mjs} +10 -4
  15. package/dist/_chunks/{LocalazyStatusColumn-B7Q_U2Lu.js → LocalazyStatusColumn-Dy6N4_X6.js} +10 -4
  16. package/dist/_chunks/{RequireLocalazyAuth-D3GeZPDh.js → RequireLocalazyAuth-BVwF0bRC.js} +30 -3
  17. package/dist/_chunks/{RequireLocalazyAuth-BwoGRfJq.mjs → RequireLocalazyAuth-DNhTZZ_6.mjs} +32 -5
  18. package/dist/_chunks/{entry-exclusion-service-D7gaRHPE.mjs → entry-exclusion-service-CF_yNCly.mjs} +1 -1
  19. package/dist/_chunks/{entry-exclusion-service-Bwruvyce.js → entry-exclusion-service-CH3ZoJQN.js} +1 -1
  20. package/dist/_chunks/{has-model-changed-Dp2Vkwjw.mjs → has-model-changed-CVJEuGxM.mjs} +2 -2
  21. package/dist/_chunks/{has-model-changed-5IV9WI_-.js → has-model-changed-DdYbyv0v.js} +2 -2
  22. package/dist/_chunks/{i18n-o24yXf-j.mjs → i18n-76ox2llT.mjs} +4 -1
  23. package/dist/_chunks/{i18n-C_5tJvr0.js → i18n-C5ucROBh.js} +4 -1
  24. package/dist/_chunks/{index-jAg6jjCu.js → index-CEGaWWh3.js} +33 -11
  25. package/dist/_chunks/{index-C9hN3KbD.mjs → index-DP2ugzc_.mjs} +34 -12
  26. package/dist/_chunks/{index-BjL9XpRh.mjs → index-shryj0jT.mjs} +16 -16
  27. package/dist/_chunks/{strapi-api-base-IG3Pe5Sg.js → strapi-api-base-CCUuu7EY.js} +1 -1
  28. package/dist/_chunks/{strapi-api-base-CAzGcwF6.mjs → strapi-api-base-IiMEtDoH.mjs} +1 -1
  29. package/dist/admin/index.js +1 -1
  30. package/dist/admin/index.mjs +1 -1
  31. package/dist/admin/src/components/LocalazyStatusColumn.d.ts +1 -1
  32. package/dist/admin/src/constants/permissions.d.ts +29 -0
  33. package/dist/admin/src/modules/@common/components/LanguagesSelector.d.ts +1 -0
  34. package/dist/admin/src/modules/login/locale/en.d.ts +1 -0
  35. package/dist/admin/src/modules/plugin-settings/components/Tree.d.ts +1 -0
  36. package/dist/admin/src/modules/plugin-settings/components/TreeItem.d.ts +1 -0
  37. package/dist/admin/src/modules/plugin-settings/components/WebhookSetup.d.ts +4 -1
  38. package/dist/admin/src/modules/plugin-settings/locale/en.d.ts +2 -0
  39. package/dist/admin/src/modules/plugin-settings/services/plugin-settings-service.d.ts +4 -0
  40. package/dist/server/index.js +157 -36
  41. package/dist/server/index.mjs +157 -36
  42. package/dist/server/src/bootstrap.d.ts +1 -1
  43. package/dist/server/src/constants/permissions.d.ts +38 -0
  44. package/dist/server/src/controllers/index.d.ts +1 -0
  45. package/dist/server/src/controllers/plugin-settings-controller.d.ts +1 -0
  46. package/dist/server/src/core/index.d.ts +3 -1
  47. package/dist/server/src/index.d.ts +57 -8
  48. package/dist/server/src/routes/activity-logs-routes.d.ts +20 -3
  49. package/dist/server/src/routes/debug-bundle-routes.d.ts +6 -1
  50. package/dist/server/src/routes/entry-exclusion-routes.d.ts +20 -3
  51. package/dist/server/src/routes/index.d.ts +52 -6
  52. package/dist/server/src/routes/localazy-auth-routes.d.ts +6 -1
  53. package/dist/server/src/routes/localazy-project-routes.d.ts +20 -3
  54. package/dist/server/src/routes/localazy-transfer-routes.d.ts +6 -1
  55. package/dist/server/src/routes/localazy-user-routes.d.ts +20 -3
  56. package/dist/server/src/routes/plugin-settings-routes.d.ts +20 -3
  57. package/dist/server/src/routes/strapi-routes.d.ts +20 -3
  58. package/dist/server/src/services/index.d.ts +3 -1
  59. package/dist/server/src/services/localazy-transfer-download-service.d.ts +2 -1
  60. package/dist/server/src/services/plugin-settings-service.d.ts +4 -0
  61. package/package.json +1 -1
@@ -20520,7 +20520,7 @@ var distExports = dist$1.exports;
20520
20520
  const io = /* @__PURE__ */ getDefaultExportFromCjs(distExports);
20521
20521
  const { Server: Server2, Namespace, Socket: Socket3 } = io;
20522
20522
  const name = "@localazy/strapi-plugin";
20523
- const version = "1.4.0";
20523
+ const version = "1.6.0";
20524
20524
  const description = "The official Strapi Plugin by Localazy.";
20525
20525
  const keywords = [
20526
20526
  "strapi",
@@ -20704,7 +20704,60 @@ const _package$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
20704
20704
  version
20705
20705
  }, Symbol.toStringTag, { value: "Module" }));
20706
20706
  const PLUGIN_NAME = strapi$1.name;
20707
- const bootstrap = ({ strapi: strapi2 }) => {
20707
+ const PERMISSION_UIDS = {
20708
+ READ: `plugin::${PLUGIN_NAME}.read`,
20709
+ TRANSFER: `plugin::${PLUGIN_NAME}.transfer`,
20710
+ SETTINGS_UPDATE: `plugin::${PLUGIN_NAME}.settings.update`
20711
+ };
20712
+ const LOCALAZY_RBAC_ACTIONS = [
20713
+ {
20714
+ section: "plugins",
20715
+ subCategory: "General",
20716
+ pluginName: PLUGIN_NAME,
20717
+ displayName: "Read",
20718
+ uid: "read"
20719
+ },
20720
+ {
20721
+ section: "plugins",
20722
+ subCategory: "General",
20723
+ pluginName: PLUGIN_NAME,
20724
+ displayName: "Transfer",
20725
+ uid: "transfer"
20726
+ },
20727
+ {
20728
+ section: "plugins",
20729
+ subCategory: "Settings",
20730
+ pluginName: PLUGIN_NAME,
20731
+ displayName: "Read settings",
20732
+ uid: "settings.read"
20733
+ },
20734
+ {
20735
+ section: "plugins",
20736
+ subCategory: "Settings",
20737
+ pluginName: PLUGIN_NAME,
20738
+ displayName: "Update settings",
20739
+ uid: "settings.update"
20740
+ }
20741
+ ];
20742
+ const registerRbacActions = async (strapi2) => {
20743
+ try {
20744
+ const permissionService = strapi2.service("admin::permission");
20745
+ const actionProvider = permissionService?.actionProvider;
20746
+ if (!actionProvider?.registerMany) {
20747
+ strapi2.log.warn(
20748
+ `[${PLUGIN_NAME}] admin::permission.actionProvider unavailable — skipping RBAC action registration`
20749
+ );
20750
+ return;
20751
+ }
20752
+ await actionProvider.registerMany(LOCALAZY_RBAC_ACTIONS);
20753
+ } catch (error) {
20754
+ strapi2.log.error(
20755
+ `[${PLUGIN_NAME}] Failed to register RBAC actions — plugin permissions will not appear in role editor: ${error instanceof Error ? error.message : String(error)}`
20756
+ );
20757
+ }
20758
+ };
20759
+ const bootstrap = async ({ strapi: strapi2 }) => {
20760
+ await registerRbacActions(strapi2);
20708
20761
  if (strapi2.plugin(PLUGIN_NAME)?.config("enableSocketIO", true)) {
20709
20762
  process.nextTick(async () => {
20710
20763
  const io2 = new Server2(strapi2.server.httpServer, {
@@ -24287,6 +24340,9 @@ const PluginSettingsController = ({ strapi: _strapi }) => ({
24287
24340
  async updatePluginSettings(ctx) {
24288
24341
  ctx.body = await getPluginSettingsService().updatePluginSettings(ctx.request.body);
24289
24342
  },
24343
+ async updatePluginSettingsUiPrefs(ctx) {
24344
+ ctx.body = await getPluginSettingsService().updatePluginSettingsUiPrefs(ctx.request.body);
24345
+ },
24290
24346
  async getSyncCursor(ctx) {
24291
24347
  ctx.body = await getPluginSettingsService().getSyncCursor();
24292
24348
  }
@@ -24386,6 +24442,8 @@ const LocalazyTransferController = ({ strapi: strapi2 }) => ({
24386
24442
  try {
24387
24443
  const LocalazyTransferDownloadService2 = getLocalazyTransferDownloadService();
24388
24444
  let fullSync = ctx.request.body?.fullSync === true;
24445
+ const rawUiLanguages = ctx.request.body?.uiLanguages;
24446
+ const requestedUiLanguages = Array.isArray(rawUiLanguages) && rawUiLanguages.every((code) => typeof code === "string") ? rawUiLanguages : void 0;
24389
24447
  const requestInitiatorHelper = new RequestInitiatorHelper(strapi2);
24390
24448
  if (requestInitiatorHelper.isInitiatedByLocalazyWebhook()) {
24391
24449
  const pluginSettingsServiceHelper = new PluginSettingsServiceHelper();
@@ -24395,7 +24453,8 @@ const LocalazyTransferController = ({ strapi: strapi2 }) => ({
24395
24453
  setTimeout(
24396
24454
  () => LocalazyTransferDownloadService2.download({
24397
24455
  notificationService: JobNotificationService$1,
24398
- fullSync
24456
+ fullSync,
24457
+ requestedUiLanguages
24399
24458
  }),
24400
24459
  1e3
24401
24460
  );
@@ -24964,13 +25023,17 @@ const middlewares = {
24964
25023
  };
24965
25024
  const policies = {};
24966
25025
  const ROUTE_PREFIX$8 = "/user";
25026
+ const readPolicy$6 = [{ name: "admin::hasPermissions", config: { actions: [PERMISSION_UIDS.READ] } }];
25027
+ const settingsUpdatePolicy$4 = [
25028
+ { name: "admin::hasPermissions", config: { actions: [PERMISSION_UIDS.SETTINGS_UPDATE] } }
25029
+ ];
24967
25030
  const LocalazyUserRoutes = [
24968
25031
  {
24969
25032
  method: "GET",
24970
25033
  path: `${ROUTE_PREFIX$8}`,
24971
25034
  handler: "LocalazyUserController.getUser",
24972
25035
  config: {
24973
- policies: []
25036
+ policies: readPolicy$6
24974
25037
  }
24975
25038
  },
24976
25039
  {
@@ -24978,7 +25041,7 @@ const LocalazyUserRoutes = [
24978
25041
  path: `${ROUTE_PREFIX$8}`,
24979
25042
  handler: "LocalazyUserController.updateUser",
24980
25043
  config: {
24981
- policies: []
25044
+ policies: settingsUpdatePolicy$4
24982
25045
  }
24983
25046
  },
24984
25047
  {
@@ -24986,18 +25049,21 @@ const LocalazyUserRoutes = [
24986
25049
  path: `${ROUTE_PREFIX$8}`,
24987
25050
  handler: "LocalazyUserController.deleteUser",
24988
25051
  config: {
24989
- policies: []
25052
+ policies: settingsUpdatePolicy$4
24990
25053
  }
24991
25054
  }
24992
25055
  ];
24993
25056
  const ROUTE_PREFIX$7 = "/auth";
25057
+ const settingsUpdatePolicy$3 = [
25058
+ { name: "admin::hasPermissions", config: { actions: [PERMISSION_UIDS.SETTINGS_UPDATE] } }
25059
+ ];
24994
25060
  const LocalazyAuthRoutes = [
24995
25061
  {
24996
25062
  method: "GET",
24997
25063
  path: `${ROUTE_PREFIX$7}/generate-keys`,
24998
25064
  handler: "LocalazyAuthController.generateKeys",
24999
25065
  config: {
25000
- policies: []
25066
+ policies: settingsUpdatePolicy$3
25001
25067
  }
25002
25068
  },
25003
25069
  {
@@ -25005,18 +25071,26 @@ const LocalazyAuthRoutes = [
25005
25071
  path: `${ROUTE_PREFIX$7}/continuous-poll`,
25006
25072
  handler: "LocalazyAuthController.continuousPoll",
25007
25073
  config: {
25008
- policies: []
25074
+ policies: settingsUpdatePolicy$3
25009
25075
  }
25010
25076
  }
25011
25077
  ];
25012
25078
  const ROUTE_PREFIX$6 = "/plugin-settings";
25079
+ const readPolicy$5 = [{ name: "admin::hasPermissions", config: { actions: [PERMISSION_UIDS.READ] } }];
25080
+ const settingsUpdatePolicy$2 = [
25081
+ { name: "admin::hasPermissions", config: { actions: [PERMISSION_UIDS.SETTINGS_UPDATE] } }
25082
+ ];
25013
25083
  const PluginSettingsRoutes = [
25014
25084
  {
25015
25085
  method: "GET",
25016
25086
  path: `${ROUTE_PREFIX$6}/content-transfer-setup`,
25017
25087
  handler: "PluginSettingsController.getContentTransferSetup",
25018
25088
  config: {
25019
- policies: []
25089
+ // Upload/Download pages call this to detect "model changed" before
25090
+ // transferring. Gating on `settings.read` would lock transfer-only
25091
+ // roles out of the transfer pages, so the read is open to any plugin
25092
+ // user. The destructive PUT below stays on `settings.update`.
25093
+ policies: readPolicy$5
25020
25094
  }
25021
25095
  },
25022
25096
  {
@@ -25024,7 +25098,7 @@ const PluginSettingsRoutes = [
25024
25098
  path: `${ROUTE_PREFIX$6}/content-transfer-setup`,
25025
25099
  handler: "PluginSettingsController.updateContentTransferSetup",
25026
25100
  config: {
25027
- policies: []
25101
+ policies: settingsUpdatePolicy$2
25028
25102
  }
25029
25103
  },
25030
25104
  {
@@ -25032,7 +25106,7 @@ const PluginSettingsRoutes = [
25032
25106
  path: `${ROUTE_PREFIX$6}/plugin-settings`,
25033
25107
  handler: "PluginSettingsController.getPluginSettings",
25034
25108
  config: {
25035
- policies: []
25109
+ policies: readPolicy$5
25036
25110
  }
25037
25111
  },
25038
25112
  {
@@ -25040,7 +25114,20 @@ const PluginSettingsRoutes = [
25040
25114
  path: `${ROUTE_PREFIX$6}/plugin-settings`,
25041
25115
  handler: "PluginSettingsController.updatePluginSettings",
25042
25116
  config: {
25043
- policies: []
25117
+ // Persists destructive Global Settings (webhookConfig, download.*, upload.*).
25118
+ // UI-pref-only writes use `PUT /plugin-settings/ui-prefs` (read-gated) below.
25119
+ policies: settingsUpdatePolicy$2
25120
+ }
25121
+ },
25122
+ {
25123
+ method: "PUT",
25124
+ path: `${ROUTE_PREFIX$6}/ui-prefs`,
25125
+ handler: "PluginSettingsController.updatePluginSettingsUiPrefs",
25126
+ config: {
25127
+ // Per-user UI state (last visited route, sort prefs). Service-side filters
25128
+ // the body to a fixed allowlist so a `read`-only caller cannot reach the
25129
+ // destructive fields that share the same plugin-settings store.
25130
+ policies: readPolicy$5
25044
25131
  }
25045
25132
  },
25046
25133
  {
@@ -25048,18 +25135,22 @@ const PluginSettingsRoutes = [
25048
25135
  path: `${ROUTE_PREFIX$6}/sync-cursor`,
25049
25136
  handler: "PluginSettingsController.getSyncCursor",
25050
25137
  config: {
25051
- policies: []
25138
+ policies: readPolicy$5
25052
25139
  }
25053
25140
  }
25054
25141
  ];
25055
25142
  const ROUTE_PREFIX$5 = "/strapi";
25143
+ const readPolicy$4 = [{ name: "admin::hasPermissions", config: { actions: [PERMISSION_UIDS.READ] } }];
25144
+ const settingsUpdatePolicy$1 = [
25145
+ { name: "admin::hasPermissions", config: { actions: [PERMISSION_UIDS.SETTINGS_UPDATE] } }
25146
+ ];
25056
25147
  const StrapiRoutes = [
25057
25148
  {
25058
25149
  method: "GET",
25059
25150
  path: `${ROUTE_PREFIX$5}/models`,
25060
25151
  handler: "StrapiController.getModels",
25061
25152
  config: {
25062
- policies: []
25153
+ policies: readPolicy$4
25063
25154
  }
25064
25155
  },
25065
25156
  {
@@ -25067,7 +25158,7 @@ const StrapiRoutes = [
25067
25158
  path: `${ROUTE_PREFIX$5}/localizable-models`,
25068
25159
  handler: "StrapiController.getLocalizableModels",
25069
25160
  config: {
25070
- policies: []
25161
+ policies: readPolicy$4
25071
25162
  }
25072
25163
  },
25073
25164
  {
@@ -25075,7 +25166,7 @@ const StrapiRoutes = [
25075
25166
  path: `${ROUTE_PREFIX$5}/lifecycle/localazy-webhooks`,
25076
25167
  handler: "StrapiController.postLifecycleLocalazyWebhooks",
25077
25168
  config: {
25078
- policies: []
25169
+ policies: settingsUpdatePolicy$1
25079
25170
  }
25080
25171
  },
25081
25172
  {
@@ -25083,18 +25174,19 @@ const StrapiRoutes = [
25083
25174
  path: `${ROUTE_PREFIX$5}/version`,
25084
25175
  handler: "StrapiController.getPluginVersion",
25085
25176
  config: {
25086
- policies: []
25177
+ policies: readPolicy$4
25087
25178
  }
25088
25179
  }
25089
25180
  ];
25090
25181
  const ROUTE_PREFIX$4 = "/transfer";
25182
+ const transferPolicy$2 = [{ name: "admin::hasPermissions", config: { actions: [PERMISSION_UIDS.TRANSFER] } }];
25091
25183
  const LocalazyTransferRoutes = [
25092
25184
  {
25093
25185
  method: "POST",
25094
25186
  path: `${ROUTE_PREFIX$4}/upload`,
25095
25187
  handler: "LocalazyTransferController.upload",
25096
25188
  config: {
25097
- policies: []
25189
+ policies: transferPolicy$2
25098
25190
  }
25099
25191
  },
25100
25192
  {
@@ -25102,18 +25194,22 @@ const LocalazyTransferRoutes = [
25102
25194
  path: `${ROUTE_PREFIX$4}/download`,
25103
25195
  handler: "LocalazyTransferController.download",
25104
25196
  config: {
25105
- policies: []
25197
+ policies: transferPolicy$2
25106
25198
  }
25107
25199
  }
25108
25200
  ];
25109
25201
  const ROUTE_PREFIX$3 = "/project";
25202
+ const readPolicy$3 = [{ name: "admin::hasPermissions", config: { actions: [PERMISSION_UIDS.READ] } }];
25203
+ const settingsUpdatePolicy = [
25204
+ { name: "admin::hasPermissions", config: { actions: [PERMISSION_UIDS.SETTINGS_UPDATE] } }
25205
+ ];
25110
25206
  const LocalazyProjectRoutes = [
25111
25207
  {
25112
25208
  method: "GET",
25113
25209
  path: `${ROUTE_PREFIX$3}`,
25114
25210
  handler: "LocalazyProjectController.getConnectedProject",
25115
25211
  config: {
25116
- policies: []
25212
+ policies: readPolicy$3
25117
25213
  }
25118
25214
  },
25119
25215
  {
@@ -25121,7 +25217,7 @@ const LocalazyProjectRoutes = [
25121
25217
  path: `${ROUTE_PREFIX$3}/webhooks`,
25122
25218
  handler: "LocalazyProjectController.getWebhookStatus",
25123
25219
  config: {
25124
- policies: []
25220
+ policies: readPolicy$3
25125
25221
  }
25126
25222
  },
25127
25223
  {
@@ -25129,7 +25225,7 @@ const LocalazyProjectRoutes = [
25129
25225
  path: `${ROUTE_PREFIX$3}/webhooks/setup`,
25130
25226
  handler: "LocalazyProjectController.setupWebhook",
25131
25227
  config: {
25132
- policies: []
25228
+ policies: settingsUpdatePolicy
25133
25229
  }
25134
25230
  },
25135
25231
  {
@@ -25137,7 +25233,7 @@ const LocalazyProjectRoutes = [
25137
25233
  path: `${ROUTE_PREFIX$3}/strapi-url`,
25138
25234
  handler: "LocalazyProjectController.getStrapiUrl",
25139
25235
  config: {
25140
- policies: []
25236
+ policies: readPolicy$3
25141
25237
  }
25142
25238
  }
25143
25239
  ];
@@ -25156,13 +25252,15 @@ const LocalazyPublicTransferRoutes = [
25156
25252
  }
25157
25253
  ];
25158
25254
  const ROUTE_PREFIX$1 = "/entry-exclusion";
25255
+ const readPolicy$2 = [{ name: "admin::hasPermissions", config: { actions: [PERMISSION_UIDS.READ] } }];
25256
+ const transferPolicy$1 = [{ name: "admin::hasPermissions", config: { actions: [PERMISSION_UIDS.TRANSFER] } }];
25159
25257
  const EntryExclusionRoutes = [
25160
25258
  {
25161
25259
  method: "GET",
25162
25260
  path: `${ROUTE_PREFIX$1}/:contentType/:documentId`,
25163
25261
  handler: "EntryExclusionController.getEntryExclusion",
25164
25262
  config: {
25165
- policies: []
25263
+ policies: readPolicy$2
25166
25264
  }
25167
25265
  },
25168
25266
  {
@@ -25170,7 +25268,7 @@ const EntryExclusionRoutes = [
25170
25268
  path: `${ROUTE_PREFIX$1}/:contentType/:documentId`,
25171
25269
  handler: "EntryExclusionController.setEntryExclusion",
25172
25270
  config: {
25173
- policies: []
25271
+ policies: transferPolicy$1
25174
25272
  }
25175
25273
  },
25176
25274
  {
@@ -25178,18 +25276,20 @@ const EntryExclusionRoutes = [
25178
25276
  path: `${ROUTE_PREFIX$1}/:contentType`,
25179
25277
  handler: "EntryExclusionController.getContentTypeExclusions",
25180
25278
  config: {
25181
- policies: []
25279
+ policies: readPolicy$2
25182
25280
  }
25183
25281
  }
25184
25282
  ];
25185
25283
  const ROUTE_PREFIX = "/activity-logs";
25284
+ const readPolicy$1 = [{ name: "admin::hasPermissions", config: { actions: [PERMISSION_UIDS.READ] } }];
25285
+ const transferPolicy = [{ name: "admin::hasPermissions", config: { actions: [PERMISSION_UIDS.TRANSFER] } }];
25186
25286
  const ActivityLogsRoutes = [
25187
25287
  {
25188
25288
  method: "GET",
25189
25289
  path: `${ROUTE_PREFIX}`,
25190
25290
  handler: "ActivityLogsController.getSessions",
25191
25291
  config: {
25192
- policies: []
25292
+ policies: readPolicy$1
25193
25293
  }
25194
25294
  },
25195
25295
  {
@@ -25197,7 +25297,7 @@ const ActivityLogsRoutes = [
25197
25297
  path: `${ROUTE_PREFIX}/export`,
25198
25298
  handler: "ActivityLogsController.exportSessions",
25199
25299
  config: {
25200
- policies: []
25300
+ policies: readPolicy$1
25201
25301
  }
25202
25302
  },
25203
25303
  {
@@ -25205,7 +25305,7 @@ const ActivityLogsRoutes = [
25205
25305
  path: `${ROUTE_PREFIX}/:sessionId`,
25206
25306
  handler: "ActivityLogsController.getSession",
25207
25307
  config: {
25208
- policies: []
25308
+ policies: readPolicy$1
25209
25309
  }
25210
25310
  },
25211
25311
  {
@@ -25213,23 +25313,28 @@ const ActivityLogsRoutes = [
25213
25313
  path: `${ROUTE_PREFIX}`,
25214
25314
  handler: "ActivityLogsController.clearSessions",
25215
25315
  config: {
25216
- policies: []
25316
+ policies: transferPolicy
25217
25317
  }
25218
25318
  }
25219
25319
  ];
25320
+ const readPolicy = [{ name: "admin::hasPermissions", config: { actions: [PERMISSION_UIDS.READ] } }];
25220
25321
  const DebugBundleRoutes = [
25221
25322
  {
25222
25323
  method: "GET",
25223
25324
  path: "/activity-logs/:sessionId/bundle",
25224
25325
  handler: "DebugBundleController.getBundle",
25225
25326
  config: {
25226
- policies: []
25327
+ policies: readPolicy
25227
25328
  }
25228
25329
  }
25229
25330
  ];
25331
+ const withoutAdminPolicies = (routes2) => routes2.map((route) => ({
25332
+ ...route,
25333
+ config: { ...route.config, policies: [] }
25334
+ }));
25230
25335
  const routes = {
25231
25336
  "content-api": {
25232
- routes: [...StrapiRoutes]
25337
+ routes: withoutAdminPolicies(StrapiRoutes)
25233
25338
  },
25234
25339
  admin: {
25235
25340
  type: "admin",
@@ -25441,6 +25546,7 @@ const KEY$1 = "sync-cursor";
25441
25546
  const emptySyncCursor = {
25442
25547
  processedKeys: {}
25443
25548
  };
25549
+ const UI_PREF_FIELDS = ["defaultRoute", "activityLogsSort"];
25444
25550
  const PluginSettingsService = ({ strapi: strapi2 }) => ({
25445
25551
  async getContentTransferSetup() {
25446
25552
  const pluginStore = getStrapiStore(strapi2);
@@ -25477,6 +25583,20 @@ const PluginSettingsService = ({ strapi: strapi2 }) => ({
25477
25583
  });
25478
25584
  return newSettings;
25479
25585
  },
25586
+ // Counterpart to `updatePluginSettings` for the `read`-gated UI-prefs route.
25587
+ // Drops any field outside `UI_PREF_FIELDS` server-side so a `read`-only caller
25588
+ // cannot reach `webhookConfig` / `download.*` / `upload.*` via the merge.
25589
+ async updatePluginSettingsUiPrefs(prefs) {
25590
+ const sanitized = {};
25591
+ if (prefs && typeof prefs === "object") {
25592
+ for (const field of UI_PREF_FIELDS) {
25593
+ if (field in prefs) {
25594
+ sanitized[field] = prefs[field];
25595
+ }
25596
+ }
25597
+ }
25598
+ return this.updatePluginSettings(sanitized);
25599
+ },
25480
25600
  async getSyncCursor() {
25481
25601
  const pluginStore = getStrapiStore(strapi2);
25482
25602
  const cursor = await pluginStore.get({ key: KEY$1 });
@@ -26053,7 +26173,7 @@ const shouldSetDownloadedProperty = (modelContentTransferSetup, parsedKeyRest) =
26053
26173
  return "no";
26054
26174
  }
26055
26175
  };
26056
- const getFilteredLanguagesCodesForDownload = async (languagesCodes) => {
26176
+ const getFilteredLanguagesCodesForDownload = async (languagesCodes, requestedUiLanguages) => {
26057
26177
  const pluginSettingsServiceHelper = new PluginSettingsServiceHelper();
26058
26178
  const requestInitiatorHelper = new RequestInitiatorHelper(strapi);
26059
26179
  await pluginSettingsServiceHelper.setup();
@@ -26061,7 +26181,7 @@ const getFilteredLanguagesCodesForDownload = async (languagesCodes) => {
26061
26181
  if (requestInitiatorHelper.isInitiatedByLocalazyWebhook()) {
26062
26182
  localLanguagesCodes = pluginSettingsServiceHelper.getWebhookLanguagesCodes();
26063
26183
  } else if (requestInitiatorHelper.isInitiatedByLocalazyPluginUI()) {
26064
- localLanguagesCodes = pluginSettingsServiceHelper.getUiLanguagesCodes();
26184
+ localLanguagesCodes = requestedUiLanguages ?? pluginSettingsServiceHelper.getUiLanguagesCodes();
26065
26185
  } else {
26066
26186
  strapi.log.warn("Called by an unknown initiator.");
26067
26187
  return languagesCodes;
@@ -26074,7 +26194,8 @@ const getFilteredLanguagesCodesForDownload = async (languagesCodes) => {
26074
26194
  const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
26075
26195
  async download({
26076
26196
  notificationService,
26077
- fullSync = false
26197
+ fullSync = false,
26198
+ requestedUiLanguages
26078
26199
  }) {
26079
26200
  console.time("download");
26080
26201
  const syncMode = fullSync ? "Full sync" : "Incremental sync";
@@ -26154,7 +26275,7 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
26154
26275
  return;
26155
26276
  }
26156
26277
  let languagesCodes = projectLanguagesWithoutSourceLanguage.map((language3) => language3.code);
26157
- languagesCodes = await getFilteredLanguagesCodesForDownload(languagesCodes);
26278
+ languagesCodes = await getFilteredLanguagesCodesForDownload(languagesCodes, requestedUiLanguages);
26158
26279
  const strapiUnsupportedLanguages = [];
26159
26280
  const strapiLocales = await StrapiI18nService2.getLocales();
26160
26281
  for (const isoLocalazy of languagesCodes) {
@@ -1,5 +1,5 @@
1
1
  import type { Core } from '@strapi/strapi';
2
2
  declare const bootstrap: ({ strapi }: {
3
3
  strapi: Core.Strapi;
4
- }) => void;
4
+ }) => Promise<void>;
5
5
  export default bootstrap;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * UIDs as Strapi sees them after `pluginName` is prepended by the action provider.
3
+ * Use these to reference permissions from route policies, admin menu/settings links
4
+ * and `useRBAC` calls. Renaming any UID is a breaking change for existing role grants
5
+ * — bumping a minor version is not enough.
6
+ */
7
+ export declare const PERMISSION_UIDS: {
8
+ readonly READ: `plugin::${string}.read`;
9
+ readonly TRANSFER: `plugin::${string}.transfer`;
10
+ readonly SETTINGS_READ: `plugin::${string}.settings.read`;
11
+ readonly SETTINGS_UPDATE: `plugin::${string}.settings.update`;
12
+ };
13
+ export type PermissionUid = (typeof PERMISSION_UIDS)[keyof typeof PERMISSION_UIDS];
14
+ type ActionRecord = {
15
+ section: 'plugins';
16
+ subCategory: string;
17
+ pluginName: string;
18
+ displayName: string;
19
+ uid: string;
20
+ };
21
+ /**
22
+ * Actions registered with `strapi.service('admin::permission').actionProvider.registerMany`
23
+ * during bootstrap. `pluginName` is prepended as `plugin::<pluginName>.` so the resulting
24
+ * UIDs become the ones in `PERMISSION_UIDS` above.
25
+ *
26
+ * All four actions live under `section: 'plugins'` so they appear together in the
27
+ * role editor's Plugins tab under "Localazy", grouped by `subCategory`. A previous
28
+ * split (settings-section for the two settings.* actions) caused them to land in a
29
+ * different tab — admins inspecting Plugins → Localazy only saw Read + Transfer and
30
+ * thought the other two were missing.
31
+ *
32
+ * Strapi's @strapi/admin yup validator (a) rejects `category` on `plugins`-section
33
+ * entries — `category` is only valid in `settings` section — and (b) allows
34
+ * `subCategory` on both `plugins` and `settings`. So we use `subCategory` alone for
35
+ * grouping here.
36
+ */
37
+ export declare const LOCALAZY_RBAC_ACTIONS: ActionRecord[];
38
+ export {};
@@ -35,6 +35,7 @@ declare const _default: {
35
35
  updateContentTransferSetup(ctx: any): Promise<void>;
36
36
  getPluginSettings(ctx: any): Promise<void>;
37
37
  updatePluginSettings(ctx: any): Promise<void>;
38
+ updatePluginSettingsUiPrefs(ctx: any): Promise<void>;
38
39
  getSyncCursor(ctx: any): Promise<void>;
39
40
  };
40
41
  LocalazyTransferController: ({ strapi }: {
@@ -6,6 +6,7 @@ declare const PluginSettingsController: ({ strapi: _strapi }: {
6
6
  updateContentTransferSetup(ctx: any): Promise<void>;
7
7
  getPluginSettings(ctx: any): Promise<void>;
8
8
  updatePluginSettings(ctx: any): Promise<void>;
9
+ updatePluginSettingsUiPrefs(ctx: any): Promise<void>;
9
10
  getSyncCursor(ctx: any): Promise<void>;
10
11
  };
11
12
  export default PluginSettingsController;
@@ -18,9 +18,10 @@ export declare const getLocalazyTransferUploadService: () => {
18
18
  }): Promise<void>;
19
19
  };
20
20
  export declare const getLocalazyTransferDownloadService: () => {
21
- download({ notificationService, fullSync, }: {
21
+ download({ notificationService, fullSync, requestedUiLanguages, }: {
22
22
  notificationService: import("../services/helpers/job-notification-service").default;
23
23
  fullSync?: boolean;
24
+ requestedUiLanguages?: string[];
24
25
  }): Promise<void>;
25
26
  };
26
27
  export declare const getPluginSettingsService: () => {
@@ -31,6 +32,7 @@ export declare const getPluginSettingsService: () => {
31
32
  }>;
32
33
  getPluginSettings(): Promise<import("../db/model/plugin-settings").PluginSettings>;
33
34
  updatePluginSettings(settings: any): Promise<any>;
35
+ updatePluginSettingsUiPrefs(prefs: Partial<Pick<import("../db/model/plugin-settings").PluginSettings, "defaultRoute" | "activityLogsSort">>): Promise<import("../db/model/plugin-settings").PluginSettings>;
34
36
  getSyncCursor(): Promise<import("../db/model/sync-cursor").SyncCursor>;
35
37
  updateSyncCursor(cursor: import("../db/model/sync-cursor").SyncCursor): Promise<import("../db/model/sync-cursor").SyncCursor>;
36
38
  };