@pnp/cli-microsoft365 7.10.0-beta.ebb7426 → 7.11.0-beta.10b9b79
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/.eslintrc.cjs +5 -2
- package/allCommands.json +1 -1
- package/allCommandsFull.json +1 -1
- package/dist/Auth.js +1 -1
- package/dist/AuthServer.js +10 -10
- package/dist/Command.js +10 -10
- package/dist/chili/index.js +1 -1
- package/dist/cli/cli.js +11 -11
- package/dist/index.js +1 -1
- package/dist/m365/base/AnonymousCommand.js +1 -1
- package/dist/m365/base/DelegatedGraphCommand.js +2 -2
- package/dist/m365/base/PowerAppsCommand.js +2 -2
- package/dist/m365/base/PowerAutomateCommand.js +2 -2
- package/dist/m365/base/PowerBICommand.js +2 -2
- package/dist/m365/base/PowerPlatformCommand.js +2 -2
- package/dist/m365/base/VivaEngageCommand.js +2 -2
- package/dist/m365/cli/commands/cli-consent.js +1 -1
- package/dist/m365/commands/login.js +1 -1
- package/dist/m365/commands/logout.js +1 -1
- package/dist/m365/commands/status.js +1 -1
- package/dist/m365/connection/commands/connection-list.js +1 -1
- package/dist/m365/connection/commands/connection-remove.js +1 -1
- package/dist/m365/connection/commands/connection-set.js +1 -1
- package/dist/m365/connection/commands/connection-use.js +1 -1
- package/dist/m365/entra/commands/app/app-permission-add.js +21 -1
- package/dist/m365/entra/commands/app/app-permission-remove.js +17 -0
- package/dist/m365/entra/commands/m365group/m365group-add.js +1 -0
- package/dist/m365/entra/commands/m365group/m365group-user-list.js +1 -1
- package/dist/m365/external/commands/connection/connection-doctor.js +1 -1
- package/dist/m365/external/commands/connection/connection-schema-add.js +4 -4
- package/dist/m365/file/commands/file-copy.js +3 -3
- package/dist/m365/pa/commands/app/app-export.js +1 -1
- package/dist/m365/pa/commands/app/app-owner-set.js +1 -1
- package/dist/m365/pp/commands/solution/solution-publish.js +1 -1
- package/dist/m365/purview/commands/threatassessment/threatassessment-list.js +1 -1
- package/dist/m365/spfx/commands/project/project-azuredevops-pipeline-add.js +1 -1
- package/dist/m365/spfx/commands/project/project-externalize.js +1 -1
- package/dist/m365/spfx/commands/project/project-github-workflow-add.js +1 -1
- package/dist/m365/spfx/commands/spfx-doctor.js +4 -4
- package/dist/m365/spo/commands/commandset/commandset-get.js +1 -1
- package/dist/m365/spo/commands/file/file-retentionlabel-remove.js +1 -1
- package/dist/m365/spo/commands/group/group-member-add.js +2 -2
- package/dist/m365/spo/commands/group/group-member-remove.js +2 -2
- package/dist/m365/spo/commands/list/list-retentionlabel-ensure.js +1 -1
- package/dist/m365/spo/commands/listitem/listitem-batch-remove.js +1 -1
- package/dist/m365/spo/commands/listitem/listitem-retentionlabel-ensure.js +2 -2
- package/dist/m365/spo/commands/listitem/listitem-retentionlabel-remove.js +2 -2
- package/dist/m365/spo/commands/site/site-admin-list.js +144 -0
- package/dist/m365/spo/commands/site/site-commsite-enable.js +1 -1
- package/dist/m365/spo/commands/spo-search.js +1 -1
- package/dist/m365/spo/commands/tenant/tenant-applicationcustomizer-set.js +4 -4
- package/dist/m365/spo/commands/tenant/tenant-commandset-set.js +2 -2
- package/dist/m365/spo/commands/user/user-ensure.js +1 -1
- package/dist/m365/spo/commands.js +1 -0
- package/dist/m365/teams/commands/chat/chat-member-add.js +1 -1
- package/dist/m365/teams/commands/meeting/meeting-list.js +1 -1
- package/dist/m365/viva/commands/engage/engage-community-get.js +1 -1
- package/dist/request.js +13 -14
- package/dist/utils/spo.js +5 -5
- package/dist/utils/validation.js +6 -0
- package/docs/docs/cmd/entra/app/app-permission-remove.mdx +4 -4
- package/docs/docs/cmd/spo/site/site-admin-list.mdx +115 -0
- package/npm-shrinkwrap.json +802 -601
- package/package.json +12 -12
|
@@ -60,7 +60,7 @@ class SpoCommandSetGetCommand extends SpoCommand {
|
|
|
60
60
|
else {
|
|
61
61
|
const resultAsKeyValuePair = formatting.convertArrayToHashTable('Id', commandSets);
|
|
62
62
|
const commandSet = await cli.handleMultipleResultsFound(`Multiple command sets with title '${args.options.title}' found.`, resultAsKeyValuePair);
|
|
63
|
-
logger.log(commandSet);
|
|
63
|
+
await logger.log(commandSet);
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -54,7 +54,7 @@ class SpoFileRetentionLabelRemoveCommand extends SpoCommand {
|
|
|
54
54
|
}
|
|
55
55
|
async getFileProperties(logger, args) {
|
|
56
56
|
if (this.verbose) {
|
|
57
|
-
logger.logToStderr(`Retrieving list and item information for file '${args.options.fileId || args.options.fileUrl}' in site at ${args.options.webUrl}...`);
|
|
57
|
+
await logger.logToStderr(`Retrieving list and item information for file '${args.options.fileId || args.options.fileUrl}' in site at ${args.options.webUrl}...`);
|
|
58
58
|
}
|
|
59
59
|
let requestUrl = `${args.options.webUrl}/_api/web/`;
|
|
60
60
|
if (args.options.fileId) {
|
|
@@ -34,11 +34,11 @@ class SpoGroupMemberAddCommand extends SpoCommand {
|
|
|
34
34
|
try {
|
|
35
35
|
if (args.options.aadGroupIds) {
|
|
36
36
|
args.options.entraGroupIds = args.options.aadGroupIds;
|
|
37
|
-
this.warn(logger, `Option 'aadGroupIds' is deprecated. Please use 'entraGroupIds' instead`);
|
|
37
|
+
await this.warn(logger, `Option 'aadGroupIds' is deprecated. Please use 'entraGroupIds' instead`);
|
|
38
38
|
}
|
|
39
39
|
if (args.options.aadGroupNames) {
|
|
40
40
|
args.options.entraGroupNames = args.options.aadGroupNames;
|
|
41
|
-
this.warn(logger, `Option 'aadGroupNames' is deprecated. Please use 'entraGroupNames' instead`);
|
|
41
|
+
await this.warn(logger, `Option 'aadGroupNames' is deprecated. Please use 'entraGroupNames' instead`);
|
|
42
42
|
}
|
|
43
43
|
const groupId = await this.getGroupId(args, logger);
|
|
44
44
|
const resolvedUsernameList = await this.getValidUsers(args, logger);
|
|
@@ -47,11 +47,11 @@ class SpoGroupMemberRemoveCommand extends SpoCommand {
|
|
|
47
47
|
async commandAction(logger, args) {
|
|
48
48
|
if (args.options.aadGroupId) {
|
|
49
49
|
args.options.entraGroupId = args.options.aadGroupId;
|
|
50
|
-
this.warn(logger, `Option 'aadGroupId' is deprecated. Please use 'entraGroupId' instead`);
|
|
50
|
+
await this.warn(logger, `Option 'aadGroupId' is deprecated. Please use 'entraGroupId' instead`);
|
|
51
51
|
}
|
|
52
52
|
if (args.options.aadGroupName) {
|
|
53
53
|
args.options.entraGroupName = args.options.aadGroupName;
|
|
54
|
-
this.warn(logger, `Option 'aadGroupName' is deprecated. Please use 'entraGroupName' instead`);
|
|
54
|
+
await this.warn(logger, `Option 'aadGroupName' is deprecated. Please use 'entraGroupName' instead`);
|
|
55
55
|
}
|
|
56
56
|
if (args.options.force) {
|
|
57
57
|
if (this.debug) {
|
|
@@ -38,7 +38,7 @@ class SpoListRetentionLabelEnsureCommand extends SpoCommand {
|
|
|
38
38
|
}
|
|
39
39
|
async getListServerRelativeUrl(args, logger) {
|
|
40
40
|
if (this.verbose) {
|
|
41
|
-
logger.logToStderr('Getting the list server relative URL');
|
|
41
|
+
await logger.logToStderr('Getting the list server relative URL');
|
|
42
42
|
}
|
|
43
43
|
if (args.options.listUrl) {
|
|
44
44
|
return urlUtil.getServerRelativePath(args.options.webUrl, args.options.listUrl);
|
|
@@ -34,7 +34,7 @@ class SpoListItemBatchRemoveCommand extends SpoCommand {
|
|
|
34
34
|
const removeListItems = async () => {
|
|
35
35
|
try {
|
|
36
36
|
if (this.verbose) {
|
|
37
|
-
logger.logToStderr('Removing the listitems from SharePoint...');
|
|
37
|
+
await logger.logToStderr('Removing the listitems from SharePoint...');
|
|
38
38
|
}
|
|
39
39
|
let idsToRemove = [];
|
|
40
40
|
if (args.options.filePath) {
|
|
@@ -46,7 +46,7 @@ class SpoListItemRetentionLabelEnsureCommand extends SpoCommand {
|
|
|
46
46
|
return options.name;
|
|
47
47
|
}
|
|
48
48
|
if (this.verbose) {
|
|
49
|
-
logger.logToStderr(`Retrieving the name of the retention label based on the Id '${options.id}'...`);
|
|
49
|
+
await logger.logToStderr(`Retrieving the name of the retention label based on the Id '${options.id}'...`);
|
|
50
50
|
}
|
|
51
51
|
const requestUrl = `${options.webUrl}/_api/SP.CompliancePolicy.SPPolicyStoreProxy.GetAvailableTagsForSite(siteUrl=@a1)?@a1='${formatting.encodeQueryParameter(options.webUrl)}'`;
|
|
52
52
|
const labels = await odata.getAllItems(requestUrl);
|
|
@@ -87,7 +87,7 @@ class SpoListItemRetentionLabelEnsureCommand extends SpoCommand {
|
|
|
87
87
|
const serverRelativePath = urlUtil.getServerRelativePath(options.webUrl, response.RootFolder.ServerRelativeUrl);
|
|
88
88
|
const listAbsoluteUrl = urlUtil.urlCombine(tenantUrl, serverRelativePath);
|
|
89
89
|
if (this.verbose) {
|
|
90
|
-
logger.logToStderr(`List absolute URL found: '${listAbsoluteUrl}'`);
|
|
90
|
+
await logger.logToStderr(`List absolute URL found: '${listAbsoluteUrl}'`);
|
|
91
91
|
}
|
|
92
92
|
return listAbsoluteUrl;
|
|
93
93
|
}
|
|
@@ -56,7 +56,7 @@ class SpoListItemRetentionLabelRemoveCommand extends SpoCommand {
|
|
|
56
56
|
return urlUtil.urlCombine(tenantUrl, serverRelativePath);
|
|
57
57
|
}
|
|
58
58
|
if (this.verbose) {
|
|
59
|
-
logger.logToStderr(`Retrieving list absolute URL...`);
|
|
59
|
+
await logger.logToStderr(`Retrieving list absolute URL...`);
|
|
60
60
|
}
|
|
61
61
|
let requestUrl = `${options.webUrl}/_api/web`;
|
|
62
62
|
if (options.listId) {
|
|
@@ -76,7 +76,7 @@ class SpoListItemRetentionLabelRemoveCommand extends SpoCommand {
|
|
|
76
76
|
const serverRelativePath = urlUtil.getServerRelativePath(options.webUrl, response.RootFolder.ServerRelativeUrl);
|
|
77
77
|
const listAbsoluteUrl = urlUtil.urlCombine(tenantUrl, serverRelativePath);
|
|
78
78
|
if (this.verbose) {
|
|
79
|
-
logger.logToStderr(`List absolute URL found: '${listAbsoluteUrl}'`);
|
|
79
|
+
await logger.logToStderr(`List absolute URL found: '${listAbsoluteUrl}'`);
|
|
80
80
|
}
|
|
81
81
|
return listAbsoluteUrl;
|
|
82
82
|
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var _SpoSiteAdminListCommand_instances, _SpoSiteAdminListCommand_initTelemetry, _SpoSiteAdminListCommand_initOptions, _SpoSiteAdminListCommand_initValidators, _SpoSiteAdminListCommand_initTypes;
|
|
7
|
+
import request from '../../../../request.js';
|
|
8
|
+
import { spo } from '../../../../utils/spo.js';
|
|
9
|
+
import { validation } from '../../../../utils/validation.js';
|
|
10
|
+
import SpoCommand from '../../../base/SpoCommand.js';
|
|
11
|
+
import commands from '../../commands.js';
|
|
12
|
+
import { ListPrincipalType } from '../list/ListPrincipalType.js';
|
|
13
|
+
class SpoSiteAdminListCommand extends SpoCommand {
|
|
14
|
+
get name() {
|
|
15
|
+
return commands.SITE_ADMIN_LIST;
|
|
16
|
+
}
|
|
17
|
+
get description() {
|
|
18
|
+
return 'Lists all administrators of a specific SharePoint site';
|
|
19
|
+
}
|
|
20
|
+
constructor() {
|
|
21
|
+
super();
|
|
22
|
+
_SpoSiteAdminListCommand_instances.add(this);
|
|
23
|
+
__classPrivateFieldGet(this, _SpoSiteAdminListCommand_instances, "m", _SpoSiteAdminListCommand_initTelemetry).call(this);
|
|
24
|
+
__classPrivateFieldGet(this, _SpoSiteAdminListCommand_instances, "m", _SpoSiteAdminListCommand_initOptions).call(this);
|
|
25
|
+
__classPrivateFieldGet(this, _SpoSiteAdminListCommand_instances, "m", _SpoSiteAdminListCommand_initValidators).call(this);
|
|
26
|
+
__classPrivateFieldGet(this, _SpoSiteAdminListCommand_instances, "m", _SpoSiteAdminListCommand_initTypes).call(this);
|
|
27
|
+
}
|
|
28
|
+
async commandAction(logger, args) {
|
|
29
|
+
try {
|
|
30
|
+
if (args.options.asAdmin) {
|
|
31
|
+
await this.callActionAsAdmin(logger, args);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
await this.callAction(logger, args);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
this.handleRejectedODataJsonPromise(err);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async callActionAsAdmin(logger, args) {
|
|
41
|
+
if (this.verbose) {
|
|
42
|
+
await logger.logToStderr('Retrieving site administrators as an administrator...');
|
|
43
|
+
}
|
|
44
|
+
const adminUrl = await spo.getSpoAdminUrl(logger, this.debug);
|
|
45
|
+
const siteId = await this.getSiteId(args.options.siteUrl, logger);
|
|
46
|
+
const requestOptions = {
|
|
47
|
+
url: `${adminUrl}/_api/SPO.Tenant/GetSiteAdministrators?siteId='${siteId}'`,
|
|
48
|
+
headers: {
|
|
49
|
+
accept: 'application/json;odata=nometadata',
|
|
50
|
+
'content-type': 'application/json;charset=utf-8'
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const response = await request.post(requestOptions);
|
|
54
|
+
const responseContent = JSON.parse(response);
|
|
55
|
+
const primaryAdminLoginName = await this.getPrimaryAdminLoginNameFromAdmin(adminUrl, siteId);
|
|
56
|
+
const mappedResult = responseContent.value.map((u) => ({
|
|
57
|
+
Id: null,
|
|
58
|
+
Email: u.email,
|
|
59
|
+
LoginName: u.loginName,
|
|
60
|
+
Title: u.name,
|
|
61
|
+
PrincipalType: null,
|
|
62
|
+
PrincipalTypeString: null,
|
|
63
|
+
IsPrimaryAdmin: u.loginName === primaryAdminLoginName
|
|
64
|
+
}));
|
|
65
|
+
await logger.log(mappedResult);
|
|
66
|
+
}
|
|
67
|
+
async getSiteId(siteUrl, logger) {
|
|
68
|
+
const siteGraphId = await spo.getSiteId(siteUrl, logger, this.verbose);
|
|
69
|
+
const match = siteGraphId.match(/,([a-f0-9\-]{36}),/i);
|
|
70
|
+
if (!match) {
|
|
71
|
+
throw `Site with URL ${siteUrl} not found`;
|
|
72
|
+
}
|
|
73
|
+
return match[1];
|
|
74
|
+
}
|
|
75
|
+
async getPrimaryAdminLoginNameFromAdmin(adminUrl, siteId) {
|
|
76
|
+
const requestOptions = {
|
|
77
|
+
url: `${adminUrl}/_api/SPO.Tenant/sites('${siteId}')?$select=OwnerLoginName`,
|
|
78
|
+
headers: {
|
|
79
|
+
accept: 'application/json;odata=nometadata',
|
|
80
|
+
'content-type': 'application/json;charset=utf-8'
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const response = await request.get(requestOptions);
|
|
84
|
+
const responseContent = JSON.parse(response);
|
|
85
|
+
return responseContent.OwnerLoginName;
|
|
86
|
+
}
|
|
87
|
+
async callAction(logger, args) {
|
|
88
|
+
if (this.verbose) {
|
|
89
|
+
await logger.logToStderr('Retrieving site administrators...');
|
|
90
|
+
}
|
|
91
|
+
const requestOptions = {
|
|
92
|
+
url: `${args.options.siteUrl}/_api/web/siteusers?$filter=IsSiteAdmin eq true`,
|
|
93
|
+
method: 'GET',
|
|
94
|
+
headers: {
|
|
95
|
+
'accept': 'application/json;odata=nometadata'
|
|
96
|
+
},
|
|
97
|
+
responseType: 'json'
|
|
98
|
+
};
|
|
99
|
+
const responseContent = await request.get(requestOptions);
|
|
100
|
+
const primaryOwnerLogin = await this.getPrimaryOwnerLoginFromSite(args.options.siteUrl);
|
|
101
|
+
const mappedResult = responseContent.value.map((u) => ({
|
|
102
|
+
Id: u.Id,
|
|
103
|
+
LoginName: u.LoginName,
|
|
104
|
+
Title: u.Title,
|
|
105
|
+
PrincipalType: u.PrincipalType,
|
|
106
|
+
PrincipalTypeString: ListPrincipalType[u.PrincipalType],
|
|
107
|
+
Email: u.Email,
|
|
108
|
+
IsPrimaryAdmin: u.LoginName === primaryOwnerLogin
|
|
109
|
+
}));
|
|
110
|
+
await logger.log(mappedResult);
|
|
111
|
+
}
|
|
112
|
+
async getPrimaryOwnerLoginFromSite(siteUrl) {
|
|
113
|
+
const requestOptions = {
|
|
114
|
+
url: `${siteUrl}/_api/site/owner`,
|
|
115
|
+
method: 'GET',
|
|
116
|
+
headers: {
|
|
117
|
+
'accept': 'application/json;odata=nometadata'
|
|
118
|
+
},
|
|
119
|
+
responseType: 'json'
|
|
120
|
+
};
|
|
121
|
+
const responseContent = await request.get(requestOptions);
|
|
122
|
+
return responseContent?.LoginName ?? null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
_SpoSiteAdminListCommand_instances = new WeakSet(), _SpoSiteAdminListCommand_initTelemetry = function _SpoSiteAdminListCommand_initTelemetry() {
|
|
126
|
+
this.telemetry.push((args) => {
|
|
127
|
+
Object.assign(this.telemetryProperties, {
|
|
128
|
+
siteUrl: typeof args.options.siteUrl !== 'undefined',
|
|
129
|
+
asAdmin: !!args.options.asAdmin
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
}, _SpoSiteAdminListCommand_initOptions = function _SpoSiteAdminListCommand_initOptions() {
|
|
133
|
+
this.options.unshift({
|
|
134
|
+
option: '-u, --siteUrl <siteUrl>'
|
|
135
|
+
}, {
|
|
136
|
+
option: '--asAdmin'
|
|
137
|
+
});
|
|
138
|
+
}, _SpoSiteAdminListCommand_initValidators = function _SpoSiteAdminListCommand_initValidators() {
|
|
139
|
+
this.validators.push(async (args) => validation.isValidSharePointUrl(args.options.siteUrl));
|
|
140
|
+
}, _SpoSiteAdminListCommand_initTypes = function _SpoSiteAdminListCommand_initTypes() {
|
|
141
|
+
this.types.string.push('siteUrl');
|
|
142
|
+
};
|
|
143
|
+
export default new SpoSiteAdminListCommand();
|
|
144
|
+
//# sourceMappingURL=site-admin-list.js.map
|
|
@@ -26,7 +26,7 @@ class SpoSiteCommSiteEnableCommand extends SpoCommand {
|
|
|
26
26
|
async commandAction(logger, args) {
|
|
27
27
|
const designPackageId = this.getDesignPackageId(args.options);
|
|
28
28
|
if (this.verbose) {
|
|
29
|
-
logger.logToStderr(`Enabling communication site with design package '${designPackageId}' at '${args.options.url}'...`);
|
|
29
|
+
await logger.logToStderr(`Enabling communication site with design package '${designPackageId}' at '${args.options.url}'...`);
|
|
30
30
|
}
|
|
31
31
|
try {
|
|
32
32
|
const requestOptions = {
|
|
@@ -39,7 +39,7 @@ class SpoSearchCommand extends SpoCommand {
|
|
|
39
39
|
await logger.logToStderr(`Executing search query '${args.options.queryText}' on site at ${webUrl}...`);
|
|
40
40
|
}
|
|
41
41
|
const results = await this.executeSearchQuery(logger, args, webUrl, []);
|
|
42
|
-
this.printResults(logger, args, results);
|
|
42
|
+
await this.printResults(logger, args, results);
|
|
43
43
|
}
|
|
44
44
|
catch (err) {
|
|
45
45
|
this.handleRejectedODataJsonPromise(err);
|
|
@@ -76,7 +76,7 @@ class SpoTenantApplicationCustomizerSetCommand extends SpoCommand {
|
|
|
76
76
|
}
|
|
77
77
|
async getComponentManifest(appCatalogUrl, clientSideComponentId, logger) {
|
|
78
78
|
if (this.verbose) {
|
|
79
|
-
logger.logToStderr('Retrieving component manifest item from the ComponentManifests list on the app catalog site so that we get the solution id');
|
|
79
|
+
await logger.logToStderr('Retrieving component manifest item from the ComponentManifests list on the app catalog site so that we get the solution id');
|
|
80
80
|
}
|
|
81
81
|
const camlQuery = `<View><ViewFields><FieldRef Name='ClientComponentId'></FieldRef><FieldRef Name='SolutionId'></FieldRef><FieldRef Name='ClientComponentManifest'></FieldRef></ViewFields><Query><Where><Eq><FieldRef Name='ClientComponentId' /><Value Type='Guid'>${clientSideComponentId}</Value></Eq></Where></Query></View>`;
|
|
82
82
|
const commandOptions = {
|
|
@@ -89,7 +89,7 @@ class SpoTenantApplicationCustomizerSetCommand extends SpoCommand {
|
|
|
89
89
|
};
|
|
90
90
|
const output = await cli.executeCommandWithOutput(spoListItemListCommand, { options: { ...commandOptions, _: [] } });
|
|
91
91
|
if (this.verbose) {
|
|
92
|
-
logger.logToStderr(output.stderr);
|
|
92
|
+
await logger.logToStderr(output.stderr);
|
|
93
93
|
}
|
|
94
94
|
const outputParsed = JSON.parse(output.stdout);
|
|
95
95
|
if (outputParsed.length === 0) {
|
|
@@ -99,7 +99,7 @@ class SpoTenantApplicationCustomizerSetCommand extends SpoCommand {
|
|
|
99
99
|
}
|
|
100
100
|
async getSolutionFromAppCatalog(appCatalogUrl, solutionId, logger) {
|
|
101
101
|
if (this.verbose) {
|
|
102
|
-
logger.logToStderr(`Retrieving solution with id ${solutionId} from the application catalog`);
|
|
102
|
+
await logger.logToStderr(`Retrieving solution with id ${solutionId} from the application catalog`);
|
|
103
103
|
}
|
|
104
104
|
const camlQuery = `<View><ViewFields><FieldRef Name='SkipFeatureDeployment'></FieldRef><FieldRef Name='ContainsTenantWideExtension'></FieldRef></ViewFields><Query><Where><Eq><FieldRef Name='AppProductID' /><Value Type='Guid'>${solutionId}</Value></Eq></Where></Query></View>`;
|
|
105
105
|
const commandOptions = {
|
|
@@ -112,7 +112,7 @@ class SpoTenantApplicationCustomizerSetCommand extends SpoCommand {
|
|
|
112
112
|
};
|
|
113
113
|
const output = await cli.executeCommandWithOutput(spoListItemListCommand, { options: { ...commandOptions, _: [] } });
|
|
114
114
|
if (this.verbose) {
|
|
115
|
-
logger.logToStderr(output.stderr);
|
|
115
|
+
await logger.logToStderr(output.stderr);
|
|
116
116
|
}
|
|
117
117
|
const outputParsed = JSON.parse(output.stdout);
|
|
118
118
|
if (outputParsed.length === 0) {
|
|
@@ -44,7 +44,7 @@ class SpoTenantCommandSetSetCommand extends SpoCommand {
|
|
|
44
44
|
}
|
|
45
45
|
async getListItemById(logger, webUrl, listServerRelativeUrl, id) {
|
|
46
46
|
if (this.verbose) {
|
|
47
|
-
logger.logToStderr(`Getting the list item by id ${id}`);
|
|
47
|
+
await logger.logToStderr(`Getting the list item by id ${id}`);
|
|
48
48
|
}
|
|
49
49
|
const reqOptions = {
|
|
50
50
|
url: `${webUrl}/_api/web/GetList('${formatting.encodeQueryParameter(listServerRelativeUrl)}')/Items(${id})`,
|
|
@@ -57,7 +57,7 @@ class SpoTenantCommandSetSetCommand extends SpoCommand {
|
|
|
57
57
|
}
|
|
58
58
|
async updateTenantWideExtension(appCatalogUrl, options, listServerRelativeUrl, logger) {
|
|
59
59
|
if (this.verbose) {
|
|
60
|
-
logger.logToStderr('Updating tenant wide extension to the TenantWideExtensions list');
|
|
60
|
+
await logger.logToStderr('Updating tenant wide extension to the TenantWideExtensions list');
|
|
61
61
|
}
|
|
62
62
|
const formValues = [];
|
|
63
63
|
if (options.newTitle !== undefined) {
|
|
@@ -27,7 +27,7 @@ class SpoUserEnsureCommand extends SpoCommand {
|
|
|
27
27
|
async commandAction(logger, args) {
|
|
28
28
|
if (args.options.aadId) {
|
|
29
29
|
args.options.entraId = args.options.aadId;
|
|
30
|
-
this.warn(logger, `Option 'aadId' is deprecated. Please use 'entraId' instead`);
|
|
30
|
+
await this.warn(logger, `Option 'aadId' is deprecated. Please use 'entraId' instead`);
|
|
31
31
|
}
|
|
32
32
|
if (this.verbose) {
|
|
33
33
|
await logger.logToStderr(`Ensuring user ${args.options.entraId || args.options.userName} at site ${args.options.webUrl}`);
|
|
@@ -239,6 +239,7 @@ export default {
|
|
|
239
239
|
SERVICEPRINCIPAL_SET: `${prefix} serviceprincipal set`,
|
|
240
240
|
SET: `${prefix} set`,
|
|
241
241
|
SITE_ADD: `${prefix} site add`,
|
|
242
|
+
SITE_ADMIN_LIST: `${prefix} site admin list`,
|
|
242
243
|
SITE_APPCATALOG_ADD: `${prefix} site appcatalog add`,
|
|
243
244
|
SITE_APPCATALOG_LIST: `${prefix} site appcatalog list`,
|
|
244
245
|
SITE_APPCATALOG_REMOVE: `${prefix} site appcatalog remove`,
|
|
@@ -27,7 +27,7 @@ class TeamsChatMemberAddCommand extends GraphCommand {
|
|
|
27
27
|
async commandAction(logger, args) {
|
|
28
28
|
try {
|
|
29
29
|
if (this.verbose) {
|
|
30
|
-
logger.logToStderr(`Adding member ${args.options.userId || args.options.userName} to chat with id ${args.options.chatId}...`);
|
|
30
|
+
await logger.logToStderr(`Adding member ${args.options.userId || args.options.userName} to chat with id ${args.options.chatId}...`);
|
|
31
31
|
}
|
|
32
32
|
const chatMemberAddOptions = {
|
|
33
33
|
url: `${this.resource}/v1.0/chats/${args.options.chatId}/members`,
|
|
@@ -90,7 +90,7 @@ class TeamsMeetingListCommand extends GraphCommand {
|
|
|
90
90
|
let result = [];
|
|
91
91
|
for (let i = 0; i < meetingUrls.length; i += 20) {
|
|
92
92
|
if (this.verbose) {
|
|
93
|
-
logger.logToStderr(`Retrieving meetings ${i + 1}-${Math.min(i + 20, meetingUrls.length)}...`);
|
|
93
|
+
await logger.logToStderr(`Retrieving meetings ${i + 1}-${Math.min(i + 20, meetingUrls.length)}...`);
|
|
94
94
|
}
|
|
95
95
|
const batch = meetingUrls.slice(i, i + 20);
|
|
96
96
|
const requestOptions = {
|
|
@@ -22,7 +22,7 @@ class VivaEngageCommunityGetCommand extends GraphCommand {
|
|
|
22
22
|
}
|
|
23
23
|
async commandAction(logger, args) {
|
|
24
24
|
if (this.verbose) {
|
|
25
|
-
logger.logToStderr(`Getting the information of Viva Engage community with id '${args.options.id}'...`);
|
|
25
|
+
await logger.logToStderr(`Getting the information of Viva Engage community with id '${args.options.id}'...`);
|
|
26
26
|
}
|
|
27
27
|
const requestOptions = {
|
|
28
28
|
url: `${this.resource}/beta/employeeExperience/communities/${args.options.id}`,
|
package/dist/request.js
CHANGED
|
@@ -14,39 +14,39 @@ class Request {
|
|
|
14
14
|
}
|
|
15
15
|
this._debug = debug;
|
|
16
16
|
if (this._debug) {
|
|
17
|
-
this.req.interceptors.request.use(config => {
|
|
17
|
+
this.req.interceptors.request.use(async (config) => {
|
|
18
18
|
if (this._logger) {
|
|
19
|
-
this._logger.logToStderr('Request:');
|
|
19
|
+
await this._logger.logToStderr('Request:');
|
|
20
20
|
const properties = ['url', 'method', 'headers', 'responseType', 'decompress'];
|
|
21
21
|
if (config.responseType !== 'stream') {
|
|
22
22
|
properties.push('data');
|
|
23
23
|
}
|
|
24
|
-
this._logger.logToStderr(JSON.stringify(formatting.filterObject(config, properties), null, 2));
|
|
24
|
+
await this._logger.logToStderr(JSON.stringify(formatting.filterObject(config, properties), null, 2));
|
|
25
25
|
}
|
|
26
26
|
return config;
|
|
27
27
|
});
|
|
28
28
|
// since we're stubbing requests, response interceptor is never called in
|
|
29
29
|
// tests, so let's exclude it from coverage
|
|
30
30
|
/* c8 ignore next 26 */
|
|
31
|
-
this.req.interceptors.response.use((response) => {
|
|
31
|
+
this.req.interceptors.response.use(async (response) => {
|
|
32
32
|
if (this._logger) {
|
|
33
|
-
this._logger.logToStderr('Response:');
|
|
33
|
+
await this._logger.logToStderr('Response:');
|
|
34
34
|
const properties = ['status', 'statusText', 'headers'];
|
|
35
35
|
if (response.headers['content-type'] &&
|
|
36
36
|
response.headers['content-type'].indexOf('json') > -1) {
|
|
37
37
|
properties.push('data');
|
|
38
38
|
}
|
|
39
|
-
this._logger.logToStderr(JSON.stringify({
|
|
39
|
+
await this._logger.logToStderr(JSON.stringify({
|
|
40
40
|
url: response.config.url,
|
|
41
41
|
...formatting.filterObject(response, properties)
|
|
42
42
|
}, null, 2));
|
|
43
43
|
}
|
|
44
44
|
return response;
|
|
45
|
-
}, (error) => {
|
|
45
|
+
}, async (error) => {
|
|
46
46
|
if (this._logger) {
|
|
47
47
|
const properties = ['status', 'statusText', 'headers'];
|
|
48
|
-
this._logger.logToStderr('Request error:');
|
|
49
|
-
this._logger.logToStderr(JSON.stringify({
|
|
48
|
+
await this._logger.logToStderr('Request error:');
|
|
49
|
+
await this._logger.logToStderr(JSON.stringify({
|
|
50
50
|
url: error.config?.url,
|
|
51
51
|
...formatting.filterObject(error.response, properties),
|
|
52
52
|
error: error.error
|
|
@@ -169,7 +169,7 @@ class Request {
|
|
|
169
169
|
timings.api.push(Number(end - start));
|
|
170
170
|
_resolve((options.responseType === 'stream' || options.fullResponse) ? res : res.data);
|
|
171
171
|
}
|
|
172
|
-
}, (error) => {
|
|
172
|
+
}, async (error) => {
|
|
173
173
|
if (error && error.response &&
|
|
174
174
|
(error.response.status === 429 ||
|
|
175
175
|
error.response.status === 503)) {
|
|
@@ -178,11 +178,10 @@ class Request {
|
|
|
178
178
|
retryAfter = 10;
|
|
179
179
|
}
|
|
180
180
|
if (this._debug) {
|
|
181
|
-
this._logger.log(`Request throttled. Waiting ${retryAfter}sec before retrying...`);
|
|
181
|
+
await this._logger.log(`Request throttled. Waiting ${retryAfter}sec before retrying...`);
|
|
182
182
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}, retryAfter * 1000);
|
|
183
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
184
|
+
setTimeout(async () => { this.execute(options, resolve || _resolve, reject || _reject); }, retryAfter * 1000);
|
|
186
185
|
}
|
|
187
186
|
else {
|
|
188
187
|
if (reject) {
|
package/dist/utils/spo.js
CHANGED
|
@@ -1173,7 +1173,7 @@ export const spo = {
|
|
|
1173
1173
|
*/
|
|
1174
1174
|
async getFileAsListItemByUrl(absoluteListUrl, url, logger, verbose) {
|
|
1175
1175
|
if (verbose && logger) {
|
|
1176
|
-
logger.logToStderr(`Getting the file properties with url ${url}`);
|
|
1176
|
+
await logger.logToStderr(`Getting the file properties with url ${url}`);
|
|
1177
1177
|
}
|
|
1178
1178
|
const serverRelativePath = urlUtil.getServerRelativePath(absoluteListUrl, url);
|
|
1179
1179
|
const requestUrl = `${absoluteListUrl}/_api/web/GetFileByServerRelativePath(DecodedUrl=@f)?$expand=ListItemAllFields&@f='${formatting.encodeQueryParameter(serverRelativePath)}'`;
|
|
@@ -1206,7 +1206,7 @@ export const spo = {
|
|
|
1206
1206
|
const serverRelativeSiteMatch = absoluteListUrl.match(new RegExp('/sites/[^/]+'));
|
|
1207
1207
|
const webUrl = `${parsedUrl.protocol}//${parsedUrl.host}${serverRelativeSiteMatch ?? ''}`;
|
|
1208
1208
|
if (verbose && logger) {
|
|
1209
|
-
logger.logToStderr(`Getting list id...`);
|
|
1209
|
+
await logger.logToStderr(`Getting list id...`);
|
|
1210
1210
|
}
|
|
1211
1211
|
const listRequestOptions = {
|
|
1212
1212
|
url: `${absoluteListUrl}?$select=Id`,
|
|
@@ -1218,7 +1218,7 @@ export const spo = {
|
|
|
1218
1218
|
const list = await request.get(listRequestOptions);
|
|
1219
1219
|
const listId = list.Id;
|
|
1220
1220
|
if (verbose && logger) {
|
|
1221
|
-
logger.logToStderr(`Getting request digest for systemUpdate request`);
|
|
1221
|
+
await logger.logToStderr(`Getting request digest for systemUpdate request`);
|
|
1222
1222
|
}
|
|
1223
1223
|
const res = await spo.getRequestDigest(webUrl);
|
|
1224
1224
|
const formDigestValue = res.FormDigestValue;
|
|
@@ -1361,7 +1361,7 @@ export const spo = {
|
|
|
1361
1361
|
*/
|
|
1362
1362
|
async getSiteId(webUrl, logger, verbose) {
|
|
1363
1363
|
if (verbose && logger) {
|
|
1364
|
-
logger.logToStderr(`Getting site id for URL: ${webUrl}...`);
|
|
1364
|
+
await logger.logToStderr(`Getting site id for URL: ${webUrl}...`);
|
|
1365
1365
|
}
|
|
1366
1366
|
const url = new URL(webUrl);
|
|
1367
1367
|
const requestOptions = {
|
|
@@ -1393,7 +1393,7 @@ export const spo = {
|
|
|
1393
1393
|
};
|
|
1394
1394
|
const response = await request.post(requestOptions);
|
|
1395
1395
|
if (verbose) {
|
|
1396
|
-
logger.logToStderr('Attempt to get _ObjectIdentity_ key values');
|
|
1396
|
+
await logger.logToStderr('Attempt to get _ObjectIdentity_ key values');
|
|
1397
1397
|
}
|
|
1398
1398
|
const json = JSON.parse(response);
|
|
1399
1399
|
const contents = json.find(x => { return x.ErrorInfo; });
|
package/dist/utils/validation.js
CHANGED
|
@@ -332,6 +332,12 @@ export const validation = {
|
|
|
332
332
|
isValidISODuration(duration) {
|
|
333
333
|
const durationRegEx = new RegExp(/^P(?!$)((\d+Y)|(\d+\.\d+Y$))?((\d+M)|(\d+\.\d+M$))?((\d+W)|(\d+\.\d+W$))?((\d+D)|(\d+\.\d+D$))?(T(?=\d)((\d+H)|(\d+\.\d+H$))?((\d+M)|(\d+\.\d+M$))?(\d+(\.\d+)?S)?)??$/);
|
|
334
334
|
return durationRegEx.test(duration);
|
|
335
|
+
},
|
|
336
|
+
isValidPermission(permissions) {
|
|
337
|
+
const invalidPermissions = permissions
|
|
338
|
+
.split(' ')
|
|
339
|
+
.filter(permission => permission.indexOf('/') < 0);
|
|
340
|
+
return invalidPermissions.length > 0 ? invalidPermissions : true;
|
|
335
341
|
}
|
|
336
342
|
};
|
|
337
343
|
//# sourceMappingURL=validation.js.map
|
|
@@ -14,19 +14,19 @@ m365 entra app permission remove [options]
|
|
|
14
14
|
|
|
15
15
|
```md definition-list
|
|
16
16
|
`-i, --appId [appId]`
|
|
17
|
-
: Client ID of the Microsoft Entra app to
|
|
17
|
+
: Client ID of the Microsoft Entra app to remove the API permissions from. Specify either `appId`, `appName` or `appObjectId`.
|
|
18
18
|
|
|
19
19
|
`--appObjectId [appObjectId]`
|
|
20
|
-
: Object ID of the Microsoft Entra app to
|
|
20
|
+
: Object ID of the Microsoft Entra app to remove the API permissions from. Specify either `appId`, `appName` or `appObjectId`.
|
|
21
21
|
|
|
22
22
|
`-n, --appName [appName]`
|
|
23
23
|
: Display name of the Entra app to remove the API permissions from. Specify either `appId`, `appName` or `appObjectId`.
|
|
24
24
|
|
|
25
25
|
`-a, --applicationPermissions [applicationPermissions]`
|
|
26
|
-
: Space-separated list of application permissions to
|
|
26
|
+
: Space-separated list of application permissions to remove. Specify at least `applicationPermissions` or `delegatedPermissions`.
|
|
27
27
|
|
|
28
28
|
`-d, --delegatedPermissions [delegatedPermissions]`
|
|
29
|
-
: Space-separated list of delegated permissions to
|
|
29
|
+
: Space-separated list of delegated permissions to remove. Specify at least `applicationPermissions` or `delegatedPermissions`.
|
|
30
30
|
|
|
31
31
|
`--revokeAdminConsent`
|
|
32
32
|
: When specified, revokes the admin consent for the specified permissions as well.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import Global from '/docs/cmd/_global.mdx';
|
|
2
|
+
import Tabs from '@theme/Tabs';
|
|
3
|
+
import TabItem from '@theme/TabItem';
|
|
4
|
+
|
|
5
|
+
# spo site admin list
|
|
6
|
+
|
|
7
|
+
Lists all administrators of a specific SharePoint site
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
m365 spo site admin list [options]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Options
|
|
16
|
+
|
|
17
|
+
```md definition-list
|
|
18
|
+
`-u, --siteUrl <siteUrl>`
|
|
19
|
+
: The URL of the SharePoint site
|
|
20
|
+
|
|
21
|
+
`--asAdmin`
|
|
22
|
+
: List admins as admin for sites you don't have permission to
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
<Global />
|
|
26
|
+
|
|
27
|
+
## Remarks
|
|
28
|
+
|
|
29
|
+
:::info
|
|
30
|
+
|
|
31
|
+
To use this command with the `--asAdmin` mode, you must have permission to access the tenant admin site.
|
|
32
|
+
|
|
33
|
+
Without this parameter, you must have site collection admin permissions for the requested site.
|
|
34
|
+
|
|
35
|
+
In `--asAdmin` mode, the Id, PrincipalType, and PrincipalTypeString properties are not exported.
|
|
36
|
+
|
|
37
|
+
:::
|
|
38
|
+
|
|
39
|
+
## Examples
|
|
40
|
+
|
|
41
|
+
Lists all admins of a SharePoint site
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
m365 spo site admin list --siteUrl https://contoso.sharepoint.com
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Lists all admins of a SharePoint site as admin
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
m365 spo site admin list --siteUrl https://contoso.sharepoint.com --asAdmin
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Response
|
|
54
|
+
|
|
55
|
+
<Tabs>
|
|
56
|
+
<TabItem value="JSON">
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
[
|
|
60
|
+
{
|
|
61
|
+
"Id": 6,
|
|
62
|
+
"LoginName": "i:0#.f|membership|user@contoso.com",
|
|
63
|
+
"Title": "User Example",
|
|
64
|
+
"PrincipalType": 1,
|
|
65
|
+
"PrincipalTypeString": "User",
|
|
66
|
+
"Email": "user@contoso.com",
|
|
67
|
+
"IsPrimaryAdmin": true
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
</TabItem>
|
|
73
|
+
<TabItem value="Text">
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
Email : user@contoso.com
|
|
77
|
+
Id : 6
|
|
78
|
+
LoginName : i:0#.f|membership|user@contoso.com
|
|
79
|
+
PrincipalType : 1
|
|
80
|
+
PrincipalTypeString : User
|
|
81
|
+
Title : User Example
|
|
82
|
+
IsPrimaryAdmin : true
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
</TabItem>
|
|
86
|
+
<TabItem value="CSV">
|
|
87
|
+
|
|
88
|
+
```csv
|
|
89
|
+
Id,LoginName,Title,PrincipalType,PrincipalTypeString,Email,IsPrimaryAdmin
|
|
90
|
+
6,i:0#.f|membership|user@contoso.com,User Example,1,User,user@contoso.com,1
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
</TabItem>
|
|
94
|
+
<TabItem value="Markdown">
|
|
95
|
+
|
|
96
|
+
```md
|
|
97
|
+
# spo site admin list --siteUrl "https://contoso.sharepoint.com/sites/Test"
|
|
98
|
+
|
|
99
|
+
Date: 20/03/2024
|
|
100
|
+
|
|
101
|
+
## User
|
|
102
|
+
|
|
103
|
+
Property | Value
|
|
104
|
+
---------|-------
|
|
105
|
+
Id | 6
|
|
106
|
+
LoginName | i:0#.f\|membership\|user@contoso.com
|
|
107
|
+
Title | User Example
|
|
108
|
+
PrincipalType | 1
|
|
109
|
+
PrincipalTypeString | User
|
|
110
|
+
Email | user@contoso.com
|
|
111
|
+
IsPrimaryAdmin | true
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
</TabItem>
|
|
115
|
+
</Tabs>
|