@joshuanode/n8n-nodes-autoelevate 0.1.0 → 0.2.0-beta.1
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/README.md +61 -8
- package/dist/nodes/AutoElevate/AutoElevate.node.d.ts +5 -0
- package/dist/nodes/AutoElevate/AutoElevate.node.js +57 -7
- package/dist/nodes/AutoElevate/ManagementFunctions.d.ts +2 -0
- package/dist/nodes/AutoElevate/ManagementFunctions.js +205 -0
- package/dist/nodes/AutoElevate/descriptions/Common.js +1 -1
- package/dist/nodes/AutoElevate/descriptions/Management.d.ts +4 -0
- package/dist/nodes/AutoElevate/descriptions/Management.js +275 -0
- package/dist/nodes/AutoElevate/descriptions/WebhookEvents.d.ts +1 -0
- package/dist/nodes/AutoElevate/descriptions/WebhookEvents.js +59 -0
- package/dist/nodes/AutoElevate/descriptions/index.js +60 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,9 +18,9 @@ An n8n community node for the [AutoElevate Partner API](https://partner-api-docs
|
|
|
18
18
|
|
|
19
19
|
## Features
|
|
20
20
|
|
|
21
|
-
-
|
|
21
|
+
- Operations for every endpoint in the Partner API v1 specification retrieved on 2026-10-27
|
|
22
22
|
- API Token (`AE-BEARER`) and signed HMAC (`AE-HMAC-SHA256`) authentication
|
|
23
|
-
- Searchable company, computer, location,
|
|
23
|
+
- Searchable company, computer, location, event, session, request, rule, user, role, and webhook selectors
|
|
24
24
|
- Automatic offset and cursor pagination
|
|
25
25
|
- Picker searches that scan all available API pages when AutoElevate has no server-side search parameter
|
|
26
26
|
- Automatic `429` retries honoring `Retry-After`
|
|
@@ -49,6 +49,18 @@ npm install @joshuanode/n8n-nodes-autoelevate
|
|
|
49
49
|
|
|
50
50
|
Restart n8n after installation if the node does not appear immediately.
|
|
51
51
|
|
|
52
|
+
### Testing prereleases
|
|
53
|
+
|
|
54
|
+
In a test n8n instance, open **Settings > Community Nodes > Install** and enter the exact version:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
@joshuanode/n8n-nodes-autoelevate@0.2.0-beta.1
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The `next` tag selects the current testing release. n8n resolves a tag at installation time; it does not keep following that tag for later updates. Pin the exact version when reproducing a test result.
|
|
61
|
+
|
|
62
|
+
Start with read operations and a narrowly scoped API key. Test changes to users, rules, and computer modes against disposable records before enabling them in scheduled workflows. Computer actions apply asynchronously, so confirm the reported state with **Computer: Get**.
|
|
63
|
+
|
|
52
64
|
## Prerequisites
|
|
53
65
|
|
|
54
66
|
- An AutoElevate partner account with access to the Partner API
|
|
@@ -82,13 +94,16 @@ AutoElevate displays secrets only once. Store them securely and revoke any key t
|
|
|
82
94
|
| --- | --- | --- |
|
|
83
95
|
| Audit Log | Get Many | Entity type, action, start, end |
|
|
84
96
|
| Company | Get, Get Many | — |
|
|
85
|
-
| Computer | Get, Get Many | Company, location |
|
|
97
|
+
| Computer | Get, Get Many, Set Elevation Mode, Set Technician Mode, Delete | Company, location |
|
|
86
98
|
| Elevated Session | Get, Get Many | Company, computer, status |
|
|
87
|
-
| Elevation Event | Get Many | Company, start, end |
|
|
99
|
+
| Elevation Event | Get, Get Many | Company, start, end |
|
|
88
100
|
| Elevation Request | Approve, Deny, Get, Get Many | Company, approval state, start, end |
|
|
89
|
-
| Elevation Rule | Get Many | Company |
|
|
101
|
+
| Elevation Rule | Get, Get Many, Update, Delete | Company |
|
|
90
102
|
| Location | Get, Get Many | Company |
|
|
103
|
+
| Role | Get, Get Many | — |
|
|
91
104
|
| Usage | Get | — |
|
|
105
|
+
| User | Get, Get Many, Create, Update, Delete | — |
|
|
106
|
+
| Webhook | Get, Get Many, Create, Update, Delete, Get Delivery Logs, Test | — |
|
|
92
107
|
|
|
93
108
|
## Example Workflows
|
|
94
109
|
|
|
@@ -124,9 +139,35 @@ Company: Select from list
|
|
|
124
139
|
Return All: true
|
|
125
140
|
```
|
|
126
141
|
|
|
142
|
+
## Computer actions
|
|
143
|
+
|
|
144
|
+
**Set Elevation Mode** accepts `audit`, `live`, `policy`, or `inherit`. Inherit clears the computer override and restores its location, company, or MSP setting. **Set Technician Mode** turns technician mode on or off on supported Windows computers. Activity is attributed to the API token owner; use individual technician tokens when individual attribution is required.
|
|
145
|
+
|
|
146
|
+
Changes apply on the next agent configuration check-in (4.5 minutes by default). The node returns the API response, including its pending state. An accepted response does not confirm activation. Use **Computer: Get** to confirm the reported `elevationMode`; technician mode reports `technicianBypass`.
|
|
147
|
+
|
|
148
|
+
**Delete** queues agent uninstall and hides the computer record. It can reappear if the agent checks in before uninstalling. Elevation history and audit entries remain. Delete operations require **Confirm Deletion**.
|
|
149
|
+
|
|
150
|
+
## Rule and user updates
|
|
151
|
+
|
|
152
|
+
**Update Fields** sends only selected fields. Omitted fields stay unchanged, and boolean `false` is preserved. For elevation rules, an empty Friendly Name or Notes clears that field with `null`. Identification Criteria accepts a JSON object using the structure returned by **Get**; its internal shape is not part of the public API contract. Rule scope cannot be edited. New rules can be created through **Elevation Request: Approve/Deny** with **Create Rule**, but there is no standalone rule-create endpoint.
|
|
153
|
+
|
|
154
|
+
**User: Create** creates human users. Service users must be created in the Admin Portal. Select a role and company access: all, none, selected companies only, or all except selected companies. On update, Company Access defaults to **Leave Unchanged**. Choosing another value replaces the complete access setting. Email and user kind cannot be changed through this API.
|
|
155
|
+
|
|
156
|
+
For elevated-session approvals, set Duration to 1–60 minutes; Addigy-managed Macs require at least 10. Leaving Duration at 0 omits it, which is only suitable for other request types. **Deny** supports a reason shown to the end user. Just-in-Time Log In approvals still require the mobile app.
|
|
157
|
+
|
|
158
|
+
## Webhooks
|
|
159
|
+
|
|
160
|
+
**Webhook: Create** registers an HTTPS destination and event subscriptions. Native JSON deliveries carry HMAC signatures. Verify the timestamp and signature against the raw request body before processing, then deduplicate by `deliveryId`. Teams and Slack formats are unsigned. User events require a webhook scoped to all companies.
|
|
161
|
+
|
|
162
|
+
Creation returns the signing secret once. Save it securely and account for n8n execution-data retention, because the creation response is node output. Later reads return only the destination URL origin and omit the secret. When updating, omit URL to preserve it; do not copy the redacted URL from Get. Adding an empty Company field to an update explicitly restores all-company scope.
|
|
163
|
+
|
|
164
|
+
**Get Delivery Logs** returns the most recent attempts (up to 50). **Test** sends a real test delivery even if the webhook is disabled. A newly created webhook may briefly return 404 on subsequent calls; retry after it becomes visible. This package manages webhook subscriptions; use n8n's Webhook node to receive events.
|
|
165
|
+
|
|
127
166
|
## API Limits
|
|
128
167
|
|
|
129
|
-
|
|
168
|
+
The [Partner API reference](https://partner-api-docs.autoelevate.com/) documents a default limit of **20 requests per minute per MSP, HTTP method, and route path** (checked 2026-10-27). Capacity refills continuously, roughly one request every three seconds. Limits may change during beta; honor the server's `Retry-After` response.
|
|
169
|
+
|
|
170
|
+
**Get Many** uses pages of up to 200 records, so large result sets consume multiple requests. A `429` response includes a `Retry-After` value.
|
|
130
171
|
|
|
131
172
|
## Error Handling and Troubleshooting
|
|
132
173
|
|
|
@@ -136,7 +177,9 @@ During beta, AutoElevate documents a default limit of 100 requests per hour for
|
|
|
136
177
|
| `401 Unauthorized` | Invalid, expired, or incorrectly configured API credentials | Confirm the selected authentication scheme and rotate the API key if needed |
|
|
137
178
|
| `403 Forbidden` | The service user or API key lacks permission for the operation | Add the required API permission in AutoElevate or use a properly scoped service user |
|
|
138
179
|
| `404 Not Found` | The record does not exist or is outside the partner account | Verify the selected company, computer, location, session, request, or rule |
|
|
139
|
-
| `
|
|
180
|
+
| `409 Conflict` | The resource state prevents this operation | Re-read the record; requests may already be resolved or multiple users may be signed in |
|
|
181
|
+
| `422 Unprocessable Entity` | The target cannot apply the operation | Check platform support, agent state, session duration, and rule constraints |
|
|
182
|
+
| `429 Too Many Requests` | The API rate limit has been reached | The node retries twice using `Retry-After`; reduce polling frequency or batch size if the limit persists |
|
|
140
183
|
|
|
141
184
|
AutoElevate error messages and error codes are preserved in n8n when the API returns them. For example, a missing audit-log permission should surface AutoElevate's original authorization message rather than a generic request failure.
|
|
142
185
|
|
|
@@ -192,10 +235,20 @@ Bug reports, feature requests, and pull requests are welcome in the [GitHub repo
|
|
|
192
235
|
|
|
193
236
|
## Version History
|
|
194
237
|
|
|
238
|
+
### 0.2.0-beta.1
|
|
239
|
+
|
|
240
|
+
- Added computer elevation-mode and technician-mode controls, plus agent uninstall and deletion
|
|
241
|
+
- Added user management, company access settings, and role lookup
|
|
242
|
+
- Added elevation rule get, update, and delete operations
|
|
243
|
+
- Added webhook management, test deliveries, and delivery logs
|
|
244
|
+
- Added individual elevation event lookup, denial reasons, withdrawn-request filtering, and rule audit filtering
|
|
245
|
+
- Updated API limits and session-duration guidance
|
|
246
|
+
- Added offline execution tests against the API contract retrieved on 2026-10-27
|
|
247
|
+
|
|
195
248
|
### 0.1.0
|
|
196
249
|
|
|
197
250
|
- Initial public release
|
|
198
|
-
-
|
|
251
|
+
- Covered the AutoElevate Partner API v1 beta endpoints available at the initial release
|
|
199
252
|
- Bearer and HMAC authentication
|
|
200
253
|
- Searchable resource selectors, pagination, filtering, rate-limit retries, and preserved API errors
|
|
201
254
|
|
|
@@ -10,6 +10,11 @@ export declare class AutoElevate implements INodeType {
|
|
|
10
10
|
searchComputers(this: ILoadOptionsFunctions, filter?: string, paginationToken?: string): Promise<INodeListSearchResult>;
|
|
11
11
|
searchElevatedSessions(this: ILoadOptionsFunctions, filter?: string, paginationToken?: string): Promise<INodeListSearchResult>;
|
|
12
12
|
searchElevationRequests(this: ILoadOptionsFunctions, filter?: string, paginationToken?: string): Promise<INodeListSearchResult>;
|
|
13
|
+
searchElevationEvents(this: ILoadOptionsFunctions, filter?: string, paginationToken?: string): Promise<INodeListSearchResult>;
|
|
14
|
+
searchElevationRules(this: ILoadOptionsFunctions, filter?: string, paginationToken?: string): Promise<INodeListSearchResult>;
|
|
15
|
+
searchUsers(this: ILoadOptionsFunctions, filter?: string, paginationToken?: string): Promise<INodeListSearchResult>;
|
|
16
|
+
searchRoles(this: ILoadOptionsFunctions, filter?: string, paginationToken?: string): Promise<INodeListSearchResult>;
|
|
17
|
+
searchWebhooks(this: ILoadOptionsFunctions, filter?: string, paginationToken?: string): Promise<INodeListSearchResult>;
|
|
13
18
|
searchLocations(this: ILoadOptionsFunctions, filter?: string, paginationToken?: string): Promise<INodeListSearchResult>;
|
|
14
19
|
};
|
|
15
20
|
};
|
|
@@ -4,6 +4,7 @@ exports.AutoElevate = void 0;
|
|
|
4
4
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
5
|
const GenericFunctions_1 = require("./GenericFunctions");
|
|
6
6
|
const descriptions_1 = require("./descriptions");
|
|
7
|
+
const ManagementFunctions_1 = require("./ManagementFunctions");
|
|
7
8
|
function dateToEpoch(value) {
|
|
8
9
|
if (!value)
|
|
9
10
|
return undefined;
|
|
@@ -35,7 +36,11 @@ async function searchResource(resource, filter, paginationToken) {
|
|
|
35
36
|
const normalizedFilter = filter?.trim().toLowerCase();
|
|
36
37
|
let items;
|
|
37
38
|
let hasMore = false;
|
|
38
|
-
if (
|
|
39
|
+
if (resource === 'roles') {
|
|
40
|
+
const response = await GenericFunctions_1.autoElevateApiRequest.call(this, 'GET', '/api/v1/roles');
|
|
41
|
+
items = response.items;
|
|
42
|
+
}
|
|
43
|
+
else if (normalizedFilter) {
|
|
39
44
|
items = await GenericFunctions_1.autoElevateApiRequestAllItems.call(this, `/api/v1/${resource}`, resource === 'elevation-requests' ? { approvalState: 'PENDING' } : {});
|
|
40
45
|
}
|
|
41
46
|
else {
|
|
@@ -52,7 +57,15 @@ async function searchResource(resource, filter, paginationToken) {
|
|
|
52
57
|
});
|
|
53
58
|
const results = items.map((item) => {
|
|
54
59
|
const id = String(item.id);
|
|
55
|
-
let name = String(item.name ??
|
|
60
|
+
let name = String(item.name ??
|
|
61
|
+
item.friendlyName ??
|
|
62
|
+
item.machineName ??
|
|
63
|
+
item.targetDescription ??
|
|
64
|
+
item.email ??
|
|
65
|
+
id);
|
|
66
|
+
if (resource === 'users')
|
|
67
|
+
name =
|
|
68
|
+
`${String(item.firstName ?? '')} ${String(item.lastName ?? '')} (${String(item.email ?? id)})`.trim();
|
|
56
69
|
if (resource === 'elevated-sessions') {
|
|
57
70
|
name = `${String(item.userName ?? 'Unknown user')} — ${String(item.status ?? '')} (${id})`;
|
|
58
71
|
}
|
|
@@ -78,7 +91,7 @@ class AutoElevate {
|
|
|
78
91
|
group: ['transform'],
|
|
79
92
|
version: 1,
|
|
80
93
|
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
81
|
-
description: '
|
|
94
|
+
description: 'Manage computers, elevation rules, users, webhooks, and security activity in AutoElevate',
|
|
82
95
|
defaults: { name: 'AutoElevate' },
|
|
83
96
|
inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
84
97
|
outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
@@ -111,7 +124,10 @@ class AutoElevate {
|
|
|
111
124
|
{ name: 'Elevation Request', value: 'elevationRequest' },
|
|
112
125
|
{ name: 'Elevation Rule', value: 'elevationRule' },
|
|
113
126
|
{ name: 'Location', value: 'location' },
|
|
127
|
+
{ name: 'Role', value: 'role' },
|
|
114
128
|
{ name: 'Usage', value: 'usage' },
|
|
129
|
+
{ name: 'User', value: 'user' },
|
|
130
|
+
{ name: 'Webhook', value: 'webhook' },
|
|
115
131
|
],
|
|
116
132
|
default: 'elevationRequest',
|
|
117
133
|
},
|
|
@@ -123,7 +139,10 @@ class AutoElevate {
|
|
|
123
139
|
async autoElevateApiCredentialTest(credential) {
|
|
124
140
|
const credentials = credential.data;
|
|
125
141
|
if (!credentials) {
|
|
126
|
-
return {
|
|
142
|
+
return {
|
|
143
|
+
status: 'Error',
|
|
144
|
+
message: 'AutoElevate credentials are incomplete',
|
|
145
|
+
};
|
|
127
146
|
}
|
|
128
147
|
const url = `${String(credentials.baseUrl).replace(/\/+$/, '')}/api/v1/usage`;
|
|
129
148
|
const headers = {
|
|
@@ -170,6 +189,21 @@ class AutoElevate {
|
|
|
170
189
|
searchElevationRequests(filter, paginationToken) {
|
|
171
190
|
return searchResource.call(this, 'elevation-requests', filter, paginationToken);
|
|
172
191
|
},
|
|
192
|
+
searchElevationEvents(filter, paginationToken) {
|
|
193
|
+
return searchResource.call(this, 'elevation-events', filter, paginationToken);
|
|
194
|
+
},
|
|
195
|
+
searchElevationRules(filter, paginationToken) {
|
|
196
|
+
return searchResource.call(this, 'elevation-rules', filter, paginationToken);
|
|
197
|
+
},
|
|
198
|
+
searchUsers(filter, paginationToken) {
|
|
199
|
+
return searchResource.call(this, 'users', filter, paginationToken);
|
|
200
|
+
},
|
|
201
|
+
searchRoles(filter, paginationToken) {
|
|
202
|
+
return searchResource.call(this, 'roles', filter, paginationToken);
|
|
203
|
+
},
|
|
204
|
+
searchWebhooks(filter, paginationToken) {
|
|
205
|
+
return searchResource.call(this, 'webhooks', filter, paginationToken);
|
|
206
|
+
},
|
|
173
207
|
searchLocations(filter, paginationToken) {
|
|
174
208
|
return searchResource.call(this, 'locations', filter, paginationToken);
|
|
175
209
|
},
|
|
@@ -184,7 +218,14 @@ class AutoElevate {
|
|
|
184
218
|
const resource = this.getNodeParameter('resource', itemIndex);
|
|
185
219
|
const operation = this.getNodeParameter('operation', itemIndex);
|
|
186
220
|
let response;
|
|
187
|
-
if (
|
|
221
|
+
if (['user', 'role', 'webhook'].includes(resource) ||
|
|
222
|
+
(resource === 'computer' &&
|
|
223
|
+
['delete', 'setElevationMode', 'setTechnicianMode'].includes(operation)) ||
|
|
224
|
+
(resource === 'elevationRule' && operation !== 'getMany') ||
|
|
225
|
+
(resource === 'elevationEvent' && operation === 'get')) {
|
|
226
|
+
response = await (0, ManagementFunctions_1.executeManagement)(this, itemIndex, resource, operation);
|
|
227
|
+
}
|
|
228
|
+
else if (resource === 'auditLog') {
|
|
188
229
|
const query = {
|
|
189
230
|
entityType: this.getNodeParameter('entityType', itemIndex, ''),
|
|
190
231
|
action: this.getNodeParameter('auditAction', itemIndex, ''),
|
|
@@ -246,6 +287,11 @@ class AutoElevate {
|
|
|
246
287
|
if (createRule) {
|
|
247
288
|
body.ruleLevel = this.getNodeParameter('ruleLevel', itemIndex);
|
|
248
289
|
}
|
|
290
|
+
if (operation === 'deny') {
|
|
291
|
+
const reason = this.getNodeParameter('denialReason', itemIndex, '');
|
|
292
|
+
if (reason)
|
|
293
|
+
body.denialReason = reason;
|
|
294
|
+
}
|
|
249
295
|
if (operation === 'approve') {
|
|
250
296
|
const elevationType = this.getNodeParameter('elevationType', itemIndex, '');
|
|
251
297
|
const duration = this.getNodeParameter('durationInMinutes', itemIndex, 0);
|
|
@@ -296,7 +342,9 @@ class AutoElevate {
|
|
|
296
342
|
catch (error) {
|
|
297
343
|
if (this.continueOnFail()) {
|
|
298
344
|
returnData.push({
|
|
299
|
-
json: {
|
|
345
|
+
json: {
|
|
346
|
+
error: error instanceof Error ? error.message : String(error),
|
|
347
|
+
},
|
|
300
348
|
pairedItem: { item: itemIndex },
|
|
301
349
|
});
|
|
302
350
|
continue;
|
|
@@ -306,7 +354,9 @@ class AutoElevate {
|
|
|
306
354
|
// eslint-disable-next-line @n8n/community-nodes/require-node-api-error
|
|
307
355
|
throw error;
|
|
308
356
|
}
|
|
309
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error, {
|
|
357
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error, {
|
|
358
|
+
itemIndex,
|
|
359
|
+
});
|
|
310
360
|
}
|
|
311
361
|
}
|
|
312
362
|
return [returnData];
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.executeManagement = executeManagement;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const GenericFunctions_1 = require("./GenericFunctions");
|
|
6
|
+
async function executeManagement(context, index, resource, operation) {
|
|
7
|
+
const parameter = (name, fallback = '') => context.getNodeParameter(name, index, fallback);
|
|
8
|
+
const fail = (message) => {
|
|
9
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), message, {
|
|
10
|
+
itemIndex: index,
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
const id = (name) => {
|
|
14
|
+
const value = (0, GenericFunctions_1.unwrapLocator)(parameter(name));
|
|
15
|
+
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value))
|
|
16
|
+
fail(`${name} must be a UUID`);
|
|
17
|
+
return value;
|
|
18
|
+
};
|
|
19
|
+
const request = (method, path, body = {}) => GenericFunctions_1.autoElevateApiRequest.call(context, method, path, body);
|
|
20
|
+
const list = (path) => GenericFunctions_1.autoElevateApiRequestAllItems.call(context, path, {}, false, parameter('returnAll', false) ? Number.POSITIVE_INFINITY : Number(parameter('limit', 50)));
|
|
21
|
+
const selectedFields = (name, allowed) => {
|
|
22
|
+
const value = parameter(name, {});
|
|
23
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
24
|
+
fail(`${name} must be an object`);
|
|
25
|
+
for (const key of Object.keys(value))
|
|
26
|
+
if (!allowed.includes(key))
|
|
27
|
+
fail(`Unsupported field: ${key}`);
|
|
28
|
+
return { ...value };
|
|
29
|
+
};
|
|
30
|
+
if (operation === 'delete' && parameter('confirmDeletion', false) !== true)
|
|
31
|
+
fail('Enable Confirm Deletion to delete this record');
|
|
32
|
+
if (resource === 'computer') {
|
|
33
|
+
const path = `/api/v1/computers/${id('computerId')}`;
|
|
34
|
+
if (operation === 'delete')
|
|
35
|
+
return request('DELETE', path);
|
|
36
|
+
if (operation === 'setTechnicianMode')
|
|
37
|
+
return request('POST', `${path}/technician-mode`, {
|
|
38
|
+
enabled: parameter('enabled', false),
|
|
39
|
+
});
|
|
40
|
+
if (operation === 'setElevationMode')
|
|
41
|
+
return request('POST', `${path}/elevation-mode`, {
|
|
42
|
+
mode: parameter('mode'),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
if (resource === 'elevationEvent' && operation === 'get')
|
|
46
|
+
return request('GET', `/api/v1/elevation-events/${id('elevationEventId')}`);
|
|
47
|
+
if (resource === 'elevationRule') {
|
|
48
|
+
const path = `/api/v1/elevation-rules/${id('elevationRuleId')}`;
|
|
49
|
+
if (operation === 'get')
|
|
50
|
+
return request('GET', path);
|
|
51
|
+
if (operation === 'delete')
|
|
52
|
+
return request('DELETE', path);
|
|
53
|
+
if (operation === 'update') {
|
|
54
|
+
const body = selectedFields('updateFields', [
|
|
55
|
+
'approved',
|
|
56
|
+
'elevationType',
|
|
57
|
+
'shouldIgnore',
|
|
58
|
+
'friendlyName',
|
|
59
|
+
'notes',
|
|
60
|
+
'identificationCriteria',
|
|
61
|
+
]);
|
|
62
|
+
for (const key of ['friendlyName', 'notes'])
|
|
63
|
+
if (body[key] === '')
|
|
64
|
+
body[key] = null;
|
|
65
|
+
if (body.identificationCriteria !== undefined) {
|
|
66
|
+
let criteria = body.identificationCriteria;
|
|
67
|
+
if (typeof criteria === 'string') {
|
|
68
|
+
try {
|
|
69
|
+
criteria = JSON.parse(criteria);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
fail('Identification Criteria must be valid JSON');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (!criteria || typeof criteria !== 'object' || Array.isArray(criteria))
|
|
76
|
+
fail('Identification Criteria must be a JSON object');
|
|
77
|
+
body.identificationCriteria = criteria;
|
|
78
|
+
}
|
|
79
|
+
if (Object.keys(body).length === 0)
|
|
80
|
+
fail('Select at least one field to update');
|
|
81
|
+
return request('PATCH', path, body);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (resource === 'role') {
|
|
85
|
+
if (operation === 'get')
|
|
86
|
+
return request('GET', `/api/v1/roles/${id('roleId')}`);
|
|
87
|
+
if (operation === 'getMany') {
|
|
88
|
+
const response = await request('GET', '/api/v1/roles');
|
|
89
|
+
return response.items;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (resource === 'user') {
|
|
93
|
+
if (operation === 'getMany')
|
|
94
|
+
return list('/api/v1/users');
|
|
95
|
+
if (operation === 'get')
|
|
96
|
+
return request('GET', `/api/v1/users/${id('userId')}`);
|
|
97
|
+
if (operation === 'delete')
|
|
98
|
+
return request('DELETE', `/api/v1/users/${id('userId')}`);
|
|
99
|
+
if (operation === 'create' || operation === 'update') {
|
|
100
|
+
const body = operation === 'create'
|
|
101
|
+
? {
|
|
102
|
+
...selectedFields('additionalFields', [
|
|
103
|
+
'lastName',
|
|
104
|
+
'technicianModeTicketingEnabled',
|
|
105
|
+
'sendInvitationEmail',
|
|
106
|
+
]),
|
|
107
|
+
firstName: parameter('firstName'),
|
|
108
|
+
email: parameter('email'),
|
|
109
|
+
roleId: id('roleId'),
|
|
110
|
+
}
|
|
111
|
+
: selectedFields('updateFields', [
|
|
112
|
+
'firstName',
|
|
113
|
+
'lastName',
|
|
114
|
+
'roleId',
|
|
115
|
+
'technicianModeTicketingEnabled',
|
|
116
|
+
]);
|
|
117
|
+
if (body.roleId !== undefined) {
|
|
118
|
+
body.roleId = (0, GenericFunctions_1.unwrapLocator)(body.roleId);
|
|
119
|
+
if (!body.roleId)
|
|
120
|
+
fail('Select a role');
|
|
121
|
+
}
|
|
122
|
+
const accessType = parameter('companyAccessType', operation === 'create' ? 'none' : '');
|
|
123
|
+
if (accessType) {
|
|
124
|
+
if (!['all', 'none', 'some', 'most'].includes(accessType))
|
|
125
|
+
fail('Unsupported company access type');
|
|
126
|
+
const access = { type: accessType };
|
|
127
|
+
if (accessType === 'some' || accessType === 'most') {
|
|
128
|
+
const companies = parameter('companies', {});
|
|
129
|
+
const ids = (companies.company ?? []).map((company) => (0, GenericFunctions_1.unwrapLocator)(company.companyId));
|
|
130
|
+
if (!ids.length || ids.some((value) => !value))
|
|
131
|
+
fail('Select at least one company for this access type');
|
|
132
|
+
access.companyIds = [...new Set(ids)];
|
|
133
|
+
}
|
|
134
|
+
body.companyAccess = access;
|
|
135
|
+
}
|
|
136
|
+
if (Object.keys(body).length === 0)
|
|
137
|
+
fail('Select at least one field to update');
|
|
138
|
+
return operation === 'create'
|
|
139
|
+
? request('POST', '/api/v1/users', body)
|
|
140
|
+
: request('PATCH', `/api/v1/users/${id('userId')}`, body);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (resource === 'webhook') {
|
|
144
|
+
if (operation === 'getMany')
|
|
145
|
+
return list('/api/v1/webhooks');
|
|
146
|
+
if (operation === 'create' || operation === 'update') {
|
|
147
|
+
const body = operation === 'create'
|
|
148
|
+
? {
|
|
149
|
+
...selectedFields('additionalFields', ['format', 'companyId']),
|
|
150
|
+
name: parameter('name'),
|
|
151
|
+
url: parameter('url'),
|
|
152
|
+
eventSubscriptions: parameter('eventSubscriptions', []),
|
|
153
|
+
}
|
|
154
|
+
: selectedFields('updateFields', [
|
|
155
|
+
'name',
|
|
156
|
+
'url',
|
|
157
|
+
'eventSubscriptions',
|
|
158
|
+
'format',
|
|
159
|
+
'enabled',
|
|
160
|
+
'companyId',
|
|
161
|
+
]);
|
|
162
|
+
if (body.companyId !== undefined) {
|
|
163
|
+
const companyId = (0, GenericFunctions_1.unwrapLocator)(body.companyId);
|
|
164
|
+
if (companyId)
|
|
165
|
+
body.companyId = companyId;
|
|
166
|
+
else if (operation === 'update')
|
|
167
|
+
body.companyId = null;
|
|
168
|
+
else
|
|
169
|
+
delete body.companyId;
|
|
170
|
+
}
|
|
171
|
+
if (body.eventSubscriptions !== undefined &&
|
|
172
|
+
(!Array.isArray(body.eventSubscriptions) || !body.eventSubscriptions.length))
|
|
173
|
+
fail('Select at least one webhook event');
|
|
174
|
+
if (body.companyId &&
|
|
175
|
+
body.eventSubscriptions?.some((event) => event.startsWith('user.')))
|
|
176
|
+
fail('User events require a webhook scoped to all companies');
|
|
177
|
+
if (body.url !== undefined) {
|
|
178
|
+
try {
|
|
179
|
+
if (new URL(String(body.url)).protocol !== 'https:')
|
|
180
|
+
fail('Webhook URL must use HTTPS');
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
fail('Webhook URL must be a valid HTTPS URL');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (Object.keys(body).length === 0)
|
|
187
|
+
fail('Select at least one field to update');
|
|
188
|
+
return operation === 'create'
|
|
189
|
+
? request('POST', '/api/v1/webhooks', body)
|
|
190
|
+
: request('PATCH', `/api/v1/webhooks/${id('webhookId')}`, body);
|
|
191
|
+
}
|
|
192
|
+
const path = `/api/v1/webhooks/${id('webhookId')}`;
|
|
193
|
+
if (operation === 'get')
|
|
194
|
+
return request('GET', path);
|
|
195
|
+
if (operation === 'delete')
|
|
196
|
+
return request('DELETE', path);
|
|
197
|
+
if (operation === 'test')
|
|
198
|
+
return request('POST', `${path}/test`);
|
|
199
|
+
if (operation === 'getDeliveryLogs') {
|
|
200
|
+
const response = await request('GET', `${path}/delivery-logs`);
|
|
201
|
+
return response.deliveryLogs;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return fail(`Unsupported operation: ${resource}.${operation}`);
|
|
205
|
+
}
|
|
@@ -52,7 +52,7 @@ function idLocator(resource, displayName, name, searchListMethod, operations = [
|
|
|
52
52
|
{
|
|
53
53
|
type: 'regex',
|
|
54
54
|
properties: {
|
|
55
|
-
regex: '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[
|
|
55
|
+
regex: '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$',
|
|
56
56
|
errorMessage: 'Enter a valid UUID',
|
|
57
57
|
},
|
|
58
58
|
},
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.managementProperties = exports.ruleOperations = exports.computerOperations = void 0;
|
|
4
|
+
const Common_1 = require("./Common");
|
|
5
|
+
const WebhookEvents_1 = require("./WebhookEvents");
|
|
6
|
+
function operations(resource, actions) {
|
|
7
|
+
return {
|
|
8
|
+
...(0, Common_1.getAndListOperations)(resource),
|
|
9
|
+
options: actions.map(([name, value, action]) => ({ name, value, action })),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function fields(resource, operation, name, options) {
|
|
13
|
+
return {
|
|
14
|
+
displayName: name === 'updateFields' ? 'Update Fields' : 'Additional Fields',
|
|
15
|
+
name,
|
|
16
|
+
type: 'collection',
|
|
17
|
+
placeholder: 'Add Field',
|
|
18
|
+
default: {},
|
|
19
|
+
displayOptions: { show: { resource: [resource], operation } },
|
|
20
|
+
options,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function text(displayName, name, description) {
|
|
24
|
+
return {
|
|
25
|
+
displayName,
|
|
26
|
+
name,
|
|
27
|
+
type: 'string',
|
|
28
|
+
default: '',
|
|
29
|
+
...(description ? { description } : {}),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function toggle(displayName, name, description) {
|
|
33
|
+
return { displayName, name, type: 'boolean', default: false, description };
|
|
34
|
+
}
|
|
35
|
+
function locator(displayName, name, search) {
|
|
36
|
+
const field = (0, Common_1.idLocator)('', displayName, name, search);
|
|
37
|
+
delete field.displayOptions;
|
|
38
|
+
return field;
|
|
39
|
+
}
|
|
40
|
+
const userOperations = [
|
|
41
|
+
['Create', 'create', 'Create a user'],
|
|
42
|
+
['Delete', 'delete', 'Delete a user'],
|
|
43
|
+
['Get', 'get', 'Get a user'],
|
|
44
|
+
['Get Many', 'getMany', 'Get many users'],
|
|
45
|
+
['Update', 'update', 'Update a user'],
|
|
46
|
+
];
|
|
47
|
+
const companyAccessType = {
|
|
48
|
+
displayName: 'Company Access',
|
|
49
|
+
name: 'companyAccessType',
|
|
50
|
+
type: 'options',
|
|
51
|
+
default: 'none',
|
|
52
|
+
options: [
|
|
53
|
+
{ name: 'All Companies', value: 'all' },
|
|
54
|
+
{ name: 'All Except Selected Companies', value: 'most' },
|
|
55
|
+
{ name: 'No Companies', value: 'none' },
|
|
56
|
+
{ name: 'Selected Companies Only', value: 'some' },
|
|
57
|
+
],
|
|
58
|
+
description: 'Replaces the complete company access setting. Selected companies are required for allow-lists and deny-lists.',
|
|
59
|
+
};
|
|
60
|
+
const eventSubscriptions = {
|
|
61
|
+
displayName: 'Events',
|
|
62
|
+
name: 'eventSubscriptions',
|
|
63
|
+
type: 'multiOptions',
|
|
64
|
+
default: [],
|
|
65
|
+
options: WebhookEvents_1.webhookEvents.map((event) => ({ name: event, value: event })),
|
|
66
|
+
description: 'Event types to receive. User events require a webhook scoped to all companies.',
|
|
67
|
+
};
|
|
68
|
+
const webhookFormat = {
|
|
69
|
+
displayName: 'Format',
|
|
70
|
+
name: 'format',
|
|
71
|
+
type: 'options',
|
|
72
|
+
default: 'native',
|
|
73
|
+
options: [
|
|
74
|
+
{ name: 'Native (Signed JSON)', value: 'native' },
|
|
75
|
+
{ name: 'Slack Incoming Webhook', value: 'slack-incoming-webhook' },
|
|
76
|
+
{ name: 'Teams Incoming Webhook', value: 'teams-incoming-webhook' },
|
|
77
|
+
],
|
|
78
|
+
};
|
|
79
|
+
exports.computerOperations = operations('computer', [
|
|
80
|
+
['Delete', 'delete', 'Delete a computer and uninstall its agent'],
|
|
81
|
+
['Get', 'get', 'Get a computer'],
|
|
82
|
+
['Get Many', 'getMany', 'Get many computers'],
|
|
83
|
+
['Set Elevation Mode', 'setElevationMode', 'Set a computer elevation mode'],
|
|
84
|
+
['Set Technician Mode', 'setTechnicianMode', 'Turn technician mode on or off'],
|
|
85
|
+
]);
|
|
86
|
+
exports.ruleOperations = operations('elevationRule', [
|
|
87
|
+
['Delete', 'delete', 'Delete an elevation rule'],
|
|
88
|
+
['Get', 'get', 'Get an elevation rule'],
|
|
89
|
+
['Get Many', 'getMany', 'Get many elevation rules'],
|
|
90
|
+
['Update', 'update', 'Update an elevation rule'],
|
|
91
|
+
]);
|
|
92
|
+
exports.managementProperties = [
|
|
93
|
+
{
|
|
94
|
+
displayName: 'Computer changes apply at the next agent check-in. An accepted response does not confirm completion. Technician mode is attributed to the API token owner.',
|
|
95
|
+
name: 'computerActionNotice',
|
|
96
|
+
type: 'notice',
|
|
97
|
+
default: '',
|
|
98
|
+
displayOptions: {
|
|
99
|
+
show: {
|
|
100
|
+
resource: ['computer'],
|
|
101
|
+
operation: ['setElevationMode', 'setTechnicianMode', 'delete'],
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
displayName: 'Elevation Mode',
|
|
107
|
+
name: 'mode',
|
|
108
|
+
type: 'options',
|
|
109
|
+
default: 'inherit',
|
|
110
|
+
options: [
|
|
111
|
+
{ name: 'Audit', value: 'audit' },
|
|
112
|
+
{ name: 'Inherit', value: 'inherit' },
|
|
113
|
+
{ name: 'Live', value: 'live' },
|
|
114
|
+
{ name: 'Policy', value: 'policy' },
|
|
115
|
+
],
|
|
116
|
+
description: 'Inherit clears the computer override and restores the location, company or MSP setting',
|
|
117
|
+
displayOptions: {
|
|
118
|
+
show: { resource: ['computer'], operation: ['setElevationMode'] },
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
...toggle('Enabled', 'enabled', 'Whether to turn technician mode on. Windows only.'),
|
|
123
|
+
displayOptions: {
|
|
124
|
+
show: { resource: ['computer'], operation: ['setTechnicianMode'] },
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
// Keep destructive actions explicit even when expressions provide the operation.
|
|
128
|
+
...['computer', 'elevationRule', 'user', 'webhook'].map((resource) => ({
|
|
129
|
+
...toggle('Confirm Deletion', 'confirmDeletion', 'Whether to delete the selected record. Deleting a computer also queues agent uninstall.'),
|
|
130
|
+
displayOptions: { show: { resource: [resource], operation: ['delete'] } },
|
|
131
|
+
})),
|
|
132
|
+
(0, Common_1.idLocator)('elevationRule', 'Elevation Rule', 'elevationRuleId', 'searchElevationRules', [
|
|
133
|
+
'get',
|
|
134
|
+
'update',
|
|
135
|
+
'delete',
|
|
136
|
+
]),
|
|
137
|
+
fields('elevationRule', ['update'], 'updateFields', [
|
|
138
|
+
toggle('Approved', 'approved', 'Whether matching events are automatically approved'),
|
|
139
|
+
{
|
|
140
|
+
displayName: 'Elevation Type',
|
|
141
|
+
name: 'elevationType',
|
|
142
|
+
type: 'options',
|
|
143
|
+
default: 'admin',
|
|
144
|
+
options: [
|
|
145
|
+
{ name: 'Admin', value: 'admin' },
|
|
146
|
+
{ name: 'User', value: 'user' },
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
text('Friendly Name', 'friendlyName', 'Leave empty to clear the friendly name'),
|
|
150
|
+
{
|
|
151
|
+
displayName: 'Identification Criteria (JSON)',
|
|
152
|
+
name: 'identificationCriteria',
|
|
153
|
+
type: 'json',
|
|
154
|
+
default: '',
|
|
155
|
+
description: 'Opaque match criteria. Supply the same object structure returned by Get; the API does not publish its shape.',
|
|
156
|
+
},
|
|
157
|
+
text('Notes', 'notes', 'Leave empty to clear the notes'),
|
|
158
|
+
toggle('Treat as Audit Mode', 'shouldIgnore', 'Whether matching events are treated as audit mode without prompting to elevate'),
|
|
159
|
+
]),
|
|
160
|
+
operations('user', userOperations),
|
|
161
|
+
(0, Common_1.idLocator)('user', 'User', 'userId', 'searchUsers', ['get', 'update', 'delete']),
|
|
162
|
+
...(0, Common_1.paginationFields)('user'),
|
|
163
|
+
...[
|
|
164
|
+
text('First Name', 'firstName'),
|
|
165
|
+
text('Email', 'email'),
|
|
166
|
+
locator('Role', 'roleId', 'searchRoles'),
|
|
167
|
+
].map((field) => ({
|
|
168
|
+
...field,
|
|
169
|
+
required: true,
|
|
170
|
+
displayOptions: { show: { resource: ['user'], operation: ['create'] } },
|
|
171
|
+
})),
|
|
172
|
+
fields('user', ['create'], 'additionalFields', [
|
|
173
|
+
text('Last Name', 'lastName'),
|
|
174
|
+
{
|
|
175
|
+
...toggle('Send Invitation Email', 'sendInvitationEmail', 'Whether to email a link for setting the initial password'),
|
|
176
|
+
default: true,
|
|
177
|
+
},
|
|
178
|
+
toggle('Technician Mode Ticketing', 'technicianModeTicketingEnabled', 'Whether the user may use technician-mode ticketing'),
|
|
179
|
+
]),
|
|
180
|
+
fields('user', ['update'], 'updateFields', [
|
|
181
|
+
text('First Name', 'firstName'),
|
|
182
|
+
text('Last Name', 'lastName'),
|
|
183
|
+
locator('Role', 'roleId', 'searchRoles'),
|
|
184
|
+
toggle('Technician Mode Ticketing', 'technicianModeTicketingEnabled', 'Whether the user may use technician-mode ticketing'),
|
|
185
|
+
]),
|
|
186
|
+
{
|
|
187
|
+
...companyAccessType,
|
|
188
|
+
displayOptions: { show: { resource: ['user'], operation: ['create'] } },
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
...companyAccessType,
|
|
192
|
+
default: '',
|
|
193
|
+
options: [{ name: 'Leave Unchanged', value: '' }, ...(companyAccessType.options ?? [])],
|
|
194
|
+
displayOptions: { show: { resource: ['user'], operation: ['update'] } },
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
displayName: 'Companies',
|
|
198
|
+
name: 'companies',
|
|
199
|
+
type: 'fixedCollection',
|
|
200
|
+
default: {},
|
|
201
|
+
typeOptions: { multipleValues: true },
|
|
202
|
+
placeholder: 'Add Company',
|
|
203
|
+
displayOptions: {
|
|
204
|
+
show: {
|
|
205
|
+
resource: ['user'],
|
|
206
|
+
operation: ['create', 'update'],
|
|
207
|
+
companyAccessType: ['some', 'most'],
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
options: [
|
|
211
|
+
{
|
|
212
|
+
displayName: 'Company',
|
|
213
|
+
name: 'company',
|
|
214
|
+
values: [locator('Company', 'companyId', 'searchCompanies')],
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
},
|
|
218
|
+
(0, Common_1.getAndListOperations)('role'),
|
|
219
|
+
(0, Common_1.idLocator)('role', 'Role', 'roleId', 'searchRoles'),
|
|
220
|
+
operations('webhook', [
|
|
221
|
+
['Create', 'create', 'Create a webhook'],
|
|
222
|
+
['Delete', 'delete', 'Delete a webhook'],
|
|
223
|
+
['Get', 'get', 'Get a webhook'],
|
|
224
|
+
['Get Delivery Logs', 'getDeliveryLogs', 'Get webhook delivery logs'],
|
|
225
|
+
['Get Many', 'getMany', 'Get many webhooks'],
|
|
226
|
+
['Test', 'test', 'Send a test webhook delivery'],
|
|
227
|
+
['Update', 'update', 'Update a webhook'],
|
|
228
|
+
]),
|
|
229
|
+
(0, Common_1.idLocator)('webhook', 'Webhook', 'webhookId', 'searchWebhooks', [
|
|
230
|
+
'get',
|
|
231
|
+
'update',
|
|
232
|
+
'delete',
|
|
233
|
+
'getDeliveryLogs',
|
|
234
|
+
'test',
|
|
235
|
+
]),
|
|
236
|
+
...(0, Common_1.paginationFields)('webhook'),
|
|
237
|
+
...[
|
|
238
|
+
text('Name', 'name'),
|
|
239
|
+
text('URL', 'url', 'Full HTTPS delivery URL, including its path'),
|
|
240
|
+
eventSubscriptions,
|
|
241
|
+
].map((field) => ({
|
|
242
|
+
...field,
|
|
243
|
+
required: true,
|
|
244
|
+
displayOptions: {
|
|
245
|
+
show: { resource: ['webhook'], operation: ['create'] },
|
|
246
|
+
},
|
|
247
|
+
})),
|
|
248
|
+
fields('webhook', ['create'], 'additionalFields', [
|
|
249
|
+
{
|
|
250
|
+
...locator('Company', 'companyId', 'searchCompanies'),
|
|
251
|
+
required: false,
|
|
252
|
+
description: 'Leave empty for all companies',
|
|
253
|
+
},
|
|
254
|
+
webhookFormat,
|
|
255
|
+
]),
|
|
256
|
+
fields('webhook', ['update'], 'updateFields', [
|
|
257
|
+
{
|
|
258
|
+
...locator('Company', 'companyId', 'searchCompanies'),
|
|
259
|
+
required: false,
|
|
260
|
+
description: 'Leave empty to scope to all companies. Omit this field to keep the current scope.',
|
|
261
|
+
},
|
|
262
|
+
toggle('Enabled', 'enabled', 'Whether webhook deliveries are enabled'),
|
|
263
|
+
eventSubscriptions,
|
|
264
|
+
webhookFormat,
|
|
265
|
+
text('Name', 'name'),
|
|
266
|
+
text('URL', 'url', 'Full HTTPS delivery URL. Omit to keep the stored URL; Get returns only its origin.'),
|
|
267
|
+
]),
|
|
268
|
+
{
|
|
269
|
+
displayName: 'Creation returns the signing secret once. Store it securely. Native JSON deliveries are signed; Teams and Slack deliveries are unsigned.',
|
|
270
|
+
name: 'webhookSecretNotice',
|
|
271
|
+
type: 'notice',
|
|
272
|
+
default: '',
|
|
273
|
+
displayOptions: { show: { resource: ['webhook'], operation: ['create'] } },
|
|
274
|
+
},
|
|
275
|
+
];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const webhookEvents: readonly ["request.created", "request.approved", "request.denied", "request.duplicate.detected", "session.created", "session.completed", "session.cancelled", "agent-update.requested", "agent-update.started", "agent-update.completed", "agent-update.failed", "agent-update.download-failed", "agent-update.verification-failed", "computer.enrolled", "computer.removed", "computer.moved", "computer.elevation-mode.changed", "computer.auto-blocker-mode.changed", "computer.technician-mode.changed", "computer.admin-privileges.changed", "computer.uac.changed", "computer.restart-requested", "computer.restarted", "rule.created", "rule.updated", "rule.removed", "alert.virus.detected", "alert.execution.blocked", "alert.execution.allowed", "blocker-rule.created", "blocker-rule.updated", "blocker-rule.removed", "blocker-event.converted-to-rule", "technician-session.started", "technician-session.authenticated", "technician-session.time-started", "technician-session.time-ended", "os-login.requested", "os-login.authenticated", "technician-mode.bypassed", "company.created", "company.updated", "company.removed", "company.merged", "location.created", "location.updated", "location.removed", "location.merged", "user.created", "user.updated", "user.removed", "user.2fa.reset", "user.password.reset"];
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.webhookEvents = void 0;
|
|
4
|
+
// Source: https://partner-api-docs.autoelevate.com/openapi.json (2026-10-27)
|
|
5
|
+
exports.webhookEvents = [
|
|
6
|
+
'request.created',
|
|
7
|
+
'request.approved',
|
|
8
|
+
'request.denied',
|
|
9
|
+
'request.duplicate.detected',
|
|
10
|
+
'session.created',
|
|
11
|
+
'session.completed',
|
|
12
|
+
'session.cancelled',
|
|
13
|
+
'agent-update.requested',
|
|
14
|
+
'agent-update.started',
|
|
15
|
+
'agent-update.completed',
|
|
16
|
+
'agent-update.failed',
|
|
17
|
+
'agent-update.download-failed',
|
|
18
|
+
'agent-update.verification-failed',
|
|
19
|
+
'computer.enrolled',
|
|
20
|
+
'computer.removed',
|
|
21
|
+
'computer.moved',
|
|
22
|
+
'computer.elevation-mode.changed',
|
|
23
|
+
'computer.auto-blocker-mode.changed',
|
|
24
|
+
'computer.technician-mode.changed',
|
|
25
|
+
'computer.admin-privileges.changed',
|
|
26
|
+
'computer.uac.changed',
|
|
27
|
+
'computer.restart-requested',
|
|
28
|
+
'computer.restarted',
|
|
29
|
+
'rule.created',
|
|
30
|
+
'rule.updated',
|
|
31
|
+
'rule.removed',
|
|
32
|
+
'alert.virus.detected',
|
|
33
|
+
'alert.execution.blocked',
|
|
34
|
+
'alert.execution.allowed',
|
|
35
|
+
'blocker-rule.created',
|
|
36
|
+
'blocker-rule.updated',
|
|
37
|
+
'blocker-rule.removed',
|
|
38
|
+
'blocker-event.converted-to-rule',
|
|
39
|
+
'technician-session.started',
|
|
40
|
+
'technician-session.authenticated',
|
|
41
|
+
'technician-session.time-started',
|
|
42
|
+
'technician-session.time-ended',
|
|
43
|
+
'os-login.requested',
|
|
44
|
+
'os-login.authenticated',
|
|
45
|
+
'technician-mode.bypassed',
|
|
46
|
+
'company.created',
|
|
47
|
+
'company.updated',
|
|
48
|
+
'company.removed',
|
|
49
|
+
'company.merged',
|
|
50
|
+
'location.created',
|
|
51
|
+
'location.updated',
|
|
52
|
+
'location.removed',
|
|
53
|
+
'location.merged',
|
|
54
|
+
'user.created',
|
|
55
|
+
'user.updated',
|
|
56
|
+
'user.removed',
|
|
57
|
+
'user.2fa.reset',
|
|
58
|
+
'user.password.reset',
|
|
59
|
+
];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.autoElevateProperties = void 0;
|
|
4
|
+
const Management_1 = require("./Management");
|
|
4
5
|
const Common_1 = require("./Common");
|
|
5
6
|
const getManyOnly = (resource, action) => ({
|
|
6
7
|
displayName: 'Operation',
|
|
@@ -21,10 +22,13 @@ exports.autoElevateProperties = [
|
|
|
21
22
|
default: '',
|
|
22
23
|
options: [
|
|
23
24
|
{ name: 'All', value: '' },
|
|
25
|
+
{ name: 'Rules', value: 'rules' },
|
|
24
26
|
{ name: 'Settings', value: 'settings' },
|
|
25
27
|
{ name: 'Users', value: 'users' },
|
|
26
28
|
],
|
|
27
|
-
displayOptions: {
|
|
29
|
+
displayOptions: {
|
|
30
|
+
show: { resource: ['auditLog'], operation: ['getMany'] },
|
|
31
|
+
},
|
|
28
32
|
},
|
|
29
33
|
{
|
|
30
34
|
displayName: 'Action',
|
|
@@ -37,21 +41,30 @@ exports.autoElevateProperties = [
|
|
|
37
41
|
{ name: 'Updated', value: 'updated' },
|
|
38
42
|
{ name: 'Deleted', value: 'deleted' },
|
|
39
43
|
],
|
|
40
|
-
displayOptions: {
|
|
44
|
+
displayOptions: {
|
|
45
|
+
show: { resource: ['auditLog'], operation: ['getMany'] },
|
|
46
|
+
},
|
|
41
47
|
},
|
|
42
48
|
...(0, Common_1.paginationFields)('auditLog'),
|
|
43
49
|
(0, Common_1.getAndListOperations)('company'),
|
|
44
50
|
(0, Common_1.idLocator)('company', 'Company', 'companyId', 'searchCompanies'),
|
|
45
51
|
...(0, Common_1.paginationFields)('company'),
|
|
46
|
-
|
|
47
|
-
(0, Common_1.idLocator)('computer', 'Computer', 'computerId', 'searchComputers'
|
|
52
|
+
Management_1.computerOperations,
|
|
53
|
+
(0, Common_1.idLocator)('computer', 'Computer', 'computerId', 'searchComputers', [
|
|
54
|
+
'get',
|
|
55
|
+
'delete',
|
|
56
|
+
'setElevationMode',
|
|
57
|
+
'setTechnicianMode',
|
|
58
|
+
]),
|
|
48
59
|
(0, Common_1.companyFilter)('computer'),
|
|
49
60
|
{
|
|
50
61
|
displayName: 'Location',
|
|
51
62
|
name: 'locationId',
|
|
52
63
|
type: 'resourceLocator',
|
|
53
64
|
default: { mode: 'list', value: '' },
|
|
54
|
-
displayOptions: {
|
|
65
|
+
displayOptions: {
|
|
66
|
+
show: { resource: ['computer'], operation: ['getMany'] },
|
|
67
|
+
},
|
|
55
68
|
modes: [
|
|
56
69
|
{
|
|
57
70
|
displayName: 'From List',
|
|
@@ -71,7 +84,9 @@ exports.autoElevateProperties = [
|
|
|
71
84
|
name: 'computerId',
|
|
72
85
|
type: 'resourceLocator',
|
|
73
86
|
default: { mode: 'list', value: '' },
|
|
74
|
-
displayOptions: {
|
|
87
|
+
displayOptions: {
|
|
88
|
+
show: { resource: ['elevatedSession'], operation: ['getMany'] },
|
|
89
|
+
},
|
|
75
90
|
modes: [
|
|
76
91
|
{
|
|
77
92
|
displayName: 'From List',
|
|
@@ -92,10 +107,13 @@ exports.autoElevateProperties = [
|
|
|
92
107
|
{ name: 'Active', value: 'active' },
|
|
93
108
|
{ name: 'Inactive', value: 'inactive' },
|
|
94
109
|
],
|
|
95
|
-
displayOptions: {
|
|
110
|
+
displayOptions: {
|
|
111
|
+
show: { resource: ['elevatedSession'], operation: ['getMany'] },
|
|
112
|
+
},
|
|
96
113
|
},
|
|
97
114
|
...(0, Common_1.paginationFields)('elevatedSession'),
|
|
98
|
-
|
|
115
|
+
(0, Common_1.getAndListOperations)('elevationEvent'),
|
|
116
|
+
(0, Common_1.idLocator)('elevationEvent', 'Elevation Event', 'elevationEventId', 'searchElevationEvents'),
|
|
99
117
|
...(0, Common_1.dateRangeFields)('elevationEvent'),
|
|
100
118
|
(0, Common_1.companyFilter)('elevationEvent'),
|
|
101
119
|
...(0, Common_1.paginationFields)('elevationEvent'),
|
|
@@ -106,10 +124,18 @@ exports.autoElevateProperties = [
|
|
|
106
124
|
noDataExpression: true,
|
|
107
125
|
displayOptions: { show: { resource: ['elevationRequest'] } },
|
|
108
126
|
options: [
|
|
109
|
-
{
|
|
127
|
+
{
|
|
128
|
+
name: 'Approve',
|
|
129
|
+
value: 'approve',
|
|
130
|
+
action: 'Approve an elevation request',
|
|
131
|
+
},
|
|
110
132
|
{ name: 'Deny', value: 'deny', action: 'Deny an elevation request' },
|
|
111
133
|
{ name: 'Get', value: 'get', action: 'Get an elevation request' },
|
|
112
|
-
{
|
|
134
|
+
{
|
|
135
|
+
name: 'Get Many',
|
|
136
|
+
value: 'getMany',
|
|
137
|
+
action: 'Get many elevation requests',
|
|
138
|
+
},
|
|
113
139
|
],
|
|
114
140
|
default: 'getMany',
|
|
115
141
|
},
|
|
@@ -126,8 +152,11 @@ exports.autoElevateProperties = [
|
|
|
126
152
|
{ name: 'Approved', value: 'APPROVED' },
|
|
127
153
|
{ name: 'Denied', value: 'DENIED' },
|
|
128
154
|
{ name: 'Pending', value: 'PENDING' },
|
|
155
|
+
{ name: 'Withdrawn', value: 'WITHDRAWN' },
|
|
129
156
|
],
|
|
130
|
-
displayOptions: {
|
|
157
|
+
displayOptions: {
|
|
158
|
+
show: { resource: ['elevationRequest'], operation: ['getMany'] },
|
|
159
|
+
},
|
|
131
160
|
},
|
|
132
161
|
{
|
|
133
162
|
displayName: 'Elevation Type',
|
|
@@ -139,16 +168,20 @@ exports.autoElevateProperties = [
|
|
|
139
168
|
{ name: 'Admin', value: 'admin' },
|
|
140
169
|
{ name: 'User', value: 'user' },
|
|
141
170
|
],
|
|
142
|
-
displayOptions: {
|
|
171
|
+
displayOptions: {
|
|
172
|
+
show: { resource: ['elevationRequest'], operation: ['approve'] },
|
|
173
|
+
},
|
|
143
174
|
},
|
|
144
175
|
{
|
|
145
176
|
displayName: 'Duration (Minutes)',
|
|
146
177
|
name: 'durationInMinutes',
|
|
147
178
|
type: 'number',
|
|
148
179
|
default: 0,
|
|
149
|
-
typeOptions: { minValue: 0 },
|
|
150
|
-
description: '
|
|
151
|
-
displayOptions: {
|
|
180
|
+
typeOptions: { minValue: 0, maxValue: 60 },
|
|
181
|
+
description: 'Required for elevated-session requests: 1 to 60 minutes (at least 10 for Addigy-managed Macs). Leave at 0 only for other request types.',
|
|
182
|
+
displayOptions: {
|
|
183
|
+
show: { resource: ['elevationRequest'], operation: ['approve'] },
|
|
184
|
+
},
|
|
152
185
|
},
|
|
153
186
|
{
|
|
154
187
|
displayName: 'Create Rule',
|
|
@@ -181,9 +214,20 @@ exports.autoElevateProperties = [
|
|
|
181
214
|
},
|
|
182
215
|
},
|
|
183
216
|
...(0, Common_1.paginationFields)('elevationRequest'),
|
|
184
|
-
|
|
217
|
+
Management_1.ruleOperations,
|
|
185
218
|
(0, Common_1.companyFilter)('elevationRule'),
|
|
186
219
|
...(0, Common_1.paginationFields)('elevationRule'),
|
|
220
|
+
{
|
|
221
|
+
displayName: 'Denial Reason',
|
|
222
|
+
name: 'denialReason',
|
|
223
|
+
type: 'string',
|
|
224
|
+
default: '',
|
|
225
|
+
description: 'Reason shown to the end user. Maximum 1000 characters.',
|
|
226
|
+
displayOptions: {
|
|
227
|
+
show: { resource: ['elevationRequest'], operation: ['deny'] },
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
...Management_1.managementProperties,
|
|
187
231
|
(0, Common_1.getAndListOperations)('location'),
|
|
188
232
|
(0, Common_1.idLocator)('location', 'Location', 'locationId', 'searchLocations'),
|
|
189
233
|
(0, Common_1.companyFilter)('location'),
|