@pnp/cli-microsoft365 7.10.0-beta.ebb7426 → 7.11.0-beta.10b9b79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +5 -2
- package/allCommands.json +1 -1
- package/allCommandsFull.json +1 -1
- package/dist/Auth.js +1 -1
- package/dist/AuthServer.js +10 -10
- package/dist/Command.js +10 -10
- package/dist/chili/index.js +1 -1
- package/dist/cli/cli.js +11 -11
- package/dist/index.js +1 -1
- package/dist/m365/base/AnonymousCommand.js +1 -1
- package/dist/m365/base/DelegatedGraphCommand.js +2 -2
- package/dist/m365/base/PowerAppsCommand.js +2 -2
- package/dist/m365/base/PowerAutomateCommand.js +2 -2
- package/dist/m365/base/PowerBICommand.js +2 -2
- package/dist/m365/base/PowerPlatformCommand.js +2 -2
- package/dist/m365/base/VivaEngageCommand.js +2 -2
- package/dist/m365/cli/commands/cli-consent.js +1 -1
- package/dist/m365/commands/login.js +1 -1
- package/dist/m365/commands/logout.js +1 -1
- package/dist/m365/commands/status.js +1 -1
- package/dist/m365/connection/commands/connection-list.js +1 -1
- package/dist/m365/connection/commands/connection-remove.js +1 -1
- package/dist/m365/connection/commands/connection-set.js +1 -1
- package/dist/m365/connection/commands/connection-use.js +1 -1
- package/dist/m365/entra/commands/app/app-permission-add.js +21 -1
- package/dist/m365/entra/commands/app/app-permission-remove.js +17 -0
- package/dist/m365/entra/commands/m365group/m365group-add.js +1 -0
- package/dist/m365/entra/commands/m365group/m365group-user-list.js +1 -1
- package/dist/m365/external/commands/connection/connection-doctor.js +1 -1
- package/dist/m365/external/commands/connection/connection-schema-add.js +4 -4
- package/dist/m365/file/commands/file-copy.js +3 -3
- package/dist/m365/pa/commands/app/app-export.js +1 -1
- package/dist/m365/pa/commands/app/app-owner-set.js +1 -1
- package/dist/m365/pp/commands/solution/solution-publish.js +1 -1
- package/dist/m365/purview/commands/threatassessment/threatassessment-list.js +1 -1
- package/dist/m365/spfx/commands/project/project-azuredevops-pipeline-add.js +1 -1
- package/dist/m365/spfx/commands/project/project-externalize.js +1 -1
- package/dist/m365/spfx/commands/project/project-github-workflow-add.js +1 -1
- package/dist/m365/spfx/commands/spfx-doctor.js +4 -4
- package/dist/m365/spo/commands/commandset/commandset-get.js +1 -1
- package/dist/m365/spo/commands/file/file-retentionlabel-remove.js +1 -1
- package/dist/m365/spo/commands/group/group-member-add.js +2 -2
- package/dist/m365/spo/commands/group/group-member-remove.js +2 -2
- package/dist/m365/spo/commands/list/list-retentionlabel-ensure.js +1 -1
- package/dist/m365/spo/commands/listitem/listitem-batch-remove.js +1 -1
- package/dist/m365/spo/commands/listitem/listitem-retentionlabel-ensure.js +2 -2
- package/dist/m365/spo/commands/listitem/listitem-retentionlabel-remove.js +2 -2
- package/dist/m365/spo/commands/site/site-admin-list.js +144 -0
- package/dist/m365/spo/commands/site/site-commsite-enable.js +1 -1
- package/dist/m365/spo/commands/spo-search.js +1 -1
- package/dist/m365/spo/commands/tenant/tenant-applicationcustomizer-set.js +4 -4
- package/dist/m365/spo/commands/tenant/tenant-commandset-set.js +2 -2
- package/dist/m365/spo/commands/user/user-ensure.js +1 -1
- package/dist/m365/spo/commands.js +1 -0
- package/dist/m365/teams/commands/chat/chat-member-add.js +1 -1
- package/dist/m365/teams/commands/meeting/meeting-list.js +1 -1
- package/dist/m365/viva/commands/engage/engage-community-get.js +1 -1
- package/dist/request.js +13 -14
- package/dist/utils/spo.js +5 -5
- package/dist/utils/validation.js +6 -0
- package/docs/docs/cmd/entra/app/app-permission-remove.mdx +4 -4
- package/docs/docs/cmd/spo/site/site-admin-list.mdx +115 -0
- package/npm-shrinkwrap.json +802 -601
- package/package.json +12 -12
package/dist/Auth.js
CHANGED
|
@@ -364,7 +364,7 @@ export class Auth {
|
|
|
364
364
|
cli.spinner.start();
|
|
365
365
|
}
|
|
366
366
|
if (cli.getSettingWithDefaultValue(settingsNames.autoOpenLinksInBrowser, false)) {
|
|
367
|
-
browserUtil.open(response.verificationUri);
|
|
367
|
+
await browserUtil.open(response.verificationUri);
|
|
368
368
|
}
|
|
369
369
|
if (cli.getSettingWithDefaultValue(settingsNames.copyDeviceCodeToClipboard, false)) {
|
|
370
370
|
// _clipboardy is never set before hitting this line, but this check
|
package/dist/AuthServer.js
CHANGED
|
@@ -16,23 +16,23 @@ export class AuthServer {
|
|
|
16
16
|
this.resource = resource;
|
|
17
17
|
this.httpServer = http.createServer(this.httpRequest).listen(0, this.httpListener);
|
|
18
18
|
};
|
|
19
|
-
this.httpListener = () => {
|
|
19
|
+
this.httpListener = async () => {
|
|
20
20
|
const requestState = Math.random().toString(16).substr(2, 20);
|
|
21
21
|
const address = this.httpServer.address();
|
|
22
22
|
this.generatedServerUrl = `http://localhost:${address.port}`;
|
|
23
23
|
const url = `${Auth.getEndpointForResource('https://login.microsoftonline.com', this.connection.cloudType)}/${this.connection.tenant}/oauth2/authorize?response_type=code&client_id=${this.connection.appId}&redirect_uri=${this.generatedServerUrl}&state=${requestState}&resource=${this.resource}&prompt=select_account`;
|
|
24
24
|
if (this.debug) {
|
|
25
|
-
this.logger.logToStderr('Redirect URL:');
|
|
26
|
-
this.logger.logToStderr(url);
|
|
27
|
-
this.logger.logToStderr('');
|
|
25
|
+
await this.logger.logToStderr('Redirect URL:');
|
|
26
|
+
await this.logger.logToStderr(url);
|
|
27
|
+
await this.logger.logToStderr('');
|
|
28
28
|
}
|
|
29
29
|
this.openUrl(url);
|
|
30
30
|
};
|
|
31
|
-
this.httpRequest = (request, response) => {
|
|
31
|
+
this.httpRequest = async (request, response) => {
|
|
32
32
|
if (this.debug) {
|
|
33
|
-
this.logger.logToStderr('Response:');
|
|
34
|
-
this.logger.logToStderr(request.url);
|
|
35
|
-
this.logger.logToStderr('');
|
|
33
|
+
await this.logger.logToStderr('Response:');
|
|
34
|
+
await this.logger.logToStderr(request.url);
|
|
35
|
+
await this.logger.logToStderr('');
|
|
36
36
|
}
|
|
37
37
|
// url.parse is deprecated but we can't move to URL, because it doesn't
|
|
38
38
|
// support server-relative URLs
|
|
@@ -82,8 +82,8 @@ export class AuthServer {
|
|
|
82
82
|
}
|
|
83
83
|
openUrl(url) {
|
|
84
84
|
browserUtil.open(url)
|
|
85
|
-
.then(_ => {
|
|
86
|
-
this.logger.logToStderr("To sign in, use the web browser that just has been opened. Please sign-in there.");
|
|
85
|
+
.then(async (_) => {
|
|
86
|
+
await this.logger.logToStderr("To sign in, use the web browser that just has been opened. Please sign-in there.");
|
|
87
87
|
})
|
|
88
88
|
.catch(_ => {
|
|
89
89
|
const errorResponse = {
|
package/dist/Command.js
CHANGED
|
@@ -88,7 +88,7 @@ class Command {
|
|
|
88
88
|
}
|
|
89
89
|
if (!prompted) {
|
|
90
90
|
prompted = true;
|
|
91
|
-
cli.error('🌶️ Provide values for the following parameters:');
|
|
91
|
+
await cli.error('🌶️ Provide values for the following parameters:');
|
|
92
92
|
}
|
|
93
93
|
const answer = optionInfo.autocomplete !== undefined
|
|
94
94
|
? await prompt.forSelection({ message: `${optionInfo.name}: `, choices: optionInfo.autocomplete.map((choice) => { return { name: choice, value: choice }; }) })
|
|
@@ -96,9 +96,9 @@ class Command {
|
|
|
96
96
|
args.options[optionInfo.name] = answer;
|
|
97
97
|
}
|
|
98
98
|
if (prompted) {
|
|
99
|
-
cli.error('');
|
|
99
|
+
await cli.error('');
|
|
100
100
|
}
|
|
101
|
-
this.processOptions(args.options);
|
|
101
|
+
await this.processOptions(args.options);
|
|
102
102
|
return true;
|
|
103
103
|
}
|
|
104
104
|
async validateOptionSets(args, command) {
|
|
@@ -129,17 +129,17 @@ class Command {
|
|
|
129
129
|
return true;
|
|
130
130
|
}
|
|
131
131
|
async promptForOptionSetNameAndValue(args, optionSet) {
|
|
132
|
-
cli.error(`🌶️ Please specify one of the following options:`);
|
|
132
|
+
await cli.error(`🌶️ Please specify one of the following options:`);
|
|
133
133
|
const selectedOptionName = await prompt.forSelection({ message: `Option to use:`, choices: optionSet.options.map((choice) => { return { name: choice, value: choice }; }) });
|
|
134
134
|
const optionValue = await prompt.forInput({ message: `${selectedOptionName}:` });
|
|
135
135
|
args.options[selectedOptionName] = optionValue;
|
|
136
|
-
cli.error('');
|
|
136
|
+
await cli.error('');
|
|
137
137
|
}
|
|
138
138
|
async promptForSpecificOption(args, commonOptions) {
|
|
139
|
-
cli.error(`🌶️ Multiple options for an option set specified. Please specify the correct option that you wish to use.`);
|
|
139
|
+
await cli.error(`🌶️ Multiple options for an option set specified. Please specify the correct option that you wish to use.`);
|
|
140
140
|
const selectedOptionName = await prompt.forSelection({ message: `Option to use:`, choices: commonOptions.map((choice) => { return { name: choice, value: choice }; }) });
|
|
141
141
|
commonOptions.filter(y => y !== selectedOptionName).map(optionName => args.options[optionName] = undefined);
|
|
142
|
-
cli.error('');
|
|
142
|
+
await cli.error('');
|
|
143
143
|
}
|
|
144
144
|
async validateOutput(args) {
|
|
145
145
|
if (args.options.output &&
|
|
@@ -179,7 +179,7 @@ class Command {
|
|
|
179
179
|
catch (error) {
|
|
180
180
|
throw new CommandError(error);
|
|
181
181
|
}
|
|
182
|
-
this.initAction(args, logger);
|
|
182
|
+
await this.initAction(args, logger);
|
|
183
183
|
if (!auth.connection.active) {
|
|
184
184
|
throw new CommandError('Log in to Microsoft 365 first');
|
|
185
185
|
}
|
|
@@ -308,13 +308,13 @@ class Command {
|
|
|
308
308
|
handleRejectedPromise(rawResponse) {
|
|
309
309
|
this.handleError(rawResponse);
|
|
310
310
|
}
|
|
311
|
-
initAction(args, logger) {
|
|
311
|
+
async initAction(args, logger) {
|
|
312
312
|
this.debug = args.options.debug || process.env.CLIMICROSOFT365_DEBUG === '1';
|
|
313
313
|
this.verbose = this.debug || args.options.verbose || process.env.CLIMICROSOFT365_VERBOSE === '1';
|
|
314
314
|
request.debug = this.debug;
|
|
315
315
|
request.logger = logger;
|
|
316
316
|
if (this.debug && auth.connection.identityName !== undefined) {
|
|
317
|
-
logger.logToStderr(`Executing command as '${auth.connection.identityName}', appId: ${auth.connection.appId}, tenantId: ${auth.connection.identityTenantId}`);
|
|
317
|
+
await logger.logToStderr(`Executing command as '${auth.connection.identityName}', appId: ${auth.connection.appId}, tenantId: ${auth.connection.identityTenantId}`);
|
|
318
318
|
}
|
|
319
319
|
telemetry.trackEvent(this.getUsedCommandName(), this.getTelemetryProperties(args));
|
|
320
320
|
}
|
package/dist/chili/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { chili } from './chili.js';
|
|
3
3
|
try {
|
|
4
|
-
(async () => await chili.startConversation(process.argv.slice(2)))();
|
|
4
|
+
await (async () => await chili.startConversation(process.argv.slice(2)))();
|
|
5
5
|
}
|
|
6
6
|
catch (err) {
|
|
7
7
|
console.error(`🛑 An error has occurred while searching documentation: ${err}`);
|
package/dist/cli/cli.js
CHANGED
|
@@ -144,23 +144,23 @@ async function execute(rawArgs) {
|
|
|
144
144
|
await cli.executeCommand(cli.commandToExecute.command, cli.optionsFromArgs);
|
|
145
145
|
const endTotal = process.hrtime.bigint();
|
|
146
146
|
timings.total.push(Number(endTotal - start));
|
|
147
|
-
printTimings(rawArgs);
|
|
147
|
+
await printTimings(rawArgs);
|
|
148
148
|
process.exit(0);
|
|
149
149
|
}
|
|
150
150
|
catch (err) {
|
|
151
151
|
const endTotal = process.hrtime.bigint();
|
|
152
152
|
timings.total.push(Number(endTotal - start));
|
|
153
|
-
printTimings(rawArgs);
|
|
153
|
+
await printTimings(rawArgs);
|
|
154
154
|
await cli.closeWithError(err, cli.optionsFromArgs);
|
|
155
155
|
/* c8 ignore next */
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
|
-
function printTimings(rawArgs) {
|
|
158
|
+
async function printTimings(rawArgs) {
|
|
159
159
|
if (rawArgs.some(arg => arg === '--debug')) {
|
|
160
|
-
cli.error('');
|
|
161
|
-
cli.error('Timings:');
|
|
162
|
-
Object.getOwnPropertyNames(timings).forEach(key => {
|
|
163
|
-
cli.error(`${key}: ${timings[key].reduce((a, b) => a + b, 0) / 1e6}ms`);
|
|
160
|
+
await cli.error('');
|
|
161
|
+
await cli.error('Timings:');
|
|
162
|
+
Object.getOwnPropertyNames(timings).forEach(async (key) => {
|
|
163
|
+
await cli.error(`${key}: ${timings[key].reduce((a, b) => a + b, 0) / 1e6}ms`);
|
|
164
164
|
});
|
|
165
165
|
}
|
|
166
166
|
}
|
|
@@ -179,7 +179,7 @@ async function executeCommand(command, args) {
|
|
|
179
179
|
},
|
|
180
180
|
logToStderr: async (message) => {
|
|
181
181
|
if (args.options.output !== 'none') {
|
|
182
|
-
cli.error(message);
|
|
182
|
+
await cli.error(message);
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
};
|
|
@@ -801,7 +801,7 @@ async function promptForSelection(config) {
|
|
|
801
801
|
cli.spinner.stop();
|
|
802
802
|
}
|
|
803
803
|
const answer = await prompt.forSelection(config);
|
|
804
|
-
cli.error('');
|
|
804
|
+
await cli.error('');
|
|
805
805
|
// Restart the spinner if it was running before the prompt
|
|
806
806
|
/* c8 ignore next 3 */
|
|
807
807
|
if (spinnerSpinning) {
|
|
@@ -816,7 +816,7 @@ async function promptForConfirmation(config) {
|
|
|
816
816
|
cli.spinner.stop();
|
|
817
817
|
}
|
|
818
818
|
const answer = await prompt.forConfirmation(config);
|
|
819
|
-
cli.error('');
|
|
819
|
+
await cli.error('');
|
|
820
820
|
// Restart the spinner if it was running before the prompt
|
|
821
821
|
/* c8 ignore next 3 */
|
|
822
822
|
if (spinnerSpinning) {
|
|
@@ -829,7 +829,7 @@ async function handleMultipleResultsFound(message, values) {
|
|
|
829
829
|
if (!prompt) {
|
|
830
830
|
throw new Error(`${message} Found: ${Object.keys(values).join(', ')}.`);
|
|
831
831
|
}
|
|
832
|
-
cli.error(`🌶️ ${message} `);
|
|
832
|
+
await cli.error(`🌶️ ${message} `);
|
|
833
833
|
const choices = Object.keys(values).map((choice) => { return { name: choice, value: choice }; });
|
|
834
834
|
const response = await cli.promptForSelection({ message: `Please choose one:`, choices });
|
|
835
835
|
return values[response];
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { cli } from './cli/cli.js';
|
|
3
3
|
import { app } from './utils/app.js';
|
|
4
|
-
(async () => {
|
|
4
|
+
await (async () => {
|
|
5
5
|
// required to make console.log() in combination with piped output synchronous
|
|
6
6
|
// on Windows/in PowerShell so that the output is not trimmed by calling
|
|
7
7
|
// process.exit() after executing the command, while the output is still
|
|
@@ -5,8 +5,8 @@ import GraphCommand from './GraphCommand.js';
|
|
|
5
5
|
* This command class is for delegated-only Graph commands.
|
|
6
6
|
*/
|
|
7
7
|
export default class DelegatedGraphCommand extends GraphCommand {
|
|
8
|
-
initAction(args, logger) {
|
|
9
|
-
super.initAction(args, logger);
|
|
8
|
+
async initAction(args, logger) {
|
|
9
|
+
await super.initAction(args, logger);
|
|
10
10
|
if (!auth.connection.active) {
|
|
11
11
|
// we fail no login in the base command command class
|
|
12
12
|
return;
|
|
@@ -5,8 +5,8 @@ export default class PowerAppsCommand extends Command {
|
|
|
5
5
|
get resource() {
|
|
6
6
|
return 'https://api.powerapps.com';
|
|
7
7
|
}
|
|
8
|
-
initAction(args, logger) {
|
|
9
|
-
super.initAction(args, logger);
|
|
8
|
+
async initAction(args, logger) {
|
|
9
|
+
await super.initAction(args, logger);
|
|
10
10
|
if (!auth.connection.active) {
|
|
11
11
|
// we fail no login in the base command command class
|
|
12
12
|
return;
|
|
@@ -5,8 +5,8 @@ export default class PowerAutomateCommand extends Command {
|
|
|
5
5
|
get resource() {
|
|
6
6
|
return 'https://api.flow.microsoft.com';
|
|
7
7
|
}
|
|
8
|
-
initAction(args, logger) {
|
|
9
|
-
super.initAction(args, logger);
|
|
8
|
+
async initAction(args, logger) {
|
|
9
|
+
await super.initAction(args, logger);
|
|
10
10
|
if (!auth.connection.active) {
|
|
11
11
|
// we fail no login in the base command command class
|
|
12
12
|
return;
|
|
@@ -5,8 +5,8 @@ export default class PowerBICommand extends Command {
|
|
|
5
5
|
get resource() {
|
|
6
6
|
return 'https://api.powerbi.com';
|
|
7
7
|
}
|
|
8
|
-
initAction(args, logger) {
|
|
9
|
-
super.initAction(args, logger);
|
|
8
|
+
async initAction(args, logger) {
|
|
9
|
+
await super.initAction(args, logger);
|
|
10
10
|
if (!auth.connection.active) {
|
|
11
11
|
// we fail no login in the base command command class
|
|
12
12
|
return;
|
|
@@ -5,8 +5,8 @@ export default class PowerPlatformCommand extends Command {
|
|
|
5
5
|
get resource() {
|
|
6
6
|
return 'https://api.bap.microsoft.com';
|
|
7
7
|
}
|
|
8
|
-
initAction(args, logger) {
|
|
9
|
-
super.initAction(args, logger);
|
|
8
|
+
async initAction(args, logger) {
|
|
9
|
+
await super.initAction(args, logger);
|
|
10
10
|
if (!auth.connection.active) {
|
|
11
11
|
// we fail no login in the base command command class
|
|
12
12
|
return;
|
|
@@ -5,8 +5,8 @@ export default class VivaEngageCommand extends Command {
|
|
|
5
5
|
get resource() {
|
|
6
6
|
return 'https://www.yammer.com/api';
|
|
7
7
|
}
|
|
8
|
-
initAction(args, logger) {
|
|
9
|
-
super.initAction(args, logger);
|
|
8
|
+
async initAction(args, logger) {
|
|
9
|
+
await super.initAction(args, logger);
|
|
10
10
|
if (!auth.connection.active) {
|
|
11
11
|
// we fail no login in the base command command class
|
|
12
12
|
return;
|
|
@@ -33,7 +33,7 @@ class CliConsentCommand extends AnonymousCommand {
|
|
|
33
33
|
await logger.log(`To consent permissions for executing ${args.options.service} commands, navigate in your web browser to https://login.microsoftonline.com/${config.tenant}/oauth2/v2.0/authorize?client_id=${config.cliEntraAppId}&response_type=code&scope=${encodeURIComponent(scope)}`);
|
|
34
34
|
}
|
|
35
35
|
async action(logger, args) {
|
|
36
|
-
this.initAction(args, logger);
|
|
36
|
+
await this.initAction(args, logger);
|
|
37
37
|
await this.commandAction(logger, args);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -61,7 +61,10 @@ class EntraAppPermissionAddCommand extends GraphCommand {
|
|
|
61
61
|
};
|
|
62
62
|
await request.patch(addPermissionsRequestOptions);
|
|
63
63
|
if (args.options.grantAdminConsent) {
|
|
64
|
-
|
|
64
|
+
let appServicePrincipal = servicePrincipals.find(sp => sp.appId === appObject.appId);
|
|
65
|
+
if (!appServicePrincipal) {
|
|
66
|
+
appServicePrincipal = await this.createServicePrincipal(appObject.appId, logger);
|
|
67
|
+
}
|
|
65
68
|
await this.grantAdminConsent(appServicePrincipal, appPermissions, logger);
|
|
66
69
|
}
|
|
67
70
|
}
|
|
@@ -69,6 +72,23 @@ class EntraAppPermissionAddCommand extends GraphCommand {
|
|
|
69
72
|
this.handleRejectedODataJsonPromise(err);
|
|
70
73
|
}
|
|
71
74
|
}
|
|
75
|
+
async createServicePrincipal(appId, logger) {
|
|
76
|
+
if (this.verbose) {
|
|
77
|
+
await logger.logToStderr(`Creating service principal for app ${appId}...`);
|
|
78
|
+
}
|
|
79
|
+
const requestOptions = {
|
|
80
|
+
url: `${this.resource}/v1.0/servicePrincipals`,
|
|
81
|
+
headers: {
|
|
82
|
+
accept: 'application/json;odata.metadata=none',
|
|
83
|
+
'content-type': 'application/json;odata=nometadata'
|
|
84
|
+
},
|
|
85
|
+
data: {
|
|
86
|
+
appId
|
|
87
|
+
},
|
|
88
|
+
responseType: 'json'
|
|
89
|
+
};
|
|
90
|
+
return await request.post(requestOptions);
|
|
91
|
+
}
|
|
72
92
|
async getAppObject(options) {
|
|
73
93
|
let appNotFoundMessage = '';
|
|
74
94
|
let apps = [];
|
|
@@ -49,6 +49,11 @@ class EntraAppPermissionRemoveCommand extends GraphCommand {
|
|
|
49
49
|
const applicationPermissions = await this.getRequiredResourceAccessForApis(servicePrincipals, args.options.applicationPermissions, ScopeType.Role, appPermissions, logger);
|
|
50
50
|
this.removePermissionsFromResourceArray(applicationPermissions, appObject.requiredResourceAccess);
|
|
51
51
|
}
|
|
52
|
+
for (let i = 0; i < appObject.requiredResourceAccess.length; i++) {
|
|
53
|
+
if (appObject.requiredResourceAccess[i].resourceAccess?.length === 0) {
|
|
54
|
+
appObject.requiredResourceAccess.splice(i, 1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
52
57
|
const removePermissionRequestOptions = {
|
|
53
58
|
url: `${this.resource}/v1.0/applications/${appObject.id}`,
|
|
54
59
|
headers: {
|
|
@@ -270,6 +275,18 @@ _EntraAppPermissionRemoveCommand_instances = new WeakSet(), _EntraAppPermissionR
|
|
|
270
275
|
if (args.options.appObjectId && !validation.isValidGuid(args.options.appObjectId)) {
|
|
271
276
|
return `${args.options.appObjectId} is not a valid GUID`;
|
|
272
277
|
}
|
|
278
|
+
if (args.options.delegatedPermissions) {
|
|
279
|
+
const invalidPermissions = validation.isValidPermission(args.options.delegatedPermissions);
|
|
280
|
+
if (Array.isArray(invalidPermissions)) {
|
|
281
|
+
return `Delegated permission(s) ${invalidPermissions.join(', ')} are not fully-qualified`;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
if (args.options.applicationPermissions) {
|
|
285
|
+
const invalidPermissions = validation.isValidPermission(args.options.applicationPermissions);
|
|
286
|
+
if (Array.isArray(invalidPermissions)) {
|
|
287
|
+
return `Application permission(s) ${invalidPermissions.join(', ')} are not fully-qualified`;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
273
290
|
return true;
|
|
274
291
|
});
|
|
275
292
|
}, _EntraAppPermissionRemoveCommand_initOptionSets = function _EntraAppPermissionRemoveCommand_initOptionSets() {
|
|
@@ -139,6 +139,7 @@ class EntraM365GroupAddCommand extends GraphCommand {
|
|
|
139
139
|
const userArr = users.split(',').map(o => o.trim());
|
|
140
140
|
let promises = [];
|
|
141
141
|
let userIds = [];
|
|
142
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
142
143
|
promises = userArr.map(user => {
|
|
143
144
|
const requestOptions = {
|
|
144
145
|
url: `${this.resource}/v1.0/users?$filter=userPrincipalName eq '${formatting.encodeQueryParameter(user)}'&$select=id,userPrincipalName`,
|
|
@@ -32,7 +32,7 @@ class EntraM365GroupUserListCommand extends GraphCommand {
|
|
|
32
32
|
await this.showDeprecationWarning(logger, aadCommands.M365GROUP_USER_LIST, commands.M365GROUP_USER_LIST);
|
|
33
33
|
try {
|
|
34
34
|
if (args.options.role === 'Guest') {
|
|
35
|
-
this.warn(logger, `Value 'Guest' for the option role is deprecated. Use --filter "userType eq 'Guest'" instead.`);
|
|
35
|
+
await this.warn(logger, `Value 'Guest' for the option role is deprecated. Use --filter "userType eq 'Guest'" instead.`);
|
|
36
36
|
}
|
|
37
37
|
const groupId = await this.getGroupId(args.options, logger);
|
|
38
38
|
const isUnifiedGroup = await entraGroup.isUnifiedGroup(groupId);
|
|
@@ -112,7 +112,7 @@ class ExternalConnectionDoctorCommand extends GraphCommand {
|
|
|
112
112
|
checks = checks.filter((check, index, self) => self.findIndex(c => c.id === check.id) === index);
|
|
113
113
|
for (const check of checks) {
|
|
114
114
|
if (this.debug) {
|
|
115
|
-
logger.logToStderr(`Running check ${check.id}...`);
|
|
115
|
+
await logger.logToStderr(`Running check ${check.id}...`);
|
|
116
116
|
}
|
|
117
117
|
// don't show spinner if running tests
|
|
118
118
|
/* c8 ignore next 3 */
|
|
@@ -39,19 +39,19 @@ class ExternalConnectionSchemaAddCommand extends GraphCommand {
|
|
|
39
39
|
try {
|
|
40
40
|
const res = await request.patch(requestOptions);
|
|
41
41
|
const location = res.headers.location;
|
|
42
|
-
logger.log(location);
|
|
42
|
+
await logger.log(location);
|
|
43
43
|
if (!args.options.wait) {
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
46
|
let status;
|
|
47
47
|
do {
|
|
48
48
|
if (this.verbose) {
|
|
49
|
-
logger.logToStderr(`Waiting 60 seconds...`);
|
|
49
|
+
await logger.logToStderr(`Waiting 60 seconds...`);
|
|
50
50
|
}
|
|
51
51
|
// waiting 60s before polling as recommended by Microsoft
|
|
52
52
|
await new Promise(resolve => setTimeout(resolve, 60000));
|
|
53
53
|
if (this.debug) {
|
|
54
|
-
logger.logToStderr(`Checking schema operation status...`);
|
|
54
|
+
await logger.logToStderr(`Checking schema operation status...`);
|
|
55
55
|
}
|
|
56
56
|
const operation = await request.get({
|
|
57
57
|
url: location,
|
|
@@ -62,7 +62,7 @@ class ExternalConnectionSchemaAddCommand extends GraphCommand {
|
|
|
62
62
|
});
|
|
63
63
|
status = operation.status;
|
|
64
64
|
if (this.verbose) {
|
|
65
|
-
logger.logToStderr(`Schema operation status: ${status}`);
|
|
65
|
+
await logger.logToStderr(`Schema operation status: ${status}`);
|
|
66
66
|
}
|
|
67
67
|
if (status === 'failed') {
|
|
68
68
|
throw `Provisioning schema failed: ${operation.error?.message}`;
|
|
@@ -31,7 +31,7 @@ class FileCopyCommand extends GraphCommand {
|
|
|
31
31
|
const sourcePath = this.getAbsoluteUrl(webUrl, sourceUrl);
|
|
32
32
|
const destinationPath = this.getAbsoluteUrl(webUrl, targetUrl);
|
|
33
33
|
if (this.verbose) {
|
|
34
|
-
logger.logToStderr(`Copying file '${sourcePath}' to '${destinationPath}'...`);
|
|
34
|
+
await logger.logToStderr(`Copying file '${sourcePath}' to '${destinationPath}'...`);
|
|
35
35
|
}
|
|
36
36
|
const copyUrl = await this.getCopyUrl(args.options, sourcePath, logger);
|
|
37
37
|
const { targetDriveId, targetItemId } = await this.getTargetDriveAndItemId(webUrl, targetUrl, logger, verbose);
|
|
@@ -83,7 +83,7 @@ class FileCopyCommand extends GraphCommand {
|
|
|
83
83
|
}
|
|
84
84
|
async getDocumentLibrary(siteId, folderUrl, folderUrlFromUser, logger) {
|
|
85
85
|
if (this.verbose) {
|
|
86
|
-
logger.logToStderr(`Getting document library...`);
|
|
86
|
+
await logger.logToStderr(`Getting document library...`);
|
|
87
87
|
}
|
|
88
88
|
const requestOptions = {
|
|
89
89
|
url: `${this.resource}/v1.0/sites/${siteId}/drives?$select=webUrl,id`,
|
|
@@ -110,7 +110,7 @@ class FileCopyCommand extends GraphCommand {
|
|
|
110
110
|
}
|
|
111
111
|
async getStartingFolderId(documentLibrary, folderUrl, logger) {
|
|
112
112
|
if (this.verbose) {
|
|
113
|
-
logger.logToStderr(`Getting starting folder id...`);
|
|
113
|
+
await logger.logToStderr(`Getting starting folder id...`);
|
|
114
114
|
}
|
|
115
115
|
const documentLibraryRelativeFolderUrl = folderUrl.href.replace(new RegExp(`${documentLibrary.webUrl}`, 'i'), '').replace(/\/+$/, '');
|
|
116
116
|
const requestOptions = {
|
|
@@ -128,7 +128,7 @@ class PaAppExportCommand extends PowerPlatformCommand {
|
|
|
128
128
|
link = response.properties.packageLink.value;
|
|
129
129
|
}
|
|
130
130
|
else {
|
|
131
|
-
setTimeout(this.pollingInterval);
|
|
131
|
+
await setTimeout(this.pollingInterval);
|
|
132
132
|
}
|
|
133
133
|
if (this.verbose) {
|
|
134
134
|
await logger.logToStderr(`Current status of the get package link: ${status}`);
|
|
@@ -26,7 +26,7 @@ class PaAppOwnerSetCommand extends PowerAppsCommand {
|
|
|
26
26
|
}
|
|
27
27
|
async commandAction(logger, args) {
|
|
28
28
|
if (this.verbose) {
|
|
29
|
-
logger.logToStderr(`Setting new owner ${args.options.userId || args.options.userName} for Power Apps app ${args.options.appName}...`);
|
|
29
|
+
await logger.logToStderr(`Setting new owner ${args.options.userId || args.options.userName} for Power Apps app ${args.options.appName}...`);
|
|
30
30
|
}
|
|
31
31
|
try {
|
|
32
32
|
const userId = await this.getUserId(args.options);
|
|
@@ -26,7 +26,7 @@ class PurviewThreatAssessmentListCommand extends GraphCommand {
|
|
|
26
26
|
}
|
|
27
27
|
async commandAction(logger, args) {
|
|
28
28
|
if (this.verbose) {
|
|
29
|
-
logger.logToStderr('Retrieving a list of threat assessments');
|
|
29
|
+
await logger.logToStderr('Retrieving a list of threat assessments');
|
|
30
30
|
}
|
|
31
31
|
try {
|
|
32
32
|
const filter = this.getFilterQuery(args.options);
|
|
@@ -37,7 +37,7 @@ class SpfxProjectAzureDevOpsPipelineAddCommand extends BaseProjectCommand {
|
|
|
37
37
|
const packageJson = fs.readFileSync(solutionPackageJsonFile, 'utf-8');
|
|
38
38
|
const solutionName = JSON.parse(packageJson).name;
|
|
39
39
|
if (this.debug) {
|
|
40
|
-
logger.logToStderr(`Adding Azure DevOps pipeline in the current SPFx project`);
|
|
40
|
+
await logger.logToStderr(`Adding Azure DevOps pipeline in the current SPFx project`);
|
|
41
41
|
}
|
|
42
42
|
try {
|
|
43
43
|
this.updatePipeline(solutionName, pipeline, args.options);
|
|
@@ -81,7 +81,7 @@ class SpfxProjectExternalizeCommand extends BaseProjectCommand {
|
|
|
81
81
|
this.allEditSuggestions.push(...rulesResults.map(x => x.suggestions).reduce((x, y) => [...x, ...y]));
|
|
82
82
|
//removing duplicates
|
|
83
83
|
this.allFindings = this.allFindings.filter((x, i) => this.allFindings.findIndex(y => y.key === x.key) === i);
|
|
84
|
-
this.writeReport(this.allFindings, this.allEditSuggestions, logger, args.options);
|
|
84
|
+
await this.writeReport(this.allFindings, this.allEditSuggestions, logger, args.options);
|
|
85
85
|
}
|
|
86
86
|
catch (err) {
|
|
87
87
|
throw new CommandError(err);
|
|
@@ -40,7 +40,7 @@ class SpfxProjectGithubWorkflowAddCommand extends BaseProjectCommand {
|
|
|
40
40
|
const packageJson = fs.readFileSync(solutionPackageJsonFile, 'utf-8');
|
|
41
41
|
const solutionName = JSON.parse(packageJson).name;
|
|
42
42
|
if (this.debug) {
|
|
43
|
-
logger.logToStderr(`Adding GitHub workflow in the current SPFx project`);
|
|
43
|
+
await logger.logToStderr(`Adding GitHub workflow in the current SPFx project`);
|
|
44
44
|
}
|
|
45
45
|
try {
|
|
46
46
|
this.updateWorkflow(solutionName, workflow, args.options);
|
|
@@ -713,7 +713,7 @@ class SpfxDoctorCommand extends BaseProjectCommand {
|
|
|
713
713
|
}
|
|
714
714
|
async checkNodeVersion(prerequisites) {
|
|
715
715
|
const nodeVersion = this.getNodeVersion();
|
|
716
|
-
this.checkStatus('Node', nodeVersion, prerequisites.node);
|
|
716
|
+
await this.checkStatus('Node', nodeVersion, prerequisites.node);
|
|
717
717
|
}
|
|
718
718
|
async checkSharePointFrameworkVersion(spfxVersionRequested) {
|
|
719
719
|
let spfxVersionDetected = await this.getSPFxVersionFromYoRcFile();
|
|
@@ -725,7 +725,7 @@ class SpfxDoctorCommand extends BaseProjectCommand {
|
|
|
725
725
|
fix: `npm i -g @microsoft/generator-sharepoint@${spfxVersionRequested}`
|
|
726
726
|
};
|
|
727
727
|
if (spfxVersionDetected) {
|
|
728
|
-
this.checkStatus(`SharePoint Framework`, spfxVersionDetected, versionCheck);
|
|
728
|
+
await this.checkStatus(`SharePoint Framework`, spfxVersionDetected, versionCheck);
|
|
729
729
|
}
|
|
730
730
|
else {
|
|
731
731
|
const message = `SharePoint Framework v${spfxVersionRequested} not found`;
|
|
@@ -742,7 +742,7 @@ class SpfxDoctorCommand extends BaseProjectCommand {
|
|
|
742
742
|
async checkYo(prerequisites) {
|
|
743
743
|
const yoVersion = await this.getPackageVersion('yo', PackageSearchMode.GlobalOnly, HandlePromise.Continue);
|
|
744
744
|
if (yoVersion) {
|
|
745
|
-
this.checkStatus('yo', yoVersion, prerequisites.yo);
|
|
745
|
+
await this.checkStatus('yo', yoVersion, prerequisites.yo);
|
|
746
746
|
}
|
|
747
747
|
else {
|
|
748
748
|
const message = 'yo not found';
|
|
@@ -758,7 +758,7 @@ class SpfxDoctorCommand extends BaseProjectCommand {
|
|
|
758
758
|
async checkGulpCli(prerequisites) {
|
|
759
759
|
const gulpCliVersion = await this.getPackageVersion('gulp-cli', PackageSearchMode.GlobalOnly, HandlePromise.Continue);
|
|
760
760
|
if (gulpCliVersion) {
|
|
761
|
-
this.checkStatus('gulp-cli', gulpCliVersion, prerequisites.gulpCli);
|
|
761
|
+
await this.checkStatus('gulp-cli', gulpCliVersion, prerequisites.gulpCli);
|
|
762
762
|
}
|
|
763
763
|
else {
|
|
764
764
|
const message = 'gulp-cli not found';
|