@pnp/cli-microsoft365 10.3.0-beta.d1b978f → 10.3.0-beta.df85113

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/allCommands.json +1 -1
  3. package/allCommandsFull.json +1 -1
  4. package/dist/config.js +2 -1
  5. package/dist/m365/entra/commands/app/app-add.js +3 -0
  6. package/dist/m365/entra/commands/pim/pim-role-assignment-remove.js +186 -0
  7. package/dist/m365/entra/commands/roledefinition/roledefinition-add.js +58 -0
  8. package/dist/m365/entra/commands/roledefinition/roledefinition-set.js +84 -0
  9. package/dist/m365/entra/commands/rolepermission/rolepermission-list.js +42 -0
  10. package/dist/m365/entra/commands.js +4 -0
  11. package/dist/m365/exo/commands/approleassignment/approleassignment-add.js +235 -0
  12. package/dist/m365/exo/commands.js +5 -0
  13. package/dist/m365/outlook/commands/mailbox/mailbox-settings-set.js +163 -0
  14. package/dist/m365/outlook/commands.js +1 -0
  15. package/dist/m365/pp/commands/website/website-get.js +60 -0
  16. package/dist/m365/pp/commands.js +2 -1
  17. package/dist/m365/spe/commands/container/container-activate.js +50 -0
  18. package/dist/m365/spe/commands.js +1 -0
  19. package/dist/m365/spo/commands/folder/folder-roleassignment-add.js +0 -13
  20. package/dist/m365/spo/commands/list/list-defaultvalue-clear.js +184 -0
  21. package/dist/m365/spo/commands/list/list-defaultvalue-remove.js +181 -0
  22. package/dist/m365/spo/commands/list/list-defaultvalue-set.js +210 -0
  23. package/dist/m365/spo/commands.js +3 -0
  24. package/dist/m365/tenant/commands/people/people-pronouns-set.js +46 -0
  25. package/dist/m365/tenant/commands/report/report-settings-set.js +47 -0
  26. package/dist/m365/tenant/commands.js +2 -0
  27. package/dist/utils/customAppScope.js +29 -0
  28. package/dist/utils/entraServicePrincipal.js +46 -0
  29. package/dist/utils/powerPlatform.js +38 -0
  30. package/dist/utils/roleDefinition.js +23 -0
  31. package/dist/utils/validation.js +4 -0
  32. package/docs/docs/cmd/entra/app/app-add.mdx +1 -1
  33. package/docs/docs/cmd/entra/pim/pim-role-assignment-remove.mdx +197 -0
  34. package/docs/docs/cmd/entra/roledefinition/roledefinition-add.mdx +131 -0
  35. package/docs/docs/cmd/entra/roledefinition/roledefinition-set.mdx +64 -0
  36. package/docs/docs/cmd/entra/rolepermission/rolepermission-list.mdx +162 -0
  37. package/docs/docs/cmd/exo/approleassignment/approleassignment-add.mdx +170 -0
  38. package/docs/docs/cmd/outlook/mailbox/mailbox-settings-set.mdx +166 -0
  39. package/docs/docs/cmd/pp/website/website-get.mdx +153 -0
  40. package/docs/docs/cmd/spe/container/container-activate.mdx +34 -0
  41. package/docs/docs/cmd/spo/list/list-defaultvalue-clear.mdx +62 -0
  42. package/docs/docs/cmd/spo/list/list-defaultvalue-remove.mdx +62 -0
  43. package/docs/docs/cmd/spo/list/list-defaultvalue-set.mdx +112 -0
  44. package/docs/docs/cmd/tenant/people/people-pronouns-set.mdx +82 -0
  45. package/docs/docs/cmd/tenant/report/report-settings-set.mdx +32 -0
  46. package/npm-shrinkwrap.json +54 -74
  47. package/package.json +9 -9
