@northern.tech/store 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions.cjs +20 -17
- package/dist/actions.cjs.map +1 -1
- package/dist/actions.js +8 -8
- package/dist/api/general-api.js +2 -2
- package/dist/api/types/Tenant.ts +17 -12
- package/dist/api/users-api.js +2 -2
- package/dist/appSlice/constants.cjs +18 -10
- package/dist/appSlice/constants.cjs.map +1 -1
- package/dist/appSlice/constants.d.cts +41 -84
- package/dist/appSlice/constants.d.ts +41 -84
- package/dist/appSlice/constants.js +1 -1
- package/dist/appSlice/index.js +2 -2
- package/dist/appSlice/thunks.cjs +137 -94
- package/dist/appSlice/thunks.cjs.map +1 -1
- package/dist/appSlice/thunks.js +19 -19
- package/dist/auth.js +2 -2
- package/dist/{chunk-Q6M5TTDQ.js → chunk-2CYOM4BK.js} +1 -1
- package/dist/chunk-2CYOM4BK.js.map +1 -0
- package/dist/{chunk-74OJIKXF.js → chunk-2JHFUQ6B.js} +133 -96
- package/dist/chunk-2JHFUQ6B.js.map +1 -0
- package/dist/{chunk-YETZPQFR.js → chunk-4XJMRVFI.js} +12 -11
- package/dist/chunk-4XJMRVFI.js.map +1 -0
- package/dist/{chunk-RX55KAKX.js → chunk-7JKWI5FK.js} +2 -2
- package/dist/{chunk-A6CT6GTI.js → chunk-C5NEDBJI.js} +17 -11
- package/dist/chunk-C5NEDBJI.js.map +1 -0
- package/dist/{chunk-NNADGHSL.js → chunk-DAPAXWA5.js} +8 -8
- package/dist/{chunk-ANB5BM5J.js → chunk-DCK2DBOA.js} +27 -20
- package/dist/chunk-DCK2DBOA.js.map +1 -0
- package/dist/{chunk-E5LEU5PF.js → chunk-HPBE6KYY.js} +2 -2
- package/dist/{chunk-2RJIDREZ.js → chunk-LEMVXAYP.js} +25 -16
- package/dist/chunk-LEMVXAYP.js.map +1 -0
- package/dist/{chunk-NI4SZOCF.js → chunk-LGNOTPUG.js} +9 -9
- package/dist/{chunk-MDC7Y3EX.js → chunk-LTKOV26W.js} +22 -20
- package/dist/chunk-LTKOV26W.js.map +1 -0
- package/dist/{chunk-YTQUNAZP.js → chunk-QRGTG4YB.js} +2 -2
- package/dist/{chunk-XTRPX7JZ.js → chunk-TI2RL5P2.js} +2 -2
- package/dist/chunk-TI2RL5P2.js.map +1 -0
- package/dist/{chunk-YGBFDXXA.js → chunk-TUACATJA.js} +2 -2
- package/dist/{chunk-25AKG5HH.js → chunk-UWMYZNUB.js} +19 -11
- package/dist/chunk-UWMYZNUB.js.map +1 -0
- package/dist/{chunk-UEP36GCI.js → chunk-VMNMD6KF.js} +2 -2
- package/dist/{chunk-KAQJH2YL.js → chunk-WXL7PVI5.js} +12 -4
- package/dist/chunk-WXL7PVI5.js.map +1 -0
- package/dist/{chunk-VOCOFE4I.js → chunk-X7IEZBM4.js} +2 -2
- package/dist/{chunk-XXHONFSQ.js → chunk-YDS36ALB.js} +3 -3
- package/dist/{chunk-XXHONFSQ.js.map → chunk-YDS36ALB.js.map} +1 -1
- package/dist/commonSelectors.cjs +40 -18
- package/dist/commonSelectors.cjs.map +1 -1
- package/dist/commonSelectors.d.cts +54 -46
- package/dist/commonSelectors.d.ts +54 -46
- package/dist/commonSelectors.js +9 -9
- package/dist/constants.cjs +35 -19
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +3 -3
- package/dist/constants.d.ts +3 -3
- package/dist/constants.js +6 -2
- package/dist/deploymentdevicehook.cjs +143 -99
- package/dist/deploymentdevicehook.cjs.map +1 -1
- package/dist/deploymentdevicehook.d.cts +1 -1
- package/dist/deploymentdevicehook.d.ts +1 -1
- package/dist/deploymentdevicehook.js +24 -22
- package/dist/deploymentdevicehook.js.map +1 -1
- package/dist/deploymentsSlice/constants.cjs +8 -8
- package/dist/deploymentsSlice/constants.cjs.map +1 -1
- package/dist/deploymentsSlice/constants.js +2 -2
- package/dist/deploymentsSlice/index.cjs +8 -8
- package/dist/deploymentsSlice/index.cjs.map +1 -1
- package/dist/deploymentsSlice/index.js +3 -3
- package/dist/deploymentsSlice/selectors.cjs +8 -8
- package/dist/deploymentsSlice/selectors.cjs.map +1 -1
- package/dist/deploymentsSlice/selectors.js +3 -3
- package/dist/deploymentsSlice/thunks.cjs +137 -94
- package/dist/deploymentsSlice/thunks.cjs.map +1 -1
- package/dist/deploymentsSlice/thunks.js +19 -19
- package/dist/devicesSlice/constants.cjs +11 -8
- package/dist/devicesSlice/constants.cjs.map +1 -1
- package/dist/devicesSlice/constants.d.cts +2 -1
- package/dist/devicesSlice/constants.d.ts +2 -1
- package/dist/devicesSlice/constants.js +4 -2
- package/dist/devicesSlice/index.cjs +8 -8
- package/dist/devicesSlice/index.cjs.map +1 -1
- package/dist/devicesSlice/index.js +3 -3
- package/dist/devicesSlice/selectors.cjs +9 -9
- package/dist/devicesSlice/selectors.cjs.map +1 -1
- package/dist/devicesSlice/selectors.js +3 -3
- package/dist/devicesSlice/thunks.cjs +139 -94
- package/dist/devicesSlice/thunks.cjs.map +1 -1
- package/dist/devicesSlice/thunks.d.cts +12 -2
- package/dist/devicesSlice/thunks.d.ts +12 -2
- package/dist/devicesSlice/thunks.js +21 -19
- package/dist/flag-eu-5477R2P4.svg +130 -0
- package/dist/flag-us-HNQAF66I.svg +63 -0
- package/dist/monitorSlice/constants.cjs +8 -8
- package/dist/monitorSlice/constants.cjs.map +1 -1
- package/dist/monitorSlice/constants.js +2 -2
- package/dist/monitorSlice/index.cjs +8 -8
- package/dist/monitorSlice/index.cjs.map +1 -1
- package/dist/monitorSlice/index.js +3 -3
- package/dist/monitorSlice/thunks.cjs +59 -37
- package/dist/monitorSlice/thunks.cjs.map +1 -1
- package/dist/monitorSlice/thunks.js +17 -17
- package/dist/onboardingSlice/thunks.cjs +146 -100
- package/dist/onboardingSlice/thunks.cjs.map +1 -1
- package/dist/onboardingSlice/thunks.d.cts +1 -32
- package/dist/onboardingSlice/thunks.d.ts +1 -32
- package/dist/onboardingSlice/thunks.js +19 -19
- package/dist/organizationSlice/constants.cjs +22 -17
- package/dist/organizationSlice/constants.cjs.map +1 -1
- package/dist/organizationSlice/constants.d.cts +33 -1
- package/dist/organizationSlice/constants.d.ts +33 -1
- package/dist/organizationSlice/constants.js +4 -2
- package/dist/organizationSlice/index.cjs +18 -15
- package/dist/organizationSlice/index.cjs.map +1 -1
- package/dist/organizationSlice/index.d.cts +26 -1012
- package/dist/organizationSlice/index.d.ts +26 -1012
- package/dist/organizationSlice/index.js +3 -3
- package/dist/organizationSlice/selectors.cjs.map +1 -1
- package/dist/organizationSlice/selectors.d.cts +9 -1
- package/dist/organizationSlice/selectors.d.ts +9 -1
- package/dist/organizationSlice/selectors.js +3 -3
- package/dist/organizationSlice/thunks.cjs +1605 -1539
- package/dist/organizationSlice/thunks.cjs.map +1 -1
- package/dist/organizationSlice/thunks.d.cts +61 -36
- package/dist/organizationSlice/thunks.d.ts +61 -36
- package/dist/organizationSlice/thunks.js +19 -19
- package/dist/organizationSlice/types.cjs +19 -0
- package/dist/organizationSlice/types.cjs.map +1 -0
- package/dist/organizationSlice/types.d.cts +114 -0
- package/dist/organizationSlice/types.d.ts +114 -0
- package/dist/organizationSlice/types.js +1 -0
- package/dist/organizationSlice/types.js.map +1 -0
- package/dist/releasesSlice/index.js +2 -2
- package/dist/releasesSlice/selectors.cjs +11 -0
- package/dist/releasesSlice/selectors.cjs.map +1 -1
- package/dist/releasesSlice/selectors.js +4 -4
- package/dist/releasesSlice/thunks.cjs +73 -49
- package/dist/releasesSlice/thunks.cjs.map +1 -1
- package/dist/releasesSlice/thunks.d.cts +1 -4
- package/dist/releasesSlice/thunks.d.ts +1 -4
- package/dist/releasesSlice/thunks.js +17 -17
- package/dist/selectors.cjs +46 -18
- package/dist/selectors.cjs.map +1 -1
- package/dist/selectors.d.cts +9 -1
- package/dist/selectors.d.ts +9 -1
- package/dist/selectors.js +36 -30
- package/dist/store.cjs +36 -23
- package/dist/store.cjs.map +1 -1
- package/dist/store.d.cts +12 -231
- package/dist/store.d.ts +12 -231
- package/dist/store.js +13 -11
- package/dist/storehooks.cjs +216 -137
- package/dist/storehooks.cjs.map +1 -1
- package/dist/storehooks.js +36 -24
- package/dist/storehooks.js.map +1 -1
- package/dist/thunks.cjs +193 -122
- package/dist/thunks.cjs.map +1 -1
- package/dist/thunks.d.cts +5 -1
- package/dist/thunks.d.ts +5 -1
- package/dist/thunks.js +21 -19
- package/dist/usersSlice/constants.cjs +10 -10
- package/dist/usersSlice/constants.cjs.map +1 -1
- package/dist/usersSlice/constants.js +2 -2
- package/dist/usersSlice/index.cjs +10 -10
- package/dist/usersSlice/index.cjs.map +1 -1
- package/dist/usersSlice/index.js +3 -3
- package/dist/usersSlice/selectors.cjs +35 -13
- package/dist/usersSlice/selectors.cjs.map +1 -1
- package/dist/usersSlice/selectors.d.cts +44 -1
- package/dist/usersSlice/selectors.d.ts +44 -1
- package/dist/usersSlice/selectors.js +12 -6
- package/dist/usersSlice/thunks.cjs +135 -94
- package/dist/usersSlice/thunks.cjs.map +1 -1
- package/dist/usersSlice/thunks.d.cts +10 -9
- package/dist/usersSlice/thunks.d.ts +10 -9
- package/dist/usersSlice/thunks.js +19 -19
- package/dist/utils.cjs +17 -16
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.js +3 -3
- package/package.json +7 -7
- package/dist/chunk-25AKG5HH.js.map +0 -1
- package/dist/chunk-2RJIDREZ.js.map +0 -1
- package/dist/chunk-74OJIKXF.js.map +0 -1
- package/dist/chunk-A6CT6GTI.js.map +0 -1
- package/dist/chunk-ANB5BM5J.js.map +0 -1
- package/dist/chunk-KAQJH2YL.js.map +0 -1
- package/dist/chunk-MDC7Y3EX.js.map +0 -1
- package/dist/chunk-Q6M5TTDQ.js.map +0 -1
- package/dist/chunk-XTRPX7JZ.js.map +0 -1
- package/dist/chunk-YETZPQFR.js.map +0 -1
- /package/dist/{chunk-RX55KAKX.js.map → chunk-7JKWI5FK.js.map} +0 -0
- /package/dist/{chunk-NNADGHSL.js.map → chunk-DAPAXWA5.js.map} +0 -0
- /package/dist/{chunk-E5LEU5PF.js.map → chunk-HPBE6KYY.js.map} +0 -0
- /package/dist/{chunk-NI4SZOCF.js.map → chunk-LGNOTPUG.js.map} +0 -0
- /package/dist/{chunk-YTQUNAZP.js.map → chunk-QRGTG4YB.js.map} +0 -0
- /package/dist/{chunk-YGBFDXXA.js.map → chunk-TUACATJA.js.map} +0 -0
- /package/dist/{chunk-UEP36GCI.js.map → chunk-VMNMD6KF.js.map} +0 -0
- /package/dist/{chunk-VOCOFE4I.js.map → chunk-X7IEZBM4.js.map} +0 -0
|
@@ -67,6 +67,14 @@ module.exports = __toCommonJS(thunks_exports);
|
|
|
67
67
|
|
|
68
68
|
// src/appSlice/constants.ts
|
|
69
69
|
var import_icons_material = require("@mui/icons-material");
|
|
70
|
+
|
|
71
|
+
// ../../assets/img/flag-eu.svg
|
|
72
|
+
var flag_eu_default = "../flag-eu-5477R2P4.svg";
|
|
73
|
+
|
|
74
|
+
// ../../assets/img/flag-us.svg
|
|
75
|
+
var flag_us_default = "../flag-us-HNQAF66I.svg";
|
|
76
|
+
|
|
77
|
+
// src/appSlice/constants.ts
|
|
70
78
|
var startingDeviceCount = {
|
|
71
79
|
os: "for first 50 devices",
|
|
72
80
|
professional: "for first 250 devices"
|
|
@@ -89,36 +97,36 @@ var emptyChartSelection = { software: "", group: "", chartType: chartTypes.bar.k
|
|
|
89
97
|
var defaultReportType = "distribution";
|
|
90
98
|
var defaultReports = [{ ...emptyChartSelection, group: null, attribute: "artifact_name", type: defaultReportType }];
|
|
91
99
|
var locations = {
|
|
92
|
-
eu: { key: "eu", title: "EU", location: "eu.hosted.mender.io" },
|
|
93
|
-
us: { key: "us", title: "US", location: "hosted.mender.io" }
|
|
100
|
+
eu: { key: "eu", title: "EU", location: "eu.hosted.mender.io", icon: flag_eu_default },
|
|
101
|
+
us: { key: "us", title: "US", location: "hosted.mender.io", icon: flag_us_default }
|
|
94
102
|
};
|
|
95
103
|
var PLANS = {
|
|
96
104
|
os: {
|
|
97
105
|
id: "os",
|
|
98
106
|
name: "Basic",
|
|
99
107
|
offer: true,
|
|
100
|
-
price: "$32/month",
|
|
108
|
+
price: "$32 / month",
|
|
101
109
|
deviceCount: startingDeviceCount.os,
|
|
102
|
-
offerprice: "$23/month for first 50 devices",
|
|
110
|
+
offerprice: "$23 / month for first 50 devices",
|
|
103
111
|
price2: "for first 6 months;\n$29/month thereafter",
|
|
104
|
-
features: ["
|
|
112
|
+
features: ["Access to core features of Mender", "Basic support"]
|
|
105
113
|
},
|
|
106
114
|
professional: {
|
|
107
115
|
id: "professional",
|
|
108
116
|
name: "Professional",
|
|
109
117
|
offer: true,
|
|
110
|
-
price: "$269/month",
|
|
118
|
+
price: "$269 / month",
|
|
111
119
|
deviceCount: startingDeviceCount.professional,
|
|
112
|
-
offerprice: "$200/month for first 50 devices",
|
|
120
|
+
offerprice: "$200 / month for first 50 devices",
|
|
113
121
|
price2: "for first 6 months;\n$249/month thereafter",
|
|
114
|
-
features: ["
|
|
122
|
+
features: ["Advanced OTA features", "Higher priority support"]
|
|
115
123
|
},
|
|
116
124
|
enterprise: {
|
|
117
125
|
id: "enterprise",
|
|
118
126
|
name: "Enterprise",
|
|
119
127
|
price: "Custom pricing",
|
|
120
|
-
deviceCount: "
|
|
121
|
-
features: ["
|
|
128
|
+
deviceCount: "Unlimited devices",
|
|
129
|
+
features: ["All Mender features", "Advanced security features", "SLA-backed support"]
|
|
122
130
|
}
|
|
123
131
|
};
|
|
124
132
|
var ADDONS = {
|
|
@@ -589,6 +597,7 @@ var DEVICE_STATES = {
|
|
|
589
597
|
rejected: "rejected"
|
|
590
598
|
};
|
|
591
599
|
var geoAttributes = ["geo-lat", "geo-lon"].map((attribute) => ({ attribute, scope: "inventory" }));
|
|
600
|
+
var REPORT_CHART_SIZE_LIMIT = 6;
|
|
592
601
|
|
|
593
602
|
// src/monitorSlice/constants.ts
|
|
594
603
|
var alertChannels = { email: "email" };
|
|
@@ -670,13 +679,16 @@ var SSO_TYPES = {
|
|
|
670
679
|
configDetails: [{ key: "startURL", label: "Start Url", getValue: getOidcStartUrl }]
|
|
671
680
|
}
|
|
672
681
|
};
|
|
673
|
-
var
|
|
674
|
-
{ title: "Artifact", queryParameter: "object_type", value: "artifact" },
|
|
675
|
-
{ title: "Deployment", queryParameter: "object_deployment_name", value: "deployment" },
|
|
676
|
-
{ title: "Device", queryParameter: "object_id", value: "device" },
|
|
677
|
-
{ title: "
|
|
678
|
-
|
|
679
|
-
|
|
682
|
+
var auditlogTypes = {
|
|
683
|
+
artifact: { title: "Artifact", queryParameter: "object_type", value: "artifact" },
|
|
684
|
+
deployment: { title: "Deployment", queryParameter: "object_deployment_name", value: "deployment" },
|
|
685
|
+
device: { title: "Device", queryParameter: "object_id", value: "device" },
|
|
686
|
+
user_access_token: { title: "Personal Access Token", queryParameter: "user_access_token", value: "user_access_token" },
|
|
687
|
+
user: { title: "User", queryParameter: "object_id", value: "user" },
|
|
688
|
+
tenant: { title: "Tenant", queryParameter: "object_id", value: "tenant" }
|
|
689
|
+
};
|
|
690
|
+
var AUDIT_LOGS_TYPES = [auditlogTypes.artifact, auditlogTypes.deployment, auditlogTypes.device, auditlogTypes.user_access_token, auditlogTypes.user];
|
|
691
|
+
var SP_AUDIT_LOGS_TYPES = [auditlogTypes.user, auditlogTypes.tenant];
|
|
680
692
|
var emptyWebhook = {
|
|
681
693
|
description: "",
|
|
682
694
|
enabled: true,
|
|
@@ -809,7 +821,7 @@ var uiPermissionsByArea = {
|
|
|
809
821
|
explanation: "Granting access to the audit log will allow tracing changes to devices, releases and user accounts, as well as providing information about deployments.",
|
|
810
822
|
key: "auditlog",
|
|
811
823
|
uiPermissions: [uiPermissionsById.read],
|
|
812
|
-
title: "System
|
|
824
|
+
title: "System Audit Log"
|
|
813
825
|
},
|
|
814
826
|
deployments: {
|
|
815
827
|
endpoints: [
|
|
@@ -960,7 +972,7 @@ var serviceProviderRolesById = {
|
|
|
960
972
|
},
|
|
961
973
|
readOnly: {
|
|
962
974
|
name: "Read access",
|
|
963
|
-
value: staticRolesByName.
|
|
975
|
+
value: staticRolesByName.readOnly,
|
|
964
976
|
description: "This role can see all linked organizations but cannot make any changes",
|
|
965
977
|
permissions: [],
|
|
966
978
|
uiPermissions: {
|
|
@@ -2037,6 +2049,9 @@ var Api = {
|
|
|
2037
2049
|
};
|
|
2038
2050
|
var general_api_default = Api;
|
|
2039
2051
|
|
|
2052
|
+
// src/devicesSlice/thunks.tsx
|
|
2053
|
+
var import_react_router_dom = require("react-router-dom");
|
|
2054
|
+
|
|
2040
2055
|
// src/appSlice/selectors.ts
|
|
2041
2056
|
var import_helpers2 = require("@northern.tech/utils/helpers");
|
|
2042
2057
|
var import_toolkit9 = require("@reduxjs/toolkit");
|
|
@@ -2165,7 +2180,7 @@ var getGroups = (0, import_toolkit11.createSelector)([getGroupsById], (groupsByI
|
|
|
2165
2180
|
(accu, [groupname, group]) => {
|
|
2166
2181
|
const name = groupname === UNGROUPED_GROUP.id ? UNGROUPED_GROUP.name : groupname;
|
|
2167
2182
|
const groupItem = { ...group, groupId: name, name: groupname };
|
|
2168
|
-
if (group.filters
|
|
2183
|
+
if (group.filters?.length > 0) {
|
|
2169
2184
|
if (groupname !== UNGROUPED_GROUP.id) {
|
|
2170
2185
|
accu.dynamic.push(groupItem);
|
|
2171
2186
|
} else {
|
|
@@ -2240,14 +2255,15 @@ var getAuditLogEntry = (0, import_toolkit12.createSelector)([getAuditLog, getAud
|
|
|
2240
2255
|
// src/utils.ts
|
|
2241
2256
|
var import_helpers4 = require("@northern.tech/utils/helpers");
|
|
2242
2257
|
var filterProcessors = {
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2258
|
+
[DEVICE_FILTERING_OPTIONS.$gt.key]: (val) => Number(val) || val,
|
|
2259
|
+
[DEVICE_FILTERING_OPTIONS.$gte.key]: (val) => Number(val) || val,
|
|
2260
|
+
[DEVICE_FILTERING_OPTIONS.$lt.key]: (val) => Number(val) || val,
|
|
2261
|
+
[DEVICE_FILTERING_OPTIONS.$lte.key]: (val) => Number(val) || val,
|
|
2262
|
+
[DEVICE_FILTERING_OPTIONS.$ltne.key]: (val) => Number(val) || val,
|
|
2263
|
+
[DEVICE_FILTERING_OPTIONS.$in.key]: (val) => ("" + val).split(",").map((i) => i.trim()),
|
|
2264
|
+
[DEVICE_FILTERING_OPTIONS.$nin.key]: (val) => ("" + val).split(",").map((i) => i.trim()),
|
|
2265
|
+
[DEVICE_FILTERING_OPTIONS.$exists.key]: import_helpers4.yes,
|
|
2266
|
+
[DEVICE_FILTERING_OPTIONS.$nexists.key]: () => false
|
|
2251
2267
|
};
|
|
2252
2268
|
var filterAliases = {
|
|
2253
2269
|
$nexists: { alias: DEVICE_FILTERING_OPTIONS.$exists.key, value: false }
|
|
@@ -2371,8 +2387,13 @@ var getTooltipsById = (state) => state.users.tooltips.byId;
|
|
|
2371
2387
|
var getGlobalSettings = (state) => state.users.globalSettings;
|
|
2372
2388
|
var getCurrentUserId = (state) => state.users.currentUser;
|
|
2373
2389
|
var getUsersById = (state) => state.users.byId;
|
|
2390
|
+
var getUsersList = (0, import_toolkit14.createSelector)([getUsersById], (usersById) => Object.values(usersById));
|
|
2374
2391
|
var getCurrentUser = (0, import_toolkit14.createSelector)([getUsersById, getCurrentUserId], (usersById, userId) => usersById[userId] ?? {});
|
|
2375
2392
|
var getUserSettings = (state) => state.users.userSettings;
|
|
2393
|
+
var getSelectedDeviceAttribute = (0, import_toolkit14.createSelector)(
|
|
2394
|
+
[getUserSettings],
|
|
2395
|
+
({ columnSelection }) => columnSelection.map((attribute) => ({ attribute: attribute.key, scope: attribute.scope }))
|
|
2396
|
+
);
|
|
2376
2397
|
var getIsDarkMode = (0, import_toolkit14.createSelector)([getUserSettings], ({ mode }) => isDarkMode(mode));
|
|
2377
2398
|
var getShowHelptips = (0, import_toolkit14.createSelector)(
|
|
2378
2399
|
[getTooltipsById],
|
|
@@ -2397,7 +2418,7 @@ var getOfflineThresholdSettings = (0, import_toolkit14.createSelector)([getGloba
|
|
|
2397
2418
|
interval: offlineThreshold?.interval || DEVICE_ONLINE_CUTOFF.interval,
|
|
2398
2419
|
intervalUnit: offlineThreshold?.intervalUnit || DEVICE_ONLINE_CUTOFF.intervalName
|
|
2399
2420
|
}));
|
|
2400
|
-
var getRolesList = (0, import_toolkit14.createSelector)([getRolesById], (rolesById2) => Object.entries(rolesById2).map(([
|
|
2421
|
+
var getRolesList = (0, import_toolkit14.createSelector)([getRolesById], (rolesById2) => Object.entries(rolesById2).map(([value, role]) => ({ value, ...role })));
|
|
2401
2422
|
var getCurrentSession = (state) => state.users.currentSession;
|
|
2402
2423
|
|
|
2403
2424
|
// src/commonSelectors.ts
|
|
@@ -2459,12 +2480,18 @@ var getUserCapabilities = (0, import_toolkit15.createSelector)([getUserRoles, ge
|
|
|
2459
2480
|
});
|
|
2460
2481
|
var getTenantCapabilities = (0, import_toolkit15.createSelector)(
|
|
2461
2482
|
[getFeatures, getOrganization, getIsEnterprise],
|
|
2462
|
-
({
|
|
2483
|
+
({
|
|
2484
|
+
hasAuditlogs: isAuditlogEnabled,
|
|
2485
|
+
hasDeviceConfig: isDeviceConfigEnabled,
|
|
2486
|
+
hasDeviceConnect: isDeviceConnectEnabled,
|
|
2487
|
+
hasMonitor: isMonitorEnabled,
|
|
2488
|
+
isHosted
|
|
2489
|
+
}, { addons = [], plan = PLANS.os.id }, isEnterprise) => {
|
|
2463
2490
|
const canDelta = isEnterprise || plan === PLANS.professional.id;
|
|
2464
2491
|
const hasAuditlogs = isAuditlogEnabled && isEnterprise;
|
|
2465
|
-
const hasDeviceConfig =
|
|
2466
|
-
const hasDeviceConnect =
|
|
2467
|
-
const hasMonitor = isMonitorEnabled && addons.some((addon) => addon.name ===
|
|
2492
|
+
const hasDeviceConfig = addons.some((addon) => addon.name === ADDONS.configure.id && addon.enabled) || isDeviceConfigEnabled && !isHosted;
|
|
2493
|
+
const hasDeviceConnect = addons.some((addon) => addon.name === ADDONS.troubleshoot.id && addon.enabled) || isDeviceConnectEnabled && !isHosted;
|
|
2494
|
+
const hasMonitor = isMonitorEnabled && addons.some((addon) => addon.name === ADDONS.monitor.id && addon.enabled);
|
|
2468
2495
|
return {
|
|
2469
2496
|
canDelta,
|
|
2470
2497
|
canRetry: canDelta,
|
|
@@ -2594,7 +2621,7 @@ var getAuditlogDevice = (0, import_toolkit15.createSelector)([getAuditLogEntry,
|
|
|
2594
2621
|
var getRelevantRoles = (0, import_toolkit15.createSelector)([getOrganization, getRolesList], ({ service_provider }, roles) => {
|
|
2595
2622
|
if (service_provider) {
|
|
2596
2623
|
return roles.reduce((accu, role) => {
|
|
2597
|
-
if (rolesById[role.
|
|
2624
|
+
if (rolesById[role.value]) {
|
|
2598
2625
|
return accu;
|
|
2599
2626
|
}
|
|
2600
2627
|
accu.push(role);
|
|
@@ -2602,20 +2629,19 @@ var getRelevantRoles = (0, import_toolkit15.createSelector)([getOrganization, ge
|
|
|
2602
2629
|
}, Object.values(serviceProviderRolesById));
|
|
2603
2630
|
}
|
|
2604
2631
|
return Object.keys(rolesById).reverse().reduce((accu, key) => {
|
|
2605
|
-
const index = accu.findIndex(({
|
|
2632
|
+
const index = accu.findIndex(({ value }) => value === key);
|
|
2606
2633
|
accu = [accu[index], ...accu.filter((item, itemIndex) => index !== itemIndex)];
|
|
2607
2634
|
return accu;
|
|
2608
2635
|
}, roles);
|
|
2609
2636
|
});
|
|
2610
2637
|
|
|
2611
2638
|
// src/store.ts
|
|
2639
|
+
var import_react_redux = require("react-redux");
|
|
2612
2640
|
var import_helpers6 = require("@northern.tech/utils/helpers");
|
|
2613
2641
|
var import_toolkit16 = require("@reduxjs/toolkit");
|
|
2614
2642
|
var { setSnackbar, uploadProgress } = actions_default;
|
|
2615
2643
|
var keys = ["sessionDeploymentChecker", settingsKeys.initialized];
|
|
2616
|
-
var resetEnvironment = () =>
|
|
2617
|
-
keys.map((key) => window.sessionStorage.removeItem(key));
|
|
2618
|
-
};
|
|
2644
|
+
var resetEnvironment = () => keys.forEach((key) => window.sessionStorage.removeItem(key));
|
|
2619
2645
|
resetEnvironment();
|
|
2620
2646
|
var commonErrorFallback = "Please check your connection.";
|
|
2621
2647
|
var commonErrorHandler = (err, errorContext, dispatch, fallback, mightBeAuthRelated = false) => {
|
|
@@ -2641,6 +2667,14 @@ var sessionReducer = (state, action) => {
|
|
|
2641
2667
|
}
|
|
2642
2668
|
return rootReducer(state, action);
|
|
2643
2669
|
};
|
|
2670
|
+
var rejectionLoggerMiddleware = () => (next) => (action) => {
|
|
2671
|
+
if (action.type.endsWith("/rejected")) {
|
|
2672
|
+
const { error } = action;
|
|
2673
|
+
console.error("Rejection in action:", action);
|
|
2674
|
+
console.error(error.stack);
|
|
2675
|
+
}
|
|
2676
|
+
return next(action);
|
|
2677
|
+
};
|
|
2644
2678
|
var getConfiguredStore = (options = {}) => {
|
|
2645
2679
|
const { preloadedState = {}, ...config } = options;
|
|
2646
2680
|
return (0, import_toolkit16.configureStore)({
|
|
@@ -2656,7 +2690,7 @@ var getConfiguredStore = (options = {}) => {
|
|
|
2656
2690
|
ignoredActionPaths: ["uploads", "snackbar", /payload\..*$/],
|
|
2657
2691
|
ignoredPaths: ["app.uploadsById", "app.snackbar", "organization.externalDeviceIntegrations"]
|
|
2658
2692
|
}
|
|
2659
|
-
})
|
|
2693
|
+
}).concat(rejectionLoggerMiddleware)
|
|
2660
2694
|
});
|
|
2661
2695
|
};
|
|
2662
2696
|
var store = getConfiguredStore({
|
|
@@ -2773,6 +2807,7 @@ var setSearchState = (0, import_toolkit17.createAsyncThunk)(`${sliceName}/setSea
|
|
|
2773
2807
|
|
|
2774
2808
|
// src/deploymentsSlice/thunks.ts
|
|
2775
2809
|
var import_helpers8 = require("@northern.tech/utils/helpers");
|
|
2810
|
+
var import_tracking = __toESM(require("@northern.tech/utils/tracking"), 1);
|
|
2776
2811
|
var import_toolkit18 = require("@reduxjs/toolkit");
|
|
2777
2812
|
var import_validator = require("validator");
|
|
2778
2813
|
var { receivedDevice, setSnackbar: setSnackbar2 } = actions_default;
|
|
@@ -2829,6 +2864,26 @@ var getDeploymentsByStatus2 = (0, import_toolkit18.createAsyncThunk)(`${sliceNam
|
|
|
2829
2864
|
return Promise.all(tasks);
|
|
2830
2865
|
});
|
|
2831
2866
|
});
|
|
2867
|
+
var isWithinFirstMonth = (expirationDate) => {
|
|
2868
|
+
if (!expirationDate) {
|
|
2869
|
+
return false;
|
|
2870
|
+
}
|
|
2871
|
+
const endOfFirstMonth = new Date(expirationDate);
|
|
2872
|
+
endOfFirstMonth.setMonth(endOfFirstMonth.getMonth() - 11);
|
|
2873
|
+
return endOfFirstMonth > /* @__PURE__ */ new Date();
|
|
2874
|
+
};
|
|
2875
|
+
var trackDeploymentCreation = (totalDeploymentCount, hasDeployments, trial_expiration) => {
|
|
2876
|
+
import_tracking.default.event({ category: "deployments", action: "create" });
|
|
2877
|
+
if (!totalDeploymentCount) {
|
|
2878
|
+
if (!hasDeployments) {
|
|
2879
|
+
import_tracking.default.event({ category: "deployments", action: "create_initial_deployment" });
|
|
2880
|
+
if (isWithinFirstMonth(trial_expiration)) {
|
|
2881
|
+
import_tracking.default.event({ category: "deployments", action: "create_initial_deployment_first_month" });
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
import_tracking.default.event({ category: "deployments", action: "create_initial_deployment_user" });
|
|
2885
|
+
}
|
|
2886
|
+
};
|
|
2832
2887
|
var MAX_PREVIOUS_PHASES_COUNT = 5;
|
|
2833
2888
|
var createDeployment = (0, import_toolkit18.createAsyncThunk)(`${sliceName2}/createDeployment`, ({ newDeployment, hasNewRetryDefault = false }, { dispatch, getState }) => {
|
|
2834
2889
|
let request;
|
|
@@ -2839,6 +2894,9 @@ var createDeployment = (0, import_toolkit18.createAsyncThunk)(`${sliceName2}/cre
|
|
|
2839
2894
|
} else {
|
|
2840
2895
|
request = general_api_default.post(`${deploymentsApiUrl}/deployments`, newDeployment);
|
|
2841
2896
|
}
|
|
2897
|
+
const totalDeploymentCount = Object.values(getDeploymentsByStatus(getState())).reduce((accu, item) => accu + item.total, 0);
|
|
2898
|
+
const { hasDeployments } = getGlobalSettings(getState());
|
|
2899
|
+
const { trial_expiration } = getOrganization(getState());
|
|
2842
2900
|
return request.catch((err) => commonErrorHandler(err, "Error creating deployment.", dispatch)).then((data) => {
|
|
2843
2901
|
const lastslashindex = data.headers.location.lastIndexOf("/");
|
|
2844
2902
|
const deploymentId = data.headers.location.substring(lastslashindex + 1);
|
|
@@ -2853,6 +2911,7 @@ var createDeployment = (0, import_toolkit18.createAsyncThunk)(`${sliceName2}/cre
|
|
|
2853
2911
|
dispatch(getSingleDeployment(deploymentId)),
|
|
2854
2912
|
dispatch(setSnackbar2("Deployment created successfully", TIMEOUTS.fiveSeconds))
|
|
2855
2913
|
];
|
|
2914
|
+
trackDeploymentCreation(totalDeploymentCount, hasDeployments, trial_expiration);
|
|
2856
2915
|
const { canManageUsers } = getUserCapabilities(getState());
|
|
2857
2916
|
if (canManageUsers) {
|
|
2858
2917
|
const { phases, retries } = newDeployment;
|
|
@@ -3090,1610 +3149,1604 @@ var saveDeltaDeploymentsConfig = (0, import_toolkit18.createAsyncThunk)(`${slice
|
|
|
3090
3149
|
});
|
|
3091
3150
|
});
|
|
3092
3151
|
|
|
3093
|
-
// src/
|
|
3094
|
-
var import_react_router_dom = require("react-router-dom");
|
|
3095
|
-
var import_helpers9 = require("@northern.tech/utils/helpers");
|
|
3152
|
+
// src/monitorSlice/thunks.ts
|
|
3096
3153
|
var import_toolkit19 = require("@reduxjs/toolkit");
|
|
3097
|
-
var import_axios2 = require("axios");
|
|
3098
|
-
var import_pluralize = __toESM(require("pluralize"), 1);
|
|
3099
|
-
var import_uuid = require("uuid");
|
|
3100
|
-
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
3101
|
-
var { cleanUpUpload, initUpload, setSnackbar: setSnackbar3, uploadProgress: uploadProgress2 } = actions_default;
|
|
3102
3154
|
var { page: defaultPage2, perPage: defaultPerPage2 } = DEVICE_LIST_DEFAULTS;
|
|
3103
|
-
var
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
{
|
|
3109
|
-
{
|
|
3110
|
-
|
|
3111
|
-
{
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
{ scope: "tags", attribute: "name" }
|
|
3116
|
-
];
|
|
3117
|
-
var getGroups2 = (0, import_toolkit19.createAsyncThunk)(
|
|
3118
|
-
`${sliceName3}/getGroups`,
|
|
3119
|
-
(_, { dispatch, getState }) => general_api_default.get(`${inventoryApiUrl}/groups`).then((res) => {
|
|
3120
|
-
const state = getGroupsById(getState());
|
|
3121
|
-
const dynamicGroups = Object.entries(state).reduce((accu, [id, group]) => {
|
|
3122
|
-
if (group.id || group.filters?.length && id !== UNGROUPED_GROUP.id) {
|
|
3123
|
-
accu[id] = group;
|
|
3124
|
-
}
|
|
3125
|
-
return accu;
|
|
3126
|
-
}, {});
|
|
3127
|
-
const groups = res.data.reduce((accu, group) => {
|
|
3128
|
-
accu[group] = { deviceIds: [], filters: [], total: 0, ...state[group] };
|
|
3129
|
-
return accu;
|
|
3130
|
-
}, dynamicGroups);
|
|
3131
|
-
const filters = [{ key: "group", value: res.data, operator: DEVICE_FILTERING_OPTIONS.$nin.key, scope: "system" }];
|
|
3132
|
-
return Promise.all([
|
|
3133
|
-
dispatch(actions3.receivedGroups(groups)),
|
|
3134
|
-
dispatch(getDevicesByStatus2({ filterSelection: filters, group: 0, page: 1, perPage: 1, status: void 0 }))
|
|
3135
|
-
]).then((promises) => {
|
|
3136
|
-
const devicesRetrieval = promises[promises.length - 1] || [];
|
|
3137
|
-
const { payload } = devicesRetrieval || {};
|
|
3138
|
-
const result = payload[payload.length - 1] || {};
|
|
3139
|
-
if (!result.total) {
|
|
3140
|
-
return Promise.resolve();
|
|
3141
|
-
}
|
|
3142
|
-
return Promise.resolve(
|
|
3143
|
-
dispatch(
|
|
3144
|
-
actions3.addGroup({
|
|
3145
|
-
groupName: UNGROUPED_GROUP.id,
|
|
3146
|
-
group: { filters: [{ key: "group", value: res.data, operator: DEVICE_FILTERING_OPTIONS.$nin.key, scope: "system" }] }
|
|
3147
|
-
})
|
|
3148
|
-
)
|
|
3149
|
-
);
|
|
3150
|
-
});
|
|
3151
|
-
})
|
|
3152
|
-
);
|
|
3153
|
-
var addDevicesToGroup = (0, import_toolkit19.createAsyncThunk)(
|
|
3154
|
-
`${sliceName3}/addDevicesToGroup`,
|
|
3155
|
-
({ group, deviceIds, isCreation }, { dispatch }) => general_api_default.patch(`${inventoryApiUrl}/groups/${group}/devices`, deviceIds).then(() => dispatch(actions3.addToGroup({ group, deviceIds }))).finally(() => isCreation ? Promise.resolve(dispatch(getGroups2())) : {})
|
|
3156
|
-
);
|
|
3157
|
-
var removeDevicesFromGroup = (0, import_toolkit19.createAsyncThunk)(
|
|
3158
|
-
`${sliceName3}/removeDevicesFromGroup`,
|
|
3159
|
-
({ group, deviceIds }, { dispatch }) => general_api_default.delete(`${inventoryApiUrl}/groups/${group}/devices`, deviceIds).then(
|
|
3160
|
-
() => Promise.all([
|
|
3161
|
-
dispatch(actions3.removeFromGroup({ group, deviceIds })),
|
|
3162
|
-
dispatch(setSnackbar3(`The ${(0, import_pluralize.default)("devices", deviceIds.length)} ${(0, import_pluralize.default)("were", deviceIds.length)} removed from the group`, TIMEOUTS.fiveSeconds))
|
|
3155
|
+
var cutoffLength = 75;
|
|
3156
|
+
var ellipsis = "...";
|
|
3157
|
+
var longTextTrimmer = (text) => text.length >= cutoffLength + ellipsis.length ? `${text.substring(0, cutoffLength + ellipsis.length)}${ellipsis}` : text;
|
|
3158
|
+
var sanitizeDeviceAlerts = (alerts) => alerts.map((alert) => ({ ...alert, fullName: alert.name, name: longTextTrimmer(alert.name) }));
|
|
3159
|
+
var getDeviceAlerts = (0, import_toolkit19.createAsyncThunk)(`${sliceName4}/getDeviceAlerts`, ({ id, config = {} }, { dispatch }) => {
|
|
3160
|
+
const { page = defaultPage2, perPage = defaultPerPage2, issuedBefore, issuedAfter, sortAscending = false } = config;
|
|
3161
|
+
const issued_after = issuedAfter ? `&issued_after=${issuedAfter}` : "";
|
|
3162
|
+
const issued_before = issuedBefore ? `&issued_before=${issuedBefore}` : "";
|
|
3163
|
+
return general_api_default.get(`${monitorApiUrlv1}/devices/${id}/alerts?page=${page}&per_page=${perPage}${issued_after}${issued_before}&sort_ascending=${sortAscending}`).catch((err) => commonErrorHandler(err, `Retrieving device alerts for device ${id} failed:`, dispatch)).then(
|
|
3164
|
+
(res) => Promise.all([
|
|
3165
|
+
dispatch(actions4.receiveDeviceAlerts({ deviceId: id, alerts: sanitizeDeviceAlerts(res.data) })),
|
|
3166
|
+
dispatch(actions4.setAlertListState({ total: Number(res.headers[headerNames.total]) }))
|
|
3163
3167
|
])
|
|
3164
|
-
)
|
|
3168
|
+
);
|
|
3169
|
+
});
|
|
3170
|
+
var getLatestDeviceAlerts = (0, import_toolkit19.createAsyncThunk)(`${sliceName4}/getLatestDeviceAlerts`, ({ id, config = {} }, { dispatch }) => {
|
|
3171
|
+
const { page = defaultPage2, perPage = 10 } = config;
|
|
3172
|
+
return general_api_default.get(`${monitorApiUrlv1}/devices/${id}/alerts/latest?page=${page}&per_page=${perPage}`).catch((err) => commonErrorHandler(err, `Retrieving device alerts for device ${id} failed:`, dispatch)).then((res) => Promise.resolve(dispatch(actions4.receiveLatestDeviceAlerts({ deviceId: id, alerts: sanitizeDeviceAlerts(res.data) }))));
|
|
3173
|
+
});
|
|
3174
|
+
var getIssueCountsByType2 = (0, import_toolkit19.createAsyncThunk)(`${sliceName4}/getIssueCountsByType`, ({ type, options = {} }, { dispatch, getState }) => {
|
|
3175
|
+
const state = getState();
|
|
3176
|
+
const { filters = getDeviceFilters(state), group, status, ...remainder } = options;
|
|
3177
|
+
const { applicableFilters: nonMonitorFilters, filterTerms } = convertDeviceListStateToFilters({
|
|
3178
|
+
...remainder,
|
|
3179
|
+
filters,
|
|
3180
|
+
group,
|
|
3181
|
+
offlineThreshold: state.app.offlineThreshold,
|
|
3182
|
+
selectedIssues: [type],
|
|
3183
|
+
status
|
|
3184
|
+
});
|
|
3185
|
+
return general_api_default.post(getSearchEndpoint(getState()), {
|
|
3186
|
+
page: 1,
|
|
3187
|
+
per_page: 1,
|
|
3188
|
+
filters: filterTerms,
|
|
3189
|
+
attributes: [{ scope: "identity", attribute: "status" }]
|
|
3190
|
+
}).catch((err) => commonErrorHandler(err, `Retrieving issue counts failed:`, dispatch, commonErrorFallback)).then((res) => {
|
|
3191
|
+
const total = nonMonitorFilters.length ? state.monitor.issueCounts.byType[type].total : Number(res.headers[headerNames.total]);
|
|
3192
|
+
const filtered = nonMonitorFilters.length ? Number(res.headers[headerNames.total]) : total;
|
|
3193
|
+
if (total === state.monitor.issueCounts.byType[type].total && filtered === state.monitor.issueCounts.byType[type].filtered) {
|
|
3194
|
+
return Promise.resolve();
|
|
3195
|
+
}
|
|
3196
|
+
return Promise.resolve(dispatch(actions4.receiveDeviceIssueCounts({ counts: { filtered, total }, issueType: type })));
|
|
3197
|
+
});
|
|
3198
|
+
});
|
|
3199
|
+
var getDeviceMonitorConfig = (0, import_toolkit19.createAsyncThunk)(
|
|
3200
|
+
`${sliceName4}/getDeviceMonitorConfig`,
|
|
3201
|
+
(id, { dispatch }) => general_api_default.get(`${monitorApiUrlv1}/devices/${id}/config`).catch((err) => commonErrorHandler(err, `Retrieving device monitor config for device ${id} failed:`, dispatch)).then(({ data }) => Promise.all([dispatch(actions_default.receivedDevice({ id, monitors: data }), Promise.resolve(data))]))
|
|
3165
3202
|
);
|
|
3166
|
-
var
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
return
|
|
3203
|
+
var changeNotificationSetting = (0, import_toolkit19.createAsyncThunk)(
|
|
3204
|
+
`${sliceName4}/changeNotificationSetting`,
|
|
3205
|
+
({ enabled, channel = alertChannels.email }, { dispatch }) => {
|
|
3206
|
+
return general_api_default.put(`${monitorApiUrlv1}/settings/global/channel/alerts/${channel}/status`, { enabled }).catch((err) => commonErrorHandler(err, `${enabled ? "En" : "Dis"}abling ${channel} alerts failed:`, dispatch)).then(
|
|
3207
|
+
() => Promise.all([
|
|
3208
|
+
dispatch(actions4.changeAlertChannel({ channel, enabled })),
|
|
3209
|
+
dispatch(actions_default.setSnackbar(`Successfully ${enabled ? "en" : "dis"}abled ${channel} alerts`, TIMEOUTS.fiveSeconds))
|
|
3210
|
+
])
|
|
3211
|
+
);
|
|
3170
3212
|
}
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3213
|
+
);
|
|
3214
|
+
|
|
3215
|
+
// src/usersSlice/thunks.ts
|
|
3216
|
+
var import_helptips = require("@northern.tech/common-ui/helptips");
|
|
3217
|
+
|
|
3218
|
+
// src/api/users-api.ts
|
|
3219
|
+
var import_axios2 = __toESM(require("axios"), 1);
|
|
3220
|
+
var Api2 = {
|
|
3221
|
+
postLogin: (url, { email: username, password, ...body }) => import_axios2.default.post(url, body, { ...commonRequestConfig, auth: { username, password } }).then((res) => ({ text: res.data, code: res.status, contentType: res.headers?.["content-type"] })),
|
|
3222
|
+
putVerifyTFA: (url, userData) => {
|
|
3223
|
+
let body = {};
|
|
3224
|
+
if (userData.hasOwnProperty("token2fa")) {
|
|
3225
|
+
body = { token2fa: userData.token2fa };
|
|
3182
3226
|
}
|
|
3183
|
-
|
|
3227
|
+
return import_axios2.default.put(url, body, { ...commonRequestConfig, headers: { ...commonRequestConfig.headers, Authorization: `Bearer ${getToken()}` } });
|
|
3228
|
+
}
|
|
3184
3229
|
};
|
|
3185
|
-
var
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3230
|
+
var users_api_default = Api2;
|
|
3231
|
+
|
|
3232
|
+
// src/usersSlice/thunks.ts
|
|
3233
|
+
var import_helpers9 = require("@northern.tech/utils/helpers");
|
|
3234
|
+
var import_retrytimer = require("@northern.tech/utils/retrytimer");
|
|
3235
|
+
var import_toolkit20 = require("@reduxjs/toolkit");
|
|
3236
|
+
var import_md5 = __toESM(require("md5"), 1);
|
|
3237
|
+
var import_universal_cookie3 = __toESM(require("universal-cookie"), 1);
|
|
3238
|
+
var cookies3 = new import_universal_cookie3.default();
|
|
3239
|
+
var { setAnnouncement, setSnackbar: setSnackbar3 } = actions_default;
|
|
3240
|
+
var handleLoginError = (err, { token2fa: has2FA, password }, rejectWithValue) => (dispatch) => {
|
|
3241
|
+
const errorText = (0, import_helpers9.extractErrorMessage)(err);
|
|
3242
|
+
const is2FABackend = errorText.includes("2fa");
|
|
3243
|
+
if (is2FABackend && !has2FA) {
|
|
3244
|
+
return rejectWithValue({ error: "2fa code missing" });
|
|
3245
|
+
}
|
|
3246
|
+
if (password === void 0) {
|
|
3247
|
+
return Promise.reject();
|
|
3248
|
+
}
|
|
3249
|
+
const twoFAError = is2FABackend ? " and verification code" : "";
|
|
3250
|
+
const errorMessage = `There was a problem logging in. Please check your email${twoFAError ? "," : " and"} password${twoFAError}. If you still have problems, contact an administrator.`;
|
|
3251
|
+
return Promise.reject(dispatch(setSnackbar3({ message: (0, import_helpers9.preformatWithRequestID)(err.response, errorMessage), action: "Copy to clipboard" })));
|
|
3252
|
+
};
|
|
3253
|
+
var loginUser = (0, import_toolkit20.createAsyncThunk)(
|
|
3254
|
+
`${sliceName8}/loginUser`,
|
|
3255
|
+
({ stayLoggedIn, ...userData }, { dispatch, rejectWithValue }) => users_api_default.postLogin(`${useradmApiUrlv1}/auth/login`, { ...userData, no_expiry: stayLoggedIn }).catch((err) => {
|
|
3256
|
+
cleanUp();
|
|
3257
|
+
return Promise.reject(dispatch(handleLoginError(err, userData, rejectWithValue)));
|
|
3258
|
+
}).then(({ text: response, contentType }) => {
|
|
3259
|
+
if (contentType.includes(APPLICATION_JSON_CONTENT_TYPE)) {
|
|
3260
|
+
const { id, kind } = response;
|
|
3261
|
+
const type = kind.split("/")[1];
|
|
3262
|
+
const ssoLoginUrl = SSO_TYPES[type].getStartUrl(id);
|
|
3263
|
+
window.location.replace(ssoLoginUrl);
|
|
3264
|
+
return;
|
|
3265
|
+
}
|
|
3266
|
+
const token = response;
|
|
3267
|
+
if (contentType !== APPLICATION_JWT_CONTENT_TYPE || !token) {
|
|
3268
|
+
return;
|
|
3269
|
+
}
|
|
3270
|
+
let now = /* @__PURE__ */ new Date();
|
|
3271
|
+
now.setSeconds(now.getSeconds() + maxSessionAge);
|
|
3272
|
+
const expiresAt = stayLoggedIn ? void 0 : now.toISOString();
|
|
3273
|
+
setSessionInfo({ token, expiresAt });
|
|
3274
|
+
cookies3.remove("JWT", { path: "/" });
|
|
3275
|
+
return dispatch(getUser(OWN_USER_ID)).unwrap().catch((e) => {
|
|
3276
|
+
cleanUp();
|
|
3277
|
+
return Promise.reject(dispatch(setSnackbar3((0, import_helpers9.extractErrorMessage)(e))));
|
|
3278
|
+
}).then(() => {
|
|
3279
|
+
window.sessionStorage.removeItem("pendings-redirect");
|
|
3280
|
+
if (window.location.pathname !== "/ui/") {
|
|
3281
|
+
window.location.replace("/ui/");
|
|
3282
|
+
}
|
|
3283
|
+
return Promise.resolve(dispatch(actions8.successfullyLoggedIn({ expiresAt, token })));
|
|
3284
|
+
});
|
|
3285
|
+
})
|
|
3203
3286
|
);
|
|
3204
|
-
var
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3287
|
+
var logoutUser = (0, import_toolkit20.createAsyncThunk)(`${sliceName8}/logoutUser`, (_, { dispatch, getState }) => {
|
|
3288
|
+
if (Object.keys(getState().app.uploadsById).length) {
|
|
3289
|
+
return Promise.reject();
|
|
3290
|
+
}
|
|
3291
|
+
return general_api_default.post(`${useradmApiUrlv1}/auth/logout`).finally(() => {
|
|
3292
|
+
cleanUp();
|
|
3293
|
+
(0, import_retrytimer.clearAllRetryTimers)(setSnackbar3);
|
|
3294
|
+
return Promise.resolve(dispatch({ type: USER_LOGOUT }));
|
|
3295
|
+
});
|
|
3296
|
+
});
|
|
3297
|
+
var switchUserOrganization = (0, import_toolkit20.createAsyncThunk)(`${sliceName8}/switchUserOrganization`, (tenantId, { getState }) => {
|
|
3298
|
+
if (Object.keys(getState().app.uploadsById).length) {
|
|
3299
|
+
return Promise.reject();
|
|
3300
|
+
}
|
|
3301
|
+
return general_api_default.get(`${useradmApiUrlv1}/users/tenants/${tenantId}/token`).then(({ data: token }) => {
|
|
3302
|
+
window.sessionStorage.setItem("tenantChanged", "true");
|
|
3303
|
+
setSessionInfo({ ...getSessionInfo(), token });
|
|
3304
|
+
window.location.reload();
|
|
3305
|
+
});
|
|
3306
|
+
});
|
|
3307
|
+
var passwordResetStart = (0, import_toolkit20.createAsyncThunk)(
|
|
3308
|
+
`${sliceName8}/passwordResetStart`,
|
|
3309
|
+
(email, { dispatch }) => general_api_default.post(`${useradmApiUrlv1}/auth/password-reset/start`, { email }).catch(
|
|
3310
|
+
(err) => commonErrorHandler(err, `The password reset request cannot be processed:`, dispatch, void 0, true)
|
|
3212
3311
|
)
|
|
3213
3312
|
);
|
|
3214
|
-
var
|
|
3215
|
-
`${
|
|
3216
|
-
(
|
|
3217
|
-
const
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
}
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
total: 0,
|
|
3228
|
-
...state[filter.name],
|
|
3229
|
-
id: filter.id,
|
|
3230
|
-
filters: mapTermsToFilters(filter.terms)
|
|
3231
|
-
};
|
|
3232
|
-
return accu;
|
|
3233
|
-
}, staticGroups);
|
|
3234
|
-
return Promise.resolve(dispatch(actions3.receivedGroups(groups)));
|
|
3235
|
-
}).catch(() => console.log("Dynamic group retrieval failed - likely accessing a non-enterprise backend"))
|
|
3313
|
+
var passwordResetComplete = (0, import_toolkit20.createAsyncThunk)(
|
|
3314
|
+
`${sliceName8}/passwordResetComplete`,
|
|
3315
|
+
({ secretHash, newPassword }, { dispatch }) => general_api_default.post(`${useradmApiUrlv1}/auth/password-reset/complete`, { secret_hash: secretHash, password: newPassword }).catch((err = {}) => {
|
|
3316
|
+
const { error, response = {} } = err;
|
|
3317
|
+
let errorMsg = "";
|
|
3318
|
+
if (response.status == 400) {
|
|
3319
|
+
errorMsg = "the link you are using expired or the request is not valid, please try again.";
|
|
3320
|
+
} else {
|
|
3321
|
+
errorMsg = error;
|
|
3322
|
+
}
|
|
3323
|
+
dispatch(setSnackbar3("The password reset request cannot be processed: " + errorMsg));
|
|
3324
|
+
return Promise.reject(err);
|
|
3325
|
+
})
|
|
3236
3326
|
);
|
|
3237
|
-
var
|
|
3238
|
-
`${
|
|
3239
|
-
(
|
|
3240
|
-
(res) => Promise.resolve(
|
|
3241
|
-
dispatch(
|
|
3242
|
-
actions3.addGroup({
|
|
3243
|
-
groupName,
|
|
3244
|
-
group: {
|
|
3245
|
-
id: res.headers[headerNames.location].substring(res.headers[headerNames.location].lastIndexOf("/") + 1),
|
|
3246
|
-
filters: filterPredicates
|
|
3247
|
-
}
|
|
3248
|
-
})
|
|
3249
|
-
)
|
|
3250
|
-
).then(() => {
|
|
3251
|
-
const { cleanedFilters } = getGroupFilters(groupName, getState().devices.groups);
|
|
3252
|
-
return Promise.all([
|
|
3253
|
-
dispatch(actions3.setDeviceFilters(cleanedFilters)),
|
|
3254
|
-
dispatch(setSnackbar3(...getGroupNotification(groupName, getState().devices.groups.selectedGroup))),
|
|
3255
|
-
dispatch(getDynamicGroups())
|
|
3256
|
-
]);
|
|
3257
|
-
})
|
|
3258
|
-
).catch((err) => commonErrorHandler(err, `Group could not be updated:`, dispatch))
|
|
3327
|
+
var verifyEmailStart = (0, import_toolkit20.createAsyncThunk)(
|
|
3328
|
+
`${sliceName8}/verifyEmailStart`,
|
|
3329
|
+
(_, { dispatch, getState }) => general_api_default.post(`${useradmApiUrlv1}/auth/verify-email/start`, { email: getCurrentUser(getState()).email }).catch((err) => commonErrorHandler(err, "An error occured starting the email verification process:", dispatch)).finally(() => Promise.resolve(dispatch(getUser(OWN_USER_ID))))
|
|
3259
3330
|
);
|
|
3260
|
-
var
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
var
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
() =>
|
|
3268
|
-
)
|
|
3269
|
-
|
|
3270
|
-
var
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3331
|
+
var verifyEmailComplete = (0, import_toolkit20.createAsyncThunk)(
|
|
3332
|
+
`${sliceName8}/verifyEmailComplete`,
|
|
3333
|
+
(secret_hash, { dispatch }) => general_api_default.post(`${useradmApiUrlv1}/auth/verify-email/complete`, { secret_hash }).catch((err) => commonErrorHandler(err, "An error occured completing the email verification process:", dispatch)).finally(() => Promise.resolve(dispatch(getUser(OWN_USER_ID))))
|
|
3334
|
+
);
|
|
3335
|
+
var verify2FA = (0, import_toolkit20.createAsyncThunk)(
|
|
3336
|
+
`${sliceName8}/verify2FA`,
|
|
3337
|
+
(tfaData, { dispatch }) => users_api_default.putVerifyTFA(`${useradmApiUrlv1}/2faverify`, tfaData).then(() => Promise.resolve(dispatch(getUser(OWN_USER_ID)))).catch(
|
|
3338
|
+
(err) => commonErrorHandler(err, "An error occured validating the verification code: failed to verify token, please try again.", dispatch, void 0, true)
|
|
3339
|
+
)
|
|
3340
|
+
);
|
|
3341
|
+
var getUserList = (0, import_toolkit20.createAsyncThunk)(
|
|
3342
|
+
`${sliceName8}/getUserList`,
|
|
3343
|
+
(_, { dispatch, getState }) => general_api_default.get(`${useradmApiUrlv1}/users`).then((res) => {
|
|
3344
|
+
const currentUsersById = getUsersById(getState());
|
|
3345
|
+
const users = res.data.reduce(
|
|
3346
|
+
(accu, item) => {
|
|
3347
|
+
accu[item.id] = {
|
|
3348
|
+
...accu[item.id],
|
|
3349
|
+
...item
|
|
3350
|
+
};
|
|
3351
|
+
return accu;
|
|
3352
|
+
},
|
|
3353
|
+
{ ...currentUsersById }
|
|
3354
|
+
);
|
|
3355
|
+
return dispatch(actions8.receivedUserList(users));
|
|
3356
|
+
}).catch((err) => commonErrorHandler(err, `Users couldn't be loaded.`, dispatch, commonErrorFallback))
|
|
3357
|
+
);
|
|
3358
|
+
var getUser = (0, import_toolkit20.createAsyncThunk)(
|
|
3359
|
+
`${sliceName8}/getUser`,
|
|
3360
|
+
(id, { dispatch, rejectWithValue }) => general_api_default.get(`${useradmApiUrlv1}/users/${id}`).then(
|
|
3361
|
+
({ data: user }) => Promise.all([
|
|
3362
|
+
dispatch(actions8.receivedUser(user)),
|
|
3363
|
+
dispatch(setHideAnnouncement({ shouldHide: false, userId: user.id })),
|
|
3364
|
+
dispatch(updateUserColumnSettings({ currentUserId: user.id })),
|
|
3365
|
+
user
|
|
3366
|
+
])
|
|
3367
|
+
).catch((e) => rejectWithValue(e))
|
|
3368
|
+
);
|
|
3369
|
+
var initializeSelf = (0, import_toolkit20.createAsyncThunk)(`${sliceName8}/initializeSelf`, (_, { dispatch }) => dispatch(getUser(OWN_USER_ID)));
|
|
3370
|
+
var updateUserColumnSettings = (0, import_toolkit20.createAsyncThunk)(`${sliceName8}/updateUserColumnSettings`, ({ columns, currentUserId }, { dispatch, getState }) => {
|
|
3371
|
+
const userId = currentUserId ?? getCurrentUser(getState()).id;
|
|
3372
|
+
const storageKey = `${userId}-column-widths`;
|
|
3373
|
+
let customColumns = [];
|
|
3374
|
+
if (!columns) {
|
|
3375
|
+
try {
|
|
3376
|
+
customColumns = JSON.parse(window.localStorage.getItem(storageKey)) || customColumns;
|
|
3377
|
+
} catch {
|
|
3378
|
+
}
|
|
3285
3379
|
} else {
|
|
3286
|
-
|
|
3287
|
-
tasks.push(dispatch(getGroupDevices({ group: groupName, perPage: 1, shouldIncludeAllStates: true })));
|
|
3380
|
+
customColumns = columns;
|
|
3288
3381
|
}
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
return Promise.all(tasks);
|
|
3382
|
+
window.localStorage.setItem(storageKey, JSON.stringify(customColumns));
|
|
3383
|
+
return Promise.resolve(dispatch(actions8.setCustomColumns(customColumns)));
|
|
3292
3384
|
});
|
|
3293
|
-
var
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
const {
|
|
3298
|
-
attributes: storedAttributes = {},
|
|
3299
|
-
identity_data: storedIdentity = {},
|
|
3300
|
-
monitor: storedMonitor = {},
|
|
3301
|
-
tags: storedTags = {},
|
|
3302
|
-
group: storedGroup
|
|
3303
|
-
} = stateDevice;
|
|
3304
|
-
const { identity, inventory, monitor, system = {}, tags } = mapDeviceAttributes(device.attributes);
|
|
3305
|
-
device.tags = { ...storedTags, ...tags };
|
|
3306
|
-
device.group = system.group ?? storedGroup;
|
|
3307
|
-
device.monitor = { ...storedMonitor, ...monitor };
|
|
3308
|
-
device.identity_data = { ...storedIdentity, ...identity, ...device.identity_data ? device.identity_data : {} };
|
|
3309
|
-
device.status = status ? status : device.status || identity.status;
|
|
3310
|
-
device.check_in_time_rounded = system.check_in_time ?? stateDevice.check_in_time_rounded;
|
|
3311
|
-
device.check_in_time_exact = device.check_in_time ?? stateDevice.check_in_time_exact;
|
|
3312
|
-
device.created_ts = getEarliestTs(getEarliestTs(system.created_ts, device.created_ts), stateDevice.created_ts);
|
|
3313
|
-
device.updated_ts = device.attributes ? device.updated_ts : stateDevice.updated_ts;
|
|
3314
|
-
device.isNew = new Date(device.created_ts) > new Date(state.app.newThreshold);
|
|
3315
|
-
device.isOffline = new Date(device.check_in_time_rounded) < new Date(state.app.offlineThreshold) || device.check_in_time_rounded === void 0;
|
|
3316
|
-
device.attributes = device.attributes ? { ...storedAttributes, ...inventory } : storedAttributes;
|
|
3317
|
-
accu.devicesById[device.id] = { ...stateDevice, ...device };
|
|
3318
|
-
accu.ids.push(device.id);
|
|
3319
|
-
return accu;
|
|
3385
|
+
var userActions = {
|
|
3386
|
+
add: {
|
|
3387
|
+
successMessage: "The user was added successfully.",
|
|
3388
|
+
errorMessage: "adding"
|
|
3320
3389
|
},
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
const { deviceAccu, total } = results[results.length - 1];
|
|
3333
|
-
const stateGroup = getState().devices.groups.byId[group];
|
|
3334
|
-
if (!stateGroup && !total && !deviceAccu.ids.length) {
|
|
3335
|
-
return Promise.resolve();
|
|
3336
|
-
}
|
|
3337
|
-
return Promise.resolve(
|
|
3338
|
-
dispatch(
|
|
3339
|
-
actions3.addGroup({
|
|
3340
|
-
group: {
|
|
3341
|
-
deviceIds: deviceAccu.ids.length === total || deviceAccu.ids.length > stateGroup?.deviceIds ? deviceAccu.ids : stateGroup.deviceIds,
|
|
3342
|
-
total
|
|
3343
|
-
},
|
|
3344
|
-
groupName: group
|
|
3345
|
-
})
|
|
3346
|
-
)
|
|
3347
|
-
);
|
|
3348
|
-
});
|
|
3349
|
-
});
|
|
3350
|
-
var getAllGroupDevices = (0, import_toolkit19.createAsyncThunk)(`${sliceName3}/getAllGroupDevices`, (group, { dispatch, getState }) => {
|
|
3351
|
-
if (!group || !!group && (!getGroupsById(getState())[group] || getGroupsById(getState())[group].filters.length)) {
|
|
3352
|
-
return Promise.resolve();
|
|
3390
|
+
create: {
|
|
3391
|
+
successMessage: "The user was created successfully.",
|
|
3392
|
+
errorMessage: "creating"
|
|
3393
|
+
},
|
|
3394
|
+
edit: {
|
|
3395
|
+
successMessage: "The user has been updated.",
|
|
3396
|
+
errorMessage: "editing"
|
|
3397
|
+
},
|
|
3398
|
+
remove: {
|
|
3399
|
+
successMessage: "The user was removed from the system.",
|
|
3400
|
+
errorMessage: "removing"
|
|
3353
3401
|
}
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
}
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
});
|
|
3375
|
-
return
|
|
3402
|
+
};
|
|
3403
|
+
var userActionErrorHandler = (err, type, dispatch) => commonErrorHandler(err, `There was an error ${userActions[type].errorMessage} the user.`, dispatch);
|
|
3404
|
+
var createUser = (0, import_toolkit20.createAsyncThunk)(
|
|
3405
|
+
`${sliceName8}/createUser`,
|
|
3406
|
+
({ shouldResetPassword, ...userData }, { dispatch }) => general_api_default.post(`${useradmApiUrlv1}/users`, { ...userData, send_reset_password: shouldResetPassword }).then(() => Promise.all([dispatch(actions8.createdUser(userData)), dispatch(getUserList()), dispatch(setSnackbar3(userActions.create.successMessage))])).catch((err) => userActionErrorHandler(err, "create", dispatch))
|
|
3407
|
+
);
|
|
3408
|
+
var removeUser = (0, import_toolkit20.createAsyncThunk)(
|
|
3409
|
+
`${sliceName8}/removeUser`,
|
|
3410
|
+
(userId, { dispatch }) => general_api_default.delete(`${useradmApiUrlv1}/users/${userId}`).then(() => Promise.all([dispatch(actions8.removedUser(userId)), dispatch(getUserList()), dispatch(setSnackbar3(userActions.remove.successMessage))])).catch((err) => userActionErrorHandler(err, "remove", dispatch))
|
|
3411
|
+
);
|
|
3412
|
+
var editUser = (0, import_toolkit20.createAsyncThunk)(
|
|
3413
|
+
`${sliceName8}/editUser`,
|
|
3414
|
+
({ id, ...userData }, { dispatch, getState }) => general_api_default.put(`${useradmApiUrlv1}/users/${id}`, userData).then(
|
|
3415
|
+
() => Promise.all([
|
|
3416
|
+
dispatch(actions8.updatedUser({ ...userData, id: id === OWN_USER_ID ? getCurrentUser(getState()).id : id })),
|
|
3417
|
+
dispatch(setSnackbar3(userActions.edit.successMessage))
|
|
3418
|
+
])
|
|
3419
|
+
)
|
|
3420
|
+
);
|
|
3421
|
+
var addUserToCurrentTenant = (0, import_toolkit20.createAsyncThunk)(`${sliceName8}/addUserToTenant`, (userId, { dispatch, getState }) => {
|
|
3422
|
+
const { id } = getOrganization(getState());
|
|
3423
|
+
return general_api_default.post(`${useradmApiUrlv1}/users/${userId}/assign`, { tenant_ids: [id] }).catch((err) => commonErrorHandler(err, `There was an error adding the user to your organization:`, dispatch)).then(() => Promise.all([dispatch(setSnackbar3(userActions.add.successMessage)), dispatch(getUserList())]));
|
|
3376
3424
|
});
|
|
3377
|
-
var
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
const
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3425
|
+
var enableUser2fa = (0, import_toolkit20.createAsyncThunk)(
|
|
3426
|
+
`${sliceName8}/enableUser2fa`,
|
|
3427
|
+
(userId = OWN_USER_ID, { dispatch }) => general_api_default.post(`${useradmApiUrlv1}/users/${userId}/2fa/enable`).catch((err) => commonErrorHandler(err, `There was an error enabling Two Factor authentication for the user.`, dispatch)).then(() => Promise.resolve(dispatch(getUser(userId))))
|
|
3428
|
+
);
|
|
3429
|
+
var disableUser2fa = (0, import_toolkit20.createAsyncThunk)(
|
|
3430
|
+
`${sliceName8}/disableUser2fa`,
|
|
3431
|
+
(userId = OWN_USER_ID, { dispatch }) => general_api_default.post(`${useradmApiUrlv1}/users/${userId}/2fa/disable`).catch((err) => commonErrorHandler(err, `There was an error disabling Two Factor authentication for the user.`, dispatch)).then(() => Promise.all([dispatch(getUser(userId)), dispatch(actions8.receivedQrCode(null))]))
|
|
3432
|
+
);
|
|
3433
|
+
var mapHttpPermission = (permission) => Object.entries(uiPermissionsByArea).reduce(
|
|
3434
|
+
(accu, [area, definition]) => {
|
|
3435
|
+
const endpointMatches = definition.endpoints.filter(
|
|
3436
|
+
(endpoint) => endpoint.path.test(permission.value) && (endpoint.types.includes(permission.type) || permission.type === PermissionTypes.Any)
|
|
3437
|
+
);
|
|
3438
|
+
if (permission.value === PermissionTypes.Any || permission.value.includes(apiRoot) && endpointMatches.length) {
|
|
3439
|
+
const endpointUiPermission = endpointMatches.reduce((endpointAccu, endpoint) => [...endpointAccu, ...endpoint.uiPermissions], []);
|
|
3440
|
+
const collector = (endpointUiPermission || definition.uiPermissions).reduce((permissionsAccu, uiPermission) => {
|
|
3441
|
+
if (permission.type === PermissionTypes.Any || !endpointMatches.length && uiPermission.verbs.some((verb) => verb === permission.type)) {
|
|
3442
|
+
permissionsAccu.push(uiPermission.value);
|
|
3443
|
+
}
|
|
3444
|
+
return permissionsAccu;
|
|
3445
|
+
}, []).filter(import_helpers9.duplicateFilter);
|
|
3446
|
+
if (Array.isArray(accu[area])) {
|
|
3447
|
+
accu[area] = [...accu[area], ...collector].filter(import_helpers9.duplicateFilter);
|
|
3448
|
+
} else {
|
|
3449
|
+
accu[area] = mergePermissions(accu[area], { [scopedPermissionAreas[area].excessiveAccessSelector]: collector });
|
|
3450
|
+
}
|
|
3393
3451
|
}
|
|
3394
|
-
return
|
|
3395
|
-
}
|
|
3396
|
-
|
|
3397
|
-
});
|
|
3398
|
-
var getDeviceById2 = (0, import_toolkit19.createAsyncThunk)(
|
|
3399
|
-
`${sliceName3}/getDeviceById`,
|
|
3400
|
-
(id, { dispatch, getState }) => general_api_default.get(`${inventoryApiUrl}/devices/${id}`).then((res) => {
|
|
3401
|
-
const device = reduceReceivedDevices([res.data], [], getState()).devicesById[id];
|
|
3402
|
-
device.etag = res.headers.etag;
|
|
3403
|
-
dispatch(actions3.receivedDevice(device));
|
|
3404
|
-
return Promise.resolve(device);
|
|
3405
|
-
}).catch((err) => {
|
|
3406
|
-
const errMsg = (0, import_helpers9.extractErrorMessage)(err);
|
|
3407
|
-
if (errMsg.includes("Not Found")) {
|
|
3408
|
-
console.log(`${id} does not have any inventory information`);
|
|
3409
|
-
const device = reduceReceivedDevices(
|
|
3410
|
-
[
|
|
3411
|
-
{
|
|
3412
|
-
id,
|
|
3413
|
-
attributes: [
|
|
3414
|
-
{ name: "status", value: "decomissioned", scope: "identity" },
|
|
3415
|
-
{ name: "decomissioned", value: "true", scope: "inventory" }
|
|
3416
|
-
]
|
|
3417
|
-
}
|
|
3418
|
-
],
|
|
3419
|
-
[],
|
|
3420
|
-
getState()
|
|
3421
|
-
).devicesById[id];
|
|
3422
|
-
dispatch(actions3.receivedDevice(device));
|
|
3423
|
-
}
|
|
3424
|
-
})
|
|
3452
|
+
return accu;
|
|
3453
|
+
},
|
|
3454
|
+
{ ...emptyUiPermissions }
|
|
3425
3455
|
);
|
|
3426
|
-
var
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3456
|
+
var permissionActionTypes = {
|
|
3457
|
+
any: mapHttpPermission,
|
|
3458
|
+
CREATE_DEPLOYMENT: (permission) => permission.type === PermissionTypes.DeviceGroup ? {
|
|
3459
|
+
deployments: [uiPermissionsById.deploy.value],
|
|
3460
|
+
groups: { [permission.value]: [uiPermissionsById.deploy.value] }
|
|
3461
|
+
} : {},
|
|
3462
|
+
http: mapHttpPermission,
|
|
3463
|
+
REMOTE_TERMINAL: (permission) => permission.type === PermissionTypes.DeviceGroup ? {
|
|
3464
|
+
groups: { [permission.value]: [uiPermissionsById.connect.value] }
|
|
3465
|
+
} : {},
|
|
3466
|
+
VIEW_DEVICE: (permission) => permission.type === PermissionTypes.DeviceGroup ? {
|
|
3467
|
+
groups: { [permission.value]: [uiPermissionsById.read.value] }
|
|
3468
|
+
} : {}
|
|
3469
|
+
};
|
|
3470
|
+
var combinePermissions = (existingPermissions, additionalPermissions = {}) => Object.entries(additionalPermissions).reduce((accu, [name, permissions]) => {
|
|
3471
|
+
let maybeExistingPermissions = accu[name] || [];
|
|
3472
|
+
accu[name] = [...permissions, ...maybeExistingPermissions].filter(import_helpers9.duplicateFilter);
|
|
3473
|
+
return accu;
|
|
3474
|
+
}, existingPermissions);
|
|
3475
|
+
var tryParseCustomPermission = (permission) => {
|
|
3476
|
+
const uiPermissions = permissionActionTypes[permission.action](permission.object);
|
|
3477
|
+
const result = mergePermissions({ ...emptyUiPermissions }, uiPermissions);
|
|
3478
|
+
return { isCustom: true, permission, result };
|
|
3479
|
+
};
|
|
3480
|
+
var customPermissionHandler = (accu, permission) => {
|
|
3481
|
+
let processor = tryParseCustomPermission(permission);
|
|
3482
|
+
return {
|
|
3483
|
+
...accu,
|
|
3484
|
+
isCustom: accu.isCustom || processor.isCustom,
|
|
3485
|
+
uiPermissions: mergePermissions(accu.uiPermissions, processor.result)
|
|
3486
|
+
};
|
|
3487
|
+
};
|
|
3488
|
+
var mapPermissionSet = (permissionSetName, names, scope, existingGroupsPermissions = {}) => {
|
|
3489
|
+
const permission = Object.values(uiPermissionsById).find((permission2) => permission2.permissionSets[scope] === permissionSetName).value;
|
|
3490
|
+
const scopedPermissions = names.reduce((accu, name) => combinePermissions(accu, { [name]: [permission] }), existingGroupsPermissions);
|
|
3491
|
+
return Object.entries(scopedPermissions).reduce((accu, [key, permissions]) => ({ ...accu, [key]: deriveImpliedAreaPermissions(scope, permissions) }), {});
|
|
3492
|
+
};
|
|
3493
|
+
var isEmptyPermissionSet = (permissionSet) => !Object.values(permissionSet).reduce((accu, permissions) => {
|
|
3494
|
+
if (Array.isArray(permissions)) {
|
|
3495
|
+
return accu || !!permissions.length;
|
|
3444
3496
|
}
|
|
3445
|
-
return
|
|
3446
|
-
});
|
|
3447
|
-
var
|
|
3448
|
-
const
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
const device = getDeviceById(getState(), id);
|
|
3454
|
-
if (device && device.updated_ts > yesterdaysIsoString) {
|
|
3455
|
-
accu.active.push(id);
|
|
3456
|
-
} else {
|
|
3457
|
-
accu.inactive.push(id);
|
|
3497
|
+
return accu || !(0, import_helpers9.isEmpty)(permissions);
|
|
3498
|
+
}, false);
|
|
3499
|
+
var parseRolePermissions = ({ permission_sets_with_scope = [], permissions = [] }, permissionSets) => {
|
|
3500
|
+
const preliminaryResult = permission_sets_with_scope.reduce(
|
|
3501
|
+
(accu, permissionSet) => {
|
|
3502
|
+
let processor = permissionSets[permissionSet.name];
|
|
3503
|
+
if (!processor) {
|
|
3504
|
+
return accu;
|
|
3458
3505
|
}
|
|
3459
|
-
|
|
3506
|
+
const scope = Object.keys(scopedPermissionAreas).find((scope2) => uiPermissionsByArea[scope2].scope === permissionSet.scope?.type);
|
|
3507
|
+
if (scope) {
|
|
3508
|
+
const result = mapPermissionSet(permissionSet.name, permissionSet.scope.value, scope, accu.uiPermissions[scope]);
|
|
3509
|
+
return { ...accu, uiPermissions: { ...accu.uiPermissions, [scope]: result } };
|
|
3510
|
+
} else if (isEmptyPermissionSet(processor.result)) {
|
|
3511
|
+
return processor.permissions.reduce(customPermissionHandler, accu);
|
|
3512
|
+
}
|
|
3513
|
+
return {
|
|
3514
|
+
...accu,
|
|
3515
|
+
isCustom: accu.isCustom || processor.isCustom,
|
|
3516
|
+
uiPermissions: mergePermissions(accu.uiPermissions, processor.result)
|
|
3517
|
+
};
|
|
3460
3518
|
},
|
|
3461
|
-
{
|
|
3519
|
+
{ isCustom: false, uiPermissions: { ...emptyUiPermissions, groups: {}, releases: {} } }
|
|
3462
3520
|
);
|
|
3463
|
-
return
|
|
3464
|
-
}
|
|
3465
|
-
var
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3521
|
+
return permissions.reduce(customPermissionHandler, preliminaryResult);
|
|
3522
|
+
};
|
|
3523
|
+
var normalizeRbacRoles = (roles, rolesById2, permissionSets) => roles.reduce(
|
|
3524
|
+
(accu, role) => {
|
|
3525
|
+
let normalizedPermissions;
|
|
3526
|
+
let isCustom = false;
|
|
3527
|
+
if (rolesById2[role.name]) {
|
|
3528
|
+
normalizedPermissions = {
|
|
3529
|
+
...rolesById2[role.name].uiPermissions,
|
|
3530
|
+
groups: { ...rolesById2[role.name].uiPermissions.groups },
|
|
3531
|
+
releases: { ...rolesById2[role.name].uiPermissions.releases }
|
|
3532
|
+
};
|
|
3533
|
+
} else {
|
|
3534
|
+
const result = parseRolePermissions(role, permissionSets);
|
|
3535
|
+
normalizedPermissions = result.uiPermissions;
|
|
3536
|
+
isCustom = result.isCustom;
|
|
3476
3537
|
}
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3538
|
+
const roleState = accu[role.name] ?? { ...emptyRole };
|
|
3539
|
+
accu[role.name] = {
|
|
3540
|
+
...roleState,
|
|
3541
|
+
...role,
|
|
3542
|
+
description: roleState.description ? roleState.description : role.description,
|
|
3543
|
+
editable: !rolesById[role.name] && !isCustom && (typeof roleState.editable !== "undefined" ? roleState.editable : true),
|
|
3544
|
+
isCustom,
|
|
3545
|
+
name: roleState.name ? roleState.name : role.name,
|
|
3546
|
+
uiPermissions: normalizedPermissions
|
|
3547
|
+
};
|
|
3548
|
+
return accu;
|
|
3549
|
+
},
|
|
3550
|
+
{ ...rolesById2 }
|
|
3483
3551
|
);
|
|
3484
|
-
var
|
|
3485
|
-
`${
|
|
3486
|
-
(_, { dispatch }) => general_api_default.get(`${
|
|
3552
|
+
var getPermissionSets = (0, import_toolkit20.createAsyncThunk)(
|
|
3553
|
+
`${sliceName8}/getPermissionSets`,
|
|
3554
|
+
(_, { dispatch, getState }) => general_api_default.get(`${useradmApiUrlv2}/permission_sets?per_page=500`).then(({ data }) => {
|
|
3555
|
+
const permissionSets = data.reduce(
|
|
3556
|
+
(accu, permissionSet) => {
|
|
3557
|
+
const permissionSetState = accu[permissionSet.name] ?? {};
|
|
3558
|
+
let permissionSetObject = { ...permissionSetState, ...permissionSet };
|
|
3559
|
+
permissionSetObject.result = Object.values(uiPermissionsById).reduce(
|
|
3560
|
+
(accu2, item) => Object.entries(item.permissionSets).reduce((collector, [area, permissionSet2]) => {
|
|
3561
|
+
if (scopedPermissionAreas[area]) {
|
|
3562
|
+
return collector;
|
|
3563
|
+
}
|
|
3564
|
+
if (permissionSet2 === permissionSetObject.name) {
|
|
3565
|
+
collector[area] = [...collector[area], item.value].filter(import_helpers9.duplicateFilter);
|
|
3566
|
+
}
|
|
3567
|
+
return collector;
|
|
3568
|
+
}, accu2),
|
|
3569
|
+
{ ...emptyUiPermissions, ...permissionSetObject.result ?? {} }
|
|
3570
|
+
);
|
|
3571
|
+
const scopes = Object.values(scopedPermissionAreas).reduce((accu2, { key, scopeType }) => {
|
|
3572
|
+
if (permissionSetObject.supported_scope_types?.includes(key) || permissionSetObject.supported_scope_types?.includes(scopeType)) {
|
|
3573
|
+
accu2.push(key);
|
|
3574
|
+
}
|
|
3575
|
+
return accu2;
|
|
3576
|
+
}, []);
|
|
3577
|
+
permissionSetObject = scopes.reduce((accu2, scope) => {
|
|
3578
|
+
accu2.result[scope] = mapPermissionSet(permissionSetObject.name, [scopedPermissionAreas[scope].excessiveAccessSelector], scope);
|
|
3579
|
+
return accu2;
|
|
3580
|
+
}, permissionSetObject);
|
|
3581
|
+
accu[permissionSet.name] = permissionSetObject;
|
|
3582
|
+
return accu;
|
|
3583
|
+
},
|
|
3584
|
+
{ ...getState().users.permissionSetsById }
|
|
3585
|
+
);
|
|
3586
|
+
return Promise.all([dispatch(actions8.receivedPermissionSets(permissionSets)), permissionSets]);
|
|
3587
|
+
}).catch(() => console.log("Permission set retrieval failed - likely accessing a non-RBAC backend"))
|
|
3487
3588
|
);
|
|
3488
|
-
var
|
|
3489
|
-
`${
|
|
3490
|
-
({
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
let nextState = {
|
|
3494
|
-
...currentState,
|
|
3495
|
-
setOnly: false,
|
|
3496
|
-
refreshTrigger,
|
|
3497
|
-
...selectionState,
|
|
3498
|
-
sort: { ...currentState.sort, ...selectionState.sort }
|
|
3499
|
-
};
|
|
3500
|
-
let tasks = [];
|
|
3501
|
-
const { isLoading: currentLoading, deviceIds: currentDevices, selection: currentSelection, ...currentRequestState } = currentState;
|
|
3502
|
-
const { isLoading: nextLoading, deviceIds: nextDevices, selection: nextSelection, ...nextRequestState } = nextState;
|
|
3503
|
-
if (!nextState.setOnly && !(0, import_helpers9.deepCompare)(currentRequestState, nextRequestState)) {
|
|
3504
|
-
const { direction: sortDown = SORTING_OPTIONS.desc, key: sortCol, scope: sortScope } = nextState.sort ?? {};
|
|
3505
|
-
const sortBy = sortCol ? [{ attribute: sortCol, order: sortDown, scope: sortScope }] : void 0;
|
|
3506
|
-
const applicableSelectedState = nextState.state === ALL_DEVICE_STATES ? void 0 : nextState.state;
|
|
3507
|
-
nextState.isLoading = true;
|
|
3508
|
-
tasks.push(
|
|
3509
|
-
dispatch(getDevicesByStatus2({ ...nextState, status: applicableSelectedState, sortOptions: sortBy, fetchAuth })).unwrap().then((results) => {
|
|
3510
|
-
const { deviceAccu, total } = results[results.length - 1];
|
|
3511
|
-
const devicesState = shouldSelectDevices ? { deviceIds: deviceAccu.ids, total, isLoading: false } : { isLoading: false };
|
|
3512
|
-
return Promise.resolve(dispatch(actions3.setDeviceListState(devicesState)));
|
|
3513
|
-
}).catch(() => Promise.resolve({ isLoading: false }))
|
|
3514
|
-
);
|
|
3589
|
+
var getRoles = (0, import_toolkit20.createAsyncThunk)(
|
|
3590
|
+
`${sliceName8}/getRoles`,
|
|
3591
|
+
(_, { dispatch, getState }) => Promise.all([general_api_default.get(`${useradmApiUrlv2}/roles?per_page=500`), dispatch(getPermissionSets())]).then((results) => {
|
|
3592
|
+
if (!results) {
|
|
3593
|
+
return Promise.resolve();
|
|
3515
3594
|
}
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3595
|
+
const [{ data: roles }, { payload: permissionSetTasks }] = results;
|
|
3596
|
+
const rolesById2 = normalizeRbacRoles(roles, getRolesById(getState()), permissionSetTasks[permissionSetTasks.length - 1]);
|
|
3597
|
+
return Promise.resolve(dispatch(actions8.receivedRoles(rolesById2)));
|
|
3598
|
+
}).catch(() => console.log("Role retrieval failed - likely accessing a non-RBAC backend"))
|
|
3519
3599
|
);
|
|
3520
|
-
var
|
|
3521
|
-
const
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
perPage = defaultPerPage2,
|
|
3529
|
-
sortOptions = [],
|
|
3530
|
-
selectedAttributes = []
|
|
3531
|
-
} = options;
|
|
3532
|
-
const state = getState();
|
|
3533
|
-
const { applicableFilters, filterTerms } = convertDeviceListStateToFilters({
|
|
3534
|
-
filters: filterSelection ?? getDeviceFilters(state),
|
|
3535
|
-
group: group ?? getSelectedGroup(state),
|
|
3536
|
-
groups: state.devices.groups,
|
|
3537
|
-
offlineThreshold: state.app.offlineThreshold,
|
|
3538
|
-
selectedIssues,
|
|
3539
|
-
status
|
|
3540
|
-
});
|
|
3541
|
-
const attributes = [...defaultAttributes, getIdAttribute(getState()), ...selectedAttributes];
|
|
3542
|
-
return general_api_default.post(getSearchEndpoint(getState()), {
|
|
3543
|
-
page,
|
|
3544
|
-
per_page: perPage,
|
|
3545
|
-
filters: filterTerms,
|
|
3546
|
-
sort: sortOptions,
|
|
3547
|
-
attributes
|
|
3548
|
-
}).then((response) => {
|
|
3549
|
-
const state2 = getState();
|
|
3550
|
-
const deviceAccu = reduceReceivedDevices(response.data, [], state2, status);
|
|
3551
|
-
let total = !applicableFilters.length ? Number(response.headers[headerNames.total]) : null;
|
|
3552
|
-
if (status && state2.devices.byStatus[status].total === deviceAccu.ids.length) {
|
|
3553
|
-
total = deviceAccu.ids.length;
|
|
3554
|
-
}
|
|
3555
|
-
let tasks = [dispatch(actions3.receivedDevices(deviceAccu.devicesById))];
|
|
3556
|
-
if (status) {
|
|
3557
|
-
tasks.push(dispatch(actions3.setDevicesByStatus({ deviceIds: deviceAccu.ids, status, total })));
|
|
3558
|
-
}
|
|
3559
|
-
const receivedDevices = Object.values(deviceAccu.devicesById);
|
|
3560
|
-
if (receivedDevices.length && fetchAuth) {
|
|
3561
|
-
tasks.push(dispatch(getDevicesWithAuth(receivedDevices)));
|
|
3562
|
-
}
|
|
3563
|
-
tasks.push(Promise.resolve({ deviceAccu, total: Number(response.headers[headerNames.total]) }));
|
|
3564
|
-
return Promise.all(tasks);
|
|
3565
|
-
}).catch((err) => commonErrorHandler(err, `${status} devices couldn't be loaded.`, dispatch, commonErrorFallback));
|
|
3566
|
-
});
|
|
3567
|
-
var getAllDevicesByStatus = (0, import_toolkit19.createAsyncThunk)(`${sliceName3}/getAllDevicesByStatus`, (status, { dispatch, getState }) => {
|
|
3568
|
-
const attributes = [...defaultAttributes, getIdAttribute(getState())];
|
|
3569
|
-
const getAllDevices = (perPage = MAX_PAGE_SIZE, page = 1, devices = []) => general_api_default.post(getSearchEndpoint(getState()), {
|
|
3570
|
-
page,
|
|
3571
|
-
per_page: perPage,
|
|
3572
|
-
filters: mapFiltersToTerms([{ key: "status", value: status, operator: DEVICE_FILTERING_OPTIONS.$eq.key, scope: "identity" }]),
|
|
3573
|
-
attributes
|
|
3574
|
-
}).then((res) => {
|
|
3575
|
-
const state = getState();
|
|
3576
|
-
const deviceAccu = reduceReceivedDevices(res.data, devices, state, status);
|
|
3577
|
-
dispatch(actions3.receivedDevices(deviceAccu.devicesById));
|
|
3578
|
-
const total = Number(res.headers[headerNames.total]);
|
|
3579
|
-
if (total > state.deployments.deploymentDeviceLimit) {
|
|
3580
|
-
return Promise.resolve();
|
|
3581
|
-
}
|
|
3582
|
-
if (total > perPage * page) {
|
|
3583
|
-
return getAllDevices(perPage, page + 1, deviceAccu.ids);
|
|
3600
|
+
var deriveImpliedAreaPermissions = (area, areaPermissions, skipPermissions = []) => {
|
|
3601
|
+
const highestAreaPermissionLevelSelected = areaPermissions.reduce(
|
|
3602
|
+
(highest, current) => uiPermissionsById[current].permissionLevel > highest ? uiPermissionsById[current].permissionLevel : highest,
|
|
3603
|
+
1
|
|
3604
|
+
);
|
|
3605
|
+
return uiPermissionsByArea[area].uiPermissions.reduce((permissions, current) => {
|
|
3606
|
+
if ((current.permissionLevel < highestAreaPermissionLevelSelected || areaPermissions.includes(current.value)) && !skipPermissions.includes(current.value)) {
|
|
3607
|
+
permissions.push(current.value);
|
|
3584
3608
|
}
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3609
|
+
return permissions;
|
|
3610
|
+
}, []);
|
|
3611
|
+
};
|
|
3612
|
+
var transformAreaRoleDataToScopedPermissionsSets = (area, areaPermissions, excessiveAccessSelector) => {
|
|
3613
|
+
const permissionSetObject = areaPermissions.reduce((accu, { item, uiPermissions }) => {
|
|
3614
|
+
const skipPermissions = scopedPermissionAreas.releases.key === area && item !== ALL_RELEASES ? [uiPermissionsById.upload.value] : [];
|
|
3615
|
+
const impliedPermissions = deriveImpliedAreaPermissions(area, uiPermissions, skipPermissions);
|
|
3616
|
+
accu = impliedPermissions.reduce((itemPermissionAccu, impliedPermission) => {
|
|
3617
|
+
const permissionSetState = itemPermissionAccu[uiPermissionsById[impliedPermission].permissionSets[area]] ?? {
|
|
3618
|
+
type: uiPermissionsByArea[area].scope,
|
|
3619
|
+
value: []
|
|
3620
|
+
};
|
|
3621
|
+
itemPermissionAccu[uiPermissionsById[impliedPermission].permissionSets[area]] = {
|
|
3622
|
+
...permissionSetState,
|
|
3623
|
+
value: [...permissionSetState.value, item]
|
|
3624
|
+
};
|
|
3625
|
+
return itemPermissionAccu;
|
|
3626
|
+
}, accu);
|
|
3627
|
+
return accu;
|
|
3628
|
+
}, {});
|
|
3629
|
+
return Object.entries(permissionSetObject).map(([name, { value, ...scope }]) => {
|
|
3630
|
+
if (value.includes(excessiveAccessSelector)) {
|
|
3631
|
+
return { name };
|
|
3589
3632
|
}
|
|
3590
|
-
return
|
|
3633
|
+
return { name, scope: { ...scope, value: value.filter(import_helpers9.duplicateFilter) } };
|
|
3591
3634
|
});
|
|
3592
|
-
|
|
3593
|
-
})
|
|
3594
|
-
|
|
3595
|
-
const
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
});
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3635
|
+
};
|
|
3636
|
+
var transformRoleDataToRole = (roleData, roleState = {}) => {
|
|
3637
|
+
const role = { ...roleState, ...roleData };
|
|
3638
|
+
const { description = "", name, uiPermissions = emptyUiPermissions } = role;
|
|
3639
|
+
const { maybeUiPermissions, remainderKeys } = Object.entries(emptyUiPermissions).reduce(
|
|
3640
|
+
(accu, [key, emptyPermissions]) => {
|
|
3641
|
+
if (!scopedPermissionAreas[key]) {
|
|
3642
|
+
accu.remainderKeys.push(key);
|
|
3643
|
+
} else if (uiPermissions[key]) {
|
|
3644
|
+
accu.maybeUiPermissions[key] = uiPermissions[key].reduce(itemUiPermissionsReducer, emptyPermissions);
|
|
3645
|
+
}
|
|
3646
|
+
return accu;
|
|
3647
|
+
},
|
|
3648
|
+
{ maybeUiPermissions: {}, remainderKeys: [] }
|
|
3649
|
+
);
|
|
3650
|
+
const { permissionSetsWithScope, roleUiPermissions } = remainderKeys.reduce(
|
|
3651
|
+
(accu, area) => {
|
|
3652
|
+
const areaPermissions = role.uiPermissions[area];
|
|
3653
|
+
if (!Array.isArray(areaPermissions)) {
|
|
3654
|
+
return accu;
|
|
3655
|
+
}
|
|
3656
|
+
const impliedPermissions = deriveImpliedAreaPermissions(area, areaPermissions);
|
|
3657
|
+
accu.roleUiPermissions[area] = impliedPermissions;
|
|
3658
|
+
const mappedPermissions = impliedPermissions.map((uiPermission) => ({ name: uiPermissionsById[uiPermission].permissionSets[area] }));
|
|
3659
|
+
accu.permissionSetsWithScope.push(...mappedPermissions);
|
|
3660
|
+
return accu;
|
|
3661
|
+
},
|
|
3662
|
+
{ permissionSetsWithScope: [{ name: defaultPermissionSets.Basic.name }], roleUiPermissions: {} }
|
|
3663
|
+
);
|
|
3664
|
+
const scopedPermissionSets = Object.values(scopedPermissionAreas).reduce((accu, { key, excessiveAccessSelector }) => {
|
|
3665
|
+
if (!uiPermissions[key]) {
|
|
3666
|
+
return accu;
|
|
3621
3667
|
}
|
|
3622
|
-
accu
|
|
3668
|
+
accu.push(...transformAreaRoleDataToScopedPermissionsSets(key, uiPermissions[key], excessiveAccessSelector));
|
|
3623
3669
|
return accu;
|
|
3670
|
+
}, []);
|
|
3671
|
+
return {
|
|
3672
|
+
permissionSetsWithScope: [...permissionSetsWithScope, ...scopedPermissionSets],
|
|
3673
|
+
role: {
|
|
3674
|
+
...emptyRole,
|
|
3675
|
+
name,
|
|
3676
|
+
description: description ? description : roleState.description,
|
|
3677
|
+
uiPermissions: {
|
|
3678
|
+
...emptyUiPermissions,
|
|
3679
|
+
...roleUiPermissions,
|
|
3680
|
+
...maybeUiPermissions
|
|
3681
|
+
}
|
|
3682
|
+
}
|
|
3683
|
+
};
|
|
3684
|
+
};
|
|
3685
|
+
var roleActions = {
|
|
3686
|
+
create: {
|
|
3687
|
+
successMessage: "The role was created successfully.",
|
|
3688
|
+
errorMessage: "creating"
|
|
3624
3689
|
},
|
|
3625
|
-
|
|
3690
|
+
edit: {
|
|
3691
|
+
successMessage: "The role has been updated.",
|
|
3692
|
+
errorMessage: "editing"
|
|
3693
|
+
},
|
|
3694
|
+
remove: {
|
|
3695
|
+
successMessage: "The role was deleted successfully.",
|
|
3696
|
+
errorMessage: "removing"
|
|
3697
|
+
}
|
|
3698
|
+
};
|
|
3699
|
+
var roleActionErrorHandler = (err, type, dispatch) => commonErrorHandler(err, `There was an error ${roleActions[type].errorMessage} the role.`, dispatch);
|
|
3700
|
+
var createRole = (0, import_toolkit20.createAsyncThunk)(`${sliceName8}/createRole`, (roleData, { dispatch }) => {
|
|
3701
|
+
const { permissionSetsWithScope, role } = transformRoleDataToRole(roleData);
|
|
3702
|
+
return general_api_default.post(`${useradmApiUrlv2}/roles`, {
|
|
3703
|
+
name: role.name,
|
|
3704
|
+
description: role.description,
|
|
3705
|
+
permission_sets_with_scope: permissionSetsWithScope
|
|
3706
|
+
}).then(() => Promise.all([dispatch(actions8.createdRole(role)), dispatch(getRoles()), dispatch(setSnackbar3(roleActions.create.successMessage))])).catch((err) => roleActionErrorHandler(err, "create", dispatch));
|
|
3707
|
+
});
|
|
3708
|
+
var editRole = (0, import_toolkit20.createAsyncThunk)(`${sliceName8}/editRole`, (roleData, { dispatch, getState }) => {
|
|
3709
|
+
const { permissionSetsWithScope, role } = transformRoleDataToRole(roleData, getRolesById(getState())[roleData.name]);
|
|
3710
|
+
return general_api_default.put(`${useradmApiUrlv2}/roles/${role.name}`, {
|
|
3711
|
+
description: role.description,
|
|
3712
|
+
name: role.name,
|
|
3713
|
+
permission_sets_with_scope: permissionSetsWithScope
|
|
3714
|
+
}).then(() => Promise.all([dispatch(actions8.createdRole(role)), dispatch(getRoles()), dispatch(setSnackbar3(roleActions.edit.successMessage))])).catch((err) => roleActionErrorHandler(err, "edit", dispatch));
|
|
3715
|
+
});
|
|
3716
|
+
var removeRole = (0, import_toolkit20.createAsyncThunk)(
|
|
3717
|
+
`${sliceName8}/removeRole`,
|
|
3718
|
+
(roleId, { dispatch }) => general_api_default.delete(`${useradmApiUrlv2}/roles/${roleId}`).then(() => Promise.all([dispatch(actions8.removedRole(roleId)), dispatch(getRoles()), dispatch(setSnackbar3(roleActions.remove.successMessage))])).catch((err) => roleActionErrorHandler(err, "remove", dispatch))
|
|
3626
3719
|
);
|
|
3627
|
-
var
|
|
3628
|
-
`${
|
|
3629
|
-
(_, { dispatch
|
|
3630
|
-
|
|
3631
|
-
return dispatch(
|
|
3720
|
+
var getGlobalSettings2 = (0, import_toolkit20.createAsyncThunk)(
|
|
3721
|
+
`${sliceName8}/getGlobalSettings`,
|
|
3722
|
+
(_, { dispatch }) => general_api_default.get(`${useradmApiUrlv1}/settings`).then(({ data: settings, headers: { etag } }) => {
|
|
3723
|
+
window.sessionStorage.setItem(settingsKeys.initialized, true);
|
|
3724
|
+
return Promise.all([dispatch(actions8.setGlobalSettings(settings)), dispatch(setOfflineThreshold()), etag]);
|
|
3632
3725
|
})
|
|
3633
3726
|
);
|
|
3634
|
-
var
|
|
3635
|
-
`${
|
|
3636
|
-
(
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3727
|
+
var saveGlobalSettings = (0, import_toolkit20.createAsyncThunk)(
|
|
3728
|
+
`${sliceName8}/saveGlobalSettings`,
|
|
3729
|
+
({ beOptimistic = false, notify = false, ...settings }, { dispatch, getState }) => {
|
|
3730
|
+
if (!window.sessionStorage.getItem(settingsKeys.initialized) && !beOptimistic) {
|
|
3731
|
+
return;
|
|
3732
|
+
}
|
|
3733
|
+
return dispatch(getGlobalSettings2()).unwrap().then((result) => {
|
|
3734
|
+
let updatedSettings = { ...getState().users.globalSettings, ...settings };
|
|
3735
|
+
if (getCurrentUser(getState()).verified) {
|
|
3736
|
+
updatedSettings["2fa"] = twoFAStates.enabled;
|
|
3737
|
+
} else {
|
|
3738
|
+
delete updatedSettings["2fa"];
|
|
3739
|
+
}
|
|
3740
|
+
let tasks = [dispatch(actions8.setGlobalSettings(updatedSettings))];
|
|
3741
|
+
const headers = result[result.length - 1] ? { "If-Match": result[result.length - 1] } : {};
|
|
3742
|
+
return general_api_default.post(`${useradmApiUrlv1}/settings`, updatedSettings, { headers }).then(() => {
|
|
3743
|
+
if (notify) {
|
|
3744
|
+
tasks.push(dispatch(setSnackbar3("Settings saved successfully")));
|
|
3745
|
+
}
|
|
3746
|
+
return Promise.all(tasks);
|
|
3747
|
+
}).catch((err) => {
|
|
3748
|
+
if (beOptimistic) {
|
|
3749
|
+
return Promise.all([tasks]);
|
|
3750
|
+
}
|
|
3751
|
+
console.log(err);
|
|
3752
|
+
return commonErrorHandler(err, `The settings couldn't be saved.`, dispatch);
|
|
3753
|
+
});
|
|
3754
|
+
});
|
|
3755
|
+
}
|
|
3756
|
+
);
|
|
3757
|
+
var getUserSettings2 = (0, import_toolkit20.createAsyncThunk)(
|
|
3758
|
+
`${sliceName8}/getUserSettings`,
|
|
3759
|
+
(_, { dispatch }) => general_api_default.get(`${useradmApiUrlv1}/settings/me`).then(({ data: settings, headers: { etag } }) => {
|
|
3760
|
+
window.sessionStorage.setItem(settingsKeys.initialized, true);
|
|
3761
|
+
return Promise.all([dispatch(actions8.setUserSettings(settings)), etag]);
|
|
3640
3762
|
})
|
|
3641
3763
|
);
|
|
3642
|
-
var
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
const { attribute, group, software = "" } = reportConfig;
|
|
3646
|
-
const filters = [{ key: "status", scope: "identity", operator: DEVICE_FILTERING_OPTIONS.$eq.key, value: "accepted" }];
|
|
3647
|
-
if (group) {
|
|
3648
|
-
const staticGroupFilter = { key: "group", scope: "system", operator: DEVICE_FILTERING_OPTIONS.$eq.key, value: group };
|
|
3649
|
-
const { cleanedFilters: groupFilters } = getGroupFilters(group, groups);
|
|
3650
|
-
filters.push(...groupFilters.length ? groupFilters : [staticGroupFilter]);
|
|
3764
|
+
var saveUserSettings = (0, import_toolkit20.createAsyncThunk)(`${sliceName8}/saveUserSettings`, (settings = { onboarding: {} }, { dispatch, getState }) => {
|
|
3765
|
+
if (!getCurrentUser(getState()).id) {
|
|
3766
|
+
return Promise.resolve();
|
|
3651
3767
|
}
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
const
|
|
3666
|
-
let { items, other_count } = data[0];
|
|
3667
|
-
const { attribute, group, software = "" } = reportConfig;
|
|
3668
|
-
const dataCount = items.reduce((accu, item) => accu + item.count, 0);
|
|
3669
|
-
const otherCount = !group && (software === rootfsImageVersion || attribute === "artifact_name") ? totalDeviceCount - dataCount : other_count;
|
|
3670
|
-
return { items, otherCount, total: otherCount + dataCount };
|
|
3671
|
-
});
|
|
3672
|
-
return Promise.resolve(dispatch(actions3.setDeviceReports(newReports)));
|
|
3673
|
-
});
|
|
3674
|
-
});
|
|
3675
|
-
var initializeDistributionData = (report, groups, devices, totalDeviceCount) => {
|
|
3676
|
-
const { attribute, group = "", software = "" } = report;
|
|
3677
|
-
const effectiveAttribute = software ? software : attribute;
|
|
3678
|
-
const { deviceIds, total = 0 } = groups[group] || {};
|
|
3679
|
-
const relevantDevices = groups[group] ? deviceIds.map((id) => devices[id]) : Object.values(devices);
|
|
3680
|
-
const distributionByAttribute = relevantDevices.reduce((accu, item) => {
|
|
3681
|
-
if (!item.attributes || item.status !== DEVICE_STATES.accepted) return accu;
|
|
3682
|
-
if (!accu[item.attributes[effectiveAttribute]]) {
|
|
3683
|
-
accu[item.attributes[effectiveAttribute]] = 0;
|
|
3684
|
-
}
|
|
3685
|
-
accu[item.attributes[effectiveAttribute]] = accu[item.attributes[effectiveAttribute]] + 1;
|
|
3686
|
-
return accu;
|
|
3687
|
-
}, {});
|
|
3688
|
-
const distributionByAttributeSorted = Object.entries(distributionByAttribute).sort((pairA, pairB) => pairB[1] - pairA[1]);
|
|
3689
|
-
const items = distributionByAttributeSorted.map(([key, count]) => ({ key, count }));
|
|
3690
|
-
const dataCount = items.reduce((accu, item) => accu + item.count, 0);
|
|
3691
|
-
const otherCount = (groups[group] ? total : totalDeviceCount) - dataCount;
|
|
3692
|
-
return { items, otherCount, total: otherCount + dataCount };
|
|
3693
|
-
};
|
|
3694
|
-
var deriveReportsData = (0, import_toolkit19.createAsyncThunk)(`${sliceName3}/deriveReportsData`, (_, { dispatch, getState }) => {
|
|
3695
|
-
const state = getState();
|
|
3696
|
-
const {
|
|
3697
|
-
groups: { byId: groupsById },
|
|
3698
|
-
byId,
|
|
3699
|
-
byStatus: {
|
|
3700
|
-
accepted: { total }
|
|
3701
|
-
}
|
|
3702
|
-
} = state.devices;
|
|
3703
|
-
const reports = getUserSettings(state).reports || state.users.globalSettings[`${state.users.currentUser}-reports`] || (Object.keys(byId).length ? defaultReports : []);
|
|
3704
|
-
const newReports = reports.map((report) => initializeDistributionData(report, groupsById, byId, total));
|
|
3705
|
-
return Promise.resolve(dispatch(actions3.setDeviceReports(newReports)));
|
|
3706
|
-
});
|
|
3707
|
-
var getReportsDataWithoutBackendSupport = (0, import_toolkit19.createAsyncThunk)(
|
|
3708
|
-
`${sliceName3}/getReportsDataWithoutBackendSupport`,
|
|
3709
|
-
(_, { dispatch, getState }) => Promise.all([dispatch(getAllDevicesByStatus(DEVICE_STATES.accepted)), dispatch(getGroups2()), dispatch(getDynamicGroups())]).then(() => {
|
|
3710
|
-
const { dynamic: dynamicGroups, static: staticGroups } = getGroups(getState());
|
|
3768
|
+
return dispatch(getUserSettings2()).unwrap().then((result) => {
|
|
3769
|
+
const userSettings = getUserSettings(getState());
|
|
3770
|
+
const onboardingState = getOnboardingState(getState());
|
|
3771
|
+
const tooltipState = getTooltipsState(getState());
|
|
3772
|
+
const updatedSettings = {
|
|
3773
|
+
...userSettings,
|
|
3774
|
+
...settings,
|
|
3775
|
+
onboarding: {
|
|
3776
|
+
...onboardingState,
|
|
3777
|
+
...settings.onboarding
|
|
3778
|
+
},
|
|
3779
|
+
tooltips: tooltipState
|
|
3780
|
+
};
|
|
3781
|
+
const headers = result[result.length - 1] ? { "If-Match": result[result.length - 1] } : {};
|
|
3711
3782
|
return Promise.all([
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
]).
|
|
3715
|
-
})
|
|
3716
|
-
);
|
|
3717
|
-
var getDeviceConnect = (0, import_toolkit19.createAsyncThunk)(
|
|
3718
|
-
`${sliceName3}/getDeviceConnect`,
|
|
3719
|
-
(id, { dispatch }) => general_api_default.get(`${deviceConnect}/devices/${id}`).then(
|
|
3720
|
-
({ data }) => Promise.all([dispatch(actions3.receivedDevice({ connect_status: data.status, connect_updated_ts: data.updated_ts, id })), Promise.resolve(data)])
|
|
3721
|
-
)
|
|
3722
|
-
);
|
|
3723
|
-
var getSessionDetails = (0, import_toolkit19.createAsyncThunk)(`${sliceName3}/getSessionDetails`, ({ sessionId, deviceId, userId, startDate, endDate }) => {
|
|
3724
|
-
const { start: startUnix, end: endUnix } = (0, import_helpers9.dateRangeToUnix)(startDate, endDate);
|
|
3725
|
-
const createdAfter = startDate ? `&created_after=${startUnix}` : "";
|
|
3726
|
-
const createdBefore = endDate ? `&created_before=${endUnix}` : "";
|
|
3727
|
-
const objectSearch = `&object_id=${deviceId}`;
|
|
3728
|
-
return general_api_default.get(`${auditLogsApiUrl}/logs?per_page=500${createdAfter}${createdBefore}&actor_id=${userId}${objectSearch}`).then(
|
|
3729
|
-
({ data: auditLogEntries }) => {
|
|
3730
|
-
const { start, end } = auditLogEntries.reduce(
|
|
3731
|
-
(accu, item) => {
|
|
3732
|
-
if (item.meta?.session_id?.includes(sessionId)) {
|
|
3733
|
-
accu.start = new Date(item.action.startsWith("open") ? item.time : accu.start);
|
|
3734
|
-
accu.end = new Date(item.action.startsWith("close") ? item.time : accu.end);
|
|
3735
|
-
}
|
|
3736
|
-
return accu;
|
|
3737
|
-
},
|
|
3738
|
-
{ start: startDate || endDate, end: endDate || startDate }
|
|
3739
|
-
);
|
|
3740
|
-
return Promise.resolve({ start, end });
|
|
3741
|
-
}
|
|
3742
|
-
);
|
|
3783
|
+
Promise.resolve(dispatch(actions8.setUserSettings(updatedSettings))),
|
|
3784
|
+
general_api_default.post(`${useradmApiUrlv1}/settings/me`, updatedSettings, { headers })
|
|
3785
|
+
]).catch(() => dispatch(actions8.setUserSettings(userSettings)));
|
|
3786
|
+
});
|
|
3743
3787
|
});
|
|
3744
|
-
var
|
|
3745
|
-
`${
|
|
3746
|
-
({
|
|
3788
|
+
var get2FAQRCode = (0, import_toolkit20.createAsyncThunk)(
|
|
3789
|
+
`${sliceName8}/get2FAQRCode`,
|
|
3790
|
+
(_, { dispatch }) => general_api_default.get(`${useradmApiUrlv1}/2faqr`).then((res) => dispatch(actions8.receivedQrCode(res.data.qr)))
|
|
3747
3791
|
);
|
|
3748
|
-
var
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
general_api_default.uploadPut(
|
|
3758
|
-
`${deviceConnect}/devices/${deviceId}/upload`,
|
|
3759
|
-
formData,
|
|
3760
|
-
(e) => dispatch(uploadProgress2({ id: uploadId, progress: progress(e) })),
|
|
3761
|
-
cancelSource.signal
|
|
3762
|
-
)
|
|
3763
|
-
]).then(() => Promise.resolve(dispatch(setSnackbar3("Upload successful", TIMEOUTS.fiveSeconds)))).catch((err) => {
|
|
3764
|
-
if ((0, import_axios2.isCancel)(err)) {
|
|
3765
|
-
return dispatch(setSnackbar3("The upload has been cancelled", TIMEOUTS.fiveSeconds));
|
|
3766
|
-
}
|
|
3767
|
-
return commonErrorHandler(err, `Error uploading file to device.`, dispatch);
|
|
3768
|
-
}).finally(() => dispatch(cleanUpUpload(uploadId)));
|
|
3792
|
+
var setHideAnnouncement = (0, import_toolkit20.createAsyncThunk)(`${sliceName8}/setHideAnnouncement`, ({ shouldHide, userId }, { dispatch, getState }) => {
|
|
3793
|
+
const currentUserId = userId || getCurrentUser(getState()).id;
|
|
3794
|
+
const hash = getState().app.hostedAnnouncement ? (0, import_md5.default)(getState().app.hostedAnnouncement) : "";
|
|
3795
|
+
const announceCookie = cookies3.get(`${currentUserId}${hash}`);
|
|
3796
|
+
if (shouldHide || hash.length && typeof announceCookie !== "undefined") {
|
|
3797
|
+
cookies3.set(`${currentUserId}${hash}`, true, { maxAge: 604800 });
|
|
3798
|
+
return Promise.resolve(dispatch(setAnnouncement()));
|
|
3799
|
+
}
|
|
3800
|
+
return Promise.resolve();
|
|
3769
3801
|
});
|
|
3770
|
-
var
|
|
3771
|
-
`${
|
|
3772
|
-
(
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3802
|
+
var getTokens = (0, import_toolkit20.createAsyncThunk)(
|
|
3803
|
+
`${sliceName8}/getTokens`,
|
|
3804
|
+
(_, { dispatch, getState }) => general_api_default.get(`${useradmApiUrlv1}/settings/tokens`).then(({ data: tokens }) => {
|
|
3805
|
+
const user = getCurrentUser(getState());
|
|
3806
|
+
const updatedUser = {
|
|
3807
|
+
...user,
|
|
3808
|
+
tokens
|
|
3809
|
+
};
|
|
3810
|
+
return Promise.resolve(dispatch(actions8.updatedUser(updatedUser)));
|
|
3777
3811
|
})
|
|
3778
3812
|
);
|
|
3779
|
-
var
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
return Promise.all([dispatch(actions3.receivedDevices(devicesById)), Promise.resolve(receivedDevices)]);
|
|
3784
|
-
}).catch((err) => commonErrorHandler(err, `Error: ${err}`, dispatch)) : Promise.resolve([[], []])
|
|
3813
|
+
var ONE_YEAR = 31536e3;
|
|
3814
|
+
var generateToken = (0, import_toolkit20.createAsyncThunk)(
|
|
3815
|
+
`${sliceName8}/generateToken`,
|
|
3816
|
+
({ expiresIn = ONE_YEAR, name }, { dispatch }) => general_api_default.post(`${useradmApiUrlv1}/settings/tokens`, { name, expires_in: expiresIn }).then(({ data: token }) => Promise.all([dispatch(getTokens()), token])).catch((err) => commonErrorHandler(err, "There was an error creating the token:", dispatch))
|
|
3785
3817
|
);
|
|
3786
|
-
var
|
|
3787
|
-
`${
|
|
3788
|
-
(
|
|
3818
|
+
var revokeToken = (0, import_toolkit20.createAsyncThunk)(
|
|
3819
|
+
`${sliceName8}/revokeToken`,
|
|
3820
|
+
(token, { dispatch }) => general_api_default.delete(`${useradmApiUrlv1}/settings/tokens/${token.id}`).then(() => Promise.resolve(dispatch(getTokens())))
|
|
3789
3821
|
);
|
|
3790
|
-
var
|
|
3791
|
-
let
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3822
|
+
var setTooltipReadState = (0, import_toolkit20.createAsyncThunk)(`${sliceName8}/setTooltipReadState`, ({ persist, ...remainder }, { dispatch }) => {
|
|
3823
|
+
let tasks = [dispatch(actions8.setTooltipState(remainder))];
|
|
3824
|
+
if (persist) {
|
|
3825
|
+
tasks.push(dispatch(saveUserSettings()));
|
|
3826
|
+
}
|
|
3827
|
+
return Promise.all(tasks);
|
|
3828
|
+
});
|
|
3829
|
+
var setAllTooltipsReadState = (0, import_toolkit20.createAsyncThunk)(`${sliceName8}/toggleHelptips`, (readState = READ_STATES.read, { dispatch }) => {
|
|
3830
|
+
const updatedTips = Object.keys(import_helptips.HELPTOOLTIPS).reduce((accu, id) => ({ ...accu, [id]: { readState } }), {});
|
|
3831
|
+
return Promise.resolve(dispatch(actions8.setTooltipsState(updatedTips))).then(() => dispatch(saveUserSettings()));
|
|
3832
|
+
});
|
|
3833
|
+
var submitFeedback = (0, import_toolkit20.createAsyncThunk)(
|
|
3834
|
+
`${sliceName8}/submitFeedback`,
|
|
3835
|
+
({ satisfaction, feedback, ...meta }, { dispatch }) => general_api_default.post(`${tenantadmApiUrlv2}/contact/support`, {
|
|
3836
|
+
subject: "feedback submission",
|
|
3837
|
+
body: JSON.stringify({ feedback, satisfaction, meta })
|
|
3838
|
+
}).then(() => {
|
|
3839
|
+
const today = /* @__PURE__ */ new Date();
|
|
3840
|
+
dispatch(saveUserSettings({ feedbackCollectedAt: today.toISOString().split("T")[0] }));
|
|
3841
|
+
setTimeout(() => dispatch(actions8.setShowFeedbackDialog(false)), TIMEOUTS.threeSeconds);
|
|
3842
|
+
})
|
|
3843
|
+
);
|
|
3844
|
+
|
|
3845
|
+
// src/devicesSlice/thunks.tsx
|
|
3846
|
+
var import_helpers10 = require("@northern.tech/utils/helpers");
|
|
3847
|
+
var import_toolkit21 = require("@reduxjs/toolkit");
|
|
3848
|
+
var import_axios3 = require("axios");
|
|
3849
|
+
var import_pluralize = __toESM(require("pluralize"), 1);
|
|
3850
|
+
var import_uuid = require("uuid");
|
|
3851
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
3852
|
+
var { cleanUpUpload, initUpload, setSnackbar: setSnackbar4, uploadProgress: uploadProgress2 } = actions_default;
|
|
3853
|
+
var { page: defaultPage3, perPage: defaultPerPage3 } = DEVICE_LIST_DEFAULTS;
|
|
3854
|
+
var defaultAttributes = [
|
|
3855
|
+
{ scope: "identity", attribute: "status" },
|
|
3856
|
+
{ scope: "inventory", attribute: "artifact_name" },
|
|
3857
|
+
{ scope: "inventory", attribute: "device_type" },
|
|
3858
|
+
{ scope: "inventory", attribute: "mender_is_gateway" },
|
|
3859
|
+
{ scope: "inventory", attribute: "mender_gateway_system_id" },
|
|
3860
|
+
{ scope: "inventory", attribute: rootfsImageVersion },
|
|
3861
|
+
{ scope: "monitor", attribute: "alerts" },
|
|
3862
|
+
{ scope: "system", attribute: "created_ts" },
|
|
3863
|
+
{ scope: "system", attribute: "updated_ts" },
|
|
3864
|
+
{ scope: "system", attribute: "check_in_time" },
|
|
3865
|
+
{ scope: "system", attribute: "group" },
|
|
3866
|
+
{ scope: "tags", attribute: "name" }
|
|
3867
|
+
];
|
|
3868
|
+
var getGroups2 = (0, import_toolkit21.createAsyncThunk)(
|
|
3869
|
+
`${sliceName3}/getGroups`,
|
|
3870
|
+
(_, { dispatch, getState }) => general_api_default.get(`${inventoryApiUrl}/groups`).then((res) => {
|
|
3871
|
+
const state = getGroupsById(getState());
|
|
3872
|
+
const dynamicGroups = Object.entries(state).reduce((accu, [id, group]) => {
|
|
3873
|
+
if (group.id || group.filters?.length && id !== UNGROUPED_GROUP.id) {
|
|
3874
|
+
accu[id] = group;
|
|
3799
3875
|
}
|
|
3800
|
-
return
|
|
3801
|
-
});
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3876
|
+
return accu;
|
|
3877
|
+
}, {});
|
|
3878
|
+
const groups = res.data.reduce((accu, group) => {
|
|
3879
|
+
accu[group] = { deviceIds: [], filters: [], total: 0, ...state[group] };
|
|
3880
|
+
return accu;
|
|
3881
|
+
}, dynamicGroups);
|
|
3882
|
+
const filters = [{ key: "group", value: res.data, operator: DEVICE_FILTERING_OPTIONS.$nin.key, scope: "system" }];
|
|
3883
|
+
return Promise.all([
|
|
3884
|
+
dispatch(actions3.receivedGroups(groups)),
|
|
3885
|
+
dispatch(getDevicesByStatus2({ filterSelection: filters, group: 0, page: 1, perPage: 1, status: void 0 }))
|
|
3886
|
+
]).then((promises) => {
|
|
3887
|
+
const devicesRetrieval = promises[promises.length - 1] || [];
|
|
3888
|
+
const { payload } = devicesRetrieval || {};
|
|
3889
|
+
const result = payload[payload.length - 1] || {};
|
|
3890
|
+
if (!result.total) {
|
|
3891
|
+
return Promise.resolve();
|
|
3892
|
+
}
|
|
3893
|
+
return Promise.resolve(
|
|
3894
|
+
dispatch(
|
|
3895
|
+
actions3.addGroup({
|
|
3896
|
+
groupName: UNGROUPED_GROUP.id,
|
|
3897
|
+
group: { filters: [{ key: "group", value: res.data, operator: DEVICE_FILTERING_OPTIONS.$nin.key, scope: "system" }] }
|
|
3898
|
+
})
|
|
3899
|
+
)
|
|
3813
3900
|
);
|
|
3814
|
-
const message = (0, import_helpers9.getSnackbarMessage)(skipped, count);
|
|
3815
|
-
return dispatch(setSnackbar3(message));
|
|
3816
3901
|
});
|
|
3817
|
-
});
|
|
3818
|
-
});
|
|
3819
|
-
var deleteAuthset = (0, import_toolkit19.createAsyncThunk)(
|
|
3820
|
-
`${sliceName3}/deleteAuthset`,
|
|
3821
|
-
({ deviceId, authId }, { dispatch, getState }) => general_api_default.delete(`${deviceAuthV2}/devices/${deviceId}/auth/${authId}`).then(() => Promise.all([dispatch(setSnackbar3("Device authorization status was updated successfully"))])).catch((err) => commonErrorHandler(err, "There was a problem updating the device authorization status:", dispatch)).then(() => Promise.resolve(dispatch(actions3.maybeUpdateDevicesByStatus({ deviceId, authId })))).finally(() => dispatch(setDeviceListState({ refreshTrigger: !getState().devices.deviceList.refreshTrigger })))
|
|
3822
|
-
);
|
|
3823
|
-
var preauthDevice = (0, import_toolkit19.createAsyncThunk)(
|
|
3824
|
-
`${sliceName3}/preauthDevice`,
|
|
3825
|
-
(authset, { dispatch }) => general_api_default.post(`${deviceAuthV2}/devices`, authset).catch((err) => {
|
|
3826
|
-
if (err.response.status === 409) {
|
|
3827
|
-
return Promise.reject("A device with a matching identity data set already exists");
|
|
3828
|
-
}
|
|
3829
|
-
return commonErrorHandler(err, "The device could not be added:", dispatch);
|
|
3830
|
-
}).then(() => Promise.resolve(dispatch(setSnackbar3("Device was successfully added to the preauthorization list", TIMEOUTS.fiveSeconds))))
|
|
3831
|
-
);
|
|
3832
|
-
var decommissionDevice = (0, import_toolkit19.createAsyncThunk)(
|
|
3833
|
-
`${sliceName3}/decommissionDevice`,
|
|
3834
|
-
({ deviceId, authId }, { dispatch, getState }) => general_api_default.delete(`${deviceAuthV2}/devices/${deviceId}`).then(() => Promise.resolve(dispatch(setSnackbar3("Device was decommissioned successfully")))).catch((err) => commonErrorHandler(err, "There was a problem decommissioning the device:", dispatch)).then(() => Promise.resolve(dispatch(actions3.maybeUpdateDevicesByStatus({ deviceId, authId })))).finally(() => dispatch(setDeviceListState({ refreshTrigger: !getState().devices.deviceList.refreshTrigger })))
|
|
3835
|
-
);
|
|
3836
|
-
var getDeviceConfig = (0, import_toolkit19.createAsyncThunk)(
|
|
3837
|
-
`${sliceName3}/getDeviceConfig`,
|
|
3838
|
-
(deviceId, { dispatch }) => general_api_default.get(`${deviceConfig}/${deviceId}`).then(({ data }) => Promise.all([dispatch(actions3.receivedDevice({ id: deviceId, config: data })), Promise.resolve(data)])).catch((err) => {
|
|
3839
|
-
if (err.response?.data?.error.status_code !== 404) {
|
|
3840
|
-
return commonErrorHandler(err, `There was an error retrieving the configuration for device ${deviceId}.`, dispatch, commonErrorFallback);
|
|
3841
|
-
}
|
|
3842
3902
|
})
|
|
3843
3903
|
);
|
|
3844
|
-
var
|
|
3845
|
-
`${sliceName3}/
|
|
3846
|
-
({
|
|
3904
|
+
var addDevicesToGroup = (0, import_toolkit21.createAsyncThunk)(
|
|
3905
|
+
`${sliceName3}/addDevicesToGroup`,
|
|
3906
|
+
({ group, deviceIds, isCreation }, { dispatch }) => general_api_default.patch(`${inventoryApiUrl}/groups/${group}/devices`, deviceIds).then(() => dispatch(actions3.addToGroup({ group, deviceIds }))).finally(() => isCreation ? Promise.resolve(dispatch(getGroups2())) : {})
|
|
3847
3907
|
);
|
|
3848
|
-
var
|
|
3849
|
-
`${sliceName3}/
|
|
3850
|
-
({
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
];
|
|
3857
|
-
if (isDefault && canManageUsers) {
|
|
3858
|
-
const { previous } = getGlobalSettings(getState()).defaultDeviceConfig ?? {};
|
|
3859
|
-
tasks.push(dispatch(saveGlobalSettings({ defaultDeviceConfig: { current: config, previous } })));
|
|
3860
|
-
}
|
|
3861
|
-
return Promise.all(tasks);
|
|
3862
|
-
})
|
|
3908
|
+
var removeDevicesFromGroup = (0, import_toolkit21.createAsyncThunk)(
|
|
3909
|
+
`${sliceName3}/removeDevicesFromGroup`,
|
|
3910
|
+
({ group, deviceIds }, { dispatch }) => general_api_default.delete(`${inventoryApiUrl}/groups/${group}/devices`, deviceIds).then(
|
|
3911
|
+
() => Promise.all([
|
|
3912
|
+
dispatch(actions3.removeFromGroup({ group, deviceIds })),
|
|
3913
|
+
dispatch(setSnackbar4(`The ${(0, import_pluralize.default)("devices", deviceIds.length)} ${(0, import_pluralize.default)("were", deviceIds.length)} removed from the group`, TIMEOUTS.fiveSeconds))
|
|
3914
|
+
])
|
|
3915
|
+
)
|
|
3863
3916
|
);
|
|
3864
|
-
var
|
|
3865
|
-
|
|
3866
|
-
(
|
|
3867
|
-
|
|
3868
|
-
Promise.resolve(dispatch(getDeviceById2(deviceId))).then((device) => {
|
|
3869
|
-
const headers = device.etag ? { "If-Match": device.etag } : {};
|
|
3870
|
-
return general_api_default.put(
|
|
3871
|
-
`${inventoryApiUrl}/devices/${deviceId}/tags`,
|
|
3872
|
-
Object.entries(tags).map(([name, value]) => ({ name, value })),
|
|
3873
|
-
{ headers }
|
|
3874
|
-
).catch((err) => commonErrorHandler(err, `There was an error setting tags for device ${deviceId}.`, dispatch, "Please check your connection.")).then(() => Promise.all([dispatch(actions3.receivedDevice({ ...device, id: deviceId, tags })), dispatch(setSnackbar3("Device name changed"))]));
|
|
3875
|
-
})
|
|
3876
|
-
)
|
|
3877
|
-
);
|
|
3878
|
-
var getDeviceTwin = (0, import_toolkit19.createAsyncThunk)(`${sliceName3}/getDeviceTwin`, ({ deviceId, integration }, { dispatch, getState }) => {
|
|
3879
|
-
let providerResult = {};
|
|
3880
|
-
return general_api_default.get(`${iotManagerBaseURL}/devices/${deviceId}/state`).then(({ data }) => {
|
|
3881
|
-
providerResult = { ...data, twinError: "" };
|
|
3882
|
-
}).catch((err) => {
|
|
3883
|
-
providerResult = {
|
|
3884
|
-
twinError: `There was an error getting the ${EXTERNAL_PROVIDER[integration.provider].twinTitle.toLowerCase()} for device ${deviceId}. ${err}`
|
|
3885
|
-
};
|
|
3886
|
-
}).finally(() => {
|
|
3887
|
-
const device = getDeviceById(getState(), deviceId);
|
|
3888
|
-
Promise.resolve(dispatch(actions3.receivedDevice({ ...device, twinsByIntegration: { ...device.twinsByIntegration, ...providerResult } })));
|
|
3889
|
-
});
|
|
3890
|
-
});
|
|
3891
|
-
var setDeviceTwin = (0, import_toolkit19.createAsyncThunk)(
|
|
3892
|
-
`${sliceName3}/setDeviceTwin`,
|
|
3893
|
-
({ deviceId, integration, settings }, { dispatch, getState }) => general_api_default.put(`${iotManagerBaseURL}/devices/${deviceId}/state/${integration.id}`, { desired: settings }).catch(
|
|
3894
|
-
(err) => commonErrorHandler(
|
|
3895
|
-
err,
|
|
3896
|
-
`There was an error updating the ${EXTERNAL_PROVIDER[integration.provider].twinTitle.toLowerCase()} for device ${deviceId}.`,
|
|
3897
|
-
dispatch
|
|
3898
|
-
)
|
|
3899
|
-
).then(() => {
|
|
3900
|
-
const device = getDeviceById(getState(), deviceId);
|
|
3901
|
-
const { twinsByIntegration = {} } = device;
|
|
3902
|
-
const { [integration.id]: currentState = {} } = twinsByIntegration;
|
|
3903
|
-
return Promise.resolve(
|
|
3904
|
-
dispatch(actions3.receivedDevice({ ...device, twinsByIntegration: { ...twinsByIntegration, [integration.id]: { ...currentState, desired: settings } } }))
|
|
3905
|
-
);
|
|
3906
|
-
})
|
|
3907
|
-
);
|
|
3908
|
-
var prepareSearchArguments = ({ filters, group, state, status }) => {
|
|
3909
|
-
const { filterTerms } = convertDeviceListStateToFilters({ filters, group, offlineThreshold: state.app.offlineThreshold, selectedIssues: [], status });
|
|
3910
|
-
const { columnSelection = [] } = getUserSettings(state);
|
|
3911
|
-
const selectedAttributes = columnSelection.map((column) => ({ attribute: column.key, scope: column.scope }));
|
|
3912
|
-
const attributes = [...defaultAttributes, getIdAttribute(state), ...selectedAttributes];
|
|
3913
|
-
return { attributes, filterTerms };
|
|
3914
|
-
};
|
|
3915
|
-
var getSystemDevices = (0, import_toolkit19.createAsyncThunk)(`${sliceName3}/getSystemDevices`, (options, { dispatch, getState }) => {
|
|
3916
|
-
const { id, page = defaultPage2, perPage = defaultPerPage2, sortOptions = [] } = options;
|
|
3917
|
-
const state = getState();
|
|
3918
|
-
const { hasFullFiltering } = getTenantCapabilities(state);
|
|
3919
|
-
if (!hasFullFiltering) {
|
|
3920
|
-
return Promise.resolve();
|
|
3917
|
+
var getGroupNotification = (newGroup, selectedGroup) => {
|
|
3918
|
+
const successMessage = "The group was updated successfully";
|
|
3919
|
+
if (newGroup === selectedGroup) {
|
|
3920
|
+
return [successMessage, TIMEOUTS.fiveSeconds];
|
|
3921
3921
|
}
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
attributes
|
|
3935
|
-
}).catch((err) => commonErrorHandler(err, `There was an error getting system devices device ${id}.`, dispatch, "Please check your connection.")).then(({ data, headers }) => {
|
|
3936
|
-
const state2 = getState();
|
|
3937
|
-
const { devicesById, ids } = reduceReceivedDevices(data, [], state2);
|
|
3938
|
-
const device = {
|
|
3939
|
-
...getDeviceById(state2, id),
|
|
3940
|
-
systemDeviceIds: ids,
|
|
3941
|
-
systemDeviceTotal: Number(headers[headerNames.total])
|
|
3942
|
-
};
|
|
3943
|
-
return Promise.resolve(dispatch(actions3.receivedDevices({ ...devicesById, [id]: device })));
|
|
3944
|
-
});
|
|
3945
|
-
});
|
|
3946
|
-
var getGatewayDevices = (0, import_toolkit19.createAsyncThunk)(`${sliceName3}/getGatewayDevices`, (deviceId, { dispatch, getState }) => {
|
|
3947
|
-
const state = getState();
|
|
3948
|
-
const { attributes = {} } = getDeviceById(state, deviceId);
|
|
3949
|
-
const { mender_gateway_system_id = "" } = attributes;
|
|
3950
|
-
const filters = [
|
|
3951
|
-
{ ...emptyFilter, key: "id", operator: DEVICE_FILTERING_OPTIONS.$ne.key, value: deviceId, scope: "identity" },
|
|
3952
|
-
{ ...emptyFilter, key: "mender_is_gateway", value: "true", scope: "inventory" },
|
|
3953
|
-
{ ...emptyFilter, key: "mender_gateway_system_id", value: mender_gateway_system_id, scope: "inventory" }
|
|
3922
|
+
return [
|
|
3923
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
3924
|
+
successMessage,
|
|
3925
|
+
" - ",
|
|
3926
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_router_dom.Link, { to: `/devices?inventory=group:eq:${newGroup}`, children: "click here" }),
|
|
3927
|
+
" to see it."
|
|
3928
|
+
] }),
|
|
3929
|
+
5e3,
|
|
3930
|
+
void 0,
|
|
3931
|
+
void 0,
|
|
3932
|
+
() => {
|
|
3933
|
+
}
|
|
3954
3934
|
];
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3935
|
+
};
|
|
3936
|
+
var addStaticGroup = (0, import_toolkit21.createAsyncThunk)(
|
|
3937
|
+
`${sliceName3}/addStaticGroup`,
|
|
3938
|
+
({ group, devices }, { dispatch, getState }) => Promise.resolve(dispatch(addDevicesToGroup({ group, deviceIds: devices.map(({ id }) => id), isCreation: true }))).then(
|
|
3939
|
+
() => Promise.resolve(
|
|
3940
|
+
dispatch(
|
|
3941
|
+
actions3.addGroup({
|
|
3942
|
+
group: { deviceIds: [], total: 0, filters: [], ...getState().devices.groups.byId[group] },
|
|
3943
|
+
groupName: group
|
|
3944
|
+
})
|
|
3945
|
+
)
|
|
3946
|
+
).then(
|
|
3947
|
+
() => Promise.all([
|
|
3948
|
+
dispatch(setDeviceListState({ setOnly: true })),
|
|
3949
|
+
dispatch(getGroups2()),
|
|
3950
|
+
dispatch(setSnackbar4(...getGroupNotification(group, getState().devices.groups.selectedGroup)))
|
|
3951
|
+
])
|
|
3952
|
+
)
|
|
3953
|
+
).catch((err) => commonErrorHandler(err, `Group could not be updated:`, dispatch))
|
|
3954
|
+
);
|
|
3955
|
+
var removeStaticGroup = (0, import_toolkit21.createAsyncThunk)(
|
|
3956
|
+
`${sliceName3}/removeStaticGroup`,
|
|
3957
|
+
(groupName, { dispatch }) => general_api_default.delete(`${inventoryApiUrl}/groups/${groupName}`).then(
|
|
3958
|
+
() => Promise.all([
|
|
3959
|
+
dispatch(actions3.removeGroup(groupName)),
|
|
3960
|
+
dispatch(getGroups2()),
|
|
3961
|
+
dispatch(setSnackbar4("Group was removed successfully", TIMEOUTS.fiveSeconds))
|
|
3962
|
+
])
|
|
3963
|
+
)
|
|
3964
|
+
);
|
|
3965
|
+
var getDynamicGroups = (0, import_toolkit21.createAsyncThunk)(
|
|
3966
|
+
`${sliceName3}/getDynamicGroups`,
|
|
3967
|
+
(_, { dispatch, getState }) => general_api_default.get(`${inventoryApiUrlV2}/filters?per_page=${MAX_PAGE_SIZE}`).then(({ data: filters }) => {
|
|
3968
|
+
const state = getGroupsById(getState());
|
|
3969
|
+
const staticGroups = Object.entries(state).reduce((accu, [id, group]) => {
|
|
3970
|
+
if (!(group.id || group.filters?.length)) {
|
|
3971
|
+
accu[id] = group;
|
|
3986
3972
|
}
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
const
|
|
3990
|
-
|
|
3991
|
-
|
|
3973
|
+
return accu;
|
|
3974
|
+
}, {});
|
|
3975
|
+
const groups = (filters || []).reduce((accu, filter) => {
|
|
3976
|
+
accu[filter.name] = {
|
|
3977
|
+
deviceIds: [],
|
|
3978
|
+
total: 0,
|
|
3979
|
+
...state[filter.name],
|
|
3980
|
+
id: filter.id,
|
|
3981
|
+
filters: mapTermsToFilters(filter.terms)
|
|
3982
|
+
};
|
|
3983
|
+
return accu;
|
|
3984
|
+
}, staticGroups);
|
|
3985
|
+
return Promise.resolve(dispatch(actions3.receivedGroups(groups)));
|
|
3986
|
+
}).catch(() => console.log("Dynamic group retrieval failed - likely accessing a non-enterprise backend"))
|
|
3987
|
+
);
|
|
3988
|
+
var addDynamicGroup = (0, import_toolkit21.createAsyncThunk)(
|
|
3989
|
+
`${sliceName3}/addDynamicGroup`,
|
|
3990
|
+
({ groupName, filterPredicates }, { dispatch, getState }) => general_api_default.post(`${inventoryApiUrlV2}/filters`, { name: groupName, terms: mapFiltersToTerms(filterPredicates) }).then(
|
|
3991
|
+
(res) => Promise.resolve(
|
|
3992
|
+
dispatch(
|
|
3993
|
+
actions3.addGroup({
|
|
3994
|
+
groupName,
|
|
3995
|
+
group: {
|
|
3996
|
+
id: res.headers[headerNames.location].substring(res.headers[headerNames.location].lastIndexOf("/") + 1),
|
|
3997
|
+
filters: filterPredicates
|
|
3998
|
+
}
|
|
3999
|
+
})
|
|
4000
|
+
)
|
|
4001
|
+
).then(() => {
|
|
4002
|
+
const { cleanedFilters } = getGroupFilters(groupName, getState().devices.groups);
|
|
4003
|
+
return Promise.all([
|
|
4004
|
+
dispatch(actions3.setDeviceFilters(cleanedFilters)),
|
|
4005
|
+
dispatch(setSnackbar4(...getGroupNotification(groupName, getState().devices.groups.selectedGroup))),
|
|
4006
|
+
dispatch(getDynamicGroups())
|
|
4007
|
+
]);
|
|
4008
|
+
})
|
|
4009
|
+
).catch((err) => commonErrorHandler(err, `Group could not be updated:`, dispatch))
|
|
4010
|
+
);
|
|
4011
|
+
var updateDynamicGroup = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/updateDynamicGroup`, ({ groupName, filterPredicates }, { dispatch, getState }) => {
|
|
4012
|
+
const filterId = getState().devices.groups.byId[groupName].id;
|
|
4013
|
+
return general_api_default.delete(`${inventoryApiUrlV2}/filters/${filterId}`).then(() => Promise.resolve(dispatch(addDynamicGroup({ groupName, filterPredicates }))));
|
|
3992
4014
|
});
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
var cutoffLength = 75;
|
|
3998
|
-
var ellipsis = "...";
|
|
3999
|
-
var longTextTrimmer = (text) => text.length >= cutoffLength + ellipsis.length ? `${text.substring(0, cutoffLength + ellipsis.length)}${ellipsis}` : text;
|
|
4000
|
-
var sanitizeDeviceAlerts = (alerts) => alerts.map((alert) => ({ ...alert, fullName: alert.name, name: longTextTrimmer(alert.name) }));
|
|
4001
|
-
var getDeviceAlerts = (0, import_toolkit20.createAsyncThunk)(`${sliceName4}/getDeviceAlerts`, ({ id, config = {} }, { dispatch }) => {
|
|
4002
|
-
const { page = defaultPage3, perPage = defaultPerPage3, issuedBefore, issuedAfter, sortAscending = false } = config;
|
|
4003
|
-
const issued_after = issuedAfter ? `&issued_after=${issuedAfter}` : "";
|
|
4004
|
-
const issued_before = issuedBefore ? `&issued_before=${issuedBefore}` : "";
|
|
4005
|
-
return general_api_default.get(`${monitorApiUrlv1}/devices/${id}/alerts?page=${page}&per_page=${perPage}${issued_after}${issued_before}&sort_ascending=${sortAscending}`).catch((err) => commonErrorHandler(err, `Retrieving device alerts for device ${id} failed:`, dispatch)).then(
|
|
4006
|
-
(res) => Promise.all([
|
|
4007
|
-
dispatch(actions4.receiveDeviceAlerts({ deviceId: id, alerts: sanitizeDeviceAlerts(res.data) })),
|
|
4008
|
-
dispatch(actions4.setAlertListState({ total: Number(res.headers[headerNames.total]) }))
|
|
4009
|
-
])
|
|
4015
|
+
var removeDynamicGroup = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/removeDynamicGroup`, (groupName, { dispatch, getState }) => {
|
|
4016
|
+
const filterId = getState().devices.groups.byId[groupName].id;
|
|
4017
|
+
return general_api_default.delete(`${inventoryApiUrlV2}/filters/${filterId}`).then(
|
|
4018
|
+
() => Promise.all([dispatch(actions3.removeGroup(groupName)), dispatch(setSnackbar4("Group was removed successfully", TIMEOUTS.fiveSeconds))])
|
|
4010
4019
|
);
|
|
4011
4020
|
});
|
|
4012
|
-
var
|
|
4013
|
-
const
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
const { filters = getDeviceFilters(state), group, status, ...remainder } = options;
|
|
4019
|
-
const { applicableFilters: nonMonitorFilters, filterTerms } = convertDeviceListStateToFilters({
|
|
4020
|
-
...remainder,
|
|
4021
|
-
filters,
|
|
4022
|
-
group,
|
|
4023
|
-
offlineThreshold: state.app.offlineThreshold,
|
|
4024
|
-
selectedIssues: [type],
|
|
4025
|
-
status
|
|
4026
|
-
});
|
|
4027
|
-
return general_api_default.post(getSearchEndpoint(getState()), {
|
|
4028
|
-
page: 1,
|
|
4029
|
-
per_page: 1,
|
|
4030
|
-
filters: filterTerms,
|
|
4031
|
-
attributes: [{ scope: "identity", attribute: "status" }]
|
|
4032
|
-
}).catch((err) => commonErrorHandler(err, `Retrieving issue counts failed:`, dispatch, commonErrorFallback)).then((res) => {
|
|
4033
|
-
const total = nonMonitorFilters.length ? state.monitor.issueCounts.byType[type].total : Number(res.headers[headerNames.total]);
|
|
4034
|
-
const filtered = nonMonitorFilters.length ? Number(res.headers[headerNames.total]) : total;
|
|
4035
|
-
if (total === state.monitor.issueCounts.byType[type].total && filtered === state.monitor.issueCounts.byType[type].filtered) {
|
|
4036
|
-
return Promise.resolve();
|
|
4037
|
-
}
|
|
4038
|
-
return Promise.resolve(dispatch(actions4.receiveDeviceIssueCounts({ counts: { filtered, total }, issueType: type })));
|
|
4039
|
-
});
|
|
4040
|
-
});
|
|
4041
|
-
var getDeviceMonitorConfig = (0, import_toolkit20.createAsyncThunk)(
|
|
4042
|
-
`${sliceName4}/getDeviceMonitorConfig`,
|
|
4043
|
-
(id, { dispatch }) => general_api_default.get(`${monitorApiUrlv1}/devices/${id}/config`).catch((err) => commonErrorHandler(err, `Retrieving device monitor config for device ${id} failed:`, dispatch)).then(({ data }) => Promise.all([dispatch(actions_default.receivedDevice({ id, monitors: data }), Promise.resolve(data))]))
|
|
4044
|
-
);
|
|
4045
|
-
var changeNotificationSetting = (0, import_toolkit20.createAsyncThunk)(
|
|
4046
|
-
`${sliceName4}/changeNotificationSetting`,
|
|
4047
|
-
({ enabled, channel = alertChannels.email }, { dispatch }) => {
|
|
4048
|
-
return general_api_default.put(`${monitorApiUrlv1}/settings/global/channel/alerts/${channel}/status`, { enabled }).catch((err) => commonErrorHandler(err, `${enabled ? "En" : "Dis"}abling ${channel} alerts failed:`, dispatch)).then(
|
|
4049
|
-
() => Promise.all([
|
|
4050
|
-
dispatch(actions4.changeAlertChannel({ channel, enabled })),
|
|
4051
|
-
dispatch(actions_default.setSnackbar(`Successfully ${enabled ? "en" : "dis"}abled ${channel} alerts`, TIMEOUTS.fiveSeconds))
|
|
4052
|
-
])
|
|
4053
|
-
);
|
|
4054
|
-
}
|
|
4055
|
-
);
|
|
4056
|
-
|
|
4057
|
-
// src/api/users-api.ts
|
|
4058
|
-
var import_axios3 = __toESM(require("axios"), 1);
|
|
4059
|
-
var Api2 = {
|
|
4060
|
-
postLogin: (url, { email: username, password, ...body }) => import_axios3.default.post(url, body, { ...commonRequestConfig, auth: { username, password } }).then((res) => ({ text: res.data, code: res.status, contentType: res.headers?.["content-type"] })),
|
|
4061
|
-
putVerifyTFA: (url, userData) => {
|
|
4062
|
-
let body = {};
|
|
4063
|
-
if (userData.hasOwnProperty("token2fa")) {
|
|
4064
|
-
body = { token2fa: userData.token2fa };
|
|
4065
|
-
}
|
|
4066
|
-
return import_axios3.default.put(url, body, { ...commonRequestConfig, headers: { ...commonRequestConfig.headers, Authorization: `Bearer ${getToken()}` } });
|
|
4067
|
-
}
|
|
4021
|
+
var getGroupFilters = (group, groupsState, filters = []) => {
|
|
4022
|
+
const groupName = group === UNGROUPED_GROUP.id || group === UNGROUPED_GROUP.name ? UNGROUPED_GROUP.id : group;
|
|
4023
|
+
const selectedGroup = groupsState.byId[groupName];
|
|
4024
|
+
const groupFilterLength = selectedGroup?.filters?.length || 0;
|
|
4025
|
+
const cleanedFilters = groupFilterLength ? [...filters, ...selectedGroup.filters].filter(filtersFilter) : filters;
|
|
4026
|
+
return { cleanedFilters, groupName, selectedGroup, groupFilterLength };
|
|
4068
4027
|
};
|
|
4069
|
-
var
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
var import_retrytimer = require("@northern.tech/utils/retrytimer");
|
|
4074
|
-
var import_toolkit21 = require("@reduxjs/toolkit");
|
|
4075
|
-
var import_md5 = __toESM(require("md5"), 1);
|
|
4076
|
-
var import_universal_cookie3 = __toESM(require("universal-cookie"), 1);
|
|
4077
|
-
var cookies3 = new import_universal_cookie3.default();
|
|
4078
|
-
var { setAnnouncement, setSnackbar: setSnackbar4 } = actions_default;
|
|
4079
|
-
var handleLoginError = (err, { token2fa: has2FA, password }, rejectWithValue) => (dispatch) => {
|
|
4080
|
-
const errorText = (0, import_helpers10.extractErrorMessage)(err);
|
|
4081
|
-
const is2FABackend = errorText.includes("2fa");
|
|
4082
|
-
if (is2FABackend && !has2FA) {
|
|
4083
|
-
return rejectWithValue({ error: "2fa code missing" });
|
|
4028
|
+
var selectGroup = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/selectGroup`, ({ group, filters = [] }, { dispatch, getState }) => {
|
|
4029
|
+
const { cleanedFilters, groupName, selectedGroup, groupFilterLength } = getGroupFilters(group, getState().devices.groups, filters);
|
|
4030
|
+
if (getSelectedGroup(getState()) === groupName && (filters.length === 0 && !groupFilterLength || filters.length === cleanedFilters.length)) {
|
|
4031
|
+
return Promise.resolve();
|
|
4084
4032
|
}
|
|
4085
|
-
|
|
4086
|
-
|
|
4033
|
+
let tasks = [];
|
|
4034
|
+
if (groupFilterLength) {
|
|
4035
|
+
tasks.push(dispatch(actions3.setDeviceFilters(cleanedFilters)));
|
|
4036
|
+
} else {
|
|
4037
|
+
tasks.push(dispatch(actions3.setDeviceFilters(filters)));
|
|
4038
|
+
tasks.push(dispatch(getGroupDevices({ group: groupName, perPage: 1, shouldIncludeAllStates: true })));
|
|
4087
4039
|
}
|
|
4088
|
-
const
|
|
4089
|
-
|
|
4090
|
-
return Promise.
|
|
4091
|
-
};
|
|
4092
|
-
var
|
|
4093
|
-
|
|
4094
|
-
(
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4040
|
+
const selectedGroupName = selectedGroup || !Object.keys(getGroupsById(getState())).length ? groupName : void 0;
|
|
4041
|
+
tasks.push(dispatch(actions3.selectGroup(selectedGroupName)));
|
|
4042
|
+
return Promise.all(tasks);
|
|
4043
|
+
});
|
|
4044
|
+
var getEarliestTs = (dateA = "", dateB = "") => !dateA || !dateB ? dateA || dateB : dateA < dateB ? dateA : dateB;
|
|
4045
|
+
var reduceReceivedDevices = (devices, ids, state, status) => devices.reduce(
|
|
4046
|
+
(accu, device) => {
|
|
4047
|
+
const stateDevice = getDeviceById(state, device.id);
|
|
4048
|
+
const {
|
|
4049
|
+
attributes: storedAttributes = {},
|
|
4050
|
+
identity_data: storedIdentity = {},
|
|
4051
|
+
monitor: storedMonitor = {},
|
|
4052
|
+
tags: storedTags = {},
|
|
4053
|
+
group: storedGroup
|
|
4054
|
+
} = stateDevice;
|
|
4055
|
+
const { identity, inventory, monitor, system = {}, tags } = mapDeviceAttributes(device.attributes);
|
|
4056
|
+
device.tags = { ...storedTags, ...tags };
|
|
4057
|
+
device.group = system.group ?? storedGroup;
|
|
4058
|
+
device.monitor = { ...storedMonitor, ...monitor };
|
|
4059
|
+
device.identity_data = { ...storedIdentity, ...identity, ...device.identity_data ? device.identity_data : {} };
|
|
4060
|
+
device.status = status ? status : device.status || identity.status;
|
|
4061
|
+
device.check_in_time_rounded = system.check_in_time ?? stateDevice.check_in_time_rounded;
|
|
4062
|
+
device.check_in_time_exact = device.check_in_time ?? stateDevice.check_in_time_exact;
|
|
4063
|
+
device.created_ts = getEarliestTs(getEarliestTs(system.created_ts, device.created_ts), stateDevice.created_ts);
|
|
4064
|
+
device.updated_ts = device.attributes ? device.updated_ts : stateDevice.updated_ts;
|
|
4065
|
+
device.isNew = new Date(device.created_ts) > new Date(state.app.newThreshold);
|
|
4066
|
+
device.isOffline = new Date(device.check_in_time_rounded) < new Date(state.app.offlineThreshold) || device.check_in_time_rounded === void 0;
|
|
4067
|
+
device.attributes = device.attributes ? { ...storedAttributes, ...inventory } : storedAttributes;
|
|
4068
|
+
accu.devicesById[device.id] = { ...stateDevice, ...device };
|
|
4069
|
+
accu.ids.push(device.id);
|
|
4070
|
+
return accu;
|
|
4071
|
+
},
|
|
4072
|
+
{ ids, devicesById: {} }
|
|
4073
|
+
);
|
|
4074
|
+
var getGroupDevices = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/getGroupDevices`, (options, { dispatch, getState }) => {
|
|
4075
|
+
const { group, shouldIncludeAllStates, ...remainder } = options;
|
|
4076
|
+
const { cleanedFilters: filterSelection } = getGroupFilters(group, getState().devices.groups);
|
|
4077
|
+
return Promise.resolve(
|
|
4078
|
+
dispatch(getDevicesByStatus2({ ...remainder, filterSelection, group, status: shouldIncludeAllStates ? void 0 : DEVICE_STATES.accepted }))
|
|
4079
|
+
).unwrap().then((results) => {
|
|
4080
|
+
if (!group) {
|
|
4081
|
+
return Promise.resolve();
|
|
4104
4082
|
}
|
|
4105
|
-
const
|
|
4106
|
-
|
|
4107
|
-
|
|
4083
|
+
const { deviceAccu, total } = results[results.length - 1];
|
|
4084
|
+
const stateGroup = getState().devices.groups.byId[group];
|
|
4085
|
+
if (!stateGroup && !total && !deviceAccu.ids.length) {
|
|
4086
|
+
return Promise.resolve();
|
|
4108
4087
|
}
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
}).then(() => {
|
|
4120
|
-
window.sessionStorage.removeItem("pendings-redirect");
|
|
4121
|
-
if (window.location.pathname !== "/ui/") {
|
|
4122
|
-
window.location.replace("/ui/");
|
|
4123
|
-
}
|
|
4124
|
-
return Promise.resolve(dispatch(actions8.successfullyLoggedIn({ expiresAt, token })));
|
|
4125
|
-
})
|
|
4088
|
+
return Promise.resolve(
|
|
4089
|
+
dispatch(
|
|
4090
|
+
actions3.addGroup({
|
|
4091
|
+
group: {
|
|
4092
|
+
deviceIds: deviceAccu.ids.length === total || deviceAccu.ids.length > stateGroup?.deviceIds ? deviceAccu.ids : stateGroup.deviceIds,
|
|
4093
|
+
total
|
|
4094
|
+
},
|
|
4095
|
+
groupName: group
|
|
4096
|
+
})
|
|
4097
|
+
)
|
|
4126
4098
|
);
|
|
4127
|
-
})
|
|
4128
|
-
);
|
|
4129
|
-
var logoutUser = (0, import_toolkit21.createAsyncThunk)(`${sliceName8}/logoutUser`, (_, { dispatch, getState }) => {
|
|
4130
|
-
if (Object.keys(getState().app.uploadsById).length) {
|
|
4131
|
-
return Promise.reject();
|
|
4132
|
-
}
|
|
4133
|
-
return general_api_default.post(`${useradmApiUrlv1}/auth/logout`).finally(() => {
|
|
4134
|
-
cleanUp();
|
|
4135
|
-
(0, import_retrytimer.clearAllRetryTimers)(setSnackbar4);
|
|
4136
|
-
return Promise.resolve(dispatch({ type: USER_LOGOUT }));
|
|
4137
4099
|
});
|
|
4138
4100
|
});
|
|
4139
|
-
var
|
|
4140
|
-
if (
|
|
4141
|
-
return Promise.
|
|
4101
|
+
var getAllGroupDevices = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/getAllGroupDevices`, (group, { dispatch, getState }) => {
|
|
4102
|
+
if (!group || !!group && (!getGroupsById(getState())[group] || getGroupsById(getState())[group].filters.length)) {
|
|
4103
|
+
return Promise.resolve();
|
|
4142
4104
|
}
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4105
|
+
const { attributes, filterTerms } = prepareSearchArguments({
|
|
4106
|
+
filters: [],
|
|
4107
|
+
group,
|
|
4108
|
+
state: getState(),
|
|
4109
|
+
status: DEVICE_STATES.accepted
|
|
4146
4110
|
});
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
)
|
|
4153
|
-
);
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
if (response.status == 400) {
|
|
4160
|
-
errorMsg = "the link you are using expired or the request is not valid, please try again.";
|
|
4161
|
-
} else {
|
|
4162
|
-
errorMsg = error;
|
|
4163
|
-
}
|
|
4164
|
-
dispatch(setSnackbar4("The password reset request cannot be processed: " + errorMsg));
|
|
4165
|
-
return Promise.reject(err);
|
|
4166
|
-
})
|
|
4167
|
-
);
|
|
4168
|
-
var verifyEmailStart = (0, import_toolkit21.createAsyncThunk)(
|
|
4169
|
-
`${sliceName8}/verifyEmailStart`,
|
|
4170
|
-
(_, { dispatch, getState }) => general_api_default.post(`${useradmApiUrlv1}/auth/verify-email/start`, { email: getCurrentUser(getState()).email }).catch((err) => commonErrorHandler(err, "An error occured starting the email verification process:", dispatch)).finally(() => Promise.resolve(dispatch(getUser(OWN_USER_ID))))
|
|
4171
|
-
);
|
|
4172
|
-
var verifyEmailComplete = (0, import_toolkit21.createAsyncThunk)(
|
|
4173
|
-
`${sliceName8}/verifyEmailComplete`,
|
|
4174
|
-
(secret_hash, { dispatch }) => general_api_default.post(`${useradmApiUrlv1}/auth/verify-email/complete`, { secret_hash }).catch((err) => commonErrorHandler(err, "An error occured completing the email verification process:", dispatch)).finally(() => Promise.resolve(dispatch(getUser(OWN_USER_ID))))
|
|
4175
|
-
);
|
|
4176
|
-
var verify2FA = (0, import_toolkit21.createAsyncThunk)(
|
|
4177
|
-
`${sliceName8}/verify2FA`,
|
|
4178
|
-
(tfaData, { dispatch }) => users_api_default.putVerifyTFA(`${useradmApiUrlv1}/2faverify`, tfaData).then(() => Promise.resolve(dispatch(getUser(OWN_USER_ID)))).catch(
|
|
4179
|
-
(err) => commonErrorHandler(err, "An error occured validating the verification code: failed to verify token, please try again.", dispatch, void 0, true)
|
|
4180
|
-
)
|
|
4181
|
-
);
|
|
4182
|
-
var getUserList = (0, import_toolkit21.createAsyncThunk)(
|
|
4183
|
-
`${sliceName8}/getUserList`,
|
|
4184
|
-
(_, { dispatch }) => general_api_default.get(`${useradmApiUrlv1}/users`).then((res) => {
|
|
4185
|
-
const users = res.data.reduce((accu, item) => {
|
|
4186
|
-
accu[item.id] = item;
|
|
4187
|
-
return accu;
|
|
4188
|
-
}, {});
|
|
4189
|
-
return dispatch(actions8.receivedUserList(users));
|
|
4190
|
-
}).catch((err) => commonErrorHandler(err, `Users couldn't be loaded.`, dispatch, commonErrorFallback))
|
|
4191
|
-
);
|
|
4192
|
-
var getUser = (0, import_toolkit21.createAsyncThunk)(
|
|
4193
|
-
`${sliceName8}/getUser`,
|
|
4194
|
-
(id, { dispatch, rejectWithValue }) => general_api_default.get(`${useradmApiUrlv1}/users/${id}`).then(
|
|
4195
|
-
({ data: user }) => Promise.all([
|
|
4196
|
-
dispatch(actions8.receivedUser(user)),
|
|
4197
|
-
// @ts-ignore
|
|
4198
|
-
dispatch(setHideAnnouncement({ shouldHide: false, userId: user.id })),
|
|
4199
|
-
// @ts-ignore
|
|
4200
|
-
dispatch(updateUserColumnSettings({ currentUserId: user.id })),
|
|
4201
|
-
user
|
|
4202
|
-
])
|
|
4203
|
-
).catch((e) => rejectWithValue(e))
|
|
4204
|
-
);
|
|
4205
|
-
var initializeSelf = (0, import_toolkit21.createAsyncThunk)(`${sliceName8}/initializeSelf`, (_, { dispatch }) => dispatch(getUser(OWN_USER_ID)));
|
|
4206
|
-
var updateUserColumnSettings = (0, import_toolkit21.createAsyncThunk)(`${sliceName8}/updateUserColumnSettings`, ({ columns, currentUserId }, { dispatch, getState }) => {
|
|
4207
|
-
const userId = currentUserId ?? getCurrentUser(getState()).id;
|
|
4208
|
-
const storageKey = `${userId}-column-widths`;
|
|
4209
|
-
let customColumns = [];
|
|
4210
|
-
if (!columns) {
|
|
4211
|
-
try {
|
|
4212
|
-
customColumns = JSON.parse(window.localStorage.getItem(storageKey)) || customColumns;
|
|
4213
|
-
} catch {
|
|
4111
|
+
const getAllDevices = (perPage = MAX_PAGE_SIZE, page = defaultPage3, devices = []) => general_api_default.post(getSearchEndpoint(getState()), {
|
|
4112
|
+
page,
|
|
4113
|
+
per_page: perPage,
|
|
4114
|
+
filters: filterTerms,
|
|
4115
|
+
attributes
|
|
4116
|
+
}).then((res) => {
|
|
4117
|
+
const state = getState();
|
|
4118
|
+
const deviceAccu = reduceReceivedDevices(res.data, devices, state);
|
|
4119
|
+
dispatch(actions3.receivedDevices(deviceAccu.devicesById));
|
|
4120
|
+
const total = Number(res.headers[headerNames.total]);
|
|
4121
|
+
if (total > perPage * page) {
|
|
4122
|
+
return getAllDevices(perPage, page + 1, deviceAccu.ids);
|
|
4214
4123
|
}
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
window.localStorage.setItem(storageKey, JSON.stringify(customColumns));
|
|
4219
|
-
return Promise.resolve(dispatch(actions8.setCustomColumns(customColumns)));
|
|
4124
|
+
return Promise.resolve(dispatch(actions3.addGroup({ group: { deviceIds: deviceAccu.ids, total: deviceAccu.ids.length }, groupName: group })));
|
|
4125
|
+
});
|
|
4126
|
+
return getAllDevices();
|
|
4220
4127
|
});
|
|
4221
|
-
var
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
errorMessage: "adding"
|
|
4225
|
-
},
|
|
4226
|
-
create: {
|
|
4227
|
-
successMessage: "The user was created successfully.",
|
|
4228
|
-
errorMessage: "creating"
|
|
4229
|
-
},
|
|
4230
|
-
edit: {
|
|
4231
|
-
successMessage: "The user has been updated.",
|
|
4232
|
-
errorMessage: "editing"
|
|
4233
|
-
},
|
|
4234
|
-
remove: {
|
|
4235
|
-
successMessage: "The user was removed from the system.",
|
|
4236
|
-
errorMessage: "removing"
|
|
4128
|
+
var getAllDynamicGroupDevices = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/getAllDynamicGroupDevices`, (group, { dispatch, getState }) => {
|
|
4129
|
+
if (!!group && (!getGroupsById(getState())[group] || !getGroupsById(getState())[group].filters.length)) {
|
|
4130
|
+
return Promise.resolve();
|
|
4237
4131
|
}
|
|
4238
|
-
}
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
)
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
() => Promise.all([
|
|
4255
|
-
dispatch(actions8.updatedUser({ ...userData, id: id === OWN_USER_ID ? getCurrentUser(getState()).id : id })),
|
|
4256
|
-
dispatch(setSnackbar4(userActions.edit.successMessage))
|
|
4257
|
-
])
|
|
4258
|
-
)
|
|
4259
|
-
);
|
|
4260
|
-
var addUserToCurrentTenant = (0, import_toolkit21.createAsyncThunk)(`${sliceName8}/addUserToTenant`, (userId, { dispatch, getState }) => {
|
|
4261
|
-
const { id } = getOrganization(getState());
|
|
4262
|
-
return general_api_default.post(`${useradmApiUrlv1}/users/${userId}/assign`, { tenant_ids: [id] }).catch((err) => commonErrorHandler(err, `There was an error adding the user to your organization:`, dispatch)).then(() => Promise.all([dispatch(setSnackbar4(userActions.add.successMessage)), dispatch(getUserList())]));
|
|
4132
|
+
const { attributes, filterTerms: filters } = prepareSearchArguments({
|
|
4133
|
+
filters: getState().devices.groups.byId[group].filters,
|
|
4134
|
+
state: getState(),
|
|
4135
|
+
status: DEVICE_STATES.accepted
|
|
4136
|
+
});
|
|
4137
|
+
const getAllDevices = (perPage = MAX_PAGE_SIZE, page = defaultPage3, devices = []) => general_api_default.post(getSearchEndpoint(getState()), { page, per_page: perPage, filters, attributes }).then((res) => {
|
|
4138
|
+
const state = getState();
|
|
4139
|
+
const deviceAccu = reduceReceivedDevices(res.data, devices, state);
|
|
4140
|
+
dispatch(actions3.receivedDevices(deviceAccu.devicesById));
|
|
4141
|
+
const total = Number(res.headers[headerNames.total]);
|
|
4142
|
+
if (total > deviceAccu.ids.length) {
|
|
4143
|
+
return getAllDevices(perPage, page + 1, deviceAccu.ids);
|
|
4144
|
+
}
|
|
4145
|
+
return Promise.resolve(dispatch(actions3.addGroup({ group: { deviceIds: deviceAccu.ids, total }, groupName: group })));
|
|
4146
|
+
});
|
|
4147
|
+
return getAllDevices();
|
|
4263
4148
|
});
|
|
4264
|
-
var
|
|
4265
|
-
`${
|
|
4266
|
-
(
|
|
4267
|
-
);
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
)
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
}
|
|
4149
|
+
var getDeviceById2 = (0, import_toolkit21.createAsyncThunk)(
|
|
4150
|
+
`${sliceName3}/getDeviceById`,
|
|
4151
|
+
(id, { dispatch, getState }) => general_api_default.get(`${inventoryApiUrl}/devices/${id}`).then((res) => {
|
|
4152
|
+
const device = reduceReceivedDevices([res.data], [], getState()).devicesById[id];
|
|
4153
|
+
device.etag = res.headers.etag;
|
|
4154
|
+
dispatch(actions3.receivedDevice(device));
|
|
4155
|
+
return Promise.resolve(device);
|
|
4156
|
+
}).catch((err) => {
|
|
4157
|
+
const errMsg = (0, import_helpers10.extractErrorMessage)(err);
|
|
4158
|
+
if (errMsg.includes("Not Found")) {
|
|
4159
|
+
console.log(`${id} does not have any inventory information`);
|
|
4160
|
+
const device = reduceReceivedDevices(
|
|
4161
|
+
[
|
|
4162
|
+
{
|
|
4163
|
+
id,
|
|
4164
|
+
attributes: [
|
|
4165
|
+
{ name: "status", value: "decomissioned", scope: "identity" },
|
|
4166
|
+
{ name: "decomissioned", value: "true", scope: "inventory" }
|
|
4167
|
+
]
|
|
4168
|
+
}
|
|
4169
|
+
],
|
|
4170
|
+
[],
|
|
4171
|
+
getState()
|
|
4172
|
+
).devicesById[id];
|
|
4173
|
+
dispatch(actions3.receivedDevice(device));
|
|
4290
4174
|
}
|
|
4291
|
-
|
|
4292
|
-
},
|
|
4293
|
-
{ ...emptyUiPermissions }
|
|
4175
|
+
})
|
|
4294
4176
|
);
|
|
4295
|
-
var
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
groups: { [permission.value]: [uiPermissionsById.connect.value] }
|
|
4304
|
-
} : {},
|
|
4305
|
-
VIEW_DEVICE: (permission) => permission.type === PermissionTypes.DeviceGroup ? {
|
|
4306
|
-
groups: { [permission.value]: [uiPermissionsById.read.value] }
|
|
4307
|
-
} : {}
|
|
4308
|
-
};
|
|
4309
|
-
var combinePermissions = (existingPermissions, additionalPermissions = {}) => Object.entries(additionalPermissions).reduce((accu, [name, permissions]) => {
|
|
4310
|
-
let maybeExistingPermissions = accu[name] || [];
|
|
4311
|
-
accu[name] = [...permissions, ...maybeExistingPermissions].filter(import_helpers10.duplicateFilter);
|
|
4312
|
-
return accu;
|
|
4313
|
-
}, existingPermissions);
|
|
4314
|
-
var tryParseCustomPermission = (permission) => {
|
|
4315
|
-
const uiPermissions = permissionActionTypes[permission.action](permission.object);
|
|
4316
|
-
const result = mergePermissions({ ...emptyUiPermissions }, uiPermissions);
|
|
4317
|
-
return { isCustom: true, permission, result };
|
|
4318
|
-
};
|
|
4319
|
-
var customPermissionHandler = (accu, permission) => {
|
|
4320
|
-
let processor = tryParseCustomPermission(permission);
|
|
4321
|
-
return {
|
|
4322
|
-
...accu,
|
|
4323
|
-
isCustom: accu.isCustom || processor.isCustom,
|
|
4324
|
-
uiPermissions: mergePermissions(accu.uiPermissions, processor.result)
|
|
4325
|
-
};
|
|
4326
|
-
};
|
|
4327
|
-
var mapPermissionSet = (permissionSetName, names, scope, existingGroupsPermissions = {}) => {
|
|
4328
|
-
const permission = Object.values(uiPermissionsById).find((permission2) => permission2.permissionSets[scope] === permissionSetName).value;
|
|
4329
|
-
const scopedPermissions = names.reduce((accu, name) => combinePermissions(accu, { [name]: [permission] }), existingGroupsPermissions);
|
|
4330
|
-
return Object.entries(scopedPermissions).reduce((accu, [key, permissions]) => ({ ...accu, [key]: deriveImpliedAreaPermissions(scope, permissions) }), {});
|
|
4331
|
-
};
|
|
4332
|
-
var isEmptyPermissionSet = (permissionSet) => !Object.values(permissionSet).reduce((accu, permissions) => {
|
|
4333
|
-
if (Array.isArray(permissions)) {
|
|
4334
|
-
return accu || !!permissions.length;
|
|
4177
|
+
var getDeviceInfo = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/getDeviceInfo`, (deviceId, { dispatch, getState }) => {
|
|
4178
|
+
const device = getDeviceById(getState(), deviceId);
|
|
4179
|
+
const { hasDeviceConfig, hasDeviceConnect, hasMonitor } = getTenantCapabilities(getState());
|
|
4180
|
+
const { canConfigure } = getUserCapabilities(getState());
|
|
4181
|
+
const integrations = getDeviceTwinIntegrations(getState());
|
|
4182
|
+
let tasks = [dispatch(getDeviceAuth(deviceId)), ...integrations.map((integration) => dispatch(getDeviceTwin({ deviceId, integration })))];
|
|
4183
|
+
if (hasDeviceConfig && canConfigure && [DEVICE_STATES.accepted, DEVICE_STATES.preauth].includes(device.status)) {
|
|
4184
|
+
tasks.push(dispatch(getDeviceConfig(deviceId)));
|
|
4335
4185
|
}
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4186
|
+
if (device.status === DEVICE_STATES.accepted) {
|
|
4187
|
+
tasks.push(dispatch(getDeviceById2(deviceId)));
|
|
4188
|
+
if (hasDeviceConnect) {
|
|
4189
|
+
tasks.push(dispatch(getDeviceConnect(deviceId)));
|
|
4190
|
+
}
|
|
4191
|
+
if (hasMonitor) {
|
|
4192
|
+
tasks.push(dispatch(getLatestDeviceAlerts({ id: deviceId })));
|
|
4193
|
+
tasks.push(dispatch(getDeviceMonitorConfig(deviceId)));
|
|
4194
|
+
}
|
|
4195
|
+
}
|
|
4196
|
+
return Promise.all(tasks);
|
|
4197
|
+
});
|
|
4198
|
+
var deriveInactiveDevices = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/deriveInactiveDevices`, (deviceIds, { dispatch, getState }) => {
|
|
4199
|
+
const yesterday = /* @__PURE__ */ new Date();
|
|
4200
|
+
yesterday.setDate(yesterday.getDate() - 1);
|
|
4201
|
+
const yesterdaysIsoString = yesterday.toISOString();
|
|
4202
|
+
const devices = deviceIds.reduce(
|
|
4203
|
+
(accu, id) => {
|
|
4204
|
+
const device = getDeviceById(getState(), id);
|
|
4205
|
+
if (device && device.updated_ts > yesterdaysIsoString) {
|
|
4206
|
+
accu.active.push(id);
|
|
4207
|
+
} else {
|
|
4208
|
+
accu.inactive.push(id);
|
|
4351
4209
|
}
|
|
4352
|
-
return
|
|
4353
|
-
...accu,
|
|
4354
|
-
isCustom: accu.isCustom || processor.isCustom,
|
|
4355
|
-
uiPermissions: mergePermissions(accu.uiPermissions, processor.result)
|
|
4356
|
-
};
|
|
4210
|
+
return accu;
|
|
4357
4211
|
},
|
|
4358
|
-
{
|
|
4212
|
+
{ active: [], inactive: [] }
|
|
4359
4213
|
);
|
|
4360
|
-
return
|
|
4361
|
-
};
|
|
4362
|
-
var
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
const result = parseRolePermissions(role, permissionSets);
|
|
4374
|
-
normalizedPermissions = result.uiPermissions;
|
|
4375
|
-
isCustom = result.isCustom;
|
|
4214
|
+
return dispatch(actions3.setInactiveDevices({ activeDeviceTotal: devices.active.length, inactiveDeviceTotal: devices.inactive.length }));
|
|
4215
|
+
});
|
|
4216
|
+
var getDeviceCount = (0, import_toolkit21.createAsyncThunk)(
|
|
4217
|
+
`${sliceName3}/getDeviceCount`,
|
|
4218
|
+
(status, { dispatch, getState }) => general_api_default.post(getSearchEndpoint(getState()), {
|
|
4219
|
+
page: 1,
|
|
4220
|
+
per_page: 1,
|
|
4221
|
+
filters: mapFiltersToTerms([{ key: "status", value: status, operator: DEVICE_FILTERING_OPTIONS.$eq.key, scope: "identity" }]),
|
|
4222
|
+
attributes: defaultAttributes
|
|
4223
|
+
}).then((response) => {
|
|
4224
|
+
const count = Number(response.headers[headerNames.total]);
|
|
4225
|
+
if (status) {
|
|
4226
|
+
return dispatch(actions3.setDevicesCountByStatus({ count, status }));
|
|
4376
4227
|
}
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4228
|
+
return dispatch(actions3.setTotalDevices(count));
|
|
4229
|
+
})
|
|
4230
|
+
);
|
|
4231
|
+
var getAllDeviceCounts = (0, import_toolkit21.createAsyncThunk)(
|
|
4232
|
+
`${sliceName3}/getAllDeviceCounts`,
|
|
4233
|
+
(_, { dispatch }) => Promise.all([DEVICE_STATES.accepted, DEVICE_STATES.pending].map((status) => dispatch(getDeviceCount(status))))
|
|
4234
|
+
);
|
|
4235
|
+
var getDeviceLimit2 = (0, import_toolkit21.createAsyncThunk)(
|
|
4236
|
+
`${sliceName3}/getDeviceLimit`,
|
|
4237
|
+
(_, { dispatch }) => general_api_default.get(`${deviceAuthV2}/limits/max_devices`).then((res) => dispatch(actions3.setDeviceLimit(res.data.limit)))
|
|
4238
|
+
);
|
|
4239
|
+
var setDeviceListState = (0, import_toolkit21.createAsyncThunk)(
|
|
4240
|
+
`${sliceName3}/setDeviceListState`,
|
|
4241
|
+
({ shouldSelectDevices = true, forceRefresh, fetchAuth = true, ...selectionState }, { dispatch, getState }) => {
|
|
4242
|
+
const currentState = getDeviceListState(getState());
|
|
4243
|
+
const refreshTrigger = forceRefresh ? !currentState.refreshTrigger : selectionState.refreshTrigger;
|
|
4244
|
+
let nextState = {
|
|
4245
|
+
...currentState,
|
|
4246
|
+
setOnly: false,
|
|
4247
|
+
refreshTrigger,
|
|
4248
|
+
...selectionState,
|
|
4249
|
+
sort: { ...currentState.sort, ...selectionState.sort }
|
|
4386
4250
|
};
|
|
4251
|
+
let tasks = [];
|
|
4252
|
+
const { isLoading: currentLoading, deviceIds: currentDevices, selection: currentSelection, ...currentRequestState } = currentState;
|
|
4253
|
+
const { isLoading: nextLoading, deviceIds: nextDevices, selection: nextSelection, ...nextRequestState } = nextState;
|
|
4254
|
+
if (!nextState.setOnly && !(0, import_helpers10.deepCompare)(currentRequestState, nextRequestState)) {
|
|
4255
|
+
const { direction: sortDown = SORTING_OPTIONS.desc, key: sortCol, scope: sortScope } = nextState.sort ?? {};
|
|
4256
|
+
const sortBy = sortCol ? [{ attribute: sortCol, order: sortDown, scope: sortScope }] : void 0;
|
|
4257
|
+
const applicableSelectedState = nextState.state === ALL_DEVICE_STATES ? void 0 : nextState.state;
|
|
4258
|
+
nextState.isLoading = true;
|
|
4259
|
+
tasks.push(
|
|
4260
|
+
dispatch(getDevicesByStatus2({ ...nextState, status: applicableSelectedState, sortOptions: sortBy, fetchAuth })).unwrap().then((results) => {
|
|
4261
|
+
const { deviceAccu, total } = results[results.length - 1];
|
|
4262
|
+
const devicesState = shouldSelectDevices ? { deviceIds: deviceAccu.ids, total, isLoading: false } : { isLoading: false };
|
|
4263
|
+
return Promise.resolve(dispatch(actions3.setDeviceListState(devicesState)));
|
|
4264
|
+
}).catch(() => Promise.resolve({ isLoading: false }))
|
|
4265
|
+
);
|
|
4266
|
+
}
|
|
4267
|
+
tasks.push(dispatch(actions3.setDeviceListState(nextState)));
|
|
4268
|
+
return Promise.all(tasks);
|
|
4269
|
+
}
|
|
4270
|
+
);
|
|
4271
|
+
var getDevicesByStatus2 = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/getDevicesByStatus`, (options, { dispatch, getState }) => {
|
|
4272
|
+
const {
|
|
4273
|
+
status,
|
|
4274
|
+
fetchAuth = true,
|
|
4275
|
+
filterSelection,
|
|
4276
|
+
group,
|
|
4277
|
+
selectedIssues = [],
|
|
4278
|
+
page = defaultPage3,
|
|
4279
|
+
perPage = defaultPerPage3,
|
|
4280
|
+
sortOptions = [],
|
|
4281
|
+
selectedAttributes = getSelectedDeviceAttribute(getState())
|
|
4282
|
+
} = options;
|
|
4283
|
+
const state = getState();
|
|
4284
|
+
const { applicableFilters, filterTerms } = convertDeviceListStateToFilters({
|
|
4285
|
+
filters: filterSelection ?? getDeviceFilters(state),
|
|
4286
|
+
group: group ?? getSelectedGroup(state),
|
|
4287
|
+
groups: state.devices.groups,
|
|
4288
|
+
offlineThreshold: state.app.offlineThreshold,
|
|
4289
|
+
selectedIssues,
|
|
4290
|
+
status
|
|
4291
|
+
});
|
|
4292
|
+
const attributes = [...defaultAttributes, getIdAttribute(getState()), ...selectedAttributes];
|
|
4293
|
+
return general_api_default.post(getSearchEndpoint(getState()), {
|
|
4294
|
+
page,
|
|
4295
|
+
per_page: perPage,
|
|
4296
|
+
filters: filterTerms,
|
|
4297
|
+
sort: sortOptions,
|
|
4298
|
+
attributes
|
|
4299
|
+
}).then((response) => {
|
|
4300
|
+
const state2 = getState();
|
|
4301
|
+
const deviceAccu = reduceReceivedDevices(response.data, [], state2, status);
|
|
4302
|
+
let total = !applicableFilters.length ? Number(response.headers[headerNames.total]) : null;
|
|
4303
|
+
if (status && state2.devices.byStatus[status].total === deviceAccu.ids.length) {
|
|
4304
|
+
total = deviceAccu.ids.length;
|
|
4305
|
+
}
|
|
4306
|
+
let tasks = [dispatch(actions3.receivedDevices(deviceAccu.devicesById))];
|
|
4307
|
+
if (status) {
|
|
4308
|
+
tasks.push(dispatch(actions3.setDevicesByStatus({ deviceIds: deviceAccu.ids, status, total })));
|
|
4309
|
+
}
|
|
4310
|
+
const receivedDevices = Object.values(deviceAccu.devicesById);
|
|
4311
|
+
if (receivedDevices.length && fetchAuth) {
|
|
4312
|
+
tasks.push(dispatch(getDevicesWithAuth(receivedDevices)));
|
|
4313
|
+
}
|
|
4314
|
+
tasks.push(Promise.resolve({ deviceAccu, total: Number(response.headers[headerNames.total]) }));
|
|
4315
|
+
return Promise.all(tasks);
|
|
4316
|
+
}).catch((err) => commonErrorHandler(err, `${status} devices couldn't be loaded.`, dispatch, commonErrorFallback));
|
|
4317
|
+
});
|
|
4318
|
+
var getAllDevicesByStatus = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/getAllDevicesByStatus`, (status, { dispatch, getState }) => {
|
|
4319
|
+
const attributes = [...defaultAttributes, getIdAttribute(getState())];
|
|
4320
|
+
const getAllDevices = (perPage = MAX_PAGE_SIZE, page = 1, devices = []) => general_api_default.post(getSearchEndpoint(getState()), {
|
|
4321
|
+
page,
|
|
4322
|
+
per_page: perPage,
|
|
4323
|
+
filters: mapFiltersToTerms([{ key: "status", value: status, operator: DEVICE_FILTERING_OPTIONS.$eq.key, scope: "identity" }]),
|
|
4324
|
+
attributes
|
|
4325
|
+
}).then((res) => {
|
|
4326
|
+
const state = getState();
|
|
4327
|
+
const deviceAccu = reduceReceivedDevices(res.data, devices, state, status);
|
|
4328
|
+
dispatch(actions3.receivedDevices(deviceAccu.devicesById));
|
|
4329
|
+
const total = Number(res.headers[headerNames.total]);
|
|
4330
|
+
if (total > state.deployments.deploymentDeviceLimit) {
|
|
4331
|
+
return Promise.resolve();
|
|
4332
|
+
}
|
|
4333
|
+
if (total > perPage * page) {
|
|
4334
|
+
return getAllDevices(perPage, page + 1, deviceAccu.ids);
|
|
4335
|
+
}
|
|
4336
|
+
let tasks = [dispatch(actions3.setDevicesByStatus({ deviceIds: deviceAccu.ids, forceUpdate: true, status, total: deviceAccu.ids.length }))];
|
|
4337
|
+
if (status === DEVICE_STATES.accepted && deviceAccu.ids.length === total) {
|
|
4338
|
+
tasks.push(dispatch(deriveInactiveDevices(deviceAccu.ids)));
|
|
4339
|
+
tasks.push(dispatch(deriveReportsData()));
|
|
4340
|
+
}
|
|
4341
|
+
return Promise.all(tasks);
|
|
4342
|
+
});
|
|
4343
|
+
return getAllDevices();
|
|
4344
|
+
});
|
|
4345
|
+
var searchDevices = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/searchDevices`, (passedOptions = {}, { dispatch, getState }) => {
|
|
4346
|
+
const state = getState();
|
|
4347
|
+
let options = { ...state.app.searchState, ...passedOptions };
|
|
4348
|
+
const { page = defaultPage3, searchTerm, sortOptions = [] } = options;
|
|
4349
|
+
const { columnSelection = [] } = getUserSettings(state);
|
|
4350
|
+
const selectedAttributes = columnSelection.map((column) => ({ attribute: column.key, scope: column.scope }));
|
|
4351
|
+
const attributes = (0, import_helpers10.attributeDuplicateFilter)([...defaultAttributes, getIdAttribute(state), ...selectedAttributes], "attribute");
|
|
4352
|
+
return general_api_default.post(getSearchEndpoint(getState()), {
|
|
4353
|
+
page,
|
|
4354
|
+
per_page: 10,
|
|
4355
|
+
filters: [],
|
|
4356
|
+
sort: sortOptions,
|
|
4357
|
+
text: searchTerm,
|
|
4358
|
+
attributes
|
|
4359
|
+
}).then((response) => {
|
|
4360
|
+
const deviceAccu = reduceReceivedDevices(response.data, [], getState());
|
|
4361
|
+
return Promise.all([
|
|
4362
|
+
dispatch(actions3.receivedDevices(deviceAccu.devicesById)),
|
|
4363
|
+
Promise.resolve({ deviceIds: deviceAccu.ids, searchTotal: Number(response.headers[headerNames.total]) })
|
|
4364
|
+
]);
|
|
4365
|
+
}).catch((err) => commonErrorHandler(err, `devices couldn't be searched.`, dispatch, commonErrorFallback));
|
|
4366
|
+
});
|
|
4367
|
+
var ATTRIBUTE_LIST_CUTOFF = 100;
|
|
4368
|
+
var attributeReducer = (attributes = []) => attributes.slice(0, ATTRIBUTE_LIST_CUTOFF).reduce(
|
|
4369
|
+
(accu, { name, scope }) => {
|
|
4370
|
+
if (!accu[scope]) {
|
|
4371
|
+
accu[scope] = [];
|
|
4372
|
+
}
|
|
4373
|
+
accu[scope].push(name);
|
|
4387
4374
|
return accu;
|
|
4388
4375
|
},
|
|
4389
|
-
{
|
|
4376
|
+
{ identity: [], inventory: [], system: [], tags: [] }
|
|
4390
4377
|
);
|
|
4391
|
-
var
|
|
4392
|
-
`${
|
|
4393
|
-
(_, { dispatch, getState }) => general_api_default.get(
|
|
4394
|
-
const
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
let permissionSetObject = { ...permissionSetState, ...permissionSet };
|
|
4398
|
-
permissionSetObject.result = Object.values(uiPermissionsById).reduce(
|
|
4399
|
-
(accu2, item) => Object.entries(item.permissionSets).reduce((collector, [area, permissionSet2]) => {
|
|
4400
|
-
if (scopedPermissionAreas[area]) {
|
|
4401
|
-
return collector;
|
|
4402
|
-
}
|
|
4403
|
-
if (permissionSet2 === permissionSetObject.name) {
|
|
4404
|
-
collector[area] = [...collector[area], item.value].filter(import_helpers10.duplicateFilter);
|
|
4405
|
-
}
|
|
4406
|
-
return collector;
|
|
4407
|
-
}, accu2),
|
|
4408
|
-
{ ...emptyUiPermissions, ...permissionSetObject.result ?? {} }
|
|
4409
|
-
);
|
|
4410
|
-
const scopes = Object.values(scopedPermissionAreas).reduce((accu2, { key, scopeType }) => {
|
|
4411
|
-
if (permissionSetObject.supported_scope_types?.includes(key) || permissionSetObject.supported_scope_types?.includes(scopeType)) {
|
|
4412
|
-
accu2.push(key);
|
|
4413
|
-
}
|
|
4414
|
-
return accu2;
|
|
4415
|
-
}, []);
|
|
4416
|
-
permissionSetObject = scopes.reduce((accu2, scope) => {
|
|
4417
|
-
accu2.result[scope] = mapPermissionSet(permissionSetObject.name, [scopedPermissionAreas[scope].excessiveAccessSelector], scope);
|
|
4418
|
-
return accu2;
|
|
4419
|
-
}, permissionSetObject);
|
|
4420
|
-
accu[permissionSet.name] = permissionSetObject;
|
|
4421
|
-
return accu;
|
|
4422
|
-
},
|
|
4423
|
-
// @ts-ignore
|
|
4424
|
-
{ ...getState().users.permissionSetsById }
|
|
4425
|
-
);
|
|
4426
|
-
return Promise.all([dispatch(actions8.receivedPermissionSets(permissionSets)), permissionSets]);
|
|
4427
|
-
}).catch(() => console.log("Permission set retrieval failed - likely accessing a non-RBAC backend"))
|
|
4378
|
+
var getDeviceAttributes = (0, import_toolkit21.createAsyncThunk)(
|
|
4379
|
+
`${sliceName3}/getDeviceAttributes`,
|
|
4380
|
+
(_, { dispatch, getState }) => general_api_default.get(getAttrsEndpoint(getState())).then(({ data }) => {
|
|
4381
|
+
const { identity: identityAttributes, inventory: inventoryAttributes, system: systemAttributes, tags: tagAttributes } = attributeReducer(data || []);
|
|
4382
|
+
return dispatch(actions3.setFilterAttributes({ identityAttributes, inventoryAttributes, systemAttributes, tagAttributes }));
|
|
4383
|
+
})
|
|
4428
4384
|
);
|
|
4429
|
-
var
|
|
4430
|
-
`${
|
|
4431
|
-
(_, { dispatch
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
}
|
|
4435
|
-
|
|
4436
|
-
const rolesById2 = normalizeRbacRoles(roles, getRolesById(getState()), permissionSetTasks[permissionSetTasks.length - 1]);
|
|
4437
|
-
return Promise.resolve(dispatch(actions8.receivedRoles(rolesById2)));
|
|
4438
|
-
}).catch(() => console.log("Role retrieval failed - likely accessing a non-RBAC backend"))
|
|
4385
|
+
var getReportingLimits = (0, import_toolkit21.createAsyncThunk)(
|
|
4386
|
+
`${sliceName3}/getReportingLimits`,
|
|
4387
|
+
(_, { dispatch }) => general_api_default.get(`${reportingApiUrl}/devices/attributes`).catch((err) => commonErrorHandler(err, `filterable attributes limit & usage could not be retrieved.`, dispatch, commonErrorFallback)).then(({ data }) => {
|
|
4388
|
+
const { attributes, count, limit } = data;
|
|
4389
|
+
const groupedAttributes = attributeReducer(attributes);
|
|
4390
|
+
return Promise.resolve(dispatch(actions3.setFilterablesConfig({ count, limit, attributes: groupedAttributes })));
|
|
4391
|
+
})
|
|
4439
4392
|
);
|
|
4440
|
-
var
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
)
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
}
|
|
4393
|
+
var ensureVersionString = (software, fallback) => software.length && software !== "artifact_name" ? software.endsWith(".version") ? software : `${software}.version` : fallback;
|
|
4394
|
+
var getSingleReportData = (reportConfig, groups) => {
|
|
4395
|
+
const { attribute, group, software = "" } = reportConfig;
|
|
4396
|
+
const filters = [{ key: "status", scope: "identity", operator: DEVICE_FILTERING_OPTIONS.$eq.key, value: "accepted" }];
|
|
4397
|
+
if (group) {
|
|
4398
|
+
const staticGroupFilter = { key: "group", scope: "system", operator: DEVICE_FILTERING_OPTIONS.$eq.key, value: group };
|
|
4399
|
+
const { cleanedFilters: groupFilters } = getGroupFilters(group, groups);
|
|
4400
|
+
filters.push(...groupFilters.length ? groupFilters : [staticGroupFilter]);
|
|
4401
|
+
}
|
|
4402
|
+
const aggregationAttribute = ensureVersionString(software, attribute);
|
|
4403
|
+
return general_api_default.post(`${reportingApiUrl}/devices/aggregate`, {
|
|
4404
|
+
aggregations: [{ attribute: aggregationAttribute, name: "*", scope: "inventory", size: REPORT_CHART_SIZE_LIMIT }],
|
|
4405
|
+
filters: mapFiltersToTerms(filters)
|
|
4406
|
+
}).then(({ data }) => ({ data, reportConfig }));
|
|
4451
4407
|
};
|
|
4452
|
-
var
|
|
4453
|
-
const
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
};
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
};
|
|
4465
|
-
|
|
4466
|
-
|
|
4408
|
+
var getReportsData = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/getReportsData`, (_, { dispatch, getState }) => {
|
|
4409
|
+
const state = getState();
|
|
4410
|
+
const currentUserId = getCurrentUser(state).id;
|
|
4411
|
+
const reports = getUserSettings(state).reports || getGlobalSettings(state)[`${currentUserId}-reports`] || (Object.keys(getDevicesById(state)).length ? defaultReports : []);
|
|
4412
|
+
return Promise.all(reports.map((report) => getSingleReportData(report, getState().devices.groups))).then((results) => {
|
|
4413
|
+
const devicesState = getState().devices;
|
|
4414
|
+
const totalDeviceCount = devicesState.byStatus.accepted.total;
|
|
4415
|
+
const newReports = results.map(({ data, reportConfig }) => {
|
|
4416
|
+
let { items, other_count } = data[0];
|
|
4417
|
+
const { attribute, group, software = "" } = reportConfig;
|
|
4418
|
+
const dataCount = items.reduce((accu, item) => accu + item.count, 0);
|
|
4419
|
+
const otherCount = !group && (software === rootfsImageVersion || attribute === "artifact_name") ? totalDeviceCount - dataCount : other_count;
|
|
4420
|
+
return { items, otherCount, total: otherCount + dataCount };
|
|
4421
|
+
});
|
|
4422
|
+
return Promise.resolve(dispatch(actions3.setDeviceReports(newReports)));
|
|
4423
|
+
});
|
|
4424
|
+
});
|
|
4425
|
+
var initializeDistributionData = (report, groups, devices, totalDeviceCount) => {
|
|
4426
|
+
const { attribute, group = "", software = "" } = report;
|
|
4427
|
+
const effectiveAttribute = software ? software : attribute;
|
|
4428
|
+
const { deviceIds, total = 0 } = groups[group] || {};
|
|
4429
|
+
const relevantDevices = groups[group] ? deviceIds.map((id) => devices[id]) : Object.values(devices);
|
|
4430
|
+
const distributionByAttribute = relevantDevices.reduce((accu, item) => {
|
|
4431
|
+
if (!item.attributes || item.status !== DEVICE_STATES.accepted) return accu;
|
|
4432
|
+
if (!accu[item.attributes[effectiveAttribute]]) {
|
|
4433
|
+
accu[item.attributes[effectiveAttribute]] = 0;
|
|
4434
|
+
}
|
|
4435
|
+
accu[item.attributes[effectiveAttribute]] = accu[item.attributes[effectiveAttribute]] + 1;
|
|
4467
4436
|
return accu;
|
|
4468
4437
|
}, {});
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
});
|
|
4438
|
+
const distributionByAttributeSorted = Object.entries(distributionByAttribute).sort((pairA, pairB) => pairB[1] - pairA[1]);
|
|
4439
|
+
const items = distributionByAttributeSorted.map(([key, count]) => ({ key, count }));
|
|
4440
|
+
const dataCount = items.reduce((accu, item) => accu + item.count, 0);
|
|
4441
|
+
const otherCount = (groups[group] ? total : totalDeviceCount) - dataCount;
|
|
4442
|
+
return { items, otherCount, total: otherCount + dataCount };
|
|
4475
4443
|
};
|
|
4476
|
-
var
|
|
4477
|
-
const
|
|
4478
|
-
const {
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
} else if (uiPermissions[key]) {
|
|
4484
|
-
accu.maybeUiPermissions[key] = uiPermissions[key].reduce(itemUiPermissionsReducer, emptyPermissions);
|
|
4485
|
-
}
|
|
4486
|
-
return accu;
|
|
4487
|
-
},
|
|
4488
|
-
{ maybeUiPermissions: {}, remainderKeys: [] }
|
|
4489
|
-
);
|
|
4490
|
-
const { permissionSetsWithScope, roleUiPermissions } = remainderKeys.reduce(
|
|
4491
|
-
(accu, area) => {
|
|
4492
|
-
const areaPermissions = role.uiPermissions[area];
|
|
4493
|
-
if (!Array.isArray(areaPermissions)) {
|
|
4494
|
-
return accu;
|
|
4495
|
-
}
|
|
4496
|
-
const impliedPermissions = deriveImpliedAreaPermissions(area, areaPermissions);
|
|
4497
|
-
accu.roleUiPermissions[area] = impliedPermissions;
|
|
4498
|
-
const mappedPermissions = impliedPermissions.map((uiPermission) => ({ name: uiPermissionsById[uiPermission].permissionSets[area] }));
|
|
4499
|
-
accu.permissionSetsWithScope.push(...mappedPermissions);
|
|
4500
|
-
return accu;
|
|
4501
|
-
},
|
|
4502
|
-
{ permissionSetsWithScope: [{ name: defaultPermissionSets.Basic.name }], roleUiPermissions: {} }
|
|
4503
|
-
);
|
|
4504
|
-
const scopedPermissionSets = Object.values(scopedPermissionAreas).reduce((accu, { key, excessiveAccessSelector }) => {
|
|
4505
|
-
if (!uiPermissions[key]) {
|
|
4506
|
-
return accu;
|
|
4444
|
+
var deriveReportsData = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/deriveReportsData`, (_, { dispatch, getState }) => {
|
|
4445
|
+
const state = getState();
|
|
4446
|
+
const {
|
|
4447
|
+
groups: { byId: groupsById },
|
|
4448
|
+
byId,
|
|
4449
|
+
byStatus: {
|
|
4450
|
+
accepted: { total }
|
|
4507
4451
|
}
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
return
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4452
|
+
} = state.devices;
|
|
4453
|
+
const reports = getUserSettings(state).reports || state.users.globalSettings[`${state.users.currentUser}-reports`] || (Object.keys(byId).length ? defaultReports : []);
|
|
4454
|
+
const newReports = reports.map((report) => initializeDistributionData(report, groupsById, byId, total));
|
|
4455
|
+
return Promise.resolve(dispatch(actions3.setDeviceReports(newReports)));
|
|
4456
|
+
});
|
|
4457
|
+
var getReportsDataWithoutBackendSupport = (0, import_toolkit21.createAsyncThunk)(
|
|
4458
|
+
`${sliceName3}/getReportsDataWithoutBackendSupport`,
|
|
4459
|
+
(_, { dispatch, getState }) => Promise.all([dispatch(getAllDevicesByStatus(DEVICE_STATES.accepted)), dispatch(getGroups2()), dispatch(getDynamicGroups())]).then(() => {
|
|
4460
|
+
const { dynamic: dynamicGroups, static: staticGroups } = getGroups(getState());
|
|
4461
|
+
return Promise.all([
|
|
4462
|
+
...staticGroups.map(({ groupId }) => dispatch(getAllGroupDevices(groupId))),
|
|
4463
|
+
...dynamicGroups.map(({ groupId }) => dispatch(getAllDynamicGroupDevices(groupId)))
|
|
4464
|
+
]).then(() => dispatch(deriveReportsData()));
|
|
4465
|
+
})
|
|
4466
|
+
);
|
|
4467
|
+
var getDeviceConnect = (0, import_toolkit21.createAsyncThunk)(
|
|
4468
|
+
`${sliceName3}/getDeviceConnect`,
|
|
4469
|
+
(id, { dispatch }) => general_api_default.get(`${deviceConnect}/devices/${id}`).then(
|
|
4470
|
+
({ data }) => Promise.all([dispatch(actions3.receivedDevice({ connect_status: data.status, connect_updated_ts: data.updated_ts, id })), Promise.resolve(data)])
|
|
4471
|
+
)
|
|
4472
|
+
);
|
|
4473
|
+
var updateTypeMap = { deploymentUpdate: "check-update", inventoryUpdate: "send-inventory" };
|
|
4474
|
+
var triggerDeviceUpdate = (0, import_toolkit21.createAsyncThunk)(
|
|
4475
|
+
`${sliceName3}/triggerDeviceUpdate`,
|
|
4476
|
+
({ id, type }, { dispatch }) => general_api_default.post(`${deviceConnect}/devices/${id}/${updateTypeMap[type] ?? updateTypeMap.deploymentUpdate}`).then(
|
|
4477
|
+
() => new Promise((resolve) => setTimeout(() => resolve(dispatch(getDeviceById2(id))), TIMEOUTS.threeSeconds))
|
|
4478
|
+
)
|
|
4479
|
+
);
|
|
4480
|
+
var getSessionDetails = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/getSessionDetails`, ({ sessionId, deviceId, userId, startDate, endDate }) => {
|
|
4481
|
+
const { start: startUnix, end: endUnix } = (0, import_helpers10.dateRangeToUnix)(startDate, endDate);
|
|
4482
|
+
const createdAfter = startDate ? `&created_after=${startUnix}` : "";
|
|
4483
|
+
const createdBefore = endDate ? `&created_before=${endUnix}` : "";
|
|
4484
|
+
const objectSearch = `&object_id=${deviceId}`;
|
|
4485
|
+
return general_api_default.get(`${auditLogsApiUrl}/logs?per_page=500${createdAfter}${createdBefore}&actor_id=${userId}${objectSearch}`).then(
|
|
4486
|
+
({ data: auditLogEntries }) => {
|
|
4487
|
+
const { start, end } = auditLogEntries.reduce(
|
|
4488
|
+
(accu, item) => {
|
|
4489
|
+
if (item.meta?.session_id?.includes(sessionId)) {
|
|
4490
|
+
accu.start = new Date(item.action.startsWith("open") ? item.time : accu.start);
|
|
4491
|
+
accu.end = new Date(item.action.startsWith("close") ? item.time : accu.end);
|
|
4492
|
+
}
|
|
4493
|
+
return accu;
|
|
4494
|
+
},
|
|
4495
|
+
{ start: startDate || endDate, end: endDate || startDate }
|
|
4496
|
+
);
|
|
4497
|
+
return Promise.resolve({ start, end });
|
|
4523
4498
|
}
|
|
4524
|
-
|
|
4525
|
-
};
|
|
4526
|
-
var roleActions = {
|
|
4527
|
-
create: {
|
|
4528
|
-
successMessage: "The role was created successfully.",
|
|
4529
|
-
errorMessage: "creating"
|
|
4530
|
-
},
|
|
4531
|
-
edit: {
|
|
4532
|
-
successMessage: "The role has been updated.",
|
|
4533
|
-
errorMessage: "editing"
|
|
4534
|
-
},
|
|
4535
|
-
remove: {
|
|
4536
|
-
successMessage: "The role was deleted successfully.",
|
|
4537
|
-
errorMessage: "removing"
|
|
4538
|
-
}
|
|
4539
|
-
};
|
|
4540
|
-
var roleActionErrorHandler = (err, type, dispatch) => commonErrorHandler(err, `There was an error ${roleActions[type].errorMessage} the role.`, dispatch);
|
|
4541
|
-
var createRole = (0, import_toolkit21.createAsyncThunk)(`${sliceName8}/createRole`, (roleData, { dispatch }) => {
|
|
4542
|
-
const { permissionSetsWithScope, role } = transformRoleDataToRole(roleData);
|
|
4543
|
-
return general_api_default.post(`${useradmApiUrlv2}/roles`, {
|
|
4544
|
-
name: role.name,
|
|
4545
|
-
description: role.description,
|
|
4546
|
-
permission_sets_with_scope: permissionSetsWithScope
|
|
4547
|
-
}).then(() => Promise.all([dispatch(actions8.createdRole(role)), dispatch(getRoles()), dispatch(setSnackbar4(roleActions.create.successMessage))])).catch((err) => roleActionErrorHandler(err, "create", dispatch));
|
|
4499
|
+
);
|
|
4548
4500
|
});
|
|
4549
|
-
var
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4501
|
+
var getDeviceFileDownloadLink = (0, import_toolkit21.createAsyncThunk)(
|
|
4502
|
+
`${sliceName3}/getDeviceFileDownloadLink`,
|
|
4503
|
+
({ deviceId, path }) => Promise.resolve(`${window.location.origin}${deviceConnect}/devices/${deviceId}/download?path=${encodeURIComponent(path)}`)
|
|
4504
|
+
);
|
|
4505
|
+
var deviceFileUpload = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/deviceFileUpload`, ({ deviceId, path, file }, { dispatch }) => {
|
|
4506
|
+
let formData = new FormData();
|
|
4507
|
+
formData.append("path", path);
|
|
4508
|
+
formData.append("file", file);
|
|
4509
|
+
const uploadId = (0, import_uuid.v4)();
|
|
4510
|
+
const cancelSource = new AbortController();
|
|
4511
|
+
return Promise.all([
|
|
4512
|
+
dispatch(setSnackbar4("Uploading file")),
|
|
4513
|
+
dispatch(initUpload({ id: uploadId, upload: { inprogress: true, uploadProgress: 0, cancelSource } })),
|
|
4514
|
+
general_api_default.uploadPut(
|
|
4515
|
+
`${deviceConnect}/devices/${deviceId}/upload`,
|
|
4516
|
+
formData,
|
|
4517
|
+
(e) => dispatch(uploadProgress2({ id: uploadId, progress: progress(e) })),
|
|
4518
|
+
cancelSource.signal
|
|
4519
|
+
)
|
|
4520
|
+
]).then(() => Promise.resolve(dispatch(setSnackbar4("Upload successful", TIMEOUTS.fiveSeconds)))).catch((err) => {
|
|
4521
|
+
if ((0, import_axios3.isCancel)(err)) {
|
|
4522
|
+
return dispatch(setSnackbar4("The upload has been cancelled", TIMEOUTS.fiveSeconds));
|
|
4523
|
+
}
|
|
4524
|
+
return commonErrorHandler(err, `Error uploading file to device.`, dispatch);
|
|
4525
|
+
}).finally(() => dispatch(cleanUpUpload(uploadId)));
|
|
4526
|
+
});
|
|
4527
|
+
var getDeviceAuth = (0, import_toolkit21.createAsyncThunk)(
|
|
4528
|
+
`${sliceName3}/getDeviceAuth`,
|
|
4529
|
+
(id, { dispatch }) => dispatch(getDevicesWithAuth([{ id }])).unwrap().then((results) => {
|
|
4530
|
+
if (results[results.length - 1]) {
|
|
4531
|
+
return Promise.resolve(results[results.length - 1][0]);
|
|
4532
|
+
}
|
|
4533
|
+
return Promise.resolve();
|
|
4534
|
+
})
|
|
4535
|
+
);
|
|
4536
|
+
var getDevicesWithAuth = (0, import_toolkit21.createAsyncThunk)(
|
|
4537
|
+
`${sliceName3}/getDevicesWithAuth`,
|
|
4538
|
+
(devices, { dispatch, getState }) => devices.length ? general_api_default.get(`${deviceAuthV2}/devices?id=${devices.map((device) => device.id).join("&id=")}`).then(({ data: receivedDevices }) => {
|
|
4539
|
+
const { devicesById } = reduceReceivedDevices(receivedDevices, [], getState());
|
|
4540
|
+
return Promise.all([dispatch(actions3.receivedDevices(devicesById)), Promise.resolve(receivedDevices)]);
|
|
4541
|
+
}).catch((err) => commonErrorHandler(err, `Error: ${err}`, dispatch)) : Promise.resolve([[], []])
|
|
4542
|
+
);
|
|
4543
|
+
var updateDeviceAuth = (0, import_toolkit21.createAsyncThunk)(
|
|
4544
|
+
`${sliceName3}/updateDeviceAuth`,
|
|
4545
|
+
({ deviceId, authId, status }, { dispatch, getState }) => general_api_default.put(`${deviceAuthV2}/devices/${deviceId}/auth/${authId}/status`, { status }).then(() => Promise.all([dispatch(getDeviceAuth(deviceId)), dispatch(setSnackbar4("Device authorization status was updated successfully"))])).catch((err) => commonErrorHandler(err, "There was a problem updating the device authorization status:", dispatch)).then(() => Promise.resolve(dispatch(actions3.maybeUpdateDevicesByStatus({ deviceId, authId })))).finally(() => dispatch(setDeviceListState({ refreshTrigger: !getDeviceListState(getState()).refreshTrigger })))
|
|
4546
|
+
);
|
|
4547
|
+
var updateDevicesAuth = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/updateDevicesAuth`, ({ deviceIds, status }, { dispatch, getState }) => {
|
|
4548
|
+
let devices = getDevicesById(getState());
|
|
4549
|
+
const deviceIdsWithoutAuth = deviceIds.reduce((accu, id) => devices[id].auth_sets ? accu : [...accu, { id }], []);
|
|
4550
|
+
return dispatch(getDevicesWithAuth(deviceIdsWithoutAuth)).then(() => {
|
|
4551
|
+
devices = getDevicesById(getState());
|
|
4552
|
+
const deviceAuthUpdates = deviceIds.map((id) => {
|
|
4553
|
+
const device = devices[id];
|
|
4554
|
+
if (device.auth_sets.length !== 1) {
|
|
4555
|
+
return Promise.reject();
|
|
4556
|
+
}
|
|
4557
|
+
return dispatch(updateDeviceAuth({ authId: device.auth_sets[0].id, deviceId: device.id, status })).unwrap().catch((err) => commonErrorHandler(err, "The action was stopped as there was a problem updating a device authorization status: ", dispatch, "", false));
|
|
4558
|
+
});
|
|
4559
|
+
return Promise.allSettled(deviceAuthUpdates).then((results) => {
|
|
4560
|
+
const { skipped, count } = results.reduce(
|
|
4561
|
+
(accu, item) => {
|
|
4562
|
+
if (item.status === "rejected") {
|
|
4563
|
+
accu.skipped = accu.skipped + 1;
|
|
4564
|
+
} else {
|
|
4565
|
+
accu.count = accu.count + 1;
|
|
4566
|
+
}
|
|
4567
|
+
return accu;
|
|
4568
|
+
},
|
|
4569
|
+
{ skipped: 0, count: 0 }
|
|
4570
|
+
);
|
|
4571
|
+
const message = (0, import_helpers10.getSnackbarMessage)(skipped, count);
|
|
4572
|
+
return dispatch(setSnackbar4(message));
|
|
4573
|
+
});
|
|
4574
|
+
});
|
|
4556
4575
|
});
|
|
4557
|
-
var
|
|
4558
|
-
`${
|
|
4559
|
-
(
|
|
4560
|
-
// @ts-ignore
|
|
4561
|
-
general_api_default.delete(`${useradmApiUrlv2}/roles/${roleId}`).then(() => Promise.all([dispatch(actions8.removedRole(roleId)), dispatch(getRoles()), dispatch(setSnackbar4(roleActions.remove.successMessage))])).catch((err) => roleActionErrorHandler(err, "remove", dispatch))
|
|
4562
|
-
)
|
|
4576
|
+
var deleteAuthset = (0, import_toolkit21.createAsyncThunk)(
|
|
4577
|
+
`${sliceName3}/deleteAuthset`,
|
|
4578
|
+
({ deviceId, authId }, { dispatch, getState }) => general_api_default.delete(`${deviceAuthV2}/devices/${deviceId}/auth/${authId}`).then(() => Promise.all([dispatch(setSnackbar4("Device authorization status was updated successfully"))])).catch((err) => commonErrorHandler(err, "There was a problem updating the device authorization status:", dispatch)).then(() => Promise.resolve(dispatch(actions3.maybeUpdateDevicesByStatus({ deviceId, authId })))).finally(() => dispatch(setDeviceListState({ refreshTrigger: !getState().devices.deviceList.refreshTrigger })))
|
|
4563
4579
|
);
|
|
4564
|
-
var
|
|
4565
|
-
`${
|
|
4566
|
-
(
|
|
4567
|
-
|
|
4568
|
-
|
|
4580
|
+
var preauthDevice = (0, import_toolkit21.createAsyncThunk)(
|
|
4581
|
+
`${sliceName3}/preauthDevice`,
|
|
4582
|
+
(authset, { dispatch, rejectWithValue }) => general_api_default.post(`${deviceAuthV2}/devices`, authset).then(() => Promise.resolve(dispatch(setSnackbar4("Device was successfully added to the preauthorization list", TIMEOUTS.fiveSeconds)))).catch((err) => {
|
|
4583
|
+
if (err.response.status === 409) {
|
|
4584
|
+
return rejectWithValue("A device with a matching identity data set already exists");
|
|
4585
|
+
}
|
|
4586
|
+
return commonErrorHandler(err, "The device could not be added:", dispatch);
|
|
4569
4587
|
})
|
|
4570
4588
|
);
|
|
4571
|
-
var
|
|
4572
|
-
`${
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4589
|
+
var decommissionDevice = (0, import_toolkit21.createAsyncThunk)(
|
|
4590
|
+
`${sliceName3}/decommissionDevice`,
|
|
4591
|
+
({ deviceId, authId }, { dispatch, getState }) => general_api_default.delete(`${deviceAuthV2}/devices/${deviceId}`).then(() => Promise.resolve(dispatch(setSnackbar4("Device was decommissioned successfully")))).catch((err) => commonErrorHandler(err, "There was a problem decommissioning the device:", dispatch)).then(() => Promise.resolve(dispatch(actions3.maybeUpdateDevicesByStatus({ deviceId, authId })))).finally(() => dispatch(setDeviceListState({ refreshTrigger: !getState().devices.deviceList.refreshTrigger })))
|
|
4592
|
+
);
|
|
4593
|
+
var getDeviceConfig = (0, import_toolkit21.createAsyncThunk)(
|
|
4594
|
+
`${sliceName3}/getDeviceConfig`,
|
|
4595
|
+
(deviceId, { dispatch }) => general_api_default.get(`${deviceConfig}/${deviceId}`).then(({ data }) => Promise.all([dispatch(actions3.receivedDevice({ id: deviceId, config: data })), Promise.resolve(data)])).catch((err) => {
|
|
4596
|
+
if (err.response?.data?.error.status_code !== 404) {
|
|
4597
|
+
return commonErrorHandler(err, `There was an error retrieving the configuration for device ${deviceId}.`, dispatch, commonErrorFallback);
|
|
4577
4598
|
}
|
|
4578
|
-
|
|
4579
|
-
let updatedSettings = { ...getState().users.globalSettings, ...settings };
|
|
4580
|
-
if (getCurrentUser(getState()).verified) {
|
|
4581
|
-
updatedSettings["2fa"] = twoFAStates.enabled;
|
|
4582
|
-
} else {
|
|
4583
|
-
delete updatedSettings["2fa"];
|
|
4584
|
-
}
|
|
4585
|
-
let tasks = [dispatch(actions8.setGlobalSettings(updatedSettings))];
|
|
4586
|
-
const headers = result[result.length - 1] ? { "If-Match": result[result.length - 1] } : {};
|
|
4587
|
-
return general_api_default.post(`${useradmApiUrlv1}/settings`, updatedSettings, { headers }).then(() => {
|
|
4588
|
-
if (notify) {
|
|
4589
|
-
tasks.push(dispatch(setSnackbar4("Settings saved successfully")));
|
|
4590
|
-
}
|
|
4591
|
-
return Promise.all(tasks);
|
|
4592
|
-
}).catch((err) => {
|
|
4593
|
-
if (beOptimistic) {
|
|
4594
|
-
return Promise.all([tasks]);
|
|
4595
|
-
}
|
|
4596
|
-
console.log(err);
|
|
4597
|
-
return commonErrorHandler(err, `The settings couldn't be saved.`, dispatch);
|
|
4598
|
-
});
|
|
4599
|
-
});
|
|
4600
|
-
}
|
|
4599
|
+
})
|
|
4601
4600
|
);
|
|
4602
|
-
var
|
|
4603
|
-
`${
|
|
4604
|
-
(
|
|
4605
|
-
|
|
4606
|
-
|
|
4601
|
+
var setDeviceConfig = (0, import_toolkit21.createAsyncThunk)(
|
|
4602
|
+
`${sliceName3}/setDeviceConfig`,
|
|
4603
|
+
({ deviceId, config }, { dispatch }) => general_api_default.put(`${deviceConfig}/${deviceId}`, config).catch((err) => commonErrorHandler(err, `There was an error setting the configuration for device ${deviceId}.`, dispatch, commonErrorFallback)).then(() => Promise.resolve(dispatch(getDeviceConfig(deviceId))))
|
|
4604
|
+
);
|
|
4605
|
+
var applyDeviceConfig = (0, import_toolkit21.createAsyncThunk)(
|
|
4606
|
+
`${sliceName3}/applyDeviceConfig`,
|
|
4607
|
+
({ deviceId, configDeploymentConfiguration, isDefault, config }, { dispatch, getState }) => general_api_default.post(`${deviceConfig}/${deviceId}/deploy`, configDeploymentConfiguration).catch((err) => commonErrorHandler(err, `There was an error deploying the configuration to device ${deviceId}.`, dispatch, commonErrorFallback)).then(({ data }) => {
|
|
4608
|
+
const device = getDeviceById(getState(), deviceId);
|
|
4609
|
+
const { canManageUsers } = getUserCapabilities(getState());
|
|
4610
|
+
let tasks = [
|
|
4611
|
+
dispatch(actions3.receivedDevice({ ...device, config: { ...device.config, deployment_id: data.deployment_id } })),
|
|
4612
|
+
new Promise((resolve) => setTimeout(() => resolve(dispatch(getSingleDeployment(data.deployment_id))), TIMEOUTS.oneSecond))
|
|
4613
|
+
];
|
|
4614
|
+
if (isDefault && canManageUsers) {
|
|
4615
|
+
const { previous } = getGlobalSettings(getState()).defaultDeviceConfig ?? {};
|
|
4616
|
+
tasks.push(dispatch(saveGlobalSettings({ defaultDeviceConfig: { current: config, previous } })));
|
|
4617
|
+
}
|
|
4618
|
+
return Promise.all(tasks);
|
|
4607
4619
|
})
|
|
4608
4620
|
);
|
|
4609
|
-
var
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4621
|
+
var setDeviceTags = (0, import_toolkit21.createAsyncThunk)(
|
|
4622
|
+
`${sliceName3}/setDeviceTags`,
|
|
4623
|
+
({ deviceId, tags }, { dispatch }) => (
|
|
4624
|
+
// to prevent tag set failures, retrieve the device & use the freshest etag we can get
|
|
4625
|
+
Promise.resolve(dispatch(getDeviceById2(deviceId))).then((device) => {
|
|
4626
|
+
const headers = device.etag ? { "If-Match": device.etag } : {};
|
|
4627
|
+
return general_api_default.put(
|
|
4628
|
+
`${inventoryApiUrl}/devices/${deviceId}/tags`,
|
|
4629
|
+
Object.entries(tags).map(([name, value]) => ({ name, value })),
|
|
4630
|
+
{ headers }
|
|
4631
|
+
).catch((err) => commonErrorHandler(err, `There was an error setting tags for device ${deviceId}.`, dispatch, "Please check your connection.")).then(() => Promise.all([dispatch(actions3.receivedDevice({ ...device, id: deviceId, tags })), dispatch(setSnackbar4("Device name changed"))]));
|
|
4632
|
+
})
|
|
4633
|
+
)
|
|
4634
|
+
);
|
|
4635
|
+
var getDeviceTwin = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/getDeviceTwin`, ({ deviceId, integration }, { dispatch, getState }) => {
|
|
4636
|
+
let providerResult = {};
|
|
4637
|
+
return general_api_default.get(`${iotManagerBaseURL}/devices/${deviceId}/state`).then(({ data }) => {
|
|
4638
|
+
providerResult = { ...data, twinError: "" };
|
|
4639
|
+
}).catch((err) => {
|
|
4640
|
+
providerResult = {
|
|
4641
|
+
twinError: `There was an error getting the ${EXTERNAL_PROVIDER[integration.provider].twinTitle.toLowerCase()} for device ${deviceId}. ${err}`
|
|
4627
4642
|
};
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
general_api_default.post(`${useradmApiUrlv1}/settings/me`, updatedSettings, { headers })
|
|
4632
|
-
]).catch(() => dispatch(actions8.setUserSettings(userSettings)));
|
|
4643
|
+
}).finally(() => {
|
|
4644
|
+
const device = getDeviceById(getState(), deviceId);
|
|
4645
|
+
Promise.resolve(dispatch(actions3.receivedDevice({ ...device, twinsByIntegration: { ...device.twinsByIntegration, ...providerResult } })));
|
|
4633
4646
|
});
|
|
4634
4647
|
});
|
|
4635
|
-
var
|
|
4636
|
-
`${
|
|
4637
|
-
(
|
|
4638
|
-
)
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
})
|
|
4649
|
-
|
|
4650
|
-
`${sliceName8}/getTokens`,
|
|
4651
|
-
(_, { dispatch, getState }) => general_api_default.get(`${useradmApiUrlv1}/settings/tokens`).then(({ data: tokens }) => {
|
|
4652
|
-
const user = getCurrentUser(getState());
|
|
4653
|
-
const updatedUser = {
|
|
4654
|
-
...user,
|
|
4655
|
-
tokens
|
|
4656
|
-
};
|
|
4657
|
-
return Promise.resolve(dispatch(actions8.updatedUser(updatedUser)));
|
|
4648
|
+
var setDeviceTwin = (0, import_toolkit21.createAsyncThunk)(
|
|
4649
|
+
`${sliceName3}/setDeviceTwin`,
|
|
4650
|
+
({ deviceId, integration, settings }, { dispatch, getState }) => general_api_default.put(`${iotManagerBaseURL}/devices/${deviceId}/state/${integration.id}`, { desired: settings }).catch(
|
|
4651
|
+
(err) => commonErrorHandler(
|
|
4652
|
+
err,
|
|
4653
|
+
`There was an error updating the ${EXTERNAL_PROVIDER[integration.provider].twinTitle.toLowerCase()} for device ${deviceId}.`,
|
|
4654
|
+
dispatch
|
|
4655
|
+
)
|
|
4656
|
+
).then(() => {
|
|
4657
|
+
const device = getDeviceById(getState(), deviceId);
|
|
4658
|
+
const { twinsByIntegration = {} } = device;
|
|
4659
|
+
const { [integration.id]: currentState = {} } = twinsByIntegration;
|
|
4660
|
+
return Promise.resolve(
|
|
4661
|
+
dispatch(actions3.receivedDevice({ ...device, twinsByIntegration: { ...twinsByIntegration, [integration.id]: { ...currentState, desired: settings } } }))
|
|
4662
|
+
);
|
|
4658
4663
|
})
|
|
4659
4664
|
);
|
|
4660
|
-
var
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
);
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
)
|
|
4671
|
-
)
|
|
4672
|
-
|
|
4673
|
-
let tasks = [dispatch(actions8.setTooltipState(remainder))];
|
|
4674
|
-
if (persist) {
|
|
4675
|
-
tasks.push(dispatch(saveUserSettings()));
|
|
4665
|
+
var prepareSearchArguments = ({ filters, group, state, status }) => {
|
|
4666
|
+
const { filterTerms } = convertDeviceListStateToFilters({ filters, group, offlineThreshold: state.app.offlineThreshold, selectedIssues: [], status });
|
|
4667
|
+
const { columnSelection = [] } = getUserSettings(state);
|
|
4668
|
+
const selectedAttributes = columnSelection.map((column) => ({ attribute: column.key, scope: column.scope }));
|
|
4669
|
+
const attributes = [...defaultAttributes, getIdAttribute(state), ...selectedAttributes];
|
|
4670
|
+
return { attributes, filterTerms };
|
|
4671
|
+
};
|
|
4672
|
+
var getSystemDevices = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/getSystemDevices`, (options, { dispatch, getState }) => {
|
|
4673
|
+
const { id, page = defaultPage3, perPage = defaultPerPage3, sortOptions = [] } = options;
|
|
4674
|
+
const state = getState();
|
|
4675
|
+
const { hasFullFiltering } = getTenantCapabilities(state);
|
|
4676
|
+
if (!hasFullFiltering) {
|
|
4677
|
+
return Promise.resolve();
|
|
4676
4678
|
}
|
|
4677
|
-
|
|
4679
|
+
const { attributes: deviceAttributes = {} } = getDeviceById(state, id);
|
|
4680
|
+
const { mender_gateway_system_id = "" } = deviceAttributes;
|
|
4681
|
+
const filters = [
|
|
4682
|
+
{ ...emptyFilter, key: "mender_is_gateway", operator: DEVICE_FILTERING_OPTIONS.$ne.key, value: "true", scope: "inventory" },
|
|
4683
|
+
{ ...emptyFilter, key: "mender_gateway_system_id", value: mender_gateway_system_id, scope: "inventory" }
|
|
4684
|
+
];
|
|
4685
|
+
const { attributes, filterTerms } = prepareSearchArguments({ filters, state });
|
|
4686
|
+
return general_api_default.post(getSearchEndpoint(getState()), {
|
|
4687
|
+
page,
|
|
4688
|
+
per_page: perPage,
|
|
4689
|
+
filters: filterTerms,
|
|
4690
|
+
sort: sortOptions,
|
|
4691
|
+
attributes
|
|
4692
|
+
}).catch((err) => commonErrorHandler(err, `There was an error getting system devices device ${id}.`, dispatch, "Please check your connection.")).then(({ data, headers }) => {
|
|
4693
|
+
const state2 = getState();
|
|
4694
|
+
const { devicesById, ids } = reduceReceivedDevices(data, [], state2);
|
|
4695
|
+
const device = {
|
|
4696
|
+
...getDeviceById(state2, id),
|
|
4697
|
+
systemDeviceIds: ids,
|
|
4698
|
+
systemDeviceTotal: Number(headers[headerNames.total])
|
|
4699
|
+
};
|
|
4700
|
+
return Promise.resolve(dispatch(actions3.receivedDevices({ ...devicesById, [id]: device })));
|
|
4701
|
+
});
|
|
4678
4702
|
});
|
|
4679
|
-
var
|
|
4680
|
-
const
|
|
4681
|
-
|
|
4703
|
+
var getGatewayDevices = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/getGatewayDevices`, (deviceId, { dispatch, getState }) => {
|
|
4704
|
+
const state = getState();
|
|
4705
|
+
const { attributes = {} } = getDeviceById(state, deviceId);
|
|
4706
|
+
const { mender_gateway_system_id = "" } = attributes;
|
|
4707
|
+
const filters = [
|
|
4708
|
+
{ ...emptyFilter, key: "id", operator: DEVICE_FILTERING_OPTIONS.$ne.key, value: deviceId, scope: "identity" },
|
|
4709
|
+
{ ...emptyFilter, key: "mender_is_gateway", value: "true", scope: "inventory" },
|
|
4710
|
+
{ ...emptyFilter, key: "mender_gateway_system_id", value: mender_gateway_system_id, scope: "inventory" }
|
|
4711
|
+
];
|
|
4712
|
+
const { attributes: attributeSelection, filterTerms } = prepareSearchArguments({ filters, state });
|
|
4713
|
+
return general_api_default.post(getSearchEndpoint(getState()), {
|
|
4714
|
+
page: 1,
|
|
4715
|
+
per_page: MAX_PAGE_SIZE,
|
|
4716
|
+
filters: filterTerms,
|
|
4717
|
+
attributes: attributeSelection
|
|
4718
|
+
}).then(({ data }) => {
|
|
4719
|
+
const { ids } = reduceReceivedDevices(data, [], getState());
|
|
4720
|
+
let tasks = ids.map((deviceId2) => dispatch(getDeviceInfo(deviceId2)));
|
|
4721
|
+
tasks.push(dispatch(actions3.receivedDevice({ id: deviceId, gatewayIds: ids })));
|
|
4722
|
+
return Promise.all(tasks);
|
|
4723
|
+
});
|
|
4724
|
+
});
|
|
4725
|
+
var getDevicesInBounds = (0, import_toolkit21.createAsyncThunk)(`${sliceName3}/getDevicesInBounds`, ({ bounds, group }, { dispatch, getState }) => {
|
|
4726
|
+
const state = getState();
|
|
4727
|
+
const { filterTerms } = convertDeviceListStateToFilters({
|
|
4728
|
+
group: group === ALL_DEVICES ? void 0 : group,
|
|
4729
|
+
groups: state.devices.groups,
|
|
4730
|
+
status: DEVICE_STATES.accepted
|
|
4731
|
+
});
|
|
4732
|
+
return general_api_default.post(getSearchEndpoint(getState()), {
|
|
4733
|
+
page: 1,
|
|
4734
|
+
per_page: MAX_PAGE_SIZE,
|
|
4735
|
+
filters: filterTerms,
|
|
4736
|
+
attributes: geoAttributes,
|
|
4737
|
+
geo_bounding_box_filter: {
|
|
4738
|
+
geo_bounding_box: {
|
|
4739
|
+
location: {
|
|
4740
|
+
top_left: { lat: bounds._northEast.lat, lon: bounds._southWest.lng },
|
|
4741
|
+
bottom_right: { lat: bounds._southWest.lat, lon: bounds._northEast.lng }
|
|
4742
|
+
}
|
|
4743
|
+
}
|
|
4744
|
+
}
|
|
4745
|
+
}).then(({ data }) => {
|
|
4746
|
+
const { devicesById } = reduceReceivedDevices(data, [], getState());
|
|
4747
|
+
return Promise.resolve(dispatch(actions3.receivedDevices(devicesById)));
|
|
4748
|
+
});
|
|
4682
4749
|
});
|
|
4683
|
-
var submitFeedback = (0, import_toolkit21.createAsyncThunk)(
|
|
4684
|
-
`${sliceName8}/submitFeedback`,
|
|
4685
|
-
// @ts-ignore
|
|
4686
|
-
({ satisfaction, feedback, ...meta }, { dispatch }) => {
|
|
4687
|
-
return general_api_default.post(`${tenantadmApiUrlv2}/contact/support`, {
|
|
4688
|
-
subject: "feedback submission",
|
|
4689
|
-
body: JSON.stringify({ feedback, satisfaction, meta })
|
|
4690
|
-
}).then(() => {
|
|
4691
|
-
const today = /* @__PURE__ */ new Date();
|
|
4692
|
-
dispatch(saveUserSettings({ feedbackCollectedAt: today.toISOString().split("T")[0] }));
|
|
4693
|
-
setTimeout(() => dispatch(actions8.setShowFeedbackDialog(false)), TIMEOUTS.threeSeconds);
|
|
4694
|
-
});
|
|
4695
|
-
}
|
|
4696
|
-
);
|
|
4697
4750
|
|
|
4698
4751
|
// src/organizationSlice/thunks.ts
|
|
4699
4752
|
var import_helpers11 = require("@northern.tech/utils/helpers");
|
|
@@ -4770,7 +4823,7 @@ var startUpgrade = (0, import_toolkit22.createAsyncThunk)(
|
|
|
4770
4823
|
var cancelUpgrade = (0, import_toolkit22.createAsyncThunk)(`${sliceName6}/cancelUpgrade`, (tenantId) => general_api_default.post(`${tenantadmApiUrlv2}/tenants/${tenantId}/upgrade/cancel`));
|
|
4771
4824
|
var completeUpgrade = (0, import_toolkit22.createAsyncThunk)(
|
|
4772
4825
|
`${sliceName6}/completeUpgrade`,
|
|
4773
|
-
({ tenantId, plan }, { dispatch }) => general_api_default.post(`${tenantadmApiUrlv2}/tenants/${tenantId}/upgrade/complete`, { plan }).catch((err) => commonErrorHandler(err, `There was an error upgrading your account:`, dispatch)).then(() => Promise.
|
|
4826
|
+
({ tenantId, plan, billing_profile }, { dispatch }) => general_api_default.post(`${tenantadmApiUrlv2}/tenants/${tenantId}/upgrade/complete`, { plan, billing_profile }).catch((err) => commonErrorHandler(err, `There was an error upgrading your account:`, dispatch)).then(() => Promise.all([dispatch(getDeviceLimit2()), dispatch(getUserOrganization())]))
|
|
4774
4827
|
);
|
|
4775
4828
|
var prepareAuditlogQuery = ({ startDate, endDate, user: userFilter, type, detail: detailFilter, sort = {} }) => {
|
|
4776
4829
|
const userId = userFilter?.id || userFilter;
|
|
@@ -4819,7 +4872,12 @@ var setAuditlogsState = (0, import_toolkit22.createAsyncThunk)(`${sliceName6}/se
|
|
|
4819
4872
|
});
|
|
4820
4873
|
var tenantDataDivergedMessage = "The system detected there is a change in your plan or purchased add-ons. Please log out and log in again";
|
|
4821
4874
|
var addTenant = (0, import_toolkit22.createAsyncThunk)(`${sliceName6}/createTenant`, (selectionState, { dispatch }) => {
|
|
4822
|
-
return general_api_default.post(`${tenantadmApiUrlv2}/tenants`, selectionState).then(
|
|
4875
|
+
return general_api_default.post(`${tenantadmApiUrlv2}/tenants`, selectionState).then(
|
|
4876
|
+
() => Promise.all([
|
|
4877
|
+
dispatch(setSnackbar5("Tenant was created successfully.")),
|
|
4878
|
+
new Promise((resolve) => setTimeout(() => resolve(dispatch(getTenants())), TIMEOUTS.oneSecond))
|
|
4879
|
+
])
|
|
4880
|
+
).catch((err) => commonErrorHandler(err, "There was an error creating tenant", dispatch, commonErrorFallback));
|
|
4823
4881
|
});
|
|
4824
4882
|
var tenantListRetrieval = async (config) => {
|
|
4825
4883
|
const { page, perPage } = config;
|
|
@@ -4847,15 +4905,20 @@ var setTenantsListState = (0, import_toolkit22.createAsyncThunk)(`${sliceName6}/
|
|
|
4847
4905
|
});
|
|
4848
4906
|
var editTenantDeviceLimit = (0, import_toolkit22.createAsyncThunk)(`${sliceName6}/editDeviceLimit`, ({ newLimit, id, name }, { dispatch }) => {
|
|
4849
4907
|
return general_api_default.put(`${tenantadmApiUrlv2}/tenants/${id}/child`, { device_limit: newLimit, name }).catch((err) => commonErrorHandler(err, `Device Limit cannot be changed`, dispatch)).then(() => {
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4908
|
+
return Promise.all([
|
|
4909
|
+
dispatch(setSnackbar5("Device Limit was changed successfully")),
|
|
4910
|
+
dispatch(getUserOrganization()),
|
|
4911
|
+
new Promise((resolve) => setTimeout(() => resolve(dispatch(getTenants())), TIMEOUTS.oneSecond))
|
|
4912
|
+
]);
|
|
4854
4913
|
});
|
|
4855
4914
|
});
|
|
4856
4915
|
var removeTenant = (0, import_toolkit22.createAsyncThunk)(`${sliceName6}/editDeviceLimit`, ({ id }, { dispatch }) => {
|
|
4857
4916
|
return general_api_default.post(`${tenantadmApiUrlv2}/tenants/${id}/remove/start`).catch((err) => commonErrorHandler(err, `There was an error removing the tenant`, dispatch)).then(
|
|
4858
|
-
() => Promise.all([
|
|
4917
|
+
() => Promise.all([
|
|
4918
|
+
dispatch(setSnackbar5("The tenant was removed successfully")),
|
|
4919
|
+
dispatch(getUserOrganization()),
|
|
4920
|
+
new Promise((resolve) => setTimeout(() => resolve(dispatch(getTenants())), TIMEOUTS.oneSecond))
|
|
4921
|
+
])
|
|
4859
4922
|
);
|
|
4860
4923
|
});
|
|
4861
4924
|
var getUserOrganization = (0, import_toolkit22.createAsyncThunk)(`${sliceName6}/getUserOrganization`, (_, { dispatch, getState }) => {
|
|
@@ -4879,7 +4942,10 @@ var sendSupportMessage = (0, import_toolkit22.createAsyncThunk)(
|
|
|
4879
4942
|
);
|
|
4880
4943
|
var requestPlanChange = (0, import_toolkit22.createAsyncThunk)(
|
|
4881
4944
|
`${sliceName6}/requestPlanChange`,
|
|
4882
|
-
({ content, tenantId }, { dispatch }) => general_api_default.post(`${tenantadmApiUrlv2}/tenants/${tenantId}/plan`, content).catch(
|
|
4945
|
+
({ content, tenantId }, { dispatch, rejectWithValue }) => general_api_default.post(`${tenantadmApiUrlv2}/tenants/${tenantId}/plan`, content).catch(async (err) => {
|
|
4946
|
+
await commonErrorHandler(err, "There was an error sending your request", dispatch, commonErrorFallback);
|
|
4947
|
+
rejectWithValue(err);
|
|
4948
|
+
}).then(() => Promise.resolve(dispatch(setSnackbar5({ message: "Your request was sent successfully", autoHideDuration: TIMEOUTS.fiveSeconds }))))
|
|
4883
4949
|
);
|
|
4884
4950
|
var downloadLicenseReport = (0, import_toolkit22.createAsyncThunk)(
|
|
4885
4951
|
`${sliceName6}/downloadLicenseReport`,
|