@pnp/cli-microsoft365 10.8.0-beta.708bf27 → 10.8.0-beta.a1c69a6
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 +2 -1
- package/README.md +3 -1
- package/allCommands.json +1 -1
- package/allCommandsFull.json +1 -1
- package/dist/Auth.js +82 -22
- package/dist/cli/cli.js +1 -1
- package/dist/config.js +1 -0
- package/dist/m365/adaptivecard/commands/adaptivecard-send.js +54 -67
- package/dist/m365/app/commands/app-get.js +5 -2
- package/dist/m365/app/commands/app-open.js +9 -22
- package/dist/m365/app/commands/permission/permission-add.js +18 -30
- package/dist/m365/app/commands/permission/permission-list.js +5 -2
- package/dist/m365/base/AppCommand.js +9 -25
- package/dist/m365/booking/commands/business/business-get.js +18 -25
- package/dist/m365/cli/commands/app/app-reconsent.js +103 -0
- package/dist/m365/cli/commands.js +1 -0
- package/dist/m365/commands/login.js +1 -1
- package/dist/m365/commands/setup.js +1 -2
- package/dist/m365/context/commands/context-remove.js +12 -25
- package/dist/m365/context/commands/option/option-remove.js +11 -25
- package/dist/m365/entra/commands/organization/organization-list.js +51 -0
- package/dist/m365/entra/commands.js +1 -0
- package/dist/m365/graph/commands/directoryextension/directoryextension-list.js +74 -0
- package/dist/m365/graph/commands/openextension/openextension-set.js +107 -0
- package/dist/m365/graph/commands.js +2 -0
- package/dist/m365/spe/commands/container/container-add.js +85 -0
- package/dist/m365/spe/commands/container/container-list.js +2 -9
- package/dist/m365/spe/commands/container/container-permission-list.js +52 -0
- package/dist/m365/spe/commands/container/container-recyclebinitem-list.js +62 -0
- package/dist/m365/spe/commands/container/container-remove.js +99 -0
- package/dist/m365/spe/commands/containertype/containertype-add.js +11 -11
- package/dist/m365/spe/commands/containertype/containertype-get.js +28 -32
- package/dist/m365/spe/commands/containertype/containertype-list.js +14 -4
- package/dist/m365/spe/commands/containertype/containertype-remove.js +81 -0
- package/dist/m365/spe/commands.js +6 -1
- package/dist/m365/spo/commands/list/list-get.js +12 -6
- package/dist/m365/spo/commands/page/page-section-add.js +20 -23
- package/dist/m365/spp/commands/model/model-apply.js +130 -0
- package/dist/m365/spp/commands/model/model-get.js +7 -24
- package/dist/m365/spp/commands/model/model-list.js +1 -1
- package/dist/m365/spp/commands/model/model-remove.js +1 -1
- package/dist/m365/spp/commands.js +1 -0
- package/dist/utils/entraServicePrincipal.js +11 -0
- package/dist/utils/formatting.js +12 -0
- package/dist/utils/spe.js +77 -0
- package/dist/utils/spo.js +0 -18
- package/dist/utils/spp.js +59 -1
- package/dist/utils/zod.js +26 -1
- package/docs/docs/cmd/adaptivecard/adaptivecard-send.mdx +1 -1
- package/docs/docs/cmd/cli/app/app-reconsent.mdx +63 -0
- package/docs/docs/cmd/entra/organization/organization-list.mdx +154 -0
- package/docs/docs/cmd/graph/directoryextension/directoryextension-list.mdx +135 -0
- package/docs/docs/cmd/graph/openextension/openextension-set.mdx +97 -0
- package/docs/docs/cmd/spe/container/container-activate.mdx +0 -2
- package/docs/docs/cmd/spe/container/container-add.mdx +128 -0
- package/docs/docs/cmd/spe/container/container-permission-list.mdx +90 -0
- package/docs/docs/cmd/spe/container/container-recyclebinitem-list.mdx +96 -0
- package/docs/docs/cmd/spe/container/container-remove.mdx +65 -0
- package/docs/docs/cmd/spe/containertype/containertype-add.mdx +9 -1
- package/docs/docs/cmd/spe/containertype/containertype-get.mdx +8 -0
- package/docs/docs/cmd/spe/containertype/containertype-list.mdx +8 -0
- package/docs/docs/cmd/spe/containertype/containertype-remove.mdx +52 -0
- package/docs/docs/cmd/spo/field/field-get.mdx +0 -1
- package/docs/docs/cmd/spo/list/list-get.mdx +12 -3
- package/docs/docs/cmd/spp/model/model-apply.mdx +79 -0
- package/npm-shrinkwrap.json +894 -477
- package/package.json +11 -11
- package/dist/m365/spe/ContainerProperties.js +0 -2
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import GraphCommand from '../../../base/GraphCommand.js';
|
|
2
|
+
import commands from '../../commands.js';
|
|
3
|
+
import auth from '../../../../Auth.js';
|
|
4
|
+
import config from '../../../../config.js';
|
|
5
|
+
import { urlUtil } from '../../../../utils/urlUtil.js';
|
|
6
|
+
import request from '../../../../request.js';
|
|
7
|
+
import { cli } from '../../../../cli/cli.js';
|
|
8
|
+
import { settingsNames } from '../../../../settingsNames.js';
|
|
9
|
+
import { browserUtil } from '../../../../utils/browserUtil.js';
|
|
10
|
+
import { entraApp } from '../../../../utils/entraApp.js';
|
|
11
|
+
import { entraServicePrincipal } from '../../../../utils/entraServicePrincipal.js';
|
|
12
|
+
class CliAppReconsentCommand extends GraphCommand {
|
|
13
|
+
get name() {
|
|
14
|
+
return commands.APP_RECONSENT;
|
|
15
|
+
}
|
|
16
|
+
get description() {
|
|
17
|
+
return 'Reconsent all permission scopes used in CLI for Microsoft 365';
|
|
18
|
+
}
|
|
19
|
+
async commandAction(logger) {
|
|
20
|
+
try {
|
|
21
|
+
const appId = auth.connection.appId;
|
|
22
|
+
if (this.verbose) {
|
|
23
|
+
await logger.logToStderr(`Adding all missing permission scopes used in CLI for Microsoft 365 to application with ID '${appId}'...`);
|
|
24
|
+
}
|
|
25
|
+
const application = await entraApp.getAppRegistrationByAppId(appId, ['requiredResourceAccess', 'id']);
|
|
26
|
+
await this.addCliAppScopes(logger, application.requiredResourceAccess);
|
|
27
|
+
await this.updateAppScopes(logger, application.id, application.requiredResourceAccess);
|
|
28
|
+
const consentUrl = `https://login.microsoftonline.com/${auth.connection.tenant}/adminconsent?client_id=${appId}`;
|
|
29
|
+
await logger.log(`To consent to the new scopes for your Microsoft Entra application registration, please navigate to the following URL: ${consentUrl}`);
|
|
30
|
+
if (cli.getSettingWithDefaultValue(settingsNames.autoOpenLinksInBrowser, false)) {
|
|
31
|
+
await browserUtil.open(consentUrl);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
this.handleRejectedODataJsonPromise(err);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async addCliAppScopes(logger, appScopes) {
|
|
39
|
+
const allCliScopes = config.allScopes;
|
|
40
|
+
const servicePrincipals = await entraServicePrincipal.getServicePrincipals('displayName,appId,oauth2PermissionScopes,servicePrincipalNames');
|
|
41
|
+
if (this.verbose) {
|
|
42
|
+
await logger.logToStderr(`Verifying if all ${allCliScopes.length} permission scopes are present in the app registration...`);
|
|
43
|
+
}
|
|
44
|
+
for (const cliScope of allCliScopes) {
|
|
45
|
+
// Extract service principal name and scope from the URL string
|
|
46
|
+
const spName = urlUtil.removeTrailingSlashes(cliScope.substring(0, cliScope.lastIndexOf('/')));
|
|
47
|
+
const scopeName = cliScope.substring(cliScope.lastIndexOf('/') + 1);
|
|
48
|
+
// Find the matching service principal by name
|
|
49
|
+
const servicePrincipal = servicePrincipals.find(sp => sp.servicePrincipalNames?.some(name => urlUtil.removeTrailingSlashes(name).toLowerCase() === spName.toLowerCase()));
|
|
50
|
+
if (!servicePrincipal) {
|
|
51
|
+
if (this.verbose) {
|
|
52
|
+
await logger.logToStderr(`Service principal with name '${spName}' not found. Skipping scope '${scopeName}'.`);
|
|
53
|
+
}
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
// Find the matching scope in the service principal
|
|
57
|
+
const scope = servicePrincipal.oauth2PermissionScopes?.find(s => s.value?.toLowerCase() === scopeName.toLowerCase());
|
|
58
|
+
if (!scope) {
|
|
59
|
+
if (this.verbose) {
|
|
60
|
+
await logger.logToStderr(`Scope '${scopeName}' not found in service principal '${spName}'. Skipping scope...`);
|
|
61
|
+
}
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
// Check if the service principal is already present in the app registration
|
|
65
|
+
let appSp = appScopes.find(sp => sp.resourceAppId?.toLowerCase() === servicePrincipal.appId.toLowerCase());
|
|
66
|
+
if (!appSp) {
|
|
67
|
+
// Service principal is not present in the app registration, let's add it
|
|
68
|
+
appSp = {
|
|
69
|
+
resourceAppId: servicePrincipal.appId,
|
|
70
|
+
resourceAccess: []
|
|
71
|
+
};
|
|
72
|
+
appScopes.push(appSp);
|
|
73
|
+
}
|
|
74
|
+
// Check if the scope is already present in the app registration
|
|
75
|
+
const isAppScopePresent = appSp.resourceAccess.some(s => s.id?.toLowerCase() === scope.id.toLowerCase());
|
|
76
|
+
if (!isAppScopePresent) {
|
|
77
|
+
// Scope is not present in the app registration, let's add it
|
|
78
|
+
appSp.resourceAccess.push({
|
|
79
|
+
id: scope.id,
|
|
80
|
+
type: 'Scope'
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async updateAppScopes(logger, appId, appScopes) {
|
|
86
|
+
if (this.verbose) {
|
|
87
|
+
await logger.logToStderr(`Updating permission scopes of application with ID '${appId}'...`);
|
|
88
|
+
}
|
|
89
|
+
const requestOptions = {
|
|
90
|
+
url: `${this.resource}/v1.0/applications/${appId}`,
|
|
91
|
+
headers: {
|
|
92
|
+
accept: 'application/json;odata.metadata=none'
|
|
93
|
+
},
|
|
94
|
+
responseType: 'json',
|
|
95
|
+
data: {
|
|
96
|
+
requiredResourceAccess: appScopes
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
await request.patch(requestOptions);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export default new CliAppReconsentCommand();
|
|
103
|
+
//# sourceMappingURL=app-reconsent.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const prefix = 'cli';
|
|
2
2
|
export default {
|
|
3
|
+
APP_RECONSENT: `${prefix} app reconsent`,
|
|
3
4
|
COMPLETION_CLINK_UPDATE: `${prefix} completion clink update`,
|
|
4
5
|
COMPLETION_PWSH_SETUP: `${prefix} completion pwsh setup`,
|
|
5
6
|
COMPLETION_PWSH_UPDATE: `${prefix} completion pwsh update`,
|
|
@@ -37,7 +37,7 @@ class LoginCommand extends Command {
|
|
|
37
37
|
}
|
|
38
38
|
getRefinedSchema(schema) {
|
|
39
39
|
return schema
|
|
40
|
-
.refine(options => typeof options.appId !== 'undefined' || cli.getClientId() || options.authType === 'identity', {
|
|
40
|
+
.refine(options => typeof options.appId !== 'undefined' || cli.getClientId() || options.authType === 'identity' || options.authType === 'federatedIdentity', {
|
|
41
41
|
message: `appId is required. TIP: use the "m365 setup" command to configure the default appId.`,
|
|
42
42
|
path: ['appId']
|
|
43
43
|
})
|
|
@@ -18,7 +18,6 @@ import { validation } from '../../utils/validation.js';
|
|
|
18
18
|
import AnonymousCommand from '../base/AnonymousCommand.js';
|
|
19
19
|
import commands from './commands.js';
|
|
20
20
|
import { interactivePreset, powerShellPreset, scriptingPreset } from './setupPresets.js';
|
|
21
|
-
import { optionsUtils } from '../../utils/optionsUtils.js';
|
|
22
21
|
export var CliUsageMode;
|
|
23
22
|
(function (CliUsageMode) {
|
|
24
23
|
CliUsageMode["Interactively"] = "interactively";
|
|
@@ -228,7 +227,7 @@ class SetupCommand extends AnonymousCommand {
|
|
|
228
227
|
});
|
|
229
228
|
const appInfo = await entraApp.createAppRegistration({
|
|
230
229
|
options,
|
|
231
|
-
unknownOptions:
|
|
230
|
+
unknownOptions: {},
|
|
232
231
|
apis,
|
|
233
232
|
logger,
|
|
234
233
|
verbose: this.verbose,
|
|
@@ -1,14 +1,15 @@
|
|
|
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 _ContextRemoveCommand_instances, _ContextRemoveCommand_initTelemetry, _ContextRemoveCommand_initOptions;
|
|
7
1
|
import fs from 'fs';
|
|
2
|
+
import { z } from 'zod';
|
|
8
3
|
import { cli } from '../../../cli/cli.js';
|
|
9
|
-
import { CommandError } from '../../../Command.js';
|
|
4
|
+
import { CommandError, globalOptionsZod } from '../../../Command.js';
|
|
5
|
+
import { zod } from '../../../utils/zod.js';
|
|
10
6
|
import AnonymousCommand from '../../base/AnonymousCommand.js';
|
|
11
7
|
import commands from '../commands.js';
|
|
8
|
+
const options = globalOptionsZod
|
|
9
|
+
.extend({
|
|
10
|
+
force: zod.alias('f', z.boolean().optional())
|
|
11
|
+
})
|
|
12
|
+
.strict();
|
|
12
13
|
class ContextRemoveCommand extends AnonymousCommand {
|
|
13
14
|
get name() {
|
|
14
15
|
return commands.REMOVE;
|
|
@@ -16,20 +17,17 @@ class ContextRemoveCommand extends AnonymousCommand {
|
|
|
16
17
|
get description() {
|
|
17
18
|
return 'Removes the CLI for Microsoft 365 context in the current working folder';
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
_ContextRemoveCommand_instances.add(this);
|
|
22
|
-
__classPrivateFieldGet(this, _ContextRemoveCommand_instances, "m", _ContextRemoveCommand_initTelemetry).call(this);
|
|
23
|
-
__classPrivateFieldGet(this, _ContextRemoveCommand_instances, "m", _ContextRemoveCommand_initOptions).call(this);
|
|
20
|
+
get schema() {
|
|
21
|
+
return options;
|
|
24
22
|
}
|
|
25
23
|
async commandAction(logger, args) {
|
|
26
24
|
if (args.options.force) {
|
|
27
|
-
|
|
25
|
+
this.removeContext();
|
|
28
26
|
}
|
|
29
27
|
else {
|
|
30
28
|
const result = await cli.promptForConfirmation({ message: `Are you sure you want to remove the context?` });
|
|
31
29
|
if (result) {
|
|
32
|
-
|
|
30
|
+
this.removeContext();
|
|
33
31
|
}
|
|
34
32
|
}
|
|
35
33
|
}
|
|
@@ -70,16 +68,5 @@ class ContextRemoveCommand extends AnonymousCommand {
|
|
|
70
68
|
}
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
|
-
_ContextRemoveCommand_instances = new WeakSet(), _ContextRemoveCommand_initTelemetry = function _ContextRemoveCommand_initTelemetry() {
|
|
74
|
-
this.telemetry.push((args) => {
|
|
75
|
-
Object.assign(this.telemetryProperties, {
|
|
76
|
-
force: !!args.options.force
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
}, _ContextRemoveCommand_initOptions = function _ContextRemoveCommand_initOptions() {
|
|
80
|
-
this.options.unshift({
|
|
81
|
-
option: '-f, --force'
|
|
82
|
-
});
|
|
83
|
-
};
|
|
84
71
|
export default new ContextRemoveCommand();
|
|
85
72
|
//# sourceMappingURL=context-remove.js.map
|
|
@@ -1,14 +1,16 @@
|
|
|
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 _ContextOptionRemoveCommand_instances, _ContextOptionRemoveCommand_initTelemetry, _ContextOptionRemoveCommand_initOptions;
|
|
7
1
|
import fs from 'fs';
|
|
2
|
+
import { z } from 'zod';
|
|
8
3
|
import { cli } from '../../../../cli/cli.js';
|
|
9
|
-
import { CommandError } from '../../../../Command.js';
|
|
4
|
+
import { CommandError, globalOptionsZod } from '../../../../Command.js';
|
|
5
|
+
import { zod } from '../../../../utils/zod.js';
|
|
10
6
|
import ContextCommand from '../../../base/ContextCommand.js';
|
|
11
7
|
import commands from '../../commands.js';
|
|
8
|
+
const options = globalOptionsZod
|
|
9
|
+
.extend({
|
|
10
|
+
name: zod.alias('n', z.string()),
|
|
11
|
+
force: zod.alias('f', z.boolean().optional())
|
|
12
|
+
})
|
|
13
|
+
.strict();
|
|
12
14
|
class ContextOptionRemoveCommand extends ContextCommand {
|
|
13
15
|
get name() {
|
|
14
16
|
return commands.OPTION_REMOVE;
|
|
@@ -16,11 +18,8 @@ class ContextOptionRemoveCommand extends ContextCommand {
|
|
|
16
18
|
get description() {
|
|
17
19
|
return 'Removes an already available name from local context file.';
|
|
18
20
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
_ContextOptionRemoveCommand_instances.add(this);
|
|
22
|
-
__classPrivateFieldGet(this, _ContextOptionRemoveCommand_instances, "m", _ContextOptionRemoveCommand_initOptions).call(this);
|
|
23
|
-
__classPrivateFieldGet(this, _ContextOptionRemoveCommand_instances, "m", _ContextOptionRemoveCommand_initTelemetry).call(this);
|
|
21
|
+
get schema() {
|
|
22
|
+
return options;
|
|
24
23
|
}
|
|
25
24
|
async commandAction(logger, args) {
|
|
26
25
|
if (this.verbose) {
|
|
@@ -70,18 +69,5 @@ class ContextOptionRemoveCommand extends ContextCommand {
|
|
|
70
69
|
}
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
|
-
_ContextOptionRemoveCommand_instances = new WeakSet(), _ContextOptionRemoveCommand_initTelemetry = function _ContextOptionRemoveCommand_initTelemetry() {
|
|
74
|
-
this.telemetry.push((args) => {
|
|
75
|
-
Object.assign(this.telemetryProperties, {
|
|
76
|
-
force: !!args.options.force
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
}, _ContextOptionRemoveCommand_initOptions = function _ContextOptionRemoveCommand_initOptions() {
|
|
80
|
-
this.options.unshift({
|
|
81
|
-
option: '-n, --name <name>'
|
|
82
|
-
}, {
|
|
83
|
-
option: '-f, --force'
|
|
84
|
-
});
|
|
85
|
-
};
|
|
86
72
|
export default new ContextOptionRemoveCommand();
|
|
87
73
|
//# sourceMappingURL=option-remove.js.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { globalOptionsZod } from '../../../../Command.js';
|
|
3
|
+
import { zod } from '../../../../utils/zod.js';
|
|
4
|
+
import GraphCommand from '../../../base/GraphCommand.js';
|
|
5
|
+
import commands from '../../commands.js';
|
|
6
|
+
import { odata } from '../../../../utils/odata.js';
|
|
7
|
+
const options = globalOptionsZod
|
|
8
|
+
.extend({
|
|
9
|
+
properties: zod.alias('p', z.string().optional())
|
|
10
|
+
})
|
|
11
|
+
.strict();
|
|
12
|
+
class EntraOrganizationListCommand extends GraphCommand {
|
|
13
|
+
get name() {
|
|
14
|
+
return commands.ORGANIZATION_LIST;
|
|
15
|
+
}
|
|
16
|
+
get description() {
|
|
17
|
+
return 'Lists all Microsoft Entra ID organizations';
|
|
18
|
+
}
|
|
19
|
+
defaultProperties() {
|
|
20
|
+
return ['id', 'displayName', 'tenantType'];
|
|
21
|
+
}
|
|
22
|
+
get schema() {
|
|
23
|
+
return options;
|
|
24
|
+
}
|
|
25
|
+
async commandAction(logger, args) {
|
|
26
|
+
try {
|
|
27
|
+
let url = `${this.resource}/v1.0/organization`;
|
|
28
|
+
if (args.options.properties) {
|
|
29
|
+
url += `?$select=${args.options.properties}`;
|
|
30
|
+
}
|
|
31
|
+
const requestOptions = {
|
|
32
|
+
url: url,
|
|
33
|
+
headers: {
|
|
34
|
+
accept: 'application/json;odata.metadata=none',
|
|
35
|
+
'content-type': 'application/json'
|
|
36
|
+
},
|
|
37
|
+
responseType: 'json'
|
|
38
|
+
};
|
|
39
|
+
if (args.options.verbose) {
|
|
40
|
+
await logger.logToStderr(`Retrieving organizations...`);
|
|
41
|
+
}
|
|
42
|
+
const res = await odata.getAllItems(requestOptions);
|
|
43
|
+
await logger.log(res);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
this.handleRejectedODataJsonPromise(err);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export default new EntraOrganizationListCommand();
|
|
51
|
+
//# sourceMappingURL=organization-list.js.map
|
|
@@ -83,6 +83,7 @@ export default {
|
|
|
83
83
|
OAUTH2GRANT_LIST: `${prefix} oauth2grant list`,
|
|
84
84
|
OAUTH2GRANT_REMOVE: `${prefix} oauth2grant remove`,
|
|
85
85
|
OAUTH2GRANT_SET: `${prefix} oauth2grant set`,
|
|
86
|
+
ORGANIZATION_LIST: `${prefix} organization list`,
|
|
86
87
|
PIM_ROLE_ASSIGNMENT_ADD: `${prefix} pim role assignment add`,
|
|
87
88
|
PIM_ROLE_ASSIGNMENT_LIST: `${prefix} pim role assignment list`,
|
|
88
89
|
PIM_ROLE_ASSIGNMENT_REMOVE: `${prefix} pim role assignment remove`,
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { globalOptionsZod } from '../../../../Command.js';
|
|
3
|
+
import request from '../../../../request.js';
|
|
4
|
+
import commands from '../../commands.js';
|
|
5
|
+
import GraphCommand from '../../../base/GraphCommand.js';
|
|
6
|
+
import { validation } from '../../../../utils/validation.js';
|
|
7
|
+
import { entraApp } from '../../../../utils/entraApp.js';
|
|
8
|
+
import { odata } from '../../../../utils/odata.js';
|
|
9
|
+
const options = globalOptionsZod
|
|
10
|
+
.extend({
|
|
11
|
+
appId: z.string().refine(id => validation.isValidGuid(id), id => ({
|
|
12
|
+
message: `'${id}' is not a valid GUID.`
|
|
13
|
+
})).optional(),
|
|
14
|
+
appObjectId: z.string().refine(id => validation.isValidGuid(id), id => ({
|
|
15
|
+
message: `'${id}' is not a valid GUID.`
|
|
16
|
+
})).optional(),
|
|
17
|
+
appName: z.string().optional()
|
|
18
|
+
})
|
|
19
|
+
.strict();
|
|
20
|
+
class GraphDirectoryExtensionListCommand extends GraphCommand {
|
|
21
|
+
get name() {
|
|
22
|
+
return commands.DIRECTORYEXTENSION_LIST;
|
|
23
|
+
}
|
|
24
|
+
get description() {
|
|
25
|
+
return 'Retrieves a list of directory extensions';
|
|
26
|
+
}
|
|
27
|
+
defaultProperties() {
|
|
28
|
+
return ['id', 'name', 'appDisplayName'];
|
|
29
|
+
}
|
|
30
|
+
get schema() {
|
|
31
|
+
return options;
|
|
32
|
+
}
|
|
33
|
+
getRefinedSchema(schema) {
|
|
34
|
+
return schema
|
|
35
|
+
.refine(options => ([options.appId, options.appObjectId, options.appName].filter(x => x !== undefined).length <= 1), {
|
|
36
|
+
message: 'Specify either appId, appObjectId, or appName, but not multiple.'
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async commandAction(logger, args) {
|
|
40
|
+
try {
|
|
41
|
+
if (args.options.appId || args.options.appObjectId || args.options.appName) {
|
|
42
|
+
const appObjectId = await this.getAppObjectId(args.options);
|
|
43
|
+
const endpoint = `${this.resource}/v1.0/applications/${appObjectId}/extensionProperties/`;
|
|
44
|
+
const items = await odata.getAllItems(endpoint);
|
|
45
|
+
await logger.log(items);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const requestOptions = {
|
|
49
|
+
url: `${this.resource}/v1.0/directoryObjects/getAvailableExtensionProperties`,
|
|
50
|
+
headers: {
|
|
51
|
+
'content-type': 'application/json;odata.metadata=none'
|
|
52
|
+
},
|
|
53
|
+
responseType: 'json'
|
|
54
|
+
};
|
|
55
|
+
const res = await request.post(requestOptions);
|
|
56
|
+
await logger.log(res.value);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
this.handleRejectedODataJsonPromise(err);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async getAppObjectId(options) {
|
|
64
|
+
if (options.appObjectId) {
|
|
65
|
+
return options.appObjectId;
|
|
66
|
+
}
|
|
67
|
+
if (options.appId) {
|
|
68
|
+
return (await entraApp.getAppRegistrationByAppId(options.appId, ["id"])).id;
|
|
69
|
+
}
|
|
70
|
+
return (await entraApp.getAppRegistrationByAppName(options.appName, ["id"])).id;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export default new GraphDirectoryExtensionListCommand();
|
|
74
|
+
//# sourceMappingURL=directoryextension-list.js.map
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { globalOptionsZod } from '../../../../Command.js';
|
|
3
|
+
import { zod } from '../../../../utils/zod.js';
|
|
4
|
+
import { validation } from '../../../../utils/validation.js';
|
|
5
|
+
import GraphCommand from '../../../base/GraphCommand.js';
|
|
6
|
+
import commands from '../../commands.js';
|
|
7
|
+
import request from '../../../../request.js';
|
|
8
|
+
import { optionsUtils } from '../../../../utils/optionsUtils.js';
|
|
9
|
+
const options = globalOptionsZod
|
|
10
|
+
.extend({
|
|
11
|
+
name: zod.alias('n', z.string()),
|
|
12
|
+
resourceId: zod.alias('i', z.string()),
|
|
13
|
+
resourceType: zod.alias('t', z.enum(['user', 'group', 'device', 'organization'])),
|
|
14
|
+
keepUnchangedProperties: zod.alias('k', z.boolean().optional())
|
|
15
|
+
})
|
|
16
|
+
.and(z.any());
|
|
17
|
+
class GraphOpenExtensionSetCommand extends GraphCommand {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(...arguments);
|
|
20
|
+
this.commandOptions = ['keepUnchangedProperties', 'resourceType', 'resourceId', 'name'];
|
|
21
|
+
this.defaultOpenExtensionProperties = ['id', 'extensionName'];
|
|
22
|
+
}
|
|
23
|
+
get name() {
|
|
24
|
+
return commands.OPENEXTENSION_SET;
|
|
25
|
+
}
|
|
26
|
+
get description() {
|
|
27
|
+
return 'Updates an open extension for a resource';
|
|
28
|
+
}
|
|
29
|
+
get schema() {
|
|
30
|
+
return options;
|
|
31
|
+
}
|
|
32
|
+
getRefinedSchema(schema) {
|
|
33
|
+
return schema
|
|
34
|
+
.refine(options => options.resourceType !== 'group' && options.resourceType !== 'device' && options.resourceType !== 'organization' || (options.resourceId && validation.isValidGuid(options.resourceId)), options => ({
|
|
35
|
+
message: `The '${options.resourceId}' must be a valid GUID`,
|
|
36
|
+
path: ['resourceId']
|
|
37
|
+
}))
|
|
38
|
+
.refine(options => options.resourceType !== 'user' || (options.resourceId && (validation.isValidGuid(options.resourceId) || validation.isValidUserPrincipalName(options.resourceId))), options => ({
|
|
39
|
+
message: `The '${options.resourceId}' must be a valid GUID or user principal name`,
|
|
40
|
+
path: ['resourceId']
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
async commandAction(logger, args) {
|
|
44
|
+
try {
|
|
45
|
+
const currentExtension = await this.getOpenExtension(logger, args);
|
|
46
|
+
const currentExtensionNames = Object.getOwnPropertyNames(currentExtension);
|
|
47
|
+
const requestBody = {};
|
|
48
|
+
requestBody["@odata.type"] = '#microsoft.graph.openTypeExtension';
|
|
49
|
+
const unknownOptions = optionsUtils.getUnknownOptions(args.options, this.options);
|
|
50
|
+
const unknownOptionsNames = Object.getOwnPropertyNames(unknownOptions);
|
|
51
|
+
unknownOptionsNames.forEach(async (option) => {
|
|
52
|
+
if (this.commandOptions.includes(option)) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const value = unknownOptions[option];
|
|
56
|
+
if (value === "") {
|
|
57
|
+
requestBody[option] = null;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
try {
|
|
61
|
+
const jsonObject = JSON.parse(value);
|
|
62
|
+
requestBody[option] = jsonObject;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
requestBody[option] = value;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
currentExtensionNames.forEach(async (name) => {
|
|
70
|
+
if (!unknownOptionsNames.includes(name) && (args.options.keepUnchangedProperties || this.defaultOpenExtensionProperties.includes(name))) {
|
|
71
|
+
requestBody[name] = currentExtension[name];
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
const requestOptions = {
|
|
75
|
+
url: `${this.resource}/v1.0/${args.options.resourceType}${args.options.resourceType === 'organization' ? '' : 's'}/${args.options.resourceId}/extensions/${args.options.name}`,
|
|
76
|
+
headers: {
|
|
77
|
+
accept: 'application/json;odata.metadata=none',
|
|
78
|
+
'content-type': 'application/json'
|
|
79
|
+
},
|
|
80
|
+
data: requestBody,
|
|
81
|
+
responseType: 'json'
|
|
82
|
+
};
|
|
83
|
+
if (args.options.verbose) {
|
|
84
|
+
await logger.logToStderr(`Updating open extension of the ${args.options.resourceType} with id '${args.options.resourceId}'...`);
|
|
85
|
+
}
|
|
86
|
+
await request.patch(requestOptions);
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
this.handleRejectedODataJsonPromise(err);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async getOpenExtension(logger, args) {
|
|
93
|
+
if (this.verbose) {
|
|
94
|
+
await logger.logToStderr(`Retrieving open extension for resource ${args.options.resourceId}...`);
|
|
95
|
+
}
|
|
96
|
+
const requestOptions = {
|
|
97
|
+
url: `${this.resource}/v1.0/${args.options.resourceType}${args.options.resourceType === 'organization' ? '' : 's'}/${args.options.resourceId}/extensions/${args.options.name}`,
|
|
98
|
+
headers: {
|
|
99
|
+
accept: 'application/json;odata.metadata=none'
|
|
100
|
+
},
|
|
101
|
+
responseType: 'json'
|
|
102
|
+
};
|
|
103
|
+
return await request.get(requestOptions);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
export default new GraphOpenExtensionSetCommand();
|
|
107
|
+
//# sourceMappingURL=openextension-set.js.map
|
|
@@ -3,11 +3,13 @@ export default {
|
|
|
3
3
|
CHANGELOG_LIST: `${prefix} changelog list`,
|
|
4
4
|
DIRECTORYEXTENSION_ADD: `${prefix} directoryextension add`,
|
|
5
5
|
DIRECTORYEXTENSION_GET: `${prefix} directoryextension get`,
|
|
6
|
+
DIRECTORYEXTENSION_LIST: `${prefix} directoryextension list`,
|
|
6
7
|
DIRECTORYEXTENSION_REMOVE: `${prefix} directoryextension remove`,
|
|
7
8
|
OPENEXTENSION_ADD: `${prefix} openextension add`,
|
|
8
9
|
OPENEXTENSION_GET: `${prefix} openextension get`,
|
|
9
10
|
OPENEXTENSION_LIST: `${prefix} openextension list`,
|
|
10
11
|
OPENEXTENSION_REMOVE: `${prefix} openextension remove`,
|
|
12
|
+
OPENEXTENSION_SET: `${prefix} openextension set`,
|
|
11
13
|
SCHEMAEXTENSION_ADD: `${prefix} schemaextension add`,
|
|
12
14
|
SCHEMAEXTENSION_GET: `${prefix} schemaextension get`,
|
|
13
15
|
SCHEMAEXTENSION_LIST: `${prefix} schemaextension list`,
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { globalOptionsZod } from '../../../../Command.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { zod } from '../../../../utils/zod.js';
|
|
4
|
+
import commands from '../../commands.js';
|
|
5
|
+
import { validation } from '../../../../utils/validation.js';
|
|
6
|
+
import { spe } from '../../../../utils/spe.js';
|
|
7
|
+
import { spo } from '../../../../utils/spo.js';
|
|
8
|
+
import GraphCommand from '../../../base/GraphCommand.js';
|
|
9
|
+
import request from '../../../../request.js';
|
|
10
|
+
const options = globalOptionsZod
|
|
11
|
+
.extend({
|
|
12
|
+
name: zod.alias('n', z.string()),
|
|
13
|
+
description: zod.alias('d', z.string()).optional(),
|
|
14
|
+
containerTypeId: z.string()
|
|
15
|
+
.refine(id => validation.isValidGuid(id), id => ({
|
|
16
|
+
message: `'${id}' is not a valid GUID.`
|
|
17
|
+
})).optional(),
|
|
18
|
+
containerTypeName: z.string().optional(),
|
|
19
|
+
ocrEnabled: z.boolean().optional(),
|
|
20
|
+
itemMajorVersionLimit: z.number()
|
|
21
|
+
.refine(numb => validation.isValidPositiveInteger(numb), numb => ({
|
|
22
|
+
message: `'${numb}' is not a valid positive integer.`
|
|
23
|
+
})).optional(),
|
|
24
|
+
itemVersioningEnabled: z.boolean().optional()
|
|
25
|
+
})
|
|
26
|
+
.strict();
|
|
27
|
+
class SpeContainerAddCommand extends GraphCommand {
|
|
28
|
+
get name() {
|
|
29
|
+
return commands.CONTAINER_ADD;
|
|
30
|
+
}
|
|
31
|
+
get description() {
|
|
32
|
+
return 'Creates a new container';
|
|
33
|
+
}
|
|
34
|
+
get schema() {
|
|
35
|
+
return options;
|
|
36
|
+
}
|
|
37
|
+
getRefinedSchema(schema) {
|
|
38
|
+
return schema
|
|
39
|
+
.refine((options) => [options.containerTypeId, options.containerTypeName].filter(o => o !== undefined).length === 1, {
|
|
40
|
+
message: 'Use one of the following options: containerTypeId or containerTypeName.'
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
async commandAction(logger, args) {
|
|
44
|
+
try {
|
|
45
|
+
const containerTypeId = await this.getContainerTypeId(args.options, logger);
|
|
46
|
+
if (this.verbose) {
|
|
47
|
+
await logger.logToStderr(`Creating container with name '${args.options.name}'...`);
|
|
48
|
+
}
|
|
49
|
+
const requestOptions = {
|
|
50
|
+
url: `${this.resource}/v1.0/storage/fileStorage/containers`,
|
|
51
|
+
headers: {
|
|
52
|
+
accept: 'application/json;odata.metadata=none'
|
|
53
|
+
},
|
|
54
|
+
responseType: 'json',
|
|
55
|
+
data: {
|
|
56
|
+
displayName: args.options.name,
|
|
57
|
+
description: args.options.description,
|
|
58
|
+
containerTypeId: containerTypeId,
|
|
59
|
+
settings: {
|
|
60
|
+
isOcrEnabled: args.options.ocrEnabled,
|
|
61
|
+
itemMajorVersionLimit: args.options.itemMajorVersionLimit,
|
|
62
|
+
isItemVersioningEnabled: args.options.itemVersioningEnabled
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const container = await request.post(requestOptions);
|
|
67
|
+
await logger.log(container);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
this.handleRejectedODataJsonPromise(err);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async getContainerTypeId(options, logger) {
|
|
74
|
+
if (options.containerTypeId) {
|
|
75
|
+
return options.containerTypeId;
|
|
76
|
+
}
|
|
77
|
+
if (this.verbose) {
|
|
78
|
+
await logger.logToStderr(`Getting container type with name '${options.containerTypeName}'...`);
|
|
79
|
+
}
|
|
80
|
+
const adminUrl = await spo.getSpoAdminUrl(logger, this.verbose);
|
|
81
|
+
return spe.getContainerTypeIdByName(adminUrl, options.containerTypeName);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export default new SpeContainerAddCommand();
|
|
85
|
+
//# sourceMappingURL=container-add.js.map
|
|
@@ -9,6 +9,7 @@ import { odata } from '../../../../utils/odata.js';
|
|
|
9
9
|
import { validation } from '../../../../utils/validation.js';
|
|
10
10
|
import GraphCommand from '../../../base/GraphCommand.js';
|
|
11
11
|
import commands from '../../commands.js';
|
|
12
|
+
import { spe } from '../../../../utils/spe.js';
|
|
12
13
|
import { spo } from '../../../../utils/spo.js';
|
|
13
14
|
class SpeContainerListCommand extends GraphCommand {
|
|
14
15
|
get name() {
|
|
@@ -47,15 +48,7 @@ class SpeContainerListCommand extends GraphCommand {
|
|
|
47
48
|
return options.containerTypeId;
|
|
48
49
|
}
|
|
49
50
|
const spoAdminUrl = await spo.getSpoAdminUrl(logger, this.debug);
|
|
50
|
-
|
|
51
|
-
// Get id of the container type by name
|
|
52
|
-
const containerType = containerTypes.find(c => c.DisplayName === options.containerTypeName);
|
|
53
|
-
if (!containerType) {
|
|
54
|
-
throw new Error(`Container type with name ${options.containerTypeName} not found`);
|
|
55
|
-
}
|
|
56
|
-
// The value is returned as "/Guid(073269af-f1d2-042d-2ef5-5bdd6ac83115)/". We need to extract the GUID from it.
|
|
57
|
-
const containerTypeValue = containerType.ContainerTypeId.toString();
|
|
58
|
-
return containerTypeValue.substring(containerTypeValue.indexOf('(') + 1, containerTypeValue.lastIndexOf(')'));
|
|
51
|
+
return spe.getContainerTypeIdByName(spoAdminUrl, options.containerTypeName);
|
|
59
52
|
}
|
|
60
53
|
}
|
|
61
54
|
_SpeContainerListCommand_instances = new WeakSet(), _SpeContainerListCommand_initTelemetry = function _SpeContainerListCommand_initTelemetry() {
|