@joshuanode/n8n-nodes-cipp 0.0.27 → 0.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +13 -0
  2. package/dist/credentials/CippApi.credentials.js +1 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/nodes/Cipp/{Cipp.node.d.ts → CippApp.node.d.ts} +1 -1
  8. package/dist/nodes/Cipp/CippApp.node.d.ts.map +1 -0
  9. package/dist/nodes/Cipp/{Cipp.node.js → CippApp.node.js} +156 -51
  10. package/dist/nodes/Cipp/CippApp.node.js.map +1 -0
  11. package/dist/nodes/Cipp/cipp.svg +4 -0
  12. package/dist/nodes/Cipp/descriptions/ConditionalAccessDescription.d.ts.map +1 -1
  13. package/dist/nodes/Cipp/descriptions/ConditionalAccessDescription.js +1 -2
  14. package/dist/nodes/Cipp/descriptions/ConditionalAccessDescription.js.map +1 -1
  15. package/dist/nodes/Cipp/descriptions/EmailSecurityDescription.js +7 -7
  16. package/dist/nodes/Cipp/descriptions/IdentityDescription.d.ts.map +1 -1
  17. package/dist/nodes/Cipp/descriptions/IdentityDescription.js +1 -2
  18. package/dist/nodes/Cipp/descriptions/IdentityDescription.js.map +1 -1
  19. package/dist/nodes/Cipp/descriptions/IntuneDescription.js +8 -8
  20. package/dist/nodes/Cipp/descriptions/MailboxDescription.d.ts.map +1 -1
  21. package/dist/nodes/Cipp/descriptions/MailboxDescription.js +1 -5
  22. package/dist/nodes/Cipp/descriptions/MailboxDescription.js.map +1 -1
  23. package/dist/nodes/Cipp/descriptions/OneDriveDescription.js +2 -2
  24. package/dist/nodes/Cipp/descriptions/OneDriveDescription.js.map +1 -1
  25. package/dist/nodes/Cipp/descriptions/PolicyDescription.js +1 -1
  26. package/dist/nodes/Cipp/descriptions/SafeLinksDescription.js +1 -1
  27. package/dist/nodes/Cipp/descriptions/SharePointDescription.js +4 -4
  28. package/dist/nodes/Cipp/descriptions/SharePointDescription.js.map +1 -1
  29. package/dist/nodes/Cipp/descriptions/ShiftDescription.d.ts.map +1 -1
  30. package/dist/nodes/Cipp/descriptions/ShiftDescription.js +2 -3
  31. package/dist/nodes/Cipp/descriptions/ShiftDescription.js.map +1 -1
  32. package/dist/nodes/Cipp/descriptions/TeamDescription.d.ts.map +1 -1
  33. package/dist/nodes/Cipp/descriptions/TeamDescription.js +13 -0
  34. package/dist/nodes/Cipp/descriptions/TeamDescription.js.map +1 -1
  35. package/dist/nodes/Cipp/descriptions/TenantDescription.js +2 -2
  36. package/dist/nodes/Cipp/descriptions/TenantDescription.js.map +1 -1
  37. package/dist/nodes/Cipp/descriptions/UserDescription.d.ts.map +1 -1
  38. package/dist/nodes/Cipp/descriptions/UserDescription.js +4 -10
  39. package/dist/nodes/Cipp/descriptions/UserDescription.js.map +1 -1
  40. package/dist/nodes/Cipp/descriptions/V105Description.d.ts +4 -0
  41. package/dist/nodes/Cipp/descriptions/V105Description.d.ts.map +1 -0
  42. package/dist/nodes/Cipp/descriptions/V105Description.js +237 -0
  43. package/dist/nodes/Cipp/descriptions/V105Description.js.map +1 -0
  44. package/dist/nodes/Cipp/descriptions/index.d.ts.map +1 -1
  45. package/dist/nodes/Cipp/descriptions/index.js +3 -0
  46. package/dist/nodes/Cipp/descriptions/index.js.map +1 -1
  47. package/package.json +3 -3
  48. package/dist/nodes/Cipp/Cipp.node.d.ts.map +0 -1
  49. package/dist/nodes/Cipp/Cipp.node.js.map +0 -1
package/README.md CHANGED
@@ -21,6 +21,7 @@ This node provides full integration with the CIPP API, enabling automation of:
21
21
  - **Intune** - Applications, Autopilot, device actions
