@pnp/cli-microsoft365 10.3.0-beta.cd20f0c → 10.3.0-beta.ea113b7

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 (41) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/README.md +11 -6
  3. package/allCommands.json +1 -1
  4. package/allCommandsFull.json +1 -1
  5. package/dist/m365/commands/login.js +6 -6
  6. package/dist/m365/entra/commands/approleassignment/approleassignment-remove.js +1 -1
  7. package/dist/m365/entra/commands/group/group-list.js +3 -2
  8. package/dist/m365/entra/commands/pim/pim-role-assignment-remove.js +186 -0
  9. package/dist/m365/entra/commands.js +1 -0
  10. package/dist/m365/exo/commands/approleassignment/approleassignment-add.js +235 -0
  11. package/dist/m365/exo/commands.js +5 -0
  12. package/dist/m365/pp/commands/website/website-get.js +60 -0
  13. package/dist/m365/pp/commands.js +2 -1
  14. package/dist/m365/spo/commands/file/file-roleassignment-add.js +26 -2
  15. package/dist/m365/spo/commands/file/file-roleassignment-remove.js +26 -2
  16. package/dist/m365/spo/commands/folder/folder-roleassignment-add.js +27 -24
  17. package/dist/m365/spo/commands/folder/folder-roleassignment-remove.js +24 -7
  18. package/dist/m365/spo/commands/list/list-defaultvalue-list.js +140 -0
  19. package/dist/m365/spo/commands/listitem/listitem-roleassignment-add.js +25 -7
  20. package/dist/m365/spo/commands/listitem/listitem-roleassignment-remove.js +22 -5
  21. package/dist/m365/spo/commands/web/web-roleassignment-add.js +22 -5
  22. package/dist/m365/spo/commands/web/web-roleassignment-remove.js +22 -5
  23. package/dist/m365/spo/commands.js +1 -0
  24. package/dist/utils/customAppScope.js +29 -0
  25. package/dist/utils/entraServicePrincipal.js +46 -0
  26. package/dist/utils/powerPlatform.js +38 -0
  27. package/dist/utils/roleDefinition.js +23 -0
  28. package/dist/utils/validation.js +4 -0
  29. package/docs/docs/cmd/entra/pim/pim-role-assignment-remove.mdx +197 -0
  30. package/docs/docs/cmd/exo/approleassignment/approleassignment-add.mdx +170 -0
  31. package/docs/docs/cmd/pp/website/website-get.mdx +153 -0
  32. package/docs/docs/cmd/spo/file/file-roleassignment-add.mdx +21 -4
  33. package/docs/docs/cmd/spo/file/file-roleassignment-remove.mdx +21 -3
  34. package/docs/docs/cmd/spo/folder/folder-roleassignment-add.mdx +15 -3
  35. package/docs/docs/cmd/spo/folder/folder-roleassignment-remove.mdx +15 -3
  36. package/docs/docs/cmd/spo/list/list-defaultvalue-list.mdx +110 -0
  37. package/docs/docs/cmd/spo/listitem/listitem-roleassignment-add.mdx +15 -3
  38. package/docs/docs/cmd/spo/listitem/listitem-roleassignment-remove.mdx +17 -5
  39. package/docs/docs/cmd/spo/web/web-roleassignment-add.mdx +15 -3
  40. package/docs/docs/cmd/spo/web/web-roleassignment-remove.mdx +15 -3
  41. package/package.json +1 -1
@@ -37,16 +37,16 @@ class LoginCommand extends Command {
37
37
  }