package/dist/config.js CHANGED
@@ -25,6 +25,7 @@ export default {
25
25
  'https://graph.microsoft.com/Mail.Read.Shared',
26
26
  'https://graph.microsoft.com/Mail.ReadWrite',
27
27
  'https://graph.microsoft.com/Mail.Send',
28
+ 'https://graph.microsoft.com/MailboxSettings.ReadWrite',
28
29
  'https://graph.microsoft.com/Notes.ReadWrite.All',
29
30
  'https://graph.microsoft.com/OnlineMeetingArtifact.Read.All',
30
31
  'https://graph.microsoft.com/OnlineMeetings.ReadWrite',
@@ -33,7 +34,7 @@ export default {
33
34
  'https://graph.microsoft.com/Place.Read.All',
34
35
  'https://graph.microsoft.com/Policy.Read.All',
35
36
  'https://graph.microsoft.com/RecordsManagement.ReadWrite.All',
36
- 'https://graph.microsoft.com/Reports.Read.All',
37
+ 'https://graph.microsoft.com/Reports.ReadWrite.All',
37
38
  'https://graph.microsoft.com/RoleAssignmentSchedule.ReadWrite.Directory',
38
39
  'https://graph.microsoft.com/RoleEligibilitySchedule.Read.Directory',
39
40
  'https://graph.microsoft.com/SecurityEvents.Read.All',
@@ -476,6 +476,9 @@ _a = EntraAppAddCommand, _EntraAppAddCommand_instances = new WeakSet(), _EntraAp
476
476
  if (args.options.redirectUris && !args.options.platform) {
477
477
  return `When you specify redirectUris you also need to specify platform`;
478
478
  }
479
+ if (args.options.platform && ['spa', 'web', 'publicClient'].indexOf(args.options.platform) > -1 && !args.options.redirectUris) {
480
+ return `When you use platform spa, web or publicClient, you'll need to specify redirectUris`;
481
+ }
479
482
  if (args.options.certificateFile && args.options.certificateBase64Encoded) {
480
483
  return 'Specify either certificateFile or certificateBase64Encoded but not both';
481
484
  }
@@ -0,0 +1,186 @@
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 _EntraPimRoleAssignmentRemoveCommand_instances, _EntraPimRoleAssignmentRemoveCommand_initTelemetry, _EntraPimRoleAssignmentRemoveCommand_initOptions, _EntraPimRoleAssignmentRemoveCommand_initValidators, _EntraPimRoleAssignmentRemoveCommand_initOptionSets, _EntraPimRoleAssignmentRemoveCommand_initTypes;
7
+ import request from '../../../../request.js';
8
+ import GraphCommand from '../../../base/GraphCommand.js';
9
+ import commands from '../../commands.js';
10
+ import { roleDefinition } from '../../../../utils/roleDefinition.js';
11
+ import { validation } from '../../../../utils/validation.js';
12
+ import { entraUser } from '../../../../utils/entraUser.js';
13
+ import { entraGroup } from '../../../../utils/entraGroup.js';
14
+ import { accessToken } from '../../../../utils/accessToken.js';
15
+ import auth from '../../../../Auth.js';
16
+ class EntraPimRoleAssignmentRemoveCommand extends GraphCommand {
17
+ get name() {
18
+ return commands.PIM_ROLE_ASSIGNMENT_REMOVE;
19
+ }
20
+ get description() {
21
+ return 'Request deactivation of an Entra role assignment for a user or group';
22
+ }
23
+ constructor() {
24
+ super();
25
+ _EntraPimRoleAssignmentRemoveCommand_instances.add(this);
26
+ __classPrivateFieldGet(this, _EntraPimRoleAssignmentRemoveCommand_instances, "m", _EntraPimRoleAssignmentRemoveCommand_initTelemetry).call(this);
27
+ __classPrivateFieldGet(this, _EntraPimRoleAssignmentRemoveCommand_instances, "m", _EntraPimRoleAssignmentRemoveCommand_initOptions).call(this);
28
+ __classPrivateFieldGet(this, _EntraPimRoleAssignmentRemoveCommand_instances, "m", _EntraPimRoleAssignmentRemoveCommand_initValidators).call(this);
29
+ __classPrivateFieldGet(this, _EntraPimRoleAssignmentRemoveCommand_instances, "m", _EntraPimRoleAssignmentRemoveCommand_initOptionSets).call(this);
30
+ __classPrivateFieldGet(this, _EntraPimRoleAssignmentRemoveCommand_instances, "m", _EntraPimRoleAssignmentRemoveCommand_initTypes).call(this);
31
+ }
32
+ async commandAction(logger, args) {
33
+ const { userId, userName, groupId, groupName, ticketNumber, ticketSystem } = args.options;
34
+ try {
35
+ const token = auth.connection.accessTokens[auth.defaultResource].accessToken;
36
+ const isAppOnlyAccessToken = accessToken.isAppOnlyAccessToken(token);
37
+ if (isAppOnlyAccessToken && !userId && !userName && !groupId && !groupName) {
38
+ throw 'When running with application permissions either userId, userName, groupId or groupName is required';
39
+ }
40
+ const roleDefinitionId = await this.getRoleDefinitionId(args.options, logger);
41
+ const principalId = await this.getPrincipalId(args.options, logger);
42
+ const requestOptions = {
43
+ url: `${this.resource}/v1.0/roleManagement/directory/roleAssignmentScheduleRequests`,
44
+ headers: {
45
+ 'accept': 'application/json;odata.metadata=none'
46
+ },
47
+ responseType: 'json',
48
+ data: {
49
+ principalId: principalId,
50
+ roleDefinitionId: roleDefinitionId,
51
+ directoryScopeId: this.getDirectoryScope(args.options),
52
+ action: !userId && !userName && !groupId && !groupName ? 'selfDeactivate' : 'adminRemove',
53
+ justification: args.options.justification,
54
+ ticketInfo: {
55
+ ticketNumber: ticketNumber,
56
+ ticketSystem: ticketSystem
57
+ }
58
+ }
59
+ };
60
+ const response = await request.post(requestOptions);
61
+ await logger.log(response);
62
+ }
63
+ catch (err) {
64
+ this.handleRejectedODataJsonPromise(err);
65
+ }
66
+ }
67
+ async getRoleDefinitionId(options, logger) {
68
+ if (options.roleDefinitionId) {
69
+ return options.roleDefinitionId;
70
+ }
71
+ if (this.verbose) {
72
+ await logger.logToStderr(`Retrieving role definition by its name '${options.roleDefinitionName}'`);
73
+ }
74
+ const role = await roleDefinition.getRoleDefinitionByDisplayName(options.roleDefinitionName);
75
+ return role.id;
76
+ }
77
+ async getPrincipalId(options, logger) {
78
+ if (options.userId || options.groupId) {
79
+ return options.userId || options.groupId;
80
+ }
81
+ if (options.userName) {
82
+ if (this.verbose) {
83
+ await logger.logToStderr(`Retrieving user by its name '${options.userName}'`);
84
+ }
85
+ return await entraUser.getUserIdByUpn(options.userName);
86
+ }
87
+ else if (options.groupName) {
88
+ if (this.verbose) {
89
+ await logger.logToStderr(`Retrieving group by its name '${options.groupName}'`);
90
+ }
91
+ return await entraGroup.getGroupIdByDisplayName(options.groupName);
92
+ }
93
+ if (this.verbose) {
94
+ await logger.logToStderr(`Retrieving id of the current user`);
95
+ }
96
+ const token = auth.connection.accessTokens[auth.defaultResource].accessToken;
97
+ return accessToken.getUserIdFromAccessToken(token);
98
+ }
99
+ getDirectoryScope(options) {
100
+ if (options.administrativeUnitId) {
101
+ return `/administrativeUnits/${options.administrativeUnitId}`;
102
+ }
103
+ if (options.applicationId) {
104
+ return `/${options.applicationId}`;
105
+ }
106
+ return '/';
107
+ }
108
+ }
109
+ _EntraPimRoleAssignmentRemoveCommand_instances = new WeakSet(), _EntraPimRoleAssignmentRemoveCommand_initTelemetry = function _EntraPimRoleAssignmentRemoveCommand_initTelemetry() {
110
+ this.telemetry.push((args) => {
111
+ Object.assign(this.telemetryProperties, {
112
+ roleDefinitionName: typeof args.options.roleDefinitionName !== 'undefined',
113
+ roleDefinitionId: typeof args.options.roleDefinitionId !== 'undefined',
114
+ userId: typeof args.options.userId !== 'undefined',
115
+ userName: typeof args.options.userName !== 'undefined',
116
+ groupId: typeof args.options.groupId !== 'undefined',
117
+ groupName: typeof args.options.groupName !== 'undefined',
118
+ administrativeUnitId: typeof args.options.administrativeUnitId !== 'undefined',
119
+ applicationId: typeof args.options.applicationId !== 'undefined',
120
+ justification: typeof args.options.justification !== 'undefined',
121
+ ticketNumber: typeof args.options.ticketNumber !== 'undefined',
122
+ ticketSystem: typeof args.options.ticketSystem !== 'undefined'
123
+ });
124
+ });
125
+ }, _EntraPimRoleAssignmentRemoveCommand_initOptions = function _EntraPimRoleAssignmentRemoveCommand_initOptions() {
126
+ this.options.unshift({
127
+ option: '-n, --roleDefinitionName [roleDefinitionName]'
128
+ }, {
129
+ option: '-i, --roleDefinitionId [roleDefinitionId]'
130
+ }, {
131
+ option: "--userId [userId]"
132
+ }, {
133
+ option: "--userName [userName]"
134
+ }, {
135
+ option: "--groupId [groupId]"
136
+ }, {
137
+ option: "--groupName [groupName]"
138
+ }, {
139
+ option: "--administrativeUnitId [administrativeUnitId]"
140
+ }, {
141
+ option: "--applicationId [applicationId]"
142
+ }, {
143
+ option: "-j, --justification [justification]"
144
+ }, {
145
+ option: "--ticketNumber [ticketNumber]"
146
+ }, {
147
+ option: "--ticketSystem [ticketSystem]"
148
+ });
149
+ }, _EntraPimRoleAssignmentRemoveCommand_initValidators = function _EntraPimRoleAssignmentRemoveCommand_initValidators() {
150
+ this.validators.push(async (args) => {
151
+ if (args.options.roleDefinitionId && !validation.isValidGuid(args.options.roleDefinitionId)) {
152
+ return `${args.options.roleDefinitionId} is not a valid GUID`;
153
+ }
154
+ if (args.options.userId && !validation.isValidGuid(args.options.userId)) {
155
+ return `${args.options.userId} is not a valid GUID`;
156
+ }
157
+ if (args.options.groupId && !validation.isValidGuid(args.options.groupId)) {
158
+ return `${args.options.groupId} is not a valid GUID`;
159
+ }
160
+ if (args.options.administrativeUnitId && !validation.isValidGuid(args.options.administrativeUnitId)) {
161
+ return `${args.options.administrativeUnitId} is not a valid GUID`;
162
+ }
163
+ if (args.options.applicationId && !validation.isValidGuid(args.options.applicationId)) {
164
+ return `${args.options.applicationId} is not a valid GUID`;
165
+ }
166
+ return true;
167
+ });
168
+ }, _EntraPimRoleAssignmentRemoveCommand_initOptionSets = function _EntraPimRoleAssignmentRemoveCommand_initOptionSets() {
169
+ this.optionSets.push({ options: ['roleDefinitionName', 'roleDefinitionId'] });
170
+ this.optionSets.push({
171
+ options: ['userId', 'userName', 'groupId', 'groupName'],
172
+ runsWhen: (args) => {
173
+ return args.options.userId !== undefined || args.options.userName !== undefined || args.options.groupId !== undefined || args.options.groupName !== undefined;
174
+ }
175
+ });
176
+ this.optionSets.push({
177
+ options: ['administrativeUnitId', 'applicationId'],
178
+ runsWhen: (args) => {
179
+ return args.options.administrativeUnitId !== undefined || args.options.applicationId !== undefined;
180
+ }
181
+ });
182
+ }, _EntraPimRoleAssignmentRemoveCommand_initTypes = function _EntraPimRoleAssignmentRemoveCommand_initTypes() {
183
+ this.types.string.push('userId', 'userName', 'groupId', 'groupName', 'administrativeUnitId', 'applicationId', 'roleDefinitionName', 'roleDefinitionId', 'justification', 'ticketNumber', 'ticketSystem');
184
+ };
185
+ export default new EntraPimRoleAssignmentRemoveCommand();
186
+ //# sourceMappingURL=pim-role-assignment-remove.js.map
@@ -0,0 +1,58 @@
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 request from '../../../../request.js';
7
+ const options = globalOptionsZod
8
+ .extend({
9
+ displayName: zod.alias('n', z.string()),
10
+ allowedResourceActions: zod.alias('a', z.string().transform((value) => value.split(',').map(String))),
11
+ description: zod.alias('d', z.string().optional()),
12
+ enabled: zod.alias('e', z.boolean().optional()),
13
+ version: zod.alias('v', z.string().optional())
14
+ })
15
+ .strict();
16
+ class EntraRoleDefinitionAddCommand extends GraphCommand {
17
+ get name() {
18
+ return commands.ROLEDEFINITION_ADD;
19
+ }
20
+ get description() {
21
+ return 'Creates a custom Microsoft Entra ID role definition';
22
+ }
23
+ get schema() {
24
+ return options;
25
+ }
26
+ async commandAction(logger, args) {
27
+ if (args.options.verbose) {
28
+ await logger.logToStderr(`Creating custom role definition with name ${args.options.displayName}...`);
29
+ }
30
+ const requestOptions = {
31
+ url: `${this.resource}/v1.0/roleManagement/directory/roleDefinitions`,
32
+ headers: {
33
+ accept: 'application/json;odata.metadata=none'
34
+ },
35
+ data: {
36
+ displayName: args.options.displayName,
37
+ rolePermissions: [
38
+ {
39
+ allowedResourceActions: args.options.allowedResourceActions
40
+ }
41
+ ],
42
+ description: args.options.description,
43
+ isEnabled: args.options.enabled !== undefined ? args.options.enabled : true,
44
+ version: args.options.version
45
+ },
46
+ responseType: 'json'
47
+ };
48
+ try {
49
+ const result = await request.post(requestOptions);
50
+ await logger.log(result);
51
+ }
52
+ catch (err) {
53
+ this.handleRejectedODataJsonPromise(err);
54
+ }
55
+ }
56
+ }
57
+ export default new EntraRoleDefinitionAddCommand();
58
+ //# sourceMappingURL=roledefinition-add.js.map
@@ -0,0 +1,84 @@
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 request from '../../../../request.js';
7
+ import { roleDefinition } from '../../../../utils/roleDefinition.js';
8
+ import { validation } from '../../../../utils/validation.js';
9
+ const options = globalOptionsZod
10
+ .extend({
11
+ id: zod.alias('i', z.string().optional()),
12
+ displayName: zod.alias('n', z.string().optional()),
13
+ newDisplayName: z.string().optional(),
14
+ allowedResourceActions: zod.alias('a', z.string().optional()),
15
+ description: zod.alias('d', z.string().optional()),
16
+ enabled: zod.alias('e', z.boolean().optional()),
17
+ version: zod.alias('v', z.string().optional())
18
+ })
19
+ .strict();
20
+ class EntraRoleDefinitionSetCommand extends GraphCommand {
21
+ get name() {
22
+ return commands.ROLEDEFINITION_SET;
23
+ }
24
+ get description() {
25
+ return 'Updates a custom Microsoft Entra ID role definition';
26
+ }
27
+ get schema() {
28
+ return options;
29
+ }
30
+ getRefinedSchema(schema) {
31
+ return schema
32
+ .refine(options => !options.id !== !options.displayName, {
33
+ message: 'Specify either id or displayName, but not both'
34
+ })
35
+ .refine(options => options.id || options.displayName, {
36
+ message: 'Specify either id or displayName'
37
+ })
38
+ .refine(options => (!options.id && !options.displayName) || options.displayName || (options.id && validation.isValidGuid(options.id)), options => ({
39
+ message: `The '${options.id}' must be a valid GUID`,
40
+ path: ['id']
41
+ }))
42
+ .refine(options => Object.values([options.newDisplayName, options.description, options.allowedResourceActions, options.enabled, options.version]).filter(v => typeof v !== 'undefined').length > 0, {
43
+ message: 'Provide value for at least one of the following parameters: newDisplayName, description, allowedResourceActions, enabled or version'
44
+ });
45
+ }
46
+ async commandAction(logger, args) {
47
+ try {
48
+ let roleDefinitionId = args.options.id;
49
+ if (args.options.displayName) {
50
+ roleDefinitionId = (await roleDefinition.getRoleDefinitionByDisplayName(args.options.displayName, 'id')).id;
51
+ }
52
+ if (args.options.verbose) {
53
+ await logger.logToStderr(`Updating custom role definition with ID ${roleDefinitionId}...`);
54
+ }
55
+ const data = {
56
+ displayName: args.options.newDisplayName,
57
+ description: args.options.description,
58
+ isEnabled: args.options.enabled,
59
+ version: args.options.version
60
+ };
61
+ if (args.options.allowedResourceActions) {
62
+ data['rolePermissions'] = [
63
+ {
64
+ allowedResourceActions: args.options.allowedResourceActions.split(',')
65
+ }
66
+ ];
67
+ }
68
+ const requestOptions = {
69
+ url: `${this.resource}/v1.0/roleManagement/directory/roleDefinitions/${roleDefinitionId}`,
70
+ headers: {
71
+ accept: 'application/json;odata.metadata=none'
72
+ },
73
+ data: data,
74
+ responseType: 'json'
75
+ };
76
+ await request.patch(requestOptions);
77
+ }
78
+ catch (err) {
79
+ this.handleRejectedODataJsonPromise(err);
80
+ }
81
+ }
82
+ }
83
+ export default new EntraRoleDefinitionSetCommand();
84
+ //# sourceMappingURL=roledefinition-set.js.map
@@ -0,0 +1,42 @@
1
+ import { odata } from '../../../../utils/odata.js';
2
+ import GraphCommand from '../../../base/GraphCommand.js';
3
+ import commands from '../../commands.js';
4
+ import { z } from 'zod';
5
+ import { globalOptionsZod } from '../../../../Command.js';
6
+ import { zod } from '../../../../utils/zod.js';
7
+ const options = globalOptionsZod
8
+ .extend({
9
+ resourceNamespace: zod.alias('n', z.string()),
10
+ privileged: zod.alias('p', z.boolean().optional())
11
+ })
12
+ .strict();
13
+ class EntraRolePermissionListCommand extends GraphCommand {
14
+ get name() {
15
+ return commands.ROLEPERMISSION_LIST;
16
+ }
17
+ get description() {
18
+ return 'Lists all Microsoft Entra ID role permissions';
19
+ }
20
+ defaultProperties() {
21
+ return ['id', 'name', 'actionVerb', 'isPrivileged'];
22
+ }
23
+ get schema() {
24
+ return options;
25
+ }
26
+ async commandAction(logger, args) {
27
+ if (this.verbose) {
28
+ await logger.logToStderr('Getting Microsoft Entra ID role permissions...');
29
+ }
30
+ try {
31
+ const queryString = args.options.privileged ? '?$filter=isPrivileged eq true' : '';
32
+ const url = `${this.resource}/beta/roleManagement/directory/resourceNamespaces/${args.options.resourceNamespace}/resourceActions${queryString}`;
33
+ const results = await odata.getAllItems(url);
34
+ await logger.log(results);
35
+ }
36
+ catch (err) {
37
+ this.handleRejectedODataJsonPromise(err);
38
+ }
39
+ }
40
+ }
41
+ export default new EntraRolePermissionListCommand();
42
+ //# sourceMappingURL=rolepermission-list.js.map
@@ -84,12 +84,16 @@ export default {
84
84
  OAUTH2GRANT_SET: `${prefix} oauth2grant set`,
85
85
  PIM_ROLE_ASSIGNMENT_ADD: `${prefix} pim role assignment add`,
86
86
  PIM_ROLE_ASSIGNMENT_LIST: `${prefix} pim role assignment list`,
87
+ PIM_ROLE_ASSIGNMENT_REMOVE: `${prefix} pim role assignment remove`,
87
88
  PIM_ROLE_ASSIGNMENT_ELIGIBILITY_LIST: `${prefix} pim role assignment eligibility list`,
88
89
  PIM_ROLE_REQUEST_LIST: `${prefix} pim role request list`,
89
90
  POLICY_LIST: `${prefix} policy list`,
91
+ ROLEDEFINITION_ADD: `${prefix} roledefinition add`,
90
92
  ROLEDEFINITION_LIST: `${prefix} roledefinition list`,
91
93
  ROLEDEFINITION_GET: `${prefix} roledefinition get`,
92
94
  ROLEDEFINITION_REMOVE: `${prefix} roledefinition remove`,
95
+ ROLEDEFINITION_SET: `${prefix} roledefinition set`,
96
+ ROLEPERMISSION_LIST: `${prefix} rolepermission list`,
93
97
  SITECLASSIFICATION_DISABLE: `${prefix} siteclassification disable`,
94
98
  SITECLASSIFICATION_ENABLE: `${prefix} siteclassification enable`,
95
99
  SITECLASSIFICATION_GET: `${prefix} siteclassification get`,
@@ -0,0 +1,235 @@
1
+ import { z } from 'zod';
2
+ import { globalOptionsZod } from '../../../../Command.js';
3
+ import { roleDefinition } from '../../../../utils/roleDefinition.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 { entraUser } from '../../../../utils/entraUser.js';
9
+ import { entraGroup } from '../../../../utils/entraGroup.js';
10
+ import { entraAdministrativeUnit } from '../../../../utils/entraAdministrativeUnit.js';
11
+ import { entraServicePrincipal } from '../../../../utils/entraServicePrincipal.js';
12
+ import { zod } from '../../../../utils/zod.js';
13
+ import { customAppScope } from '../../../../utils/customAppScope.js';
14
+ const options = globalOptionsZod
15
+ .extend({
16
+ roleDefinitionId: z.string().optional(),
17
+ roleDefinitionName: z.string().optional(),
18
+ principalId: z.string().optional(),
19
+ principalName: z.string().optional(),
20
+ scope: zod.alias('s', z.enum(['tenant', 'user', 'group', 'administrativeUnit', 'custom'])),
21
+ userId: z.string().optional(),
22
+ userName: z.string().optional(),
23
+ groupId: z.string().optional(),
24
+ groupName: z.string().optional(),
25
+ administrativeUnitId: z.string().optional(),
26
+ administrativeUnitName: z.string().optional(),
27
+ customAppScopeId: z.string().optional(),
28
+ customAppScopeName: z.string().optional()
29
+ })
30
+ .strict();
31
+ class ExoAppRoleAssignmentAddCommand extends GraphCommand {
32
+ get name() {
33
+ return commands.APPROLEASSIGNMENT_ADD;
34
+ }
35
+ get description() {
36
+ return `Grant permissions to an application that's accessing data in Exchange Online and specify which mailboxes an app can access.`;
37
+ }
38
+ get schema() {
39
+ return options;
40
+ }
41
+ getRefinedSchema(schema) {
42
+ return schema
43
+ .refine(options => !options.roleDefinitionId !== !options.roleDefinitionName, {
44
+ message: 'Specify either roleDefinitionId or roleDefinitionName, but not both'
45
+ })
46
+ .refine(options => options.roleDefinitionId || options.roleDefinitionName, {
47
+ message: 'Specify either roleDefinitionId or roleDefinitionName'
48
+ })
49
+ .refine(options => (!options.roleDefinitionId && !options.roleDefinitionName) || options.roleDefinitionName || (options.roleDefinitionId && validation.isValidGuid(options.roleDefinitionId)), options => ({
50
+ message: `The '${options.roleDefinitionId}' must be a valid GUID`,
51
+ path: ['roleDefinitionId']
52
+ }))
53
+ .refine(options => !options.principalId !== !options.principalName, {
54
+ message: 'Specify either principalId or principalName, but not both'
55
+ })
56
+ .refine(options => options.principalId || options.principalName, {
57
+ message: 'Specify either principalId or principalName'
58
+ })
59
+ .refine(options => (!options.principalId && !options.principalName) || options.principalName || (options.principalId && validation.isValidGuid(options.principalId)), options => ({
60
+ message: `The '${options.principalId}' must be a valid GUID`,
61
+ path: ['principalId']
62
+ }))
63
+ .refine(options => options.scope !== 'tenant' || Object.values([options.userId, options.userName, options.groupId, options.groupName, options.administrativeUnitId, options.administrativeUnitName, options.customAppScopeId, options.customAppScopeName]).filter(v => typeof v !== 'undefined').length === 0, {
64
+ message: "When the scope is set to 'tenant' then do not specify neither userId, userName, groupId, groupName, administrativeUnitId, administrativeUnitName, customAppScopeId nor customAppScopeName",
65
+ path: ['scope']
66
+ })
67
+ .refine(options => options.scope !== 'user' || Object.values([options.groupId, options.groupName, options.administrativeUnitId, options.administrativeUnitName, options.customAppScopeId, options.customAppScopeName]).filter(v => typeof v !== 'undefined').length === 0, {
68
+ message: "When the scope is set to 'user' then do not specify groupId, groupName, administrativeUnitId, administrativeUnitName, customAppScopeId nor customAppScopeName",
69
+ path: ['scope']
70
+ })
71
+ .refine(options => options.scope !== 'user' || (!options.userId !== !options.userName), {
72
+ message: "When the scope is set to 'user' specify either userId or userName, but not both",
73
+ path: ['scope']
74
+ })
75
+ .refine(options => options.scope !== 'user' || (options.userId || options.userName), {
76
+ message: "When the scope is set to 'user' specify either userId or userName",
77
+ path: ['scope']
78
+ })
79
+ .refine(options => options.scope !== 'user' || (!options.userId && !options.userName) || options.userName || (options.userId && validation.isValidGuid(options.userId)), options => ({
80
+ message: `The '${options.userId}' must be a valid GUID`,
81
+ path: ['userId']
82
+ }))
83
+ .refine(options => options.scope !== 'user' || (!options.userId && !options.userName) || options.userId || (options.userName && validation.isValidUserPrincipalName(options.userName)), options => ({
84
+ message: `The '${options.userId}' must be a valid GUID`,
85
+ path: ['userName']
86
+ }))
87
+ .refine(options => options.scope !== 'group' || Object.values([options.userId, options.userName, options.administrativeUnitId, options.administrativeUnitName, options.customAppScopeId, options.customAppScopeName]).filter(v => typeof v !== 'undefined').length === 0, {
88
+ message: "When the scope is set to 'group' then do not specify userId, userName, administrativeUnitId, administrativeUnitName, customAppScopeId nor customAppScopeName",
89
+ path: ['scope']
90
+ })
91
+ .refine(options => options.scope !== 'group' || (!options.groupId !== !options.groupName), {
92
+ message: "When the scope is set to 'group' specify either groupId or groupName, but not both",
93
+ path: ['scope']
94
+ })
95
+ .refine(options => options.scope !== 'group' || (options.groupId || options.groupName), {
96
+ message: "When the scope is set to 'group' specify either groupId or groupName",
97
+ path: ['scope']
98
+ })
99
+ .refine(options => options.scope !== 'group' || (!options.groupId && !options.groupName) || options.groupName || (options.groupId && validation.isValidGuid(options.groupId)), options => ({
100
+ message: `The '${options.groupId}' must be a valid GUID`,
101
+ path: ['groupId']
102
+ }))
103
+ .refine(options => options.scope !== 'administrativeUnit' || Object.values([options.userId, options.userName, options.groupId, options.groupName, options.customAppScopeId, options.customAppScopeName]).filter(v => typeof v !== 'undefined').length === 0, {
104
+ message: "When the scope is set to 'administrativeUnit' then do not specify userId, userName, groupId, groupName, customAppScopeId nor customAppScopeName",
105
+ path: ['scope']
106
+ })
107
+ .refine(options => options.scope !== 'administrativeUnit' || (!options.administrativeUnitId !== !options.administrativeUnitName), {
108
+ message: "When the scope is set to 'administrativeUnit' specify either administrativeUnitId or administrativeUnitName, but not both",
109
+ path: ['scope']
110
+ })
111
+ .refine(options => options.scope !== 'administrativeUnit' || (options.administrativeUnitId || options.administrativeUnitName), {
112
+ message: "When the scope is set to 'administrativeUnit' specify either administrativeUnitId or administrativeUnitName",
113
+ path: ['scope']
114
+ })
115
+ .refine(options => options.scope !== 'administrativeUnit' || (!options.administrativeUnitId && !options.administrativeUnitName) || options.administrativeUnitName || (options.administrativeUnitId && validation.isValidGuid(options.administrativeUnitId)), options => ({
116
+ message: `The '${options.administrativeUnitId}' must be a valid GUID`,
117
+ path: ['administrativeUnitId']
118
+ }))
119
+ .refine(options => options.scope !== 'custom' || Object.values([options.userId, options.userName, options.groupId, options.groupName, options.administrativeUnitId, options.administrativeUnitName]).filter(v => typeof v !== 'undefined').length === 0, {
120
+ message: "When the scope is set to 'custom' then do not specify userId, userName, groupId, groupName, administrativeUnitId nor administrativeUnitName",
121
+ path: ['scope']
122
+ })
123
+ .refine(options => options.scope !== 'custom' || (!options.customAppScopeId !== !options.customAppScopeName), {
124
+ message: "When the scope is set to 'custom' specify either customAppScopeId or customAppScopeName, but not both",
125
+ path: ['scope']
126
+ })
127
+ .refine(options => options.scope !== 'custom' || (options.customAppScopeId || options.customAppScopeName), {
128
+ message: "When the scope is set to 'custom' specify either customAppScopeId or customAppScopeName",
129
+ path: ['scope']
130
+ })
131
+ .refine(options => options.scope !== 'custom' || (!options.customAppScopeId && !options.customAppScopeName) || options.customAppScopeName || (options.customAppScopeId && validation.isValidGuid(options.customAppScopeId)), options => ({
132
+ message: `The '${options.customAppScopeId}' must be a valid GUID`,
133
+ path: ['customAppScopeId']
134
+ }));
135
+ }
136
+ async commandAction(logger, args) {
137
+ try {
138
+ const roleDefinitionId = await this.getRoleDefinitionId(args.options, logger);
139
+ const data = {
140
+ roleDefinitionId: roleDefinitionId,
141
+ principalId: await this.getPrincipalId(args.options, logger),
142
+ directoryScopeId: await this.getDirectoryScopeId(args.options),
143
+ appScopeId: await this.getAppScopeId(args.options, logger)
144
+ };
145
+ const requestOptions = {
146
+ url: `${this.resource}/beta/roleManagement/exchange/roleAssignments`,
147
+ headers: {
148
+ accept: 'application/json;odata.metadata=none'
149
+ },
150
+ responseType: 'json',
151
+ data: data
152
+ };
153
+ const response = await request.post(requestOptions);
154
+ await logger.log(response);
155
+ }
156
+ catch (err) {
157
+ this.handleRejectedODataJsonPromise(err);
158
+ }
159
+ }
160
+ async getRoleDefinitionId(options, logger) {
161
+ if (options.roleDefinitionId) {
162
+ return options.roleDefinitionId;
163
+ }
164
+ if (this.verbose) {
165
+ await logger.logToStderr(`Retrieving role definition by its name '${options.roleDefinitionName}'`);
166
+ }
167
+ const role = await roleDefinition.getExchangeRoleDefinitionByDisplayName(options.roleDefinitionName);
168
+ return role.id;
169
+ }
170
+ async getPrincipalId(options, logger) {
171
+ if (options.principalId) {
172
+ return `/ServicePrincipals/${options.principalId}`;
173
+ }
174
+ if (this.verbose) {
175
+ await logger.logToStderr(`Retrieving service principal by its name '${options.principalName}'`);
176
+ }
177
+ const principal = await entraServicePrincipal.getServicePrincipalByAppName(options.principalName, 'id');
178
+ return `/ServicePrincipals/${principal.id}`;
179
+ }
180
+ async getDirectoryScopeId(options) {
181
+ if (options.scope === 'custom') {
182
+ return null;
183
+ }
184
+ let prefix = '/';
185
+ let resourceId = '';
186
+ switch (options.scope) {
187
+ case 'tenant':
188
+ break;
189
+ case 'user':
190
+ prefix = '/users/';
191
+ if (options.userId) {
192
+ resourceId = options.userId;
193
+ }
194
+ else if (options.userName) {
195
+ resourceId = await entraUser.getUserIdByUpn(options.userName);
196
+ }
197
+ break;
198
+ case 'group':
199
+ prefix = '/groups/';
200
+ if (options.groupId) {
201
+ resourceId = options.groupId;
202
+ }
203
+ else if (options.groupName) {
204
+ resourceId = await entraGroup.getGroupIdByDisplayName(options.groupName);
205
+ }
206
+ break;
207
+ case 'administrativeUnit':
208
+ prefix = '/administrativeUnits/';
209
+ if (options.administrativeUnitId) {
210
+ resourceId = options.administrativeUnitId;
211
+ }
212
+ else if (options.administrativeUnitName) {
213
+ const administrativeUnit = await entraAdministrativeUnit.getAdministrativeUnitByDisplayName(options.administrativeUnitName);
214
+ resourceId = administrativeUnit.id;
215
+ }
216
+ break;
217
+ }
218
+ return `${prefix}${resourceId}`;
219
+ }
220
+ async getAppScopeId(options, logger) {
221
+ if (options.scope !== 'custom') {
222
+ return null;
223
+ }
224
+ if (options.customAppScopeId) {
225
+ return options.customAppScopeId;
226
+ }
227
+ if (this.verbose) {
228
+ await logger.logToStderr(`Retrieving custom application scope by its name '${options.customAppScopeName}'`);
229
+ }
230
+ const applicationScopeId = (await customAppScope.getCustomAppScopeByDisplayName(options.customAppScopeName, 'id')).id;
231
+ return applicationScopeId;
232
+ }
233
+ }
234
+ export default new ExoAppRoleAssignmentAddCommand();
235
+ //# sourceMappingURL=approleassignment-add.js.map
@@ -0,0 +1,5 @@
1
+ const prefix = 'exo';
2
+ export default {
3
+ APPROLEASSIGNMENT_ADD: `${prefix} approleassignment add`
4
+ };
5
+ //# sourceMappingURL=commands.js.map