@pnp/cli-microsoft365 5.3.0-beta.f028e14 → 5.3.0
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.js +1 -0
- package/dist/Auth.js +5 -0
- package/dist/m365/aad/commands/app/app-add.js +91 -35
- package/dist/m365/aad/commands/app/app-role-list.js +1 -1
- package/dist/m365/aad/commands/app/app-set.js +91 -0
- package/dist/m365/aad/commands/approleassignment/approleassignment-list.js +55 -22
- package/dist/m365/aad/commands/group/group-list.js +1 -1
- package/dist/m365/aad/commands/groupsetting/groupsetting-list.js +1 -1
- package/dist/m365/aad/commands/groupsettingtemplate/groupsettingtemplate-get.js +1 -1
- package/dist/m365/aad/commands/groupsettingtemplate/groupsettingtemplate-list.js +1 -1
- package/dist/m365/aad/commands/o365group/o365group-conversation-list.js +1 -1
- package/dist/m365/aad/commands/o365group/o365group-conversation-post-list.js +1 -1
- package/dist/m365/aad/commands/o365group/o365group-list.js +1 -1
- package/dist/m365/aad/commands/o365group/o365group-recyclebinitem-clear.js +3 -3
- package/dist/m365/aad/commands/o365group/o365group-recyclebinitem-list.js +1 -1
- package/dist/m365/aad/commands/o365group/o365group-user-list.js +2 -2
- package/dist/m365/aad/commands/o365group/o365group-user-set.js +2 -2
- package/dist/m365/aad/commands/user/user-list.js +1 -1
- package/dist/m365/aad/commands/user/user-signin-list.js +1 -1
- package/dist/m365/aad/commands.js +1 -1
- package/dist/m365/app/commands/app-open.js +64 -0
- package/dist/m365/app/commands.js +1 -0
- package/dist/m365/base/PowerBICommand.js +10 -0
- package/dist/m365/file/commands/file-list.js +1 -1
- package/dist/m365/outlook/commands/message/message-list.js +1 -1
- package/dist/m365/outlook/commands/room/room-list.js +1 -1
- package/dist/m365/outlook/commands/roomlist/roomlist-list.js +1 -1
- package/dist/m365/planner/commands/bucket/bucket-add.js +8 -16
- package/dist/m365/planner/commands/bucket/bucket-get.js +186 -0
- package/dist/m365/planner/commands/bucket/bucket-list.js +10 -19
- package/dist/m365/planner/commands/bucket/bucket-remove.js +8 -20
- package/dist/m365/planner/commands/bucket/bucket-set.js +9 -21
- package/dist/m365/planner/commands/plan/plan-add.js +6 -1
- package/dist/m365/planner/commands/plan/plan-details-get.js +12 -15
- package/dist/m365/planner/commands/plan/plan-get.js +13 -18
- package/dist/m365/planner/commands/plan/plan-list.js +10 -13
- package/dist/m365/planner/commands/task/task-add.js +8 -16
- package/dist/m365/planner/commands/task/task-details-get.js +6 -0
- package/dist/m365/planner/commands/task/task-get.js +138 -7
- package/dist/m365/planner/commands/task/task-list.js +15 -24
- package/dist/m365/planner/commands/task/task-reference-add.js +75 -0
- package/dist/m365/planner/commands/task/task-reference-list.js +45 -0
- package/dist/m365/planner/commands/task/task-set.js +9 -18
- package/dist/m365/planner/commands.js +4 -1
- package/dist/m365/pp/commands/gateway/gateway-list.js +36 -0
- package/dist/m365/pp/commands/managementapp/managementapp-list.js +1 -1
- package/dist/m365/pp/commands.js +1 -0
- package/dist/m365/search/commands/externalconnection/externalconnection-list.js +26 -0
- package/dist/m365/search/commands.js +2 -1
- package/dist/m365/spo/commands/eventreceiver/eventreceiver-get.js +119 -0
- package/dist/m365/spo/commands/field/field-list.js +84 -0
- package/dist/m365/spo/commands/list/list-roleinheritance-break.js +84 -0
- package/dist/m365/spo/commands/list/list-roleinheritance-reset.js +76 -0
- package/dist/m365/spo/commands/list/list-view-add.js +113 -0
- package/dist/m365/spo/commands/listitem/listitem-roleinheritance-break.js +83 -0
- package/dist/m365/spo/commands/listitem/listitem-roleinheritance-reset.js +79 -0
- package/dist/m365/spo/commands/roledefinition/roledefinition-list.js +49 -0
- package/dist/m365/spo/commands.js +8 -0
- package/dist/m365/teams/commands/app/app-list.js +1 -1
- package/dist/m365/teams/commands/channel/channel-list.js +1 -1
- package/dist/m365/teams/commands/channel/channel-member-add.js +4 -1
- package/dist/m365/teams/commands/channel/channel-member-list.js +1 -1
- package/dist/m365/teams/commands/channel/channel-member-remove.js +3 -0
- package/dist/m365/teams/commands/channel/channel-member-set.js +3 -0
- package/dist/m365/teams/commands/chat/chat-get.js +8 -8
- package/dist/m365/teams/commands/chat/chat-list.js +1 -1
- package/dist/m365/teams/commands/chat/chat-member-list.js +1 -1
- package/dist/m365/teams/commands/chat/chat-message-list.js +1 -1
- package/dist/m365/teams/commands/chat/chat-message-send.js +6 -6
- package/dist/m365/teams/commands/chat/chatUtil.js +4 -4
- package/dist/m365/teams/commands/message/message-list.js +1 -1
- package/dist/m365/teams/commands/message/message-reply-list.js +1 -1
- package/dist/m365/teams/commands/tab/tab-list.js +1 -1
- package/dist/m365/teams/commands/team/team-list.js +1 -1
- package/dist/m365/teams/commands/user/user-app-list.js +1 -1
- package/dist/m365/teams/commands/user/user-list.js +2 -2
- package/dist/m365/tenant/commands/security/security-alerts-list.js +71 -0
- package/dist/m365/tenant/commands/serviceannouncement/serviceannouncement-healthissue-list.js +1 -1
- package/dist/m365/tenant/commands/serviceannouncement/serviceannouncement-message-list.js +1 -1
- package/dist/m365/tenant/commands.js +1 -0
- package/dist/m365/todo/commands/list/list-list.js +1 -1
- package/dist/m365/todo/commands/task/task-list.js +1 -1
- package/dist/utils/accessToken.js +18 -0
- package/dist/utils/formatting.js +11 -2
- package/dist/utils/odata.js +2 -2
- package/dist/utils/planner.js +65 -0
- package/docs/docs/cmd/aad/app/app-add.md +15 -0
- package/docs/docs/cmd/aad/app/app-set.md +17 -0
- package/docs/docs/cmd/aad/approleassignment/approleassignment-remove.md +1 -1
- package/docs/docs/cmd/app/app-open.md +45 -0
- package/docs/docs/cmd/planner/bucket/bucket-get.md +57 -0
- package/docs/docs/cmd/planner/task/task-get.md +30 -3
- package/docs/docs/cmd/planner/task/task-reference-add.md +45 -0
- package/docs/docs/cmd/planner/task/task-reference-list.md +24 -0
- package/docs/docs/cmd/pp/gateway/gateway-list.md +21 -0
- package/docs/docs/cmd/search/externalconnection/externalconnection-list.md +21 -0
- package/docs/docs/cmd/spo/eventreceiver/eventreceiver-get.md +70 -0
- package/docs/docs/cmd/spo/field/field-list.md +51 -0
- package/docs/docs/cmd/spo/list/list-roleinheritance-break.md +55 -0
- package/docs/docs/cmd/spo/list/list-roleinheritance-reset.md +36 -0
- package/docs/docs/cmd/spo/list/list-view-add.md +67 -0
- package/docs/docs/cmd/spo/listitem/listitem-roleinheritance-break.md +58 -0
- package/docs/docs/cmd/spo/listitem/listitem-roleinheritance-reset.md +39 -0
- package/docs/docs/cmd/spo/roledefinition/roledefinition-list.md +24 -0
- package/docs/docs/cmd/spo/userprofile/userprofile-get.md +1 -1
- package/docs/docs/cmd/teams/channel/channel-member-list.md +4 -4
- package/docs/docs/cmd/teams/channel/channel-member-remove.md +2 -2
- package/docs/docs/cmd/teams/channel/channel-member-set.md +2 -2
- package/docs/docs/cmd/tenant/security/security-alerts-list.md +30 -0
- package/npm-shrinkwrap.json +1515 -1282
- package/package.json +26 -25
package/.eslintrc.js
CHANGED
package/dist/Auth.js
CHANGED
|
@@ -540,6 +540,11 @@ class Auth {
|
|
|
540
540
|
// we need to use https://management.azure.com/ instead
|
|
541
541
|
resource = 'https://management.azure.com/';
|
|
542
542
|
}
|
|
543
|
+
if (resource === 'https://api.powerbi.com') {
|
|
544
|
+
// api.powerbi.com is not a valid resource
|
|
545
|
+
// we need to use https://analysis.windows.net/powerbi/api instead
|
|
546
|
+
resource = 'https://analysis.windows.net/powerbi/api';
|
|
547
|
+
}
|
|
543
548
|
return resource;
|
|
544
549
|
}
|
|
545
550
|
getServiceConnectionInfo() {
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
2
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
12
|
const fs = require("fs");
|
|
4
13
|
const uuid_1 = require("uuid");
|
|
@@ -31,6 +40,9 @@ class AadAppAddCommand extends GraphCommand_1.default {
|
|
|
31
40
|
telemetryProps.scopeName = typeof args.options.scopeName !== 'undefined';
|
|
32
41
|
telemetryProps.uri = typeof args.options.uri !== 'undefined';
|
|
33
42
|
telemetryProps.withSecret = args.options.withSecret;
|
|
43
|
+
telemetryProps.certificateFile = typeof args.options.certificateFile !== 'undefined';
|
|
44
|
+
telemetryProps.certificateBase64Encoded = typeof args.options.certificateBase64Encoded !== 'undefined';
|
|
45
|
+
telemetryProps.certificateDisplayName = typeof args.options.certificateDisplayName !== 'undefined';
|
|
34
46
|
return telemetryProps;
|
|
35
47
|
}
|
|
36
48
|
commandAction(logger, args, cb) {
|
|
@@ -66,43 +78,55 @@ class AadAppAddCommand extends GraphCommand_1.default {
|
|
|
66
78
|
}, (rawRes) => this.handleRejectedODataJsonPromise(rawRes, logger, cb));
|
|
67
79
|
}
|
|
68
80
|
createAppRegistration(args, apis, logger) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (!applicationInfo.displayName && this.manifest) {
|
|
74
|
-
applicationInfo.displayName = this.manifest.name;
|
|
75
|
-
}
|
|
76
|
-
this.appName = applicationInfo.displayName;
|
|
77
|
-
if (apis.length > 0) {
|
|
78
|
-
applicationInfo.requiredResourceAccess = apis;
|
|
79
|
-
}
|
|
80
|
-
if (args.options.redirectUris) {
|
|
81
|
-
applicationInfo[args.options.platform] = {
|
|
82
|
-
redirectUris: args.options.redirectUris.split(',').map(u => u.trim())
|
|
81
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
82
|
+
const applicationInfo = {
|
|
83
|
+
displayName: args.options.name,
|
|
84
|
+
signInAudience: args.options.multitenant ? 'AzureADMultipleOrgs' : 'AzureADMyOrg'
|
|
83
85
|
};
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
if (!applicationInfo.displayName && this.manifest) {
|
|
87
|
+
applicationInfo.displayName = this.manifest.name;
|
|
88
|
+
}
|
|
89
|
+
this.appName = applicationInfo.displayName;
|
|
90
|
+
if (apis.length > 0) {
|
|
91
|
+
applicationInfo.requiredResourceAccess = apis;
|
|
92
|
+
}
|
|
93
|
+
if (args.options.redirectUris) {
|
|
94
|
+
applicationInfo[args.options.platform] = {
|
|
95
|
+
redirectUris: args.options.redirectUris.split(',').map(u => u.trim())
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
if (args.options.implicitFlow) {
|
|
99
|
+
if (!applicationInfo.web) {
|
|
100
|
+
applicationInfo.web = {};
|
|
101
|
+
}
|
|
102
|
+
applicationInfo.web.implicitGrantSettings = {
|
|
103
|
+
enableAccessTokenIssuance: true,
|
|
104
|
+
enableIdTokenIssuance: true
|
|
105
|
+
};
|
|
88
106
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
107
|
+
if (args.options.certificateFile || args.options.certificateBase64Encoded) {
|
|
108
|
+
const certificateBase64Encoded = this.getCertificateBase64Encoded(args, logger);
|
|
109
|
+
const newKeyCredential = {
|
|
110
|
+
type: "AsymmetricX509Cert",
|
|
111
|
+
usage: "Verify",
|
|
112
|
+
displayName: args.options.certificateDisplayName,
|
|
113
|
+
key: certificateBase64Encoded
|
|
114
|
+
};
|
|
115
|
+
applicationInfo.keyCredentials = [newKeyCredential];
|
|
116
|
+
}
|
|
117
|
+
if (this.verbose) {
|
|
118
|
+
logger.logToStderr(`Creating Azure AD app registration...`);
|
|
119
|
+
}
|
|
120
|
+
const createApplicationRequestOptions = {
|
|
121
|
+
url: `${this.resource}/v1.0/myorganization/applications`,
|
|
122
|
+
headers: {
|
|
123
|
+
accept: 'application/json;odata.metadata=none'
|
|
124
|
+
},
|
|
125
|
+
responseType: 'json',
|
|
126
|
+
data: applicationInfo
|
|
92
127
|
};
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
logger.logToStderr(`Creating Azure AD app registration...`);
|
|
96
|
-
}
|
|
97
|
-
const createApplicationRequestOptions = {
|
|
98
|
-
url: `${this.resource}/v1.0/myorganization/applications`,
|
|
99
|
-
headers: {
|
|
100
|
-
accept: 'application/json;odata.metadata=none'
|
|
101
|
-
},
|
|
102
|
-
responseType: 'json',
|
|
103
|
-
data: applicationInfo
|
|
104
|
-
};
|
|
105
|
-
return request_1.default.post(createApplicationRequestOptions);
|
|
128
|
+
return request_1.default.post(createApplicationRequestOptions);
|
|
129
|
+
});
|
|
106
130
|
}
|
|
107
131
|
updateAppFromManifest(args, appInfo) {
|
|
108
132
|
if (!args.options.manifest) {
|
|
@@ -325,7 +349,7 @@ class AadAppAddCommand extends GraphCommand_1.default {
|
|
|
325
349
|
logger.logToStderr('Resolving requested APIs...');
|
|
326
350
|
}
|
|
327
351
|
return utils_1.odata
|
|
328
|
-
.getAllItems(`${this.resource}/v1.0/myorganization/servicePrincipals?$select=servicePrincipalNames,appId,oauth2PermissionScopes,appRoles
|
|
352
|
+
.getAllItems(`${this.resource}/v1.0/myorganization/servicePrincipals?$select=servicePrincipalNames,appId,oauth2PermissionScopes,appRoles`)
|
|
329
353
|
.then(servicePrincipals => {
|
|
330
354
|
try {
|
|
331
355
|
const resolvedApis = this.getRequiredResourceAccessForApis(servicePrincipals, args.options.apisDelegated, 'Scope', logger);
|
|
@@ -437,6 +461,20 @@ class AadAppAddCommand extends GraphCommand_1.default {
|
|
|
437
461
|
value: password.secretText
|
|
438
462
|
}));
|
|
439
463
|
}
|
|
464
|
+
getCertificateBase64Encoded(args, logger) {
|
|
465
|
+
if (args.options.certificateBase64Encoded) {
|
|
466
|
+
return args.options.certificateBase64Encoded;
|
|
467
|
+
}
|
|
468
|
+
if (this.debug) {
|
|
469
|
+
logger.logToStderr(`Reading existing ${args.options.certificateFile}...`);
|
|
470
|
+
}
|
|
471
|
+
try {
|
|
472
|
+
return fs.readFileSync(args.options.certificateFile, { encoding: 'base64' });
|
|
473
|
+
}
|
|
474
|
+
catch (e) {
|
|
475
|
+
throw new Error(`Error reading certificate file: ${e}. Please add the certificate using base64 option '--certificateBase64Encoded'.`);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
440
478
|
saveAppInfo(args, appInfo, logger) {
|
|
441
479
|
if (!args.options.save) {
|
|
442
480
|
return Promise.resolve(appInfo);
|
|
@@ -519,6 +557,15 @@ class AadAppAddCommand extends GraphCommand_1.default {
|
|
|
519
557
|
{
|
|
520
558
|
option: '--scopeAdminConsentDescription [scopeAdminConsentDescription]'
|
|
521
559
|
},
|
|
560
|
+
{
|
|
561
|
+
option: '--certificateFile [certificateFile]'
|
|
562
|
+
},
|
|
563
|
+
{
|
|
564
|
+
option: '--certificateBase64Encoded [certificateBase64Encoded]'
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
option: '--certificateDisplayName [certificateDisplayName]'
|
|
568
|
+
},
|
|
522
569
|
{
|
|
523
570
|
option: '--manifest [manifest]'
|
|
524
571
|
},
|
|
@@ -540,6 +587,15 @@ class AadAppAddCommand extends GraphCommand_1.default {
|
|
|
540
587
|
if (args.options.redirectUris && !args.options.platform) {
|
|
541
588
|
return `When you specify redirectUris you also need to specify platform`;
|
|
542
589
|
}
|
|
590
|
+
if (args.options.certificateFile && args.options.certificateBase64Encoded) {
|
|
591
|
+
return 'Specify either certificateFile or certificateBase64Encoded but not both';
|
|
592
|
+
}
|
|
593
|
+
if (args.options.certificateDisplayName && !args.options.certificateFile && !args.options.certificateBase64Encoded) {
|
|
594
|
+
return 'When you specify certificateDisplayName you also need to specify certificateFile or certificateBase64Encoded';
|
|
595
|
+
}
|
|
596
|
+
if (args.options.certificateFile && !fs.existsSync(args.options.certificateFile)) {
|
|
597
|
+
return 'Certificate file not found';
|
|
598
|
+
}
|
|
543
599
|
if (args.options.scopeName) {
|
|
544
600
|
if (!args.options.uri) {
|
|
545
601
|
return `When you specify scopeName you also need to specify uri`;
|
|
@@ -24,7 +24,7 @@ class AadAppRoleListCommand extends GraphCommand_1.default {
|
|
|
24
24
|
commandAction(logger, args, cb) {
|
|
25
25
|
this
|
|
26
26
|
.getAppObjectId(args, logger)
|
|
27
|
-
.then(objectId => utils_1.odata.getAllItems(`${this.resource}/v1.0/myorganization/applications/${objectId}/appRoles
|
|
27
|
+
.then(objectId => utils_1.odata.getAllItems(`${this.resource}/v1.0/myorganization/applications/${objectId}/appRoles`))
|
|
28
28
|
.then(appRoles => {
|
|
29
29
|
logger.log(appRoles);
|
|
30
30
|
cb();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const fs = require("fs");
|
|
3
4
|
const request_1 = require("../../../../request");
|
|
4
5
|
const GraphCommand_1 = require("../../../base/GraphCommand");
|
|
5
6
|
const commands_1 = require("../../commands");
|
|
@@ -19,6 +20,9 @@ class AadAppSetCommand extends GraphCommand_1.default {
|
|
|
19
20
|
telemetryProps.redirectUris = typeof args.options.redirectUris !== 'undefined';
|
|
20
21
|
telemetryProps.redirectUrisToRemove = typeof args.options.redirectUrisToRemove !== 'undefined';
|
|
21
22
|
telemetryProps.uri = typeof args.options.uri !== 'undefined';
|
|
23
|
+
telemetryProps.certificateFile = typeof args.options.certificateFile !== 'undefined';
|
|
24
|
+
telemetryProps.certificateBase64Encoded = typeof args.options.certificateBase64Encoded !== 'undefined';
|
|
25
|
+
telemetryProps.certificateDisplayName = typeof args.options.certificateDisplayName !== 'undefined';
|
|
22
26
|
return telemetryProps;
|
|
23
27
|
}
|
|
24
28
|
commandAction(logger, args, cb) {
|
|
@@ -26,6 +30,7 @@ class AadAppSetCommand extends GraphCommand_1.default {
|
|
|
26
30
|
.getAppObjectId(args, logger)
|
|
27
31
|
.then(objectId => this.configureUri(args, objectId, logger))
|
|
28
32
|
.then(objectId => this.configureRedirectUris(args, objectId, logger))
|
|
33
|
+
.then(objectId => this.configureCertificate(args, objectId, logger))
|
|
29
34
|
.then(_ => cb(), (rawRes) => this.handleRejectedODataJsonPromise(rawRes, logger, cb));
|
|
30
35
|
}
|
|
31
36
|
getAppObjectId(args, logger) {
|
|
@@ -156,6 +161,80 @@ class AadAppSetCommand extends GraphCommand_1.default {
|
|
|
156
161
|
})
|
|
157
162
|
.then(_ => Promise.resolve(objectId));
|
|
158
163
|
}
|
|
164
|
+
configureCertificate(args, objectId, logger) {
|
|
165
|
+
if (!args.options.certificateFile && !args.options.certificateBase64Encoded) {
|
|
166
|
+
return Promise.resolve();
|
|
167
|
+
}
|
|
168
|
+
if (this.verbose) {
|
|
169
|
+
logger.logToStderr(`Setting certificate for Azure AD app...`);
|
|
170
|
+
}
|
|
171
|
+
const certificateBase64Encoded = this.getCertificateBase64Encoded(args, logger);
|
|
172
|
+
return this
|
|
173
|
+
.getCurrentKeyCredentialsList(args, objectId, certificateBase64Encoded, logger)
|
|
174
|
+
.then(currentKeyCredentials => {
|
|
175
|
+
if (this.verbose) {
|
|
176
|
+
logger.logToStderr(`Adding new keyCredential to list`);
|
|
177
|
+
}
|
|
178
|
+
// The KeyCredential graph type defines the 'key' property as 'NullableOption<number>'
|
|
179
|
+
// while it is a base64 encoded string. This is why a cast to any is used here.
|
|
180
|
+
const keyCredentials = currentKeyCredentials.filter(existingCredential => existingCredential.key !== certificateBase64Encoded);
|
|
181
|
+
const newKeyCredential = {
|
|
182
|
+
type: "AsymmetricX509Cert",
|
|
183
|
+
usage: "Verify",
|
|
184
|
+
displayName: args.options.certificateDisplayName,
|
|
185
|
+
key: certificateBase64Encoded
|
|
186
|
+
};
|
|
187
|
+
keyCredentials.push(newKeyCredential);
|
|
188
|
+
return Promise.resolve(keyCredentials);
|
|
189
|
+
})
|
|
190
|
+
.then(keyCredentials => this.updateKeyCredentials(objectId, keyCredentials, logger));
|
|
191
|
+
}
|
|
192
|
+
getCertificateBase64Encoded(args, logger) {
|
|
193
|
+
if (args.options.certificateBase64Encoded) {
|
|
194
|
+
return args.options.certificateBase64Encoded;
|
|
195
|
+
}
|
|
196
|
+
if (this.debug) {
|
|
197
|
+
logger.logToStderr(`Reading existing ${args.options.certificateFile}...`);
|
|
198
|
+
}
|
|
199
|
+
try {
|
|
200
|
+
return fs.readFileSync(args.options.certificateFile, { encoding: 'base64' });
|
|
201
|
+
}
|
|
202
|
+
catch (e) {
|
|
203
|
+
throw new Error(`Error reading certificate file: ${e}. Please add the certificate using base64 option '--certificateBase64Encoded'.`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// We first retrieve existing certificates because we need to specify the full list of certificates when updating the app.
|
|
207
|
+
getCurrentKeyCredentialsList(args, objectId, certificateBase64Encoded, logger) {
|
|
208
|
+
if (this.verbose) {
|
|
209
|
+
logger.logToStderr(`Retrieving current keyCredentials list for app`);
|
|
210
|
+
}
|
|
211
|
+
const getAppRequestOptions = {
|
|
212
|
+
url: `${this.resource}/v1.0/myorganization/applications/${objectId}?$select=keyCredentials`,
|
|
213
|
+
headers: {
|
|
214
|
+
'content-type': 'application/json;odata.metadata=none'
|
|
215
|
+
},
|
|
216
|
+
responseType: 'json'
|
|
217
|
+
};
|
|
218
|
+
return request_1.default.get(getAppRequestOptions).then((application) => {
|
|
219
|
+
return Promise.resolve(application.keyCredentials || []);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
updateKeyCredentials(objectId, keyCredentials, logger) {
|
|
223
|
+
if (this.verbose) {
|
|
224
|
+
logger.logToStderr(`Updating keyCredentials in AAD app`);
|
|
225
|
+
}
|
|
226
|
+
const requestOptions = {
|
|
227
|
+
url: `${this.resource}/v1.0/myorganization/applications/${objectId}`,
|
|
228
|
+
headers: {
|
|
229
|
+
'content-type': 'application/json;odata.metadata=none'
|
|
230
|
+
},
|
|
231
|
+
responseType: 'json',
|
|
232
|
+
data: {
|
|
233
|
+
keyCredentials: keyCredentials
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
return request_1.default.patch(requestOptions);
|
|
237
|
+
}
|
|
159
238
|
options() {
|
|
160
239
|
const options = [
|
|
161
240
|
{ option: '--appId [appId]' },
|
|
@@ -163,6 +242,9 @@ class AadAppSetCommand extends GraphCommand_1.default {
|
|
|
163
242
|
{ option: '-n, --name [name]' },
|
|
164
243
|
{ option: '-u, --uri [uri]' },
|
|
165
244
|
{ option: '-r, --redirectUris [redirectUris]' },
|
|
245
|
+
{ option: '--certificateFile [certificateFile]' },
|
|
246
|
+
{ option: '--certificateBase64Encoded [certificateBase64Encoded]' },
|
|
247
|
+
{ option: '--certificateDisplayName [certificateDisplayName]' },
|
|
166
248
|
{
|
|
167
249
|
option: '--platform [platform]',
|
|
168
250
|
autocomplete: AadAppSetCommand.aadApplicationPlatform
|
|
@@ -183,6 +265,15 @@ class AadAppSetCommand extends GraphCommand_1.default {
|
|
|
183
265
|
(args.options.objectId && args.options.name)) {
|
|
184
266
|
return 'Specify either appId, objectId or name but not both';
|
|
185
267
|
}
|
|
268
|
+
if (args.options.certificateFile && args.options.certificateBase64Encoded) {
|
|
269
|
+
return 'Specify either certificateFile or certificateBase64Encoded but not both';
|
|
270
|
+
}
|
|
271
|
+
if (args.options.certificateDisplayName && !args.options.certificateFile && !args.options.certificateBase64Encoded) {
|
|
272
|
+
return 'When you specify certificateDisplayName you also need to specify certificateFile or certificateBase64Encoded';
|
|
273
|
+
}
|
|
274
|
+
if (args.options.certificateFile && !fs.existsSync(args.options.certificateFile)) {
|
|
275
|
+
return 'Certificate file not found';
|
|
276
|
+
}
|
|
186
277
|
if (args.options.redirectUris && !args.options.platform) {
|
|
187
278
|
return `When you specify redirectUris you also need to specify platform`;
|
|
188
279
|
}
|
|
@@ -22,29 +22,14 @@ class AadAppRoleAssignmentListCommand extends GraphCommand_1.default {
|
|
|
22
22
|
return ['resourceDisplayName', 'roleName'];
|
|
23
23
|
}
|
|
24
24
|
commandAction(logger, args, cb) {
|
|
25
|
-
let
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
spMatchQuery = `appId eq '${encodeURIComponent(args.options.appId)}'`;
|
|
30
|
-
}
|
|
31
|
-
else if (args.options.objectId) {
|
|
32
|
-
spMatchQuery = `id eq '${encodeURIComponent(args.options.objectId)}'`;
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
spMatchQuery = `displayName eq '${encodeURIComponent(args.options.displayName)}'`;
|
|
36
|
-
}
|
|
37
|
-
this
|
|
38
|
-
.getServicePrincipalForApp(spMatchQuery)
|
|
39
|
-
.then((resp) => {
|
|
40
|
-
if (!resp.value.length) {
|
|
41
|
-
return Promise.reject('app registration not found');
|
|
42
|
-
}
|
|
43
|
-
sp = resp.value[0];
|
|
25
|
+
let spAppRoleAssignments;
|
|
26
|
+
this.getAppRoleAssignments(args.options)
|
|
27
|
+
.then((appRoleAssignments) => {
|
|
28
|
+
spAppRoleAssignments = appRoleAssignments;
|
|
44
29
|
// the role assignment has an appRoleId but no name. To get the name,
|
|
45
30
|
// we need to get all the roles from the resource. the resource is
|
|
46
31
|
// a service principal. Multiple roles may have same resource id.
|
|
47
|
-
const resourceIds =
|
|
32
|
+
const resourceIds = appRoleAssignments.map((item) => item.resourceId);
|
|
48
33
|
const tasks = [];
|
|
49
34
|
for (let i = 0; i < resourceIds.length; i++) {
|
|
50
35
|
tasks.push(this.getServicePrincipal(resourceIds[i]));
|
|
@@ -55,7 +40,7 @@ class AadAppRoleAssignmentListCommand extends GraphCommand_1.default {
|
|
|
55
40
|
// loop through all appRoleAssignments for the servicePrincipal
|
|
56
41
|
// and lookup the appRole.Id in the resources[resourceId].appRoles array...
|
|
57
42
|
const results = [];
|
|
58
|
-
|
|
43
|
+
spAppRoleAssignments.map((appRoleAssignment) => {
|
|
59
44
|
const resource = resources.find((r) => r.id === appRoleAssignment.resourceId);
|
|
60
45
|
if (resource) {
|
|
61
46
|
const appRole = resource.appRoles.find((r) => r.id === appRoleAssignment.appRoleId);
|
|
@@ -65,7 +50,9 @@ class AadAppRoleAssignmentListCommand extends GraphCommand_1.default {
|
|
|
65
50
|
resourceDisplayName: appRoleAssignment.resourceDisplayName,
|
|
66
51
|
resourceId: appRoleAssignment.resourceId,
|
|
67
52
|
roleId: appRole.id,
|
|
68
|
-
roleName: appRole.value
|
|
53
|
+
roleName: appRole.value,
|
|
54
|
+
created: appRoleAssignment.createdDateTime,
|
|
55
|
+
deleted: appRoleAssignment.deletedDateTime
|
|
69
56
|
});
|
|
70
57
|
}
|
|
71
58
|
}
|
|
@@ -74,6 +61,52 @@ class AadAppRoleAssignmentListCommand extends GraphCommand_1.default {
|
|
|
74
61
|
cb();
|
|
75
62
|
}, (err) => this.handleRejectedODataJsonPromise(err, logger, cb));
|
|
76
63
|
}
|
|
64
|
+
getAppRoleAssignments(argOptions) {
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
if (argOptions.objectId) {
|
|
67
|
+
this.getSPAppRoleAssignments(argOptions.objectId)
|
|
68
|
+
.then((spAppRoleAssignments) => {
|
|
69
|
+
if (!spAppRoleAssignments.value.length) {
|
|
70
|
+
reject('no app role assignments found');
|
|
71
|
+
}
|
|
72
|
+
resolve(spAppRoleAssignments.value);
|
|
73
|
+
})
|
|
74
|
+
.catch((err) => {
|
|
75
|
+
reject(err);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// Use existing way to get service principal object
|
|
80
|
+
let spMatchQuery = '';
|
|
81
|
+
if (argOptions.appId) {
|
|
82
|
+
spMatchQuery = `appId eq '${encodeURIComponent(argOptions.appId)}'`;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
spMatchQuery = `displayName eq '${encodeURIComponent(argOptions.displayName)}'`;
|
|
86
|
+
}
|
|
87
|
+
this.getServicePrincipalForApp(spMatchQuery)
|
|
88
|
+
.then((resp) => {
|
|
89
|
+
if (!resp.value.length) {
|
|
90
|
+
reject('app registration not found');
|
|
91
|
+
}
|
|
92
|
+
resolve(resp.value[0].appRoleAssignments);
|
|
93
|
+
})
|
|
94
|
+
.catch((err) => {
|
|
95
|
+
reject(err);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
getSPAppRoleAssignments(spId) {
|
|
101
|
+
const spRequestOptions = {
|
|
102
|
+
url: `${this.resource}/v1.0/servicePrincipals/${spId}/appRoleAssignments`,
|
|
103
|
+
headers: {
|
|
104
|
+
accept: 'application/json'
|
|
105
|
+
},
|
|
106
|
+
responseType: 'json'
|
|
107
|
+
};
|
|
108
|
+
return request_1.default.get(spRequestOptions);
|
|
109
|
+
}
|
|
77
110
|
getServicePrincipalForApp(filterParam) {
|
|
78
111
|
const spRequestOptions = {
|
|
79
112
|
url: `${this.resource}/v1.0/servicePrincipals?$expand=appRoleAssignments&$filter=${filterParam}`,
|
|
@@ -21,7 +21,7 @@ class AadGroupListCommand extends GraphCommand_1.default {
|
|
|
21
21
|
commandAction(logger, args, cb) {
|
|
22
22
|
const endpoint = args.options.deleted ? 'directory/deletedItems/microsoft.graph.group' : 'groups';
|
|
23
23
|
utils_1.odata
|
|
24
|
-
.getAllItems(`${this.resource}/v1.0/${endpoint}
|
|
24
|
+
.getAllItems(`${this.resource}/v1.0/${endpoint}`)
|
|
25
25
|
.then((groups) => {
|
|
26
26
|
if (args.options.output === 'text') {
|
|
27
27
|
groups.forEach((group) => {
|
|
@@ -15,7 +15,7 @@ class AadGroupSettingListCommand extends GraphCommand_1.default {
|
|
|
15
15
|
}
|
|
16
16
|
commandAction(logger, args, cb) {
|
|
17
17
|
utils_1.odata
|
|
18
|
-
.getAllItems(`${this.resource}/v1.0/groupSettings
|
|
18
|
+
.getAllItems(`${this.resource}/v1.0/groupSettings`)
|
|
19
19
|
.then((groupSettings) => {
|
|
20
20
|
logger.log(groupSettings);
|
|
21
21
|
cb();
|
|
@@ -19,7 +19,7 @@ class AadGroupSettingTemplateGetCommand extends GraphCommand_1.default {
|
|
|
19
19
|
}
|
|
20
20
|
commandAction(logger, args, cb) {
|
|
21
21
|
utils_1.odata
|
|
22
|
-
.getAllItems(`${this.resource}/v1.0/groupSettingTemplates
|
|
22
|
+
.getAllItems(`${this.resource}/v1.0/groupSettingTemplates`)
|
|
23
23
|
.then((templates) => {
|
|
24
24
|
const groupSettingTemplate = templates.filter(t => args.options.id ? t.id === args.options.id : t.displayName === args.options.displayName);
|
|
25
25
|
if (groupSettingTemplate && groupSettingTemplate.length > 0) {
|
|
@@ -15,7 +15,7 @@ class AadGroupSettingTemplateListCommand extends GraphCommand_1.default {
|
|
|
15
15
|
}
|
|
16
16
|
commandAction(logger, args, cb) {
|
|
17
17
|
utils_1.odata
|
|
18
|
-
.getAllItems(`${this.resource}/v1.0/groupSettingTemplates
|
|
18
|
+
.getAllItems(`${this.resource}/v1.0/groupSettingTemplates`)
|
|
19
19
|
.then((templates) => {
|
|
20
20
|
logger.log(templates);
|
|
21
21
|
cb();
|
|
@@ -15,7 +15,7 @@ class AadO365GroupConversationListCommand extends GraphCommand_1.default {
|
|
|
15
15
|
}
|
|
16
16
|
commandAction(logger, args, cb) {
|
|
17
17
|
utils_1.odata
|
|
18
|
-
.getAllItems(`${this.resource}/v1.0/groups/${args.options.groupId}/conversations
|
|
18
|
+
.getAllItems(`${this.resource}/v1.0/groups/${args.options.groupId}/conversations`)
|
|
19
19
|
.then((conversations) => {
|
|
20
20
|
logger.log(conversations);
|
|
21
21
|
cb();
|
|
@@ -24,7 +24,7 @@ class AadO365GroupConversationPostListCommand extends GraphCommand_1.default {
|
|
|
24
24
|
this
|
|
25
25
|
.getGroupId(args)
|
|
26
26
|
.then((retrievedgroupId) => {
|
|
27
|
-
return utils_1.odata.getAllItems(`${this.resource}/v1.0/groups/${retrievedgroupId}/threads/${args.options.threadId}/posts
|
|
27
|
+
return utils_1.odata.getAllItems(`${this.resource}/v1.0/groups/${retrievedgroupId}/threads/${args.options.threadId}/posts`);
|
|
28
28
|
})
|
|
29
29
|
.then((posts) => {
|
|
30
30
|
logger.log(posts);
|
|
@@ -19,7 +19,7 @@ class AadO365GroupRecycleBinItemClearCommand extends GraphCommand_1.default {
|
|
|
19
19
|
}
|
|
20
20
|
commandAction(logger, args, cb) {
|
|
21
21
|
const clearO365GroupRecycleBinItems = () => {
|
|
22
|
-
this.processRecycleBinItemsClear(
|
|
22
|
+
this.processRecycleBinItemsClear().then(_ => cb(), (rawRes) => this.handleRejectedODataJsonPromise(rawRes, logger, cb));
|
|
23
23
|
};
|
|
24
24
|
if (args.options.confirm) {
|
|
25
25
|
clearO365GroupRecycleBinItems();
|
|
@@ -40,12 +40,12 @@ class AadO365GroupRecycleBinItemClearCommand extends GraphCommand_1.default {
|
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
processRecycleBinItemsClear(
|
|
43
|
+
processRecycleBinItemsClear() {
|
|
44
44
|
const filter = `?$filter=groupTypes/any(c:c+eq+'Unified')`;
|
|
45
45
|
const topCount = '&$top=100';
|
|
46
46
|
const endpoint = `${this.resource}/v1.0/directory/deletedItems/Microsoft.Graph.Group${filter}${topCount}`;
|
|
47
47
|
return utils_1.odata
|
|
48
|
-
.getAllItems(endpoint
|
|
48
|
+
.getAllItems(endpoint)
|
|
49
49
|
.then((recycleBinItems) => {
|
|
50
50
|
if (recycleBinItems.length === 0) {
|
|
51
51
|
return Promise.resolve();
|
|
@@ -26,7 +26,7 @@ class AadO365GroupRecycleBinItemListCommand extends GraphCommand_1.default {
|
|
|
26
26
|
const topCount = '&$top=100';
|
|
27
27
|
const endpoint = `${this.resource}/v1.0/directory/deletedItems/Microsoft.Graph.Group${filter}${displayNameFilter}${mailNicknameFilter}${topCount}`;
|
|
28
28
|
utils_1.odata
|
|
29
|
-
.getAllItems(endpoint
|
|
29
|
+
.getAllItems(endpoint)
|
|
30
30
|
.then((recycleBinItems) => {
|
|
31
31
|
logger.log(recycleBinItems);
|
|
32
32
|
cb();
|
|
@@ -38,7 +38,7 @@ class AadO365GroupUserListCommand extends GraphCommand_1.default {
|
|
|
38
38
|
getOwners(logger, groupId) {
|
|
39
39
|
const endpoint = `${this.resource}/v1.0/groups/${groupId}/owners?$select=id,displayName,userPrincipalName,userType`;
|
|
40
40
|
return utils_1.odata
|
|
41
|
-
.getAllItems(endpoint
|
|
41
|
+
.getAllItems(endpoint)
|
|
42
42
|
.then(users => {
|
|
43
43
|
// Currently there is a bug in the Microsoft Graph that returns Owners as
|
|
44
44
|
// userType 'member'. We therefore update all returned user as owner
|
|
@@ -50,7 +50,7 @@ class AadO365GroupUserListCommand extends GraphCommand_1.default {
|
|
|
50
50
|
}
|
|
51
51
|
getMembersAndGuests(logger, groupId) {
|
|
52
52
|
const endpoint = `${this.resource}/v1.0/groups/${groupId}/members?$select=id,displayName,userPrincipalName,userType`;
|
|
53
|
-
return utils_1.odata.getAllItems(endpoint
|
|
53
|
+
return utils_1.odata.getAllItems(endpoint);
|
|
54
54
|
}
|
|
55
55
|
options() {
|
|
56
56
|
const options = [
|
|
@@ -92,7 +92,7 @@ class AadO365GroupUserSetCommand extends GraphCommand_1.default {
|
|
|
92
92
|
getOwners(logger, groupId) {
|
|
93
93
|
const endpoint = `${this.resource}/v1.0/groups/${groupId}/owners?$select=id,displayName,userPrincipalName,userType`;
|
|
94
94
|
return utils_1.odata
|
|
95
|
-
.getAllItems(endpoint
|
|
95
|
+
.getAllItems(endpoint)
|
|
96
96
|
.then(users => {
|
|
97
97
|
// Currently there is a bug in the Microsoft Graph that returns Owners as
|
|
98
98
|
// userType 'member'. We therefore update all returned user as owner
|
|
@@ -104,7 +104,7 @@ class AadO365GroupUserSetCommand extends GraphCommand_1.default {
|
|
|
104
104
|
}
|
|
105
105
|
getMembersAndGuests(logger, groupId) {
|
|
106
106
|
const endpoint = `${this.resource}/v1.0/groups/${groupId}/members?$select=id,displayName,userPrincipalName,userType`;
|
|
107
|
-
return utils_1.odata.getAllItems(endpoint
|
|
107
|
+
return utils_1.odata.getAllItems(endpoint);
|
|
108
108
|
}
|
|
109
109
|
options() {
|
|
110
110
|
const options = [
|
|
@@ -27,7 +27,7 @@ class AadUserListCommand extends GraphCommand_1.default {
|
|
|
27
27
|
const endpoint = args.options.deleted ? 'directory/deletedItems/microsoft.graph.user' : 'users';
|
|
28
28
|
const url = `${this.resource}/v1.0/${endpoint}?$select=${properties.join(',')}${(filter.length > 0 ? '&' + filter : '')}&$top=100`;
|
|
29
29
|
utils_1.odata
|
|
30
|
-
.getAllItems(url
|
|
30
|
+
.getAllItems(url)
|
|
31
31
|
.then((users) => {
|
|
32
32
|
logger.log(users);
|
|
33
33
|
cb();
|
|
@@ -6,11 +6,11 @@ exports.default = {
|
|
|
6
6
|
APP_DELETE: `${prefix} app delete`,
|
|
7
7
|
APP_GET: `${prefix} app get`,
|
|
8
8
|
APP_REMOVE: `${prefix} app remove`,
|
|
9
|
-
APP_SET: `${prefix} app set`,
|
|
10
9
|
APP_ROLE_ADD: `${prefix} app role add`,
|
|
11
10
|
APP_ROLE_DELETE: `${prefix} app role delete`,
|
|
12
11
|
APP_ROLE_LIST: `${prefix} app role list`,
|
|
13
12
|
APP_ROLE_REMOVE: `${prefix} app role remove`,
|
|
13
|
+
APP_SET: `${prefix} app set`,
|
|
14
14
|
APPROLEASSIGNMENT_ADD: `${prefix} approleassignment add`,
|
|
15
15
|
APPROLEASSIGNMENT_LIST: `${prefix} approleassignment list`,
|
|
16
16
|
APPROLEASSIGNMENT_REMOVE: `${prefix} approleassignment remove`,
|