22
22
  - **Teams & SharePoint** - Teams, sites, voice numbers, shifts scheduling
23
23
  - **Security & Compliance** - Defender alerts, incidents
24
+ - **CIPP v10.5 APIs** - Purview compliance, enrollment profiles, mailbox restores, alert snoozing, license reports
24
25
  - **Tools** - Breach search, Graph API requests, ExecGraphRequest
25
26
  - **CIPP System** - Scheduled jobs, backups
26
27
 
@@ -77,6 +78,7 @@ For detailed authentication setup, see the [CIPP API Documentation](https://docs
77
78
  | **Voice** | Get Phone Numbers, Get Locations, Assign/Unassign Numbers |
78
79
  | **Scheduled Item** | Add, Get Many, Remove |
79
80
  | **Backup** | Get Many, Run, Restore, Set Auto-Backup |
81
+ | **CIPP v10.5** | Purview compliance policy/SIT/sensitivity label actions, enrollment profile actions, mailbox restore/CAS/HVE reports, alert snoozing, package tags, license reports |
80
82
  | **Tools** | Breach Search (Account/Tenant), Exec Graph Request, Graph Request (List), Graph Request (Exec) |
81
83
 
82
84
  ## Example Usage
@@ -131,6 +133,17 @@ $select: id,displayName,userPrincipalName
131
133
  $filter: startsWith(displayName,'John')
132
134
  ```
133
135
 
136
+ ### CIPP v10.5 APIs
137
+
138
+ ```
139
+ Resource: CIPP v10.5
140
+ Operation: List Licenses Report
141
+ Tenant: Select from dropdown
142
+ Return All: true
143
+ ```
144
+
145
+ Complex CIPP v10.5 create/edit/action operations use a validated JSON body so requests can match CIPP's current API fields without the node guessing incomplete schemas. The node only allows the enumerated CIPP v10.5 endpoints, validates query/body JSON objects, and enforces a maximum serialized body size.
146
+
134
147
  ### Teams Shifts (Dedicated Resource)
135
148
 
136
149
  ```
@@ -53,7 +53,7 @@ async function getAccessToken(credentials) {
53
53
  class CippApi {
54
54
  name = 'cippApi';
55
55
  displayName = 'CIPP.app API';
56
- icon = 'file:cipp.png';
56
+ icon = 'file:cipp.svg';
57
57
  documentationUrl = 'https://docs.cipp.app/api-documentation/setup-and-authentication';
58
58
  genericAuth = true;
59
59
  properties = [
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export * from './nodes/Cipp/Cipp.node';
1
+ export * from './nodes/Cipp/CippApp.node';
2
2
  export * from './credentials/CippApi.credentials';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,mCAAmC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC"}
package/dist/index.js CHANGED
@@ -14,6 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./nodes/Cipp/Cipp.node"), exports);
17
+ __exportStar(require("./nodes/Cipp/CippApp.node"), exports);
18
18
  __exportStar(require("./credentials/CippApi.credentials"), exports);
19
19
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yDAAuC;AACvC,oEAAkD"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4DAA0C;AAC1C,oEAAkD"}
@@ -11,4 +11,4 @@ export declare class Cipp implements INodeType {
11
11
  };
12
12
  execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
13
13
  }
14
- //# sourceMappingURL=Cipp.node.d.ts.map
14
+ //# sourceMappingURL=CippApp.node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CippApp.node.d.ts","sourceRoot":"","sources":["../../../nodes/Cipp/CippApp.node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,qBAAqB,EACrB,wBAAwB,EAExB,iBAAiB,EAEjB,qBAAqB,EACrB,yBAAyB,EACzB,kBAAkB,EAClB,qBAAqB,EACrB,SAAS,EACT,oBAAoB,EACpB,MAAM,cAAc,CAAC;AAWtB,qBAAa,IAAK,YAAW,SAAS;IACrC,WAAW,EAAE,oBAAoB,CA8K/B;IAEF,OAAO;;wCAGE,wBAAwB,cAClB,qBAAqB,GAC/B,OAAO,CAAC,yBAAyB,CAAC;;;+BA6D9B,qBAAqB,WAClB,MAAM,GACb,OAAO,CAAC,qBAAqB,CAAC;;MAqBjC;IAEI,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;CA09HvE"}
@@ -8,7 +8,7 @@ class Cipp {
8
8
  description = {
9
9
  displayName: 'CIPP.app',
10
10
  name: 'cippApp',
11
- icon: 'file:cipp.png',
11
+ icon: 'file:cipp.svg',
12
12
  group: ['transform'],
13
13
  version: 1,
14
14
  subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
@@ -52,6 +52,11 @@ class Cipp {
52
52
  value: 'backup',
53
53
  description: 'Manage CIPP backups',
54
54
  },
55
+ {
56
+ name: 'CIPP v10.5',
57
+ value: 'cippV105',
58
+ description: 'Use CIPP v10.5 API additions',
59
+ },
55
60
  {
56
61
  name: 'Conditional Access',
57
62
  value: 'conditionalAccess',
@@ -113,7 +118,7 @@ class Cipp {
113
118
  description: 'Manage quarantined email messages',
114
119
  },
115
120
  {
116
- name: 'Safe Links',
121
+ name: 'Safe Link',
117
122
  value: 'safeLinks',
118
123
  description: 'Manage Safe Links policies and templates',
119
124
  },
@@ -128,7 +133,7 @@ class Cipp {
128
133
  description: 'Manage SharePoint sites, quotas, and settings',
129
134
  },
130
135
  {
131
- name: 'Standards',
136
+ name: 'Standard',
132
137
  value: 'standards',
133
138
  description: 'Manage tenant standards, drift, BPA, and domain analyser',
134
139
  },
@@ -142,16 +147,16 @@ class Cipp {
142
147
  value: 'teamsShift',
143
148
  description: 'Manage Teams Shifts schedule — shifts, open shifts, groups, time off',
144
149
  },
145
- {
146
- name: 'Testing',
147
- value: 'testing',
148
- description: 'Manage test runs, test reports, and available tests',
149
- },
150
150
  {
151
151
  name: 'Tenant',
152
152
  value: 'tenant',
153
153
  description: 'List and manage tenants',
154
154
  },
155
+ {
156
+ name: 'Testing',
157
+ value: 'testing',
158
+ description: 'Manage test runs, test reports, and available tests',
159
+ },
155
160
  {
156
161
  name: 'Tool',
157
162
  value: 'tools',
@@ -188,31 +193,34 @@ class Cipp {
188
193
  const tokenUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
189
194
  const scope = `api://${clientId}/.default`;
190
195
  const tokenBody = `grant_type=client_credentials&client_id=${encodeURIComponent(clientId)}&client_secret=${encodeURIComponent(clientSecret)}&scope=${encodeURIComponent(scope)}`;
191
- const tokenResponse = (await this.helpers.request({
196
+ const tokenRequest = await fetch(tokenUrl, {
192
197
  method: 'POST',
193
- uri: tokenUrl,
194
198
  headers: {
195
199
  'Content-Type': 'application/x-www-form-urlencoded',
196
200
  },
197
201
  body: tokenBody,
198
- json: true,
199
- }));
200
- if (!tokenResponse.access_token) {
202
+ });
203
+ const tokenResponse = (await tokenRequest.json().catch(() => ({})));
204
+ if (!tokenRequest.ok || typeof tokenResponse.access_token !== 'string') {
201
205
  return {
202
206
  status: 'Error',
203
207
  message: 'Failed to obtain access token from Azure AD. Check your Tenant ID, Client ID, and Client Secret.',
204
208
  };
205
209
  }
206
210
  // Step 2: Test API connection with the token
207
- await this.helpers.request({
211
+ const testRequest = await fetch(`${baseUrl}/api/ListTenants`, {
208
212
  method: 'GET',
209
- uri: `${baseUrl}/api/ListTenants`,
210
213
  headers: {
211
214
  Authorization: `Bearer ${tokenResponse.access_token}`,
212
215
  Accept: 'application/json',
213
216
  },
214
- json: true,
215
217
  });
218
+ if (!testRequest.ok) {
219
+ return {
220
+ status: 'Error',
221
+ message: `CIPP API test request failed with status ${testRequest.status}.`,
222
+ };
223
+ }
216
224
  return {
217
225
  status: 'OK',
218
226
  message: 'Connection successful!',
@@ -309,6 +317,51 @@ class Cipp {
309
317
  .map((entry) => entry.trim())
310
318
  .filter(Boolean);
311
319
  };
320
+ const v105Endpoints = {
321
+ addAssignmentFilterTemplate: { method: 'POST', endpoint: '/api/AddAssignmentFilterTemplate' },
322
+ addDlpCompliancePolicy: { method: 'POST', endpoint: '/api/AddDlpCompliancePolicy' },
323
+ addEnrollment: { method: 'POST', endpoint: '/api/AddEnrollment' },
324
+ addGroupTeam: { method: 'POST', endpoint: '/api/AddGroupTeam' },
325
+ addRetentionCompliancePolicy: { method: 'POST', endpoint: '/api/AddRetentionCompliancePolicy' },
326
+ addSensitiveInfoType: { method: 'POST', endpoint: '/api/AddSensitiveInfoType' },
327
+ addSensitivityLabel: { method: 'POST', endpoint: '/api/AddSensitivityLabel' },
328
+ addUserBulk: { method: 'POST', endpoint: '/api/AddUserBulk' },
329
+ assignPolicy: { method: 'POST', endpoint: '/api/ExecAssignPolicy' },
330
+ editAssignmentFilter: { method: 'POST', endpoint: '/api/EditAssignmentFilter' },
331
+ editDlpCompliancePolicy: { method: 'POST', endpoint: '/api/EditDlpCompliancePolicy' },
332
+ editRetentionCompliancePolicy: { method: 'POST', endpoint: '/api/EditRetentionCompliancePolicy' },
333
+ editSensitiveInfoType: { method: 'POST', endpoint: '/api/EditSensitiveInfoType' },
334
+ editSensitivityLabel: { method: 'POST', endpoint: '/api/EditSensitivityLabel' },
335
+ execAssignmentFilter: { method: 'DELETE', endpoint: '/api/ExecAssignmentFilter' },
336
+ execMailboxRestore: { method: 'POST', endpoint: '/api/ExecMailboxRestore' },
337
+ execMcp: { method: 'POST', endpoint: '/api/ExecMcp' },
338
+ execSpoVersionCleanup: { method: 'POST', endpoint: '/api/ExecSPOVersionCleanup' },
339
+ listActiveSyncDevices: { method: 'GET', endpoint: '/api/ListActiveSyncDevices' },
340
+ listAndroidEnrollmentProfiles: { method: 'POST', endpoint: '/api/ListAndroidEnrollmentProfiles' },
341
+ listAppleEnrollmentProfiles: { method: 'POST', endpoint: '/api/ListAppleEnrollmentProfiles' },
342
+ listAssignmentFilterTemplates: { method: 'GET', endpoint: '/api/ListAssignmentFilterTemplates' },
343
+ listCspSku: { method: 'GET', endpoint: '/api/ListCSPsku' },
344
+ listDlpCompliancePolicy: { method: 'GET', endpoint: '/api/ListDlpCompliancePolicy' },
345
+ listHveAccounts: { method: 'GET', endpoint: '/api/ListHVEAccounts' },
346
+ listLicensesReport: { method: 'GET', endpoint: '/api/ListLicensesReport' },
347
+ listMailboxRestores: { method: 'GET', endpoint: '/api/ListMailboxRestores' },
348
+ listRetentionCompliancePolicy: { method: 'GET', endpoint: '/api/ListRetentionCompliancePolicy' },
349
+ listSensitiveInfoType: { method: 'GET', endpoint: '/api/ListSensitiveInfoType' },
350
+ listSensitivityLabel: { method: 'GET', endpoint: '/api/ListSensitivityLabel' },
351
+ listSnoozedAlerts: { method: 'GET', endpoint: '/api/ListSnoozedAlerts' },
352
+ patchUser: { method: 'PATCH', endpoint: '/api/PatchUser' },
353
+ removeAdminRole: { method: 'POST', endpoint: '/api/ExecRemoveAdminRole' },
354
+ removeAssignmentFilterTemplate: { method: 'POST', endpoint: '/api/RemoveAssignmentFilterTemplate' },
355
+ removeDlpCompliancePolicy: { method: 'POST', endpoint: '/api/RemoveDlpCompliancePolicy' },
356
+ removeEnrollmentProfile: { method: 'POST', endpoint: '/api/ExecRemoveEnrollmentProfile' },
357
+ removeRetentionCompliancePolicy: { method: 'POST', endpoint: '/api/RemoveRetentionCompliancePolicy' },
358
+ removeSensitiveInfoType: { method: 'POST', endpoint: '/api/RemoveSensitiveInfoType' },
359
+ removeSensitivityLabel: { method: 'POST', endpoint: '/api/RemoveSensitivityLabel' },
360
+ removeSnooze: { method: 'POST', endpoint: '/api/ExecRemoveSnooze' },
361
+ setCasMailbox: { method: 'POST', endpoint: '/api/ExecSetCASMailbox' },
362
+ setPackageTag: { method: 'POST', endpoint: '/api/ExecSetPackageTag' },
363
+ snoozeAlert: { method: 'POST', endpoint: '/api/ExecSnoozeAlert' },
364
+ };
312
365
  for (let i = 0; i < items.length; i++) {
313
366
  try {
314
367
  let responseData = {};
@@ -352,7 +405,9 @@ class Cipp {
352
405
  // Strip out AssignedUsers and AssignedGroups if summaryOnly is enabled
353
406
  if (licenseOptions.summaryOnly && Array.isArray(responseData)) {
354
407
  responseData = responseData.map((license) => {
355
- const { AssignedUsers, AssignedGroups, ...summary } = license;
408
+ const summary = { ...license };
409
+ delete summary.AssignedUsers;
410
+ delete summary.AssignedGroups;
356
411
  return summary;
357
412
  });
358
413
  }
@@ -881,7 +936,7 @@ class Cipp {
881
936
  try {
882
937
  editData = JSON.parse(editJson);
883
938
  }
884
- catch (e) {
939
+ catch {
885
940
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Policy JSON must be valid JSON', { itemIndex: i });
886
941
  }
887
942
  if (editData.displayName)
@@ -901,7 +956,7 @@ class Cipp {
901
956
  try {
902
957
  templateData = JSON.parse(templateJson);
903
958
  }
904
- catch (e) {
959
+ catch {
905
960
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Template JSON must be valid JSON', { itemIndex: i });
906
961
  }
907
962
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/AddCATemplate', {
@@ -959,7 +1014,7 @@ class Cipp {
959
1014
  try {
960
1015
  locationData = JSON.parse(locationJson);
961
1016
  }
962
- catch (e) {
1017
+ catch {
963
1018
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Location JSON must be valid JSON', { itemIndex: i });
964
1019
  }
965
1020
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/ExecNamedLocation', {
@@ -1901,7 +1956,12 @@ class Cipp {
1901
1956
  else if (operation === 'getSites') {
1902
1957
  const returnAll = this.getNodeParameter('returnAll', i);
1903
1958
  const siteType = this.getNodeParameter('siteType', i);
1904
- responseData = await GenericFunctions_1.cippApiRequest.call(this, 'GET', '/api/ListSites', {}, { tenantFilter, type: siteType });
1959
+ const useReportDB = this.getNodeParameter('useReportDB', i, false);
1960
+ const sitesQuery = { tenantFilter, type: siteType };
1961
+ if (useReportDB) {
1962
+ sitesQuery.UseReportDB = true;
1963
+ }
1964
+ responseData = await GenericFunctions_1.cippApiRequest.call(this, 'GET', '/api/ListSites', {}, sitesQuery);
1905
1965
  if (Array.isArray(responseData) && !returnAll) {
1906
1966
  const limit = this.getNodeParameter('limit', i);
1907
1967
  responseData = responseData.slice(0, limit);
@@ -2030,7 +2090,7 @@ class Cipp {
2030
2090
  try {
2031
2091
  policyData = JSON.parse(policyJson);
2032
2092
  }
2033
- catch (e) {
2093
+ catch {
2034
2094
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Policy JSON must be valid JSON', { itemIndex: i });
2035
2095
  }
2036
2096
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/ExecNewSafeLinksPolicy', {
@@ -2046,7 +2106,7 @@ class Cipp {
2046
2106
  try {
2047
2107
  policyData = JSON.parse(policyJson);
2048
2108
  }
2049
- catch (e) {
2109
+ catch {
2050
2110
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Policy JSON must be valid JSON', { itemIndex: i });
2051
2111
  }
2052
2112
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/EditSafeLinksPolicy', {
@@ -2069,7 +2129,7 @@ class Cipp {
2069
2129
  try {
2070
2130
  templateData = JSON.parse(templateJson);
2071
2131
  }
2072
- catch (e) {
2132
+ catch {
2073
2133
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Template JSON must be valid JSON', { itemIndex: i });
2074
2134
  }
2075
2135
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/AddSafeLinksPolicyTemplate', {
@@ -2084,7 +2144,7 @@ class Cipp {
2084
2144
  try {
2085
2145
  templateData = JSON.parse(templateJson);
2086
2146
  }
2087
- catch (e) {
2147
+ catch {
2088
2148
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Template JSON must be valid JSON', { itemIndex: i });
2089
2149
  }
2090
2150
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/EditSafeLinksPolicyTemplate', {
@@ -2180,6 +2240,50 @@ class Cipp {
2180
2240
  }, {});
2181
2241
  }
2182
2242
  }
2243
+ // ==================== CIPP V10.5 ====================
2244
+ else if (resource === 'cippV105') {
2245
+ const config = v105Endpoints[operation];
2246
+ if (!config) {
2247
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unsupported CIPP v10.5 operation: ${operation}`, { itemIndex: i });
2248
+ }
2249
+ const includeTenant = this.getNodeParameter('v105IncludeTenant', i);
2250
+ const query = parseJsonObjectPayload(this.getNodeParameter('v105QueryJson', i, '{}'), 'Query Parameters', i);
2251
+ const body = config.method === 'GET'
2252
+ ? {}
2253
+ : parseJsonObjectPayload(this.getNodeParameter('v105BodyJson', i, '{}'), 'Body', i);
2254
+ if (includeTenant) {
2255
+ const tenantValue = this.getNodeParameter('tenantFilter', i);
2256
+ const tenantFilter = (0, GenericFunctions_1.getResourceLocatorValue)(tenantValue);
2257
+ if (!tenantFilter) {
2258
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Tenant is required.', {
2259
+ itemIndex: i,
2260
+ });
2261
+ }
2262
+ if (!query.tenantFilter) {
2263
+ query.tenantFilter = tenantFilter;
2264
+ }
2265
+ if (!body.tenantFilter) {
2266
+ body.tenantFilter = tenantFilter;
2267
+ }
2268
+ }
2269
+ const options = this.getNodeParameter('v105Options', i, {});
2270
+ const maxPayloadBytes = Number(options.maxPayloadBytes ?? 262144);
2271
+ if (!Number.isFinite(maxPayloadBytes) || maxPayloadBytes <= 0) {
2272
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Max Payload Bytes must be a positive number.', { itemIndex: i });
2273
+ }
2274
+ const payloadBytes = new TextEncoder().encode(JSON.stringify(body)).length;
2275
+ if (payloadBytes > maxPayloadBytes) {
2276
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Payload is ${payloadBytes} bytes, which exceeds Max Payload Bytes (${maxPayloadBytes}).`, { itemIndex: i });
2277
+ }
2278
+ responseData = await GenericFunctions_1.cippApiRequest.call(this, config.method, config.endpoint, body, query);
2279
+ if (Array.isArray(responseData)) {
2280
+ const returnAll = this.getNodeParameter('returnAll', i, true);
2281
+ if (!returnAll) {
2282
+ const limit = this.getNodeParameter('limit', i);
2283
+ responseData = responseData.slice(0, limit);
2284
+ }
2285
+ }
2286
+ }
2183
2287
  // ==================== TOOLS ====================
2184
2288
  else if (resource === 'tools') {
2185
2289
  if (operation === 'breachAccount') {
@@ -2741,7 +2845,7 @@ class Cipp {
2741
2845
  try {
2742
2846
  policyData = JSON.parse(policyJson);
2743
2847
  }
2744
- catch (e) {
2848
+ catch {
2745
2849
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Policy JSON must be valid JSON', { itemIndex: i });
2746
2850
  }
2747
2851
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/AddSpamFilter', {
@@ -2755,7 +2859,7 @@ class Cipp {
2755
2859
  try {
2756
2860
  policyData = JSON.parse(policyJson);
2757
2861
  }
2758
- catch (e) {
2862
+ catch {
2759
2863
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Policy JSON must be valid JSON', { itemIndex: i });
2760
2864
  }
2761
2865
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/EditSpamFilter', {
@@ -2783,7 +2887,7 @@ class Cipp {
2783
2887
  try {
2784
2888
  ruleData = JSON.parse(ruleJson);
2785
2889
  }
2786
- catch (e) {
2890
+ catch {
2787
2891
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Rule JSON must be valid JSON', { itemIndex: i });
2788
2892
  }
2789
2893
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/AddTransportRule', {
@@ -2797,7 +2901,7 @@ class Cipp {
2797
2901
  try {
2798
2902
  ruleData = JSON.parse(ruleJson);
2799
2903
  }
2800
- catch (e) {
2904
+ catch {
2801
2905
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Rule JSON must be valid JSON', { itemIndex: i });
2802
2906
  }
2803
2907
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/EditTransportRule', {
@@ -2825,7 +2929,7 @@ class Cipp {
2825
2929
  try {
2826
2930
  connectorData = JSON.parse(connectorJson);
2827
2931
  }
2828
- catch (e) {
2932
+ catch {
2829
2933
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Connector JSON must be valid JSON', { itemIndex: i });
2830
2934
  }
2831
2935
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/AddExConnector', {
@@ -2839,7 +2943,7 @@ class Cipp {
2839
2943
  try {
2840
2944
  connectorData = JSON.parse(connectorJson);
2841
2945
  }
2842
- catch (e) {
2946
+ catch {
2843
2947
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Connector JSON must be valid JSON', { itemIndex: i });
2844
2948
  }
2845
2949
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/EditExConnector', {
@@ -2867,7 +2971,7 @@ class Cipp {
2867
2971
  try {
2868
2972
  filterData = JSON.parse(filterJson);
2869
2973
  }
2870
- catch (e) {
2974
+ catch {
2871
2975
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Filter JSON must be valid JSON', { itemIndex: i });
2872
2976
  }
2873
2977
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/AddConnectionFilter', {
@@ -2888,7 +2992,7 @@ class Cipp {
2888
2992
  try {
2889
2993
  filterData = JSON.parse(filterJson);
2890
2994
  }
2891
- catch (e) {
2995
+ catch {
2892
2996
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Filter JSON must be valid JSON', { itemIndex: i });
2893
2997
  }
2894
2998
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/EditAntiPhishingFilter', {
@@ -2909,7 +3013,7 @@ class Cipp {
2909
3013
  try {
2910
3014
  filterData = JSON.parse(filterJson);
2911
3015
  }
2912
- catch (e) {
3016
+ catch {
2913
3017
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Filter JSON must be valid JSON', { itemIndex: i });
2914
3018
  }
2915
3019
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/EditMalwareFilter', {
@@ -2930,7 +3034,7 @@ class Cipp {
2930
3034
  try {
2931
3035
  blockListData = JSON.parse(blockListJson);
2932
3036
  }
2933
- catch (e) {
3037
+ catch {
2934
3038
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Block List JSON must be valid JSON', { itemIndex: i });
2935
3039
  }
2936
3040
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/AddTenantAllowBlockList', {
@@ -2944,7 +3048,7 @@ class Cipp {
2944
3048
  try {
2945
3049
  blockListData = JSON.parse(blockListJson);
2946
3050
  }
2947
- catch (e) {
3051
+ catch {
2948
3052
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Block List JSON must be valid JSON', { itemIndex: i });
2949
3053
  }
2950
3054
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/RemoveTenantAllowBlockList', {
@@ -2980,7 +3084,7 @@ class Cipp {
2980
3084
  try {
2981
3085
  additionalData = JSON.parse(additionalJson);
2982
3086
  }
2983
- catch (e) {
3087
+ catch {
2984
3088
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Additional JSON must be valid JSON', { itemIndex: i });
2985
3089
  }
2986
3090
  }
@@ -2998,7 +3102,7 @@ class Cipp {
2998
3102
  try {
2999
3103
  roomData = JSON.parse(roomJson);
3000
3104
  }
3001
- catch (e) {
3105
+ catch {
3002
3106
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Room JSON must be valid JSON', { itemIndex: i });
3003
3107
  }
3004
3108
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/EditRoomMailbox', {
@@ -3030,7 +3134,7 @@ class Cipp {
3030
3134
  try {
3031
3135
  equipmentData = JSON.parse(equipmentJson);
3032
3136
  }
3033
- catch (e) {
3137
+ catch {
3034
3138
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Equipment JSON must be valid JSON', { itemIndex: i });
3035
3139
  }
3036
3140
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/EditEquipmentMailbox', {
@@ -3062,7 +3166,7 @@ class Cipp {
3062
3166
  try {
3063
3167
  roomListData = JSON.parse(roomListJson);
3064
3168
  }
3065
- catch (e) {
3169
+ catch {
3066
3170
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Room List JSON must be valid JSON', { itemIndex: i });
3067
3171
  }
3068
3172
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/EditRoomList', {
@@ -3108,7 +3212,7 @@ class Cipp {
3108
3212
  try {
3109
3213
  standardsData = JSON.parse(standardsJson);
3110
3214
  }
3111
- catch (e) {
3215
+ catch {
3112
3216
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Standards JSON must be valid JSON', { itemIndex: i });
3113
3217
  }
3114
3218
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/AddStandardsDeploy', {
@@ -3136,7 +3240,7 @@ class Cipp {
3136
3240
  try {
3137
3241
  templateData = JSON.parse(templateJson);
3138
3242
  }
3139
- catch (e) {
3243
+ catch {
3140
3244
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Template JSON must be valid JSON', { itemIndex: i });
3141
3245
  }
3142
3246
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/AddStandardsTemplate', {
@@ -3208,7 +3312,7 @@ class Cipp {
3208
3312
  try {
3209
3313
  driftData = JSON.parse(driftJson);
3210
3314
  }
3211
- catch (e) {
3315
+ catch {
3212
3316
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Drift JSON must be valid JSON', { itemIndex: i });
3213
3317
  }
3214
3318
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/ExecDriftClone', {
@@ -3233,7 +3337,7 @@ class Cipp {
3233
3337
  try {
3234
3338
  scriptData = JSON.parse(scriptJson);
3235
3339
  }
3236
- catch (e) {
3340
+ catch {
3237
3341
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Script JSON must be valid JSON', { itemIndex: i });
3238
3342
  }
3239
3343
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/EditIntuneScript', {
@@ -3275,7 +3379,7 @@ class Cipp {
3275
3379
  try {
3276
3380
  filterData = JSON.parse(filterJson);
3277
3381
  }
3278
- catch (e) {
3382
+ catch {
3279
3383
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Filter JSON must be valid JSON', { itemIndex: i });
3280
3384
  }
3281
3385
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/AddAssignmentFilter', {
@@ -3296,7 +3400,7 @@ class Cipp {
3296
3400
  try {
3297
3401
  settingData = JSON.parse(settingJson);
3298
3402
  }
3299
- catch (e) {
3403
+ catch {
3300
3404
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Setting JSON must be valid JSON', { itemIndex: i });
3301
3405
  }
3302
3406
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/AddIntuneReusableSetting', {
@@ -3324,7 +3428,7 @@ class Cipp {
3324
3428
  try {
3325
3429
  appData = JSON.parse(appJson);
3326
3430
  }
3327
- catch (e) {
3431
+ catch {
3328
3432
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'App JSON must be valid JSON', { itemIndex: i });
3329
3433
  }
3330
3434
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/AddWin32ScriptApp', {
@@ -3359,7 +3463,8 @@ class Cipp {
3359
3463
  }
3360
3464
  else if (operation === 'listSharepointAdminUrl') {
3361
3465
  const returnAll = this.getNodeParameter('returnAll', i);
3362
- responseData = await GenericFunctions_1.cippApiRequest.call(this, 'GET', '/api/ListSharepointAdminUrl', {}, { tenantFilter });
3466
+ // ReturnUrl=true makes the endpoint return JSON ({ AdminUrl }) instead of a 302 redirect to the admin center
3467
+ responseData = await GenericFunctions_1.cippApiRequest.call(this, 'GET', '/api/ListSharepointAdminUrl', {}, { tenantFilter, ReturnUrl: true });
3363
3468
  if (Array.isArray(responseData) && !returnAll) {
3364
3469
  responseData = responseData.slice(0, this.getNodeParameter('limit', i));
3365
3470
  }
@@ -3388,7 +3493,7 @@ class Cipp {
3388
3493
  try {
3389
3494
  testData = JSON.parse(testJson);
3390
3495
  }
3391
- catch (e) {
3496
+ catch {
3392
3497
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Test JSON must be valid JSON', { itemIndex: i });
3393
3498
  }
3394
3499
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/ExecTestRun', {
@@ -3409,7 +3514,7 @@ class Cipp {
3409
3514
  try {
3410
3515
  reportData = JSON.parse(reportJson);
3411
3516
  }
3412
- catch (e) {
3517
+ catch {
3413
3518
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Report JSON must be valid JSON', { itemIndex: i });
3414
3519
  }
3415
3520
  responseData = await GenericFunctions_1.cippApiRequest.call(this, 'POST', '/api/AddTestReport', {
@@ -3442,4 +3547,4 @@ class Cipp {
3442
3547
  }
3443
3548
  }
3444
3549
  exports.Cipp = Cipp;
3445
- //# sourceMappingURL=Cipp.node.js.map
3550
+ //# sourceMappingURL=CippApp.node.js.map