@pnp/cli-microsoft365 7.7.0 → 7.8.0-beta.5ca5055
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/allCommands.json +1 -1
- package/allCommandsFull.json +1 -1
- package/dist/cli/cli.js +16 -1
- package/dist/m365/cli/commands/config/config-set.js +4 -0
- package/dist/m365/flow/commands/run/run-list.js +25 -0
- package/dist/m365/spo/commands/site/site-add.js +17 -26
- package/dist/m365/spo/commands/site/site-remove.js +17 -26
- package/dist/m365/spo/commands/site/site-set.js +9 -13
- package/dist/m365/spo/commands/tenant/tenant-recyclebinitem-remove.js +9 -13
- package/dist/settingsNames.js +1 -0
- package/dist/utils/spo.js +209 -278
- package/docs/docs/_clisettings.mdx +1 -0
- package/docs/docs/cmd/flow/run/run-list.mdx +74 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
package/dist/utils/spo.js
CHANGED
|
@@ -11,8 +11,9 @@ import { odata } from './odata.js';
|
|
|
11
11
|
import { RoleType } from '../m365/spo/commands/roledefinition/RoleType.js';
|
|
12
12
|
import { entraGroup } from './entraGroup.js';
|
|
13
13
|
import { SharingCapabilities } from '../m365/spo/commands/site/SharingCapabilities.js';
|
|
14
|
+
import { setTimeout } from 'timers/promises';
|
|
14
15
|
export const spo = {
|
|
15
|
-
getRequestDigest(siteUrl) {
|
|
16
|
+
async getRequestDigest(siteUrl) {
|
|
16
17
|
const requestOptions = {
|
|
17
18
|
url: `${siteUrl}/_api/contextinfo`,
|
|
18
19
|
headers: {
|
|
@@ -22,172 +23,128 @@ export const spo = {
|
|
|
22
23
|
};
|
|
23
24
|
return request.post(requestOptions);
|
|
24
25
|
},
|
|
25
|
-
ensureFormDigest(siteUrl, logger, context, debug) {
|
|
26
|
-
|
|
27
|
-
if (validation.isValidFormDigest(context)) {
|
|
28
|
-
if (debug) {
|
|
29
|
-
await logger.logToStderr('Existing form digest still valid');
|
|
30
|
-
}
|
|
31
|
-
resolve(context);
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
spo
|
|
35
|
-
.getRequestDigest(siteUrl)
|
|
36
|
-
.then((res) => {
|
|
37
|
-
const now = new Date();
|
|
38
|
-
now.setSeconds(now.getSeconds() + res.FormDigestTimeoutSeconds - 5);
|
|
39
|
-
context = {
|
|
40
|
-
FormDigestValue: res.FormDigestValue,
|
|
41
|
-
FormDigestTimeoutSeconds: res.FormDigestTimeoutSeconds,
|
|
42
|
-
FormDigestExpiresAt: now,
|
|
43
|
-
WebFullUrl: res.WebFullUrl
|
|
44
|
-
};
|
|
45
|
-
resolve(context);
|
|
46
|
-
}, (error) => {
|
|
47
|
-
reject(error);
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
},
|
|
51
|
-
waitUntilFinished({ operationId, siteUrl, resolve, reject, logger, currentContext, debug, verbose }) {
|
|
52
|
-
spo
|
|
53
|
-
.ensureFormDigest(siteUrl, logger, currentContext, debug)
|
|
54
|
-
.then(async (res) => {
|
|
55
|
-
currentContext = res;
|
|
26
|
+
async ensureFormDigest(siteUrl, logger, context, debug) {
|
|
27
|
+
if (validation.isValidFormDigest(context)) {
|
|
56
28
|
if (debug) {
|
|
57
|
-
await logger.logToStderr(
|
|
29
|
+
await logger.logToStderr('Existing form digest still valid');
|
|
58
30
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
31
|
+
return context;
|
|
32
|
+
}
|
|
33
|
+
const res = await spo.getRequestDigest(siteUrl);
|
|
34
|
+
const now = new Date();
|
|
35
|
+
now.setSeconds(now.getSeconds() + res.FormDigestTimeoutSeconds - 5);
|
|
36
|
+
context = {
|
|
37
|
+
FormDigestValue: res.FormDigestValue,
|
|
38
|
+
FormDigestTimeoutSeconds: res.FormDigestTimeoutSeconds,
|
|
39
|
+
FormDigestExpiresAt: now,
|
|
40
|
+
WebFullUrl: res.WebFullUrl
|
|
41
|
+
};
|
|
42
|
+
return context;
|
|
43
|
+
},
|
|
44
|
+
async waitUntilFinished({ operationId, siteUrl, logger, currentContext, debug, verbose }) {
|
|
45
|
+
const resFormDigest = await spo.ensureFormDigest(siteUrl, logger, currentContext, debug);
|
|
46
|
+
currentContext = resFormDigest;
|
|
47
|
+
if (debug) {
|
|
48
|
+
await logger.logToStderr(`Checking if operation ${operationId} completed...`);
|
|
49
|
+
}
|
|
50
|
+
const requestOptions = {
|
|
51
|
+
url: `${siteUrl}/_vti_bin/client.svc/ProcessQuery`,
|
|
52
|
+
headers: {
|
|
53
|
+
'X-RequestDigest': currentContext.FormDigestValue
|
|
54
|
+
},
|
|
55
|
+
data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><Query Id="188" ObjectPathId="184"><Query SelectAllProperties="false"><Properties><Property Name="IsComplete" ScalarProperty="true" /><Property Name="PollingInterval" ScalarProperty="true" /></Properties></Query></Query></Actions><ObjectPaths><Identity Id="184" Name="${operationId.replace(/\\n/g, '
').replace(/"/g, '')}" /></ObjectPaths></Request>`
|
|
56
|
+
};
|
|
57
|
+
const res = await request.post(requestOptions);
|
|
58
|
+
const json = JSON.parse(res);
|
|
59
|
+
const response = json[0];
|
|
60
|
+
if (response.ErrorInfo) {
|
|
61
|
+
throw new Error(response.ErrorInfo.ErrorMessage);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
const operation = json[json.length - 1];
|
|
65
|
+
const isComplete = operation.IsComplete;
|
|
66
|
+
if (isComplete) {
|
|
67
|
+
if (!debug && verbose) {
|
|
68
|
+
process.stdout.write('\n');
|
|
83
69
|
}
|
|
84
|
-
|
|
85
|
-
spo.waitUntilFinished({
|
|
86
|
-
operationId: JSON.stringify(operation._ObjectIdentity_),
|
|
87
|
-
siteUrl,
|
|
88
|
-
resolve,
|
|
89
|
-
reject,
|
|
90
|
-
logger,
|
|
91
|
-
currentContext,
|
|
92
|
-
debug,
|
|
93
|
-
verbose
|
|
94
|
-
});
|
|
95
|
-
}, operation.PollingInterval);
|
|
70
|
+
return;
|
|
96
71
|
}
|
|
97
|
-
|
|
72
|
+
await setTimeout(operation.PollingInterval);
|
|
73
|
+
await spo.waitUntilFinished({
|
|
74
|
+
operationId: JSON.stringify(operation._ObjectIdentity_),
|
|
75
|
+
siteUrl,
|
|
76
|
+
logger,
|
|
77
|
+
currentContext,
|
|
78
|
+
debug,
|
|
79
|
+
verbose
|
|
80
|
+
});
|
|
81
|
+
}
|
|
98
82
|
},
|
|
99
83
|
async getSpoUrl(logger, debug) {
|
|
100
84
|
if (auth.connection.spoUrl) {
|
|
101
85
|
if (debug) {
|
|
102
86
|
await logger.logToStderr(`SPO URL previously retrieved ${auth.connection.spoUrl}. Returning...`);
|
|
103
87
|
}
|
|
104
|
-
return
|
|
88
|
+
return auth.connection.spoUrl;
|
|
89
|
+
}
|
|
90
|
+
if (debug) {
|
|
91
|
+
await logger.logToStderr(`No SPO URL available. Retrieving from MS Graph...`);
|
|
105
92
|
}
|
|
106
|
-
|
|
93
|
+
const requestOptions = {
|
|
94
|
+
url: `https://graph.microsoft.com/v1.0/sites/root?$select=webUrl`,
|
|
95
|
+
headers: {
|
|
96
|
+
'accept': 'application/json;odata.metadata=none'
|
|
97
|
+
},
|
|
98
|
+
responseType: 'json'
|
|
99
|
+
};
|
|
100
|
+
const res = await request.get(requestOptions);
|
|
101
|
+
auth.connection.spoUrl = res.webUrl;
|
|
102
|
+
try {
|
|
103
|
+
await auth.storeConnectionInfo();
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
107
106
|
if (debug) {
|
|
108
|
-
await logger.logToStderr(
|
|
107
|
+
await logger.logToStderr('Error while storing connection info');
|
|
109
108
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
headers: {
|
|
113
|
-
'accept': 'application/json;odata.metadata=none'
|
|
114
|
-
},
|
|
115
|
-
responseType: 'json'
|
|
116
|
-
};
|
|
117
|
-
request
|
|
118
|
-
.get(requestOptions)
|
|
119
|
-
.then((res) => {
|
|
120
|
-
auth.connection.spoUrl = res.webUrl;
|
|
121
|
-
return auth.storeConnectionInfo();
|
|
122
|
-
})
|
|
123
|
-
.then(() => {
|
|
124
|
-
resolve(auth.connection.spoUrl);
|
|
125
|
-
}, (err) => {
|
|
126
|
-
if (auth.connection.spoUrl) {
|
|
127
|
-
resolve(auth.connection.spoUrl);
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
reject(err);
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
});
|
|
109
|
+
}
|
|
110
|
+
return auth.connection.spoUrl;
|
|
134
111
|
},
|
|
135
|
-
getSpoAdminUrl(logger, debug) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
.getSpoUrl(logger, debug)
|
|
139
|
-
.then((spoUrl) => {
|
|
140
|
-
resolve(spoUrl.replace(/(https:\/\/)([^\.]+)(.*)/, '$1$2-admin$3'));
|
|
141
|
-
}, (error) => {
|
|
142
|
-
reject(error);
|
|
143
|
-
});
|
|
144
|
-
});
|
|
112
|
+
async getSpoAdminUrl(logger, debug) {
|
|
113
|
+
const spoUrl = await spo.getSpoUrl(logger, debug);
|
|
114
|
+
return (spoUrl.replace(/(https:\/\/)([^\.]+)(.*)/, '$1$2-admin$3'));
|
|
145
115
|
},
|
|
146
116
|
async getTenantId(logger, debug) {
|
|
147
117
|
if (auth.connection.spoTenantId) {
|
|
148
118
|
if (debug) {
|
|
149
119
|
await logger.logToStderr(`SPO Tenant ID previously retrieved ${auth.connection.spoTenantId}. Returning...`);
|
|
150
120
|
}
|
|
151
|
-
return
|
|
121
|
+
return auth.connection.spoTenantId;
|
|
122
|
+
}
|
|
123
|
+
if (debug) {
|
|
124
|
+
await logger.logToStderr(`No SPO Tenant ID available. Retrieving...`);
|
|
125
|
+
}
|
|
126
|
+
const spoAdminUrl = await spo.getSpoAdminUrl(logger, debug);
|
|
127
|
+
const contextInfo = await spo.getRequestDigest(spoAdminUrl);
|
|
128
|
+
const tenantInfoRequestOptions = {
|
|
129
|
+
url: `${spoAdminUrl}/_vti_bin/client.svc/ProcessQuery`,
|
|
130
|
+
headers: {
|
|
131
|
+
'X-RequestDigest': contextInfo.FormDigestValue,
|
|
132
|
+
accept: 'application/json;odata=nometadata'
|
|
133
|
+
},
|
|
134
|
+
data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="4" ObjectPathId="3" /><Query Id="5" ObjectPathId="3"><Query SelectAllProperties="true"><Properties /></Query></Query></Actions><ObjectPaths><Constructor Id="3" TypeId="{268004ae-ef6b-4e9b-8425-127220d84719}" /></ObjectPaths></Request>`
|
|
135
|
+
};
|
|
136
|
+
const res = await request.post(tenantInfoRequestOptions);
|
|
137
|
+
const json = JSON.parse(res);
|
|
138
|
+
auth.connection.spoTenantId = json[json.length - 1]._ObjectIdentity_.replace('\n', '
');
|
|
139
|
+
try {
|
|
140
|
+
await auth.storeConnectionInfo();
|
|
152
141
|
}
|
|
153
|
-
|
|
142
|
+
catch (e) {
|
|
154
143
|
if (debug) {
|
|
155
|
-
await logger.logToStderr(
|
|
144
|
+
await logger.logToStderr('Error while storing connection info');
|
|
156
145
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
.getSpoAdminUrl(logger, debug)
|
|
160
|
-
.then((_spoAdminUrl) => {
|
|
161
|
-
spoAdminUrl = _spoAdminUrl;
|
|
162
|
-
return spo.getRequestDigest(spoAdminUrl);
|
|
163
|
-
})
|
|
164
|
-
.then((contextInfo) => {
|
|
165
|
-
const tenantInfoRequestOptions = {
|
|
166
|
-
url: `${spoAdminUrl}/_vti_bin/client.svc/ProcessQuery`,
|
|
167
|
-
headers: {
|
|
168
|
-
'X-RequestDigest': contextInfo.FormDigestValue,
|
|
169
|
-
accept: 'application/json;odata=nometadata'
|
|
170
|
-
},
|
|
171
|
-
data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="4" ObjectPathId="3" /><Query Id="5" ObjectPathId="3"><Query SelectAllProperties="true"><Properties /></Query></Query></Actions><ObjectPaths><Constructor Id="3" TypeId="{268004ae-ef6b-4e9b-8425-127220d84719}" /></ObjectPaths></Request>`
|
|
172
|
-
};
|
|
173
|
-
return request.post(tenantInfoRequestOptions);
|
|
174
|
-
})
|
|
175
|
-
.then((res) => {
|
|
176
|
-
const json = JSON.parse(res);
|
|
177
|
-
auth.connection.spoTenantId = json[json.length - 1]._ObjectIdentity_.replace('\n', '
');
|
|
178
|
-
return auth.storeConnectionInfo();
|
|
179
|
-
})
|
|
180
|
-
.then(() => {
|
|
181
|
-
resolve(auth.connection.spoTenantId);
|
|
182
|
-
}, (err) => {
|
|
183
|
-
if (auth.connection.spoTenantId) {
|
|
184
|
-
resolve(auth.connection.spoTenantId);
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
reject(err);
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
|
-
});
|
|
146
|
+
}
|
|
147
|
+
return auth.connection.spoTenantId;
|
|
191
148
|
},
|
|
192
149
|
/**
|
|
193
150
|
* Returns the Graph id of a site
|
|
@@ -214,10 +171,10 @@ export const spo = {
|
|
|
214
171
|
async ensureFolder(webFullUrl, folderToEnsure, logger, debug) {
|
|
215
172
|
const webUrl = url.parse(webFullUrl);
|
|
216
173
|
if (!webUrl.protocol || !webUrl.hostname) {
|
|
217
|
-
|
|
174
|
+
throw new Error('webFullUrl is not a valid URL');
|
|
218
175
|
}
|
|
219
176
|
if (!folderToEnsure) {
|
|
220
|
-
|
|
177
|
+
throw new Error('folderToEnsure cannot be empty');
|
|
221
178
|
}
|
|
222
179
|
// remove last '/' of webFullUrl if exists
|
|
223
180
|
const webFullUrlLastCharPos = webFullUrl.length - 1;
|
|
@@ -242,12 +199,12 @@ export const spo = {
|
|
|
242
199
|
await logger.log('');
|
|
243
200
|
}
|
|
244
201
|
// recursive function
|
|
245
|
-
|
|
202
|
+
async function checkOrAddFolder() {
|
|
246
203
|
if (folderIndex === folders.length) {
|
|
247
204
|
if (debug) {
|
|
248
205
|
await logger.log(`All sub-folders exist`);
|
|
249
206
|
}
|
|
250
|
-
return
|
|
207
|
+
return;
|
|
251
208
|
}
|
|
252
209
|
// append the next sub-folder to the folder path and check if it exists
|
|
253
210
|
prevFolder = nextFolder;
|
|
@@ -259,13 +216,12 @@ export const spo = {
|
|
|
259
216
|
'accept': 'application/json;odata=nometadata'
|
|
260
217
|
}
|
|
261
218
|
};
|
|
262
|
-
|
|
263
|
-
.get(requestOptions)
|
|
264
|
-
.then(() => {
|
|
219
|
+
try {
|
|
220
|
+
await request.get(requestOptions);
|
|
265
221
|
folderIndex++;
|
|
266
|
-
checkOrAddFolder(
|
|
267
|
-
}
|
|
268
|
-
|
|
222
|
+
await checkOrAddFolder();
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
269
225
|
const prevFolderServerRelativeUrl = urlUtil.getServerRelativePath(webFullUrl, prevFolder);
|
|
270
226
|
const requestOptions = {
|
|
271
227
|
url: `${webFullUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl=@a1)/AddSubFolderUsingPath(DecodedUrl=@a2)?@a1=%27${formatting.encodeQueryParameter(prevFolderServerRelativeUrl)}%27&@a2=%27${formatting.encodeQueryParameter(folders[folderIndex])}%27`,
|
|
@@ -274,20 +230,21 @@ export const spo = {
|
|
|
274
230
|
},
|
|
275
231
|
responseType: 'json'
|
|
276
232
|
};
|
|
277
|
-
|
|
278
|
-
.
|
|
233
|
+
try {
|
|
234
|
+
await request.post(requestOptions);
|
|
279
235
|
folderIndex++;
|
|
280
|
-
checkOrAddFolder(
|
|
281
|
-
}
|
|
282
|
-
|
|
236
|
+
await checkOrAddFolder();
|
|
237
|
+
}
|
|
238
|
+
catch (err) {
|
|
283
239
|
if (debug) {
|
|
284
240
|
await logger.log(`Could not create sub-folder ${folderServerRelativeUrl}`);
|
|
285
241
|
}
|
|
286
|
-
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
242
|
+
throw err;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
;
|
|
247
|
+
return checkOrAddFolder();
|
|
291
248
|
},
|
|
292
249
|
/**
|
|
293
250
|
* Requests web object identity for the current web.
|
|
@@ -299,7 +256,7 @@ export const spo = {
|
|
|
299
256
|
* @param webUrl web url
|
|
300
257
|
* @param formDigestValue formDigestValue
|
|
301
258
|
*/
|
|
302
|
-
getCurrentWebIdentity(webUrl, formDigestValue) {
|
|
259
|
+
async getCurrentWebIdentity(webUrl, formDigestValue) {
|
|
303
260
|
const requestOptions = {
|
|
304
261
|
url: `${webUrl}/_vti_bin/client.svc/ProcessQuery`,
|
|
305
262
|
headers: {
|
|
@@ -307,23 +264,20 @@ export const spo = {
|
|
|
307
264
|
},
|
|
308
265
|
data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><Query Id="1" ObjectPathId="5"><Query SelectAllProperties="false"><Properties><Property Name="ServerRelativeUrl" ScalarProperty="true" /></Properties></Query></Query></Actions><ObjectPaths><Property Id="5" ParentId="3" Name="Web" /><StaticProperty Id="3" TypeId="{3747adcd-a3c3-41b9-bfab-4a64dd2f1e0a}" Name="Current" /></ObjectPaths></Request>`
|
|
309
266
|
};
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
reject('Cannot proceed. _ObjectIdentity_ not found'); // this is not supposed to happen
|
|
325
|
-
}, (err) => { reject(err); });
|
|
326
|
-
});
|
|
267
|
+
const res = await request.post(requestOptions);
|
|
268
|
+
const json = JSON.parse(res);
|
|
269
|
+
const contents = json.find(x => { return x.ErrorInfo; });
|
|
270
|
+
if (contents && contents.ErrorInfo) {
|
|
271
|
+
throw contents.ErrorInfo.ErrorMessage || 'ClientSvc unknown error';
|
|
272
|
+
}
|
|
273
|
+
const identityObject = json.find(x => { return x._ObjectIdentity_; });
|
|
274
|
+
if (identityObject) {
|
|
275
|
+
return {
|
|
276
|
+
objectIdentity: identityObject._ObjectIdentity_,
|
|
277
|
+
serverRelativeUrl: identityObject.ServerRelativeUrl
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
throw 'Cannot proceed. _ObjectIdentity_ not found';
|
|
327
281
|
},
|
|
328
282
|
/**
|
|
329
283
|
* Gets EffectiveBasePermissions for web return type is "_ObjectType_\":\"SP.Web\".
|
|
@@ -332,7 +286,7 @@ export const spo = {
|
|
|
332
286
|
* @param siteAccessToken site access token
|
|
333
287
|
* @param formDigestValue formDigestValue
|
|
334
288
|
*/
|
|
335
|
-
getEffectiveBasePermissions(webObjectIdentity, webUrl, formDigestValue, logger, debug) {
|
|
289
|
+
async getEffectiveBasePermissions(webObjectIdentity, webUrl, formDigestValue, logger, debug) {
|
|
336
290
|
const basePermissionsResult = new BasePermissions();
|
|
337
291
|
const requestOptions = {
|
|
338
292
|
url: `${webUrl}/_vti_bin/client.svc/ProcessQuery`,
|
|
@@ -341,25 +295,22 @@ export const spo = {
|
|
|
341
295
|
},
|
|
342
296
|
data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><Query Id="11" ObjectPathId="5"><Query SelectAllProperties="false"><Properties><Property Name="EffectiveBasePermissions" ScalarProperty="true" /></Properties></Query></Query></Actions><ObjectPaths><Identity Id="5" Name="${webObjectIdentity}" /></ObjectPaths></Request>`
|
|
343
297
|
};
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
reject('Cannot proceed. EffectiveBasePermissions not found'); // this is not supposed to happen
|
|
361
|
-
}, (err) => { reject(err); });
|
|
362
|
-
});
|
|
298
|
+
const res = await request.post(requestOptions);
|
|
299
|
+
if (debug) {
|
|
300
|
+
await logger.log('Attempt to get the web EffectiveBasePermissions');
|
|
301
|
+
}
|
|
302
|
+
const json = JSON.parse(res);
|
|
303
|
+
const contents = json.find(x => { return x.ErrorInfo; });
|
|
304
|
+
if (contents && contents.ErrorInfo) {
|
|
305
|
+
throw contents.ErrorInfo.ErrorMessage || 'ClientSvc unknown error';
|
|
306
|
+
}
|
|
307
|
+
const permissionsObj = json.find(x => { return x.EffectiveBasePermissions; });
|
|
308
|
+
if (permissionsObj) {
|
|
309
|
+
basePermissionsResult.high = permissionsObj.EffectiveBasePermissions.High;
|
|
310
|
+
basePermissionsResult.low = permissionsObj.EffectiveBasePermissions.Low;
|
|
311
|
+
return basePermissionsResult;
|
|
312
|
+
}
|
|
313
|
+
throw ('Cannot proceed. EffectiveBasePermissions not found'); // this is not supposed to happen
|
|
363
314
|
},
|
|
364
315
|
/**
|
|
365
316
|
* Gets folder by server relative url (GetFolderByServerRelativeUrl in REST)
|
|
@@ -371,7 +322,7 @@ export const spo = {
|
|
|
371
322
|
* @param siteRelativeUrl site relative url e.g. /Shared Documents/Folder1
|
|
372
323
|
* @param formDigestValue formDigestValue
|
|
373
324
|
*/
|
|
374
|
-
getFolderIdentity(webObjectIdentity, webUrl, siteRelativeUrl, formDigestValue) {
|
|
325
|
+
async getFolderIdentity(webObjectIdentity, webUrl, siteRelativeUrl, formDigestValue) {
|
|
375
326
|
const serverRelativePath = urlUtil.getServerRelativePath(webUrl, siteRelativeUrl);
|
|
376
327
|
const requestOptions = {
|
|
377
328
|
url: `${webUrl}/_vti_bin/client.svc/ProcessQuery`,
|
|
@@ -380,23 +331,20 @@ export const spo = {
|
|
|
380
331
|
},
|
|
381
332
|
data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="10" ObjectPathId="9" /><ObjectIdentityQuery Id="11" ObjectPathId="9" /><Query Id="12" ObjectPathId="9"><Query SelectAllProperties="false"><Properties><Property Name="Properties" SelectAll="true"><Query SelectAllProperties="false"><Properties /></Query></Property></Properties></Query></Query></Actions><ObjectPaths><Method Id="9" ParentId="5" Name="GetFolderByServerRelativeUrl"><Parameters><Parameter Type="String">${serverRelativePath}</Parameter></Parameters></Method><Identity Id="5" Name="${webObjectIdentity}" /></ObjectPaths></Request>`
|
|
382
333
|
};
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
reject('Cannot proceed. Folder _ObjectIdentity_ not found'); // this is not suppose to happen
|
|
398
|
-
}, (err) => { reject(err); });
|
|
399
|
-
});
|
|
334
|
+
const res = await request.post(requestOptions);
|
|
335
|
+
const json = JSON.parse(res);
|
|
336
|
+
const contents = json.find(x => { return x.ErrorInfo; });
|
|
337
|
+
if (contents && contents.ErrorInfo) {
|
|
338
|
+
throw contents.ErrorInfo.ErrorMessage || 'ClientSvc unknown error';
|
|
339
|
+
}
|
|
340
|
+
const objectIdentity = json.find(x => { return x._ObjectIdentity_; });
|
|
341
|
+
if (objectIdentity) {
|
|
342
|
+
return {
|
|
343
|
+
objectIdentity: objectIdentity._ObjectIdentity_,
|
|
344
|
+
serverRelativeUrl: serverRelativePath
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
throw 'Cannot proceed. Folder _ObjectIdentity_ not found';
|
|
400
348
|
},
|
|
401
349
|
/**
|
|
402
350
|
* Retrieves the SiteId, VroomItemId and VroomDriveId from a specific file.
|
|
@@ -702,19 +650,14 @@ export const spo = {
|
|
|
702
650
|
if (!wait || isComplete) {
|
|
703
651
|
return;
|
|
704
652
|
}
|
|
705
|
-
await
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
currentContext: context,
|
|
714
|
-
verbose: verbose,
|
|
715
|
-
debug: verbose
|
|
716
|
-
});
|
|
717
|
-
}, operation.PollingInterval);
|
|
653
|
+
await setTimeout(operation.PollingInterval);
|
|
654
|
+
await spo.waitUntilFinished({
|
|
655
|
+
operationId: JSON.stringify(operation._ObjectIdentity_),
|
|
656
|
+
siteUrl: spoAdminUrl,
|
|
657
|
+
logger,
|
|
658
|
+
currentContext: context,
|
|
659
|
+
verbose: verbose,
|
|
660
|
+
debug: verbose
|
|
718
661
|
});
|
|
719
662
|
}
|
|
720
663
|
}
|
|
@@ -921,19 +864,14 @@ export const spo = {
|
|
|
921
864
|
if (!wait || isComplete) {
|
|
922
865
|
return;
|
|
923
866
|
}
|
|
924
|
-
await
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
currentContext: context,
|
|
933
|
-
verbose: verbose,
|
|
934
|
-
debug: verbose
|
|
935
|
-
});
|
|
936
|
-
}, operation.PollingInterval);
|
|
867
|
+
await setTimeout(operation.PollingInterval);
|
|
868
|
+
await spo.waitUntilFinished({
|
|
869
|
+
operationId: JSON.stringify(operation._ObjectIdentity_),
|
|
870
|
+
siteUrl: spoAdminUrl,
|
|
871
|
+
logger,
|
|
872
|
+
currentContext: context,
|
|
873
|
+
verbose: verbose,
|
|
874
|
+
debug: verbose
|
|
937
875
|
});
|
|
938
876
|
},
|
|
939
877
|
/**
|
|
@@ -1072,19 +1010,14 @@ export const spo = {
|
|
|
1072
1010
|
const operation = json[json.length - 1];
|
|
1073
1011
|
const isComplete = operation.IsComplete;
|
|
1074
1012
|
if (!isComplete) {
|
|
1075
|
-
await
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
currentContext: context,
|
|
1084
|
-
verbose: verbose,
|
|
1085
|
-
debug: verbose
|
|
1086
|
-
});
|
|
1087
|
-
}, operation.PollingInterval);
|
|
1013
|
+
await setTimeout(operation.PollingInterval);
|
|
1014
|
+
await spo.waitUntilFinished({
|
|
1015
|
+
operationId: JSON.stringify(operation._ObjectIdentity_),
|
|
1016
|
+
siteUrl: spoAdminUrl,
|
|
1017
|
+
logger,
|
|
1018
|
+
currentContext: context,
|
|
1019
|
+
verbose: verbose,
|
|
1020
|
+
debug: verbose
|
|
1088
1021
|
});
|
|
1089
1022
|
}
|
|
1090
1023
|
}
|
|
@@ -1113,21 +1046,19 @@ export const spo = {
|
|
|
1113
1046
|
},
|
|
1114
1047
|
responseType: 'json'
|
|
1115
1048
|
};
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
}));
|
|
1130
|
-
});
|
|
1049
|
+
const res = await request.get(requestOptions);
|
|
1050
|
+
if (res.value.length === 0) {
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
await Promise.all(res.value.map(user => {
|
|
1054
|
+
const requestOptions = {
|
|
1055
|
+
url: `${spoAdminUrl}/_api/SP.Directory.DirectorySession/Group('${groupId}')/Owners/Add(objectId='${user.id}', principalName='')`,
|
|
1056
|
+
headers: {
|
|
1057
|
+
'content-type': 'application/json;odata=verbose'
|
|
1058
|
+
}
|
|
1059
|
+
};
|
|
1060
|
+
return request.post(requestOptions);
|
|
1061
|
+
}));
|
|
1131
1062
|
},
|
|
1132
1063
|
/**
|
|
1133
1064
|
* Updates the site admin
|
|
@@ -1216,7 +1147,7 @@ export const spo = {
|
|
|
1216
1147
|
*/
|
|
1217
1148
|
async applyRetentionLabelToListItems(webUrl, name, listAbsoluteUrl, itemIds, logger, verbose) {
|
|
1218
1149
|
if (verbose && logger) {
|
|
1219
|
-
logger.logToStderr(`Applying retention label '${name}' to item(s) in list '${listAbsoluteUrl}'...`);
|
|
1150
|
+
await logger.logToStderr(`Applying retention label '${name}' to item(s) in list '${listAbsoluteUrl}'...`);
|
|
1220
1151
|
}
|
|
1221
1152
|
const requestOptions = {
|
|
1222
1153
|
url: `${webUrl}/_api/SP_CompliancePolicy_SPPolicyStoreProxy_SetComplianceTagOnBulkItems`,
|
|
@@ -1349,7 +1280,7 @@ export const spo = {
|
|
|
1349
1280
|
*/
|
|
1350
1281
|
async removeRetentionLabelFromListItems(webUrl, listAbsoluteUrl, itemIds, logger, verbose) {
|
|
1351
1282
|
if (verbose && logger) {
|
|
1352
|
-
logger.logToStderr(`Removing retention label from item(s) in list '${listAbsoluteUrl}'...`);
|
|
1283
|
+
await logger.logToStderr(`Removing retention label from item(s) in list '${listAbsoluteUrl}'...`);
|
|
1353
1284
|
}
|
|
1354
1285
|
const requestOptions = {
|
|
1355
1286
|
url: `${webUrl}/_api/SP_CompliancePolicy_SPPolicyStoreProxy_SetComplianceTagOnBulkItems`,
|
|
@@ -1376,7 +1307,7 @@ export const spo = {
|
|
|
1376
1307
|
*/
|
|
1377
1308
|
async applyDefaultRetentionLabelToList(webUrl, name, listAbsoluteUrl, syncToItems, logger, verbose) {
|
|
1378
1309
|
if (verbose && logger) {
|
|
1379
|
-
logger.logToStderr(`Applying default retention label '${name}' to the list '${listAbsoluteUrl}'...`);
|
|
1310
|
+
await logger.logToStderr(`Applying default retention label '${name}' to the list '${listAbsoluteUrl}'...`);
|
|
1380
1311
|
}
|
|
1381
1312
|
const requestOptions = {
|
|
1382
1313
|
url: `${webUrl}/_api/SP_CompliancePolicy_SPPolicyStoreProxy_SetListComplianceTag`,
|
|
@@ -1403,7 +1334,7 @@ export const spo = {
|
|
|
1403
1334
|
*/
|
|
1404
1335
|
async removeDefaultRetentionLabelFromList(webUrl, listAbsoluteUrl, logger, verbose) {
|
|
1405
1336
|
if (verbose && logger) {
|
|
1406
|
-
logger.logToStderr(`Removing the default retention label from the list '${listAbsoluteUrl}'...`);
|
|
1337
|
+
await logger.logToStderr(`Removing the default retention label from the list '${listAbsoluteUrl}'...`);
|
|
1407
1338
|
}
|
|
1408
1339
|
const requestOptions = {
|
|
1409
1340
|
url: `${webUrl}/_api/SP_CompliancePolicy_SPPolicyStoreProxy_SetListComplianceTag`,
|