38
38
  getRefinedSchema(schema) {
39
39
  return schema
40
- .refine(options => typeof options.appId !== 'undefined' || cli.getClientId(), {
41
- message: `appId is required. TIP: use the "m365 setup" command to configure the default appId`,
40
+ .refine(options => typeof options.appId !== 'undefined' || cli.getClientId() || options.authType === 'identity', {
41
+ message: `appId is required. TIP: use the "m365 setup" command to configure the default appId.`,
42
42
  path: ['appId']
43
43
  })
44
44
  .refine(options => options.authType !== 'password' || options.userName, {
45
- message: 'Username is required when using password authentication',
45
+ message: 'Username is required when using password authentication.',
46
46
  path: ['userName']
47
47
  })
48
48
  .refine(options => options.authType !== 'password' || options.password, {
49
- message: 'Password is required when using password authentication',
49
+ message: 'Password is required when using password authentication.',
50
50
  path: ['password']
51
51
  })
52
52
  .refine(options => options.authType !== 'certificate' || !(options.certificateFile && options.certificateBase64Encoded), {
@@ -58,13 +58,13 @@ class LoginCommand extends Command {
58
58
  options.certificateBase64Encoded ||
59
59
  cli.getConfig().get(settingsNames.clientCertificateFile) ||
60
60
  cli.getConfig().get(settingsNames.clientCertificateBase64Encoded), {
61
- message: 'Specify either certificateFile or certificateBase64Encoded',
61
+ message: 'Specify either certificateFile or certificateBase64Encoded.',
62
62
  path: ['certificateFile']
63
63
  })
64
64
  .refine(options => options.authType !== 'secret' ||
65
65
  options.secret ||
66
66
  cli.getConfig().get(settingsNames.clientSecret), {
67
- message: 'Secret is required when using secret authentication',
67
+ message: 'Secret is required when using secret authentication.',
68
68
  path: ['secret']
69
69
  });
70
70
  }
@@ -111,7 +111,7 @@ class EntraAppRoleAssignmentRemoveCommand extends GraphCommand {
111
111
  await removeAppRoleAssignment();
112
112
  }
113
113
  else {
114
- const result = await cli.promptForConfirmation({ message: `Are you sure you want to remove the appRoleAssignment with scope ${args.options.scope} for resource ${args.options.resource}?` });
114
+ const result = await cli.promptForConfirmation({ message: `Are you sure you want to remove the appRoleAssignment with scope(s) ${args.options.scopes} for resource ${args.options.resource}?` });
115
115
  if (result) {
116
116
  await removeAppRoleAssignment();
117
117
  }
@@ -39,7 +39,8 @@ class EntraGroupListCommand extends GraphCommand {
39
39
  requestUrl += '?$filter=securityEnabled eq true and mailEnabled eq false';
40
40
  break;
41
41
  case 'distribution':
42
- requestUrl += '?$filter=securityEnabled eq false and mailEnabled eq true';
42
+ useConsistencyLevelHeader = true;
43
+ requestUrl += `?$filter=securityEnabled eq false and mailEnabled eq true and not(groupTypes/any(t:t eq 'Unified'))&$count=true`;
43
44
  break;
44
45
  case 'mailEnabledSecurity':
45
46
  useConsistencyLevelHeader = true;
@@ -77,7 +78,7 @@ class EntraGroupListCommand extends GraphCommand {
77
78
  }
78
79
  if (cli.shouldTrimOutput(args.options.output)) {
79
80
  groups.forEach((group) => {
80
- if (group.groupTypes && group.groupTypes.length > 0 && group.groupTypes[0] === 'Unified') {
81
+ if (group.groupTypes && group.groupTypes.length > 0 && group.groupTypes.includes('Unified')) {
81
82
  group.groupType = 'Microsoft 365';
82
83
  }
83
84
  else if (group.mailEnabled && group.securityEnabled) {
@@ -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
@@ -84,6 +84,7 @@ 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`,
@@ -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
@@ -0,0 +1,60 @@
1
+ import { globalOptionsZod } from '../../../../Command.js';
2
+ import { powerPlatform } from '../../../../utils/powerPlatform.js';
3
+ import { validation } from '../../../../utils/validation.js';
4
+ import { zod } from '../../../../utils/zod.js';
5
+ import PowerPlatformCommand from '../../../base/PowerPlatformCommand.js';
6
+ import commands from '../../commands.js';
7
+ import { z } from 'zod';
8
+ const options = globalOptionsZod
9
+ .extend({
10
+ url: zod.alias('u', z.string().optional()
11
+ .refine(url => url === undefined || validation.isValidPowerPagesUrl(url) === true, url => ({
12
+ message: `'${url}' is not a valid Power Pages URL.`
13
+ }))),
14
+ id: zod.alias('i', z.string().uuid().optional()),
15
+ name: zod.alias('n', z.string().optional()),
16
+ environmentName: zod.alias('e', z.string())
17
+ }).strict();
18
+ class PpWebSiteGetCommand extends PowerPlatformCommand {
19
+ get name() {
20
+ return commands.WEBSITE_GET;
21
+ }
22
+ get description() {
23
+ return 'Gets information about the specified Power Pages website.';
24
+ }
25
+ defaultProperties() {
26
+ return ['id', 'name', 'websiteUrl', 'tenantId', 'subdomain', 'type', 'status', 'siteVisibility'];
27
+ }
28
+ get schema() {
29
+ return options;
30
+ }
31
+ getRefinedSchema(schema) {
32
+ return schema
33
+ .refine(options => [options.url, options.id, options.name].filter(x => x !== undefined).length === 1, {
34
+ message: `Specify either url, id or name, but not multiple.`
35
+ });
36
+ }
37
+ async commandAction(logger, args) {
38
+ if (this.verbose) {
39
+ await logger.logToStderr(`Retrieving the website...`);
40
+ }
41
+ try {
42
+ let item = null;
43
+ if (args.options.id) {
44
+ item = await powerPlatform.getWebsiteById(args.options.environmentName, args.options.id);
45
+ }
46
+ else if (args.options.name) {
47
+ item = await powerPlatform.getWebsiteByName(args.options.environmentName, args.options.name);
48
+ }
49
+ else if (args.options.url) {
50
+ item = await powerPlatform.getWebsiteByUrl(args.options.environmentName, args.options.url);
51
+ }
52
+ await logger.log(item);
53
+ }
54
+ catch (err) {
55
+ this.handleRejectedODataJsonPromise(err);
56
+ }
57
+ }
58
+ }
59
+ export default new PpWebSiteGetCommand();
60
+ //# sourceMappingURL=website-get.js.map
@@ -33,6 +33,7 @@ export default {
33
33
  SOLUTION_PUBLISHER_LIST: `${prefix} solution publisher list`,
34
34
  SOLUTION_PUBLISHER_REMOVE: `${prefix} solution publisher remove`,
35
35
  TENANT_SETTINGS_LIST: `${prefix} tenant settings list`,
36
- TENANT_SETTINGS_SET: `${prefix} tenant settings set`
36
+ TENANT_SETTINGS_SET: `${prefix} tenant settings set`,
37
+ WEBSITE_GET: `${prefix} website get`
37
38
  };
38
39
  //# sourceMappingURL=commands.js.map
@@ -11,6 +11,7 @@ import { urlUtil } from '../../../../utils/urlUtil.js';
11
11
  import { validation } from '../../../../utils/validation.js';
12
12
  import SpoCommand from '../../../base/SpoCommand.js';
13
13
  import commands from '../../commands.js';
14
+ import { entraGroup } from '../../../../utils/entraGroup.js';
14
15
  class SpoFileRoleAssignmentAddCommand extends SpoCommand {
15
16
  get name() {
16
17
  return commands.FILE_ROLEASSIGNMENT_ADD;
@@ -42,6 +43,20 @@ class SpoFileRoleAssignmentAddCommand extends SpoCommand {
42
43
  const groupPrincipalId = await this.getGroupPrincipalId(args.options, logger);
43
44
  await this.addRoleAssignment(fileUrl, args.options.webUrl, groupPrincipalId, roleDefinitionId);
44
45
  }
46
+ else if (args.options.entraGroupId || args.options.entraGroupName) {
47
+ if (this.verbose) {
48
+ await logger.logToStderr('Retrieving group information...');
49
+ }
50
+ let group;
51
+ if (args.options.entraGroupId) {
52
+ group = await entraGroup.getGroupById(args.options.entraGroupId);
53
+ }
54
+ else {
55
+ group = await entraGroup.getGroupByDisplayName(args.options.entraGroupName);
56
+ }
57
+ const entraSiteUser = await spo.ensureEntraGroup(args.options.webUrl, group);
58
+ await this.addRoleAssignment(fileUrl, args.options.webUrl, entraSiteUser.Id, roleDefinitionId);
59
+ }
45
60
  else {
46
61
  await this.addRoleAssignment(fileUrl, args.options.webUrl, args.options.principalId, roleDefinitionId);
47
62
  }
@@ -93,6 +108,8 @@ _SpoFileRoleAssignmentAddCommand_instances = new WeakSet(), _SpoFileRoleAssignme
93
108
  principalId: typeof args.options.principalId !== 'undefined',
94
109
  upn: typeof args.options.upn !== 'undefined',
95
110
  groupName: typeof args.options.groupName !== 'undefined',
111
+ entraGroupId: typeof args.options.entraGroupId !== 'undefined',
112
+ entraGroupName: typeof args.options.entraGroupName !== 'undefined',
96
113
  roleDefinitionId: typeof args.options.roleDefinitionId !== 'undefined',
97
114
  roleDefinitionName: typeof args.options.roleDefinitionName !== 'undefined'
98
115
  });
@@ -110,6 +127,10 @@ _SpoFileRoleAssignmentAddCommand_instances = new WeakSet(), _SpoFileRoleAssignme
110
127
  option: '--upn [upn]'
111
128
  }, {
112
129
  option: '--groupName [groupName]'
130
+ }, {
131
+ option: '--entraGroupId [entraGroupId]'
132
+ }, {
133
+ option: '--entraGroupName [entraGroupName]'
113
134
  }, {
114
135
  option: '--roleDefinitionId [roleDefinitionId]'
115
136
  }, {
@@ -127,15 +148,18 @@ _SpoFileRoleAssignmentAddCommand_instances = new WeakSet(), _SpoFileRoleAssignme
127
148
  if (args.options.principalId && isNaN(args.options.principalId)) {
128
149
  return `Specified principalId ${args.options.principalId} is not a number`;
129
150
  }
151
+ if (args.options.entraGroupId && !validation.isValidGuid(args.options.entraGroupId)) {
152
+ return `'${args.options.entraGroupId}' is not a valid GUID for option entraGroupId`;
153
+ }
130
154
  if (args.options.roleDefinitionId && isNaN(args.options.roleDefinitionId)) {
131
155
  return `Specified roleDefinitionId ${args.options.roleDefinitionId} is not a number`;
132
156
  }
133
157
  return true;
134
158
  });
135
159
  }, _SpoFileRoleAssignmentAddCommand_initOptionSets = function _SpoFileRoleAssignmentAddCommand_initOptionSets() {
136
- this.optionSets.push({ options: ['fileId', 'fileUrl'] }, { options: ['principalId', 'upn', 'groupName'] }, { options: ['roleDefinitionId', 'roleDefinitionName'] });
160
+ this.optionSets.push({ options: ['fileId', 'fileUrl'] }, { options: ['principalId', 'upn', 'groupName', 'entraGroupId', 'entraGroupName'] }, { options: ['roleDefinitionId', 'roleDefinitionName'] });
137
161
  }, _SpoFileRoleAssignmentAddCommand_initTypes = function _SpoFileRoleAssignmentAddCommand_initTypes() {
138
- this.types.string.push('webUrl', 'fileUrl', 'fileId', 'upn', 'groupName', 'roleDefinitionName');
162
+ this.types.string.push('webUrl', 'fileUrl', 'fileId', 'upn', 'groupName', 'entraGroupId', 'entraGroupName', 'roleDefinitionName');
139
163
  };
140
164
  export default new SpoFileRoleAssignmentAddCommand();
141
165
  //# sourceMappingURL=file-roleassignment-add.js.map