From e16d09c8cb3cba3542f49bf69997a196664b09bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20W=C3=B3jcik?= Date: Sun, 7 Jul 2024 03:15:26 +0200 Subject: [PATCH 01/20] Updates version to 9.0.0 --- .github/workflows/release_v9.yml | 201 +++++++++++++++++++++++++++++++ npm-shrinkwrap.json | 4 +- package.json | 2 +- 3 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/release_v9.yml diff --git a/.github/workflows/release_v9.yml b/.github/workflows/release_v9.yml new file mode 100644 index 00000000000..4e7bc32c7d2 --- /dev/null +++ b/.github/workflows/release_v9.yml @@ -0,0 +1,201 @@ +name: Release v9 + +on: + push: + branches: [v9] + +jobs: + build: + if: github.repository_owner == 'pnp' + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-latest, windows-latest, ubuntu-latest] + node: [20] + + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + registry-url: 'https://registry.npmjs.org' + - name: Cache node modules + id: cache + uses: actions/cache@v4 + with: + path: | + **/node_modules + key: node_modules-${{ matrix.os }}-${{ matrix.node }}-${{ hashFiles('**/npm-shrinkwrap.json') }} + - name: Restore dependencies + if: steps.cache.outputs.cache-hit != 'true' + run: npm ci + - name: Build + run: npm run build + - name: Compress output (non-Windows) + if: matrix.os != 'windows-latest' + run: tar -cvf build.tar --exclude node_modules ./ + - name: Compress output (Windows) + if: matrix.os == 'windows-latest' + run: 7z a -ttar -xr!node_modules -r build.tar . + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: build-${{ matrix.os }}-${{ matrix.node }} + path: build.tar + test: + if: github.repository_owner == 'pnp' + needs: build + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-latest, windows-latest, ubuntu-latest] + # node versions to run tests on + nodeRun: [20] + # node version on which code was built and should be tested + nodeBuild: [20] + include: + - os: ubuntu-latest + nodeRun: 18 + nodeBuild: 20 + + steps: + - name: Configure pagefile + if: matrix.os == 'windows-latest' + uses: al-cheb/configure-pagefile-action@v1.4 + with: + minimum-size: 16GB + disk-root: "C:" + - uses: actions/download-artifact@v4 + with: + name: build-${{ matrix.os }}-${{ matrix.nodeBuild }} + - name: Unpack build artifact (non-Windows) + if: matrix.os != 'windows-latest' + run: tar -xvf build.tar && rm build.tar + - name: Unpack build artifact (Windows) + if: matrix.os == 'windows-latest' + run: 7z x build.tar && del build.tar + - name: Use Node.js ${{ matrix.nodeRun }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.nodeRun }} + registry-url: 'https://registry.npmjs.org' + - name: Cache node modules + id: cache + uses: actions/cache@v4 + with: + path: | + **/node_modules + key: node_modules-${{ matrix.os }}-${{ matrix.nodeBuild }}-${{ hashFiles('**/npm-shrinkwrap.json') }} + - name: Restore dependencies + if: steps.cache.outputs.cache-hit != 'true' + run: npm ci + - name: Test with coverage + # we run coverage only on Node that was used to build + if: matrix.nodeRun == matrix.nodeBuild + run: npm test + - name: Test without coverage + # we want to run tests on older Node versions to ensure that code works + if: matrix.nodeRun != matrix.nodeBuild + run: npm run test:test + - name: Compress output (non-Windows) + if: matrix.nodeRun == matrix.nodeBuild && matrix.os != 'windows-latest' && always() + run: tar -cvf coverage.tar coverage + - name: Compress output (Windows) + if: matrix.nodeRun == matrix.nodeBuild && matrix.os == 'windows-latest' && always() + run: 7z a -ttar -r coverage.tar coverage + - uses: actions/upload-artifact@v4 + if: matrix.nodeRun == matrix.nodeBuild && always() + with: + name: coverage-${{ matrix.os }}-${{ matrix.nodeRun }} + path: coverage.tar + + publish_v9: + if: github.repository_owner == 'pnp' + needs: test + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + + steps: + - uses: actions/download-artifact@v4 + with: + name: build-ubuntu-latest-20 + - name: Unpack build artifact + run: tar -xvf build.tar && rm build.tar + - name: Use Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: 'https://registry.npmjs.org' + - name: Cache node modules + id: cache + uses: actions/cache@v4 + with: + path: | + **/node_modules + key: node_modules-ubuntu-latest-20-${{ hashFiles('**/npm-shrinkwrap.json') }} + - name: Restore dependencies + if: steps.cache.outputs.cache-hit != 'true' + run: npm ci + - name: Stamp beta to package version + run: node scripts/update-package-version.js $GITHUB_SHA + - name: Publish @nine + run: npm publish --tag nine --access public --provenance + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} + - name: Compress output + run: tar -cvf build.tar --exclude node_modules ./ + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: build-ubuntu-latest-20 + path: build.tar + overwrite: true + + deploy_docker: + if: github.repository_owner == 'pnp' + needs: publish_v9 + runs-on: ubuntu-latest + + steps: + - uses: actions/download-artifact@v4 + with: + name: build-ubuntu-latest-20 + - name: Unpack build artifact + run: tar -xvf build.tar && rm build.tar + - name: Use Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: 'https://registry.npmjs.org' + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - name: Extract version from package + id: package_version + run: | + echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT + - name: Wait for npm publish + run: node scripts/wait-npm-publish.js nine ${{ steps.package_version.outputs.version }} + - name: Build and push ${{ steps.package_version.outputs.version }} + uses: docker/build-push-action@v5 + with: + push: true + tags: m365pnp/cli-microsoft365:${{ steps.package_version.outputs.version }} + build-args: | + CLI_VERSION=${{ steps.package_version.outputs.version }} + - name: Build and push nine + uses: docker/build-push-action@v5 + with: + push: true + tags: m365pnp/cli-microsoft365:nine + build-args: | + CLI_VERSION=${{ steps.package_version.outputs.version }} \ No newline at end of file diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index cdb81de0b69..507b4f838e3 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,12 +1,12 @@ { "name": "@pnp/cli-microsoft365", - "version": "8.1.0", + "version": "9.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@pnp/cli-microsoft365", - "version": "8.1.0", + "version": "9.0.0", "license": "MIT", "dependencies": { "@azure/msal-common": "^14.11.0", diff --git a/package.json b/package.json index 538b0272a8b..0a606bdf07b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@pnp/cli-microsoft365", - "version": "8.1.0", + "version": "9.0.0", "description": "Manage Microsoft 365 and SharePoint Framework projects on any platform", "license": "MIT", "main": "./dist/api.js", From 017e095b03478659321f8a2cdb20327b727f60c4 Mon Sep 17 00:00:00 2001 From: Nanddeep Nachan Date: Mon, 8 Jul 2024 13:55:04 +0000 Subject: [PATCH 02/20] Updates option names of 'app permission add' to plural. Closes #5719 --- .../cmd/app/permission/permission-add.mdx | 10 +++---- .../permission/permission-add.spec.ts | 30 +++++++++---------- .../app/commands/permission/permission-add.ts | 24 +++++++-------- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/docs/docs/cmd/app/permission/permission-add.mdx b/docs/docs/cmd/app/permission/permission-add.mdx index a3532a704c5..de9640c9c5d 100644 --- a/docs/docs/cmd/app/permission/permission-add.mdx +++ b/docs/docs/cmd/app/permission/permission-add.mdx @@ -16,10 +16,10 @@ m365 app permission add [options] `--appId [appId]` : Client ID of the Microsoft Entra app registered in the .m365rc.json file to retrieve API permissions for. -`--applicationPermission [applicationPermission]` +`--applicationPermissions [applicationPermissions]` : Space-separated list of application permissions to add. -`--delegatedPermission [delegatedPermission]` +`--delegatedPermissions [delegatedPermissions]` : Space-separated list of delegated permissions to add. `--grantAdminConsent` @@ -37,19 +37,19 @@ If you have multiple apps registered in your .m365rc.json file, you can specify Adds the specified application permissions to the default app registered in the _.m365rc.json_ file while granting admin consent. ```sh -m365 app permission add --applicationPermission 'https://graph.microsoft.com/User.ReadWrite.All https://graph.microsoft.com/User.Read.All' --grantAdminConsent +m365 app permission add --applicationPermissions 'https://graph.microsoft.com/User.ReadWrite.All https://graph.microsoft.com/User.Read.All' --grantAdminConsent ``` Adds the specified delegated permissions to the default app registered in the _.m365rc.json_ file without granting admin consent. ```sh -m365 app permission add --delegatedPermission 'https://graph.microsoft.com/offline_access' +m365 app permission add --delegatedPermissions 'https://graph.microsoft.com/offline_access' ``` Adds the specified application and delegated permissions to a specific app registered in the _.m365rc.json_ file while granting admin consent. ```sh -m365 app permission add --appId '1663767b-4172-4519-bfd1-28e6ff19055b' --applicationPermission 'https://graph.microsoft.com/User.ReadWrite.All https://graph.microsoft.com/User.Read.All' --delegatedPermission 'https://graph.microsoft.com/offline_access' --grantAdminConsent +m365 app permission add --appId '1663767b-4172-4519-bfd1-28e6ff19055b' --applicationPermissions 'https://graph.microsoft.com/User.ReadWrite.All https://graph.microsoft.com/User.Read.All' --delegatedPermissions 'https://graph.microsoft.com/offline_access' --grantAdminConsent ``` ## Response diff --git a/src/m365/app/commands/permission/permission-add.spec.ts b/src/m365/app/commands/permission/permission-add.spec.ts index 3a72eeeb98e..691a50fdfa1 100644 --- a/src/m365/app/commands/permission/permission-add.spec.ts +++ b/src/m365/app/commands/permission/permission-add.spec.ts @@ -112,7 +112,7 @@ describe(commands.PERMISSION_ADD, () => { throw 'Invalid request'; }); - await command.action(logger, { options: { applicationPermission: applicationPermissions, verbose: true } }); + await command.action(logger, { options: { applicationPermissions: applicationPermissions, verbose: true } }); assert(patchStub.called); }); @@ -144,7 +144,7 @@ describe(commands.PERMISSION_ADD, () => { throw 'Invalid request'; }); - await command.action(logger, { options: { applicationPermission: applicationPermissions, grantAdminConsent: true, verbose: true } }); + await command.action(logger, { options: { applicationPermissions: applicationPermissions, grantAdminConsent: true, verbose: true } }); assert.strictEqual(amountOfPostCalls, 2); }); @@ -167,7 +167,7 @@ describe(commands.PERMISSION_ADD, () => { throw 'Invalid request'; }); - await command.action(logger, { options: { delegatedPermission: delegatedPermissions, verbose: true } }); + await command.action(logger, { options: { delegatedPermissions: delegatedPermissions, verbose: true } }); assert(patchStub.called); }); @@ -200,7 +200,7 @@ describe(commands.PERMISSION_ADD, () => { throw 'Invalid request'; }); - await command.action(logger, { options: { delegatedPermission: delegatedPermissions, grantAdminConsent: true, verbose: true } }); + await command.action(logger, { options: { delegatedPermissions: delegatedPermissions, grantAdminConsent: true, verbose: true } }); assert.deepStrictEqual(postStub.lastCall.args[0].data, { clientId: servicePrincipalId, consentType: 'AllPrincipals', @@ -244,7 +244,7 @@ describe(commands.PERMISSION_ADD, () => { throw 'Invalid request'; }); - await command.action(logger, { options: { delegatedPermission: delegatedPermissions, applicationPermission: applicationPermissions, grantAdminConsent: true, verbose: true } }); + await command.action(logger, { options: { delegatedPermissions: delegatedPermissions, applicationPermissions: applicationPermissions, grantAdminConsent: true, verbose: true } }); assert.strictEqual(amountOfPostCalls, 3); }); @@ -260,7 +260,7 @@ describe(commands.PERMISSION_ADD, () => { } }); - await assert.rejects(command.action(logger, { options: { applicationPermission: applicationPermissions, verbose: true } }), + await assert.rejects(command.action(logger, { options: { applicationPermissions: applicationPermissions, verbose: true } }), new CommandError(`App with id ${appId} not found in Microsoft Entra ID.`)); }); @@ -279,7 +279,7 @@ describe(commands.PERMISSION_ADD, () => { } }); - await assert.rejects(command.action(logger, { options: { applicationPermission: api, verbose: true } }), + await assert.rejects(command.action(logger, { options: { applicationPermissions: api, verbose: true } }), new CommandError(`Service principal ${servicePrincipalName} not found`)); }); @@ -299,26 +299,26 @@ describe(commands.PERMISSION_ADD, () => { } }); - await assert.rejects(command.action(logger, { options: { applicationPermission: api, verbose: true } }), + await assert.rejects(command.action(logger, { options: { applicationPermissions: api, verbose: true } }), new CommandError(`Permission ${permissionName} for service principal ${servicePrincipalName} not found`)); }); - it('passes validation if applicationPermission is passed', async () => { - const actual = await command.validate({ options: { applicationPermission: applicationPermissions } }, commandInfo); + it('passes validation if applicationPermissions is passed', async () => { + const actual = await command.validate({ options: { applicationPermissions: applicationPermissions } }, commandInfo); assert.strictEqual(actual, true); }); - it('passes validation if delegatedPermission is passed', async () => { - const actual = await command.validate({ options: { delegatedPermission: delegatedPermissions } }, commandInfo); + it('passes validation if delegatedPermissions is passed', async () => { + const actual = await command.validate({ options: { delegatedPermissions: delegatedPermissions } }, commandInfo); assert.strictEqual(actual, true); }); - it('passes validation if both applicationPermission or delegatedPermission are passed', async () => { - const actual = await command.validate({ options: { applicationPermission: applicationPermissions, delegatedPermission: delegatedPermissions } }, commandInfo); + it('passes validation if both applicationPermissions or delegatedPermissions are passed', async () => { + const actual = await command.validate({ options: { applicationPermissions: applicationPermissions, delegatedPermissions: delegatedPermissions } }, commandInfo); assert.strictEqual(actual, true); }); - it('fails validation if both applicationPermission or delegatedPermission is not passed', async () => { + it('fails validation if both applicationPermissions or delegatedPermissions is not passed', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { return false; diff --git a/src/m365/app/commands/permission/permission-add.ts b/src/m365/app/commands/permission/permission-add.ts index ae7c7fc234e..5bb975df4f7 100644 --- a/src/m365/app/commands/permission/permission-add.ts +++ b/src/m365/app/commands/permission/permission-add.ts @@ -13,8 +13,8 @@ interface CommandArgs { interface Options extends GlobalOptions { appId?: string; - applicationPermission?: string; - delegatedPermission?: string; + applicationPermissions?: string; + delegatedPermissions?: string; grantAdminConsent?: boolean; } @@ -50,8 +50,8 @@ class AppPermissionAddCommand extends AppCommand { this.telemetry.push((args: CommandArgs) => { Object.assign(this.telemetryProperties, { appId: typeof args.options.appId !== 'undefined', - applicationPermission: typeof args.options.applicationPermission !== 'undefined', - delegatedPermission: typeof args.options.delegatedPermission !== 'undefined', + applicationPermissions: typeof args.options.applicationPermissions !== 'undefined', + delegatedPermissions: typeof args.options.delegatedPermissions !== 'undefined', grantAdminConsent: !!args.options.grantAdminConsent }); }); @@ -60,16 +60,16 @@ class AppPermissionAddCommand extends AppCommand { #initOptions(): void { this.options.unshift( { option: '--appId [appId]' }, - { option: '--applicationPermission [applicationPermission]' }, - { option: '--delegatedPermission [delegatedPermission]' }, + { option: '--applicationPermissions [applicationPermissions]' }, + { option: '--delegatedPermissions [delegatedPermissions]' }, { option: '--grantAdminConsent' } ); } #initOptionSets(): void { this.optionSets.push({ - options: ['applicationPermission', 'delegatedPermission'], - runsWhen: (args) => args.options.delegatedPermission === undefined && args.options.applicationPermission === undefined + options: ['applicationPermissions', 'delegatedPermissions'], + runsWhen: (args) => args.options.delegatedPermissions === undefined && args.options.applicationPermissions === undefined }); } @@ -79,13 +79,13 @@ class AppPermissionAddCommand extends AppCommand { const servicePrincipals = await odata.getAllItems(`${this.resource}/v1.0/myorganization/servicePrincipals?$select=appId,appRoles,id,oauth2PermissionScopes,servicePrincipalNames`); const appPermissions: AppPermission[] = []; - if (args.options.delegatedPermission) { - const delegatedPermissions = await this.getRequiredResourceAccessForApis(servicePrincipals, args.options.delegatedPermission, ScopeType.Scope, appPermissions, logger); + if (args.options.delegatedPermissions) { + const delegatedPermissions = await this.getRequiredResourceAccessForApis(servicePrincipals, args.options.delegatedPermissions, ScopeType.Scope, appPermissions, logger); this.addPermissionsToResourceArray(delegatedPermissions, appObject.requiredResourceAccess!); } - if (args.options.applicationPermission) { - const applicationPermissions = await this.getRequiredResourceAccessForApis(servicePrincipals, args.options.applicationPermission, ScopeType.Role, appPermissions, logger); + if (args.options.applicationPermissions) { + const applicationPermissions = await this.getRequiredResourceAccessForApis(servicePrincipals, args.options.applicationPermissions, ScopeType.Role, appPermissions, logger); this.addPermissionsToResourceArray(applicationPermissions, appObject.requiredResourceAccess!); } From 8dd16456a7cc7ad58925a27b619bbe7e16740d19 Mon Sep 17 00:00:00 2001 From: Nanddeep Nachan Date: Tue, 9 Jul 2024 13:57:26 +0000 Subject: [PATCH 03/20] Removes deprecated Guest value from 'aad m365group user list' command. Closes #5558 --- .../entra/m365group/m365group-user-list.mdx | 2 +- .../m365group/m365group-user-list.spec.ts | 54 ++----------------- .../commands/m365group/m365group-user-list.ts | 16 +++--- 3 files changed, 12 insertions(+), 60 deletions(-) diff --git a/docs/docs/cmd/entra/m365group/m365group-user-list.mdx b/docs/docs/cmd/entra/m365group/m365group-user-list.mdx index 06126c04fd8..48f3b0d13f1 100644 --- a/docs/docs/cmd/entra/m365group/m365group-user-list.mdx +++ b/docs/docs/cmd/entra/m365group/m365group-user-list.mdx @@ -28,7 +28,7 @@ m365 aad m365group user list [options] : The display name of the Microsoft 365 group. Specify `groupId` or `groupDisplayName` but not both. `-r, --role [role]` -: Filter the results to only users with the given role. Allowed values: `Owner`, `Member`, or (Deprecated) `Guest`. +: Filter the results to only users with the given role. Allowed values: `Owner`, `Member`. `-p, --properties [properties]` : Comma-separated list of properties to retrieve. diff --git a/src/m365/entra/commands/m365group/m365group-user-list.spec.ts b/src/m365/entra/commands/m365group/m365group-user-list.spec.ts index 9e9a6844d0d..15f071e272b 100644 --- a/src/m365/entra/commands/m365group/m365group-user-list.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-user-list.spec.ts @@ -125,16 +125,6 @@ describe(commands.M365GROUP_USER_LIST, () => { assert.strictEqual(actual, true); }); - it('passes validation when valid groupId and Guest role specified', async () => { - const actual = await command.validate({ - options: { - groupId: '6703ac8a-c49b-4fd4-8223-28f0ac3a6402', - role: 'Guest' - } - }, commandInfo); - assert.strictEqual(actual, true); - }); - it('correctly lists all users in a Microsoft 365 group by group id', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/groups/00000000-0000-0000-0000-000000000000/Owners/microsoft.graph.user?$select=id,displayName,userPrincipalName,givenName,surname,userType`) { @@ -161,7 +151,7 @@ describe(commands.M365GROUP_USER_LIST, () => { "id": "00000000-0000-0000-0000-000000000000", "displayName": "Anne Matthews", "userPrincipalName": "anne.matthews@contoso.onmicrosoft.com", - "userType": "Owner", + "userType": "Member", "givenName": "Anne", "surname": "Matthews", "roles": ["Owner", "Member"] @@ -206,7 +196,7 @@ describe(commands.M365GROUP_USER_LIST, () => { "id": "00000000-0000-0000-0000-000000000000", "displayName": "Anne Matthews", "userPrincipalName": "anne.matthews@contoso.onmicrosoft.com", - "userType": "Owner", + "userType": "Member", "givenName": "Anne", "surname": "Matthews", "roles": ["Owner", "Member"] @@ -240,7 +230,7 @@ describe(commands.M365GROUP_USER_LIST, () => { "id": "00000000-0000-0000-0000-000000000000", "displayName": "Anne Matthews", "userPrincipalName": "anne.matthews@contoso.onmicrosoft.com", - "userType": "Owner", + "userType": "Member", "givenName": "Anne", "surname": "Matthews", "roles": ["Owner"] @@ -291,40 +281,6 @@ describe(commands.M365GROUP_USER_LIST, () => { ])); }); - it('correctly lists all guests in a Microsoft 365 group by group id', async () => { - sinon.stub(request, 'get').callsFake(async (opts) => { - if (opts.url === `https://graph.microsoft.com/v1.0/groups/00000000-0000-0000-0000-000000000000/Owners/microsoft.graph.user?$select=id,displayName,userPrincipalName,givenName,surname,userType`) { - return { - "value": [{ "id": "00000000-0000-0000-0000-000000000001", "displayName": "Karl Matteson", "userPrincipalName": "karl.matteson@contoso.onmicrosoft.com", "givenName": "Karl", "surname": "Matteson", "userType": "Member" }] - }; - } - - if (opts.url === `https://graph.microsoft.com/v1.0/groups/00000000-0000-0000-0000-000000000000/Members/microsoft.graph.user?$select=id,displayName,userPrincipalName,givenName,surname,userType`) { - return { - "value": [ - { "id": "00000000-0000-0000-0000-000000000000", "displayName": "Anne Matthews", "userPrincipalName": "annematthews_gmail.com#EXT#@nachan365.onmicrosoft.com", "givenName": "Anne", "surname": "Matthews", "userType": "Guest" }, - { "id": "00000000-0000-0000-0000-000000000001", "displayName": "Karl Matteson", "userPrincipalName": "karl.matteson@contoso.onmicrosoft.com", "givenName": "Karl", "surname": "Matteson", "userType": "Member" } - ] - }; - } - - throw 'Invalid request'; - }); - - await command.action(logger, { options: { groupId: "00000000-0000-0000-0000-000000000000", role: "Guest" } }); - assert(loggerLogSpy.calledOnceWithExactly([ - { - "id": "00000000-0000-0000-0000-000000000000", - "displayName": "Anne Matthews", - "userPrincipalName": "annematthews_gmail.com#EXT#@nachan365.onmicrosoft.com", - "userType": "Guest", - "givenName": "Anne", - "surname": "Matthews", - "roles": ["Member"] - } - ])); - }); - it('correctly lists all users in a Microsoft 365 group by group id (debug)', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/groups/00000000-0000-0000-0000-000000000000/Owners/microsoft.graph.user?$select=id,displayName,userPrincipalName,givenName,surname,userType`) { @@ -351,7 +307,7 @@ describe(commands.M365GROUP_USER_LIST, () => { "id": "00000000-0000-0000-0000-000000000000", "displayName": "Anne Matthews", "userPrincipalName": "anne.matthews@contoso.onmicrosoft.com", - "userType": "Owner", + "userType": "Member", "givenName": "Anne", "surname": "Matthews", "roles": ["Owner", "Member"] @@ -392,7 +348,7 @@ describe(commands.M365GROUP_USER_LIST, () => { await command.action(logger, { options: { groupId: "2c1ba4c4-cd9b-4417-832f-92a34bc34b2a", properties: "displayName,mail,memberof/id,memberof/displayName" } }); assert(loggerLogSpy.calledOnceWithExactly([ - { "id": "00000000-0000-0000-0000-000000000000", "displayName": "Karl Matteson", "mail": "karl.matteson@contoso.onmicrosoft.com", "memberOf": [{ "displayName": "Life and Music", "id": "d6c88284-c598-468d-8074-56acaf3c0453" }], "roles": ["Owner"], "userType": "Owner" }, + { "id": "00000000-0000-0000-0000-000000000000", "displayName": "Karl Matteson", "mail": "karl.matteson@contoso.onmicrosoft.com", "memberOf": [{ "displayName": "Life and Music", "id": "d6c88284-c598-468d-8074-56acaf3c0453" }], "roles": ["Owner"] }, { "id": "00000000-0000-0000-0000-000000000001", "displayName": "Anne Matthews", "mail": "anne.matthews@contoso.onmicrosoft.com", "memberOf": [{ "displayName": "Life and Music", "id": "d6c88284-c598-468d-8074-56acaf3c0454" }], "roles": ["Member"] } ])); }); diff --git a/src/m365/entra/commands/m365group/m365group-user-list.ts b/src/m365/entra/commands/m365group/m365group-user-list.ts index e5ff5859fca..90de68209ab 100644 --- a/src/m365/entra/commands/m365group/m365group-user-list.ts +++ b/src/m365/entra/commands/m365group/m365group-user-list.ts @@ -69,7 +69,7 @@ class EntraM365GroupUserListCommand extends GraphCommand { }, { option: "-r, --role [type]", - autocomplete: ["Owner", "Member", "Guest"] + autocomplete: ["Owner", "Member"] }, { option: "-p, --properties [properties]" @@ -96,8 +96,8 @@ class EntraM365GroupUserListCommand extends GraphCommand { } if (args.options.role) { - if (['Owner', 'Member', 'Guest'].indexOf(args.options.role) === -1) { - return `${args.options.role} is not a valid role value. Allowed values Owner|Member|Guest`; + if (['Owner', 'Member'].indexOf(args.options.role) === -1) { + return `${args.options.role} is not a valid role value. Allowed values Owner|Member`; } } @@ -110,10 +110,6 @@ class EntraM365GroupUserListCommand extends GraphCommand { await this.showDeprecationWarning(logger, aadCommands.M365GROUP_USER_LIST, commands.M365GROUP_USER_LIST); try { - if (args.options.role === 'Guest') { - await this.warn(logger, `Value 'Guest' for the option role is deprecated. Use --filter "userType eq 'Guest'" instead.`); - } - const groupId = await this.getGroupId(args.options, logger); const isUnifiedGroup = await entraGroup.isUnifiedGroup(groupId); @@ -124,10 +120,10 @@ class EntraM365GroupUserListCommand extends GraphCommand { let users: ExtendedUser[] = []; if (!args.options.role || args.options.role === 'Owner') { const owners = await this.getUsers(args.options, 'Owners', groupId, logger); - owners.forEach(owner => users.push({ ...owner, roles: ['Owner'], userType: 'Owner' })); + owners.forEach(owner => users.push({ ...owner, roles: ['Owner'] })); } - if (!args.options.role || args.options.role === 'Member' || args.options.role === 'Guest') { + if (!args.options.role || args.options.role === 'Member') { const members = await this.getUsers(args.options, 'Members', groupId, logger); members.forEach((member: ExtendedUser) => { @@ -143,7 +139,7 @@ class EntraM365GroupUserListCommand extends GraphCommand { } if (args.options.role) { - users = users.filter(i => i.userType === args.options.role); + users = users.filter(i => i.roles.indexOf(args.options.role!) > -1); } await logger.log(users); From 3b4162da56291d81b39b92c1b60252af8d50b27e Mon Sep 17 00:00:00 2001 From: Saurabh Date: Wed, 10 Jul 2024 11:12:05 +0200 Subject: [PATCH 04/20] Adds --force option to 'spo site appcatalog remove' command. Closes #6091 --- .../cmd/spo/site/site-appcatalog-remove.mdx | 13 ++- docs/docs/v9-upgrade-guidance.mdx | 23 ++++++ docs/src/config/sidebars.ts | 1 + .../site/site-appcatalog-remove.spec.ts | 35 ++++++-- .../commands/site/site-appcatalog-remove.ts | 82 +++++++++++++------ 5 files changed, 122 insertions(+), 32 deletions(-) create mode 100644 docs/docs/v9-upgrade-guidance.mdx diff --git a/docs/docs/cmd/spo/site/site-appcatalog-remove.mdx b/docs/docs/cmd/spo/site/site-appcatalog-remove.mdx index f2b7c3bfbf1..1598d47d553 100644 --- a/docs/docs/cmd/spo/site/site-appcatalog-remove.mdx +++ b/docs/docs/cmd/spo/site/site-appcatalog-remove.mdx @@ -14,7 +14,10 @@ m365 spo site appcatalog remove [options] ```md definition-list `-u, --siteUrl ` -: URL of the site collection containing the app catalog to disable +: URL of the site collection containing the app catalog to disable. + +`-f, --force` +: Don't prompt for confirmation. ``` @@ -31,12 +34,18 @@ To use this command you have to have permissions to access the tenant admin site ## Examples -Remove the site collection app catalog from specified site +Remove the site collection app catalog from specified site. ```sh m365 spo site appcatalog remove --siteUrl https://contoso.sharepoint/sites/site ``` +Remove the site collection app catalog from specified site without prompting for confirmation. + +```sh +m365 spo site appcatalog remove --siteUrl https://contoso.sharepoint/sites/site --force +``` + ## Response The command won't return a response on success. diff --git a/docs/docs/v9-upgrade-guidance.mdx b/docs/docs/v9-upgrade-guidance.mdx new file mode 100644 index 00000000000..588b94e4c16 --- /dev/null +++ b/docs/docs/v9-upgrade-guidance.mdx @@ -0,0 +1,23 @@ +# v9 Upgrade Guidance + +The v9 of CLI for Microsoft 365 introduces several breaking changes. To help you upgrade to the latest version of CLI for Microsoft 365, we've listed those changes along with any actions you may need to take. + +## SharePoint + +### Updated `spo site appcatalog remove` options + +We updated the [spo site appcatalog remove](./cmd/spo/site/site-appcatalog-remove.mdx) command. This command is a destructive operation that removes a site collection app catalog. Previously, it did not prompt for confirmation before executing this action, which could potentially lead to unintended data loss. To address this, we have added a confirmation prompt by default. + +Because of this rework, we have added a new option. + +**New options:** + +Option | Description +--- | --- +`-f, --force` | Don't prompt for confirmation. + +#### What action do I need to take? + +Update your scripts with the following: + +- Add the option `--force` if you want to bypass the confirmation prompt and proceed with the removal operation automatically. diff --git a/docs/src/config/sidebars.ts b/docs/src/config/sidebars.ts index 8aaae228c2d..3c0ca67ba7a 100644 --- a/docs/src/config/sidebars.ts +++ b/docs/src/config/sidebars.ts @@ -3,6 +3,7 @@ import type { SidebarsConfig } from '@docusaurus/plugin-content-docs'; const sidebars: SidebarsConfig = { home: [ 'index', + 'v9-upgrade-guidance', 'v8-upgrade-guidance', 'v7-upgrade-guidance', 'v6-upgrade-guidance', diff --git a/src/m365/spo/commands/site/site-appcatalog-remove.spec.ts b/src/m365/spo/commands/site/site-appcatalog-remove.spec.ts index c08daf0c2f4..dda6607b991 100644 --- a/src/m365/spo/commands/site/site-appcatalog-remove.spec.ts +++ b/src/m365/spo/commands/site/site-appcatalog-remove.spec.ts @@ -21,6 +21,7 @@ describe(commands.SITE_APPCATALOG_REMOVE, () => { let logger: Logger; let loggerLogToStderrSpy: sinon.SinonSpy; let commandInfo: CommandInfo; + let promptIssued: boolean = false; before(() => { sinon.stub(auth, 'restoreAuth').resolves(); @@ -52,12 +53,19 @@ describe(commands.SITE_APPCATALOG_REMOVE, () => { } }; loggerLogToStderrSpy = sinon.spy(logger, 'logToStderr'); + + sinon.stub(cli, 'promptForConfirmation').callsFake(() => { + promptIssued = true; + return Promise.resolve(false); + }); + promptIssued = false; }); afterEach(() => { sinonUtil.restore([ request.post, - cli.getSettingWithDefaultValue + cli.getSettingWithDefaultValue, + cli.promptForConfirmation ]); }); @@ -75,7 +83,19 @@ describe(commands.SITE_APPCATALOG_REMOVE, () => { assert.notStrictEqual(command.description, null); }); - it('removes site collection app catalog (debug=false)', async () => { + it('prompts before removing the site app catalog when force option not passed', async () => { + await command.action(logger, { options: { siteUrl: 'https://contoso.sharepoint.com/sites/site' } }); + assert(promptIssued); + }); + + it('aborts removing site app catalog when prompt not confirmed', async () => { + const postSpy = sinon.stub(request, 'post').resolves(); + + await command.action(logger, { options: { siteUrl: 'https://contoso.sharepoint.com/sites/site' } }); + assert(postSpy.notCalled); + }); + + it('removes site collection app catalog (debug=false) without prompting for confirmation', async () => { sinon.stub(request, 'post').callsFake(async (opts) => { if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) { if (opts.headers && @@ -104,10 +124,10 @@ describe(commands.SITE_APPCATALOG_REMOVE, () => { throw 'Invalid request'; }); - await command.action(logger, { options: { siteUrl: 'https://contoso.sharepoint.com/sites/site' } }); + await command.action(logger, { options: { siteUrl: 'https://contoso.sharepoint.com/sites/site', force: true } }); }); - it('removes site collection app catalog (debug=true)', async () => { + it('removes site collection app catalog (debug=true) while prompting for confirmation', async () => { sinon.stub(request, 'post').callsFake(async (opts) => { if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) { if (opts.headers && @@ -136,6 +156,9 @@ describe(commands.SITE_APPCATALOG_REMOVE, () => { throw 'Invalid request'; }); + sinonUtil.restore(cli.promptForConfirmation); + sinon.stub(cli, 'promptForConfirmation').resolves(true); + await command.action(logger, { options: { debug: true, siteUrl: 'https://contoso.sharepoint.com/sites/site' } }); assert(loggerLogToStderrSpy.called); }); @@ -161,13 +184,13 @@ describe(commands.SITE_APPCATALOG_REMOVE, () => { throw 'Invalid request'; }); - await assert.rejects(command.action(logger, { options: { debug: true, siteUrl: 'https://contoso.sharepoint.com/sites/site' } } as any), new CommandError('Unknown Error')); + await assert.rejects(command.action(logger, { options: { debug: true, siteUrl: 'https://contoso.sharepoint.com/sites/site', force: true } } as any), new CommandError('Unknown Error')); }); it('correctly handles random API error', async () => { sinon.stub(request, 'post').rejects(new Error('An error has occurred')); - await assert.rejects(command.action(logger, { options: { debug: true, siteUrl: 'https://contoso.sharepoint.com/sites/site' } } as any), new CommandError('An error has occurred')); + await assert.rejects(command.action(logger, { options: { debug: true, siteUrl: 'https://contoso.sharepoint.com/sites/site', force: true } } as any), new CommandError('An error has occurred')); }); it('supports specifying site url', () => { diff --git a/src/m365/spo/commands/site/site-appcatalog-remove.ts b/src/m365/spo/commands/site/site-appcatalog-remove.ts index 7f4ed7aaa7f..ee87eb05ffd 100644 --- a/src/m365/spo/commands/site/site-appcatalog-remove.ts +++ b/src/m365/spo/commands/site/site-appcatalog-remove.ts @@ -1,3 +1,4 @@ +import { cli } from '../../../../cli/cli.js'; import { Logger } from '../../../../cli/Logger.js'; import config from '../../../../config.js'; import GlobalOptions from '../../../../GlobalOptions.js'; @@ -14,6 +15,7 @@ interface CommandArgs { interface Options extends GlobalOptions { siteUrl: string; + force?: boolean; } class SpoSiteAppCatalogRemoveCommand extends SpoCommand { @@ -28,14 +30,27 @@ class SpoSiteAppCatalogRemoveCommand extends SpoCommand { constructor() { super(); + this.#initTelemetry(); this.#initOptions(); this.#initValidators(); + this.#initTypes(); + } + + #initTelemetry(): void { + this.telemetry.push((args: CommandArgs) => { + Object.assign(this.telemetryProperties, { + force: !!args.options.force + }); + }); } #initOptions(): void { this.options.unshift( { option: '-u, --siteUrl ' + }, + { + option: '-f, --force' } ); } @@ -46,40 +61,59 @@ class SpoSiteAppCatalogRemoveCommand extends SpoCommand { ); } + #initTypes(): void { + this.types.string.push('siteUrl'); + } + + public async commandAction(logger: Logger, args: CommandArgs): Promise { - const url: string = args.options.siteUrl; + const removeSiteAppcatalog = async (): Promise => { + const url: string = args.options.siteUrl; - try { - const spoAdminUrl: string = await spo.getSpoAdminUrl(logger, this.debug); - const requestDigest: ContextInfo = await spo.getRequestDigest(spoAdminUrl); if (this.verbose) { await logger.logToStderr(`Disabling site collection app catalog...`); } - const requestOptions: any = { - url: `${spoAdminUrl}/_vti_bin/client.svc/ProcessQuery`, - headers: { - 'X-RequestDigest': requestDigest.FormDigestValue - }, - data: `${formatting.escapeXml(url)}${formatting.escapeXml(url)}` - }; - - const res: string = await request.post(requestOptions); - const json: ClientSvcResponse = JSON.parse(res); - const response: ClientSvcResponseContents = json[0]; - if (response.ErrorInfo) { - throw response.ErrorInfo.ErrorMessage; - } - else { - if (this.verbose) { - await logger.logToStderr('Site collection app catalog disabled'); + try { + const spoAdminUrl: string = await spo.getSpoAdminUrl(logger, this.debug); + const requestDigest: ContextInfo = await spo.getRequestDigest(spoAdminUrl); + + const requestOptions: any = { + url: `${spoAdminUrl}/_vti_bin/client.svc/ProcessQuery`, + headers: { + 'X-RequestDigest': requestDigest.FormDigestValue + }, + data: `${formatting.escapeXml(url)}${formatting.escapeXml(url)}` + }; + + const res: string = await request.post(requestOptions); + const json: ClientSvcResponse = JSON.parse(res); + const response: ClientSvcResponseContents = json[0]; + if (response.ErrorInfo) { + throw response.ErrorInfo.ErrorMessage; } + else { + if (this.verbose) { + await logger.logToStderr('Site collection app catalog disabled'); + } + } + } + catch (err: any) { + this.handleRejectedPromise(err); } + }; + + if (args.options.force) { + await removeSiteAppcatalog(); } - catch (err: any) { - this.handleRejectedPromise(err); + else { + const result = await cli.promptForConfirmation({ message: `Are you sure you want to remove the app catalog from ${args.options.siteUrl}?` }); + + if (result) { + await removeSiteAppcatalog(); + } } } } -export default new SpoSiteAppCatalogRemoveCommand(); \ No newline at end of file +export default new SpoSiteAppCatalogRemoveCommand(); From 669d7149d640a48bdc970f760feff8892694957a Mon Sep 17 00:00:00 2001 From: Nanddeep Nachan Date: Fri, 12 Jul 2024 12:08:05 +0000 Subject: [PATCH 05/20] Aligns options with naming convention. Closes #5616 --- docs/docs/cmd/entra/group/group-user-list.mdx | 14 ++++---- .../m365group-conversation-post-list.mdx | 10 +++--- .../m365group-recyclebinitem-list.mdx | 6 ++-- docs/docs/cmd/outlook/message/message-get.mdx | 10 +++--- .../commands/group/group-user-list.spec.ts | 12 +++---- .../entra/commands/group/group-user-list.ts | 10 +++--- .../m365group-conversation-post-list.spec.ts | 10 +++--- .../m365group-conversation-post-list.ts | 10 +++--- .../m365group-recyclebinitem-list.spec.ts | 8 ++--- .../m365group-recyclebinitem-list.ts | 8 ++--- .../commands/message/message-get.spec.ts | 36 +++++++++---------- .../outlook/commands/message/message-get.ts | 24 ++++++------- 12 files changed, 79 insertions(+), 79 deletions(-) diff --git a/docs/docs/cmd/entra/group/group-user-list.mdx b/docs/docs/cmd/entra/group/group-user-list.mdx index 347b86b401b..6d87aee976f 100644 --- a/docs/docs/cmd/entra/group/group-user-list.mdx +++ b/docs/docs/cmd/entra/group/group-user-list.mdx @@ -22,10 +22,10 @@ m365 aad group user list [options] ```md definition-list `-i, --groupId [groupId]` -: The ID of the Entra group. Specify `groupId` or `groupDisplayName` but not both. +: The ID of the Entra group. Specify `groupId` or `groupName` but not both. -`-n, --groupDisplayName [groupDisplayName]` -: The display name of the Entra group. Specify `groupId` or `groupDisplayName` but not both. +`-n, --groupName [groupName]` +: The display name of the Entra group. Specify `groupId` or `groupName` but not both. `-r, --role [role]` : Filter the results to only users with the given role: `Owner`, `Member`. @@ -54,25 +54,25 @@ m365 entra group user list --groupId 03cba9da-3974-46c1-afaf-79caa2e45bbe List all owners from a group specified by display name. ```sh -m365 entra group user list --groupDisplayName Developers --role Owner +m365 entra group user list --groupName Developers --role Owner ``` List all group users from a group specified by name. For each one return the display name, e-mail address, and manager display name. ```sh -m365 entra group user list --groupDisplayName Developers --properties "displayName,mail,manager/displayName" +m365 entra group user list --groupName Developers --properties "displayName,mail,manager/displayName" ``` List all group users from a group specified by name. For each one return the display name, e-mail address, and manager information. ```sh -m365 entra group user list --groupDisplayName Developers --properties "displayName,mail,manager/*" +m365 entra group user list --groupName Developers --properties "displayName,mail,manager/*" ``` List all group members that are guest users. ```sh -m365 entra group user list --groupDisplayName Developers --filter "userType eq 'Guest'" +m365 entra group user list --groupName Developers --filter "userType eq 'Guest'" ``` ## Response diff --git a/docs/docs/cmd/entra/m365group/m365group-conversation-post-list.mdx b/docs/docs/cmd/entra/m365group/m365group-conversation-post-list.mdx index 539fef72ea2..f24890ed5a8 100644 --- a/docs/docs/cmd/entra/m365group/m365group-conversation-post-list.mdx +++ b/docs/docs/cmd/entra/m365group/m365group-conversation-post-list.mdx @@ -22,10 +22,10 @@ m365 aad m365group conversation post list [options] ```md definition-list `-i, --groupId [groupId]` -: The Id of the Microsoft 365 Group. You can specify the groupId or groupDisplayName, but not both. +: The Id of the Microsoft 365 Group. You can specify the groupId or groupName, but not both. -`-d, --groupDisplayName [groupDisplayName]` -: The Displayname of the Microsoft 365 Group. You can specify the groupId or groupDisplayName, but not both. +`-d, --groupName [groupName]` +: The Displayname of the Microsoft 365 Group. You can specify the groupId or groupName, but not both. `-t, --threadId ` : The ID of the thread to retrieve details for @@ -41,10 +41,10 @@ Lists the posts of the specific conversation of Microsoft 365 group by groupId m365 entra m365group conversation post list --groupId '00000000-0000-0000-0000-000000000000' --threadId 'AAQkADkwN2Q2NDg1LWQ3ZGYtNDViZi1iNGRiLTVhYjJmN2Q5NDkxZQAQAOnRAfDf71lIvrdK85FAn5E=' ``` -Lists the posts of the specific conversation of Microsoft 365 group by groupDisplayName +Lists the posts of the specific conversation of Microsoft 365 group by groupName ```sh -m365 entra m365group conversation post list --groupDisplayName 'MyGroup' --threadId 'AAQkADkwN2Q2NDg1LWQ3ZGYtNDViZi1iNGRiLTVhYjJmN2Q5NDkxZQAQAOnRAfDf71lIvrdK85FAn5E=' +m365 entra m365group conversation post list --groupName 'MyGroup' --threadId 'AAQkADkwN2Q2NDg1LWQ3ZGYtNDViZi1iNGRiLTVhYjJmN2Q5NDkxZQAQAOnRAfDf71lIvrdK85FAn5E=' ``` ## Response diff --git a/docs/docs/cmd/entra/m365group/m365group-recyclebinitem-list.mdx b/docs/docs/cmd/entra/m365group/m365group-recyclebinitem-list.mdx index 6173c72d673..1c7014d6371 100644 --- a/docs/docs/cmd/entra/m365group/m365group-recyclebinitem-list.mdx +++ b/docs/docs/cmd/entra/m365group/m365group-recyclebinitem-list.mdx @@ -21,7 +21,7 @@ m365 aad m365group recyclebinitem list [options] ## Options ```md definition-list -`-d, --groupDisplayName [groupDisplayName]` +`-d, --groupName [groupName]` : Lists groups with DisplayName starting with the specified value `-m, --groupMailNickname [groupMailNickname]` @@ -41,7 +41,7 @@ m365 entra m365group recyclebinitem list List deleted Microsoft 365 Groups with display name starting with _Project_ ```sh -m365 entra m365group recyclebinitem list --groupDisplayName Project +m365 entra m365group recyclebinitem list --groupName Project ``` List deleted Microsoft 365 Groups mail nick name starting with _team_ @@ -53,7 +53,7 @@ m365 entra m365group recyclebinitem list --groupMailNickname team List deleted Microsoft 365 Groups mail nick name starting with _team_ and with display name starting with _Project_ ```sh -m365 entra m365group recyclebinitem list --groupMailNickname team --groupDisplayName Project +m365 entra m365group recyclebinitem list --groupMailNickname team --groupName Project ``` ## Response diff --git a/docs/docs/cmd/outlook/message/message-get.mdx b/docs/docs/cmd/outlook/message/message-get.mdx index d314805b01a..b597cde666c 100644 --- a/docs/docs/cmd/outlook/message/message-get.mdx +++ b/docs/docs/cmd/outlook/message/message-get.mdx @@ -19,10 +19,10 @@ m365 outlook message get [options] : ID of the message. `--userId [userId]` -: ID of the user from which to retrieve the message. Specify either `userId` or `userPrincipalName`, but not both. This option is required when using application permissions. +: ID of the user from which to retrieve the message. Specify either `userId` or `userName`, but not both. This option is required when using application permissions. -`--userPrincipalName [userPrincipalName]` -: UPN of the user from which to retrieve the message Specify either `userId` or `userPrincipalName`, but not both. This option is required when using application permissions. +`--userName [userName]` +: UPN of the user from which to retrieve the message Specify either `userId` or `userName`, but not both. This option is required when using application permissions. ``` @@ -38,7 +38,7 @@ m365 outlook message get --id AAMkAGVmMDEzMTM4LTZmYWUtNDdkNC1hMDZiLTU1OGY5OTZhYm Get a specific message using delegated permissions from a shared mailbox. ```sh -m365 outlook message get --id AAMkAGVmMDEzMTM4LTZmYWUtNDdkNC1hMDZiLTU1OGY5OTZhYmY4OABGAAAAAAAiQ8W967B7TKBjgx9rVEURBwAiIsqMbYjsT5e-T7KzowPTAAAAAAEMAAAiIsqMbYjsT5e-T7KzowPTAALvuv07AAA= --userPrincipalName sharedmailbox@tenant.com +m365 outlook message get --id AAMkAGVmMDEzMTM4LTZmYWUtNDdkNC1hMDZiLTU1OGY5OTZhYmY4OABGAAAAAAAiQ8W967B7TKBjgx9rVEURBwAiIsqMbYjsT5e-T7KzowPTAAAAAAEMAAAiIsqMbYjsT5e-T7KzowPTAALvuv07AAA= --userName sharedmailbox@tenant.com ``` Get a specific message from a specific user retrieved by user ID using application permissions. @@ -50,7 +50,7 @@ m365 outlook message get --id AAMkAGVmMDEzMTM4LTZmYWUtNDdkNC1hMDZiLTU1OGY5OTZhYm Get a specific message from a specific user retrieved by user principal name using application permissions. ```sh -m365 outlook message get --id AAMkAGVmMDEzMTM4LTZmYWUtNDdkNC1hMDZiLTU1OGY5OTZhYmY4OABGAAAAAAAiQ8W967B7TKBjgx9rVEURBwAiIsqMbYjsT5e-T7KzowPTAAAAAAEMAAAiIsqMbYjsT5e-T7KzowPTAALvuv07AAA= --userPrincipalName user@tenant.com +m365 outlook message get --id AAMkAGVmMDEzMTM4LTZmYWUtNDdkNC1hMDZiLTU1OGY5OTZhYmY4OABGAAAAAAAiQ8W967B7TKBjgx9rVEURBwAiIsqMbYjsT5e-T7KzowPTAAAAAAEMAAAiIsqMbYjsT5e-T7KzowPTAALvuv07AAA= --userName user@tenant.com ``` ## Response diff --git a/src/m365/entra/commands/group/group-user-list.spec.ts b/src/m365/entra/commands/group/group-user-list.spec.ts index 0684b4694a6..ff6ff99ef10 100644 --- a/src/m365/entra/commands/group/group-user-list.spec.ts +++ b/src/m365/entra/commands/group/group-user-list.spec.ts @@ -19,7 +19,7 @@ import aadCommands from '../../aadCommands.js'; describe(commands.GROUP_USER_LIST, () => { const groupId = '2c1ba4c4-cd9b-4417-832f-92a34bc34b2a'; - const groupDisplayName = 'CLI Test Group'; + const groupName = 'CLI Test Group'; let log: string[]; let logger: Logger; @@ -180,7 +180,7 @@ describe(commands.GROUP_USER_LIST, () => { throw 'Invalid request'; }); - await command.action(logger, { options: { verbose: true, groupDisplayName: groupDisplayName } }); + await command.action(logger, { options: { verbose: true, groupName: groupName } }); assert(loggerLogSpy.calledOnceWithExactly([ { @@ -235,7 +235,7 @@ describe(commands.GROUP_USER_LIST, () => { }); sinon.stub(request, 'get').callsFake(async opts => { - if (opts.url === `https://graph.microsoft.com/v1.0/groups?$filter=displayName eq '${formatting.encodeQueryParameter(groupDisplayName)}'&$select=id`) { + if (opts.url === `https://graph.microsoft.com/v1.0/groups?$filter=displayName eq '${formatting.encodeQueryParameter(groupName)}'&$select=id`) { return { value: [ { id: '9b1b1e42-794b-4c71-93ac-5ed92488b67f' }, @@ -249,14 +249,14 @@ describe(commands.GROUP_USER_LIST, () => { await assert.rejects(command.action(logger, { options: { - groupDisplayName: groupDisplayName + groupName: groupName } }), new CommandError(`Multiple groups with name 'CLI Test Group' found. Found: 9b1b1e42-794b-4c71-93ac-5ed92488b67f, 9b1b1e42-794b-4c71-93ac-5ed92488b67g.`)); }); it('handles selecting single result when multiple Microsoft Entra groups with the specified name found and cli is set to prompt', async () => { sinon.stub(request, 'get').callsFake(async opts => { - if (opts.url === `https://graph.microsoft.com/v1.0/groups?$filter=displayName eq '${formatting.encodeQueryParameter(groupDisplayName)}'&$select=id`) { + if (opts.url === `https://graph.microsoft.com/v1.0/groups?$filter=displayName eq '${formatting.encodeQueryParameter(groupName)}'&$select=id`) { return { value: [ { id: '9b1b1e42-794b-4c71-93ac-5ed92488b67f' }, @@ -276,7 +276,7 @@ describe(commands.GROUP_USER_LIST, () => { sinon.stub(cli, 'handleMultipleResultsFound').resolves({ id: '9b1b1e42-794b-4c71-93ac-5ed92488b67f' }); - await command.action(logger, { options: { groupDisplayName: groupDisplayName, role: "Owner" } }); + await command.action(logger, { options: { groupName: groupName, role: "Owner" } }); assert(loggerLogSpy.calledOnceWithExactly([ { "id": "00000000-0000-0000-0000-000000000000", diff --git a/src/m365/entra/commands/group/group-user-list.ts b/src/m365/entra/commands/group/group-user-list.ts index 888906ebab4..e6fb34b5c5f 100644 --- a/src/m365/entra/commands/group/group-user-list.ts +++ b/src/m365/entra/commands/group/group-user-list.ts @@ -15,7 +15,7 @@ interface CommandArgs { interface Options extends GlobalOptions { groupId?: string; - groupDisplayName?: string; + groupName?: string; role?: string; properties?: string; filter?: string; @@ -55,7 +55,7 @@ class EntraGroupUserListCommand extends GraphCommand { this.telemetry.push((args: CommandArgs) => { Object.assign(this.telemetryProperties, { groupId: typeof args.options.groupId !== 'undefined', - groupDisplayName: typeof args.options.groupDisplayName !== 'undefined', + groupName: typeof args.options.groupName !== 'undefined', role: typeof args.options.role !== 'undefined', properties: typeof args.options.properties !== 'undefined', filter: typeof args.options.filter !== 'undefined' @@ -69,7 +69,7 @@ class EntraGroupUserListCommand extends GraphCommand { option: "-i, --groupId [groupId]" }, { - option: "-n, --groupDisplayName [groupDisplayName]" + option: "-n, --groupName [groupName]" }, { option: "-r, --role [role]", @@ -87,7 +87,7 @@ class EntraGroupUserListCommand extends GraphCommand { #initOptionSets(): void { this.optionSets.push( { - options: ['groupId', 'groupDisplayName'] + options: ['groupId', 'groupName'] } ); } @@ -154,7 +154,7 @@ class EntraGroupUserListCommand extends GraphCommand { await logger.logToStderr('Retrieving Group Id...'); } - return await entraGroup.getGroupIdByDisplayName(options.groupDisplayName!); + return await entraGroup.getGroupIdByDisplayName(options.groupName!); } private async getUsers(options: Options, role: string, groupId: string, logger: Logger): Promise { diff --git a/src/m365/entra/commands/m365group/m365group-conversation-post-list.spec.ts b/src/m365/entra/commands/m365group/m365group-conversation-post-list.spec.ts index 08c66bf6bc3..994f414c56f 100644 --- a/src/m365/entra/commands/m365group/m365group-conversation-post-list.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-conversation-post-list.spec.ts @@ -135,7 +135,7 @@ describe(commands.M365GROUP_CONVERSATION_POST_LIST, () => { it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['receivedDateTime', 'id']); }); - it('fails validation if groupId and groupDisplayName specified', async () => { + it('fails validation if groupId and groupName specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { return false; @@ -144,10 +144,10 @@ describe(commands.M365GROUP_CONVERSATION_POST_LIST, () => { return defaultValue; }); - const actual = await command.validate({ options: { groupId: '1caf7dcd-7e83-4c3a-94f7-932a1299c844', groupDisplayName: 'MyGroup', threadId: '123' } }, commandInfo); + const actual = await command.validate({ options: { groupId: '1caf7dcd-7e83-4c3a-94f7-932a1299c844', groupName: 'MyGroup', threadId: '123' } }, commandInfo); assert.notStrictEqual(actual, true); }); - it('fails validation if neither groupId nor groupDisplayName specified', async () => { + it('fails validation if neither groupId nor groupName specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { return false; @@ -187,7 +187,7 @@ describe(commands.M365GROUP_CONVERSATION_POST_LIST, () => { jsonOutput.value )); }); - it('Retrieve posts for the specified conversation threadId of m365 group groupDisplayName in the tenant (verbose)', async () => { + it('Retrieve posts for the specified conversation threadId of m365 group groupName in the tenant (verbose)', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if ((opts.url as string).indexOf('/groups?$filter=displayName') > -1) { return { @@ -208,7 +208,7 @@ describe(commands.M365GROUP_CONVERSATION_POST_LIST, () => { await command.action(logger, { options: { verbose: true, - groupDisplayName: "MyGroup", + groupName: "MyGroup", threadId: "AAQkADkwN2Q2NDg1LWQ3ZGYtNDViZi1iNGRiLTVhYjJmN2Q5NDkxZQAQAOnRAfDf71lIvrdK85FAn5E=" } }); diff --git a/src/m365/entra/commands/m365group/m365group-conversation-post-list.ts b/src/m365/entra/commands/m365group/m365group-conversation-post-list.ts index 3c680103a59..a6baa453ed8 100644 --- a/src/m365/entra/commands/m365group/m365group-conversation-post-list.ts +++ b/src/m365/entra/commands/m365group/m365group-conversation-post-list.ts @@ -15,7 +15,7 @@ interface CommandArgs { interface Options extends GlobalOptions { groupId?: string; - groupDisplayName?: string; + groupName?: string; threadId: string; } @@ -45,7 +45,7 @@ class EntraM365GroupConversationPostListCommand extends GraphCommand { this.telemetry.push((args: CommandArgs) => { Object.assign(this.telemetryProperties, { groupId: typeof args.options.groupId !== 'undefined', - groupDisplayName: typeof args.options.groupDisplayName !== 'undefined' + groupName: typeof args.options.groupName !== 'undefined' }); }); } @@ -56,7 +56,7 @@ class EntraM365GroupConversationPostListCommand extends GraphCommand { option: '-i, --groupId [groupId]' }, { - option: '-d, --groupDisplayName [groupDisplayName]' + option: '-d, --groupName [groupName]' }, { option: '-t, --threadId ' @@ -77,7 +77,7 @@ class EntraM365GroupConversationPostListCommand extends GraphCommand { } #initOptionSets(): void { - this.optionSets.push({ options: ['groupId', 'groupDisplayName'] }); + this.optionSets.push({ options: ['groupId', 'groupName'] }); } public defaultProperties(): string[] | undefined { @@ -108,7 +108,7 @@ class EntraM365GroupConversationPostListCommand extends GraphCommand { return formatting.encodeQueryParameter(args.options.groupId); } - const group = await entraGroup.getGroupByDisplayName(args.options.groupDisplayName!); + const group = await entraGroup.getGroupByDisplayName(args.options.groupName!); return group.id!; } } diff --git a/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.spec.ts b/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.spec.ts index b84f15bb9f4..d2d24332087 100644 --- a/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.spec.ts @@ -371,7 +371,7 @@ describe(commands.M365GROUP_RECYCLEBINITEM_LIST, () => { throw 'Invalid request'; }); - await command.action(logger, { options: { groupDisplayName: 'Deleted' } }); + await command.action(logger, { options: { groupName: 'Deleted' } }); assert(loggerLogSpy.calledWith([ { "id": "010d2f0a-0c17-4ec8-b694-e85bbe607013", @@ -605,7 +605,7 @@ describe(commands.M365GROUP_RECYCLEBINITEM_LIST, () => { throw 'Invalid request'; }); - await command.action(logger, { options: { groupDisplayName: 'Deleted', groupMailNickname: 'd_team' } }); + await command.action(logger, { options: { groupName: 'Deleted', groupMailNickname: 'd_team' } }); assert(loggerLogSpy.calledWith([ { "id": "010d2f0a-0c17-4ec8-b694-e85bbe607013", @@ -667,11 +667,11 @@ describe(commands.M365GROUP_RECYCLEBINITEM_LIST, () => { await assert.rejects(command.action(logger, { options: { mailNickname: 'd_team' } }), new CommandError(errorMessage)); }); - it('supports specifying groupDisplayName', () => { + it('supports specifying groupName', () => { const options = command.options; let containsOption = false; options.forEach(o => { - if (o.option.indexOf('--groupDisplayName') > -1) { + if (o.option.indexOf('--groupName') > -1) { containsOption = true; } }); diff --git a/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.ts b/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.ts index 29bc43833e6..93859678918 100644 --- a/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.ts +++ b/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.ts @@ -12,7 +12,7 @@ interface CommandArgs { } interface Options extends GlobalOptions { - groupDisplayName?: string; + groupName?: string; groupMailNickname?: string; } @@ -39,7 +39,7 @@ class EntraM365GroupRecycleBinItemListCommand extends GraphCommand { #initTelemetry(): void { this.telemetry.push((args: CommandArgs) => { Object.assign(this.telemetryProperties, { - groupDisplayName: typeof args.options.groupDisplayName !== 'undefined', + groupName: typeof args.options.groupName !== 'undefined', groupMailNickname: typeof args.options.groupMailNickname !== 'undefined' }); }); @@ -48,7 +48,7 @@ class EntraM365GroupRecycleBinItemListCommand extends GraphCommand { #initOptions(): void { this.options.unshift( { - option: '-d, --groupDisplayName [groupDisplayName]' + option: '-d, --groupName [groupName]' }, { option: '-m, --groupMailNickname [groupMailNickname]' @@ -65,7 +65,7 @@ class EntraM365GroupRecycleBinItemListCommand extends GraphCommand { try { const filter: string = `?$filter=groupTypes/any(c:c+eq+'Unified')`; - const displayNameFilter: string = args.options.groupDisplayName ? ` and startswith(DisplayName,'${formatting.encodeQueryParameter(args.options.groupDisplayName).replace(/'/g, `''`)}')` : ''; + const displayNameFilter: string = args.options.groupName ? ` and startswith(DisplayName,'${formatting.encodeQueryParameter(args.options.groupName).replace(/'/g, `''`)}')` : ''; const mailNicknameFilter: string = args.options.groupMailNickname ? ` and startswith(MailNickname,'${formatting.encodeQueryParameter(args.options.groupMailNickname).replace(/'/g, `''`)}')` : ''; const topCount: string = '&$top=100'; const endpoint: string = `${this.resource}/v1.0/directory/deletedItems/Microsoft.Graph.Group${filter}${displayNameFilter}${mailNicknameFilter}${topCount}`; diff --git a/src/m365/outlook/commands/message/message-get.spec.ts b/src/m365/outlook/commands/message/message-get.spec.ts index 19fb4f5221b..06e4cae741e 100644 --- a/src/m365/outlook/commands/message/message-get.spec.ts +++ b/src/m365/outlook/commands/message/message-get.spec.ts @@ -17,7 +17,7 @@ import { settingsNames } from '../../../../settingsNames.js'; describe(commands.MESSAGE_GET, () => { const messageId = 'AAMkAGVmMDEzMTM4LTZmYWUtNDdkNC1hMDZiLTU1OGY5OTZhYmY4OABGAAAAAAAiQ8W967B7TKBjgx9rVEURBwAiIsqMbYjsT5e-T7KzowPTAAAAAAEMAAAiIsqMbYjsT5e-T7KzowPTAALvuv07AAA='; - const userPrincipalName = 'user@tenant.com'; + const userName = 'user@tenant.com'; const userId = '6799fd1a-723b-4eb7-8e52-41ae530274ca'; const emailResponse = { "id": "AAMkAGVmMDEzMTM4LTZmYWUtNDdkNC1hMDZiLTU1OGY5OTZhYmY4OABGAAAAAAAiQ8W967B7TKBjgx9rVEURBwAiIsqMbYjsT5e-T7KzowPTAAAAAAEMAAAiIsqMbYjsT5e-T7KzowPTAALvuv07AAA=", @@ -144,16 +144,16 @@ describe(commands.MESSAGE_GET, () => { assert(loggerLogSpy.calledWith(emailResponse)); }); - it('retrieves specific message using delegated permissions from a shared mailbox using userPrincipalName as option', async () => { + it('retrieves specific message using delegated permissions from a shared mailbox using userName as option', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { - if (opts.url === `https://graph.microsoft.com/v1.0/users/${userPrincipalName}/messages/${messageId}`) { + if (opts.url === `https://graph.microsoft.com/v1.0/users/${userName}/messages/${messageId}`) { return emailResponse; } throw `Invalid request`; }); - await command.action(logger, { options: { verbose: true, id: messageId, userPrincipalName: userPrincipalName } }); + await command.action(logger, { options: { verbose: true, id: messageId, userName: userName } }); assert(loggerLogSpy.calledWith(emailResponse)); }); @@ -183,18 +183,18 @@ describe(commands.MESSAGE_GET, () => { new CommandError(`Graph error occurred`)); }); - it('retrieves specific message using application permissions and using userPrincipalName as option', async () => { + it('retrieves specific message using application permissions and using userName as option', async () => { sinonUtil.restore([accessToken.isAppOnlyAccessToken]); sinon.stub(accessToken, 'isAppOnlyAccessToken').returns(true); sinon.stub(request, 'get').callsFake(async (opts) => { - if (opts.url === `https://graph.microsoft.com/v1.0/users/${userPrincipalName}/messages/${messageId}`) { + if (opts.url === `https://graph.microsoft.com/v1.0/users/${userName}/messages/${messageId}`) { return emailResponse; } throw `Invalid request`; }); - await command.action(logger, { options: { verbose: true, id: messageId, userPrincipalName: userPrincipalName } }); + await command.action(logger, { options: { verbose: true, id: messageId, userName: userName } }); assert(loggerLogSpy.calledWith(emailResponse)); }); @@ -228,18 +228,18 @@ describe(commands.MESSAGE_GET, () => { new CommandError(`Graph error occurred`)); }); - it('throws error if something fails using application permissions and userPrincipalName as option', async () => { + it('throws error if something fails using application permissions and userName as option', async () => { sinonUtil.restore([accessToken.isAppOnlyAccessToken]); sinon.stub(accessToken, 'isAppOnlyAccessToken').returns(true); sinon.stub(request, 'get').callsFake(async (opts) => { - if (opts.url === `https://graph.microsoft.com/v1.0/users/${userPrincipalName}/messages/${messageId}`) { + if (opts.url === `https://graph.microsoft.com/v1.0/users/${userName}/messages/${messageId}`) { throw `Graph error occurred`; } throw `Invalid request`; }); - await assert.rejects(command.action(logger, { options: { id: messageId, userPrincipalName: userPrincipalName } } as any), + await assert.rejects(command.action(logger, { options: { id: messageId, userName: userName } } as any), new CommandError(`Graph error occurred`)); }); @@ -260,27 +260,27 @@ describe(commands.MESSAGE_GET, () => { assert.equal(actual, true); }); - it('throws an error when the upn or userprincipalname is not defined when signed in using app only authentication', async () => { + it('throws an error when the upn or userName is not defined when signed in using app only authentication', async () => { sinonUtil.restore([accessToken.isAppOnlyAccessToken]); sinon.stub(accessToken, 'isAppOnlyAccessToken').returns(true); await assert.rejects(command.action(logger, { options: { id: messageId } } as any), - new CommandError(`The option 'userId' or 'userPrincipalName' is required when retrieving an email using app only credentials`)); + new CommandError(`The option 'userId' or 'userName' is required when retrieving an email using app only credentials`)); }); - it('throws an error when the upn or userprincipalname are both defined when signed in using app only authentication', async () => { + it('throws an error when the upn or userName are both defined when signed in using app only authentication', async () => { sinonUtil.restore([accessToken.isAppOnlyAccessToken]); sinon.stub(accessToken, 'isAppOnlyAccessToken').returns(true); - await assert.rejects(command.action(logger, { options: { id: messageId, userId: userId, userPrincipalName: userPrincipalName } } as any), - new CommandError(`Both options 'userId' and 'userPrincipalName' cannot be set when retrieving an email using app only credentials`)); + await assert.rejects(command.action(logger, { options: { id: messageId, userId: userId, userName: userName } } as any), + new CommandError(`Both options 'userId' and 'userName' cannot be set when retrieving an email using app only credentials`)); }); - it('throws an error when the upn and userprincipalname are both filled in when signed in using delegated authentication', async () => { + it('throws an error when the upn and userName are both filled in when signed in using delegated authentication', async () => { sinonUtil.restore([accessToken.isAppOnlyAccessToken]); sinon.stub(accessToken, 'isAppOnlyAccessToken').returns(false); - await assert.rejects(command.action(logger, { options: { id: messageId, userId: userId, userPrincipalName: userPrincipalName } } as any), - new CommandError(`Both options 'userId' and 'userPrincipalName' cannot be set when retrieving an email using delegated credentials`)); + await assert.rejects(command.action(logger, { options: { id: messageId, userId: userId, userName: userName } } as any), + new CommandError(`Both options 'userId' and 'userName' cannot be set when retrieving an email using delegated credentials`)); }); }); diff --git a/src/m365/outlook/commands/message/message-get.ts b/src/m365/outlook/commands/message/message-get.ts index 1c68e5fa5a4..f4d3ff066db 100644 --- a/src/m365/outlook/commands/message/message-get.ts +++ b/src/m365/outlook/commands/message/message-get.ts @@ -13,7 +13,7 @@ interface CommandArgs { interface Options extends GlobalOptions { id: string; userId?: string; - userPrincipalName?: string; + userName?: string; } class OutlookMessageGetCommand extends GraphCommand { @@ -36,7 +36,7 @@ class OutlookMessageGetCommand extends GraphCommand { this.telemetry.push((args: CommandArgs) => { Object.assign(this.telemetryProperties, { userId: typeof args.options.userId !== 'undefined', - userPrincipalName: typeof args.options.userPrincipalName !== 'undefined' + userName: typeof args.options.userName !== 'undefined' }); }); } @@ -50,7 +50,7 @@ class OutlookMessageGetCommand extends GraphCommand { option: '--userId [userId]' }, { - option: '--userPrincipalName [userPrincipalName]' + option: '--userName [userName]' } ); } @@ -65,21 +65,21 @@ class OutlookMessageGetCommand extends GraphCommand { let requestUrl = ''; if (isAppOnlyAccessToken) { - if (!args.options.userId && !args.options.userPrincipalName) { - throw `The option 'userId' or 'userPrincipalName' is required when retrieving an email using app only credentials`; + if (!args.options.userId && !args.options.userName) { + throw `The option 'userId' or 'userName' is required when retrieving an email using app only credentials`; } - if (args.options.userId && args.options.userPrincipalName) { - throw `Both options 'userId' and 'userPrincipalName' cannot be set when retrieving an email using app only credentials`; + if (args.options.userId && args.options.userName) { + throw `Both options 'userId' and 'userName' cannot be set when retrieving an email using app only credentials`; } - requestUrl += `users/${args.options.userId ? args.options.userId : args.options.userPrincipalName}`; + requestUrl += `users/${args.options.userId ? args.options.userId : args.options.userName}`; } else { - if (args.options.userId && args.options.userPrincipalName) { - throw `Both options 'userId' and 'userPrincipalName' cannot be set when retrieving an email using delegated credentials`; + if (args.options.userId && args.options.userName) { + throw `Both options 'userId' and 'userName' cannot be set when retrieving an email using delegated credentials`; } - if (args.options.userId || args.options.userPrincipalName) { - requestUrl += `users/${args.options.userId ? args.options.userId : args.options.userPrincipalName}`; + if (args.options.userId || args.options.userName) { + requestUrl += `users/${args.options.userId ? args.options.userId : args.options.userName}`; } else { requestUrl += 'me'; From ccee81647edebe6b92fcab195500443e397da0ae Mon Sep 17 00:00:00 2001 From: Smita Nachan Date: Sun, 14 Jul 2024 08:43:27 +0000 Subject: [PATCH 06/20] Removes duplicate property from 'spo list list' command. Closes #6042 --- docs/docs/cmd/spo/list/list-list.mdx | 12 +++++------- src/m365/spo/commands/list/list-list.spec.ts | 10 ++++------ src/m365/spo/commands/list/list-list.ts | 6 +----- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/docs/docs/cmd/spo/list/list-list.mdx b/docs/docs/cmd/spo/list/list-list.mdx index c30817e392c..e4f4c3acf4f 100644 --- a/docs/docs/cmd/spo/list/list-list.mdx +++ b/docs/docs/cmd/spo/list/list-list.mdx @@ -126,8 +126,7 @@ m365 spo list list --webUrl https://contoso.sharepoint.com/sites/project-x --fil "ParserDisabled": false, "ServerTemplateCanCreateFolders": false, "TemplateFeatureId": "00000000-0000-0000-0000-000000000000", - "Title": "Theme Gallery", - "Url": "/_catalogs/theme" + "Title": "Theme Gallery" } ] ``` @@ -136,17 +135,17 @@ m365 spo list list --webUrl https://contoso.sharepoint.com/sites/project-x --fil ```text - Id Url + Id Title ------------------------------------ ---------------- - 66e5148c-7060-4479-88e7-636d79579148 /_catalogs/theme + 66e5148c-7060-4479-88e7-636d79579148 Theme Gallery ``` ```csv - Id,Url - Theme Gallery,/_catalogs/theme,66e5148c-7060-4479-88e7-636d79579148 + Id,Title + 66e5148c-7060-4479-88e7-636d79579148,Theme Gallery ``` @@ -211,7 +210,6 @@ m365 spo list list --webUrl https://contoso.sharepoint.com/sites/project-x --fil ServerTemplateCanCreateFolders | true TemplateFeatureId | 00000000-0000-0000-0000-000000000000 Title | Theme Gallery - Url | //\_catalogs/theme ``` diff --git a/src/m365/spo/commands/list/list-list.spec.ts b/src/m365/spo/commands/list/list-list.spec.ts index 3ba90c799d3..d664c241213 100644 --- a/src/m365/spo/commands/list/list-list.spec.ts +++ b/src/m365/spo/commands/list/list-list.spec.ts @@ -119,7 +119,7 @@ describe(commands.LIST_LIST, () => { }); it('defines correct properties for the default output', () => { - assert.deepStrictEqual(command.defaultProperties(), ['Title', 'Url', 'Id']); + assert.deepStrictEqual(command.defaultProperties(), ['Title', 'Id']); }); it('retrieves all lists', async () => { @@ -149,8 +149,7 @@ describe(commands.LIST_LIST, () => { ParentWebUrl: "/", RootFolder: { ServerRelativeUrl: "/Lists/test" - }, - Url: "/Lists/test" + } }] }; } @@ -169,8 +168,7 @@ describe(commands.LIST_LIST, () => { ParentWebUrl: "/", RootFolder: { ServerRelativeUrl: "/Lists/test" - }, - Url: "/Lists/test" + } }])); }); @@ -231,4 +229,4 @@ describe(commands.LIST_LIST, () => { const actual = await command.validate({ options: { webUrl: 'https://contoso.sharepoint.com' } }, commandInfo); assert(actual); }); -}); +}); \ No newline at end of file diff --git a/src/m365/spo/commands/list/list-list.ts b/src/m365/spo/commands/list/list-list.ts index c7403ad326a..fbfec3ec0d1 100644 --- a/src/m365/spo/commands/list/list-list.ts +++ b/src/m365/spo/commands/list/list-list.ts @@ -31,7 +31,7 @@ class SpoListListCommand extends SpoCommand { } public defaultProperties(): string[] | undefined { - return ['Title', 'Url', 'Id']; + return ['Title', 'Id']; } constructor() { @@ -85,10 +85,6 @@ class SpoListListCommand extends SpoCommand { } const listInstances = await odata.getAllItems(`${args.options.webUrl}/_api/web/lists?${queryParams.join('&')}`); - listInstances.forEach(l => { - l.Url = l.RootFolder.ServerRelativeUrl; - }); - await logger.log(listInstances); } catch (err: any) { From 6116b66e7a751c21ab897f62f12831442dd2b261 Mon Sep 17 00:00:00 2001 From: Nanddeep Nachan Date: Sun, 4 Aug 2024 17:18:08 +0000 Subject: [PATCH 07/20] Updates 'spo tenant recyclebinitem restore' command. Closes #6063 --- .../tenant/tenant-recyclebinitem-restore.mdx | 51 +------------------ docs/docs/v9-upgrade-guidance.mdx | 9 ++++ .../tenant-recyclebinitem-restore.spec.ts | 15 +----- .../tenant/tenant-recyclebinitem-restore.ts | 26 ---------- 4 files changed, 12 insertions(+), 89 deletions(-) diff --git a/docs/docs/cmd/spo/tenant/tenant-recyclebinitem-restore.mdx b/docs/docs/cmd/spo/tenant/tenant-recyclebinitem-restore.mdx index df4bfd690bd..6b06a9d63a3 100644 --- a/docs/docs/cmd/spo/tenant/tenant-recyclebinitem-restore.mdx +++ b/docs/docs/cmd/spo/tenant/tenant-recyclebinitem-restore.mdx @@ -17,9 +17,6 @@ m365 spo tenant recyclebinitem restore [options] ```md definition-list `-u, --siteUrl ` : URL of the site. - -`--wait` -: (deprecated) Wait for the site collection to be restored before completing the command. ``` @@ -34,7 +31,7 @@ To use this command you must be a Global or SharePoint administrator. ## Examples -Restore a deleted site collection from tenant recycle bin +Restores a deleted site collection from tenant recycle bin. ```sh m365 spo tenant recyclebinitem restore --siteUrl https://contoso.sharepoint.com/sites/team @@ -42,48 +39,4 @@ m365 spo tenant recyclebinitem restore --siteUrl https://contoso.sharepoint.com/ ## Response - - - - ```json - { - "HasTimedout": false, - "IsComplete": true, - "PollingInterval": 15000 - } - ``` - - - - - ```text - HasTimedout : false - IsComplete : true - PollingInterval: 15000 - ``` - - - - - ```csv - HasTimedout,IsComplete,PollingInterval - ,1,15000 - ``` - - - - - ```md - # spo tenant recyclebinitem restore --siteUrl "https://contoso.sharepoint.com/teams/team1" - - Date: 2023-06-22 - - Property | Value - ---------|------- - HasTimedout | false - IsComplete | true - PollingInterval | 15000 - ``` - - - +The command won't return a response on success. diff --git a/docs/docs/v9-upgrade-guidance.mdx b/docs/docs/v9-upgrade-guidance.mdx index 588b94e4c16..f7c00bce579 100644 --- a/docs/docs/v9-upgrade-guidance.mdx +++ b/docs/docs/v9-upgrade-guidance.mdx @@ -21,3 +21,12 @@ Option | Description Update your scripts with the following: - Add the option `--force` if you want to bypass the confirmation prompt and proceed with the removal operation automatically. + +### Removed the deprecated `wait` option and output from the `spo tenant recyclebinitem restore` command + +For this new major version, we've removed the deprecated `wait` option from the `spo tenant recyclebinitem restore` command. The command now won't return a response on success. + +#### What action do I need to take? + +- Please, check the documentation of the [spo tenant recyclebinitem restore](./cmd/spo/tenant/tenant-recyclebinitem-restore.mdx) command to see the updated output and adjust your scripts accordingly. +- In the `spo tenant recyclebinitem restore` command, remove deprecated `wait` option from your scripts. diff --git a/src/m365/spo/commands/tenant/tenant-recyclebinitem-restore.spec.ts b/src/m365/spo/commands/tenant/tenant-recyclebinitem-restore.spec.ts index ec4323fafc4..b3fa35d005c 100644 --- a/src/m365/spo/commands/tenant/tenant-recyclebinitem-restore.spec.ts +++ b/src/m365/spo/commands/tenant/tenant-recyclebinitem-restore.spec.ts @@ -70,19 +70,6 @@ describe(commands.TENANT_RECYCLEBINITEM_RESTORE, () => { assert.notStrictEqual(command.description, null); }); - it(`correctly shows deprecation warning for option 'wait'`, async () => { - const chalk = (await import('chalk')).default; - const loggerErrSpy = sinon.spy(logger, 'logToStderr'); - - sinon.stub(request, 'post').resolves(); - sinon.stub(odata, 'getAllItems').resolves([{ GroupId: '00000000-0000-0000-0000-000000000000' }]); - - await command.action(logger, { options: { siteUrl: siteUrl, wait: true } }); - assert(loggerErrSpy.calledWith(chalk.yellow(`Option 'wait' is deprecated and will be removed in the next major release.`))); - - sinonUtil.restore(loggerErrSpy); - }); - it('fails validation if the url option is not a valid SharePoint site URL', async () => { const actual = await command.validate({ options: { siteUrl: 'foo' } }, commandInfo); assert.notStrictEqual(actual, true); @@ -158,4 +145,4 @@ describe(commands.TENANT_RECYCLEBINITEM_RESTORE, () => { await assert.rejects(command.action(logger, { options: { siteUrl: siteUrl, verbose: true } } as any), new CommandError(error.error['odata.error'].message.value)); }); -}); +}); \ No newline at end of file diff --git a/src/m365/spo/commands/tenant/tenant-recyclebinitem-restore.ts b/src/m365/spo/commands/tenant/tenant-recyclebinitem-restore.ts index 74e427322d8..589f91bb101 100644 --- a/src/m365/spo/commands/tenant/tenant-recyclebinitem-restore.ts +++ b/src/m365/spo/commands/tenant/tenant-recyclebinitem-restore.ts @@ -15,7 +15,6 @@ interface CommandArgs { interface Options extends GlobalOptions { siteUrl: string; - wait?: boolean; } class SpoTenantRecycleBinItemRestoreCommand extends SpoCommand { @@ -30,27 +29,15 @@ class SpoTenantRecycleBinItemRestoreCommand extends SpoCommand { constructor() { super(); - this.#initTelemetry(); this.#initOptions(); this.#initValidators(); this.#initTypes(); } - #initTelemetry(): void { - this.telemetry.push((args: CommandArgs) => { - Object.assign(this.telemetryProperties, { - wait: !!args.options.wait - }); - }); - } - #initOptions(): void { this.options.unshift( { option: '-u, --siteUrl ' - }, - { - option: '--wait' } ); } @@ -63,14 +50,9 @@ class SpoTenantRecycleBinItemRestoreCommand extends SpoCommand { #initTypes(): void { this.types.string.push('siteUrl'); - this.types.boolean.push('wait'); } public async commandAction(logger: Logger, args: CommandArgs): Promise { - if (args.options.wait) { - await this.warn(logger, `Option 'wait' is deprecated and will be removed in the next major release.`); - } - try { if (this.verbose) { await logger.logToStderr(`Restoring site collection '${args.options.siteUrl}' from recycle bin.`); @@ -108,14 +90,6 @@ class SpoTenantRecycleBinItemRestoreCommand extends SpoCommand { await request.post(restoreOptions); } - - // Here, we return a fixed response because this new API endpoint doesn't return a response while the previous API did. - // This has to be removed in the next major release. - await logger.log({ - HasTimedout: false, - IsComplete: !!args.options.wait, - PollingInterval: 15000 - }); } catch (err: any) { this.handleRejectedODataJsonPromise(err); From fb54940e55ee5a2fdc70e3a387b3c25411aa6b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20W=C3=B3jcik?= Date: Mon, 12 Aug 2024 01:00:25 +0200 Subject: [PATCH 08/20] Updates upgrade guidance --- docs/docs/v9-upgrade-guidance.mdx | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/docs/docs/v9-upgrade-guidance.mdx b/docs/docs/v9-upgrade-guidance.mdx index f7c00bce579..04f48dfb2c1 100644 --- a/docs/docs/v9-upgrade-guidance.mdx +++ b/docs/docs/v9-upgrade-guidance.mdx @@ -2,6 +2,26 @@ The v9 of CLI for Microsoft 365 introduces several breaking changes. To help you upgrade to the latest version of CLI for Microsoft 365, we've listed those changes along with any actions you may need to take. +## App + +### Updated option names of 'app permission add' to plural + +We updated the [app permission add](./cmd/app/permission/permission-add.mdx) command. Option were updated to `applicationPermissions` and `delegatedPermissions`. + +#### What action do I need to take? + +- Please, check the documentation of the [app permission add](./cmd/app/permission/permission-add.mdx) command to see the updated options and adjust your scripts accordingly. + +## Entra ID + +### Removed deprecated Guest value from 'aad m365group user list' command. + +The deprecated Guest value was removed from the `role` option in the [aad m365group user list](./cmd/entra/m365group/m365group-user-list.mdx) command. + +#### What action do I need to take? + +- Please, check the documentation of the aad m365group user list](./cmd/entra/m365group/m365group-user-list.mdx) command to see the updated ``role` option and adjust your scripts accordingly. + ## SharePoint ### Updated `spo site appcatalog remove` options @@ -30,3 +50,26 @@ For this new major version, we've removed the deprecated `wait` option from the - Please, check the documentation of the [spo tenant recyclebinitem restore](./cmd/spo/tenant/tenant-recyclebinitem-restore.mdx) command to see the updated output and adjust your scripts accordingly. - In the `spo tenant recyclebinitem restore` command, remove deprecated `wait` option from your scripts. + +#### Aligned options with naming convention + +We updated option naming from `groupDisplayName` to `groupName` and `userPrincipalName` to `userName`. + +**Affected commands:** + +- [entra group user list](./cmd/entra/group/group-user-list.mdx) +- [entra m365group conversation post list](./cmd/entra/m365group/m365group-conversation-post-list.mdx) +- [entra m365group recyclebinitem list](./cmd/entra/m365group/m365group-recyclebinitem-list.mdx) +- [outlook message get](./cmd/outlook/message/message-get.mdx) + +#### What action do I need to take? + +- Please, check the documentation of the affected commands to see the updated option naming and adjust your scripts accordingly. + +### Removes duplicate property from 'spo list list' command. + +In the [spo list list](./cmd/spo/list/list-list.mdx) we removed the `Url` from the command output as it was a duplicate of the `RootFolder/ServerRelativeUrl` property. + +#### What action do I need to take? + +- Please update your scripts not to use the `Url` property from the command output. From 33615bdd5f042db41d5164fa419731bbd905ff2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20W=C3=B3jcik?= Date: Mon, 12 Aug 2024 01:13:21 +0200 Subject: [PATCH 09/20] Updates release notes --- docs/docs/about/release-notes.mdx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/docs/about/release-notes.mdx b/docs/docs/about/release-notes.mdx index b83288331f2..69e96cb5fe0 100644 --- a/docs/docs/about/release-notes.mdx +++ b/docs/docs/about/release-notes.mdx @@ -4,6 +4,17 @@ sidebar_position: 3 # Release notes +## v9.0.0 (beta) + +### Changes + +- updated option names of 'app permission add' to plural [#5719](https://github.com/pnp/cli-microsoft365/issues/5975) +- removed deprecated Guest value from 'aad m365group user list' command [#5558](https://github.com/pnp/cli-microsoft365/issues/5558) +- added `--force` option to 'spo site appcatalog remove' command [#6091](https://github.com/pnp/cli-microsoft365/issues/6091) +- aligned options with naming convention [#5616](https://github.com/pnp/cli-microsoft365/issues/5616) +- removed duplicate property from 'spo list list' command [#6042](https://github.com/pnp/cli-microsoft365/issues/6042) +- updated 'spo tenant recyclebinitem restore' command [#6063](https://github.com/pnp/cli-microsoft365/issues/6063) + ## v8.1.0 (beta) ### New commands From f08bfaa750378777ca378575df92e94032323039 Mon Sep 17 00:00:00 2001 From: Nanddeep Nachan Date: Fri, 12 Jul 2024 08:02:56 +0000 Subject: [PATCH 10/20] Removes deprecated option '--wait' from 'spo site remove' command. Closes #5956 --- docs/docs/cmd/spo/site/site-remove.mdx | 3 -- docs/docs/v9-upgrade-guidance.mdx | 34 ++++++++++++------- .../spo/commands/site/site-remove.spec.ts | 10 ------ src/m365/spo/commands/site/site-remove.ts | 11 +----- 4 files changed, 22 insertions(+), 36 deletions(-) diff --git a/docs/docs/cmd/spo/site/site-remove.mdx b/docs/docs/cmd/spo/site/site-remove.mdx index f699099ef56..c4334eb8b3a 100644 --- a/docs/docs/cmd/spo/site/site-remove.mdx +++ b/docs/docs/cmd/spo/site/site-remove.mdx @@ -22,9 +22,6 @@ m365 spo site remove [options] `--fromRecycleBin` : Set to remove the site from the recycle bin. -`--wait` -: (deprecated) Wait for the site to be removed before completing the command. - `-f, --force` : Don't prompt for confirmation. ``` diff --git a/docs/docs/v9-upgrade-guidance.mdx b/docs/docs/v9-upgrade-guidance.mdx index 04f48dfb2c1..21d2a039a04 100644 --- a/docs/docs/v9-upgrade-guidance.mdx +++ b/docs/docs/v9-upgrade-guidance.mdx @@ -10,7 +10,7 @@ We updated the [app permission add](./cmd/app/permission/permission-add.mdx) com #### What action do I need to take? -- Please, check the documentation of the [app permission add](./cmd/app/permission/permission-add.mdx) command to see the updated options and adjust your scripts accordingly. +Please, check the documentation of the [app permission add](./cmd/app/permission/permission-add.mdx) command to see the updated options and adjust your scripts accordingly. ## Entra ID @@ -20,7 +20,22 @@ The deprecated Guest value was removed from the `role` option in the [aad m365gr #### What action do I need to take? -- Please, check the documentation of the aad m365group user list](./cmd/entra/m365group/m365group-user-list.mdx) command to see the updated ``role` option and adjust your scripts accordingly. +Please, check the documentation of the aad m365group user list](./cmd/entra/m365group/m365group-user-list.mdx) command to see the updated ``role` option and adjust your scripts accordingly. + +#### Aligned options with naming convention + +We updated option naming from `groupDisplayName` to `groupName` and `userPrincipalName` to `userName`. + +**Affected commands:** + +- [entra group user list](./cmd/entra/group/group-user-list.mdx) +- [entra m365group conversation post list](./cmd/entra/m365group/m365group-conversation-post-list.mdx) +- [entra m365group recyclebinitem list](./cmd/entra/m365group/m365group-recyclebinitem-list.mdx) +- [outlook message get](./cmd/outlook/message/message-get.mdx) + +#### What action do I need to take? + +Please, check the documentation of the affected commands to see the updated option naming and adjust your scripts accordingly. ## SharePoint @@ -51,20 +66,13 @@ For this new major version, we've removed the deprecated `wait` option from the - Please, check the documentation of the [spo tenant recyclebinitem restore](./cmd/spo/tenant/tenant-recyclebinitem-restore.mdx) command to see the updated output and adjust your scripts accordingly. - In the `spo tenant recyclebinitem restore` command, remove deprecated `wait` option from your scripts. -#### Aligned options with naming convention - -We updated option naming from `groupDisplayName` to `groupName` and `userPrincipalName` to `userName`. +### Removed the deprecated `wait` option and output from the `spo site remove` command -**Affected commands:** - -- [entra group user list](./cmd/entra/group/group-user-list.mdx) -- [entra m365group conversation post list](./cmd/entra/m365group/m365group-conversation-post-list.mdx) -- [entra m365group recyclebinitem list](./cmd/entra/m365group/m365group-recyclebinitem-list.mdx) -- [outlook message get](./cmd/outlook/message/message-get.mdx) +For this new major version, we've removed the deprecated `wait` option from the `spo site remove` command. #### What action do I need to take? -- Please, check the documentation of the affected commands to see the updated option naming and adjust your scripts accordingly. +In the [spo site remove](./cmd/spo/site/site-remove.mdx) command, remove deprecated `wait` option from your scripts. ### Removes duplicate property from 'spo list list' command. @@ -72,4 +80,4 @@ In the [spo list list](./cmd/spo/list/list-list.mdx) we removed the `Url` from t #### What action do I need to take? -- Please update your scripts not to use the `Url` property from the command output. +Please update your scripts not to use the `Url` property from the command output. diff --git a/src/m365/spo/commands/site/site-remove.spec.ts b/src/m365/spo/commands/site/site-remove.spec.ts index ef3b68596a9..28f8b4f4334 100644 --- a/src/m365/spo/commands/site/site-remove.spec.ts +++ b/src/m365/spo/commands/site/site-remove.spec.ts @@ -360,16 +360,6 @@ describe(commands.SITE_REMOVE, () => { new CommandError('Site is currently not in the recycle bin. Remove --fromRecycleBin if you want to remove it as active site.')); }); - it(`correctly shows deprecation warning for option 'wait'`, async () => { - const chalk = (await import('chalk')).default; - const loggerErrSpy = sinon.spy(logger, 'logToStderr'); - - await command.action(logger, { options: { url: siteUrl, wait: true } }); - assert(loggerErrSpy.calledWith(chalk.yellow(`Option 'wait' is deprecated and will be removed in the next major release.`))); - - sinonUtil.restore(loggerErrSpy); - }); - it('prompts before removing the site when force option not passed', async () => { await command.action(logger, { options: { url: siteUrl, verbose: true } }); assert(promptIssued); diff --git a/src/m365/spo/commands/site/site-remove.ts b/src/m365/spo/commands/site/site-remove.ts index 775f460d38f..39bcf717d5b 100644 --- a/src/m365/spo/commands/site/site-remove.ts +++ b/src/m365/spo/commands/site/site-remove.ts @@ -19,7 +19,6 @@ interface Options extends GlobalOptions { url: string; skipRecycleBin?: boolean; fromRecycleBin?: boolean; - wait?: boolean; force?: boolean; } @@ -55,7 +54,6 @@ class SpoSiteRemoveCommand extends SpoCommand { Object.assign(this.telemetryProperties, { skipRecycleBin: !!args.options.skipRecycleBin, fromRecycleBin: !!args.options.fromRecycleBin, - wait: !!args.options.wait, force: !!args.options.force }); }); @@ -72,9 +70,6 @@ class SpoSiteRemoveCommand extends SpoCommand { { option: '--fromRecycleBin' }, - { - option: '--wait' - }, { option: '-f, --force' } @@ -105,14 +100,10 @@ class SpoSiteRemoveCommand extends SpoCommand { #initTypes(): void { this.types.string.push('url'); - this.types.boolean.push('skipRecycleBin', 'fromRecycleBin', 'wait', 'force'); + this.types.boolean.push('skipRecycleBin', 'fromRecycleBin', 'force'); } public async commandAction(logger: Logger, args: CommandArgs): Promise { - if (args.options.wait) { - await this.warn(logger, `Option 'wait' is deprecated and will be removed in the next major release.`); - } - if (args.options.force) { await this.removeSite(logger, args.options); } From 4e76fbfbabe640f5133f03892b7f7756aa3d30df Mon Sep 17 00:00:00 2001 From: Milan Holemans <11723921+milanholemans@users.noreply.github.com> Date: Sun, 11 Aug 2024 01:06:04 +0200 Subject: [PATCH 11/20] Reworks command 'spo file copy' to new API endpoint. Closes #6152 --- docs/docs/cmd/spo/file/file-copy.mdx | 131 ++++- docs/docs/v9-upgrade-guidance.mdx | 18 + src/m365/spo/commands/file/file-copy.spec.ts | 488 ++++++++++++------- src/m365/spo/commands/file/file-copy.ts | 107 ++-- src/utils/spo.spec.ts | 285 ++++++++++- src/utils/spo.ts | 113 ++++- 6 files changed, 911 insertions(+), 231 deletions(-) diff --git a/docs/docs/cmd/spo/file/file-copy.mdx b/docs/docs/cmd/spo/file/file-copy.mdx index e9bea634c00..bee5fa717fd 100644 --- a/docs/docs/cmd/spo/file/file-copy.mdx +++ b/docs/docs/cmd/spo/file/file-copy.mdx @@ -1,4 +1,6 @@ import Global from '/docs/cmd/_global.mdx'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; # spo file copy @@ -31,11 +33,14 @@ m365 spo file copy [options] `--nameConflictBehavior [nameConflictBehavior]` : Behavior when a document with the same name is already present at the destination. Allowed values: `fail`, `replace`, `rename`. Defaults to `fail`. -`--resetAuthorAndCreated` -: Use this option to clear the author and created date. When not specified, the values from the source file are used. - `--bypassSharedLock` : This indicates whether a file with a share lock can still be copied. Use this option to copy a file that is locked. + +`--ignoreVersionHistory` +: Only copy the most recent version of the file and ignore the version history. + +`--skipWait` +: Don't wait for the copy operation to complete. ``` @@ -43,7 +48,6 @@ m365 spo file copy [options] ## Remarks When you specify a value for `nameConflictBehavior`, consider the following: - - `fail` will throw an error when the destination file already exists. - `replace` will replace the destination file if it already exists. - `rename` will add a suffix (e.g. Document1.pdf) when the destination file already exists. @@ -56,16 +60,16 @@ Copy a file by server-relative URL to a document library in another site collect m365 spo file copy --webUrl https://contoso.sharepoint.com/sites/project --sourceUrl "/sites/project/Shared Documents/Document.pdf" --targetUrl "/sites/IT/Shared Documents" ``` -Copy a file by site-relative URL to a document library in another site collection and clear the author and created date. +Copy a file by site-relative URL to a document library in another site collection and ignore the file history. ```sh -m365 spo file copy --webUrl https://contoso.sharepoint.com/sites/project --sourceUrl "/Shared Documents/Document.pdf" --targetUrl "/sites/IT/Shared Documents" --resetAuthorAndCreated +m365 spo file copy --webUrl https://contoso.sharepoint.com/sites/project --sourceUrl "/Shared Documents/Document.pdf" --targetUrl "/sites/IT/Shared Documents" --ignoreVersionHistory ``` -Copy file by sourceId (UniqueId) to a document library in another site collection and rename the file. +Copy file by sourceId (UniqueId) to a document library in another site collection and rename the file (without specifying the file extension). ```sh -m365 spo file copy --webUrl https://contoso.sharepoint.com/sites/project --sourceId "b2307a39-e878-458b-bc90-03bc578531d6" --targetUrl "/sites/IT/Shared Documents" --newName "Report.pdf" +m365 spo file copy --webUrl https://contoso.sharepoint.com/sites/project --sourceId "b2307a39-e878-458b-bc90-03bc578531d6" --targetUrl "/sites/IT/Shared Documents" --newName "Report" ``` Copy file by sourceId (UniqueId) to a document library in another site collection with a new name, rename the file if it already exists. @@ -76,8 +80,111 @@ m365 spo file copy --webUrl https://contoso.sharepoint.com/sites/project --sourc ## Response -The command won't return a response on success. - -## More information +### Standard Response + + + + + ```json + { + "CheckInComment": "", + "CheckOutType": 2, + "ContentTag": "{03E171B6-9DF2-46D9-A7A1-D5FA0BD23E4B},1,1", + "CustomizedPageStatus": 0, + "ETag": "\"{03E171B6-9DF2-46D9-A7A1-D5FA0BD23E4B},1\"", + "Exists": true, + "IrmEnabled": false, + "Length": "5987", + "Level": 1, + "LinkingUri": null, + "LinkingUrl": "", + "MajorVersion": 1, + "MinorVersion": 0, + "Name": "Test1.docx", + "ServerRelativeUrl": "/sites/project-x/documents/Test1.docx", + "TimeCreated": "2022-10-30T10:16:18Z", + "TimeLastModified": "2022-10-30T10:16:18Z", + "Title": null, + "UIVersion": 512, + "UIVersionLabel": "1.0", + "UniqueId": "b2307a39-e878-458b-bc90-03bc578531d6" + } + ``` + + + + + ```text + CheckInComment : + CheckOutType : 2 + ContentTag : {03E171B6-9DF2-46D9-A7A1-D5FA0BD23E4B},1,1 + CustomizedPageStatus: 0 + ETag : "{03E171B6-9DF2-46D9-A7A1-D5FA0BD23E4B},1" + Exists : true + IrmEnabled : false + Length : 5987 + Level : 1 + LinkingUri : null + LinkingUrl : + MajorVersion : 1 + MinorVersion : 0 + Name : Test1.docx + ServerRelativeUrl : /sites/project-x/documents/Test1.docx + TimeCreated : 2022-10-30T10:16:18Z + TimeLastModified : 2022-10-30T10:16:18Z + Title : null + UIVersion : 512 + UIVersionLabel : 1.0 + UniqueId : b2307a39-e878-458b-bc90-03bc578531d6 + ``` + + + + + ```csv + CheckInComment,CheckOutType,ContentTag,CustomizedPageStatus,ETag,Exists,IrmEnabled,Length,Level,LinkingUri,LinkingUrl,MajorVersion,MinorVersion,Name,ServerRelativeUrl,TimeCreated,TimeLastModified,Title,UIVersion,UIVersionLabel,UniqueId + ,2,"{03E171B6-9DF2-46D9-A7A1-D5FA0BD23E4B},1,1",0,"""{03E171B6-9DF2-46D9-A7A1-D5FA0BD23E4B},1""",1,,5987,1,,,1,0,Test1.docx,/sites/project-x/documents/Test1.docx,2022-10-30T10:16:18Z,2022-10-30T10:16:18Z,,512,1.0,b2307a39-e878-458b-bc90-03bc578531d6 + ``` + + + + + ```md + # spo file copy --webUrl "https://contoso.sharepoint.com/sites/IT" --sourceUrl "/Shared Documents/Document.docx" --targetUrl "/sites/project-x/Shared Documents" + + Date: 10/3/2023 + + ## b2307a39-e878-458b-bc90-03bc578531d6 + + Property | Value + ---------|------- + CheckInComment | + CheckOutType | 2 + ContentTag | {03E171B6-9DF2-46D9-A7A1-D5FA0BD23E4B},1,1 + CustomizedPageStatus | 0 + ETag | "{03E171B6-9DF2-46D9-A7A1-D5FA0BD23E4B},1" + Exists | true + ExistsAllowThrowForPolicyFailures | true + IrmEnabled | false + Length | 5987 + Level | 1 + LinkingUri | https://contoso.sharepoint.com/sites/project-x/shared%20documents/Document.docx?d=w59d4e6fcf6f94ce78bea0273cedb1a19 + LinkingUrl | https://contoso.sharepoint.com/sites/project-x/shared documents/Document.docx?d=w59d4e6fcf6f94ce78bea0273cedb1a19 + MajorVersion | 1 + MinorVersion | 0 + Name | Document.docx + ServerRelativeUrl | /sites/project-x/shared documents/Document.docx + TimeCreated | 2023-05-23T09:51:34Z + TimeLastModified | 2023-05-23T10:13:01Z + Title | + UIVersion | 1536 + UIVersionLabel | 1.0 + UniqueId | b2307a39-e878-458b-bc90-03bc578531d6 + ``` + + + + +### `skipWait` response -- Copy items from a SharePoint document library: [https://support.office.com/en-us/article/move-or-copy-items-from-a-sharepoint-document-library-00e2f483-4df3-46be-a861-1f5f0c1a87bc](https://support.office.com/en-us/article/move-or-copy-items-from-a-sharepoint-document-library-00e2f483-4df3-46be-a861-1f5f0c1a87bc) +The command won't return a response on success. diff --git a/docs/docs/v9-upgrade-guidance.mdx b/docs/docs/v9-upgrade-guidance.mdx index 21d2a039a04..3431a0d4f6b 100644 --- a/docs/docs/v9-upgrade-guidance.mdx +++ b/docs/docs/v9-upgrade-guidance.mdx @@ -81,3 +81,21 @@ In the [spo list list](./cmd/spo/list/list-list.mdx) we removed the `Url` from t #### What action do I need to take? Please update your scripts not to use the `Url` property from the command output. + +### Updated command `spo file copy` + +Because of some limitations of the current [spo file copy](./cmd/spo/file/file-copy.mdx) command, we have decided to move it to a new endpoint. This change is necessary to ensure the command's functionality and reliability. Because of the new endpoint, the command input and output have changed. + +**Command options:** + +Unfortunately, we had to drop the `--resetAuthorAndCreated` options as it's no longer supported by the new endpoint. In return, we were able to add two new options: +- `--ignoreVersionHistory`: Only copy the most recent version of the file and ignore the version history. +- `--skipWait`: Don't wait for the copy operation to complete. + +**Command output:** + +In the past versions of CLI for Microsoft 365, the command had no output. When using option `--nameConflictBehavior rename`, it's hard for the user to know what the actual name of the copied file is. With the new endpoint, the command now returns the file information about the destination file, providing you with all the info you need to execute other commands on this file. + +#### What action do I need to take? + +When using the [spo file copy](./cmd/spo/file/file-copy.mdx) command, please use the new command input. This means that you'll have to remove option `--resetAuthorAndCreated` from your scripts and automation tools. diff --git a/src/m365/spo/commands/file/file-copy.spec.ts b/src/m365/spo/commands/file/file-copy.spec.ts index 9e6fba938f2..55cc6f2907e 100644 --- a/src/m365/spo/commands/file/file-copy.spec.ts +++ b/src/m365/spo/commands/file/file-copy.spec.ts @@ -13,20 +13,77 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './file-copy.js'; import { settingsNames } from '../../../../settingsNames.js'; +import { CreateCopyJobsNameConflictBehavior, spo } from '../../../../utils/spo.js'; describe(commands.FILE_COPY, () => { - const webUrl = 'https://contoso.sharepoint.com/sites/project'; - const documentName = 'Document.pdf'; - const relSourceUrl = '/sites/project/Documents/' + documentName; - const absoluteSourceUrl = 'https://contoso.sharepoint.com/sites/project/Documents/' + documentName; - const sourceId = 'f09c4efe-b8c0-4e89-a166-03418661b89b'; - const relTargetUrl = '/sites/project/Documents'; - const absoluteTargetUrl = 'https://contoso.sharepoint.com/sites/project/Documents'; + const sourceWebUrl = 'https://contoso.sharepoint.com/sites/Sales'; + const sourceDocumentName = 'Document.pdf'; + const sourceServerRelUrl = '/sites/Sales/Shared Documents/' + sourceDocumentName; + const sourceAbsoluteUrl = 'https://contoso.sharepoint.com' + sourceServerRelUrl; + const sourceDocId = 'f09c4efe-b8c0-4e89-a166-03418661b89b'; + + const destWebUrl = 'https://contoso.sharepoint.com/sites/Marketing'; + const destSiteRelUrl = '/Documents/Logos'; + const destServerRelUrl = '/sites/Marketing' + destSiteRelUrl; + const destAbsoluteTargetUrl = 'https://contoso.sharepoint.com' + destServerRelUrl; + const destDocId = '15488d89-b82b-40be-958a-922b2ed79383'; + + const copyJobInfo = { + EncryptionKey: '2by8+2oizihYOFqk02Tlokj8lWUShePAEE+WMuA9lzA=', + JobId: 'd812e5a0-d95a-4e4f-bcb7-d4415e88c8ee', + JobQueueUri: 'https://spoam1db1m020p4.queue.core.windows.net/2-1499-20240831-29533e6c72c6464780b756c71ea3fe92?sv=2018-03-28&sig=aX%2BNOkUimZ3f%2B%2BvdXI95%2FKJI1e5UE6TU703Dw3Eb5c8%3D&st=2024-08-09T00%3A00%3A00Z&se=2024-08-31T00%3A00%3A00Z&sp=rap', + SourceListItemUniqueIds: [ + sourceDocId + ] + }; + + const copyJobResult = { + Event: 'JobFinishedObjectInfo', + JobId: '6d1eda82-0d1c-41eb-ab05-1d9cd4afe786', + Time: '08/10/2024 18:59:40.145', + SourceObjectFullUrl: sourceAbsoluteUrl, + TargetServerUrl: 'https://contoso.sharepoint.com', + TargetSiteId: '794dada8-4389-45ce-9559-0de74bf3554a', + TargetWebId: '8de9b4d3-3c30-4fd0-a9d7-2452bd065555', + TargetListId: '44b336a5-e397-4e22-a270-c39e9069b123', + TargetObjectUniqueId: destDocId, + TargetObjectSiteRelativeUrl: destSiteRelUrl.substring(1), + CorrelationId: '5efd44a1-c034-9000-9692-4e1a1b3ca33b' + }; + + const destFileResponse = { + CheckInComment: '', + CheckOutType: 2, + ContentTag: '{C194762B-3F54-4F5F-9F5C-EBA26084E29D},53,23', + CustomizedPageStatus: 0, + ETag: '"{C194762B-3F54-4F5F-9F5C-EBA26084E29D},53"', + Exists: true, + ExistsAllowThrowForPolicyFailures: true, + ExistsWithException: true, + IrmEnabled: false, + Length: '18911', + Level: 1, + LinkingUri: `${destAbsoluteTargetUrl + '/' + sourceDocumentName}?d=wc194762b3f544f5f9f5ceba26084e29d`, + LinkingUrl: '', + MajorVersion: 14, + MinorVersion: 0, + Name: sourceDocumentName, + ServerRelativeUrl: destServerRelUrl + '/' + sourceDocumentName, + TimeCreated: '2024-05-01T19:54:50Z', + TimeLastModified: '2024-08-10T19:31:34Z', + Title: '', + UIVersion: 7168, + UIVersionLabel: '14.0', + UniqueId: destDocId + }; let log: any[]; let logger: Logger; - let requestPostStub: sinon.SinonStub; let commandInfo: CommandInfo; + let loggerLogSpy: sinon.SinonSpy; + + let spoUtilCreateCopyJobStub: sinon.SinonStub; + let spoUtilGetCopyJobResultStub: sinon.SinonStub; before(() => { sinon.stub(auth, 'restoreAuth').resolves(); @@ -35,13 +92,9 @@ describe(commands.FILE_COPY, () => { sinon.stub(session, 'getId').returns(''); auth.connection.active = true; commandInfo = cli.getCommandInfo(command); - sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName: string, defaultValue: any) => { - if (settingName === 'prompt') { - return false; - } - return defaultValue; - }); + sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName: string, defaultValue: any) => settingName === settingsNames.prompt ? false : defaultValue); + spoUtilCreateCopyJobStub = sinon.stub(spo, 'createCopyJob').resolves(copyJobInfo); }); beforeEach(() => { @@ -58,21 +111,15 @@ describe(commands.FILE_COPY, () => { } }; - requestPostStub = sinon.stub(request, 'post').callsFake(async (opts) => { - if (opts.url === `${webUrl}/_api/SP.MoveCopyUtil.CopyFileByPath`) { - return { - 'odata.null': true - }; - } - - throw 'Invalid request URL: ' + opts.url; - }); + loggerLogSpy = sinon.spy(logger, 'log'); + spoUtilGetCopyJobResultStub = sinon.stub(spo, 'getCopyJobResult').resolves(copyJobResult); }); afterEach(() => { sinonUtil.restore([ request.post, - cli.getSettingWithDefaultValue + request.get, + spo.getCopyJobResult ]); }); @@ -90,276 +137,355 @@ describe(commands.FILE_COPY, () => { }); it('fails validation if the webUrl option is not a valid SharePoint site URL', async () => { - const actual = await command.validate({ options: { webUrl: 'foo', sourceUrl: absoluteSourceUrl, targetUrl: absoluteTargetUrl } }, commandInfo); + const actual = await command.validate({ options: { webUrl: 'foo', sourceUrl: sourceAbsoluteUrl, targetUrl: destAbsoluteTargetUrl } }, commandInfo); assert.notStrictEqual(actual, true); }); it('fails validation if the sourceId option is not a valid GUID', async () => { - const actual = await command.validate({ options: { webUrl: webUrl, sourceId: 'invalid', targetUrl: absoluteTargetUrl } }, commandInfo); + const actual = await command.validate({ options: { webUrl: sourceWebUrl, sourceId: 'invalid', targetUrl: destAbsoluteTargetUrl } }, commandInfo); assert.notStrictEqual(actual, true); }); it('passes validation if the sourceId option is a valid GUID', async () => { - const actual = await command.validate({ options: { webUrl: webUrl, sourceId: sourceId, targetUrl: absoluteTargetUrl } }, commandInfo); + const actual = await command.validate({ options: { webUrl: sourceWebUrl, sourceId: sourceDocId, targetUrl: destAbsoluteTargetUrl } }, commandInfo); assert(actual); }); it('fails validation if both sourceId and sourceUrl options are not specified', async () => { - sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { - if (settingName === settingsNames.prompt) { - return false; - } - - return defaultValue; - }); - - const actual = await command.validate({ options: { webUrl: webUrl, targetUrl: absoluteTargetUrl } }, commandInfo); + const actual = await command.validate({ options: { webUrl: sourceWebUrl, targetUrl: destAbsoluteTargetUrl } }, commandInfo); assert.notStrictEqual(actual, true); }); it('fails validation if both sourceId and url options are specified', async () => { - sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { - if (settingName === settingsNames.prompt) { - return false; - } - - return defaultValue; - }); - - const actual = await command.validate({ options: { webUrl: webUrl, sourceId: sourceId, sourceUrl: absoluteSourceUrl, targetUrl: absoluteTargetUrl } }, commandInfo); + const actual = await command.validate({ options: { webUrl: sourceWebUrl, sourceId: sourceDocId, sourceUrl: sourceAbsoluteUrl, targetUrl: destAbsoluteTargetUrl } }, commandInfo); assert.notStrictEqual(actual, true); }); it('fails validation if nameConflictBehavior has an invalid value', async () => { - const actual = await command.validate({ options: { webUrl: webUrl, sourceUrl: absoluteSourceUrl, targetUrl: absoluteTargetUrl, nameConflictBehavior: 'invalid' } }, commandInfo); + const actual = await command.validate({ options: { webUrl: sourceWebUrl, sourceUrl: sourceAbsoluteUrl, targetUrl: destAbsoluteTargetUrl, nameConflictBehavior: 'invalid' } }, commandInfo); assert.notStrictEqual(actual, true); }); - it('passes validation if all required properties are provided', async () => { - const actual = await command.validate({ options: { webUrl: webUrl, sourceUrl: absoluteSourceUrl, targetUrl: absoluteTargetUrl } }, commandInfo); + it('passes validation if all required options are provided', async () => { + const actual = await command.validate({ options: { webUrl: sourceWebUrl, sourceUrl: sourceAbsoluteUrl, targetUrl: destAbsoluteTargetUrl } }, commandInfo); assert.strictEqual(actual, true); }); - it('copies file with sourceId successfully when absolute URLs are provided', async () => { + it('passes validation if all required options are provided with optional', async () => { + const actual = await command.validate({ options: { webUrl: sourceWebUrl, sourceUrl: sourceAbsoluteUrl, targetUrl: destAbsoluteTargetUrl, ignoreVersionHistory: true, nameConflictBehavior: 'RePlAcE' } }, commandInfo); + assert.strictEqual(actual, true); + }); + + it('correctly outputs exactly one result when file is copied when using sourceId', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { - if (opts.url === `${webUrl}/_api/Web/GetFileById('${sourceId}')?$select=ServerRelativePath`) { + if (opts.url === `${sourceWebUrl}/_api/Web/GetFileById('${sourceDocId}')/ServerRelativePath`) { return { - ServerRelativePath: { - DecodedUrl: absoluteTargetUrl + `/${documentName}` - } + DecodedUrl: destAbsoluteTargetUrl + `/${sourceDocumentName}` }; } + + if (opts.url === `${destWebUrl}/_api/Web/GetFileById('${destDocId}')`) { + return destFileResponse; + } + throw 'Invalid request: ' + opts.url; }); await command.action(logger, { options: { verbose: true, - webUrl: webUrl, - sourceId: sourceId, - targetUrl: absoluteTargetUrl + webUrl: sourceWebUrl, + sourceId: sourceDocId, + targetUrl: destAbsoluteTargetUrl } }); - const response = { - srcPath: { - DecodedUrl: absoluteSourceUrl - }, - destPath: { - DecodedUrl: absoluteTargetUrl + `/${documentName}` - }, - overwrite: false, - options: { - KeepBoth: false, - ResetAuthorAndCreatedOnCopy: false, - ShouldBypassSharedLocks: false + assert(loggerLogSpy.calledOnce); + }); + + it('correctly outputs result when file is copied when using sourceId', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `${sourceWebUrl}/_api/Web/GetFileById('${sourceDocId}')/ServerRelativePath`) { + return { + DecodedUrl: sourceAbsoluteUrl + }; } - }; - assert.deepStrictEqual(requestPostStub.lastCall.args[0].data, response); - }); + if (opts.url === `${destWebUrl}/_api/Web/GetFileById('${destDocId}')`) { + return destFileResponse; + } + + throw 'Invalid request: ' + opts.url; + }); - it('copies file with absolute url successfully when absolute URLs are provided', async () => { await command.action(logger, { options: { verbose: true, - webUrl: webUrl, - sourceUrl: absoluteSourceUrl, - targetUrl: absoluteTargetUrl + webUrl: sourceWebUrl, + sourceId: sourceDocId, + targetUrl: destAbsoluteTargetUrl } }); - const response = { - srcPath: { - DecodedUrl: absoluteSourceUrl - }, - destPath: { - DecodedUrl: absoluteTargetUrl + `/${documentName}` - }, - overwrite: false, - options: { - KeepBoth: false, - ResetAuthorAndCreatedOnCopy: false, - ShouldBypassSharedLocks: false + assert.deepStrictEqual(loggerLogSpy.lastCall.args[0], destFileResponse); + }); + + it('correctly outputs exactly one result when file is copied when using sourceUrl', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `${destWebUrl}/_api/Web/GetFileById('${destDocId}')`) { + return destFileResponse; } - }; - assert.deepStrictEqual(requestPostStub.lastCall.args[0].data, response); - }); + throw 'Invalid request: ' + opts.url; + }); - it('copies file with relative url successfully when server relative URLs are provided', async () => { await command.action(logger, { options: { verbose: true, - webUrl: webUrl, - sourceUrl: relSourceUrl, - targetUrl: relTargetUrl + webUrl: sourceWebUrl, + sourceUrl: sourceServerRelUrl, + targetUrl: destAbsoluteTargetUrl } }); - const response = { - srcPath: { - DecodedUrl: absoluteSourceUrl - }, - destPath: { - DecodedUrl: absoluteTargetUrl + `/${documentName}` - }, - overwrite: false, - options: { - KeepBoth: false, - ResetAuthorAndCreatedOnCopy: false, - ShouldBypassSharedLocks: false + assert(loggerLogSpy.calledOnce); + }); + + it('correctly outputs result when file is copied when using sourceUrl', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `${destWebUrl}/_api/Web/GetFileById('${destDocId}')`) { + return destFileResponse; } - }; - assert.deepStrictEqual(requestPostStub.lastCall.args[0].data, response); - }); + throw 'Invalid request: ' + opts.url; + }); - it('copies file with relative url successfully with a new name', async () => { await command.action(logger, { options: { verbose: true, - webUrl: webUrl, - sourceUrl: relSourceUrl, - targetUrl: relTargetUrl, - newName: 'Document-renamed.pdf' + webUrl: sourceWebUrl, + sourceUrl: sourceServerRelUrl, + targetUrl: destAbsoluteTargetUrl } }); - const response = { - srcPath: { - DecodedUrl: absoluteSourceUrl - }, - destPath: { - DecodedUrl: absoluteTargetUrl + '/Document-renamed.pdf' - }, - overwrite: false, + assert.deepStrictEqual(loggerLogSpy.lastCall.args[0], destFileResponse); + }); + + it('correctly copies a file when using sourceId', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `${sourceWebUrl}/_api/Web/GetFileById('${sourceDocId}')/ServerRelativePath`) { + return { + DecodedUrl: sourceAbsoluteUrl + }; + } + + if (opts.url === `${destWebUrl}/_api/Web/GetFileById('${destDocId}')`) { + return destFileResponse; + } + + throw 'Invalid request: ' + opts.url; + }); + + await command.action(logger, { options: { - KeepBoth: false, - ResetAuthorAndCreatedOnCopy: false, - ShouldBypassSharedLocks: false + webUrl: sourceWebUrl, + sourceId: sourceDocId, + targetUrl: destAbsoluteTargetUrl } - }; + }); - assert.deepStrictEqual(requestPostStub.lastCall.args[0].data, response); + assert.deepStrictEqual(spoUtilCreateCopyJobStub.lastCall.args, [ + sourceWebUrl, + sourceAbsoluteUrl, + destAbsoluteTargetUrl, + { + nameConflictBehavior: CreateCopyJobsNameConflictBehavior.Fail, + bypassSharedLock: false, + ignoreVersionHistory: false, + newName: undefined + } + ]); }); - it('copies file with relative url successfully with nameConflictBehavior fail', async () => { + it('correctly copies a file when using sourceUrl', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `${destWebUrl}/_api/Web/GetFileById('${destDocId}')`) { + return destFileResponse; + } + + throw 'Invalid request: ' + opts.url; + }); + await command.action(logger, { options: { - verbose: true, - webUrl: webUrl, - sourceUrl: relSourceUrl, - targetUrl: relTargetUrl, + webUrl: sourceWebUrl, + sourceUrl: sourceServerRelUrl, + targetUrl: destAbsoluteTargetUrl, nameConflictBehavior: 'fail' } }); - assert.strictEqual(requestPostStub.lastCall.args[0].data.overwrite, false, 'Overwrite option is not false'); - assert.strictEqual(requestPostStub.lastCall.args[0].data.options.KeepBoth, false, 'KeepBoth option is not false'); + assert.deepStrictEqual(spoUtilCreateCopyJobStub.lastCall.args, [ + sourceWebUrl, + sourceAbsoluteUrl, + destAbsoluteTargetUrl, + { + nameConflictBehavior: CreateCopyJobsNameConflictBehavior.Fail, + bypassSharedLock: false, + ignoreVersionHistory: false, + newName: undefined + } + ]); }); - it('copies file with relative url successfully with nameConflictBehavior replace', async () => { + it('correctly copies a file when using sourceUrl with extra options', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `${destWebUrl}/_api/Web/GetFileById('${destDocId}')`) { + return destFileResponse; + } + + throw 'Invalid request: ' + opts.url; + }); + await command.action(logger, { options: { - verbose: true, - webUrl: webUrl, - sourceUrl: relSourceUrl, - targetUrl: relTargetUrl, - nameConflictBehavior: 'replace' + webUrl: sourceWebUrl, + sourceUrl: sourceServerRelUrl, + targetUrl: destAbsoluteTargetUrl, + nameConflictBehavior: 'rename', + bypassSharedLock: true, + ignoreVersionHistory: true, + newName: 'Document-renamed.pdf' } }); - assert.strictEqual(requestPostStub.lastCall.args[0].data.overwrite, true, 'Overwrite option is not true'); - assert.strictEqual(requestPostStub.lastCall.args[0].data.options.KeepBoth, false, 'KeepBoth option is not false'); + assert.deepStrictEqual(spoUtilCreateCopyJobStub.lastCall.args, [ + sourceWebUrl, + sourceAbsoluteUrl, + destAbsoluteTargetUrl, + { + nameConflictBehavior: CreateCopyJobsNameConflictBehavior.Rename, + bypassSharedLock: true, + ignoreVersionHistory: true, + newName: 'Document-renamed.pdf' + } + ]); }); - it('copies file with relative url successfully with nameConflictBehavior rename', async () => { + it('correctly copies a file when using sourceUrl with new name without extension', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `${destWebUrl}/_api/Web/GetFileById('${destDocId}')`) { + return destFileResponse; + } + + throw 'Invalid request: ' + opts.url; + }); + await command.action(logger, { options: { - verbose: true, - webUrl: webUrl, - sourceUrl: relSourceUrl, - targetUrl: relTargetUrl, - nameConflictBehavior: 'rename' + webUrl: sourceWebUrl, + sourceUrl: sourceServerRelUrl, + targetUrl: destAbsoluteTargetUrl, + nameConflictBehavior: 'replace', + newName: 'Document-renamed' } }); - assert.strictEqual(requestPostStub.lastCall.args[0].data.overwrite, false, 'Overwrite option is not false'); - assert.strictEqual(requestPostStub.lastCall.args[0].data.options.KeepBoth, true, 'KeepBoth option is not true'); + assert.deepStrictEqual(spoUtilCreateCopyJobStub.lastCall.args, [ + sourceWebUrl, + sourceAbsoluteUrl, + destAbsoluteTargetUrl, + { + nameConflictBehavior: CreateCopyJobsNameConflictBehavior.Replace, + bypassSharedLock: false, + ignoreVersionHistory: false, + newName: 'Document-renamed.pdf' + } + ]); }); - it('copies file with relative url successfully with bypassSharedLock option', async () => { + it('correctly polls for the copy job to finish', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `${destWebUrl}/_api/Web/GetFileById('${destDocId}')`) { + return destFileResponse; + } + + throw 'Invalid request: ' + opts.url; + }); + await command.action(logger, { options: { - verbose: true, - webUrl: webUrl, - sourceUrl: relSourceUrl, - targetUrl: relTargetUrl, - bypassSharedLock: true + webUrl: sourceWebUrl, + sourceUrl: sourceServerRelUrl, + targetUrl: destAbsoluteTargetUrl + } + }); + + assert.deepStrictEqual(spoUtilGetCopyJobResultStub.lastCall.args, [ + sourceWebUrl, + copyJobInfo + ]); + }); + + it('outputs no result when skipWait is specified', async () => { + await command.action(logger, { + options: { + webUrl: sourceWebUrl, + sourceUrl: sourceServerRelUrl, + targetUrl: destAbsoluteTargetUrl, + skipWait: true } }); - assert.strictEqual(requestPostStub.lastCall.args[0].data.options.ShouldBypassSharedLocks, true); + assert(loggerLogSpy.notCalled); }); - it('copies file with relative url successfully with resetAuthorAndCreated option', async () => { + it('correctly skips polling when skipWait is specified', async () => { await command.action(logger, { options: { - verbose: true, - webUrl: webUrl, - sourceUrl: relSourceUrl, - targetUrl: relTargetUrl, - resetAuthorAndCreated: true + webUrl: sourceWebUrl, + sourceUrl: sourceServerRelUrl, + targetUrl: destAbsoluteTargetUrl, + skipWait: true } }); - assert.strictEqual(requestPostStub.lastCall.args[0].data.options.ResetAuthorAndCreatedOnCopy, true); + assert(spoUtilGetCopyJobResultStub.notCalled); }); - it('handles file not found error correctly', async () => { - const errorMessage = 'File Not Found.'; - requestPostStub.restore(); - sinon.stub(request, 'post').callsFake(async () => { - throw { - error: { - 'odata.error': { - message: { - lang: 'en-US', - value: errorMessage - } + it('correctly handles error when sourceId does not exist', async () => { + sinon.stub(request, 'get').rejects({ + error: { + 'odata.error': { + code: '-2147024894, System.IO.FileNotFoundException', + message: { + lang: 'en-US', + value: 'File Not Found.' } } - }; + } }); await assert.rejects(command.action(logger, { options: { - verbose: true, - webUrl: webUrl, - sourceUrl: relSourceUrl, - targetUrl: relTargetUrl + webUrl: sourceWebUrl, + sourceId: sourceDocId, + targetUrl: destAbsoluteTargetUrl + } + }), new CommandError('File Not Found.')); + }); + + it('correctly handles error when getCopyJobResult fails', async () => { + spoUtilGetCopyJobResultStub.restore(); + spoUtilGetCopyJobResultStub = sinon.stub(spo, 'getCopyJobResult').rejects(new Error('Target file already exists.')); + + await assert.rejects(command.action(logger, { + options: { + webUrl: sourceWebUrl, + sourceUrl: sourceServerRelUrl, + targetUrl: destAbsoluteTargetUrl } - }), new CommandError(errorMessage)); + }), new CommandError('Target file already exists.')); }); }); diff --git a/src/m365/spo/commands/file/file-copy.ts b/src/m365/spo/commands/file/file-copy.ts index b386b45f8e2..757ca8232c1 100644 --- a/src/m365/spo/commands/file/file-copy.ts +++ b/src/m365/spo/commands/file/file-copy.ts @@ -1,6 +1,7 @@ import { Logger } from '../../../../cli/Logger.js'; import GlobalOptions from '../../../../GlobalOptions.js'; import request, { CliRequestOptions } from '../../../../request.js'; +import { CreateCopyJobsNameConflictBehavior, spo } from '../../../../utils/spo.js'; import { urlUtil } from '../../../../utils/urlUtil.js'; import { validation } from '../../../../utils/validation.js'; import SpoCommand from '../../../base/SpoCommand.js'; @@ -17,8 +18,9 @@ interface Options extends GlobalOptions { targetUrl: string; newName?: string; nameConflictBehavior?: string; - resetAuthorAndCreated?: boolean; bypassSharedLock?: boolean; + ignoreVersionHistory?: boolean; + skipWait?: boolean; } class SpoFileCopyCommand extends SpoCommand { @@ -46,9 +48,10 @@ class SpoFileCopyCommand extends SpoCommand { sourceUrl: typeof args.options.sourceUrl !== 'undefined', sourceId: typeof args.options.sourceId !== 'undefined', newName: typeof args.options.newName !== 'undefined', - nameConflictBehavior: args.options.nameConflictBehavior || false, - resetAuthorAndCreated: !!args.options.resetAuthorAndCreated, - bypassSharedLock: !!args.options.bypassSharedLock + nameConflictBehavior: typeof args.options.nameConflictBehavior !== 'undefined', + ignoreVersionHistory: !!args.options.ignoreVersionHistory, + bypassSharedLock: !!args.options.bypassSharedLock, + skipWait: !!args.options.skipWait }); }); } @@ -76,10 +79,13 @@ class SpoFileCopyCommand extends SpoCommand { autocomplete: this.nameConflictBehaviorOptions }, { - option: '--resetAuthorAndCreated' + option: '--bypassSharedLock' }, { - option: '--bypassSharedLock' + option: '--ignoreVersionHistory' + }, + { + option: '--skipWait' } ); } @@ -96,7 +102,7 @@ class SpoFileCopyCommand extends SpoCommand { return `${args.options.sourceId} is not a valid GUID for sourceId.`; } - if (args.options.nameConflictBehavior && this.nameConflictBehaviorOptions.indexOf(args.options.nameConflictBehavior) === -1) { + if (args.options.nameConflictBehavior && !this.nameConflictBehaviorOptions.includes(args.options.nameConflictBehavior.toLowerCase())) { return `${args.options.nameConflictBehavior} is not a valid nameConflictBehavior value. Allowed values: ${this.nameConflictBehaviorOptions.join(', ')}.`; } @@ -111,50 +117,65 @@ class SpoFileCopyCommand extends SpoCommand { #initTypes(): void { this.types.string.push('webUrl', 'sourceUrl', 'sourceId', 'targetUrl', 'newName', 'nameConflictBehavior'); - this.types.boolean.push('resetAuthorAndCreated', 'bypassSharedLock'); + this.types.boolean.push('bypassSharedLock', 'ignoreVersionHistory', 'skipWait'); } public async commandAction(logger: Logger, args: CommandArgs): Promise { try { const sourceServerRelativePath = await this.getSourcePath(logger, args.options); const sourcePath = this.getAbsoluteUrl(args.options.webUrl, sourceServerRelativePath); - let destinationPath = this.getAbsoluteUrl(args.options.webUrl, args.options.targetUrl) + '/'; + const destinationPath = this.getAbsoluteUrl(args.options.webUrl, args.options.targetUrl); + + if (this.verbose) { + await logger.logToStderr(`Copying file '${sourceServerRelativePath}' to '${args.options.targetUrl}'...`); + } - if (args.options.newName) { - destinationPath += args.options.newName; + let newName = args.options.newName; + // Add original file extension if not provided + if (newName && !newName.includes('.')) { + newName += sourceServerRelativePath.substring(sourceServerRelativePath.lastIndexOf('.')); } - else { - // Keep the original file name - destinationPath += sourcePath.substring(sourcePath.lastIndexOf('/') + 1); + + const copyJobResponse = await spo.createCopyJob( + args.options.webUrl, + sourcePath, + destinationPath, + { + nameConflictBehavior: this.getNameConflictBehaviorValue(args.options.nameConflictBehavior), + bypassSharedLock: !!args.options.bypassSharedLock, + ignoreVersionHistory: !!args.options.ignoreVersionHistory, + newName: newName + } + ); + + if (args.options.skipWait) { + return; } if (this.verbose) { - await logger.logToStderr(`Copying file '${sourcePath}' to '${destinationPath}'...`); + await logger.logToStderr('Waiting for the copy job to complete...'); } + const copyJobResult = await spo.getCopyJobResult(args.options.webUrl, copyJobResponse); + + if (this.verbose) { + await logger.logToStderr('Getting information about the destination file...'); + } + + // Get destination file data + const siteRelativeDestinationFolder = '/' + copyJobResult.TargetObjectSiteRelativeUrl.substring(0, copyJobResult.TargetObjectSiteRelativeUrl.lastIndexOf('/')); + const absoluteWebUrl = destinationPath.substring(0, destinationPath.toLowerCase().lastIndexOf(siteRelativeDestinationFolder.toLowerCase())); + const requestOptions: CliRequestOptions = { - url: `${args.options.webUrl}/_api/SP.MoveCopyUtil.CopyFileByPath`, + url: `${absoluteWebUrl}/_api/Web/GetFileById('${copyJobResult.TargetObjectUniqueId}')`, headers: { accept: 'application/json;odata=nometadata' }, - responseType: 'json', - data: { - srcPath: { - DecodedUrl: sourcePath - }, - destPath: { - DecodedUrl: destinationPath - }, - overwrite: args.options.nameConflictBehavior === 'replace', - options: { - KeepBoth: args.options.nameConflictBehavior === 'rename', - ResetAuthorAndCreatedOnCopy: !!args.options.resetAuthorAndCreated, - ShouldBypassSharedLocks: !!args.options.bypassSharedLock - } - } + responseType: 'json' }; - await request.post(requestOptions); + const destinationFile = await request.get(requestOptions); + await logger.log(destinationFile); } catch (err: any) { this.handleRejectedODataJsonPromise(err); @@ -171,19 +192,33 @@ class SpoFileCopyCommand extends SpoCommand { } const requestOptions: CliRequestOptions = { - url: `${options.webUrl}/_api/Web/GetFileById('${options.sourceId}')?$select=ServerRelativePath`, + url: `${options.webUrl}/_api/Web/GetFileById('${options.sourceId}')/ServerRelativePath`, headers: { accept: 'application/json;odata=nometadata' }, responseType: 'json' }; - const file = await request.get<{ ServerRelativePath: { DecodedUrl: string } }>(requestOptions); - return file.ServerRelativePath.DecodedUrl; + const file = await request.get<{ DecodedUrl: string }>(requestOptions); + return file.DecodedUrl; + } + + private getNameConflictBehaviorValue(nameConflictBehavior?: string): CreateCopyJobsNameConflictBehavior { + switch (nameConflictBehavior?.toLowerCase()) { + case 'fail': + return CreateCopyJobsNameConflictBehavior.Fail; + case 'replace': + return CreateCopyJobsNameConflictBehavior.Replace; + case 'rename': + return CreateCopyJobsNameConflictBehavior.Rename; + default: + return CreateCopyJobsNameConflictBehavior.Fail; + } } private getAbsoluteUrl(webUrl: string, url: string): string { - return url.startsWith('https://') ? url : urlUtil.getAbsoluteUrl(webUrl, url); + const result = url.startsWith('https://') ? url : urlUtil.getAbsoluteUrl(webUrl, url); + return urlUtil.removeTrailingSlashes(result); } } diff --git a/src/utils/spo.spec.ts b/src/utils/spo.spec.ts index bf7f71612e3..7d07e39d646 100644 --- a/src/utils/spo.spec.ts +++ b/src/utils/spo.spec.ts @@ -7,7 +7,7 @@ import config from '../config.js'; import { RoleDefinition } from '../m365/spo/commands/roledefinition/RoleDefinition.js'; import request from '../request.js'; import { sinonUtil } from '../utils/sinonUtil.js'; -import { FormDigestInfo, SpoOperation, spo } from '../utils/spo.js'; +import { CreateCopyJobsNameConflictBehavior, FormDigestInfo, SpoOperation, spo, settings } from '../utils/spo.js'; import { entraGroup } from './entraGroup.js'; import { formatting } from './formatting.js'; import { Group } from '@microsoft/microsoft-graph-types'; @@ -78,6 +78,15 @@ const entraGroupResponse = { UserPrincipalName: null }; +const copyJobInfo = { + EncryptionKey: "2by8+2oizihYOFqk02Tlokj8lWUShePAEE+WMuA9lzA=", + JobId: "d812e5a0-d95a-4e4f-bcb7-d4415e88c8ee", + JobQueueUri: "https://spoam1db1m020p4.queue.core.windows.net/2-1499-20240831-29533e6c72c6464780b756c71ea3fe92?sv=2018-03-28&sig=aX%2BNOkUimZ3f%2B%2BvdXI95%2FKJI1e5UE6TU703Dw3Eb5c8%3D&st=2024-08-09T00%3A00%3A00Z&se=2024-08-31T00%3A00%3A00Z&sp=rap", + SourceListItemUniqueIds: [ + 'c194762b-3f54-4f5f-9f5c-eba26084e29d' + ] +}; + describe('utils/spo', () => { let logger: Logger; let log: string[]; @@ -85,6 +94,7 @@ describe('utils/spo', () => { before(() => { auth.connection.active = true; + sinon.stub(settings, 'pollingInterval').value(0); }); beforeEach(() => { @@ -2512,4 +2522,277 @@ describe('utils/spo', () => { }); assert.strictEqual(amountOfCalls, 4); }); + + it('correctly outputs result when calling createCopyJob', async () => { + sinon.stub(request, 'post').callsFake(async (opts) => { + if (opts.url === 'https://contoso.sharepoint.com/sites/sales/_api/Site/CreateCopyJobs') { + return { + value: [ + copyJobInfo + ] + }; + } + + throw 'Invalid request: ' + opts.url; + }); + + const result = await spo.createCopyJob('https://contoso.sharepoint.com/sites/sales', 'https://contoso.sharepoint.com/sites/sales/Icons/Company.png', 'https://contoso.sharepoint.com/sites/marketing/Shared Documents'); + assert.deepStrictEqual(result, copyJobInfo); + }); + + it('correctly creates a copy job with default options when using createCopyJob', async () => { + const postStub = sinon.stub(request, 'post').callsFake(async (opts) => { + if (opts.url === 'https://contoso.sharepoint.com/sites/sales/_api/Site/CreateCopyJobs') { + return { + value: [ + copyJobInfo + ] + }; + } + + throw 'Invalid request: ' + opts.url; + }); + + await spo.createCopyJob('https://contoso.sharepoint.com/sites/sales', 'https://contoso.sharepoint.com/sites/sales/Icons/Company.png', 'https://contoso.sharepoint.com/sites/marketing/Shared Documents'); + assert.deepStrictEqual(postStub.firstCall.args[0].data, { + destinationUri: 'https://contoso.sharepoint.com/sites/marketing/Shared Documents', + exportObjectUris: ['https://contoso.sharepoint.com/sites/sales/Icons/Company.png'], + options: { + NameConflictBehavior: CreateCopyJobsNameConflictBehavior.Fail, + AllowSchemaMismatch: true, + BypassSharedLock: false, + IgnoreVersionHistory: false, + CustomizedItemName: undefined, + SameWebCopyMoveOptimization: true + } + }); + }); + + it('correctly creates a copy job with custom options when using createCopyJob', async () => { + const postStub = sinon.stub(request, 'post').callsFake(async (opts) => { + if (opts.url === 'https://contoso.sharepoint.com/sites/sales/_api/Site/CreateCopyJobs') { + return { + value: [ + copyJobInfo + ] + }; + } + + throw 'Invalid request: ' + opts.url; + }); + + await spo.createCopyJob( + 'https://contoso.sharepoint.com/sites/sales', + 'https://contoso.sharepoint.com/sites/sales/Icons/Company.png', + 'https://contoso.sharepoint.com/sites/marketing/Shared Documents', + { + nameConflictBehavior: CreateCopyJobsNameConflictBehavior.Rename, + bypassSharedLock: true, + ignoreVersionHistory: true, + newName: 'CompanyV2.png' + } + ); + assert.deepStrictEqual(postStub.firstCall.args[0].data, { + destinationUri: 'https://contoso.sharepoint.com/sites/marketing/Shared Documents', + exportObjectUris: ['https://contoso.sharepoint.com/sites/sales/Icons/Company.png'], + options: { + NameConflictBehavior: CreateCopyJobsNameConflictBehavior.Rename, + AllowSchemaMismatch: true, + BypassSharedLock: true, + IgnoreVersionHistory: true, + CustomizedItemName: ['CompanyV2.png'], + SameWebCopyMoveOptimization: true + } + }); + }); + + it('correctly polls for copy job status when using getCopyJobResult', async () => { + const postStub = sinon.stub(request, 'post').callsFake(async (opts) => { + if (opts.url === 'https://contoso.sharepoint.com/sites/sales/_api/Site/GetCopyJobProgress') { + if (postStub.callCount < 5) { + return { + JobState: 4, + Logs: [] + }; + } + + return { + JobState: 0, + Logs: [ + JSON.stringify({ + Event: 'JobStart', + JobId: 'fb4cc143-383c-4da0-bd91-02d2acbb01c7', + Time: '08/10/2024 16:30:39.004', + SiteId: '53dec431-9d4f-415b-b12b-010259d5b4e1', + WebId: 'af102f32-b389-49dc-89bf-d116a17e0aa6', + DBId: '5a926054-85d7-4cf6-85f0-c38fa01c4d39', + FarmId: '823af112-cd95-49a2-adf5-eccb09c8ba5d', + ServerId: 'a6145d7e-1b85-4124-895e-b1e618bfe5ae', + SubscriptionId: '18c58817-3bc9-489d-ac63-f7264fb357e5', + TotalRetryCount: '0', + MigrationType: 'Copy', + MigrationDirection: 'Import', + CorrelationId: 'd8f444a1-10a8-9000-862c-0bad6eff1006' + }), + JSON.stringify({ + Event: 'JobFinishedObjectInfo', + JobId: '6d1eda82-0d1c-41eb-ab05-1d9cd4afe786', + Time: '08/10/2024 18:59:40.145', + SourceObjectFullUrl: 'https://contoso.sharepoint.com/sites/marketing/Shared Documents/Icons/Company.png', + TargetServerUrl: 'https://contoso.sharepoint.com', + TargetSiteId: '794dada8-4389-45ce-9559-0de74bf3554a', + TargetWebId: '8de9b4d3-3c30-4fd0-a9d7-2452bd065555', + TargetListId: '44b336a5-e397-4e22-a270-c39e9069b123', + TargetObjectUniqueId: '15488d89-b82b-40be-958a-922b2ed79383', + TargetObjectSiteRelativeUrl: 'Shared Documents/Icons/Company.png', + CorrelationId: '5efd44a1-c034-9000-9692-4e1a1b3ca33b' + }), + JSON.stringify({ + Event: 'JobEnd', + JobId: 'fb4cc143-383c-4da0-bd91-02d2acbb01c7', + Time: '08/10/2024 16:30:39.008', + TotalRetryCount: '0', + MigrationType: 'Copy', + MigrationDirection: 'Import', + CorrelationId: 'd8f444a1-10a8-9000-862c-0bad6eff1006' + }) + ] + }; + } + + throw 'Invalid request: ' + opts.url; + }); + + await spo.getCopyJobResult('https://contoso.sharepoint.com/sites/sales', copyJobInfo); + + const postRequests = postStub.getCalls(); + postRequests.forEach((request) => + assert.deepStrictEqual(request.args[0].data, { copyJobInfo: copyJobInfo }) + ); + }); + + it('correctly returns result when using getCopyJobResult', async () => { + sinon.stub(request, 'post').callsFake(async (opts) => { + if (opts.url === 'https://contoso.sharepoint.com/sites/sales/_api/Site/GetCopyJobProgress') { + return { + JobState: 0, + Logs: [ + JSON.stringify({ + Event: 'JobStart', + JobId: 'fb4cc143-383c-4da0-bd91-02d2acbb01c7', + Time: '08/10/2024 16:30:39.004', + SiteId: '53dec431-9d4f-415b-b12b-010259d5b4e1', + WebId: 'af102f32-b389-49dc-89bf-d116a17e0aa6', + DBId: '5a926054-85d7-4cf6-85f0-c38fa01c4d39', + FarmId: '823af112-cd95-49a2-adf5-eccb09c8ba5d', + ServerId: 'a6145d7e-1b85-4124-895e-b1e618bfe5ae', + SubscriptionId: '18c58817-3bc9-489d-ac63-f7264fb357e5', + TotalRetryCount: '0', + MigrationType: 'Copy', + MigrationDirection: 'Import', + CorrelationId: 'd8f444a1-10a8-9000-862c-0bad6eff1006' + }), + JSON.stringify({ + Event: 'JobFinishedObjectInfo', + JobId: '6d1eda82-0d1c-41eb-ab05-1d9cd4afe786', + Time: '08/10/2024 18:59:40.145', + SourceObjectFullUrl: 'https://contoso.sharepoint.com/sites/marketing/Shared Documents/Icons/Company.png', + TargetServerUrl: 'https://contoso.sharepoint.com', + TargetSiteId: '794dada8-4389-45ce-9559-0de74bf3554a', + TargetWebId: '8de9b4d3-3c30-4fd0-a9d7-2452bd065555', + TargetListId: '44b336a5-e397-4e22-a270-c39e9069b123', + TargetObjectUniqueId: '15488d89-b82b-40be-958a-922b2ed79383', + TargetObjectSiteRelativeUrl: 'Shared Documents/Icons/Company.png', + CorrelationId: '5efd44a1-c034-9000-9692-4e1a1b3ca33b' + }), + JSON.stringify({ + Event: 'JobEnd', + JobId: 'fb4cc143-383c-4da0-bd91-02d2acbb01c7', + Time: '08/10/2024 16:30:39.008', + TotalRetryCount: '0', + MigrationType: 'Copy', + MigrationDirection: 'Import', + CorrelationId: 'd8f444a1-10a8-9000-862c-0bad6eff1006' + }) + ] + }; + } + + throw 'Invalid request: ' + opts.url; + }); + + const result = await spo.getCopyJobResult('https://contoso.sharepoint.com/sites/sales', copyJobInfo); + assert.deepStrictEqual(result, + { + Event: 'JobFinishedObjectInfo', + JobId: '6d1eda82-0d1c-41eb-ab05-1d9cd4afe786', + Time: '08/10/2024 18:59:40.145', + SourceObjectFullUrl: 'https://contoso.sharepoint.com/sites/marketing/Shared Documents/Icons/Company.png', + TargetServerUrl: 'https://contoso.sharepoint.com', + TargetSiteId: '794dada8-4389-45ce-9559-0de74bf3554a', + TargetWebId: '8de9b4d3-3c30-4fd0-a9d7-2452bd065555', + TargetListId: '44b336a5-e397-4e22-a270-c39e9069b123', + TargetObjectUniqueId: '15488d89-b82b-40be-958a-922b2ed79383', + TargetObjectSiteRelativeUrl: 'Shared Documents/Icons/Company.png', + CorrelationId: '5efd44a1-c034-9000-9692-4e1a1b3ca33b' + } + ); + }); + + it('correctly throws error when using getCopyJobResult', async () => { + sinon.stub(request, 'post').callsFake(async (opts) => { + if (opts.url === 'https://contoso.sharepoint.com/sites/sales/_api/Site/GetCopyJobProgress') { + return { + JobState: 0, + Logs: [ + JSON.stringify({ + Event: 'JobStart', + JobId: 'fb4cc143-383c-4da0-bd91-02d2acbb01c7', + Time: '08/10/2024 16:30:39.004', + SiteId: '53dec431-9d4f-415b-b12b-010259d5b4e1', + WebId: 'af102f32-b389-49dc-89bf-d116a17e0aa6', + DBId: '5a926054-85d7-4cf6-85f0-c38fa01c4d39', + FarmId: '823af112-cd95-49a2-adf5-eccb09c8ba5d', + ServerId: 'a6145d7e-1b85-4124-895e-b1e618bfe5ae', + SubscriptionId: '18c58817-3bc9-489d-ac63-f7264fb357e5', + TotalRetryCount: '0', + MigrationType: 'Copy', + MigrationDirection: 'Import', + CorrelationId: 'd8f444a1-10a8-9000-862c-0bad6eff1006' + }), + JSON.stringify({ + Event: 'JobError', + JobId: 'fb4cc143-383c-4da0-bd91-02d2acbb01c7', + Time: '08/10/2024 16:30:39.007', + TotalRetryCount: '0', + MigrationType: 'Copy', + MigrationDirection: 'Import', + ObjectType: 'File', + Url: 'Shared Documents/Icons/Company.png', + Id: 'c194762b-3f54-4f5f-9f5c-eba26084e29d', + SourceListItemIntId: '38', + ErrorCode: '-2147024713', + Message: 'A file or folder with the name Company.png already exists at the destination.', + TargetListItemIntId: 'f9628bfc-1e80-4486-aa3e-25d1f1ac67f9', + CorrelationId: 'd8f444a1-10a8-9000-862c-0bad6eff1006' + }), + JSON.stringify({ + Event: 'JobEnd', + JobId: 'fb4cc143-383c-4da0-bd91-02d2acbb01c7', + Time: '08/10/2024 16:30:39.008', + TotalRetryCount: '0', + MigrationType: 'Copy', + MigrationDirection: 'Import', + CorrelationId: 'd8f444a1-10a8-9000-862c-0bad6eff1006' + }) + ] + }; + } + + throw 'Invalid request: ' + opts.url; + }); + + await assert.rejects(spo.getCopyJobResult('https://contoso.sharepoint.com/sites/sales', copyJobInfo), + new Error('A file or folder with the name Company.png already exists at the destination.')); + }); }); \ No newline at end of file diff --git a/src/utils/spo.ts b/src/utils/spo.ts index 7f99aca451e..13cd276e06e 100644 --- a/src/utils/spo.ts +++ b/src/utils/spo.ts @@ -21,7 +21,8 @@ import { WebProperties } from '../m365/spo/commands/web/WebProperties.js'; import { Group, Site } from '@microsoft/microsoft-graph-types'; import { ListItemInstance } from '../m365/spo/commands/listitem/ListItemInstance.js'; import { ListItemFieldValueResult } from '../m365/spo/commands/listitem/ListItemFieldValueResult.js'; -import { FileProperties } from '../m365/spo/commands/file/FileProperties.js'; import { setTimeout } from 'timers/promises'; +import { FileProperties } from '../m365/spo/commands/file/FileProperties.js'; +import { setTimeout } from 'timers/promises'; export interface ContextInfo { FormDigestTimeoutSeconds: number; @@ -88,6 +89,45 @@ export interface User { UserPrincipalName: string | null; } +interface CreateCopyJobsOptions { + nameConflictBehavior?: CreateCopyJobsNameConflictBehavior; + bypassSharedLock?: boolean; + ignoreVersionHistory?: boolean; + newName?: string; +} + +export enum CreateCopyJobsNameConflictBehavior { + Fail = 0, + Replace = 1, + Rename = 2, +} + +interface CreateCopyJobInfo { + EncryptionKey: string; + JobId: string; + JobQueueUri: string; + SourceListItemUniqueIds: string[]; +} + +interface CopyJobObjectInfo { + Event: string; + JobId: string; + Time: string; + SourceObjectFullUrl: string; + TargetServerUrl: string; + TargetSiteId: string; + TargetWebId: string; + TargetListId: string; + TargetObjectUniqueId: string; + TargetObjectSiteRelativeUrl: string; + CorrelationId: string; +} + +// Wrapping this into a settings object so we can alter the values in tests +export const settings = { + pollingInterval: 3_000 +}; + export const spo = { async getRequestDigest(siteUrl: string): Promise { const requestOptions: CliRequestOptions = { @@ -1822,5 +1862,76 @@ export const spo = { const itemsResponse = await request.get(requestOptionsItems); return (itemsResponse); + }, + + /** + * Create a SharePoint copy job to copy a file/folder to another location. + * @param webUrl Absolute web URL where the source file/folder is located. + * @param sourceUrl Absolute URL of the source file/folder. + * @param destinationUrl Absolute URL of the destination folder. + * @param options Options for the copy job. + * @returns Copy job information. Use {@link spo.getCopyJobResult} to get the result of the copy job. + */ + async createCopyJob(webUrl: string, sourceUrl: string, destinationUrl: string, options?: CreateCopyJobsOptions): Promise { + const requestOptions: CliRequestOptions = { + url: `${webUrl}/_api/Site/CreateCopyJobs`, + headers: { + accept: 'application/json;odata=nometadata' + }, + responseType: 'json', + data: { + destinationUri: destinationUrl, + exportObjectUris: [sourceUrl], + options: { + NameConflictBehavior: options?.nameConflictBehavior ?? CreateCopyJobsNameConflictBehavior.Fail, + AllowSchemaMismatch: true, + BypassSharedLock: !!options?.bypassSharedLock, + IgnoreVersionHistory: !!options?.ignoreVersionHistory, + CustomizedItemName: options?.newName ? [options.newName] : undefined, + SameWebCopyMoveOptimization: true + } + } + }; + + const response = await request.post<{ value: CreateCopyJobInfo[] }>(requestOptions); + return response.value[0]; + }, + + /** + * Poll until the copy job is finished and return the result. + * @param webUrl Absolute web URL where the copy job was created. + * @param copyJobInfo Information about the copy job. + * @throws Error if the copy job has failed. + * @returns Information about the destination object. + */ + async getCopyJobResult(webUrl: string, copyJobInfo: CreateCopyJobInfo): Promise { + const requestOptions: CliRequestOptions = { + url: `${webUrl}/_api/Site/GetCopyJobProgress`, + headers: { + accept: 'application/json;odata=nometadata' + }, + responseType: 'json', + data: { + copyJobInfo: copyJobInfo + } + }; + let progress = await request.post<{ JobState: number; Logs: string[] }>(requestOptions); + + while (progress.JobState !== 0) { + await setTimeout(settings.pollingInterval); + progress = await request.post<{ JobState: number; Logs: string[] }>(requestOptions); + } + + const logs = progress.Logs.map(l => JSON.parse(l)); + + // Check if the job has failed + const errorLog = logs.find(l => l.Event === 'JobError'); + if (errorLog) { + throw new Error(errorLog.Message); + } + + // Get the destination object information + const objectInfo = logs.find(l => l.Event === 'JobFinishedObjectInfo') as CopyJobObjectInfo; + return objectInfo; } }; \ No newline at end of file From e3102bc05a178e4773e50fac63b5b104fe03015c Mon Sep 17 00:00:00 2001 From: Nanddeep Nachan Date: Sat, 20 Jul 2024 12:06:02 +0000 Subject: [PATCH 12/20] Removes deprecated CLI environment variables. Closes #5918 --- docs/docs/user-guide/connecting-microsoft-365.mdx | 2 +- docs/docs/v9-upgrade-guidance.mdx | 10 ++++++++++ src/config.spec.ts | 10 +--------- src/config.ts | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/docs/user-guide/connecting-microsoft-365.mdx b/docs/docs/user-guide/connecting-microsoft-365.mdx index a49d0450550..1d795e578f4 100644 --- a/docs/docs/user-guide/connecting-microsoft-365.mdx +++ b/docs/docs/user-guide/connecting-microsoft-365.mdx @@ -152,7 +152,7 @@ When logging in to Microsoft 365 using a secret, CLI for Microsoft 365 will pers #### Login without setting the environment variables -In all the examples above, we make use of the `CLIMICROSOFT365_AADAPPID` and `CLIMICROSOFT365_TENANT` environment variables. If you don't want to set these environment variables, you can specify the options `appId` and `tenant` when logging in to Microsoft 365. +In all the examples above, we make use of the `CLIMICROSOFT365_ENTRAAPPID` and `CLIMICROSOFT365_TENANT` environment variables. If you don't want to set these environment variables, you can specify the options `appId` and `tenant` when logging in to Microsoft 365. Below would be the command to log in to Microsoft 365 using a Personal Information Exchange (.pfx) file, execute: diff --git a/docs/docs/v9-upgrade-guidance.mdx b/docs/docs/v9-upgrade-guidance.mdx index 3431a0d4f6b..91aa8976edf 100644 --- a/docs/docs/v9-upgrade-guidance.mdx +++ b/docs/docs/v9-upgrade-guidance.mdx @@ -99,3 +99,13 @@ In the past versions of CLI for Microsoft 365, the command had no output. When u #### What action do I need to take? When using the [spo file copy](./cmd/spo/file/file-copy.mdx) command, please use the new command input. This means that you'll have to remove option `--resetAuthorAndCreated` from your scripts and automation tools. + +## CLI environment variables + +### Removed deprecated CLI environment variables + +For this new major version, we've removed the deprecated `AAD` CLI environment variables. We have renamed `CLIMICROSOFT365_AADAPPID` variable to `CLIMICROSOFT365_ENTRAAPPID`. + +#### What action do I need to take? + +Please, check the user guidance [Log in to Microsoft 365](./user-guide/connecting-microsoft-365.mdx) command to see the updated environment variables to use. diff --git a/src/config.spec.ts b/src/config.spec.ts index db8a8d3f231..949925817a0 100644 --- a/src/config.spec.ts +++ b/src/config.spec.ts @@ -8,13 +8,6 @@ describe('Config', () => { assert.strictEqual(config.default.tenant, 'tenant123'); }); - it('returns process.env CLIMICROSOFT365_AADAPPID value', async () => { - process.env.CLIMICROSOFT365_AADAPPID = 'appId123'; - - const config = await import(`./config.js#${Math.random()}`); - assert.strictEqual(config.default.cliEntraAppId, 'appId123'); - }); - it('returns process.env CLIMICROSOFT365_ENTRAAPPID value', async () => { process.env.CLIMICROSOFT365_ENTRAAPPID = 'appId123'; @@ -29,8 +22,7 @@ describe('Config', () => { assert.strictEqual(config.default.tenant, 'common'); }); - it('returns default value since env CLIMICROSOFT365_AADAPPID or CLIMICROSOFT365_ENTRAAPPID not present', async () => { - delete process.env.CLIMICROSOFT365_AADAPPID; + it('returns default value since env CLIMICROSOFT365_ENTRAAPPID not present', async () => { delete process.env.CLIMICROSOFT365_ENTRAAPPID; const config = await import(`./config.js#${Math.random()}`); diff --git a/src/config.ts b/src/config.ts index bd0c50f4ffc..a4fc46c66ce 100644 --- a/src/config.ts +++ b/src/config.ts @@ -5,7 +5,7 @@ const cliEntraAppId: string = '31359c7f-bd7e-475c-86db-fdb8c937548e'; export default { applicationName: `CLI for Microsoft 365 v${app.packageJson().version}`, delimiter: 'm365\$', - cliEntraAppId: process.env.CLIMICROSOFT365_ENTRAAPPID || process.env.CLIMICROSOFT365_AADAPPID || cliEntraAppId, + cliEntraAppId: process.env.CLIMICROSOFT365_ENTRAAPPID || cliEntraAppId, tenant: process.env.CLIMICROSOFT365_TENANT || 'common', configstoreName: 'cli-m365-config' }; \ No newline at end of file From 498e4487a500158a4049b2fb01975923250cb60b Mon Sep 17 00:00:00 2001 From: Nanddeep Nachan Date: Thu, 25 Jul 2024 09:46:07 +0000 Subject: [PATCH 13/20] Updates options of 'entra enterpriseapp' commands. Closes #6155 --- .../entra/enterpriseapp/enterpriseapp-add.mdx | 24 ++++----- .../entra/enterpriseapp/enterpriseapp-get.mdx | 28 +++++----- .../enterpriseapp/enterpriseapp-list.mdx | 10 ++-- docs/docs/v9-upgrade-guidance.mdx | 29 ++++++++++ .../enterpriseapp/enterpriseapp-add.spec.ts | 50 ++++++++--------- .../enterpriseapp/enterpriseapp-add.ts | 30 +++++------ .../enterpriseapp/enterpriseapp-get.spec.ts | 54 +++++++++---------- .../enterpriseapp/enterpriseapp-get.ts | 42 +++++++-------- .../enterpriseapp/enterpriseapp-list.ts | 2 +- 9 files changed, 149 insertions(+), 120 deletions(-) diff --git a/docs/docs/cmd/entra/enterpriseapp/enterpriseapp-add.mdx b/docs/docs/cmd/entra/enterpriseapp/enterpriseapp-add.mdx index 41d98b72f25..511a85a0380 100644 --- a/docs/docs/cmd/entra/enterpriseapp/enterpriseapp-add.mdx +++ b/docs/docs/cmd/entra/enterpriseapp/enterpriseapp-add.mdx @@ -22,39 +22,39 @@ m365 entra sp add [options] ## Options ```md definition-list -`--appId [appId]` -: ID of the app for which the enterprise application should be created +`-i, --id [id]` +: ID of the app for which the enterprise application should be created. -`--appName [appName]` -: Display name of the app for which the enterprise application should be created +`-n, --displayName [displayName]` +: Display name of the app for which the enterprise application should be created. `--objectId [objectId]` -: ObjectId of the app for which the enterprise application should be created +: ObjectId of the app for which the enterprise application should be created. ``` ## Remarks -Specify either the `appId`, `appName` or `objectId`. If you specify more than one option value, the command will fail with an error. +Specify either the `id`, `displayName` or `objectId`. If you specify more than one option value, the command will fail with an error. If you register an application in the portal, an application object as well as an enterprise application object are automatically created in your home tenant. If you register an application using CLI for Microsoft 365 or the Microsoft Graph, you'll need to create the enterprise application separately. To register/create an application using the CLI for Microsoft 365, use the [m365 entra app add](../app/app-add.mdx) command. ## Examples -Creates an enterprise application for a registered Entra app with appId _b2307a39-e878-458b-bc90-03bc578531d6_. +Creates an enterprise application for a registered Entra app with the specified id. ```sh -m365 entra enterpriseapp add --appId b2307a39-e878-458b-bc90-03bc578531d6 +m365 entra enterpriseapp add --id b2307a39-e878-458b-bc90-03bc578531d6 ``` -Creates an enterprise application for a registered Entra app with appName _Microsoft Graph_. +Creates an enterprise application for a registered Entra app with the specified displayName. ```sh -m365 entra enterpriseapp add --appName "Microsoft Graph" +m365 entra enterpriseapp add --displayName "Microsoft Graph" ``` -Creates an enterprise application for a registered Entra app with objectId _b2307a39-e878-458b-bc90-03bc578531d6_. +Creates an enterprise application for a registered Entra app with the specified objectId. ```sh m365 entra enterpriseapp add --objectId b2307a39-e878-458b-bc90-03bc578531d6 @@ -172,7 +172,7 @@ m365 entra enterpriseapp add --objectId b2307a39-e878-458b-bc90-03bc578531d6 ```md - # entra enterpriseapp add --appId "8da75b6a-4272-4b17-8ee1-20ba66e2b06f" + # entra enterpriseapp add --id "8da75b6a-4272-4b17-8ee1-20ba66e2b06f" Date: 2023-06-02 diff --git a/docs/docs/cmd/entra/enterpriseapp/enterpriseapp-get.mdx b/docs/docs/cmd/entra/enterpriseapp/enterpriseapp-get.mdx index 13b0ff155e1..ed83fcc0863 100644 --- a/docs/docs/cmd/entra/enterpriseapp/enterpriseapp-get.mdx +++ b/docs/docs/cmd/entra/enterpriseapp/enterpriseapp-get.mdx @@ -22,40 +22,40 @@ m365 entra sp get [options] ## Options ```md definition-list -`-i, --appId [appId]` -: ID of the application for which the enterprise application should be retrieved +`-i, --id [id]` +: ID of the application for which the enterprise application should be retrieved. -`-n, --appDisplayName [appDisplayName]` -: Display name of the application for which the enterprise application should be retrieved +`-n, --displayName [displayName]` +: Display name of the application for which the enterprise application should be retrieved. -`--appObjectId [appObjectId]` -: ObjectId of the application for which the enterprise application should be retrieved +`--objectId [objectId]` +: ObjectId of the application for which the enterprise application should be retrieved. ``` ## Remarks -Specify either the `appId`, `appObjectId` or `appDisplayName`. If you specify more than one option value, the command will fail with an error. +Specify either the `id`, `objectId` or `displayName`. If you specify more than one option value, the command will fail with an error. ## Examples -Return details about the enterprise application with appId _b2307a39-e878-458b-bc90-03bc578531d6_. +Return details about the enterprise application with the specified id. ```sh -m365 entra enterpriseapp get --appId b2307a39-e878-458b-bc90-03bc578531d6 +m365 entra enterpriseapp get --id b2307a39-e878-458b-bc90-03bc578531d6 ``` -Return details about the _Microsoft Graph_ enterprise application. +Return details about the enterprise application with the specified displayName. ```sh -m365 entra enterpriseapp get --appDisplayName "Microsoft Graph" +m365 entra enterpriseapp get --displayName "Microsoft Graph" ``` -Return details about the enterprise application with ObjectId _b2307a39-e878-458b-bc90-03bc578531dd_. +Return details about the enterprise application with the specified ObjectId. ```sh -m365 entra enterpriseapp get --appObjectId b2307a39-e878-458b-bc90-03bc578531dd +m365 entra enterpriseapp get --objectId b2307a39-e878-458b-bc90-03bc578531dd ``` ## Response @@ -198,7 +198,7 @@ m365 entra enterpriseapp get --appObjectId b2307a39-e878-458b-bc90-03bc578531dd ```md - # entra enterpriseapp get --appId "ac7c9b4b-83b0-4a5e-ace2-a3530162c8f8" + # entra enterpriseapp get --id "ac7c9b4b-83b0-4a5e-ace2-a3530162c8f8" Date: 2023-06-02 diff --git a/docs/docs/cmd/entra/enterpriseapp/enterpriseapp-list.mdx b/docs/docs/cmd/entra/enterpriseapp/enterpriseapp-list.mdx index 547a1ebdd37..c3785dfc4e2 100644 --- a/docs/docs/cmd/entra/enterpriseapp/enterpriseapp-list.mdx +++ b/docs/docs/cmd/entra/enterpriseapp/enterpriseapp-list.mdx @@ -22,24 +22,24 @@ m365 entra sp list [options] ## Options ```md definition-list -`--displayName [displayName]` -: Returns only enterprise applications with the specified name +`-n, --displayName [displayName]` +: Returns only enterprise applications with the specified name. `--tag [tag]` -: Returns only enterprise applications with the specified tag +: Returns only enterprise applications with the specified tag. ``` ## Examples -Return a list of all enterprise applications +Returns a list of all enterprise applications. ```sh m365 entra enterpriseapp list ``` -Return a list of all enterprise applications that comply with the display name and the tag parameters +Returns a list of all enterprise applications that comply with the specified display name and the tag parameters. ```sh m365 entra enterpriseapp list --displayName "My custom enterprise application" --tag "WindowsAzureActiveDirectoryIntegratedApp" diff --git a/docs/docs/v9-upgrade-guidance.mdx b/docs/docs/v9-upgrade-guidance.mdx index 91aa8976edf..375766eaa20 100644 --- a/docs/docs/v9-upgrade-guidance.mdx +++ b/docs/docs/v9-upgrade-guidance.mdx @@ -37,6 +37,35 @@ We updated option naming from `groupDisplayName` to `groupName` and `userPrincip Please, check the documentation of the affected commands to see the updated option naming and adjust your scripts accordingly. +### Aligns options of `entra enterpriseapp` commands + +For this new major version, we've aligned the options of the `entra enterpriseapp` commands as follows: + +[entra enterpriseapp add](https://pnp.github.io/cli-microsoft365/cmd/entra/enterpriseapp/enterpriseapp-add) + +| Old option | New option | +|---------------|---------------| +| --appId [appId] | -i, --id [id] | +| --appName [appName] | -n, --displayName [displayName] | + +[entra enterpriseapp get](https://pnp.github.io/cli-microsoft365/cmd/entra/enterpriseapp/enterpriseapp-get) + +| Old option | New option | +|---------------|---------------| +| -i, --appId [appId] | -i, --id [id] | +| -n, --appDisplayName [appDisplayName] | -n, --displayName [displayName] | +| --appObjectId [appObjectId] | --objectId [objectId] | + +[entra enterpriseapp list](https://pnp.github.io/cli-microsoft365/cmd/entra/enterpriseapp/enterpriseapp-list) + +| Old option | New option | +|---------------|---------------| +| --displayName [displayName] | -n, --displayName [displayName] | + +#### What action do I need to take? + +Please, check the documentation of the [entra enterpriseapp add](./cmd/entra/enterpriseapp/enterpriseapp-add), [entra enterpriseapp get](./cmd/entra/enterpriseapp/enterpriseapp-get), and [entra enterpriseapp list](./cmd/entra/enterpriseapp/enterpriseapp-list) commands to see the updated options and adjust your scripts accordingly. + ## SharePoint ### Updated `spo site appcatalog remove` options diff --git a/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.spec.ts b/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.spec.ts index efd8db7d221..b6810d693cd 100644 --- a/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.spec.ts +++ b/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.spec.ts @@ -79,7 +79,7 @@ describe(commands.ENTERPRISEAPP_ADD, () => { assert.deepStrictEqual(alias, [aadCommands.SP_ADD, commands.SP_ADD]); }); - it('fails validation if neither the appId, appName, nor objectId option specified', async () => { + it('fails validation if neither the id, displayName, nor objectId option specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { return false; @@ -92,8 +92,8 @@ describe(commands.ENTERPRISEAPP_ADD, () => { assert.notStrictEqual(actual, true); }); - it('fails validation if the appId is not a valid GUID', async () => { - const actual = await command.validate({ options: { appId: '123' } }, commandInfo); + it('fails validation if the id is not a valid GUID', async () => { + const actual = await command.validate({ options: { id: '123' } }, commandInfo); assert.notStrictEqual(actual, true); }); @@ -102,7 +102,7 @@ describe(commands.ENTERPRISEAPP_ADD, () => { assert.notStrictEqual(actual, true); }); - it('fails validation if both appId and appName are specified', async () => { + it('fails validation if both id and displayName are specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { return false; @@ -111,11 +111,11 @@ describe(commands.ENTERPRISEAPP_ADD, () => { return defaultValue; }); - const actual = await command.validate({ options: { appId: '00000000-0000-0000-0000-000000000000', appName: 'abc' } }, commandInfo); + const actual = await command.validate({ options: { id: '00000000-0000-0000-0000-000000000000', displayName: 'abc' } }, commandInfo); assert.notStrictEqual(actual, true); }); - it('fails validation if both appName and objectId are specified', async () => { + it('fails validation if both displayName and objectId are specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { return false; @@ -124,11 +124,11 @@ describe(commands.ENTERPRISEAPP_ADD, () => { return defaultValue; }); - const actual = await command.validate({ options: { appName: 'abc', objectId: '123' } }, commandInfo); + const actual = await command.validate({ options: { displayName: 'abc', objectId: '123' } }, commandInfo); assert.notStrictEqual(actual, true); }); - it('fails validation if both appId and objectId are specified', async () => { + it('fails validation if both id and objectId are specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { return false; @@ -137,17 +137,17 @@ describe(commands.ENTERPRISEAPP_ADD, () => { return defaultValue; }); - const actual = await command.validate({ options: { appId: '00000000-0000-0000-0000-000000000000', objectId: '00000000-0000-0000-0000-000000000000' } }, commandInfo); + const actual = await command.validate({ options: { id: '00000000-0000-0000-0000-000000000000', objectId: '00000000-0000-0000-0000-000000000000' } }, commandInfo); assert.notStrictEqual(actual, true); }); - it('passes validation when the appId option specified', async () => { - const actual = await command.validate({ options: { appId: '00000000-0000-0000-0000-000000000000' } }, commandInfo); + it('passes validation when the id option specified', async () => { + const actual = await command.validate({ options: { id: '00000000-0000-0000-0000-000000000000' } }, commandInfo); assert.strictEqual(actual, true); }); - it('passes validation when the appName option specified', async () => { - const actual = await command.validate({ options: { appName: 'abc' } }, commandInfo); + it('passes validation when the displayName option specified', async () => { + const actual = await command.validate({ options: { displayName: 'abc' } }, commandInfo); assert.strictEqual(actual, true); }); @@ -156,22 +156,22 @@ describe(commands.ENTERPRISEAPP_ADD, () => { assert.strictEqual(actual, true); }); - it('supports specifying appId', () => { + it('supports specifying id', () => { const options = command.options; let containsOption = false; options.forEach(o => { - if (o.option.indexOf('--appId') > -1) { + if (o.option.indexOf('--id') > -1) { containsOption = true; } }); assert(containsOption); }); - it('supports specifying appName', () => { + it('supports specifying displayName', () => { const options = command.options; let containsOption = false; options.forEach(o => { - if (o.option.indexOf('--appName') > -1) { + if (o.option.indexOf('--displayName') > -1) { containsOption = true; } }); @@ -190,7 +190,7 @@ describe(commands.ENTERPRISEAPP_ADD, () => { }); it('correctly handles API OData error', async () => { - sinon.stub(request, 'get').rejects({ + sinon.stub(request, 'post').rejects({ error: { 'odata.error': { code: '-1, InvalidOperationException', @@ -201,7 +201,7 @@ describe(commands.ENTERPRISEAPP_ADD, () => { } }); - await assert.rejects(command.action(logger, { options: { id: 'b2307a39-e878-458b-bc90-03bc578531d6' } } as any), + await assert.rejects(command.action(logger, { options: { id: '65415bb1-9267-4313-bbf5-ae259732ee12' } } as any), new CommandError('An error has occurred')); }); @@ -260,7 +260,7 @@ describe(commands.ENTERPRISEAPP_ADD, () => { await assert.rejects(command.action(logger, { options: { debug: true, - appName: 'Test App' + displayName: 'Test App' } }), new CommandError("Multiple Entra apps with name 'Test App' found. Found: ee091f63-9e48-4697-8462-7cfbf7410b8e, e9fd0957-049f-40d0-8d1d-112320fb1cbd.")); }); @@ -309,7 +309,7 @@ describe(commands.ENTERPRISEAPP_ADD, () => { await command.action(logger, { options: { debug: true, - appName: 'Test App' + displayName: 'Test App' } }); assert(loggerLogSpy.calledWith({ @@ -319,7 +319,7 @@ describe(commands.ENTERPRISEAPP_ADD, () => { })); }); - it('creates an enterprise application for a registered Entra app by appId', async () => { + it('creates an enterprise application for a registered Entra app by id', async () => { sinon.stub(request, 'post').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/servicePrincipals`) { return { @@ -333,7 +333,7 @@ describe(commands.ENTERPRISEAPP_ADD, () => { await command.action(logger, { options: { - appId: '65415bb1-9267-4313-bbf5-ae259732ee12' + id: '65415bb1-9267-4313-bbf5-ae259732ee12' } }); assert(loggerLogSpy.calledWith({ @@ -343,7 +343,7 @@ describe(commands.ENTERPRISEAPP_ADD, () => { })); }); - it('creates an enterprise application for a registered Entra app by appName', async () => { + it('creates an enterprise application for a registered Entra app by displayName', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if ((opts.url as string).indexOf(`/v1.0/applications?$filter=displayName eq `) > -1) { return { @@ -375,7 +375,7 @@ describe(commands.ENTERPRISEAPP_ADD, () => { await command.action(logger, { options: { debug: true, - appName: 'foo' + displayName: 'foo' } }); assert(loggerLogSpy.calledWith({ diff --git a/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.ts b/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.ts index 755732a6d82..aa0cdab113e 100644 --- a/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.ts +++ b/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.ts @@ -13,8 +13,8 @@ interface CommandArgs { } interface Options extends GlobalOptions { - appId?: string; - appName?: string; + id?: string; + displayName?: string; objectId?: string; } @@ -43,8 +43,8 @@ class EntraEnterpriseAppAddCommand extends GraphCommand { #initTelemetry(): void { this.telemetry.push((args: CommandArgs) => { Object.assign(this.telemetryProperties, { - appId: (!(!args.options.appId)).toString(), - appName: (!(!args.options.appName)).toString(), + id: (!(!args.options.id)).toString(), + displayName: (!(!args.options.displayName)).toString(), objectId: (!(!args.options.objectId)).toString() }); }); @@ -53,10 +53,10 @@ class EntraEnterpriseAppAddCommand extends GraphCommand { #initOptions(): void { this.options.unshift( { - option: '--appId [appId]' + option: '-i, --id [id]' }, { - option: '--appName [appName]' + option: '-n, --displayName [displayName]' }, { option: '--objectId [objectId]' @@ -67,12 +67,12 @@ class EntraEnterpriseAppAddCommand extends GraphCommand { #initValidators(): void { this.validators.push( async (args: CommandArgs) => { - if (args.options.appId && !validation.isValidGuid(args.options.appId)) { - return `${args.options.appId} is not a valid appId GUID`; + if (args.options.id && !validation.isValidGuid(args.options.id)) { + return `${args.options.id} is not a valid GUID`; } if (args.options.objectId && !validation.isValidGuid(args.options.objectId)) { - return `${args.options.objectId} is not a valid objectId GUID`; + return `${args.options.objectId} is not a valid GUID`; } return true; @@ -81,17 +81,17 @@ class EntraEnterpriseAppAddCommand extends GraphCommand { } #initOptionSets(): void { - this.optionSets.push({ options: ['appId', 'appName', 'objectId'] }); + this.optionSets.push({ options: ['id', 'displayName', 'objectId'] }); } private async getAppId(args: CommandArgs): Promise { - if (args.options.appId) { - return args.options.appId; + if (args.options.id) { + return args.options.id; } let spMatchQuery: string = ''; - if (args.options.appName) { - spMatchQuery = `displayName eq '${formatting.encodeQueryParameter(args.options.appName)}'`; + if (args.options.displayName) { + spMatchQuery = `displayName eq '${formatting.encodeQueryParameter(args.options.displayName)}'`; } else if (args.options.objectId) { spMatchQuery = `id eq '${formatting.encodeQueryParameter(args.options.objectId)}'`; @@ -115,7 +115,7 @@ class EntraEnterpriseAppAddCommand extends GraphCommand { if (response.value.length > 1) { const resultAsKeyValuePair = formatting.convertArrayToHashTable('appId', response.value); - const result = await cli.handleMultipleResultsFound<{ appId: string }>(`Multiple Entra apps with name '${args.options.appName}' found.`, resultAsKeyValuePair); + const result = await cli.handleMultipleResultsFound<{ appId: string }>(`Multiple Entra apps with name '${args.options.displayName}' found.`, resultAsKeyValuePair); return result.appId; } diff --git a/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.spec.ts b/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.spec.ts index 8c4b5143fa1..e5664bbfe2a 100644 --- a/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.spec.ts +++ b/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.spec.ts @@ -106,11 +106,11 @@ describe(commands.ENTERPRISEAPP_GET, () => { throw 'Invalid request'; }); - await command.action(logger, { options: { debug: true, appDisplayName: 'foo' } }); + await command.action(logger, { options: { debug: true, displayName: 'foo' } }); assert(loggerLogSpy.calledWith(spAppInfo)); }); - it('retrieves information about the specified enterprise application using its appId', async () => { + it('retrieves information about the specified enterprise application using its id', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if ((opts.url as string).indexOf(`/v1.0/servicePrincipals?$filter=appId eq `) > -1) { return spAppInfo; @@ -123,11 +123,11 @@ describe(commands.ENTERPRISEAPP_GET, () => { throw 'Invalid request'; }); - await command.action(logger, { options: { appId: '65415bb1-9267-4313-bbf5-ae259732ee12' } }); + await command.action(logger, { options: { id: '65415bb1-9267-4313-bbf5-ae259732ee12' } }); assert(loggerLogSpy.calledWith(spAppInfo)); }); - it('retrieves information about the specified enterprise application using its appObjectId', async () => { + it('retrieves information about the specified enterprise application using its objectId', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if ((opts.url as string).indexOf(`/v1.0/servicePrincipals?$filter=objectId eq `) > -1) { return spAppInfo; @@ -140,7 +140,7 @@ describe(commands.ENTERPRISEAPP_GET, () => { throw 'Invalid request'; }); - await command.action(logger, { options: { appObjectId: '59e617e5-e447-4adc-8b88-00af644d7c92' } }); + await command.action(logger, { options: { objectId: '59e617e5-e447-4adc-8b88-00af644d7c92' } }); assert(loggerLogSpy.calledWith(spAppInfo)); }); @@ -206,7 +206,7 @@ describe(commands.ENTERPRISEAPP_GET, () => { await assert.rejects(command.action(logger, { options: { debug: true, - appDisplayName: 'foo' + displayName: 'foo' } }), new CommandError("Multiple Entra apps with name 'foo' found. Found: be559819-b036-470f-858b-281c4e808403, 93d75ef9-ba9b-4361-9a47-1f6f7478f05f.")); }); @@ -252,7 +252,7 @@ describe(commands.ENTERPRISEAPP_GET, () => { sinon.stub(cli, 'handleMultipleResultsFound').resolves(spAppInfo.value[0]); - await command.action(logger, { options: { debug: true, appDisplayName: 'foo' } }); + await command.action(logger, { options: { debug: true, displayName: 'foo' } }); assert(loggerLogSpy.calledWith(spAppInfo)); }); @@ -271,12 +271,12 @@ describe(commands.ENTERPRISEAPP_GET, () => { await assert.rejects(command.action(logger, { options: { debug: true, - appDisplayName: 'Test App' + displayName: 'Test App' } }), new CommandError(`The specified Entra app does not exist`)); }); - it('fails validation if neither the appId nor the appDisplayName option specified', async () => { + it('fails validation if neither the id nor the displayName option specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { return false; @@ -289,22 +289,22 @@ describe(commands.ENTERPRISEAPP_GET, () => { assert.notStrictEqual(actual, true); }); - it('fails validation if the appId is not a valid GUID', async () => { - const actual = await command.validate({ options: { appId: '123' } }, commandInfo); + it('fails validation if the id is not a valid GUID', async () => { + const actual = await command.validate({ options: { id: '123' } }, commandInfo); assert.notStrictEqual(actual, true); }); - it('passes validation when the appId option specified', async () => { - const actual = await command.validate({ options: { appId: '6a7b1395-d313-4682-8ed4-65a6265a6320' } }, commandInfo); + it('passes validation when the id option specified', async () => { + const actual = await command.validate({ options: { id: '6a7b1395-d313-4682-8ed4-65a6265a6320' } }, commandInfo); assert.strictEqual(actual, true); }); - it('passes validation when the appDisplayName option specified', async () => { - const actual = await command.validate({ options: { appDisplayName: 'Microsoft Graph' } }, commandInfo); + it('passes validation when the displayName option specified', async () => { + const actual = await command.validate({ options: { displayName: 'Microsoft Graph' } }, commandInfo); assert.strictEqual(actual, true); }); - it('fails validation when both the appId and appDisplayName are specified', async () => { + it('fails validation when both the id and displayName are specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { return false; @@ -313,16 +313,16 @@ describe(commands.ENTERPRISEAPP_GET, () => { return defaultValue; }); - const actual = await command.validate({ options: { appId: '6a7b1395-d313-4682-8ed4-65a6265a6320', appDisplayName: 'Microsoft Graph' } }, commandInfo); + const actual = await command.validate({ options: { id: '6a7b1395-d313-4682-8ed4-65a6265a6320', displayName: 'Microsoft Graph' } }, commandInfo); assert.notStrictEqual(actual, true); }); - it('fails validation if the appObjectId is not a valid GUID', async () => { - const actual = await command.validate({ options: { appObjectId: '123' } }, commandInfo); + it('fails validation if the objectId is not a valid GUID', async () => { + const actual = await command.validate({ options: { objectId: '123' } }, commandInfo); assert.notStrictEqual(actual, true); }); - it('fails validation if both appId and appDisplayName are specified', async () => { + it('fails validation if both id and displayName are specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { return false; @@ -331,11 +331,11 @@ describe(commands.ENTERPRISEAPP_GET, () => { return defaultValue; }); - const actual = await command.validate({ options: { appId: '123', appDisplayName: 'abc' } }, commandInfo); + const actual = await command.validate({ options: { id: '123', displayName: 'abc' } }, commandInfo); assert.notStrictEqual(actual, true); }); - it('fails validation if appObjectId and appDisplayName are specified', async () => { + it('fails validation if objectId and displayName are specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { return false; @@ -344,26 +344,26 @@ describe(commands.ENTERPRISEAPP_GET, () => { return defaultValue; }); - const actual = await command.validate({ options: { appDisplayName: 'abc', appObjectId: '123' } }, commandInfo); + const actual = await command.validate({ options: { displayName: 'abc', objectId: '123' } }, commandInfo); assert.notStrictEqual(actual, true); }); - it('supports specifying appId', () => { + it('supports specifying id', () => { const options = command.options; let containsOption = false; options.forEach(o => { - if (o.option.indexOf('--appId') > -1) { + if (o.option.indexOf('--id') > -1) { containsOption = true; } }); assert(containsOption); }); - it('supports specifying appDisplayName', () => { + it('supports specifying displayName', () => { const options = command.options; let containsOption = false; options.forEach(o => { - if (o.option.indexOf('--appDisplayName') > -1) { + if (o.option.indexOf('--displayName') > -1) { containsOption = true; } }); diff --git a/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.ts b/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.ts index 8f7d76fafc6..e159fbee368 100644 --- a/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.ts +++ b/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.ts @@ -13,9 +13,9 @@ interface CommandArgs { } interface Options extends GlobalOptions { - appId?: string; - appDisplayName?: string; - appObjectId?: string; + id?: string; + displayName?: string; + objectId?: string; } class EntraEnterpriseAppGetCommand extends GraphCommand { @@ -43,9 +43,9 @@ class EntraEnterpriseAppGetCommand extends GraphCommand { #initTelemetry(): void { this.telemetry.push((args: CommandArgs) => { Object.assign(this.telemetryProperties, { - appId: (!(!args.options.appId)).toString(), - appDisplayName: (!(!args.options.appDisplayName)).toString(), - appObjectId: (!(!args.options.appObjectId)).toString() + id: (!(!args.options.id)).toString(), + displayName: (!(!args.options.displayName)).toString(), + objectId: (!(!args.options.objectId)).toString() }); }); } @@ -53,13 +53,13 @@ class EntraEnterpriseAppGetCommand extends GraphCommand { #initOptions(): void { this.options.unshift( { - option: '-i, --appId [appId]' + option: '-i, --id [id]' }, { - option: '-n, --appDisplayName [appDisplayName]' + option: '-n, --displayName [displayName]' }, { - option: '--appObjectId [appObjectId]' + option: '--objectId [objectId]' } ); } @@ -67,12 +67,12 @@ class EntraEnterpriseAppGetCommand extends GraphCommand { #initValidators(): void { this.validators.push( async (args: CommandArgs) => { - if (args.options.appId && !validation.isValidGuid(args.options.appId)) { - return `${args.options.appId} is not a valid appId GUID`; + if (args.options.id && !validation.isValidGuid(args.options.id)) { + return `${args.options.id} is not a valid GUID`; } - if (args.options.appObjectId && !validation.isValidGuid(args.options.appObjectId)) { - return `${args.options.appObjectId} is not a valid objectId GUID`; + if (args.options.objectId && !validation.isValidGuid(args.options.objectId)) { + return `${args.options.objectId} is not a valid GUID`; } return true; @@ -81,20 +81,20 @@ class EntraEnterpriseAppGetCommand extends GraphCommand { } #initOptionSets(): void { - this.optionSets.push({ options: ['appId', 'appDisplayName', 'appObjectId'] }); + this.optionSets.push({ options: ['id', 'displayName', 'objectId'] }); } private async getSpId(args: CommandArgs): Promise { - if (args.options.appObjectId) { - return args.options.appObjectId; + if (args.options.objectId) { + return args.options.objectId; } let spMatchQuery: string = ''; - if (args.options.appDisplayName) { - spMatchQuery = `displayName eq '${formatting.encodeQueryParameter(args.options.appDisplayName)}'`; + if (args.options.displayName) { + spMatchQuery = `displayName eq '${formatting.encodeQueryParameter(args.options.displayName)}'`; } - else if (args.options.appId) { - spMatchQuery = `appId eq '${formatting.encodeQueryParameter(args.options.appId)}'`; + else if (args.options.id) { + spMatchQuery = `appId eq '${formatting.encodeQueryParameter(args.options.id)}'`; } const idRequestOptions: CliRequestOptions = { @@ -115,7 +115,7 @@ class EntraEnterpriseAppGetCommand extends GraphCommand { if (response.value.length > 1) { const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', response.value); - const result = await cli.handleMultipleResultsFound<{ id: string }>(`Multiple Entra apps with name '${args.options.appDisplayName}' found.`, resultAsKeyValuePair); + const result = await cli.handleMultipleResultsFound<{ id: string }>(`Multiple Entra apps with name '${args.options.displayName}' found.`, resultAsKeyValuePair); return result.id; } diff --git a/src/m365/entra/commands/enterpriseapp/enterpriseapp-list.ts b/src/m365/entra/commands/enterpriseapp/enterpriseapp-list.ts index 911b7d59fba..a2547c38260 100644 --- a/src/m365/entra/commands/enterpriseapp/enterpriseapp-list.ts +++ b/src/m365/entra/commands/enterpriseapp/enterpriseapp-list.ts @@ -50,7 +50,7 @@ class EntraEnterpriseAppListCommand extends GraphCommand { #initOptions(): void { this.options.unshift( { - option: '--displayName [displayName]' + option: '-n, --displayName [displayName]' }, { option: '--tag [tag]' From 5299844b10a40421f2a342fb86d97770b06e3e4e Mon Sep 17 00:00:00 2001 From: Smita Nachan Date: Sat, 27 Jul 2024 07:11:30 +0000 Subject: [PATCH 14/20] Removes 'overwrite' option from 'spfx project github workflow add' command. Closes #5765 --- .../project/project-github-workflow-add.mdx | 23 +++++++++---------- docs/docs/v9-upgrade-guidance.mdx | 18 +++++++++++---- .../spfx/commands/project/DeployWorkflow.ts | 2 +- .../project-github-workflow-add.spec.ts | 2 +- .../project/project-github-workflow-add.ts | 15 +----------- 5 files changed, 28 insertions(+), 32 deletions(-) diff --git a/docs/docs/cmd/spfx/project/project-github-workflow-add.mdx b/docs/docs/cmd/spfx/project/project-github-workflow-add.mdx index a2984eecd4e..d2df584cfe1 100644 --- a/docs/docs/cmd/spfx/project/project-github-workflow-add.mdx +++ b/docs/docs/cmd/spfx/project/project-github-workflow-add.mdx @@ -14,28 +14,25 @@ m365 spfx project github workflow add [options] ```md definition-list `-n, --name [name]` -: Name of the workflow that will be created. If none is specified a default name will be used 'Deploy Solution ${name of sppkg file}' +: Name of the workflow that will be created. If none is specified a default name will be used 'Deploy Solution ${name of sppkg file}'. `-b, --branchName [branchName]` -: Specify the branch name which should trigger the workflow on push. If none is specified a default will be used which is 'main' +: Specify the branch name which should trigger the workflow on push. If none is specified a default will be used which is 'main'. `-m, --manuallyTrigger` -: When specified a manual trigger option will be added to the workflow: `workflow_dispatch` +: When specified a manual trigger option will be added to the workflow: `workflow_dispatch`. `-l, --loginMethod [loginMethod]` -: Specify the login method used for the login action. Possible options are: `user`, `application`. Default `application`' +: Specify the login method used for the login action. Possible options are: `user`, `application`. Default `application`. `-s, --scope [scope]` -: Scope of the app catalog: `tenant`, `sitecollection`. Default is `tenant` +: Scope of the app catalog: `tenant`, `sitecollection`. Default is `tenant`. `-u, --siteUrl [siteUrl]` -: The URL of the site collection where the solution package will be added. Required if scope is set to `sitecollection` +: The URL of the site collection where the solution package will be added. Required if scope is set to `sitecollection`. `--skipFeatureDeployment` -: When specified and the app supports tenant-wide deployment, deploy it to the whole tenant - -`--overwrite` -: When specified the workflow will overwrite the existing .sppkg if it is already deployed in the app catalog. +: When specified and the app supports tenant-wide deployment, deploy it to the whole tenant. ``` @@ -59,6 +56,8 @@ For the `user` login method you will need to create the following secrets in Git This method is perfect to test your workflow, in a dev context, for personal usage. It will not work for accounts with MFA. +The workflow will overwrite the existing .sppkg if it is already deployed in the app catalog. Overwriting your sppkg file on every deployment is required to make continuous delivery of the latest version of your app which is the aim of the continuous delivery pipeline. + :::info Run this command in the SPFx solution folder. @@ -67,7 +66,7 @@ Run this command in the SPFx solution folder. ## Examples -Adds a GitHub workflow for a SharePoint Framework project with `application` login method triggered on push to main +Adds a GitHub workflow for a SharePoint Framework project with `application` login method triggered on push to main. ```sh m365 spfx project github workflow add @@ -79,7 +78,7 @@ Adds a GitHub workflow for a SharePoint Framework project with `user` login meth m365 spfx project github workflow add --manuallyTrigger --loginMethod "user" ``` -Adds a GitHub workflow for a SharePoint Framework project with deployment to a site collection app catalog +Adds a GitHub workflow for a SharePoint Framework project with deployment to a site collection app catalog. ```sh m365 spfx project github workflow add --scope "sitecollection" --siteUrl "https://some.sharepoint.com/sites/someSite" diff --git a/docs/docs/v9-upgrade-guidance.mdx b/docs/docs/v9-upgrade-guidance.mdx index 375766eaa20..8d306384eb9 100644 --- a/docs/docs/v9-upgrade-guidance.mdx +++ b/docs/docs/v9-upgrade-guidance.mdx @@ -12,6 +12,16 @@ We updated the [app permission add](./cmd/app/permission/permission-add.mdx) com Please, check the documentation of the [app permission add](./cmd/app/permission/permission-add.mdx) command to see the updated options and adjust your scripts accordingly. +## CLI environment variables + +### Removed deprecated CLI environment variables + +For this new major version, we've removed the deprecated `AAD` CLI environment variables. We have renamed `CLIMICROSOFT365_AADAPPID` variable to `CLIMICROSOFT365_ENTRAAPPID`. + +#### What action do I need to take? + +Please, check the user guidance [Log in to Microsoft 365](./user-guide/connecting-microsoft-365.mdx) command to see the updated environment variables to use. + ## Entra ID ### Removed deprecated Guest value from 'aad m365group user list' command. @@ -129,12 +139,12 @@ In the past versions of CLI for Microsoft 365, the command had no output. When u When using the [spo file copy](./cmd/spo/file/file-copy.mdx) command, please use the new command input. This means that you'll have to remove option `--resetAuthorAndCreated` from your scripts and automation tools. -## CLI environment variables +## SharePoint Framework -### Removed deprecated CLI environment variables +### Removed overwrite option from `spfx project github workflow add` command -For this new major version, we've removed the deprecated `AAD` CLI environment variables. We have renamed `CLIMICROSOFT365_AADAPPID` variable to `CLIMICROSOFT365_ENTRAAPPID`. +Overwriting the SPFx package should be the default behavior of the continuous delivery pipeline. The `overwrite` option was removed from the [spfx project github workflow add](./cmd/spfx/project/project-github-workflow-add.mdx) command. #### What action do I need to take? -Please, check the user guidance [Log in to Microsoft 365](./user-guide/connecting-microsoft-365.mdx) command to see the updated environment variables to use. +Please update your scripts not to use the `overwrite` option. \ No newline at end of file diff --git a/src/m365/spfx/commands/project/DeployWorkflow.ts b/src/m365/spfx/commands/project/DeployWorkflow.ts index 36495617a3c..300d1d76594 100644 --- a/src/m365/spfx/commands/project/DeployWorkflow.ts +++ b/src/m365/spfx/commands/project/DeployWorkflow.ts @@ -49,7 +49,7 @@ export const workflow: GitHubWorkflow = { with: { "APP_FILE_PATH": "sharepoint/solution/{{ solutionName }}.sppkg", "SKIP_FEATURE_DEPLOYMENT": false, - "OVERWRITE": false + "OVERWRITE": true } } ] diff --git a/src/m365/spfx/commands/project/project-github-workflow-add.spec.ts b/src/m365/spfx/commands/project/project-github-workflow-add.spec.ts index 397fff00185..2d448e515b0 100644 --- a/src/m365/spfx/commands/project/project-github-workflow-add.spec.ts +++ b/src/m365/spfx/commands/project/project-github-workflow-add.spec.ts @@ -186,7 +186,7 @@ describe(commands.PROJECT_GITHUB_WORKFLOW_ADD, () => { const writeFileSyncStub: sinon.SinonStub = sinon.stub(fs, 'writeFileSync').resolves({}); - await command.action(logger, { options: { name: 'test', branchName: 'dev', manuallyTrigger: true, skipFeatureDeployment: true, overwrite: true, loginMethod: 'user', scope: 'sitecollection' } } as any); + await command.action(logger, { options: { name: 'test', branchName: 'dev', manuallyTrigger: true, skipFeatureDeployment: true, loginMethod: 'user', scope: 'sitecollection' } } as any); assert(writeFileSyncStub.calledWith(path.join(process.cwd(), projectPath, '/.github', 'workflows', 'deploy-spfx-solution.yml')), 'workflow file not created'); }); diff --git a/src/m365/spfx/commands/project/project-github-workflow-add.ts b/src/m365/spfx/commands/project/project-github-workflow-add.ts index e0817dd3be5..0ef39f20db1 100644 --- a/src/m365/spfx/commands/project/project-github-workflow-add.ts +++ b/src/m365/spfx/commands/project/project-github-workflow-add.ts @@ -24,7 +24,6 @@ interface Options extends GlobalOptions { scope?: string; skipFeatureDeployment?: boolean; siteUrl?: string; - overwrite?: boolean; } class SpfxProjectGithubWorkflowAddCommand extends BaseProjectCommand { @@ -56,8 +55,7 @@ class SpfxProjectGithubWorkflowAddCommand extends BaseProjectCommand { manuallyTrigger: !!args.options.manuallyTrigger, loginMethod: typeof args.options.loginMethod !== 'undefined', scope: typeof args.options.scope !== 'undefined', - skipFeatureDeployment: !!args.options.skipFeatureDeployment, - overwrite: !!args.options.overwrite + skipFeatureDeployment: !!args.options.skipFeatureDeployment }); }); } @@ -86,9 +84,6 @@ class SpfxProjectGithubWorkflowAddCommand extends BaseProjectCommand { }, { option: '--skipFeatureDeployment' - }, - { - option: '--overwrite' } ); } @@ -126,10 +121,6 @@ class SpfxProjectGithubWorkflowAddCommand extends BaseProjectCommand { throw new CommandError(`Couldn't find project root folder`, SpfxProjectGithubWorkflowAddCommand.ERROR_NO_PROJECT_ROOT_FOLDER); } - if (!args.options.overwrite) { - await this.warn(logger, `We recommend always using the --overwrite option and it will become the default behavior in next major release. Overwriting your sppkg file on every deployment is required to make continuous delivery of the latest version of your app which is the aim of the continuous delivery pipeline.`); - } - const solutionPackageJsonFile: string = path.join(this.projectRootPath, 'package.json'); const packageJson: string = fs.readFileSync(solutionPackageJsonFile, 'utf-8'); const solutionName = JSON.parse(packageJson).name; @@ -190,10 +181,6 @@ class SpfxProjectGithubWorkflowAddCommand extends BaseProjectCommand { this.getDeployAction(workflow).with!.SKIP_FEATURE_DEPLOYMENT = true; } - if (options.overwrite) { - this.getDeployAction(workflow).with!.OVERWRITE = true; - } - if (options.loginMethod === 'user') { const loginAction = this.getLoginAction(workflow); loginAction.with = { From 256b86f97e039c609fb96fc32c2433995f9a9aaa Mon Sep 17 00:00:00 2001 From: Nanddeep Nachan Date: Sat, 20 Jul 2024 13:00:48 +0000 Subject: [PATCH 15/20] Updates 'm365 status' command output. Closes #5849 --- docs/docs/v9-upgrade-guidance.mdx | 10 ++++++++++ src/m365/commands/status.spec.ts | 4 ++-- src/m365/commands/status.ts | 4 ++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/docs/v9-upgrade-guidance.mdx b/docs/docs/v9-upgrade-guidance.mdx index 8d306384eb9..dab399a9c96 100644 --- a/docs/docs/v9-upgrade-guidance.mdx +++ b/docs/docs/v9-upgrade-guidance.mdx @@ -22,6 +22,16 @@ For this new major version, we've removed the deprecated `AAD` CLI environment v Please, check the user guidance [Log in to Microsoft 365](./user-guide/connecting-microsoft-365.mdx) command to see the updated environment variables to use. +## CLI Status + +### Removed deprecated CLI environment variables + +We've updated the [m365 status](./cmd/status.mdx) command output. Previously the command would return `Logged out from Microsoft 365` now it will return `Logged out`. + +#### What action do I need to take? + +Please, update your scripts to reflect the new output of the [m365 status](./cmd/status.mdx) command. + ## Entra ID ### Removed deprecated Guest value from 'aad m365group user list' command. diff --git a/src/m365/commands/status.spec.ts b/src/m365/commands/status.spec.ts index 49b1e354337..18604fefbf1 100644 --- a/src/m365/commands/status.spec.ts +++ b/src/m365/commands/status.spec.ts @@ -120,7 +120,7 @@ describe(commands.STATUS, () => { auth.connection.active = false; (auth as any)._allConnections = []; await command.action(logger, { options: { verbose: true } }); - assert(loggerLogToStderrSpy.calledWith('Logged out from Microsoft 365')); + assert(loggerLogToStderrSpy.calledWith('Logged out')); }); it('shows logged out status when not logged in with connections available', async () => { @@ -132,7 +132,7 @@ describe(commands.STATUS, () => { it('shows logged out status when not logged in with connections available (verbose)', async () => { auth.connection.active = false; await command.action(logger, { options: { verbose: true } }); - assert(loggerLogToStderrSpy.calledWith('Logged out from Microsoft 365, signed in connections available')); + assert(loggerLogToStderrSpy.calledWith('Logged out, signed in connections available')); }); it('shows logged out status when the refresh token is expired', async () => { diff --git a/src/m365/commands/status.ts b/src/m365/commands/status.ts index 836a766f576..04af8fb5c98 100644 --- a/src/m365/commands/status.ts +++ b/src/m365/commands/status.ts @@ -38,8 +38,8 @@ class StatusCommand extends Command { const connections = await auth.getAllConnections(); if (this.verbose) { const message = connections.length > 0 - ? `Logged out from Microsoft 365, signed in connections available` - : 'Logged out from Microsoft 365'; + ? `Logged out, signed in connections available` + : 'Logged out'; await logger.logToStderr(message); } else { From 670326a64779175a0ec515e613ac00ec18ec215f Mon Sep 17 00:00:00 2001 From: Smita Nachan Date: Sun, 14 Jul 2024 09:17:25 +0000 Subject: [PATCH 16/20] Removes 'spo folder rename' alias. Closes #5911 --- docs/docs/cmd/spo/folder/folder-set.mdx | 6 ------ docs/docs/v9-upgrade-guidance.mdx | 8 ++++++++ src/m365/spo/commands.ts | 1 - .../spo/commands/folder/folder-set.spec.ts | 18 ------------------ src/m365/spo/commands/folder/folder-set.ts | 6 ------ 5 files changed, 8 insertions(+), 31 deletions(-) diff --git a/docs/docs/cmd/spo/folder/folder-set.mdx b/docs/docs/cmd/spo/folder/folder-set.mdx index fb97993974b..9da38e4a22f 100644 --- a/docs/docs/cmd/spo/folder/folder-set.mdx +++ b/docs/docs/cmd/spo/folder/folder-set.mdx @@ -10,12 +10,6 @@ Updates a folder m365 spo folder set [options] ``` -## Alias - -```sh -m365 spo folder rename [options] -``` - ## Options ```md definition-list diff --git a/docs/docs/v9-upgrade-guidance.mdx b/docs/docs/v9-upgrade-guidance.mdx index dab399a9c96..c806c87e0fc 100644 --- a/docs/docs/v9-upgrade-guidance.mdx +++ b/docs/docs/v9-upgrade-guidance.mdx @@ -149,6 +149,14 @@ In the past versions of CLI for Microsoft 365, the command had no output. When u When using the [spo file copy](./cmd/spo/file/file-copy.mdx) command, please use the new command input. This means that you'll have to remove option `--resetAuthorAndCreated` from your scripts and automation tools. +### Removed 'spo folder rename' alias + +The `spo folder rename` command was removed and replaced by the [spo folder set](./cmd/spo/folder/folder-set.mdx) command. + +#### What action do I need to take? + +Please, update your scripts to use the `spo folder set` command instead of `spo folder rename`. + ## SharePoint Framework ### Removed overwrite option from `spfx project github workflow add` command diff --git a/src/m365/spo/commands.ts b/src/m365/spo/commands.ts index 647206645aa..251b12b9c83 100644 --- a/src/m365/spo/commands.ts +++ b/src/m365/spo/commands.ts @@ -93,7 +93,6 @@ export default { FOLDER_LIST: `${prefix} folder list`, FOLDER_MOVE: `${prefix} folder move`, FOLDER_REMOVE: `${prefix} folder remove`, - FOLDER_RENAME: `${prefix} folder rename`, FOLDER_SET: `${prefix} folder set`, FOLDER_RETENTIONLABEL_ENSURE: `${prefix} folder retentionlabel ensure`, FOLDER_RETENTIONLABEL_REMOVE: `${prefix} folder retentionlabel remove`, diff --git a/src/m365/spo/commands/folder/folder-set.spec.ts b/src/m365/spo/commands/folder/folder-set.spec.ts index d840bfc8b08..851dc8d2c15 100644 --- a/src/m365/spo/commands/folder/folder-set.spec.ts +++ b/src/m365/spo/commands/folder/folder-set.spec.ts @@ -12,7 +12,6 @@ import { pid } from '../../../../utils/pid.js'; import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; - import command from './folder-set.js'; describe(commands.FOLDER_SET, () => { @@ -72,23 +71,6 @@ describe(commands.FOLDER_SET, () => { assert.notStrictEqual(command.description, null); }); - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [commands.FOLDER_RENAME]); - }); - - it('correctly logs deprecation warning for yammer command', async () => { - const chalk = (await import('chalk')).default; - const loggerErrSpy = sinon.spy(logger, 'logToStderr'); - const commandNameStub = sinon.stub(cli, 'currentCommandName').value(commands.FOLDER_RENAME); - sinon.stub(request, 'patch').resolves(); - - await command.action(logger, { options: { webUrl: webUrl, url: folderRelServerUrl, name: newFolderName } }); - assert.deepStrictEqual(loggerErrSpy.firstCall.firstArg, chalk.yellow(`Command '${commands.FOLDER_RENAME}' is deprecated. Please use '${commands.FOLDER_SET}' instead.`)); - - sinonUtil.restore([loggerErrSpy, commandNameStub]); - }); - it('renames folder correctly by using server relative URL', async () => { const patchStub = sinon.stub(request, 'patch').callsFake(async (opts) => { if (opts.url === `${webUrl}/_api/Web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(folderRelServerUrl)}')/ListItemAllFields`) { diff --git a/src/m365/spo/commands/folder/folder-set.ts b/src/m365/spo/commands/folder/folder-set.ts index 8d83458ff06..84c0d5a695c 100644 --- a/src/m365/spo/commands/folder/folder-set.ts +++ b/src/m365/spo/commands/folder/folder-set.ts @@ -29,10 +29,6 @@ class SpoFolderSetCommand extends SpoCommand { return 'Updates a folder'; } - public alias(): string[] | undefined { - return [commands.FOLDER_RENAME]; - } - constructor() { super(); @@ -99,8 +95,6 @@ class SpoFolderSetCommand extends SpoCommand { public async commandAction(logger: Logger, args: CommandArgs): Promise { try { - await this.showDeprecationWarning(logger, this.alias()![0], this.name); - if (this.verbose) { await logger.logToStderr(`Updating folder '${args.options.name}'...`); } From 1cfb646a10c6aca1e5dd2da4e3d2449696a8393a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20W=C3=B3jcik?= Date: Wed, 14 Aug 2024 00:27:30 +0200 Subject: [PATCH 17/20] Updates release notes --- docs/docs/about/release-notes.mdx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/docs/about/release-notes.mdx b/docs/docs/about/release-notes.mdx index 69e96cb5fe0..017c41dc066 100644 --- a/docs/docs/about/release-notes.mdx +++ b/docs/docs/about/release-notes.mdx @@ -14,6 +14,13 @@ sidebar_position: 3 - aligned options with naming convention [#5616](https://github.com/pnp/cli-microsoft365/issues/5616) - removed duplicate property from 'spo list list' command [#6042](https://github.com/pnp/cli-microsoft365/issues/6042) - updated 'spo tenant recyclebinitem restore' command [#6063](https://github.com/pnp/cli-microsoft365/issues/6063) +- removed deprecated option '--wait' from 'spo site remove' command [#5956](https://github.com/pnp/cli-microsoft365/issues/5956) +- reworked command 'spo file copy' to new API endpoint [#6152](https://github.com/pnp/cli-microsoft365/issues/6152) +- removed deprecated CLI environment variables [#5918](https://github.com/pnp/cli-microsoft365/issues/5918) +- updated options of 'entra enterpriseapp' commands [#6155](https://github.com/pnp/cli-microsoft365/issues/6155) +- removed 'overwrite' option from 'spfx project github workflow add' command [#5765](https://github.com/pnp/cli-microsoft365/issues/5765) +- updated 'm365 status' command output [#5849](https://github.com/pnp/cli-microsoft365/issues/5849) +- removed 'spo folder rename' alias [#5911](https://github.com/pnp/cli-microsoft365/issues/5911) ## v8.1.0 (beta) From 401d6d45e9f3c20451ece26e3d90bfbd1f51b1e9 Mon Sep 17 00:00:00 2001 From: Nanddeep Nachan Date: Fri, 12 Jul 2024 10:01:07 +0000 Subject: [PATCH 18/20] Remove aad options --- docs/docs/cmd/spo/group/group-member-add.mdx | 22 ++-- .../cmd/spo/group/group-member-remove.mdx | 16 +-- docs/docs/cmd/spo/user/user-ensure.mdx | 7 +- .../commands/group/group-member-add.spec.ts | 103 +++++------------- .../spo/commands/group/group-member-add.ts | 35 +----- .../group/group-member-remove.spec.ts | 75 ------------- .../spo/commands/group/group-member-remove.ts | 28 +---- .../spo/commands/user/user-ensure.spec.ts | 27 ----- src/m365/spo/commands/user/user-ensure.ts | 17 +-- 9 files changed, 47 insertions(+), 283 deletions(-) diff --git a/docs/docs/cmd/spo/group/group-member-add.mdx b/docs/docs/cmd/spo/group/group-member-add.mdx index 090310f31f3..8973044ffc7 100644 --- a/docs/docs/cmd/spo/group/group-member-add.mdx +++ b/docs/docs/cmd/spo/group/group-member-add.mdx @@ -25,32 +25,26 @@ m365 spo group member add [options] : Name of the SharePoint Group to which the user needs to be added. Specify either `groupId` or `groupName`. `--userNames [userNames]` -: User's UPN (user principal name, eg. megan.bowen@contoso.com). If multiple users need to be added, they have to be comma-separated (e.g. megan.bowen@contoso.com,alex.wilber@contoso.com). Specify either `userIds`, `userNames`, `emails`, `aadGroupIds` or `aadGroupNames`. +: User's UPN (user principal name, eg. megan.bowen@contoso.com). If multiple users need to be added, they have to be comma-separated (e.g. megan.bowen@contoso.com,alex.wilber@contoso.com). Specify either `userIds`, `userNames`, `emails`, `entraGroupIds` or `entraGroupNames`. `--emails [emails]` -: User's email (eg. megan.bowen@contoso.com). If multiple users need to be added, they have to be comma-separated (e.g. megan.bowen@contoso.com,alex.wilber@contoso.com). Specify either `userIds`, `userNames`, `emails`, `aadGroupIds` or `aadGroupNames`. +: User's email (eg. megan.bowen@contoso.com). If multiple users need to be added, they have to be comma-separated (e.g. megan.bowen@contoso.com,alex.wilber@contoso.com). Specify either `userIds`, `userNames`, `emails`, `entraGroupIds` or `entraGroupNames`. `--userIds [userIds]` -: The user Id of the user to add as a member. (Id of the site user, for example: 14) If multiple users need to be added, the Ids have to be comma-separated. Specify either `userIds`, `userNames`, `emails`, `aadGroupIds` or `aadGroupNames`. +: The user Id of the user to add as a member. (Id of the site user, for example: 14). If multiple users need to be added, the Ids have to be comma-separated. Specify either `userIds`, `userNames`, `emails`, `entraGroupIds` or `entraGroupNames`. `--entraGroupIds [entraGroupIds]` -: The object Id of the Entra group to add as a member. If multiple groups need to be added, the Ids have to be comma-separated. Specify either `userIds`, `userNames`, `emails`, `aadGroupIds`, `entraGroupIds`, `aadGroupNames`, or `entraGroupNames`. - -`--aadGroupIds [aadGroupIds]` -: (deprecated. Use `entraGroupIds` instead) The object ID of the Microsoft Entra group to add as a member. If multiple groups need to be added, the Ids have to be comma-separated. Specify either `userIds`, `userNames`, `emails`, `aadGroupIds`, `entraGroupIds`, `aadGroupNames`, or `entraGroupNames`. +: The object Id of the Entra group to add as a member. If multiple groups need to be added, the Ids have to be comma-separated. Specify either `userIds`, `userNames`, `emails`, `entraGroupIds`or `entraGroupNames`. `--entraGroupNames [entraGroupNames]` -: The name of the Entra group to add as a member. If multiple groups need to be added, they have to be comma-separated. Specify either `userIds`, `userNames`, `emails`, `aadGroupIds`, `entraGroupIds`, `aadGroupNames`, or `entraGroupNames`. - -`--aadGroupNames [aadGroupNames]` -: (deprecated. Use `entraGroupNames` instead) The name of the Microsoft Entra group to add as a member. If multiple groups need to be added, they have to be comma-separated. Specify either `userIds`, `userNames`, `emails`, `aadGroupIds`, `entraGroupIds`, `aadGroupNames`, or `entraGroupNames`. +: The name of the Entra group to add as a member. If multiple groups need to be added, they have to be comma-separated. Specify either `userIds`, `userNames`, `emails`, `entraGroupIds` or `entraGroupNames`. ``` ## Remarks -For the `userIds`, `userNames`, `emails`, `aadGroupIds`, `entraGroupIds`, `aadGroupNames`, or `entraGroupNames` options you can specify multiple values by separating them with a comma. If one of the specified entries is not valid, the command will fail with an error message showing the list of invalid values. +For the `userIds`, `userNames`, `emails`, `entraGroupIds`, or `entraGroupNames` options you can specify multiple values by separating them with a comma. If one of the specified entries is not valid, the command will fail with an error message showing the list of invalid values. ## Examples @@ -63,7 +57,7 @@ m365 spo group member add --webUrl https://contoso.sharepoint.com/sites/SiteA -- Add multiple users with the userNames parameter to a SharePoint group with the groupId parameter. ```sh -m365 spo group member add --webUrl https://contoso.sharepoint.com/sites/SiteA --groupId 5 --userNames "Alex.Wilber@contoso.com, Adele.Vance@contoso.com" +m365 spo group member add --webUrl https://contoso.sharepoint.com/sites/SiteA --groupId 5 --userNames "Alex.Wilber@contoso.com,Adele.Vance@contoso.com" ``` Add a user with the emails parameter to a SharePoint group with the groupName parameter. @@ -75,7 +69,7 @@ m365 spo group member add --webUrl https://contoso.sharepoint.com/sites/SiteA -- Add multiple users with the emails parameter to a SharePoint group with the groupName parameter. ```sh -m365 spo group member add --webUrl https://contoso.sharepoint.com/sites/SiteA --groupName "Contoso Site Owners" --emails "Alex.Wilber@contoso.com, Adele.Vance@contoso.com" +m365 spo group member add --webUrl https://contoso.sharepoint.com/sites/SiteA --groupName "Contoso Site Owners" --emails "Alex.Wilber@contoso.com,Adele.Vance@contoso.com" ``` Add a user with the userIds parameter to a SharePoint group with the groupId parameter. diff --git a/docs/docs/cmd/spo/group/group-member-remove.mdx b/docs/docs/cmd/spo/group/group-member-remove.mdx index 4b2adc95922..7ed285b92d8 100644 --- a/docs/docs/cmd/spo/group/group-member-remove.mdx +++ b/docs/docs/cmd/spo/group/group-member-remove.mdx @@ -23,25 +23,19 @@ m365 spo group member remove [options] : Name of the SharePoint group from which user has to be removed. Specify either `groupName` or `groupId`, but not both. `--userName [userName]` -: The UPN (user principal name, eg. megan.bowen@contoso.com) of the user that needs to be removed. Specify either `userName`, `email`, `userId`, `aadGroupId` or `aadGroupName`. +: The UPN (user principal name, eg. megan.bowen@contoso.com) of the user that needs to be removed. Specify either `userName`, `email`, `userId`, `entraGroupId` or `entraGroupName`. `--email [email]` -: The email of the user to remove as a member. Specify either `userName`, `email`, `userId`, `aadGroupId` or `aadGroupName`. +: The email of the user to remove as a member. Specify either `userName`, `email`, `userId`, `entraGroupId` or `entraGroupName`. `--userId [userId]` -: The user Id (Id of the site user, eg. 14) of the user to remove as a member. Specify either `userName`, `email`, `userId`, `aadGroupId` or `aadGroupName`. +: The user Id (Id of the site user, eg. 14) of the user to remove as a member. Specify either `userName`, `email`, `userId`, `entraGroupId` or `entraGroupName`. `--entraGroupId [entraGroupId]` -: The object Id of the Entra group to remove as a member. Specify either `userName`, `email`, `userId`, `aadGroupId`, `entraGroupId`, `aadGroupName`, or `entraGroupName`. - -`--aadGroupId [aadGroupId]` -: (deprecated. Use `entraGroupId` instead) The object ID of the Microsoft Entra group to remove as a member. Specify either `userName`, `email`, `userId`, `aadGroupId`, `entraGroupId`, `aadGroupName`, or `entraGroupName`. +: The object Id of the Entra group to remove as a member. Specify either `userName`, `email`, `userId`, `entraGroupId`, or `entraGroupName`. `--entraGroupName [entraGroupName]` -: The name of the Entra group to remove as a member. Specify either `userName`, `email`, `userId`, `aadGroupId`, `entraGroupId`, `aadGroupName`, or `entraGroupName`. - -`--aadGroupName [aadGroupName]` -: (deprecated. Use `entraGroupName` instead) The name of the Microsoft Entra group to remove as a member. Specify either `userName`, `email`, `userId`, `aadGroupId`, `entraGroupId`, `aadGroupName`, or `entraGroupName`. +: The name of the Entra group to remove as a member. Specify either `userName`, `email`, `userId`, `entraGroupId`, or `entraGroupName`. ``` diff --git a/docs/docs/cmd/spo/user/user-ensure.mdx b/docs/docs/cmd/spo/user/user-ensure.mdx index 077838c0c41..12551b5ef98 100644 --- a/docs/docs/cmd/spo/user/user-ensure.mdx +++ b/docs/docs/cmd/spo/user/user-ensure.mdx @@ -19,13 +19,10 @@ m365 spo user ensure [options] : Absolute URL of the site. `--entraId [--entraId]` -: Id of the user in Entra. Specify either `aadId`, `entraId`, or `userName`. - -`--aadId [--aadId]` -: (deprecated. Use `entraId` instead) Id of the user in Microsoft Entra. Specify either `aadId`, `entraId`, or `userName`. +: Id of the user in Entra. Specify either `entraId` or `userName`. `--userName [userName]` -: User's UPN (user principal name, e.g. john@contoso.com). Specify either `aadId`, `entraId`, or `userName`. +: User's UPN (user principal name, e.g. john@contoso.com). Specify either `entraId` or `userName`. ``` diff --git a/src/m365/spo/commands/group/group-member-add.spec.ts b/src/m365/spo/commands/group/group-member-add.spec.ts index 03b31d42482..c264f73d894 100644 --- a/src/m365/spo/commands/group/group-member-add.spec.ts +++ b/src/m365/spo/commands/group/group-member-add.spec.ts @@ -6,6 +6,7 @@ import { CommandInfo } from '../../../../cli/CommandInfo.js'; import { Logger } from '../../../../cli/Logger.js'; import request from '../../../../request.js'; import { telemetry } from '../../../../telemetry.js'; +import { formatting } from '../../../../utils/formatting.js'; import { pid } from '../../../../utils/pid.js'; import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; @@ -163,7 +164,7 @@ describe(commands.GROUP_MEMBER_ADD, () => { //#region Option values const webUrl = 'https://contoso.sharepoint.com/sites/Marketing'; - const spGroupName = 'Marketing Site Owners'; + const spGroupName = "Contoso Site Owners"; const spGroupId = 3; const spUserIds = userResponses.map(u => u.Id); const userNames = userResponses.map(u => u.UserPrincipalName); @@ -231,7 +232,7 @@ describe(commands.GROUP_MEMBER_ADD, () => { options: { webUrl: "https://contoso.sharepoint.com/sites/SiteA", groupId: 32, - groupName: "Contoso Site Owners", + groupName: spGroupName, userNames: "Alex.Wilber@contoso.com" } }, commandInfo); @@ -284,18 +285,6 @@ describe(commands.GROUP_MEMBER_ADD, () => { assert.notStrictEqual(actual, true); }); - it('fails validation if both emails and aadGroupIds options are passed', async () => { - const actual = await command.validate({ - options: { - webUrl: "https://contoso.sharepoint.com/sites/SiteA", - groupId: 32, - emails: "Alex.Wilber@contoso.com", - aadGroupIds: "56ca9023-3449-4e98-a96a-69e81a6f4983" - } - }, commandInfo); - assert.notStrictEqual(actual, true); - }); - it('fails validation if both userIds and entraGroupNames options are passed', async () => { const actual = await command.validate({ options: { @@ -308,18 +297,6 @@ describe(commands.GROUP_MEMBER_ADD, () => { assert.notStrictEqual(actual, true); }); - it('fails validation if both userIds and aadGroupNames options are passed', async () => { - const actual = await command.validate({ - options: { - webUrl: "https://contoso.sharepoint.com/sites/SiteA", - groupId: 32, - userIds: 5, - aadGroupNames: "Microsoft Entra Group name" - } - }, commandInfo); - assert.notStrictEqual(actual, true); - }); - it('fails validation if both userIds and emails options are passed', async () => { const actual = await command.validate({ options: { @@ -332,7 +309,7 @@ describe(commands.GROUP_MEMBER_ADD, () => { assert.notStrictEqual(actual, true); }); - it('fails validation if userNames, emails, userIds, entraGroupIds, aadGroupIds, entraGroupNames, or aadGroupNames options are not passed', async () => { + it('fails validation if userNames, emails, userIds, entraGroupIds, or entraGroupNames options are not passed', async () => { const actual = await command.validate({ options: { webUrl: "https://contoso.sharepoint.com/sites/SiteA", @@ -372,11 +349,6 @@ describe(commands.GROUP_MEMBER_ADD, () => { assert.notStrictEqual(actual, true); }); - it('fails validation if aadGroupIds is Invalid', async () => { - const actual = await command.validate({ options: { webUrl: "https://contoso.sharepoint.com/sites/SiteA", groupId: 32, aadGroupIds: "56ca9023-3449-4e98-a96a-69e81a6f4983,9" } }, commandInfo); - assert.notStrictEqual(actual, true); - }); - it('passes validation if all the required options are specified', async () => { const actual = await command.validate({ options: { webUrl: "https://contoso.sharepoint.com/sites/SiteA", groupId: 32, userNames: "Alex.Wilber@contoso.com" } }, commandInfo); assert.strictEqual(actual, true); @@ -386,28 +358,6 @@ describe(commands.GROUP_MEMBER_ADD, () => { assert.deepStrictEqual(command.defaultProperties(), ['Title', 'UserPrincipalName']); }); - it('correctly logs deprecation warning for aadGroupIds option', async () => { - const chalk = (await import('chalk')).default; - const loggerErrSpy = sinon.spy(logger, 'logToStderr'); - sinon.stub(request, 'post').resolves(); - - await command.action(logger, { options: { webUrl: webUrl, groupName: spGroupName, aadGroupIds: entraGroupIds[0] } }); - assert.deepStrictEqual(loggerErrSpy.firstCall.firstArg, chalk.yellow(`Option 'aadGroupIds' is deprecated. Please use 'entraGroupIds' instead.`)); - - sinonUtil.restore(loggerErrSpy); - }); - - it('correctly logs deprecation warning for aadGroupNames option', async () => { - const chalk = (await import('chalk')).default; - const loggerErrSpy = sinon.spy(logger, 'logToStderr'); - sinon.stub(request, 'post').resolves(); - - await command.action(logger, { options: { webUrl: webUrl, groupName: spGroupName, aadGroupNames: entraGroupNames[0] } }); - assert.deepStrictEqual(loggerErrSpy.firstCall.firstArg, chalk.yellow(`Option 'aadGroupNames' is deprecated. Please use 'entraGroupNames' instead.`)); - - sinonUtil.restore(loggerErrSpy); - }); - it('correctly logs result when adding users by userNames', async () => { const postStub = sinon.stub(request, 'post').callsFake(async (opts) => { if (opts.url === `${webUrl}/_api/web/SiteGroups/GetById(${spGroupId})/users`) { @@ -428,27 +378,6 @@ describe(commands.GROUP_MEMBER_ADD, () => { assert(loggerLogSpy.calledOnceWithExactly(userResponses)); }); - it('correctly adds users to group by UPNs', async () => { - const postStub = sinon.stub(request, 'post').callsFake(async (opts) => { - if (opts.url === `${webUrl}/_api/web/SiteGroups/GetById(${spGroupId})/users`) { - return userResponses[postStub.callCount - 1]; - } - - throw 'Invalid request: ' + opts.url; - }); - - await command.action(logger, { - options: { - webUrl: webUrl, - groupId: spGroupId, - userNames: userNames.join(',') - } - }); - - assert.deepStrictEqual(postStub.firstCall.args[0].data, { LoginName: 'i:0#.f|membership|adelev@contoso.onmicrosoft.com' }); - assert.deepStrictEqual(postStub.secondCall.args[0].data, { LoginName: 'i:0#.f|membership|johnd@contoso.onmicrosoft.com' }); - }); - it('correctly adds users to group by emails', async () => { const postStub = sinon.stub(request, 'post').callsFake(async (opts) => { if (opts.url === `${webUrl}/_api/web/SiteGroups/GetById(${spGroupId})/users`) { @@ -544,6 +473,28 @@ describe(commands.GROUP_MEMBER_ADD, () => { assert.deepStrictEqual(postStub.secondCall.args[0].data, { LoginName: `c:0t.c|tenant|${entraGroupResponses[1].id}` }); }); + it('correctly adds user to a group by groupName and emails (DEBUG)', async () => { + const postStub = sinon.stub(request, 'post').callsFake(async (opts) => { + if (opts.url === `${webUrl}/_api/web/SiteGroups/GetByName('${formatting.encodeQueryParameter(spGroupName)}')/users`) { + return groupResponses[postStub.callCount - 1]; + } + + throw 'Invalid request: ' + opts.url; + }); + + await command.action(logger, { + options: { + debug: true, + webUrl: webUrl, + groupName: spGroupName, + emails: emails.join(',') + } + }); + + assert.deepStrictEqual(postStub.firstCall.args[0].data, { LoginName: 'i:0#.f|membership|Adele.Vance@contoso.onmicrosoft.com' }); + assert.deepStrictEqual(postStub.secondCall.args[0].data, { LoginName: 'i:0#.f|membership|John.Doe@contoso.onmicrosoft.com' }); + }); + it('correctly adds users to group by entraGroupNames', async () => { const postStub = sinon.stub(request, 'post').callsFake(async (opts) => { if (opts.url === `${webUrl}/_api/web/SiteGroups/GetById(${spGroupId})/users`) { @@ -584,4 +535,4 @@ describe(commands.GROUP_MEMBER_ADD, () => { await assert.rejects(command.action(logger, { options: { webUrl: webUrl, groupId: spGroupId, userNames: userNames.join(',') } }), new CommandError(error.error['odata.error'].message.value)); }); -}); +}); \ No newline at end of file diff --git a/src/m365/spo/commands/group/group-member-add.ts b/src/m365/spo/commands/group/group-member-add.ts index 52779256bd9..fabe2e128ab 100644 --- a/src/m365/spo/commands/group/group-member-add.ts +++ b/src/m365/spo/commands/group/group-member-add.ts @@ -20,9 +20,7 @@ interface Options extends GlobalOptions { emails?: string; userIds?: string; entraGroupIds?: string; - aadGroupIds?: string; entraGroupNames?: string; - aadGroupNames?: string; } class SpoGroupMemberAddCommand extends SpoCommand { @@ -57,9 +55,7 @@ class SpoGroupMemberAddCommand extends SpoCommand { emails: typeof args.options.emails !== 'undefined', userIds: typeof args.options.userIds !== 'undefined', entraGroupIds: typeof args.options.entraGroupIds !== 'undefined', - aadGroupIds: typeof args.options.aadGroupIds !== 'undefined', - entraGroupNames: typeof args.options.entraGroupNames !== 'undefined', - aadGroupNames: typeof args.options.aadGroupNames !== 'undefined' + entraGroupNames: typeof args.options.entraGroupNames !== 'undefined' }); }); } @@ -87,14 +83,8 @@ class SpoGroupMemberAddCommand extends SpoCommand { { option: '--entraGroupIds [entraGroupIds]' }, - { - option: '--aadGroupIds [aadGroupIds]' - }, { option: '--entraGroupNames [entraGroupNames]' - }, - { - option: '--aadGroupNames [aadGroupNames]' } ); } @@ -139,13 +129,6 @@ class SpoGroupMemberAddCommand extends SpoCommand { } } - if (args.options.aadGroupIds) { - const isValidArray = validation.isValidGuidArray(args.options.aadGroupIds); - if (isValidArray !== true) { - return `Option 'aadGroupIds' contains one or more invalid GUIDs: ${isValidArray}.`; - } - } - return true; } ); @@ -154,28 +137,16 @@ class SpoGroupMemberAddCommand extends SpoCommand { #initOptionSets(): void { this.optionSets.push( { options: ['groupId', 'groupName'] }, - { options: ['userNames', 'emails', 'userIds', 'entraGroupIds', 'aadGroupIds', 'entraGroupNames', 'aadGroupNames'] } + { options: ['userNames', 'emails', 'userIds', 'entraGroupIds', 'entraGroupNames'] } ); } #initTypes(): void { - this.types.string.push('webUrl', 'groupName', 'userNames', 'emails', 'userIds', 'entraGroupIds', 'aadGroupIds', 'entraGroupNames', 'aadGroupNames'); + this.types.string.push('webUrl', 'groupName', 'userNames', 'emails', 'userIds', 'entraGroupIds', 'entraGroupNames'); } public async commandAction(logger: Logger, args: CommandArgs): Promise { try { - if (args.options.aadGroupIds) { - args.options.entraGroupIds = args.options.aadGroupIds; - - await this.warn(logger, `Option 'aadGroupIds' is deprecated. Please use 'entraGroupIds' instead.`); - } - - if (args.options.aadGroupNames) { - args.options.entraGroupNames = args.options.aadGroupNames; - - await this.warn(logger, `Option 'aadGroupNames' is deprecated. Please use 'entraGroupNames' instead.`); - } - const loginNames = await this.getLoginNames(logger, args.options); let apiUrl = `${args.options.webUrl}/_api/web/SiteGroups`; diff --git a/src/m365/spo/commands/group/group-member-remove.spec.ts b/src/m365/spo/commands/group/group-member-remove.spec.ts index 84ecd5fa54c..cbccf4c3882 100644 --- a/src/m365/spo/commands/group/group-member-remove.spec.ts +++ b/src/m365/spo/commands/group/group-member-remove.spec.ts @@ -130,40 +130,6 @@ describe(commands.GROUP_MEMBER_REMOVE, () => { assert(postStub.called); }); - it('Removes Microsoft Entra group from SharePoint group using Microsoft Entra Group Name', async () => { - sinonUtil.restore(cli.promptForConfirmation); - sinon.stub(cli, 'promptForConfirmation').resolves(true); - - sinon.stub(cli, 'executeCommandWithOutput').callsFake(async (command): Promise => { - if (command === spoGroupMemberListCommand) { - return ({ - stdout: spoGroupMemberListCommandOutput - }); - } - - throw new CommandError('Unknown case'); - }); - - const postStub = sinon.stub(request, 'post').callsFake(async opts => { - if ((opts.url as string).indexOf('/_api/web/sitegroups/GetByName') > -1) { - return UserRemovalJSONResponse; - } - - throw `Invalid request ${JSON.stringify(opts)}`; - }); - - await command.action(logger, { - options: { - debug: true, - webUrl: "https://contoso.sharepoint.com/sites/SiteA", - groupName: "Site A Visitors", - aadGroupName: "Microsoft Entra Security Group" - } - }); - - assert(postStub.called); - }); - it('Removes Entra group from SharePoint group using Entra Group ID - Without Confirmation Prompt', async () => { sinon.stub(cli, 'executeCommandWithOutput').callsFake(async (command): Promise => { if (command === spoGroupMemberListCommand) { @@ -194,36 +160,6 @@ describe(commands.GROUP_MEMBER_REMOVE, () => { assert(postStub.called); }); - it('Removes Microsoft Entra group from SharePoint group using Microsoft Entra Group ID - Without Confirmation Prompt', async () => { - sinon.stub(cli, 'executeCommandWithOutput').callsFake(async (command): Promise => { - if (command === spoGroupMemberListCommand) { - return ({ - stdout: spoGroupMemberListCommandOutput - }); - } - - throw new CommandError('Unknown case'); - }); - - const postStub = sinon.stub(request, 'post').callsFake(async opts => { - if ((opts.url as string).indexOf('/_api/web/sitegroups/GetByName') > -1) { - return UserRemovalJSONResponse; - } - - throw `Invalid request ${JSON.stringify(opts)}`; - }); - await command.action(logger, { - options: { - debug: true, - webUrl: "https://contoso.sharepoint.com/sites/SiteA", - groupName: "Site A Visitors", - aadGroupId: "5786b8e8-c495-4734-b345-756733960730", - force: true - } - }); - assert(postStub.called); - }); - it('Removes Entra group from SharePoint group using Entra Group ID and SharePoint Group ID', async () => { sinonUtil.restore(cli.promptForConfirmation); sinon.stub(cli, 'promptForConfirmation').resolves(true); @@ -710,15 +646,4 @@ describe(commands.GROUP_MEMBER_REMOVE, () => { }, commandInfo); assert.notStrictEqual(actual, true); }); - - it('fails validation if aadGroupId is not a valid guid.', async () => { - const actual = await command.validate({ - options: { - webUrl: "https://contoso.sharepoint.com/sites/SiteA", - groupId: 3, - aadGroupId: 'Invalid GUID' - } - }, commandInfo); - assert.notStrictEqual(actual, true); - }); }); \ No newline at end of file diff --git a/src/m365/spo/commands/group/group-member-remove.ts b/src/m365/spo/commands/group/group-member-remove.ts index 4ea58a7bc06..420a5b09d83 100644 --- a/src/m365/spo/commands/group/group-member-remove.ts +++ b/src/m365/spo/commands/group/group-member-remove.ts @@ -22,9 +22,7 @@ interface Options extends GlobalOptions { email?: string; userId?: number; entraGroupId?: string; - aadGroupId?: string; entraGroupName?: string; - aadGroupName?: string; force?: boolean; } @@ -55,9 +53,7 @@ class SpoGroupMemberRemoveCommand extends SpoCommand { email: (!(!args.options.email)).toString(), userId: (!(!args.options.userId)).toString(), entraGroupId: (!(!args.options.entraGroupId)).toString(), - aadGroupId: (!(!args.options.groupId)).toString(), entraGroupName: (!(!args.options.entraGroupName)).toString(), - aadGroupName: (!(!args.options.aadGroupName)).toString(), force: (!(!args.options.force)).toString() }); }); @@ -86,15 +82,9 @@ class SpoGroupMemberRemoveCommand extends SpoCommand { { option: '--entraGroupId [entraGroupId]' }, - { - option: '--aadGroupId [aadGroupId]' - }, { option: '--entraGroupName [entraGroupName]' }, - { - option: '--aadGroupName [aadGroupName]' - }, { option: '-f, --force' } @@ -124,10 +114,6 @@ class SpoGroupMemberRemoveCommand extends SpoCommand { return `${args.options.entraGroupId} is not a valid GUID`; } - if (args.options.aadGroupId && !validation.isValidGuid(args.options.aadGroupId as string)) { - return `${args.options.aadGroupId} is not a valid GUID`; - } - return validation.isValidSharePointUrl(args.options.webUrl); } ); @@ -136,7 +122,7 @@ class SpoGroupMemberRemoveCommand extends SpoCommand { #initOptionSets(): void { this.optionSets.push( { options: ['groupName', 'groupId'] }, - { options: ['userName', 'email', 'userId', 'entraGroupId', 'aadGroupId', 'entraGroupName', 'aadGroupName'] } + { options: ['userName', 'email', 'userId', 'entraGroupId', 'entraGroupName'] } ); } @@ -162,18 +148,6 @@ class SpoGroupMemberRemoveCommand extends SpoCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - if (args.options.aadGroupId) { - args.options.entraGroupId = args.options.aadGroupId; - - await this.warn(logger, `Option 'aadGroupId' is deprecated. Please use 'entraGroupId' instead`); - } - - if (args.options.aadGroupName) { - args.options.entraGroupName = args.options.aadGroupName; - - await this.warn(logger, `Option 'aadGroupName' is deprecated. Please use 'entraGroupName' instead`); - } - if (args.options.force) { if (this.debug) { await logger.logToStderr('Confirmation bypassed by entering confirm option. Removing the user from SharePoint Group...'); diff --git a/src/m365/spo/commands/user/user-ensure.spec.ts b/src/m365/spo/commands/user/user-ensure.spec.ts index c9f99d0ded8..9e8382f0723 100644 --- a/src/m365/spo/commands/user/user-ensure.spec.ts +++ b/src/m365/spo/commands/user/user-ensure.spec.ts @@ -116,23 +116,6 @@ describe(commands.USER_ENSURE, () => { assert(loggerLogSpy.calledWith(ensuredUserResponse)); }); - it('ensures user for a specific web by aadId', async () => { - sinon.stub(entraUser, 'getUpnByUserId').callsFake(async () => { - return validUserName; - }); - - sinon.stub(request, 'post').callsFake(async (opts) => { - if (opts.url === `${validWebUrl}/_api/web/ensureuser`) { - return ensuredUserResponse; - } - - throw 'Invalid request'; - }); - - await command.action(logger, { options: { verbose: true, webUrl: validWebUrl, aadId: validEntraId } }); - assert(loggerLogSpy.calledWith(ensuredUserResponse)); - }); - it('throws error message when no user was found with a specific id', async () => { sinon.stub(entraUser, 'getUpnByUserId').callsFake(async (id) => { throw { @@ -186,11 +169,6 @@ describe(commands.USER_ENSURE, () => { assert.notStrictEqual(actual, true); }); - it('fails validation if aadId is not a valid id', async () => { - const actual = await command.validate({ options: { webUrl: validWebUrl, aadId: 'invalid' } }, commandInfo); - assert.notStrictEqual(actual, true); - }); - it('fails validation if userName is not a valid user principal name', async () => { const actual = await command.validate({ options: { webUrl: validWebUrl, userName: 'invalid' } }, commandInfo); assert.notStrictEqual(actual, true); @@ -201,11 +179,6 @@ describe(commands.USER_ENSURE, () => { assert.strictEqual(actual, true); }); - it('passes validation if the url is valid and aadId is a valid id', async () => { - const actual = await command.validate({ options: { webUrl: validWebUrl, aadId: validEntraId } }, commandInfo); - assert.strictEqual(actual, true); - }); - it('passes validation if the url is valid and userName is a valid user principal name', async () => { const actual = await command.validate({ options: { webUrl: validWebUrl, userName: validUserName } }, commandInfo); assert.strictEqual(actual, true); diff --git a/src/m365/spo/commands/user/user-ensure.ts b/src/m365/spo/commands/user/user-ensure.ts index 7a624851303..c4f681d15aa 100644 --- a/src/m365/spo/commands/user/user-ensure.ts +++ b/src/m365/spo/commands/user/user-ensure.ts @@ -13,7 +13,6 @@ interface CommandArgs { interface Options extends GlobalOptions { webUrl: string; entraId?: string; - aadId?: string; userName?: string; } @@ -39,7 +38,6 @@ class SpoUserEnsureCommand extends SpoCommand { this.telemetry.push((args: CommandArgs) => { Object.assign(this.telemetryProperties, { entraId: typeof args.options.entraId !== 'undefined', - aadId: typeof args.options.aadId !== 'undefined', userName: typeof args.options.userName !== 'undefined' }); }); @@ -53,9 +51,6 @@ class SpoUserEnsureCommand extends SpoCommand { { option: '--entraId [entraId]' }, - { - option: '--aadId [aadId]' - }, { option: '--userName [userName]' } @@ -74,10 +69,6 @@ class SpoUserEnsureCommand extends SpoCommand { return `${args.options.entraId} is not a valid GUID.`; } - if (args.options.aadId && !validation.isValidGuid(args.options.aadId)) { - return `${args.options.aadId} is not a valid GUID.`; - } - if (args.options.userName && !validation.isValidUserPrincipalName(args.options.userName)) { return `${args.options.userName} is not a valid userName.`; } @@ -88,16 +79,10 @@ class SpoUserEnsureCommand extends SpoCommand { } #initOptionSets(): void { - this.optionSets.push({ options: ['entraId', 'aadId', 'userName'] }); + this.optionSets.push({ options: ['entraId', 'userName'] }); } public async commandAction(logger: Logger, args: CommandArgs): Promise { - if (args.options.aadId) { - args.options.entraId = args.options.aadId; - - await this.warn(logger, `Option 'aadId' is deprecated. Please use 'entraId' instead`); - } - if (this.verbose) { await logger.logToStderr(`Ensuring user ${args.options.entraId || args.options.userName} at site ${args.options.webUrl}`); } From 78282a9a5aed705f78da90e8d0e9e9eb2e2bd8ed Mon Sep 17 00:00:00 2001 From: Nanddeep Nachan Date: Fri, 9 Aug 2024 17:10:23 +0000 Subject: [PATCH 19/20] v9 guidance --- docs/docs/v9-upgrade-guidance.mdx | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/docs/v9-upgrade-guidance.mdx b/docs/docs/v9-upgrade-guidance.mdx index c806c87e0fc..8ef145b34b0 100644 --- a/docs/docs/v9-upgrade-guidance.mdx +++ b/docs/docs/v9-upgrade-guidance.mdx @@ -157,6 +157,17 @@ The `spo folder rename` command was removed and replaced by the [spo folder set] Please, update your scripts to use the `spo folder set` command instead of `spo folder rename`. +### Renamed `aad` options in `spo group member add`, `spo group member remove`, and `spo user ensure` commands + +For this new major version, we've Removed `aad` options in below spo commands: + - Renamed `--aadGroupIds` and `--aadGroupNames` option to `--entraGroupIds' and `--entraGroupNames` in `spo group member add`. + - Renamed `--aadGroupIds` and `--aadGroupNames` option to `--entraGroupIds' and '--entraGroupNames' in 'spo group member remove'. + - Renamed `--aadId` option to `--entraId` in `spo user ensure`. + +#### What action do I need to take? + +Please, check the documentation of the [spo group member add](./cmd/spo/group/group-member-add.mdx), [spo group member remove](./cmd/spo/group/group-member-remove.mdx), and [spo user ensure](./cmd/spo/user/user-ensure.mdx) command to see the updated options and adjust your scripts accordingly. + ## SharePoint Framework ### Removed overwrite option from `spfx project github workflow add` command @@ -165,4 +176,6 @@ Overwriting the SPFx package should be the default behavior of the continuous de #### What action do I need to take? -Please update your scripts not to use the `overwrite` option. \ No newline at end of file +Please update your scripts not to use the `overwrite` option.# v9 Upgrade Guidance + +The v9 of CLI for Microsoft 365 introduces several breaking changes. To help you upgrade to the latest version of CLI for Microsoft 365, we've listed those changes along with any actions you may need to take. From 30010864642c38b9a736470fe528c4d2f6b60165 Mon Sep 17 00:00:00 2001 From: Nanddeep Nachan Date: Wed, 14 Aug 2024 10:20:14 +0000 Subject: [PATCH 20/20] removed aad aliases --- docs/docs/cmd/spo/group/group-member-add.mdx | 2 +- docs/docusaurus.config.ts | 3 - src/m365/entra/aadCommands.ts | 89 ------------------- .../administrativeunit-add.spec.ts | 11 --- .../administrativeunit-add.ts | 7 -- .../administrativeunit-get.spec.ts | 11 --- .../administrativeunit-get.ts | 7 -- .../administrativeunit-list.spec.ts | 11 --- .../administrativeunit-list.ts | 7 -- .../administrativeunit-member-add.spec.ts | 11 --- .../administrativeunit-member-add.ts | 7 -- .../administrativeunit-member-get.spec.ts | 11 --- .../administrativeunit-member-get.ts | 7 -- .../administrativeunit-member-list.spec.ts | 11 --- .../administrativeunit-member-list.ts | 7 -- .../administrativeunit-remove.spec.ts | 11 --- .../administrativeunit-remove.ts | 8 -- src/m365/entra/commands/app/app-add.spec.ts | 11 --- src/m365/entra/commands/app/app-add.ts | 7 -- src/m365/entra/commands/app/app-get.spec.ts | 11 --- src/m365/entra/commands/app/app-get.ts | 7 -- src/m365/entra/commands/app/app-list.spec.ts | 11 --- src/m365/entra/commands/app/app-list.ts | 7 -- .../commands/app/app-permission-add.spec.ts | 11 --- .../entra/commands/app/app-permission-add.ts | 7 -- .../entra/commands/app/app-remove.spec.ts | 11 --- src/m365/entra/commands/app/app-remove.ts | 7 -- .../entra/commands/app/app-role-add.spec.ts | 11 --- src/m365/entra/commands/app/app-role-add.ts | 7 -- .../entra/commands/app/app-role-list.spec.ts | 11 --- src/m365/entra/commands/app/app-role-list.ts | 7 -- .../commands/app/app-role-remove.spec.ts | 11 --- .../entra/commands/app/app-role-remove.ts | 7 -- src/m365/entra/commands/app/app-set.spec.ts | 11 --- src/m365/entra/commands/app/app-set.ts | 7 -- .../approleassignment-add.spec.ts | 11 --- .../approleassignment-add.ts | 7 -- .../approleassignment-list.spec.ts | 11 --- .../approleassignment-list.ts | 7 -- .../approleassignment-remove.spec.ts | 11 --- .../approleassignment-remove.ts | 7 -- .../enterpriseapp/enterpriseapp-add.spec.ts | 11 --- .../enterpriseapp/enterpriseapp-add.ts | 7 -- .../enterpriseapp/enterpriseapp-get.spec.ts | 11 --- .../enterpriseapp/enterpriseapp-get.ts | 7 -- .../enterpriseapp/enterpriseapp-list.spec.ts | 11 --- .../enterpriseapp/enterpriseapp-list.ts | 7 -- .../entra/commands/group/group-add.spec.ts | 11 --- src/m365/entra/commands/group/group-add.ts | 5 -- .../entra/commands/group/group-get.spec.ts | 11 --- src/m365/entra/commands/group/group-get.ts | 7 -- .../entra/commands/group/group-list.spec.ts | 11 --- src/m365/entra/commands/group/group-list.ts | 7 -- .../entra/commands/group/group-remove.spec.ts | 11 --- src/m365/entra/commands/group/group-remove.ts | 7 -- .../commands/group/group-user-list.spec.ts | 11 --- .../entra/commands/group/group-user-list.ts | 7 -- .../groupsetting/groupsetting-add.spec.ts | 11 --- .../commands/groupsetting/groupsetting-add.ts | 7 -- .../groupsetting/groupsetting-get.spec.ts | 11 --- .../commands/groupsetting/groupsetting-get.ts | 7 -- .../groupsetting/groupsetting-list.spec.ts | 11 --- .../groupsetting/groupsetting-list.ts | 7 -- .../groupsetting/groupsetting-remove.spec.ts | 11 --- .../groupsetting/groupsetting-remove.ts | 7 -- .../groupsetting/groupsetting-set.spec.ts | 11 --- .../commands/groupsetting/groupsetting-set.ts | 7 -- .../groupsettingtemplate-get.spec.ts | 11 --- .../groupsettingtemplate-get.ts | 7 -- .../groupsettingtemplate-list.spec.ts | 11 --- .../groupsettingtemplate-list.ts | 7 -- .../commands/license/license-list.spec.ts | 11 --- .../entra/commands/license/license-list.ts | 7 -- .../commands/m365group/m365group-add.spec.ts | 11 --- .../entra/commands/m365group/m365group-add.ts | 7 -- .../m365group-conversation-list.spec.ts | 11 --- .../m365group/m365group-conversation-list.ts | 7 -- .../m365group-conversation-post-list.spec.ts | 18 ++-- .../m365group-conversation-post-list.ts | 7 -- .../commands/m365group/m365group-get.spec.ts | 11 --- .../entra/commands/m365group/m365group-get.ts | 7 -- .../commands/m365group/m365group-list.spec.ts | 11 --- .../commands/m365group/m365group-list.ts | 7 -- .../m365group-recyclebinitem-clear.spec.ts | 11 --- .../m365group-recyclebinitem-clear.ts | 7 -- .../m365group-recyclebinitem-list.spec.ts | 11 --- .../m365group-recyclebinitem-list.ts | 7 -- .../m365group-recyclebinitem-remove.spec.ts | 11 --- .../m365group-recyclebinitem-remove.ts | 7 -- .../m365group-recyclebinitem-restore.spec.ts | 11 --- .../m365group-recyclebinitem-restore.ts | 7 -- .../m365group/m365group-remove.spec.ts | 11 --- .../commands/m365group/m365group-remove.ts | 7 -- .../m365group/m365group-renew.spec.ts | 11 --- .../commands/m365group/m365group-renew.ts | 7 -- .../m365group-report-activitycounts.spec.ts | 11 --- .../m365group-report-activitycounts.ts | 5 -- .../m365group-report-activitydetail.spec.ts | 11 --- .../m365group-report-activitydetail.ts | 5 -- ...365group-report-activityfilecounts.spec.ts | 13 +-- .../m365group-report-activityfilecounts.ts | 5 -- ...65group-report-activitygroupcounts.spec.ts | 13 +-- .../m365group-report-activitygroupcounts.ts | 5 -- .../m365group-report-activitystorage.spec.ts | 13 +-- .../m365group-report-activitystorage.ts | 5 -- .../commands/m365group/m365group-set.spec.ts | 11 --- .../entra/commands/m365group/m365group-set.ts | 7 -- .../m365group/m365group-teamify.spec.ts | 11 --- .../commands/m365group/m365group-teamify.ts | 7 -- .../m365group/m365group-user-add.spec.ts | 12 --- .../commands/m365group/m365group-user-add.ts | 8 -- .../m365group/m365group-user-list.spec.ts | 11 --- .../commands/m365group/m365group-user-list.ts | 7 -- .../m365group/m365group-user-remove.spec.ts | 12 --- .../m365group/m365group-user-remove.ts | 8 -- .../m365group/m365group-user-set.spec.ts | 12 --- .../commands/m365group/m365group-user-set.ts | 9 -- .../oauth2grant/oauth2grant-add.spec.ts | 11 --- .../commands/oauth2grant/oauth2grant-add.ts | 7 -- .../oauth2grant/oauth2grant-list.spec.ts | 11 --- .../commands/oauth2grant/oauth2grant-list.ts | 7 -- .../oauth2grant/oauth2grant-remove.spec.ts | 11 --- .../oauth2grant/oauth2grant-remove.ts | 7 -- .../oauth2grant/oauth2grant-set.spec.ts | 11 --- .../commands/oauth2grant/oauth2grant-set.ts | 7 -- .../entra/commands/policy/policy-list.spec.ts | 11 --- src/m365/entra/commands/policy/policy-list.ts | 7 -- .../siteclassification-disable.spec.ts | 11 --- .../siteclassification-disable.ts | 7 -- .../siteclassification-enable.spec.ts | 11 --- .../siteclassification-enable.ts | 7 -- .../siteclassification-get.spec.ts | 11 --- .../siteclassification-get.ts | 7 -- .../siteclassification-set.spec.ts | 11 --- .../siteclassification-set.ts | 7 -- src/m365/entra/commands/user/user-add.spec.ts | 11 --- src/m365/entra/commands/user/user-add.ts | 7 -- src/m365/entra/commands/user/user-get.spec.ts | 21 ++--- src/m365/entra/commands/user/user-get.ts | 7 -- .../commands/user/user-guest-add.spec.ts | 11 --- .../entra/commands/user/user-guest-add.ts | 7 -- .../entra/commands/user/user-hibp.spec.ts | 11 --- src/m365/entra/commands/user/user-hibp.ts | 7 -- .../commands/user/user-license-add.spec.ts | 11 --- .../entra/commands/user/user-license-add.ts | 7 -- .../commands/user/user-license-list.spec.ts | 11 --- .../entra/commands/user/user-license-list.ts | 7 -- .../commands/user/user-license-remove.spec.ts | 11 --- .../commands/user/user-license-remove.ts | 7 -- .../entra/commands/user/user-list.spec.ts | 11 --- src/m365/entra/commands/user/user-list.ts | 7 -- .../user/user-password-validate.spec.ts | 11 --- .../commands/user/user-password-validate.ts | 7 -- .../user/user-recyclebinitem-clear.spec.ts | 11 --- .../user/user-recyclebinitem-clear.ts | 7 -- .../user/user-recyclebinitem-list.spec.ts | 11 --- .../commands/user/user-recyclebinitem-list.ts | 7 -- .../user/user-recyclebinitem-remove.spec.ts | 11 --- .../user/user-recyclebinitem-remove.ts | 7 -- .../user/user-recyclebinitem-restore.spec.ts | 11 --- .../user/user-recyclebinitem-restore.ts | 7 -- .../user-registrationdetails-list.spec.ts | 11 --- .../user/user-registrationdetails-list.ts | 5 -- .../entra/commands/user/user-remove.spec.ts | 11 --- src/m365/entra/commands/user/user-remove.ts | 7 -- src/m365/entra/commands/user/user-set.spec.ts | 11 --- src/m365/entra/commands/user/user-set.ts | 7 -- .../commands/user/user-signin-list.spec.ts | 11 --- .../entra/commands/user/user-signin-list.ts | 7 -- .../group/group-member-remove.spec.ts | 64 +++++++++++++ 170 files changed, 79 insertions(+), 1590 deletions(-) delete mode 100644 src/m365/entra/aadCommands.ts diff --git a/docs/docs/cmd/spo/group/group-member-add.mdx b/docs/docs/cmd/spo/group/group-member-add.mdx index 8973044ffc7..ae521aed3f0 100644 --- a/docs/docs/cmd/spo/group/group-member-add.mdx +++ b/docs/docs/cmd/spo/group/group-member-add.mdx @@ -34,7 +34,7 @@ m365 spo group member add [options] : The user Id of the user to add as a member. (Id of the site user, for example: 14). If multiple users need to be added, the Ids have to be comma-separated. Specify either `userIds`, `userNames`, `emails`, `entraGroupIds` or `entraGroupNames`. `--entraGroupIds [entraGroupIds]` -: The object Id of the Entra group to add as a member. If multiple groups need to be added, the Ids have to be comma-separated. Specify either `userIds`, `userNames`, `emails`, `entraGroupIds`or `entraGroupNames`. +: The object Id of the Entra group to add as a member. If multiple groups need to be added, the Ids have to be comma-separated. Specify either `userIds`, `userNames`, `emails`, `entraGroupIds` or `entraGroupNames`. `--entraGroupNames [entraGroupNames]` : The name of the Entra group to add as a member. If multiple groups need to be added, they have to be comma-separated. Specify either `userIds`, `userNames`, `emails`, `entraGroupIds` or `entraGroupNames`. diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index ef1c39e6c2e..f676d2eed82 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -49,9 +49,6 @@ const config: Config = { 'client-redirects', { createRedirects(routePath) { - if (routePath.includes('/entra')) { - return [routePath.replace('/entra', '/aad')]; - } if (routePath.includes('/viva/engage')) { return [routePath.replace('/viva/engage', '/yammer')]; } diff --git a/src/m365/entra/aadCommands.ts b/src/m365/entra/aadCommands.ts deleted file mode 100644 index 3ceff166f60..00000000000 --- a/src/m365/entra/aadCommands.ts +++ /dev/null @@ -1,89 +0,0 @@ -const prefix: string = 'aad'; - -export default { - ADMINISTRATIVEUNIT_ADD: `${prefix} administrativeunit add`, - ADMINISTRATIVEUNIT_GET: `${prefix} administrativeunit get`, - ADMINISTRATIVEUNIT_LIST: `${prefix} administrativeunit list`, - ADMINISTRATIVEUNIT_REMOVE: `${prefix} administrativeunit remove`, - ADMINISTRATIVEUNIT_MEMBER_ADD: `${prefix} administrativeunit member add`, - ADMINISTRATIVEUNIT_MEMBER_GET: `${prefix} administrativeunit member get`, - ADMINISTRATIVEUNIT_MEMBER_LIST: `${prefix} administrativeunit member list`, - ADMINISTRATIVEUNIT_MEMBER_REMOVE: `${prefix} administrativeunit member remove`, - ADMINISTRATIVEUNIT_ROLEASSIGNMENT_ADD: `${prefix} administrativeunit roleassignment add`, - APP_ADD: `${prefix} app add`, - APP_GET: `${prefix} app get`, - APP_LIST: `${prefix} app list`, - APP_REMOVE: `${prefix} app remove`, - APP_SET: `${prefix} app set`, - APP_PERMISSION_ADD: `${prefix} app permission add`, - APP_ROLE_ADD: `${prefix} app role add`, - APP_ROLE_LIST: `${prefix} app role list`, - APP_ROLE_REMOVE: `${prefix} app role remove`, - APPROLEASSIGNMENT_ADD: `${prefix} approleassignment add`, - APPROLEASSIGNMENT_LIST: `${prefix} approleassignment list`, - APPROLEASSIGNMENT_REMOVE: `${prefix} approleassignment remove`, - GROUP_ADD: `${prefix} group add`, - GROUP_GET: `${prefix} group get`, - GROUP_LIST: `${prefix} group list`, - GROUP_REMOVE: `${prefix} group remove`, - GROUP_USER_LIST: `${prefix} group user list`, - GROUPSETTING_ADD: `${prefix} groupsetting add`, - GROUPSETTING_GET: `${prefix} groupsetting get`, - GROUPSETTING_LIST: `${prefix} groupsetting list`, - GROUPSETTING_REMOVE: `${prefix} groupsetting remove`, - GROUPSETTING_SET: `${prefix} groupsetting set`, - GROUPSETTINGTEMPLATE_GET: `${prefix} groupsettingtemplate get`, - GROUPSETTINGTEMPLATE_LIST: `${prefix} groupsettingtemplate list`, - LICENSE_LIST: `${prefix} license list`, - M365GROUP_ADD: `${prefix} m365group add`, - M365GROUP_GET: `${prefix} m365group get`, - M365GROUP_LIST: `${prefix} m365group list`, - M365GROUP_CONVERSATION_LIST: `${prefix} m365group conversation list`, - M365GROUP_CONVERSATION_POST_LIST: `${prefix} m365group conversation post list`, - M365GROUP_RECYCLEBINITEM_CLEAR: `${prefix} m365group recyclebinitem clear`, - M365GROUP_RECYCLEBINITEM_LIST: `${prefix} m365group recyclebinitem list`, - M365GROUP_RECYCLEBINITEM_REMOVE: `${prefix} m365group recyclebinitem remove`, - M365GROUP_RECYCLEBINITEM_RESTORE: `${prefix} m365group recyclebinitem restore`, - M365GROUP_SET: `${prefix} m365group set`, - M365GROUP_TEAMIFY: `${prefix} m365group teamify`, - M365GROUP_REMOVE: `${prefix} m365group remove`, - M365GROUP_RENEW: `${prefix} m365group renew`, - M365GROUP_REPORT_ACTIVITYCOUNTS: `${prefix} m365group report activitycounts`, - M365GROUP_REPORT_ACTIVITYDETAIL: `${prefix} m365group report activitydetail`, - M365GROUP_REPORT_ACTIVITYFILECOUNTS: `${prefix} m365group report activityfilecounts`, - M365GROUP_REPORT_ACTIVITYGROUPCOUNTS: `${prefix} m365group report activitygroupcounts`, - M365GROUP_REPORT_ACTIVITYSTORAGE: `${prefix} m365group report activitystorage`, - M365GROUP_USER_ADD: `${prefix} m365group user add`, - M365GROUP_USER_LIST: `${prefix} m365group user list`, - M365GROUP_USER_REMOVE: `${prefix} m365group user remove`, - M365GROUP_USER_SET: `${prefix} m365group user set`, - OAUTH2GRANT_ADD: `${prefix} oauth2grant add`, - OAUTH2GRANT_LIST: `${prefix} oauth2grant list`, - OAUTH2GRANT_REMOVE: `${prefix} oauth2grant remove`, - OAUTH2GRANT_SET: `${prefix} oauth2grant set`, - POLICY_LIST: `${prefix} policy list`, - SITECLASSIFICATION_DISABLE: `${prefix} siteclassification disable`, - SITECLASSIFICATION_ENABLE: `${prefix} siteclassification enable`, - SITECLASSIFICATION_GET: `${prefix} siteclassification get`, - SITECLASSIFICATION_SET: `${prefix} siteclassification set`, - SP_ADD: `${prefix} sp add`, - SP_GET: `${prefix} sp get`, - SP_LIST: `${prefix} sp list`, - USER_ADD: `${prefix} user add`, - USER_GET: `${prefix} user get`, - USER_GUEST_ADD: `${prefix} user guest add`, - USER_HIBP: `${prefix} user hibp`, - USER_LICENSE_ADD: `${prefix} user license add`, - USER_LICENSE_LIST: `${prefix} user license list`, - USER_LICENSE_REMOVE: `${prefix} user license remove`, - USER_LIST: `${prefix} user list`, - USER_PASSWORD_VALIDATE: `${prefix} user password validate`, - USER_RECYCLEBINITEM_CLEAR: `${prefix} user recyclebinitem clear`, - USER_RECYCLEBINITEM_LIST: `${prefix} user recyclebinitem list`, - USER_RECYCLEBINITEM_REMOVE: `${prefix} user recyclebinitem remove`, - USER_REGISTRATIONDETAILS_LIST: `${prefix} user registrationdetails list`, - USER_REMOVE: `${prefix} user remove`, - USER_RECYCLEBINITEM_RESTORE: `${prefix} user recyclebinitem restore`, - USER_SET: `${prefix} user set`, - USER_SIGNIN_LIST: `${prefix} user signin list` -}; diff --git a/src/m365/entra/commands/administrativeunit/administrativeunit-add.spec.ts b/src/m365/entra/commands/administrativeunit/administrativeunit-add.spec.ts index a762d5cac0b..7f3b5c2521e 100644 --- a/src/m365/entra/commands/administrativeunit/administrativeunit-add.spec.ts +++ b/src/m365/entra/commands/administrativeunit/administrativeunit-add.spec.ts @@ -12,7 +12,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import request from '../../../../request.js'; import { Logger } from '../../../../cli/Logger.js'; import { CommandError } from '../../../../Command.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.ADMINISTRATIVEUNIT_ADD, () => { const administrativeUnitReponse: any = { @@ -72,16 +71,6 @@ describe(commands.ADMINISTRATIVEUNIT_ADD, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.ADMINISTRATIVEUNIT_ADD]); - }); - it('creates an administrative unit with a specific display name', async () => { const postStub = sinon.stub(request, 'post').callsFake(async (opts) => { if (opts.url === 'https://graph.microsoft.com/v1.0/directory/administrativeUnits') { diff --git a/src/m365/entra/commands/administrativeunit/administrativeunit-add.ts b/src/m365/entra/commands/administrativeunit/administrativeunit-add.ts index 4a314149dbd..37e60e17884 100644 --- a/src/m365/entra/commands/administrativeunit/administrativeunit-add.ts +++ b/src/m365/entra/commands/administrativeunit/administrativeunit-add.ts @@ -4,7 +4,6 @@ import { Logger } from "../../../../cli/Logger.js"; import request, { CliRequestOptions } from "../../../../request.js"; import GraphCommand from "../../../base/GraphCommand.js"; import commands from "../../commands.js"; -import aadCommands from "../../aadCommands.js"; interface CommandArgs { options: Options; @@ -25,10 +24,6 @@ class EntraAdministrativeUnitAddCommand extends GraphCommand { return 'Creates an administrative unit'; } - public alias(): string[] | undefined { - return [aadCommands.ADMINISTRATIVEUNIT_ADD]; - } - constructor() { super(); @@ -59,8 +54,6 @@ class EntraAdministrativeUnitAddCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.ADMINISTRATIVEUNIT_ADD, commands.ADMINISTRATIVEUNIT_ADD); - const requestOptions: CliRequestOptions = { url: `${this.resource}/v1.0/directory/administrativeUnits`, headers: { diff --git a/src/m365/entra/commands/administrativeunit/administrativeunit-get.spec.ts b/src/m365/entra/commands/administrativeunit/administrativeunit-get.spec.ts index d5b26f3fac1..2bee010e9c9 100644 --- a/src/m365/entra/commands/administrativeunit/administrativeunit-get.spec.ts +++ b/src/m365/entra/commands/administrativeunit/administrativeunit-get.spec.ts @@ -13,7 +13,6 @@ import request from '../../../../request.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import { CommandError } from '../../../../Command.js'; import { entraAdministrativeUnit } from '../../../../utils/entraAdministrativeUnit.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.ADMINISTRATIVEUNIT_GET, () => { let log: string[]; @@ -83,16 +82,6 @@ describe(commands.ADMINISTRATIVEUNIT_GET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.ADMINISTRATIVEUNIT_GET]); - }); - it('retrieves information about the specified administrative unit by id', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/directory/administrativeUnits/${validId}`) { diff --git a/src/m365/entra/commands/administrativeunit/administrativeunit-get.ts b/src/m365/entra/commands/administrativeunit/administrativeunit-get.ts index 930c7015c83..9c3755317c9 100644 --- a/src/m365/entra/commands/administrativeunit/administrativeunit-get.ts +++ b/src/m365/entra/commands/administrativeunit/administrativeunit-get.ts @@ -6,7 +6,6 @@ import request, { CliRequestOptions } from "../../../../request.js"; import GraphCommand from "../../../base/GraphCommand.js"; import commands from "../../commands.js"; import { entraAdministrativeUnit } from "../../../../utils/entraAdministrativeUnit.js"; -import aadCommands from "../../aadCommands.js"; interface CommandArgs { options: Options; @@ -26,10 +25,6 @@ class EntraAdministrativeUnitGetCommand extends GraphCommand { return 'Gets information about a specific administrative unit'; } - public alias(): string[] | undefined { - return [aadCommands.ADMINISTRATIVEUNIT_GET]; - } - constructor() { super(); @@ -81,8 +76,6 @@ class EntraAdministrativeUnitGetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.ADMINISTRATIVEUNIT_GET, commands.ADMINISTRATIVEUNIT_GET); - let administrativeUnit: AdministrativeUnit; try { diff --git a/src/m365/entra/commands/administrativeunit/administrativeunit-list.spec.ts b/src/m365/entra/commands/administrativeunit/administrativeunit-list.spec.ts index f1d18809f7b..c746daa2a22 100644 --- a/src/m365/entra/commands/administrativeunit/administrativeunit-list.spec.ts +++ b/src/m365/entra/commands/administrativeunit/administrativeunit-list.spec.ts @@ -10,7 +10,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './administrativeunit-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.ADMINISTRATIVEUNIT_LIST, () => { let log: string[]; @@ -60,16 +59,6 @@ describe(commands.ADMINISTRATIVEUNIT_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.ADMINISTRATIVEUNIT_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['id', 'displayName', 'visibility']); }); diff --git a/src/m365/entra/commands/administrativeunit/administrativeunit-list.ts b/src/m365/entra/commands/administrativeunit/administrativeunit-list.ts index 826bfe432dd..83b84bc1552 100644 --- a/src/m365/entra/commands/administrativeunit/administrativeunit-list.ts +++ b/src/m365/entra/commands/administrativeunit/administrativeunit-list.ts @@ -3,7 +3,6 @@ import { Logger } from '../../../../cli/Logger.js'; import { odata } from '../../../../utils/odata.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; class EntraAdministrativeUnitListCommand extends GraphCommand { public get name(): string { @@ -14,17 +13,11 @@ class EntraAdministrativeUnitListCommand extends GraphCommand { return 'Retrieves a list of administrative units'; } - public alias(): string[] | undefined { - return [aadCommands.ADMINISTRATIVEUNIT_LIST]; - } - public defaultProperties(): string[] | undefined { return ['id', 'displayName', 'visibility']; } public async commandAction(logger: Logger): Promise { - await this.showDeprecationWarning(logger, aadCommands.ADMINISTRATIVEUNIT_LIST, commands.ADMINISTRATIVEUNIT_LIST); - try { const results = await odata.getAllItems(`${this.resource}/v1.0/directory/administrativeUnits`); await logger.log(results); diff --git a/src/m365/entra/commands/administrativeunit/administrativeunit-member-add.spec.ts b/src/m365/entra/commands/administrativeunit/administrativeunit-member-add.spec.ts index e1f5b89156b..b83234ecdfe 100644 --- a/src/m365/entra/commands/administrativeunit/administrativeunit-member-add.spec.ts +++ b/src/m365/entra/commands/administrativeunit/administrativeunit-member-add.spec.ts @@ -17,7 +17,6 @@ import { entraGroup } from '../../../../utils/entraGroup.js'; import { entraUser } from '../../../../utils/entraUser.js'; import { entraDevice } from '../../../../utils/entraDevice.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.ADMINISTRATIVEUNIT_MEMBER_ADD, () => { const administrativeUnitId = 'fc33aa61-cf0e-46b6-9506-f633347202ab'; @@ -83,16 +82,6 @@ describe(commands.ADMINISTRATIVEUNIT_MEMBER_ADD, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.ADMINISTRATIVEUNIT_MEMBER_ADD]); - }); - it('passes validation when administrativeUnitId is a valid GUID', async () => { const actual = await command.validate({ options: { administrativeUnitId: administrativeUnitId, userId: '00000000-0000-0000-0000-000000000000' } }, commandInfo); assert.strictEqual(actual, true); diff --git a/src/m365/entra/commands/administrativeunit/administrativeunit-member-add.ts b/src/m365/entra/commands/administrativeunit/administrativeunit-member-add.ts index 91107daa660..b9a0bd8d964 100644 --- a/src/m365/entra/commands/administrativeunit/administrativeunit-member-add.ts +++ b/src/m365/entra/commands/administrativeunit/administrativeunit-member-add.ts @@ -8,7 +8,6 @@ import GraphCommand from "../../../base/GraphCommand.js"; import commands from "../../commands.js"; import request, { CliRequestOptions } from "../../../../request.js"; import { entraDevice } from "../../../../utils/entraDevice.js"; -import aadCommands from "../../aadCommands.js"; interface CommandArgs { options: Options; @@ -34,10 +33,6 @@ class EntraAdministrativeUnitMemberAddCommand extends GraphCommand { return 'Adds a member (user, group, device) to an administrative unit'; } - public alias(): string[] | undefined { - return [aadCommands.ADMINISTRATIVEUNIT_MEMBER_ADD]; - } - constructor() { super(); @@ -119,8 +114,6 @@ class EntraAdministrativeUnitMemberAddCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.ADMINISTRATIVEUNIT_MEMBER_ADD, commands.ADMINISTRATIVEUNIT_MEMBER_ADD); - let administrativeUnitId = args.options.administrativeUnitId; let memberType; let memberId; diff --git a/src/m365/entra/commands/administrativeunit/administrativeunit-member-get.spec.ts b/src/m365/entra/commands/administrativeunit/administrativeunit-member-get.spec.ts index 2081aa4a876..1fe76b10455 100644 --- a/src/m365/entra/commands/administrativeunit/administrativeunit-member-get.spec.ts +++ b/src/m365/entra/commands/administrativeunit/administrativeunit-member-get.spec.ts @@ -14,7 +14,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import { CommandError } from '../../../../Command.js'; import { entraAdministrativeUnit } from '../../../../utils/entraAdministrativeUnit.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.ADMINISTRATIVEUNIT_MEMBER_GET, () => { const administrativeUnitId = 'fc33aa61-cf0e-46b6-9506-f633347202ab'; @@ -89,16 +88,6 @@ describe(commands.ADMINISTRATIVEUNIT_MEMBER_GET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.ADMINISTRATIVEUNIT_MEMBER_GET]); - }); - it('passes validation when member id and administrativeUnitId are GUIDs', async () => { const actual = await command.validate({ options: { id: userId, administrativeUnitId: administrativeUnitId } }, commandInfo); assert.strictEqual(actual, true); diff --git a/src/m365/entra/commands/administrativeunit/administrativeunit-member-get.ts b/src/m365/entra/commands/administrativeunit/administrativeunit-member-get.ts index 079176990a8..8e03b756c1c 100644 --- a/src/m365/entra/commands/administrativeunit/administrativeunit-member-get.ts +++ b/src/m365/entra/commands/administrativeunit/administrativeunit-member-get.ts @@ -6,7 +6,6 @@ import { Logger } from '../../../../cli/Logger.js'; import { validation } from '../../../../utils/validation.js'; import { entraAdministrativeUnit } from '../../../../utils/entraAdministrativeUnit.js'; import request, { CliRequestOptions } from '../../../../request.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -34,10 +33,6 @@ class EntraAdministrativeUnitMemberGetCommand extends GraphCommand { return 'Retrieve a specific member (user, group, or device) of an administrative unit'; } - public alias(): string[] | undefined { - return [aadCommands.ADMINISTRATIVEUNIT_MEMBER_GET]; - } - constructor() { super(); @@ -95,8 +90,6 @@ class EntraAdministrativeUnitMemberGetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.ADMINISTRATIVEUNIT_MEMBER_GET, commands.ADMINISTRATIVEUNIT_MEMBER_GET); - let administrativeUnitId = args.options.administrativeUnitId; try { diff --git a/src/m365/entra/commands/administrativeunit/administrativeunit-member-list.spec.ts b/src/m365/entra/commands/administrativeunit/administrativeunit-member-list.spec.ts index dde7b23d60e..b62afa68c56 100644 --- a/src/m365/entra/commands/administrativeunit/administrativeunit-member-list.spec.ts +++ b/src/m365/entra/commands/administrativeunit/administrativeunit-member-list.spec.ts @@ -14,7 +14,6 @@ import { settingsNames } from '../../../../settingsNames.js'; import { CommandInfo } from '../../../../cli/CommandInfo.js'; import { cli } from '../../../../cli/cli.js'; import { entraAdministrativeUnit } from '../../../../utils/entraAdministrativeUnit.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.ADMINISTRATIVEUNIT_MEMBER_LIST, () => { const administrativeUnitId = 'fc33aa61-cf0e-46b6-9506-f633347202ab'; @@ -326,16 +325,6 @@ describe(commands.ADMINISTRATIVEUNIT_MEMBER_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.ADMINISTRATIVEUNIT_MEMBER_LIST]); - }); - it('passes validation when administrativeUnitId is a valid GUID', async () => { const actual = await command.validate({ options: { administrativeUnitId: administrativeUnitId } }, commandInfo); assert.strictEqual(actual, true); diff --git a/src/m365/entra/commands/administrativeunit/administrativeunit-member-list.ts b/src/m365/entra/commands/administrativeunit/administrativeunit-member-list.ts index 32bef4536ea..0055e560e47 100644 --- a/src/m365/entra/commands/administrativeunit/administrativeunit-member-list.ts +++ b/src/m365/entra/commands/administrativeunit/administrativeunit-member-list.ts @@ -7,7 +7,6 @@ import GlobalOptions from '../../../../GlobalOptions.js'; import { entraAdministrativeUnit } from '../../../../utils/entraAdministrativeUnit.js'; import { validation } from '../../../../utils/validation.js'; import { CliRequestOptions } from '../../../../request.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -35,10 +34,6 @@ class EntraAdministrativeUnitMemberListCommand extends GraphCommand { return 'Retrieves members (users, groups, or devices) of an administrative unit.'; } - public alias(): string[] | undefined { - return [aadCommands.ADMINISTRATIVEUNIT_MEMBER_LIST]; - } - public defaultProperties(): string[] | undefined { return ['id', 'displayName']; } @@ -110,8 +105,6 @@ class EntraAdministrativeUnitMemberListCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.ADMINISTRATIVEUNIT_MEMBER_LIST, commands.ADMINISTRATIVEUNIT_MEMBER_LIST); - let administrativeUnitId = args.options.administrativeUnitId; try { diff --git a/src/m365/entra/commands/administrativeunit/administrativeunit-remove.spec.ts b/src/m365/entra/commands/administrativeunit/administrativeunit-remove.spec.ts index 8b00fe054ff..3aa290db0af 100644 --- a/src/m365/entra/commands/administrativeunit/administrativeunit-remove.spec.ts +++ b/src/m365/entra/commands/administrativeunit/administrativeunit-remove.spec.ts @@ -13,7 +13,6 @@ import { cli } from '../../../../cli/cli.js'; import { CommandInfo } from '../../../../cli/CommandInfo.js'; import command from './administrativeunit-remove.js'; import { entraAdministrativeUnit } from '../../../../utils/entraAdministrativeUnit.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.ADMINISTRATIVEUNIT_REMOVE, () => { const administrativeUnitId = 'fc33aa61-cf0e-46b6-9506-f633347202ab'; @@ -76,16 +75,6 @@ describe(commands.ADMINISTRATIVEUNIT_REMOVE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.ADMINISTRATIVEUNIT_REMOVE]); - }); - it('removes the specified administrative unit by id without prompting for confirmation', async () => { const deleteRequestStub = sinon.stub(request, 'delete').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/directory/administrativeUnits/${administrativeUnitId}`) { diff --git a/src/m365/entra/commands/administrativeunit/administrativeunit-remove.ts b/src/m365/entra/commands/administrativeunit/administrativeunit-remove.ts index a46c6638c23..35bb9a277dd 100644 --- a/src/m365/entra/commands/administrativeunit/administrativeunit-remove.ts +++ b/src/m365/entra/commands/administrativeunit/administrativeunit-remove.ts @@ -6,8 +6,6 @@ import request, { CliRequestOptions } from "../../../../request.js"; import GraphCommand from "../../../base/GraphCommand.js"; import commands from "../../commands.js"; import { cli } from "../../../../cli/cli.js"; -import aadCommands from '../../aadCommands.js'; - interface CommandArgs { options: Options; @@ -27,10 +25,6 @@ class EntraAdministrativeUnitRemoveCommand extends GraphCommand { return 'Removes an administrative unit'; } - public alias(): string[] | undefined { - return [aadCommands.ADMINISTRATIVEUNIT_REMOVE]; - } - constructor() { super(); @@ -90,8 +84,6 @@ class EntraAdministrativeUnitRemoveCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.ADMINISTRATIVEUNIT_REMOVE, commands.ADMINISTRATIVEUNIT_REMOVE); - const removeAdministrativeUnit = async (): Promise => { try { let administrativeUnitId = args.options.id; diff --git a/src/m365/entra/commands/app/app-add.spec.ts b/src/m365/entra/commands/app/app-add.spec.ts index 9b26f9275e3..cbc0f83a0bf 100644 --- a/src/m365/entra/commands/app/app-add.spec.ts +++ b/src/m365/entra/commands/app/app-add.spec.ts @@ -14,7 +14,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './app-add.js'; import * as mocks from './app-add.mock.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.APP_ADD, () => { @@ -204,16 +203,6 @@ describe(commands.APP_ADD, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.APP_ADD, commands.APPREGISTRATION_ADD]); - }); - it('creates Microsoft Entra app reg with just the name', async () => { sinon.stub(request, 'get').rejects('Issues GET request'); sinon.stub(request, 'patch').rejects('Issued PATCH request'); diff --git a/src/m365/entra/commands/app/app-add.ts b/src/m365/entra/commands/app/app-add.ts index 2a51964bceb..8c241ba62ec 100644 --- a/src/m365/entra/commands/app/app-add.ts +++ b/src/m365/entra/commands/app/app-add.ts @@ -9,7 +9,6 @@ import { odata } from '../../../../utils/odata.js'; import GraphCommand from '../../../base/GraphCommand.js'; import { M365RcJson } from '../../../base/M365RcJson.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface ServicePrincipalInfo { appId: string; @@ -89,10 +88,6 @@ class EntraAppAddCommand extends GraphCommand { return 'Creates new Entra app registration'; } - public alias(): string[] | undefined { - return [aadCommands.APP_ADD, commands.APPREGISTRATION_ADD]; - } - constructor() { super(); @@ -259,8 +254,6 @@ class EntraAppAddCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.APP_ADD, commands.APP_ADD); - try { const apis = await this.resolveApis(args, logger); let appInfo: any = await this.createAppRegistration(args, apis, logger); diff --git a/src/m365/entra/commands/app/app-get.spec.ts b/src/m365/entra/commands/app/app-get.spec.ts index 50a93894b01..5147ec30235 100644 --- a/src/m365/entra/commands/app/app-get.spec.ts +++ b/src/m365/entra/commands/app/app-get.spec.ts @@ -14,7 +14,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './app-get.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.APP_GET, () => { let log: string[]; @@ -71,16 +70,6 @@ describe(commands.APP_GET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.APP_GET, commands.APPREGISTRATION_GET]); - }); - it('handles error when the app specified with the appId not found', async () => { sinon.stub(request, 'get').callsFake(async opts => { if (opts.url === `https://graph.microsoft.com/v1.0/myorganization/applications?$filter=appId eq '9b1b1e42-794b-4c71-93ac-5ed92488b67f'&$select=id`) { diff --git a/src/m365/entra/commands/app/app-get.ts b/src/m365/entra/commands/app/app-get.ts index 969a5849d0f..d4b9be64cec 100644 --- a/src/m365/entra/commands/app/app-get.ts +++ b/src/m365/entra/commands/app/app-get.ts @@ -9,7 +9,6 @@ import GraphCommand from '../../../base/GraphCommand.js'; import { M365RcJson } from '../../../base/M365RcJson.js'; import commands from '../../commands.js'; import { cli } from '../../../../cli/cli.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -31,10 +30,6 @@ class EntraAppGetCommand extends GraphCommand { return 'Gets an Entra app registration'; } - public alias(): string[] | undefined { - return [aadCommands.APP_GET, commands.APPREGISTRATION_GET]; - } - constructor() { super(); @@ -84,8 +79,6 @@ class EntraAppGetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.APP_GET, commands.APP_GET); - try { const appObjectId = await this.getAppObjectId(args); const appInfo = await this.getAppInfo(appObjectId); diff --git a/src/m365/entra/commands/app/app-list.spec.ts b/src/m365/entra/commands/app/app-list.spec.ts index cf858293c48..e94f74a31d0 100644 --- a/src/m365/entra/commands/app/app-list.spec.ts +++ b/src/m365/entra/commands/app/app-list.spec.ts @@ -10,7 +10,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './app-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.APP_LIST, () => { let log: string[]; @@ -60,16 +59,6 @@ describe(commands.APP_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.APP_LIST, commands.APPREGISTRATION_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['appId', 'id', 'displayName', 'signInAudience']); }); diff --git a/src/m365/entra/commands/app/app-list.ts b/src/m365/entra/commands/app/app-list.ts index dd1c5fd9223..24d920ee920 100644 --- a/src/m365/entra/commands/app/app-list.ts +++ b/src/m365/entra/commands/app/app-list.ts @@ -3,7 +3,6 @@ import { Logger } from '../../../../cli/Logger.js'; import { odata } from "../../../../utils/odata.js"; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; class EntraAppListCommand extends GraphCommand { public get name(): string { @@ -14,17 +13,11 @@ class EntraAppListCommand extends GraphCommand { return 'Retrieves a list of Entra app registrations'; } - public alias(): string[] | undefined { - return [aadCommands.APP_LIST, commands.APPREGISTRATION_LIST]; - } - public defaultProperties(): string[] | undefined { return ['appId', 'id', 'displayName', "signInAudience"]; } public async commandAction(logger: Logger): Promise { - await this.showDeprecationWarning(logger, aadCommands.APP_LIST, commands.APP_LIST); - try { const results = await odata.getAllItems(`${this.resource}/v1.0/applications`); await logger.log(results); diff --git a/src/m365/entra/commands/app/app-permission-add.spec.ts b/src/m365/entra/commands/app/app-permission-add.spec.ts index 46ae98ab85e..7967484fe47 100644 --- a/src/m365/entra/commands/app/app-permission-add.spec.ts +++ b/src/m365/entra/commands/app/app-permission-add.spec.ts @@ -15,7 +15,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './app-permission-add.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.APP_PERMISSION_ADD, () => { const appId = '9c79078b-815e-4a3e-bb80-2aaf2d9e9b3d'; @@ -86,16 +85,6 @@ describe(commands.APP_PERMISSION_ADD, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.APP_PERMISSION_ADD, commands.APPREGISTRATION_PERMISSION_ADD]); - }); - it('adds application permissions to app specified by appObjectId without granting admin consent', async () => { sinon.stub(odata, 'getAllItems').callsFake(async (url: string) => { switch (url) { diff --git a/src/m365/entra/commands/app/app-permission-add.ts b/src/m365/entra/commands/app/app-permission-add.ts index 849498fdefc..68820520720 100644 --- a/src/m365/entra/commands/app/app-permission-add.ts +++ b/src/m365/entra/commands/app/app-permission-add.ts @@ -6,7 +6,6 @@ import commands from "../../commands.js"; import request, { CliRequestOptions } from "../../../../request.js"; import { Logger } from "../../../../cli/Logger.js"; import { validation } from "../../../../utils/validation.js"; -import aadCommands from "../../aadCommands.js"; import { formatting } from "../../../../utils/formatting.js"; import { cli } from "../../../../cli/cli.js"; @@ -43,10 +42,6 @@ class EntraAppPermissionAddCommand extends GraphCommand { return 'Adds the specified application and/or delegated permissions to a specified Microsoft Entra app'; } - public alias(): string[] | undefined { - return [aadCommands.APP_PERMISSION_ADD, commands.APPREGISTRATION_PERMISSION_ADD]; - } - constructor() { super(); @@ -105,8 +100,6 @@ class EntraAppPermissionAddCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.APP_PERMISSION_ADD, commands.APP_PERMISSION_ADD); - try { const appObject = await this.getAppObject(args.options); const servicePrincipals = await this.getServicePrincipals(); diff --git a/src/m365/entra/commands/app/app-remove.spec.ts b/src/m365/entra/commands/app/app-remove.spec.ts index 4f57cd50a6b..5e564df95b4 100644 --- a/src/m365/entra/commands/app/app-remove.spec.ts +++ b/src/m365/entra/commands/app/app-remove.spec.ts @@ -13,7 +13,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './app-remove.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.APP_REMOVE, () => { let log: string[]; @@ -100,16 +99,6 @@ describe(commands.APP_REMOVE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.APP_REMOVE, commands.APPREGISTRATION_REMOVE]); - }); - it('fails validation if appId and name specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { diff --git a/src/m365/entra/commands/app/app-remove.ts b/src/m365/entra/commands/app/app-remove.ts index 05987b6d612..e32424318f5 100644 --- a/src/m365/entra/commands/app/app-remove.ts +++ b/src/m365/entra/commands/app/app-remove.ts @@ -5,7 +5,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { formatting } from '../../../../utils/formatting.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -28,10 +27,6 @@ class EntraAppRemoveCommand extends GraphCommand { return 'Removes an Entra app registration'; } - public alias(): string[] | undefined { - return [aadCommands.APP_REMOVE, commands.APPREGISTRATION_REMOVE]; - } - constructor() { super(); @@ -82,8 +77,6 @@ class EntraAppRemoveCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.APP_REMOVE, commands.APP_REMOVE); - const deleteApp = async (): Promise => { try { const objectId = await this.getObjectId(args, logger); diff --git a/src/m365/entra/commands/app/app-role-add.spec.ts b/src/m365/entra/commands/app/app-role-add.spec.ts index 8754d96f1d7..d9ee59dc53e 100644 --- a/src/m365/entra/commands/app/app-role-add.spec.ts +++ b/src/m365/entra/commands/app/app-role-add.spec.ts @@ -13,7 +13,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './app-role-add.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.APP_ROLE_ADD, () => { let log: string[]; @@ -66,16 +65,6 @@ describe(commands.APP_ROLE_ADD, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.APP_ROLE_ADD, commands.APPREGISTRATION_ROLE_ADD]); - }); - it('creates app role for the specified appId, app has no roles', async () => { sinon.stub(request, 'get').callsFake(async opts => { if (opts.url === `https://graph.microsoft.com/v1.0/myorganization/applications?$filter=appId eq 'bc724b77-da87-43a9-b385-6ebaaf969db8'&$select=id`) { diff --git a/src/m365/entra/commands/app/app-role-add.ts b/src/m365/entra/commands/app/app-role-add.ts index e1211b8a714..c9929f8a808 100644 --- a/src/m365/entra/commands/app/app-role-add.ts +++ b/src/m365/entra/commands/app/app-role-add.ts @@ -6,7 +6,6 @@ import { formatting } from '../../../../utils/formatting.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; import { cli } from '../../../../cli/cli.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -44,10 +43,6 @@ class EntraAppRoleAddCommand extends GraphCommand { return 'Adds role to the specified Entra app registration'; } - public alias(): string[] | undefined { - return [aadCommands.APP_ROLE_ADD, commands.APPREGISTRATION_ROLE_ADD]; - } - constructor() { super(); @@ -112,8 +107,6 @@ class EntraAppRoleAddCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.APP_ROLE_ADD, commands.APP_ROLE_ADD); - try { const appId = await this.getAppObjectId(args, logger); const appInfo = await this.getAppInfo(appId, logger); diff --git a/src/m365/entra/commands/app/app-role-list.spec.ts b/src/m365/entra/commands/app/app-role-list.spec.ts index da55924e438..7c8fc10cb2c 100644 --- a/src/m365/entra/commands/app/app-role-list.spec.ts +++ b/src/m365/entra/commands/app/app-role-list.spec.ts @@ -13,7 +13,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './app-role-list.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.APP_ROLE_LIST, () => { let log: string[]; @@ -68,16 +67,6 @@ describe(commands.APP_ROLE_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.APP_ROLE_LIST, commands.APPREGISTRATION_ROLE_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['displayName', 'description', 'id']); }); diff --git a/src/m365/entra/commands/app/app-role-list.ts b/src/m365/entra/commands/app/app-role-list.ts index 594ec364a76..bd2660955cd 100644 --- a/src/m365/entra/commands/app/app-role-list.ts +++ b/src/m365/entra/commands/app/app-role-list.ts @@ -7,7 +7,6 @@ import { odata } from '../../../../utils/odata.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; import { cli } from '../../../../cli/cli.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -28,10 +27,6 @@ class EntraAppRoleListCommand extends GraphCommand { return 'Gets Entra app registration roles'; } - public alias(): string[] | undefined { - return [aadCommands.APP_ROLE_LIST, commands.APPREGISTRATION_ROLE_LIST]; - } - constructor() { super(); @@ -67,8 +62,6 @@ class EntraAppRoleListCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.APP_ROLE_LIST, commands.APP_ROLE_LIST); - try { const objectId = await this.getAppObjectId(args, logger); const appRoles = await odata.getAllItems(`${this.resource}/v1.0/myorganization/applications/${objectId}/appRoles`); diff --git a/src/m365/entra/commands/app/app-role-remove.spec.ts b/src/m365/entra/commands/app/app-role-remove.spec.ts index 649a6f8bb9e..ff93f72ea01 100644 --- a/src/m365/entra/commands/app/app-role-remove.spec.ts +++ b/src/m365/entra/commands/app/app-role-remove.spec.ts @@ -13,7 +13,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './app-role-remove.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.APP_ROLE_REMOVE, () => { let log: string[]; @@ -74,16 +73,6 @@ describe(commands.APP_ROLE_REMOVE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.APP_ROLE_REMOVE, commands.APPREGISTRATION_ROLE_REMOVE]); - }); - it('deletes an app role when the role is in enabled state and valid appObjectId, role claim and --force option specified', async () => { sinon.stub(request, 'get').callsFake(async opts => { if (opts.url === 'https://graph.microsoft.com/v1.0/myorganization/applications/5b31c38c-2584-42f0-aa47-657fb3a84230?$select=id,appRoles') { diff --git a/src/m365/entra/commands/app/app-role-remove.ts b/src/m365/entra/commands/app/app-role-remove.ts index 258b09bfa86..b8796f2c13f 100644 --- a/src/m365/entra/commands/app/app-role-remove.ts +++ b/src/m365/entra/commands/app/app-role-remove.ts @@ -7,7 +7,6 @@ import { formatting } from "../../../../utils/formatting.js"; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from "../../aadCommands.js"; interface CommandArgs { options: Options; @@ -31,10 +30,6 @@ class EntraAppRoleRemoveCommand extends GraphCommand { return 'Removes role from the specified Entra app registration'; } - public alias(): string[] | undefined { - return [aadCommands.APP_ROLE_REMOVE, commands.APPREGISTRATION_ROLE_REMOVE]; - } - constructor() { super(); @@ -91,8 +86,6 @@ class EntraAppRoleRemoveCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.APP_ROLE_REMOVE, commands.APP_ROLE_REMOVE); - const deleteAppRole = async (): Promise => { try { await this.processAppRoleDelete(logger, args); diff --git a/src/m365/entra/commands/app/app-set.spec.ts b/src/m365/entra/commands/app/app-set.spec.ts index 88612d755f9..3936f23a3d6 100644 --- a/src/m365/entra/commands/app/app-set.spec.ts +++ b/src/m365/entra/commands/app/app-set.spec.ts @@ -14,7 +14,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './app-set.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.APP_SET, () => { @@ -74,16 +73,6 @@ describe(commands.APP_SET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.APP_SET, commands.APPREGISTRATION_SET]); - }); - it('updates uris for the specified appId', async () => { sinon.stub(request, 'get').callsFake(async opts => { if (opts.url === `https://graph.microsoft.com/v1.0/myorganization/applications?$filter=appId eq 'bc724b77-da87-43a9-b385-6ebaaf969db8'&$select=id`) { diff --git a/src/m365/entra/commands/app/app-set.ts b/src/m365/entra/commands/app/app-set.ts index 070f6b9302d..21fcc119f72 100644 --- a/src/m365/entra/commands/app/app-set.ts +++ b/src/m365/entra/commands/app/app-set.ts @@ -7,7 +7,6 @@ import { formatting } from '../../../../utils/formatting.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; import { cli } from '../../../../cli/cli.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -38,10 +37,6 @@ class EntraAppSetCommand extends GraphCommand { return 'Updates Entra app registration'; } - public alias(): string[] | undefined { - return [aadCommands.APP_SET, commands.APPREGISTRATION_SET]; - } - constructor() { super(); @@ -130,8 +125,6 @@ class EntraAppSetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.APP_SET, commands.APP_SET); - try { let objectId = await this.getAppObjectId(args, logger); objectId = await this.configureUri(args, objectId, logger); diff --git a/src/m365/entra/commands/approleassignment/approleassignment-add.spec.ts b/src/m365/entra/commands/approleassignment/approleassignment-add.spec.ts index e0838ad535d..48b06f262e3 100644 --- a/src/m365/entra/commands/approleassignment/approleassignment-add.spec.ts +++ b/src/m365/entra/commands/approleassignment/approleassignment-add.spec.ts @@ -14,7 +14,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './approleassignment-add.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.APPROLEASSIGNMENT_ADD, () => { let log: string[]; @@ -89,16 +88,6 @@ describe(commands.APPROLEASSIGNMENT_ADD, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.APPROLEASSIGNMENT_ADD]); - }); - it('sets App Role assignments for service principal with specified appDisplayName', async () => { getRequestStub(); postRequestStub(); diff --git a/src/m365/entra/commands/approleassignment/approleassignment-add.ts b/src/m365/entra/commands/approleassignment/approleassignment-add.ts index c2cae66c315..b48eb8e930b 100644 --- a/src/m365/entra/commands/approleassignment/approleassignment-add.ts +++ b/src/m365/entra/commands/approleassignment/approleassignment-add.ts @@ -8,7 +8,6 @@ import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; import { ServicePrincipal } from '@microsoft/microsoft-graph-types'; import { cli } from '../../../../cli/cli.js'; -import aadCommands from '../../aadCommands.js'; interface AppRole { objectId: string; @@ -37,10 +36,6 @@ class EntraAppRoleAssignmentAddCommand extends GraphCommand { return 'Adds service principal permissions also known as scopes and app role assignments for specified Microsoft Entra application registration'; } - public alias(): string[] | undefined { - return [aadCommands.APPROLEASSIGNMENT_ADD]; - } - constructor() { super(); @@ -102,8 +97,6 @@ class EntraAppRoleAssignmentAddCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.APPROLEASSIGNMENT_ADD, commands.APPROLEASSIGNMENT_ADD); - let objectId: string = ''; let queryFilter: string = ''; if (args.options.appId) { diff --git a/src/m365/entra/commands/approleassignment/approleassignment-list.spec.ts b/src/m365/entra/commands/approleassignment/approleassignment-list.spec.ts index c8227378468..c25ff909230 100644 --- a/src/m365/entra/commands/approleassignment/approleassignment-list.spec.ts +++ b/src/m365/entra/commands/approleassignment/approleassignment-list.spec.ts @@ -14,7 +14,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './approleassignment-list.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; class ServicePrincipalAppRoleAssignments { private static AppRoleAssignments: any = { @@ -482,16 +481,6 @@ describe(commands.APPROLEASSIGNMENT_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.APPROLEASSIGNMENT_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['resourceDisplayName', 'roleName']); }); diff --git a/src/m365/entra/commands/approleassignment/approleassignment-list.ts b/src/m365/entra/commands/approleassignment/approleassignment-list.ts index 60d702996a8..3d82c94fac6 100644 --- a/src/m365/entra/commands/approleassignment/approleassignment-list.ts +++ b/src/m365/entra/commands/approleassignment/approleassignment-list.ts @@ -6,7 +6,6 @@ import { formatting } from '../../../../utils/formatting.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -27,10 +26,6 @@ class EntraAppRoleAssignmentListCommand extends GraphCommand { return 'Lists app role assignments for the specified application registration'; } - public alias(): string[] | undefined { - return [aadCommands.APPROLEASSIGNMENT_LIST]; - } - constructor() { super(); @@ -89,8 +84,6 @@ class EntraAppRoleAssignmentListCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.APPROLEASSIGNMENT_LIST, commands.APPROLEASSIGNMENT_LIST); - try { const spAppRoleAssignments = await this.getAppRoleAssignments(args.options); // the role assignment has an appRoleId but no name. To get the name, diff --git a/src/m365/entra/commands/approleassignment/approleassignment-remove.spec.ts b/src/m365/entra/commands/approleassignment/approleassignment-remove.spec.ts index 43c8a605b40..5cbe52b11af 100644 --- a/src/m365/entra/commands/approleassignment/approleassignment-remove.spec.ts +++ b/src/m365/entra/commands/approleassignment/approleassignment-remove.spec.ts @@ -14,7 +14,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './approleassignment-remove.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.APPROLEASSIGNMENT_REMOVE, () => { let log: string[]; @@ -92,16 +91,6 @@ describe(commands.APPROLEASSIGNMENT_REMOVE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.APPROLEASSIGNMENT_REMOVE]); - }); - it('prompts before removing the app role assignment when force option not passed', async () => { await command.action(logger, { options: { appId: 'dc311e81-e099-4c64-bd66-c7183465f3f2', resource: 'SharePoint', scope: 'Sites.Read.All' } }); diff --git a/src/m365/entra/commands/approleassignment/approleassignment-remove.ts b/src/m365/entra/commands/approleassignment/approleassignment-remove.ts index c1619daf51b..eb67e31fcdb 100644 --- a/src/m365/entra/commands/approleassignment/approleassignment-remove.ts +++ b/src/m365/entra/commands/approleassignment/approleassignment-remove.ts @@ -8,7 +8,6 @@ import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; import { AppRole, AppRoleAssignment, ServicePrincipal } from '@microsoft/microsoft-graph-types'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -32,10 +31,6 @@ class EntraAppRoleAssignmentRemoveCommand extends GraphCommand { return 'Deletes an app role assignment for the specified Entra Application Registration'; } - public alias(): string[] | undefined { - return [aadCommands.APPROLEASSIGNMENT_REMOVE]; - } - constructor() { super(); @@ -101,8 +96,6 @@ class EntraAppRoleAssignmentRemoveCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.APPROLEASSIGNMENT_REMOVE, commands.APPROLEASSIGNMENT_REMOVE); - const removeAppRoleAssignment = async (): Promise => { let sp: ServicePrincipal; // get the service principal associated with the appId diff --git a/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.spec.ts b/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.spec.ts index b6810d693cd..009558afa22 100644 --- a/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.spec.ts +++ b/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.spec.ts @@ -13,7 +13,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './enterpriseapp-add.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.ENTERPRISEAPP_ADD, () => { let log: string[]; @@ -69,16 +68,6 @@ describe(commands.ENTERPRISEAPP_ADD, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.SP_ADD, commands.SP_ADD]); - }); - it('fails validation if neither the id, displayName, nor objectId option specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { diff --git a/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.ts b/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.ts index aa0cdab113e..f732ea1a64a 100644 --- a/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.ts +++ b/src/m365/entra/commands/enterpriseapp/enterpriseapp-add.ts @@ -6,7 +6,6 @@ import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; import { cli } from '../../../../cli/cli.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -27,10 +26,6 @@ class EntraEnterpriseAppAddCommand extends GraphCommand { return 'Creates an enterprise application (or service principal) for a registered Entra app'; } - public alias(): string[] | undefined { - return [aadCommands.SP_ADD, commands.SP_ADD]; - } - constructor() { super(); @@ -123,8 +118,6 @@ class EntraEnterpriseAppAddCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.SP_ADD, commands.SP_ADD); - try { const appId = await this.getAppId(args); diff --git a/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.spec.ts b/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.spec.ts index e5664bbfe2a..a95f812c6d5 100644 --- a/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.spec.ts +++ b/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.spec.ts @@ -13,7 +13,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './enterpriseapp-get.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.ENTERPRISEAPP_GET, () => { let log: string[]; @@ -83,16 +82,6 @@ describe(commands.ENTERPRISEAPP_GET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.SP_GET, commands.SP_GET]); - }); - it('retrieves information about the specified enterprise application using its display name', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if ((opts.url as string).indexOf(`/v1.0/servicePrincipals?$filter=displayName eq `) > -1) { diff --git a/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.ts b/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.ts index e159fbee368..0fe94b35b4a 100644 --- a/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.ts +++ b/src/m365/entra/commands/enterpriseapp/enterpriseapp-get.ts @@ -5,7 +5,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { formatting } from '../../../../utils/formatting.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -27,10 +26,6 @@ class EntraEnterpriseAppGetCommand extends GraphCommand { return 'Gets information about an Enterprise Application'; } - public alias(): string[] | undefined { - return [aadCommands.SP_GET, commands.SP_GET]; - } - constructor() { super(); @@ -123,8 +118,6 @@ class EntraEnterpriseAppGetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.SP_GET, commands.SP_GET); - if (this.verbose) { await logger.logToStderr(`Retrieving enterprise application information...`); } diff --git a/src/m365/entra/commands/enterpriseapp/enterpriseapp-list.spec.ts b/src/m365/entra/commands/enterpriseapp/enterpriseapp-list.spec.ts index 60e23ae9db2..5e9355420f9 100644 --- a/src/m365/entra/commands/enterpriseapp/enterpriseapp-list.spec.ts +++ b/src/m365/entra/commands/enterpriseapp/enterpriseapp-list.spec.ts @@ -9,7 +9,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './enterpriseapp-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.ENTERPRISEAPP_LIST, () => { let log: string[]; @@ -135,16 +134,6 @@ describe(commands.ENTERPRISEAPP_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.SP_LIST, commands.SP_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['appId', 'displayName', 'tag']); }); diff --git a/src/m365/entra/commands/enterpriseapp/enterpriseapp-list.ts b/src/m365/entra/commands/enterpriseapp/enterpriseapp-list.ts index a2547c38260..903518dfe78 100644 --- a/src/m365/entra/commands/enterpriseapp/enterpriseapp-list.ts +++ b/src/m365/entra/commands/enterpriseapp/enterpriseapp-list.ts @@ -2,7 +2,6 @@ import { Logger } from '../../../../cli/Logger.js'; import GlobalOptions from '../../../../GlobalOptions.js'; import { odata } from '../../../../utils/odata.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -27,10 +26,6 @@ class EntraEnterpriseAppListCommand extends GraphCommand { return 'Lists the enterprise applications (or service principals) in Entra ID'; } - public alias(): string[] | undefined { - return [aadCommands.SP_LIST, commands.SP_LIST]; - } - constructor() { super(); @@ -59,8 +54,6 @@ class EntraEnterpriseAppListCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.SP_LIST, commands.SP_LIST); - if (this.verbose) { await logger.logToStderr(`Retrieving enterprise application information...`); } diff --git a/src/m365/entra/commands/group/group-add.spec.ts b/src/m365/entra/commands/group/group-add.spec.ts index eee6c612402..47874bc868d 100644 --- a/src/m365/entra/commands/group/group-add.spec.ts +++ b/src/m365/entra/commands/group/group-add.spec.ts @@ -2,7 +2,6 @@ import assert from 'assert'; import sinon from 'sinon'; import auth from '../../../../Auth.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; import { Logger } from '../../../../cli/Logger.js'; import request from '../../../../request.js'; import { telemetry } from '../../../../telemetry.js'; @@ -223,16 +222,6 @@ describe(commands.GROUP_ADD, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.GROUP_ADD]); - }); - it('fails validation if the length of displayName is more than 256 characters', async () => { const displayName = 'lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum'; const actual = await command.validate({ options: { displayName: displayName, type: 'security' } }, commandInfo); diff --git a/src/m365/entra/commands/group/group-add.ts b/src/m365/entra/commands/group/group-add.ts index 70130284397..f20abe55d42 100644 --- a/src/m365/entra/commands/group/group-add.ts +++ b/src/m365/entra/commands/group/group-add.ts @@ -2,7 +2,6 @@ import { Group } from '@microsoft/microsoft-graph-types'; import GlobalOptions from '../../../../GlobalOptions.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; import { validation } from '../../../../utils/validation.js'; import request, { CliRequestOptions } from '../../../../request.js'; import { Logger } from '../../../../cli/Logger.js'; @@ -33,10 +32,6 @@ class EntraGroupAddCommand extends GraphCommand { return 'Creates a Microsoft Entra group'; } - public alias(): string[] | undefined { - return [aadCommands.GROUP_ADD]; - } - public allowUnknownOptions(): boolean | undefined { return true; } diff --git a/src/m365/entra/commands/group/group-get.spec.ts b/src/m365/entra/commands/group/group-get.spec.ts index 04b98462b3c..725c6501aaa 100644 --- a/src/m365/entra/commands/group/group-get.spec.ts +++ b/src/m365/entra/commands/group/group-get.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './group-get.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.GROUP_GET, () => { let log: string[]; @@ -94,16 +93,6 @@ describe(commands.GROUP_GET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.GROUP_GET]); - }); - it('retrieves information about the specified Microsoft Entra Group by id', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/groups/${validId}`) { diff --git a/src/m365/entra/commands/group/group-get.ts b/src/m365/entra/commands/group/group-get.ts index fc2df0c0cc6..c642572d3f1 100644 --- a/src/m365/entra/commands/group/group-get.ts +++ b/src/m365/entra/commands/group/group-get.ts @@ -5,7 +5,6 @@ import { entraGroup } from '../../../../utils/entraGroup.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -25,10 +24,6 @@ class EntraGroupGetCommand extends GraphCommand { return 'Gets information about the specified Entra group'; } - public alias(): string[] | undefined { - return [aadCommands.GROUP_GET]; - } - constructor() { super(); @@ -77,8 +72,6 @@ class EntraGroupGetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.GROUP_GET, commands.GROUP_GET); - let group: Group; try { diff --git a/src/m365/entra/commands/group/group-list.spec.ts b/src/m365/entra/commands/group/group-list.spec.ts index 5751651aba1..9eec88ca640 100644 --- a/src/m365/entra/commands/group/group-list.spec.ts +++ b/src/m365/entra/commands/group/group-list.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './group-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.GROUP_LIST, () => { let log: string[]; @@ -65,16 +64,6 @@ describe(commands.GROUP_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.GROUP_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['id', 'displayName', 'groupType']); }); diff --git a/src/m365/entra/commands/group/group-list.ts b/src/m365/entra/commands/group/group-list.ts index b113840f31f..ca2f1acdad0 100644 --- a/src/m365/entra/commands/group/group-list.ts +++ b/src/m365/entra/commands/group/group-list.ts @@ -6,7 +6,6 @@ import { CliRequestOptions } from '../../../../request.js'; import { odata } from '../../../../utils/odata.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -31,10 +30,6 @@ class EntraGroupListCommand extends GraphCommand { return 'Lists all groups defined in Entra ID.'; } - public alias(): string[] | undefined { - return [aadCommands.GROUP_LIST]; - } - public defaultProperties(): string[] | undefined { return ['id', 'displayName', 'groupType']; } @@ -77,8 +72,6 @@ class EntraGroupListCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.GROUP_LIST, commands.GROUP_LIST); - try { let requestUrl: string = `${this.resource}/v1.0/groups`; let useConsistencyLevelHeader = false; diff --git a/src/m365/entra/commands/group/group-remove.spec.ts b/src/m365/entra/commands/group/group-remove.spec.ts index aed1f7eea19..5368f945021 100644 --- a/src/m365/entra/commands/group/group-remove.spec.ts +++ b/src/m365/entra/commands/group/group-remove.spec.ts @@ -15,7 +15,6 @@ import { CommandInfo } from '../../../../cli/CommandInfo.js'; import command from './group-remove.js'; import { settingsNames } from '../../../../settingsNames.js'; import { formatting } from '../../../../utils/formatting.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.GROUP_REMOVE, () => { const groupId = '2c1ba4c4-cd9b-4417-832f-92a34bc34b2a'; @@ -73,16 +72,6 @@ describe(commands.GROUP_REMOVE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.GROUP_REMOVE]); - }); - it('removes the specified group by id without prompting for confirmation', async () => { const deleteRequestStub = sinon.stub(request, 'delete').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/groups/${groupId}`) { diff --git a/src/m365/entra/commands/group/group-remove.ts b/src/m365/entra/commands/group/group-remove.ts index 7b05dceb479..3f133610996 100644 --- a/src/m365/entra/commands/group/group-remove.ts +++ b/src/m365/entra/commands/group/group-remove.ts @@ -6,7 +6,6 @@ import commands from '../../commands.js'; import request, { CliRequestOptions } from '../../../../request.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; import { validation } from '../../../../utils/validation.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -27,10 +26,6 @@ class EntraGroupRemoveCommand extends GraphCommand { return 'Removes an Entra group'; } - public alias(): string[] | undefined { - return [aadCommands.GROUP_REMOVE]; - } - constructor() { super(); @@ -90,8 +85,6 @@ class EntraGroupRemoveCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.GROUP_REMOVE, commands.GROUP_REMOVE); - const removeGroup = async (): Promise => { if (this.verbose) { await logger.logToStderr(`Removing group ${args.options.id || args.options.displayName}...`); diff --git a/src/m365/entra/commands/group/group-user-list.spec.ts b/src/m365/entra/commands/group/group-user-list.spec.ts index ff6ff99ef10..1bc8380c88b 100644 --- a/src/m365/entra/commands/group/group-user-list.spec.ts +++ b/src/m365/entra/commands/group/group-user-list.spec.ts @@ -15,7 +15,6 @@ import { settingsNames } from '../../../../settingsNames.js'; import { formatting } from '../../../../utils/formatting.js'; import commands from '../../commands.js'; import command from './group-user-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.GROUP_USER_LIST, () => { const groupId = '2c1ba4c4-cd9b-4417-832f-92a34bc34b2a'; @@ -74,16 +73,6 @@ describe(commands.GROUP_USER_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.GROUP_USER_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['id', 'displayName', 'userPrincipalName', 'roles']); }); diff --git a/src/m365/entra/commands/group/group-user-list.ts b/src/m365/entra/commands/group/group-user-list.ts index e6fb34b5c5f..0e4437321e6 100644 --- a/src/m365/entra/commands/group/group-user-list.ts +++ b/src/m365/entra/commands/group/group-user-list.ts @@ -7,7 +7,6 @@ import { odata } from '../../../../utils/odata.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -34,10 +33,6 @@ class EntraGroupUserListCommand extends GraphCommand { return 'Lists users of a specific Entra group'; } - public alias(): string[] | undefined { - return [aadCommands.GROUP_USER_LIST]; - } - public defaultProperties(): string[] | undefined { return ['id', 'displayName', 'userPrincipalName', 'roles']; } @@ -111,8 +106,6 @@ class EntraGroupUserListCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.GROUP_USER_LIST, commands.GROUP_USER_LIST); - try { const groupId = await this.getGroupId(args.options, logger); diff --git a/src/m365/entra/commands/groupsetting/groupsetting-add.spec.ts b/src/m365/entra/commands/groupsetting/groupsetting-add.spec.ts index ee66f1901e3..0b9756407d2 100644 --- a/src/m365/entra/commands/groupsetting/groupsetting-add.spec.ts +++ b/src/m365/entra/commands/groupsetting/groupsetting-add.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './groupsetting-add.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.GROUPSETTING_ADD, () => { let log: string[]; @@ -66,16 +65,6 @@ describe(commands.GROUPSETTING_ADD, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.GROUPSETTING_ADD]); - }); - it('adds group setting using default template setting values', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/groupSettingTemplates/62375ab9-6b52-47ed-826b-58e47e0e304b`) { diff --git a/src/m365/entra/commands/groupsetting/groupsetting-add.ts b/src/m365/entra/commands/groupsetting/groupsetting-add.ts index 66b7f62c01d..325b8439bfb 100644 --- a/src/m365/entra/commands/groupsetting/groupsetting-add.ts +++ b/src/m365/entra/commands/groupsetting/groupsetting-add.ts @@ -5,7 +5,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -24,10 +23,6 @@ class EntraGroupSettingAddCommand extends GraphCommand { return 'Creates a group setting'; } - public alias(): string[] | undefined { - return [aadCommands.GROUPSETTING_ADD]; - } - constructor() { super(); @@ -60,8 +55,6 @@ class EntraGroupSettingAddCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.GROUPSETTING_ADD, commands.GROUPSETTING_ADD); - if (this.verbose) { await logger.logToStderr(`Retrieving group setting template with id '${args.options.templateId}'...`); } diff --git a/src/m365/entra/commands/groupsetting/groupsetting-get.spec.ts b/src/m365/entra/commands/groupsetting/groupsetting-get.spec.ts index b032cad31e4..fbc6cdf579d 100644 --- a/src/m365/entra/commands/groupsetting/groupsetting-get.spec.ts +++ b/src/m365/entra/commands/groupsetting/groupsetting-get.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './groupsetting-get.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.GROUPSETTING_GET, () => { let log: string[]; @@ -64,16 +63,6 @@ describe(commands.GROUPSETTING_GET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.GROUPSETTING_GET]); - }); - it('retrieves information about the specified Group Setting', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/groupSettings/1caf7dcd-7e83-4c3a-94f7-932a1299c844`) { diff --git a/src/m365/entra/commands/groupsetting/groupsetting-get.ts b/src/m365/entra/commands/groupsetting/groupsetting-get.ts index e38a13ce2ac..95305c50ae8 100644 --- a/src/m365/entra/commands/groupsetting/groupsetting-get.ts +++ b/src/m365/entra/commands/groupsetting/groupsetting-get.ts @@ -3,7 +3,6 @@ import GlobalOptions from '../../../../GlobalOptions.js'; import request, { CliRequestOptions } from '../../../../request.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -23,10 +22,6 @@ class EntraGroupSettingGetCommand extends GraphCommand { return 'Gets information about the particular group setting'; } - public alias(): string[] | undefined { - return [aadCommands.GROUPSETTING_GET]; - } - constructor() { super(); @@ -55,8 +50,6 @@ class EntraGroupSettingGetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.GROUPSETTING_GET, commands.GROUPSETTING_GET); - try { const requestOptions: CliRequestOptions = { url: `${this.resource}/v1.0/groupSettings/${args.options.id}`, diff --git a/src/m365/entra/commands/groupsetting/groupsetting-list.spec.ts b/src/m365/entra/commands/groupsetting/groupsetting-list.spec.ts index 6fc1cec91f5..1ddfe94ef5f 100644 --- a/src/m365/entra/commands/groupsetting/groupsetting-list.spec.ts +++ b/src/m365/entra/commands/groupsetting/groupsetting-list.spec.ts @@ -10,7 +10,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './groupsetting-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.GROUPSETTING_LIST, () => { let log: string[]; @@ -61,16 +60,6 @@ describe(commands.GROUPSETTING_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.GROUPSETTING_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['id', 'displayName']); }); diff --git a/src/m365/entra/commands/groupsetting/groupsetting-list.ts b/src/m365/entra/commands/groupsetting/groupsetting-list.ts index 47a090d5e7c..eeab4ae3ebd 100644 --- a/src/m365/entra/commands/groupsetting/groupsetting-list.ts +++ b/src/m365/entra/commands/groupsetting/groupsetting-list.ts @@ -3,7 +3,6 @@ import { Logger } from '../../../../cli/Logger.js'; import { odata } from '../../../../utils/odata.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; class EntraGroupSettingListCommand extends GraphCommand { public get name(): string { @@ -14,17 +13,11 @@ class EntraGroupSettingListCommand extends GraphCommand { return 'Lists Entra group settings'; } - public alias(): string[] | undefined { - return [aadCommands.GROUPSETTING_LIST]; - } - public defaultProperties(): string[] | undefined { return ['id', 'displayName']; } public async commandAction(logger: Logger): Promise { - await this.showDeprecationWarning(logger, aadCommands.GROUPSETTING_LIST, commands.GROUPSETTING_LIST); - try { const groupSettings = await odata.getAllItems(`${this.resource}/v1.0/groupSettings`); await logger.log(groupSettings); diff --git a/src/m365/entra/commands/groupsetting/groupsetting-remove.spec.ts b/src/m365/entra/commands/groupsetting/groupsetting-remove.spec.ts index da66313ff97..7f616096824 100644 --- a/src/m365/entra/commands/groupsetting/groupsetting-remove.spec.ts +++ b/src/m365/entra/commands/groupsetting/groupsetting-remove.spec.ts @@ -13,7 +13,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './groupsetting-remove.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.GROUPSETTING_REMOVE, () => { let log: string[]; @@ -73,16 +72,6 @@ describe(commands.GROUPSETTING_REMOVE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.GROUPSETTING_REMOVE]); - }); - it('removes the specified group setting without prompting for confirmation when force option specified', async () => { const deleteRequestStub = sinon.stub(request, 'delete').callsFake(async (opts) => { if (opts.url === 'https://graph.microsoft.com/v1.0/groupSettings/28beab62-7540-4db1-a23f-29a6018a3848') { diff --git a/src/m365/entra/commands/groupsetting/groupsetting-remove.ts b/src/m365/entra/commands/groupsetting/groupsetting-remove.ts index d19453c86e2..7f89a7a3d03 100644 --- a/src/m365/entra/commands/groupsetting/groupsetting-remove.ts +++ b/src/m365/entra/commands/groupsetting/groupsetting-remove.ts @@ -4,7 +4,6 @@ import GlobalOptions from '../../../../GlobalOptions.js'; import request, { CliRequestOptions } from '../../../../request.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -25,10 +24,6 @@ class EntraGroupSettingRemoveCommand extends GraphCommand { return 'Removes the particular group setting'; } - public alias(): string[] | undefined { - return [aadCommands.GROUPSETTING_REMOVE]; - } - constructor() { super(); @@ -69,8 +64,6 @@ class EntraGroupSettingRemoveCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.GROUPSETTING_REMOVE, commands.GROUPSETTING_REMOVE); - const removeGroupSetting = async (): Promise => { if (this.verbose) { await logger.logToStderr(`Removing group setting: ${args.options.id}...`); diff --git a/src/m365/entra/commands/groupsetting/groupsetting-set.spec.ts b/src/m365/entra/commands/groupsetting/groupsetting-set.spec.ts index 2c8fd4eabfd..9383f71552f 100644 --- a/src/m365/entra/commands/groupsetting/groupsetting-set.spec.ts +++ b/src/m365/entra/commands/groupsetting/groupsetting-set.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './groupsetting-set.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.GROUPSETTING_SET, () => { let log: string[]; @@ -66,16 +65,6 @@ describe(commands.GROUPSETTING_SET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.GROUPSETTING_SET]); - }); - it('updates group setting', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/groupSettings/c391b57d-5783-4c53-9236-cefb5c6ef323`) { diff --git a/src/m365/entra/commands/groupsetting/groupsetting-set.ts b/src/m365/entra/commands/groupsetting/groupsetting-set.ts index b192f0132c8..78be6f8c18d 100644 --- a/src/m365/entra/commands/groupsetting/groupsetting-set.ts +++ b/src/m365/entra/commands/groupsetting/groupsetting-set.ts @@ -5,7 +5,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -24,10 +23,6 @@ class EntraGroupSettingSetCommand extends GraphCommand { return 'Updates the particular group setting'; } - public alias(): string[] | undefined { - return [aadCommands.GROUPSETTING_SET]; - } - public allowUnknownOptions(): boolean | undefined { return true; } @@ -60,8 +55,6 @@ class EntraGroupSettingSetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.GROUPSETTING_SET, commands.GROUPSETTING_SET); - if (this.verbose) { await logger.logToStderr(`Retrieving group setting with id '${args.options.id}'...`); } diff --git a/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-get.spec.ts b/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-get.spec.ts index 02c2dab2b77..bac4967f757 100644 --- a/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-get.spec.ts +++ b/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-get.spec.ts @@ -13,7 +13,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './groupsettingtemplate-get.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.GROUPSETTINGTEMPLATE_GET, () => { let log: string[]; @@ -67,16 +66,6 @@ describe(commands.GROUPSETTINGTEMPLATE_GET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.GROUPSETTINGTEMPLATE_GET]); - }); - it('retrieves group setting template by id', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/groupSettingTemplates`) { diff --git a/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-get.ts b/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-get.ts index d7f8f624864..13646081cd8 100644 --- a/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-get.ts +++ b/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-get.ts @@ -5,7 +5,6 @@ import { odata } from '../../../../utils/odata.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -25,10 +24,6 @@ class EntraGroupSettingTemplateGetCommand extends GraphCommand { return 'Gets information about the specified Entra group settings template'; } - public alias(): string[] | undefined { - return [aadCommands.GROUPSETTINGTEMPLATE_GET]; - } - constructor() { super(); @@ -76,8 +71,6 @@ class EntraGroupSettingTemplateGetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.GROUPSETTINGTEMPLATE_GET, commands.GROUPSETTINGTEMPLATE_GET); - try { const templates = await odata.getAllItems(`${this.resource}/v1.0/groupSettingTemplates`); diff --git a/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-list.spec.ts b/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-list.spec.ts index fae3e1ef34c..6ae07d80be5 100644 --- a/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-list.spec.ts +++ b/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-list.spec.ts @@ -10,7 +10,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './groupsettingtemplate-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.GROUPSETTINGTEMPLATE_LIST, () => { let log: string[]; @@ -61,16 +60,6 @@ describe(commands.GROUPSETTINGTEMPLATE_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.GROUPSETTINGTEMPLATE_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['id', 'displayName']); }); diff --git a/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-list.ts b/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-list.ts index 3372562e795..301d0654cd6 100644 --- a/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-list.ts +++ b/src/m365/entra/commands/groupsettingtemplate/groupsettingtemplate-list.ts @@ -3,7 +3,6 @@ import { Logger } from '../../../../cli/Logger.js'; import { odata } from '../../../../utils/odata.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; class EntraGroupSettingTemplateListCommand extends GraphCommand { public get name(): string { @@ -14,17 +13,11 @@ class EntraGroupSettingTemplateListCommand extends GraphCommand { return 'Lists Entra group settings templates'; } - public alias(): string[] | undefined { - return [aadCommands.GROUPSETTINGTEMPLATE_LIST]; - } - public defaultProperties(): string[] | undefined { return ['id', 'displayName']; } public async commandAction(logger: Logger): Promise { - await this.showDeprecationWarning(logger, aadCommands.GROUPSETTINGTEMPLATE_LIST, commands.GROUPSETTINGTEMPLATE_LIST); - try { const templates = await odata.getAllItems(`${this.resource}/v1.0/groupSettingTemplates`); await logger.log(templates); diff --git a/src/m365/entra/commands/license/license-list.spec.ts b/src/m365/entra/commands/license/license-list.spec.ts index 3352e6afe6a..0209d51c014 100644 --- a/src/m365/entra/commands/license/license-list.spec.ts +++ b/src/m365/entra/commands/license/license-list.spec.ts @@ -10,7 +10,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './license-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.LICENSE_LIST, () => { //#region Mocked Responses @@ -110,16 +109,6 @@ describe(commands.LICENSE_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.LICENSE_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['id', 'skuId', 'skuPartNumber']); }); diff --git a/src/m365/entra/commands/license/license-list.ts b/src/m365/entra/commands/license/license-list.ts index 15557a9461f..b3bdcc9dfba 100644 --- a/src/m365/entra/commands/license/license-list.ts +++ b/src/m365/entra/commands/license/license-list.ts @@ -1,7 +1,6 @@ import { Logger } from '../../../../cli/Logger.js'; import { odata } from '../../../../utils/odata.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; class EntraLicenseListCommand extends GraphCommand { @@ -13,17 +12,11 @@ class EntraLicenseListCommand extends GraphCommand { return 'Lists commercial subscriptions that an organization has acquired'; } - public alias(): string[] | undefined { - return [aadCommands.LICENSE_LIST]; - } - public defaultProperties(): string[] | undefined { return ['id', 'skuId', 'skuPartNumber']; } public async commandAction(logger: Logger): Promise { - await this.showDeprecationWarning(logger, aadCommands.LICENSE_LIST, commands.LICENSE_LIST); - if (this.verbose) { await logger.logToStderr(`Retrieving the commercial subscriptions that an organization has acquired`); } diff --git a/src/m365/entra/commands/m365group/m365group-add.spec.ts b/src/m365/entra/commands/m365group/m365group-add.spec.ts index d984ad0309f..de48fd07452 100644 --- a/src/m365/entra/commands/m365group/m365group-add.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-add.spec.ts @@ -13,7 +13,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-add.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_ADD, () => { @@ -121,16 +120,6 @@ describe(commands.M365GROUP_ADD, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_ADD]); - }); - it('creates Microsoft 365 Group using basic info', async () => { const postStub = sinon.stub(request, 'post').callsFake(async (opts) => { if (opts.url === 'https://graph.microsoft.com/v1.0/groups') { diff --git a/src/m365/entra/commands/m365group/m365group-add.ts b/src/m365/entra/commands/m365group/m365group-add.ts index 0edb70595ee..8238e6ca1e0 100644 --- a/src/m365/entra/commands/m365group/m365group-add.ts +++ b/src/m365/entra/commands/m365group/m365group-add.ts @@ -8,7 +8,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { formatting } from '../../../../utils/formatting.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -41,10 +40,6 @@ class EntraM365GroupAddCommand extends GraphCommand { return 'Creates a Microsoft 365 Group'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_ADD]; - } - constructor() { super(); @@ -165,8 +160,6 @@ class EntraM365GroupAddCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_ADD, commands.M365GROUP_ADD); - let group: Group; let ownerIds: string[] = []; let memberIds: string[] = []; diff --git a/src/m365/entra/commands/m365group/m365group-conversation-list.spec.ts b/src/m365/entra/commands/m365group/m365group-conversation-list.spec.ts index 593b3915aa6..c9e5ae6745f 100644 --- a/src/m365/entra/commands/m365group/m365group-conversation-list.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-conversation-list.spec.ts @@ -12,7 +12,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-conversation-list.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; -import aadCommands from '../../aadCommands.js'; import { cli } from '../../../../cli/cli.js'; describe(commands.M365GROUP_CONVERSATION_LIST, () => { @@ -91,16 +90,6 @@ describe(commands.M365GROUP_CONVERSATION_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_CONVERSATION_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['topic', 'lastDeliveredDateTime', 'id']); }); diff --git a/src/m365/entra/commands/m365group/m365group-conversation-list.ts b/src/m365/entra/commands/m365group/m365group-conversation-list.ts index bd54d2cacd0..813dd35fe37 100644 --- a/src/m365/entra/commands/m365group/m365group-conversation-list.ts +++ b/src/m365/entra/commands/m365group/m365group-conversation-list.ts @@ -6,7 +6,6 @@ import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -25,10 +24,6 @@ class EntraM365GroupConversationListCommand extends GraphCommand { return 'Lists conversations for the specified Microsoft 365 group'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_CONVERSATION_LIST]; - } - public defaultProperties(): string[] | undefined { return ['topic', 'lastDeliveredDateTime', 'id']; } @@ -61,8 +56,6 @@ class EntraM365GroupConversationListCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_CONVERSATION_LIST, commands.M365GROUP_CONVERSATION_LIST); - try { const isUnifiedGroup = await entraGroup.isUnifiedGroup(args.options.groupId); diff --git a/src/m365/entra/commands/m365group/m365group-conversation-post-list.spec.ts b/src/m365/entra/commands/m365group/m365group-conversation-post-list.spec.ts index 994f414c56f..1ae642b6c9e 100644 --- a/src/m365/entra/commands/m365group/m365group-conversation-post-list.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-conversation-post-list.spec.ts @@ -14,7 +14,6 @@ import commands from '../../commands.js'; import command from './m365group-conversation-post-list.js'; import { settingsNames } from '../../../../settingsNames.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_CONVERSATION_POST_LIST, () => { let log: string[]; @@ -122,19 +121,10 @@ describe(commands.M365GROUP_CONVERSATION_POST_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_CONVERSATION_POST_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['receivedDateTime', 'id']); }); + it('fails validation if groupId and groupName specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { @@ -147,6 +137,7 @@ describe(commands.M365GROUP_CONVERSATION_POST_LIST, () => { const actual = await command.validate({ options: { groupId: '1caf7dcd-7e83-4c3a-94f7-932a1299c844', groupName: 'MyGroup', threadId: '123' } }, commandInfo); assert.notStrictEqual(actual, true); }); + it('fails validation if neither groupId nor groupName specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { @@ -159,10 +150,12 @@ describe(commands.M365GROUP_CONVERSATION_POST_LIST, () => { const actual = await command.validate({ options: { threadId: '123' } }, commandInfo); assert.notStrictEqual(actual, true); }); + it('fails validation if the groupId is not a valid GUID', async () => { const actual = await command.validate({ options: { groupId: 'not-c49b-4fd4-8223-28f0ac3a6402', threadId: '123' } }, commandInfo); assert.notStrictEqual(actual, true); }); + it('passes validation if the groupId is a valid GUID', async () => { const actual = await command.validate({ options: { groupId: '1caf7dcd-7e83-4c3a-94f7-932a1299c844', threadId: '123' } }, commandInfo); assert.strictEqual(actual, true); @@ -187,6 +180,7 @@ describe(commands.M365GROUP_CONVERSATION_POST_LIST, () => { jsonOutput.value )); }); + it('Retrieve posts for the specified conversation threadId of m365 group groupName in the tenant (verbose)', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if ((opts.url as string).indexOf('/groups?$filter=displayName') > -1) { @@ -237,4 +231,4 @@ describe(commands.M365GROUP_CONVERSATION_POST_LIST, () => { await assert.rejects(command.action(logger, { options: { groupId: groupId, threadId: 'AAQkADkwN2Q2NDg1LWQ3ZGYtNDViZi1iNGRiLTVhYjJmN2Q5NDkxZQAQAOnRAfDf71lIvrdK85FAn5E=' } } as any), new CommandError(`Specified group with id '${groupId}' is not a Microsoft 365 group.`)); }); -}); +}); \ No newline at end of file diff --git a/src/m365/entra/commands/m365group/m365group-conversation-post-list.ts b/src/m365/entra/commands/m365group/m365group-conversation-post-list.ts index a6baa453ed8..3e2d7840eac 100644 --- a/src/m365/entra/commands/m365group/m365group-conversation-post-list.ts +++ b/src/m365/entra/commands/m365group/m365group-conversation-post-list.ts @@ -7,7 +7,6 @@ import { odata } from '../../../../utils/odata.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -28,10 +27,6 @@ class EntraM365GroupConversationPostListCommand extends GraphCommand { return 'Lists conversation posts of a Microsoft 365 group'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_CONVERSATION_POST_LIST]; - } - constructor() { super(); @@ -85,8 +80,6 @@ class EntraM365GroupConversationPostListCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_CONVERSATION_POST_LIST, commands.M365GROUP_CONVERSATION_POST_LIST); - try { const retrievedgroupId = await this.getGroupId(args); const isUnifiedGroup = await entraGroup.isUnifiedGroup(retrievedgroupId); diff --git a/src/m365/entra/commands/m365group/m365group-get.spec.ts b/src/m365/entra/commands/m365group/m365group-get.spec.ts index fdd501dd2cb..962e5824ade 100644 --- a/src/m365/entra/commands/m365group/m365group-get.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-get.spec.ts @@ -13,7 +13,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-get.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_GET, () => { let log: string[]; @@ -66,16 +65,6 @@ describe(commands.M365GROUP_GET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_GET]); - }); - it('retrieves information about the specified Microsoft 365 Group', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/groups/1caf7dcd-7e83-4c3a-94f7-932a1299c844`) { diff --git a/src/m365/entra/commands/m365group/m365group-get.ts b/src/m365/entra/commands/m365group/m365group-get.ts index 9d7611b37b3..6b4dc99bfe6 100644 --- a/src/m365/entra/commands/m365group/m365group-get.ts +++ b/src/m365/entra/commands/m365group/m365group-get.ts @@ -4,7 +4,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; import { GroupExtended } from './GroupExtended.js'; @@ -26,10 +25,6 @@ class EntraM365GroupGetCommand extends GraphCommand { return 'Gets information about the specified Microsoft 365 Group or Microsoft Teams team'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_GET]; - } - constructor() { super(); @@ -61,8 +56,6 @@ class EntraM365GroupGetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_GET, commands.M365GROUP_GET); - let group: GroupExtended; try { diff --git a/src/m365/entra/commands/m365group/m365group-list.spec.ts b/src/m365/entra/commands/m365group/m365group-list.spec.ts index 0b6830d0cf1..47d529c2705 100644 --- a/src/m365/entra/commands/m365group/m365group-list.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-list.spec.ts @@ -14,7 +14,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_LIST, () => { let log: string[]; @@ -67,16 +66,6 @@ describe(commands.M365GROUP_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['id', 'displayName', 'mailNickname', 'siteUrl']); }); diff --git a/src/m365/entra/commands/m365group/m365group-list.ts b/src/m365/entra/commands/m365group/m365group-list.ts index 00019feb2c1..20a777b1bac 100644 --- a/src/m365/entra/commands/m365group/m365group-list.ts +++ b/src/m365/entra/commands/m365group/m365group-list.ts @@ -4,7 +4,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { formatting } from '../../../../utils/formatting.js'; import { odata } from '../../../../utils/odata.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; import { GroupExtended } from './GroupExtended.js'; @@ -28,10 +27,6 @@ class EntraM365GroupListCommand extends GraphCommand { return 'Lists Microsoft 365 Groups in the current tenant'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_LIST]; - } - constructor() { super(); @@ -72,8 +67,6 @@ class EntraM365GroupListCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_LIST, commands.M365GROUP_LIST); - const groupFilter: string = `?$filter=groupTypes/any(c:c+eq+'Unified')`; const displayNameFilter: string = args.options.displayName ? ` and startswith(DisplayName,'${formatting.encodeQueryParameter(args.options.displayName)}')` : ''; const mailNicknameFilter: string = args.options.mailNickname ? ` and startswith(MailNickname,'${formatting.encodeQueryParameter(args.options.mailNickname)}')` : ''; diff --git a/src/m365/entra/commands/m365group/m365group-recyclebinitem-clear.spec.ts b/src/m365/entra/commands/m365group/m365group-recyclebinitem-clear.spec.ts index 2c563f32899..304e2bab266 100644 --- a/src/m365/entra/commands/m365group/m365group-recyclebinitem-clear.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-recyclebinitem-clear.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-recyclebinitem-clear.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_RECYCLEBINITEM_CLEAR, () => { let log: string[]; @@ -70,16 +69,6 @@ describe(commands.M365GROUP_RECYCLEBINITEM_CLEAR, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_RECYCLEBINITEM_CLEAR]); - }); - it('clears the recycle bin items without prompting for confirmation when --force option specified', async () => { const deleteStub = sinon.stub(request, 'delete').resolves(); diff --git a/src/m365/entra/commands/m365group/m365group-recyclebinitem-clear.ts b/src/m365/entra/commands/m365group/m365group-recyclebinitem-clear.ts index 9829dc99617..6319d1e3139 100644 --- a/src/m365/entra/commands/m365group/m365group-recyclebinitem-clear.ts +++ b/src/m365/entra/commands/m365group/m365group-recyclebinitem-clear.ts @@ -6,7 +6,6 @@ import request from '../../../../request.js'; import { odata } from '../../../../utils/odata.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -25,10 +24,6 @@ class EntraM365GroupRecycleBinItemClearCommand extends GraphCommand { return 'Clears all M365 Groups from recycle bin.'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_RECYCLEBINITEM_CLEAR]; - } - constructor() { super(); @@ -53,8 +48,6 @@ class EntraM365GroupRecycleBinItemClearCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_RECYCLEBINITEM_CLEAR, commands.M365GROUP_RECYCLEBINITEM_CLEAR); - const clearM365GroupRecycleBinItems = async (): Promise => { try { await this.processRecycleBinItemsClear(); diff --git a/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.spec.ts b/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.spec.ts index d2d24332087..1d1bd2d3a2b 100644 --- a/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.spec.ts @@ -10,7 +10,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-recyclebinitem-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_RECYCLEBINITEM_LIST, () => { let log: string[]; @@ -61,16 +60,6 @@ describe(commands.M365GROUP_RECYCLEBINITEM_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_RECYCLEBINITEM_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['id', 'displayName', 'mailNickname']); }); diff --git a/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.ts b/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.ts index 93859678918..dde8f5219db 100644 --- a/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.ts +++ b/src/m365/entra/commands/m365group/m365group-recyclebinitem-list.ts @@ -5,7 +5,6 @@ import { formatting } from '../../../../utils/formatting.js'; import { odata } from '../../../../utils/odata.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -25,10 +24,6 @@ class EntraM365GroupRecycleBinItemListCommand extends GraphCommand { return 'Lists Microsoft 365 Groups deleted in the current tenant'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_RECYCLEBINITEM_LIST]; - } - constructor() { super(); @@ -61,8 +56,6 @@ class EntraM365GroupRecycleBinItemListCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_RECYCLEBINITEM_LIST, commands.M365GROUP_RECYCLEBINITEM_LIST); - try { const filter: string = `?$filter=groupTypes/any(c:c+eq+'Unified')`; const displayNameFilter: string = args.options.groupName ? ` and startswith(DisplayName,'${formatting.encodeQueryParameter(args.options.groupName).replace(/'/g, `''`)}')` : ''; diff --git a/src/m365/entra/commands/m365group/m365group-recyclebinitem-remove.spec.ts b/src/m365/entra/commands/m365group/m365group-recyclebinitem-remove.spec.ts index c80a4d41dfe..751661880e4 100644 --- a/src/m365/entra/commands/m365group/m365group-recyclebinitem-remove.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-recyclebinitem-remove.spec.ts @@ -14,7 +14,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-recyclebinitem-remove.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_RECYCLEBINITEM_REMOVE, () => { const validGroupId = '00000000-0000-0000-0000-000000000000'; @@ -122,16 +121,6 @@ describe(commands.M365GROUP_RECYCLEBINITEM_REMOVE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_RECYCLEBINITEM_REMOVE]); - }); - it('fails validation when id is not a valid GUID', async () => { const actual = await command.validate({ options: { diff --git a/src/m365/entra/commands/m365group/m365group-recyclebinitem-remove.ts b/src/m365/entra/commands/m365group/m365group-recyclebinitem-remove.ts index 7751fa9338b..64ac3680379 100644 --- a/src/m365/entra/commands/m365group/m365group-recyclebinitem-remove.ts +++ b/src/m365/entra/commands/m365group/m365group-recyclebinitem-remove.ts @@ -7,7 +7,6 @@ import { formatting } from '../../../../utils/formatting.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -29,10 +28,6 @@ class EntraM365GroupRecycleBinItemRemoveCommand extends GraphCommand { return 'Permanently deletes a Microsoft 365 Group from the recycle bin in the current tenant'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_RECYCLEBINITEM_REMOVE]; - } - constructor() { super(); @@ -87,8 +82,6 @@ class EntraM365GroupRecycleBinItemRemoveCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_RECYCLEBINITEM_REMOVE, commands.M365GROUP_RECYCLEBINITEM_REMOVE); - const removeGroup: () => Promise = async (): Promise => { try { const groupId = await this.getGroupId(args.options); diff --git a/src/m365/entra/commands/m365group/m365group-recyclebinitem-restore.spec.ts b/src/m365/entra/commands/m365group/m365group-recyclebinitem-restore.spec.ts index b4165dd0370..4d51190373a 100644 --- a/src/m365/entra/commands/m365group/m365group-recyclebinitem-restore.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-recyclebinitem-restore.spec.ts @@ -14,7 +14,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-recyclebinitem-restore.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_RECYCLEBINITEM_RESTORE, () => { const validGroupId = '00000000-0000-0000-0000-000000000000'; @@ -116,16 +115,6 @@ describe(commands.M365GROUP_RECYCLEBINITEM_RESTORE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_RECYCLEBINITEM_RESTORE]); - }); - it('fails validation if the id is not a valid GUID', async () => { const actual = await command.validate({ options: { id: 'abc' } }, commandInfo); assert.notStrictEqual(actual, true); diff --git a/src/m365/entra/commands/m365group/m365group-recyclebinitem-restore.ts b/src/m365/entra/commands/m365group/m365group-recyclebinitem-restore.ts index b30a40716ba..02aec59d3b2 100644 --- a/src/m365/entra/commands/m365group/m365group-recyclebinitem-restore.ts +++ b/src/m365/entra/commands/m365group/m365group-recyclebinitem-restore.ts @@ -7,7 +7,6 @@ import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; import { cli } from '../../../../cli/cli.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -28,10 +27,6 @@ class EntraM365GroupRecycleBinItemRestoreCommand extends GraphCommand { return 'Restores a deleted Microsoft 365 Group'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_RECYCLEBINITEM_RESTORE]; - } - constructor() { super(); @@ -82,8 +77,6 @@ class EntraM365GroupRecycleBinItemRestoreCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_RECYCLEBINITEM_RESTORE, commands.M365GROUP_RECYCLEBINITEM_RESTORE); - if (this.verbose) { await logger.logToStderr(`Restoring Microsoft 365 Group: ${args.options.id || args.options.displayName || args.options.mailNickname}...`); } diff --git a/src/m365/entra/commands/m365group/m365group-remove.spec.ts b/src/m365/entra/commands/m365group/m365group-remove.spec.ts index a035ded8ede..b2f5cdba427 100644 --- a/src/m365/entra/commands/m365group/m365group-remove.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-remove.spec.ts @@ -15,7 +15,6 @@ import commands from '../../commands.js'; import { spo } from '../../../../utils/spo.js'; import command from './m365group-remove.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_REMOVE, () => { let log: string[]; @@ -160,16 +159,6 @@ describe(commands.M365GROUP_REMOVE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_REMOVE]); - }); - it('fails validation if the id is not a valid GUID', async () => { const actual = await command.validate({ options: { id: 'abc' } }, commandInfo); assert.notStrictEqual(actual, true); diff --git a/src/m365/entra/commands/m365group/m365group-remove.ts b/src/m365/entra/commands/m365group/m365group-remove.ts index 142c2509617..c6384714180 100644 --- a/src/m365/entra/commands/m365group/m365group-remove.ts +++ b/src/m365/entra/commands/m365group/m365group-remove.ts @@ -10,7 +10,6 @@ import config from '../../../../config.js'; import { formatting } from '../../../../utils/formatting.js'; import { ClientSvcResponse, ClientSvcResponseContents, FormDigestInfo, spo } from '../../../../utils/spo.js'; import { setTimeout } from 'timers/promises'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -34,10 +33,6 @@ class EntraM365GroupRemoveCommand extends GraphCommand { return 'Removes a Microsoft 365 Group'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_REMOVE]; - } - constructor() { super(); @@ -82,8 +77,6 @@ class EntraM365GroupRemoveCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_REMOVE, commands.M365GROUP_REMOVE); - const removeGroup = async (): Promise => { if (this.verbose) { await logger.logToStderr(`Removing Microsoft 365 Group: ${args.options.id}...`); diff --git a/src/m365/entra/commands/m365group/m365group-renew.spec.ts b/src/m365/entra/commands/m365group/m365group-renew.spec.ts index 086879d22ff..1eb96a99173 100644 --- a/src/m365/entra/commands/m365group/m365group-renew.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-renew.spec.ts @@ -13,7 +13,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-renew.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_RENEW, () => { let log: string[]; @@ -69,16 +68,6 @@ describe(commands.M365GROUP_RENEW, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_RENEW]); - }); - it('renews expiration the specified group', async () => { sinon.stub(request, 'post').callsFake(async (opts) => { if (opts.url === 'https://graph.microsoft.com/v1.0/groups/28beab62-7540-4db1-a23f-29a6018a3848/renew/') { diff --git a/src/m365/entra/commands/m365group/m365group-renew.ts b/src/m365/entra/commands/m365group/m365group-renew.ts index b68cba2940a..aa251b235ca 100644 --- a/src/m365/entra/commands/m365group/m365group-renew.ts +++ b/src/m365/entra/commands/m365group/m365group-renew.ts @@ -4,7 +4,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -24,10 +23,6 @@ class EntraM365GroupRenewCommand extends GraphCommand { return `Renews Microsoft 365 group's expiration`; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_RENEW]; - } - constructor() { super(); @@ -56,8 +51,6 @@ class EntraM365GroupRenewCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_RENEW, commands.M365GROUP_RENEW); - if (this.verbose) { await logger.logToStderr(`Renewing Microsoft 365 group's expiration: ${args.options.id}...`); } diff --git a/src/m365/entra/commands/m365group/m365group-report-activitycounts.spec.ts b/src/m365/entra/commands/m365group/m365group-report-activitycounts.spec.ts index 1dac6316ff0..13c888a4e8a 100644 --- a/src/m365/entra/commands/m365group/m365group-report-activitycounts.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-report-activitycounts.spec.ts @@ -9,7 +9,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-report-activitycounts.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_REPORT_ACTIVITYCOUNTS, () => { let log: string[]; @@ -58,16 +57,6 @@ describe(commands.M365GROUP_REPORT_ACTIVITYCOUNTS, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_REPORT_ACTIVITYCOUNTS]); - }); - it('gets the number of group activities across group workloads for the given period', async () => { const requestStub: sinon.SinonStub = sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/reports/getOffice365GroupsActivityCounts(period='D7')`) { diff --git a/src/m365/entra/commands/m365group/m365group-report-activitycounts.ts b/src/m365/entra/commands/m365group/m365group-report-activitycounts.ts index 63187fe38f7..38f4963420b 100644 --- a/src/m365/entra/commands/m365group/m365group-report-activitycounts.ts +++ b/src/m365/entra/commands/m365group/m365group-report-activitycounts.ts @@ -1,5 +1,4 @@ import PeriodBasedReport from '../../../base/PeriodBasedReport.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; class M365GroupReportActivityCountsCommand extends PeriodBasedReport { @@ -11,10 +10,6 @@ class M365GroupReportActivityCountsCommand extends PeriodBasedReport { return 'Get the number of group activities across group workloads'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_REPORT_ACTIVITYCOUNTS]; - } - public get usageEndpoint(): string { return 'getOffice365GroupsActivityCounts'; } diff --git a/src/m365/entra/commands/m365group/m365group-report-activitydetail.spec.ts b/src/m365/entra/commands/m365group/m365group-report-activitydetail.spec.ts index 6b8e1e04015..2885c2b1e1c 100644 --- a/src/m365/entra/commands/m365group/m365group-report-activitydetail.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-report-activitydetail.spec.ts @@ -9,7 +9,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-report-activitydetail.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_REPORT_ACTIVITYDETAIL, () => { let log: string[]; @@ -58,16 +57,6 @@ describe(commands.M365GROUP_REPORT_ACTIVITYDETAIL, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_REPORT_ACTIVITYDETAIL]); - }); - it('gets details about Microsoft 365 Groups activity by group for the given period', async () => { const requestStub: sinon.SinonStub = sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/reports/getOffice365GroupsActivityDetail(period='D7')`) { diff --git a/src/m365/entra/commands/m365group/m365group-report-activitydetail.ts b/src/m365/entra/commands/m365group/m365group-report-activitydetail.ts index db2b6153024..f1c372b02ae 100644 --- a/src/m365/entra/commands/m365group/m365group-report-activitydetail.ts +++ b/src/m365/entra/commands/m365group/m365group-report-activitydetail.ts @@ -1,5 +1,4 @@ import DateAndPeriodBasedReport from '../../../base/DateAndPeriodBasedReport.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; class M365GroupReportActivityDetailCommand extends DateAndPeriodBasedReport { @@ -11,10 +10,6 @@ class M365GroupReportActivityDetailCommand extends DateAndPeriodBasedReport { return 'Get details about Microsoft 365 Groups activity by group'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_REPORT_ACTIVITYDETAIL]; - } - public get usageEndpoint(): string { return 'getOffice365GroupsActivityDetail'; } diff --git a/src/m365/entra/commands/m365group/m365group-report-activityfilecounts.spec.ts b/src/m365/entra/commands/m365group/m365group-report-activityfilecounts.spec.ts index a0952e60045..7c1c20df5b3 100644 --- a/src/m365/entra/commands/m365group/m365group-report-activityfilecounts.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-report-activityfilecounts.spec.ts @@ -9,7 +9,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-report-activityfilecounts.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_REPORT_ACTIVITYFILECOUNTS, () => { let log: string[]; @@ -58,16 +57,6 @@ describe(commands.M365GROUP_REPORT_ACTIVITYFILECOUNTS, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_REPORT_ACTIVITYFILECOUNTS]); - }); - it('gets the number of group activities across group workloads for the given period', async () => { const requestStub: sinon.SinonStub = sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/reports/getOffice365GroupsActivityFileCounts(period='D7')`) { @@ -83,4 +72,4 @@ describe(commands.M365GROUP_REPORT_ACTIVITYFILECOUNTS, () => { assert.strictEqual(requestStub.lastCall.args[0].url, "https://graph.microsoft.com/v1.0/reports/getOffice365GroupsActivityFileCounts(period='D7')"); assert.strictEqual(requestStub.lastCall.args[0].headers["accept"], 'application/json;odata.metadata=none'); }); -}); +}); \ No newline at end of file diff --git a/src/m365/entra/commands/m365group/m365group-report-activityfilecounts.ts b/src/m365/entra/commands/m365group/m365group-report-activityfilecounts.ts index bd8f4a831e8..bd6ccb27659 100644 --- a/src/m365/entra/commands/m365group/m365group-report-activityfilecounts.ts +++ b/src/m365/entra/commands/m365group/m365group-report-activityfilecounts.ts @@ -1,5 +1,4 @@ import PeriodBasedReport from '../../../base/PeriodBasedReport.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; class M365GroupReportActivityFileCountsCommand extends PeriodBasedReport { @@ -11,10 +10,6 @@ class M365GroupReportActivityFileCountsCommand extends PeriodBasedReport { return 'Get the total number of files and how many of them were active across all group sites associated with an Microsoft 365 Group'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_REPORT_ACTIVITYFILECOUNTS]; - } - public get usageEndpoint(): string { return 'getOffice365GroupsActivityFileCounts'; } diff --git a/src/m365/entra/commands/m365group/m365group-report-activitygroupcounts.spec.ts b/src/m365/entra/commands/m365group/m365group-report-activitygroupcounts.spec.ts index 30f823dce3d..ce6703f8c43 100644 --- a/src/m365/entra/commands/m365group/m365group-report-activitygroupcounts.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-report-activitygroupcounts.spec.ts @@ -9,7 +9,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-report-activitygroupcounts.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_REPORT_ACTIVITYGROUPCOUNTS, () => { let log: string[]; @@ -58,16 +57,6 @@ describe(commands.M365GROUP_REPORT_ACTIVITYGROUPCOUNTS, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_REPORT_ACTIVITYGROUPCOUNTS]); - }); - it('gets the daily total number of groups and how many of them were active based on activities for the given period', async () => { const requestStub: sinon.SinonStub = sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/reports/getOffice365GroupsActivityGroupCounts(period='D7')`) { @@ -85,4 +74,4 @@ describe(commands.M365GROUP_REPORT_ACTIVITYGROUPCOUNTS, () => { assert.strictEqual(requestStub.lastCall.args[0].url, "https://graph.microsoft.com/v1.0/reports/getOffice365GroupsActivityGroupCounts(period='D7')"); assert.strictEqual(requestStub.lastCall.args[0].headers["accept"], 'application/json;odata.metadata=none'); }); -}); +}); \ No newline at end of file diff --git a/src/m365/entra/commands/m365group/m365group-report-activitygroupcounts.ts b/src/m365/entra/commands/m365group/m365group-report-activitygroupcounts.ts index 664b023fdc7..219f4d46a3c 100644 --- a/src/m365/entra/commands/m365group/m365group-report-activitygroupcounts.ts +++ b/src/m365/entra/commands/m365group/m365group-report-activitygroupcounts.ts @@ -1,5 +1,4 @@ import PeriodBasedReport from '../../../base/PeriodBasedReport.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; class M365GroupReportActivityGroupCountsCommand extends PeriodBasedReport { @@ -11,10 +10,6 @@ class M365GroupReportActivityGroupCountsCommand extends PeriodBasedReport { return 'Get the daily total number of groups and how many of them were active based on email conversations, Viva Engage posts, and SharePoint file activities'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_REPORT_ACTIVITYGROUPCOUNTS]; - } - public get usageEndpoint(): string { return 'getOffice365GroupsActivityGroupCounts'; } diff --git a/src/m365/entra/commands/m365group/m365group-report-activitystorage.spec.ts b/src/m365/entra/commands/m365group/m365group-report-activitystorage.spec.ts index c6ba3c19586..144a00803f5 100644 --- a/src/m365/entra/commands/m365group/m365group-report-activitystorage.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-report-activitystorage.spec.ts @@ -9,7 +9,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-report-activitystorage.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_REPORT_ACTIVITYSTORAGE, () => { let log: string[]; @@ -58,16 +57,6 @@ describe(commands.M365GROUP_REPORT_ACTIVITYSTORAGE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_REPORT_ACTIVITYSTORAGE]); - }); - it('get the reports', async () => { const requestStub: sinon.SinonStub = sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/reports/getOffice365GroupsActivityStorage(period='D7')`) { @@ -83,4 +72,4 @@ describe(commands.M365GROUP_REPORT_ACTIVITYSTORAGE, () => { assert.strictEqual(requestStub.lastCall.args[0].url, "https://graph.microsoft.com/v1.0/reports/getOffice365GroupsActivityStorage(period='D7')"); assert.strictEqual(requestStub.lastCall.args[0].headers["accept"], 'application/json;odata.metadata=none'); }); -}); +}); \ No newline at end of file diff --git a/src/m365/entra/commands/m365group/m365group-report-activitystorage.ts b/src/m365/entra/commands/m365group/m365group-report-activitystorage.ts index 442900e5d6d..8d87d227010 100644 --- a/src/m365/entra/commands/m365group/m365group-report-activitystorage.ts +++ b/src/m365/entra/commands/m365group/m365group-report-activitystorage.ts @@ -1,5 +1,4 @@ import PeriodBasedReport from '../../../base/PeriodBasedReport.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; class M365GroupReportActivityStorageCommand extends PeriodBasedReport { @@ -11,10 +10,6 @@ class M365GroupReportActivityStorageCommand extends PeriodBasedReport { return 'Get the total storage used across all group mailboxes and group sites'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_REPORT_ACTIVITYSTORAGE]; - } - public get usageEndpoint(): string { return 'getOffice365GroupsActivityStorage'; } diff --git a/src/m365/entra/commands/m365group/m365group-set.spec.ts b/src/m365/entra/commands/m365group/m365group-set.spec.ts index e9e2f05fcd8..ed11c867533 100644 --- a/src/m365/entra/commands/m365group/m365group-set.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-set.spec.ts @@ -15,7 +15,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-set.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; -import aadCommands from '../../aadCommands.js'; import { accessToken } from '../../../../utils/accessToken.js'; describe(commands.M365GROUP_SET, () => { @@ -115,16 +114,6 @@ describe(commands.M365GROUP_SET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_SET]); - }); - it('updates Microsoft 365 Group display name', async () => { sinon.stub(request, 'patch').callsFake(async (opts) => { if (opts.url === 'https://graph.microsoft.com/v1.0/groups/28beab62-7540-4db1-a23f-29a6018a3848') { diff --git a/src/m365/entra/commands/m365group/m365group-set.ts b/src/m365/entra/commands/m365group/m365group-set.ts index cb4a19e09c1..f6a4a038eb1 100644 --- a/src/m365/entra/commands/m365group/m365group-set.ts +++ b/src/m365/entra/commands/m365group/m365group-set.ts @@ -9,7 +9,6 @@ import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; -import aadCommands from '../../aadCommands.js'; import { accessToken } from '../../../../utils/accessToken.js'; import auth from '../../../../Auth.js'; @@ -43,10 +42,6 @@ class EntraM365GroupSetCommand extends GraphCommand { return 'Updates Microsoft 365 Group properties'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_SET]; - } - constructor() { super(); @@ -173,8 +168,6 @@ class EntraM365GroupSetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_SET, commands.M365GROUP_SET); - try { if ((args.options.allowExternalSenders !== undefined || args.options.autoSubscribeNewMembers !== undefined) && accessToken.isAppOnlyAccessToken(auth.connection.accessTokens[auth.defaultResource].accessToken)) { throw `Option 'allowExternalSenders' and 'autoSubscribeNewMembers' can only be used when using delegated permissions.`; diff --git a/src/m365/entra/commands/m365group/m365group-teamify.spec.ts b/src/m365/entra/commands/m365group/m365group-teamify.spec.ts index f8c1b22baff..727be4534ed 100644 --- a/src/m365/entra/commands/m365group/m365group-teamify.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-teamify.spec.ts @@ -14,7 +14,6 @@ import commands from '../../commands.js'; import command from './m365group-teamify.js'; import { settingsNames } from '../../../../settingsNames.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_TEAMIFY, () => { let log: string[]; @@ -69,16 +68,6 @@ describe(commands.M365GROUP_TEAMIFY, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_TEAMIFY]); - }); - it('fails validation if both id and mailNickname options are not passed', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { diff --git a/src/m365/entra/commands/m365group/m365group-teamify.ts b/src/m365/entra/commands/m365group/m365group-teamify.ts index 2f4a2d8ee7e..de91436791a 100644 --- a/src/m365/entra/commands/m365group/m365group-teamify.ts +++ b/src/m365/entra/commands/m365group/m365group-teamify.ts @@ -6,7 +6,6 @@ import { entraGroup } from '../../../../utils/entraGroup.js'; import { formatting } from '../../../../utils/formatting.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -27,10 +26,6 @@ class EntraM365GroupTeamifyCommand extends GraphCommand { return 'Creates a new Microsoft Teams team under existing Microsoft 365 group'; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_TEAMIFY]; - } - constructor() { super(); @@ -106,8 +101,6 @@ class EntraM365GroupTeamifyCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_TEAMIFY, commands.M365GROUP_TEAMIFY); - try { const groupId = await this.getGroupId(args.options); const isUnifiedGroup = await entraGroup.isUnifiedGroup(groupId); diff --git a/src/m365/entra/commands/m365group/m365group-user-add.spec.ts b/src/m365/entra/commands/m365group/m365group-user-add.spec.ts index 9152acfd2a2..725b0958414 100644 --- a/src/m365/entra/commands/m365group/m365group-user-add.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-user-add.spec.ts @@ -10,12 +10,10 @@ import { telemetry } from '../../../../telemetry.js'; import { pid } from '../../../../utils/pid.js'; import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; -import teamsCommands from '../../../teams/commands.js'; import commands from '../../commands.js'; import command from './m365group-user-add.js'; import { settingsNames } from '../../../../settingsNames.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_USER_ADD, () => { let log: string[]; @@ -69,16 +67,6 @@ describe(commands.M365GROUP_USER_ADD, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [teamsCommands.USER_ADD, aadCommands.M365GROUP_USER_ADD]); - }); - it('fails validation if the groupId is not a valid guid.', async () => { const actual = await command.validate({ options: { diff --git a/src/m365/entra/commands/m365group/m365group-user-add.ts b/src/m365/entra/commands/m365group/m365group-user-add.ts index 044c673a851..066ffbda555 100644 --- a/src/m365/entra/commands/m365group/m365group-user-add.ts +++ b/src/m365/entra/commands/m365group/m365group-user-add.ts @@ -5,8 +5,6 @@ import { entraGroup } from '../../../../utils/entraGroup.js'; import { formatting } from '../../../../utils/formatting.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import teamsCommands from '../../../teams/commands.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -29,10 +27,6 @@ class EntraM365GroupUserAddCommand extends GraphCommand { return 'Adds user to specified Microsoft 365 Group or Microsoft Teams team'; } - public alias(): string[] | undefined { - return [teamsCommands.USER_ADD, aadCommands.M365GROUP_USER_ADD]; - } - constructor() { super(); @@ -97,8 +91,6 @@ class EntraM365GroupUserAddCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_USER_ADD, commands.M365GROUP_USER_ADD); - try { const providedGroupId: string = (typeof args.options.groupId !== 'undefined') ? args.options.groupId : args.options.teamId as string; const isUnifiedGroup = await entraGroup.isUnifiedGroup(providedGroupId); diff --git a/src/m365/entra/commands/m365group/m365group-user-list.spec.ts b/src/m365/entra/commands/m365group/m365group-user-list.spec.ts index 15f071e272b..73c329c0bf0 100644 --- a/src/m365/entra/commands/m365group/m365group-user-list.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-user-list.spec.ts @@ -13,7 +13,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './m365group-user-list.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_USER_LIST, () => { let log: string[]; @@ -67,16 +66,6 @@ describe(commands.M365GROUP_USER_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.M365GROUP_USER_LIST]); - }); - it('fails validation if the groupId is not a valid guid.', async () => { const actual = await command.validate({ options: { diff --git a/src/m365/entra/commands/m365group/m365group-user-list.ts b/src/m365/entra/commands/m365group/m365group-user-list.ts index 90de68209ab..237da67859e 100644 --- a/src/m365/entra/commands/m365group/m365group-user-list.ts +++ b/src/m365/entra/commands/m365group/m365group-user-list.ts @@ -7,7 +7,6 @@ import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; import { CliRequestOptions } from '../../../../request.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -34,10 +33,6 @@ class EntraM365GroupUserListCommand extends GraphCommand { return "Lists users for the specified Microsoft 365 group"; } - public alias(): string[] | undefined { - return [aadCommands.M365GROUP_USER_LIST]; - } - constructor() { super(); @@ -107,8 +102,6 @@ class EntraM365GroupUserListCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_USER_LIST, commands.M365GROUP_USER_LIST); - try { const groupId = await this.getGroupId(args.options, logger); const isUnifiedGroup = await entraGroup.isUnifiedGroup(groupId); diff --git a/src/m365/entra/commands/m365group/m365group-user-remove.spec.ts b/src/m365/entra/commands/m365group/m365group-user-remove.spec.ts index eec3e1c0fdb..6b2b25dfd02 100644 --- a/src/m365/entra/commands/m365group/m365group-user-remove.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-user-remove.spec.ts @@ -10,12 +10,10 @@ import { telemetry } from '../../../../telemetry.js'; import { pid } from '../../../../utils/pid.js'; import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; -import teamsCommands from '../../../teams/commands.js'; import commands from '../../commands.js'; import command from './m365group-user-remove.js'; import { settingsNames } from '../../../../settingsNames.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_USER_REMOVE, () => { let log: string[]; @@ -76,16 +74,6 @@ describe(commands.M365GROUP_USER_REMOVE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [teamsCommands.USER_REMOVE, aadCommands.M365GROUP_USER_REMOVE]); - }); - it('fails validation if the groupId is not a valid guid.', async () => { const actual = await command.validate({ options: { diff --git a/src/m365/entra/commands/m365group/m365group-user-remove.ts b/src/m365/entra/commands/m365group/m365group-user-remove.ts index 16e94fa3b77..71d14fd1852 100644 --- a/src/m365/entra/commands/m365group/m365group-user-remove.ts +++ b/src/m365/entra/commands/m365group/m365group-user-remove.ts @@ -6,8 +6,6 @@ import { entraGroup } from '../../../../utils/entraGroup.js'; import { formatting } from '../../../../utils/formatting.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import teamsCommands from '../../../teams/commands.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -34,10 +32,6 @@ class EntraM365GroupUserRemoveCommand extends GraphCommand { return 'Removes the specified user from specified Microsoft 365 Group or Microsoft Teams team'; } - public alias(): string[] | undefined { - return [teamsCommands.USER_REMOVE, aadCommands.M365GROUP_USER_REMOVE]; - } - constructor() { super(); @@ -95,8 +89,6 @@ class EntraM365GroupUserRemoveCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_USER_REMOVE, commands.M365GROUP_USER_REMOVE); - const groupId: string = (typeof args.options.groupId !== 'undefined') ? args.options.groupId : args.options.teamId as string; const removeUser = async (): Promise => { diff --git a/src/m365/entra/commands/m365group/m365group-user-set.spec.ts b/src/m365/entra/commands/m365group/m365group-user-set.spec.ts index 73843fdff4d..0d98e58c34a 100644 --- a/src/m365/entra/commands/m365group/m365group-user-set.spec.ts +++ b/src/m365/entra/commands/m365group/m365group-user-set.spec.ts @@ -10,12 +10,10 @@ import { telemetry } from '../../../../telemetry.js'; import { pid } from '../../../../utils/pid.js'; import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; -import teamsCommands from '../../../teams/commands.js'; import commands from '../../commands.js'; import command from './m365group-user-set.js'; import { settingsNames } from '../../../../settingsNames.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.M365GROUP_USER_SET, () => { let log: string[]; @@ -70,16 +68,6 @@ describe(commands.M365GROUP_USER_SET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [teamsCommands.USER_SET, aadCommands.M365GROUP_USER_SET]); - }); - it('fails validation if the groupId is not a valid guid.', async () => { const actual = await command.validate({ options: { diff --git a/src/m365/entra/commands/m365group/m365group-user-set.ts b/src/m365/entra/commands/m365group/m365group-user-set.ts index b07491f0e64..b71ed34a66a 100644 --- a/src/m365/entra/commands/m365group/m365group-user-set.ts +++ b/src/m365/entra/commands/m365group/m365group-user-set.ts @@ -5,10 +5,8 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { odata } from '../../../../utils/odata.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import teamsCommands from '../../../teams/commands.js'; import commands from '../../commands.js'; import { entraGroup } from '../../../../utils/entraGroup.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -30,11 +28,6 @@ class EntraM365GroupUserSetCommand extends GraphCommand { return 'Updates role of the specified user in the specified Microsoft 365 Group or Microsoft Teams team'; } - - public alias(): string[] | undefined { - return [teamsCommands.USER_SET, aadCommands.M365GROUP_USER_SET]; - } - constructor() { super(); @@ -97,8 +90,6 @@ class EntraM365GroupUserSetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.M365GROUP_USER_SET, commands.M365GROUP_USER_SET); - try { const groupId: string = (typeof args.options.groupId !== 'undefined') ? args.options.groupId : args.options.teamId as string; const isUnifiedGroup = await entraGroup.isUnifiedGroup(groupId); diff --git a/src/m365/entra/commands/oauth2grant/oauth2grant-add.spec.ts b/src/m365/entra/commands/oauth2grant/oauth2grant-add.spec.ts index b59e1297026..fdc6fad32bc 100644 --- a/src/m365/entra/commands/oauth2grant/oauth2grant-add.spec.ts +++ b/src/m365/entra/commands/oauth2grant/oauth2grant-add.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './oauth2grant-add.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.OAUTH2GRANT_ADD, () => { let log: string[]; @@ -66,16 +65,6 @@ describe(commands.OAUTH2GRANT_ADD, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.OAUTH2GRANT_ADD]); - }); - it('adds OAuth2 permission grant (debug)', async () => { sinon.stub(request, 'post').callsFake(async (opts) => { if ((opts.url as string).indexOf(`/v1.0/oauth2PermissionGrants`) > -1) { diff --git a/src/m365/entra/commands/oauth2grant/oauth2grant-add.ts b/src/m365/entra/commands/oauth2grant/oauth2grant-add.ts index b27b2d844a6..fd2bd08a12a 100644 --- a/src/m365/entra/commands/oauth2grant/oauth2grant-add.ts +++ b/src/m365/entra/commands/oauth2grant/oauth2grant-add.ts @@ -3,7 +3,6 @@ import GlobalOptions from '../../../../GlobalOptions.js'; import request, { CliRequestOptions } from '../../../../request.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -25,10 +24,6 @@ class EntraOAuth2GrantAddCommand extends GraphCommand { return 'Grant the specified service principal OAuth2 permissions to the specified resource'; } - public alias(): string[] | undefined { - return [aadCommands.OAUTH2GRANT_ADD]; - } - constructor() { super(); @@ -67,8 +62,6 @@ class EntraOAuth2GrantAddCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.OAUTH2GRANT_ADD, commands.OAUTH2GRANT_ADD); - if (this.verbose) { await logger.logToStderr(`Granting the service principal specified permissions...`); } diff --git a/src/m365/entra/commands/oauth2grant/oauth2grant-list.spec.ts b/src/m365/entra/commands/oauth2grant/oauth2grant-list.spec.ts index 19e52027f03..8dac2d17a59 100644 --- a/src/m365/entra/commands/oauth2grant/oauth2grant-list.spec.ts +++ b/src/m365/entra/commands/oauth2grant/oauth2grant-list.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './oauth2grant-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.OAUTH2GRANT_LIST, () => { let log: string[]; @@ -64,16 +63,6 @@ describe(commands.OAUTH2GRANT_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.OAUTH2GRANT_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['objectId', 'resourceId', 'scope']); }); diff --git a/src/m365/entra/commands/oauth2grant/oauth2grant-list.ts b/src/m365/entra/commands/oauth2grant/oauth2grant-list.ts index cb8352c8496..979855a5afc 100644 --- a/src/m365/entra/commands/oauth2grant/oauth2grant-list.ts +++ b/src/m365/entra/commands/oauth2grant/oauth2grant-list.ts @@ -4,7 +4,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { formatting } from '../../../../utils/formatting.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -24,10 +23,6 @@ class EntraOAuth2GrantListCommand extends GraphCommand { return 'Lists OAuth2 permission grants for the specified service principal'; } - public alias(): string[] | undefined { - return [aadCommands.OAUTH2GRANT_LIST]; - } - public defaultProperties(): string[] | undefined { return ['objectId', 'resourceId', 'scope']; } @@ -60,8 +55,6 @@ class EntraOAuth2GrantListCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.OAUTH2GRANT_LIST, commands.OAUTH2GRANT_LIST); - if (this.verbose) { await logger.logToStderr(`Retrieving list of OAuth grants for the service principal...`); } diff --git a/src/m365/entra/commands/oauth2grant/oauth2grant-remove.spec.ts b/src/m365/entra/commands/oauth2grant/oauth2grant-remove.spec.ts index 60bb2da88c4..d7756cfde97 100644 --- a/src/m365/entra/commands/oauth2grant/oauth2grant-remove.spec.ts +++ b/src/m365/entra/commands/oauth2grant/oauth2grant-remove.spec.ts @@ -11,7 +11,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './oauth2grant-remove.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.OAUTH2GRANT_REMOVE, () => { let log: string[]; @@ -71,16 +70,6 @@ describe(commands.OAUTH2GRANT_REMOVE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.OAUTH2GRANT_REMOVE]); - }); - it('removes OAuth2 permission grant when prompt confirmed (debug)', async () => { const deleteRequestStub = sinon.stub(request, 'delete').callsFake(async (opts) => { if ((opts.url as string).indexOf(`/v1.0/oauth2PermissionGrants/YgA60KYa4UOPSdc-lpxYEnQkr8KVLDpCsOXkiV8i-ek`) > -1) { diff --git a/src/m365/entra/commands/oauth2grant/oauth2grant-remove.ts b/src/m365/entra/commands/oauth2grant/oauth2grant-remove.ts index b36db4bc7cd..567b8d53b9f 100644 --- a/src/m365/entra/commands/oauth2grant/oauth2grant-remove.ts +++ b/src/m365/entra/commands/oauth2grant/oauth2grant-remove.ts @@ -4,7 +4,6 @@ import GlobalOptions from '../../../../GlobalOptions.js'; import request, { CliRequestOptions } from '../../../../request.js'; import { formatting } from '../../../../utils/formatting.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -24,10 +23,6 @@ class EntraOAuth2GrantRemoveCommand extends GraphCommand { return 'Remove specified service principal OAuth2 permissions'; } - public alias(): string[] | undefined { - return [aadCommands.OAUTH2GRANT_REMOVE]; - } - constructor() { super(); @@ -46,8 +41,6 @@ class EntraOAuth2GrantRemoveCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.OAUTH2GRANT_REMOVE, commands.OAUTH2GRANT_REMOVE); - const removeOauth2Grant: () => Promise = async (): Promise => { if (this.verbose) { await logger.logToStderr(`Removing OAuth2 permissions...`); diff --git a/src/m365/entra/commands/oauth2grant/oauth2grant-set.spec.ts b/src/m365/entra/commands/oauth2grant/oauth2grant-set.spec.ts index 57f05a617a8..897c0c64a73 100644 --- a/src/m365/entra/commands/oauth2grant/oauth2grant-set.spec.ts +++ b/src/m365/entra/commands/oauth2grant/oauth2grant-set.spec.ts @@ -10,7 +10,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './oauth2grant-set.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.OAUTH2GRANT_SET, () => { let log: string[]; @@ -62,16 +61,6 @@ describe(commands.OAUTH2GRANT_SET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.OAUTH2GRANT_SET]); - }); - it('updates OAuth2 permission grant (debug)', async () => { sinon.stub(request, 'patch').callsFake(async (opts) => { if ((opts.url as string).indexOf(`/v1.0/oauth2PermissionGrants/YgA60KYa4UOPSdc-lpxYEnQkr8KVLDpCsOXkiV8i-ek`) > -1) { diff --git a/src/m365/entra/commands/oauth2grant/oauth2grant-set.ts b/src/m365/entra/commands/oauth2grant/oauth2grant-set.ts index f06fbb66a2d..14c27647eb7 100644 --- a/src/m365/entra/commands/oauth2grant/oauth2grant-set.ts +++ b/src/m365/entra/commands/oauth2grant/oauth2grant-set.ts @@ -3,7 +3,6 @@ import GlobalOptions from '../../../../GlobalOptions.js'; import request, { CliRequestOptions } from '../../../../request.js'; import { formatting } from '../../../../utils/formatting.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -24,10 +23,6 @@ class EntraOAuth2GrantSetCommand extends GraphCommand { return 'Update OAuth2 permissions for the service principal'; } - public alias(): string[] | undefined { - return [aadCommands.OAUTH2GRANT_SET]; - } - constructor() { super(); @@ -46,8 +41,6 @@ class EntraOAuth2GrantSetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.OAUTH2GRANT_SET, commands.OAUTH2GRANT_SET); - if (this.verbose) { await logger.logToStderr(`Updating OAuth2 permissions...`); } diff --git a/src/m365/entra/commands/policy/policy-list.spec.ts b/src/m365/entra/commands/policy/policy-list.spec.ts index 9f9628d1350..b563b4e0657 100644 --- a/src/m365/entra/commands/policy/policy-list.spec.ts +++ b/src/m365/entra/commands/policy/policy-list.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './policy-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.POLICY_LIST, () => { let log: string[]; @@ -65,16 +64,6 @@ describe(commands.POLICY_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.POLICY_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['id', 'displayName', 'isOrganizationDefault']); }); diff --git a/src/m365/entra/commands/policy/policy-list.ts b/src/m365/entra/commands/policy/policy-list.ts index 138fb52a536..edd239f17f2 100644 --- a/src/m365/entra/commands/policy/policy-list.ts +++ b/src/m365/entra/commands/policy/policy-list.ts @@ -2,7 +2,6 @@ import { Logger } from '../../../../cli/Logger.js'; import GlobalOptions from '../../../../GlobalOptions.js'; import request, { CliRequestOptions } from '../../../../request.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -34,10 +33,6 @@ class EntraPolicyListCommand extends GraphCommand { return 'Returns policies from Entra ID'; } - public alias(): string[] | undefined { - return [aadCommands.POLICY_LIST]; - } - constructor() { super(); @@ -83,8 +78,6 @@ class EntraPolicyListCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.POLICY_LIST, commands.POLICY_LIST); - const policyType: string = args.options.type ? args.options.type.toLowerCase() : 'all'; try { diff --git a/src/m365/entra/commands/siteclassification/siteclassification-disable.spec.ts b/src/m365/entra/commands/siteclassification/siteclassification-disable.spec.ts index 61e16367733..39090557a71 100644 --- a/src/m365/entra/commands/siteclassification/siteclassification-disable.spec.ts +++ b/src/m365/entra/commands/siteclassification/siteclassification-disable.spec.ts @@ -11,7 +11,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './siteclassification-disable.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.SITECLASSIFICATION_DISABLE, () => { let log: string[]; @@ -69,16 +68,6 @@ describe(commands.SITECLASSIFICATION_DISABLE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.SITECLASSIFICATION_DISABLE]); - }); - it('prompts before disabling siteclassification when force option not passed', async () => { await command.action(logger, { options: {} }); diff --git a/src/m365/entra/commands/siteclassification/siteclassification-disable.ts b/src/m365/entra/commands/siteclassification/siteclassification-disable.ts index c2e5432ee34..b34fd79a5c5 100644 --- a/src/m365/entra/commands/siteclassification/siteclassification-disable.ts +++ b/src/m365/entra/commands/siteclassification/siteclassification-disable.ts @@ -5,7 +5,6 @@ import GlobalOptions from '../../../../GlobalOptions.js'; import request, { CliRequestOptions } from '../../../../request.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -24,10 +23,6 @@ class EntraSiteClassificationDisableCommand extends GraphCommand { return 'Disables site classification'; } - public alias(): string[] | undefined { - return [aadCommands.SITECLASSIFICATION_DISABLE]; - } - constructor() { super(); @@ -52,8 +47,6 @@ class EntraSiteClassificationDisableCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.SITECLASSIFICATION_DISABLE, commands.SITECLASSIFICATION_DISABLE); - const disableSiteClassification = async (): Promise => { try { let requestOptions: CliRequestOptions = { diff --git a/src/m365/entra/commands/siteclassification/siteclassification-enable.spec.ts b/src/m365/entra/commands/siteclassification/siteclassification-enable.spec.ts index 9e4c640ba6e..66b385a2ad3 100644 --- a/src/m365/entra/commands/siteclassification/siteclassification-enable.spec.ts +++ b/src/m365/entra/commands/siteclassification/siteclassification-enable.spec.ts @@ -10,7 +10,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './siteclassification-enable.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.SITECLASSIFICATION_ENABLE, () => { let log: string[]; @@ -59,16 +58,6 @@ describe(commands.SITECLASSIFICATION_ENABLE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.SITECLASSIFICATION_ENABLE]); - }); - it('handles Microsoft 365 Tenant siteclassification missing DirectorySettingTemplate', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/groupSettingTemplates`) { diff --git a/src/m365/entra/commands/siteclassification/siteclassification-enable.ts b/src/m365/entra/commands/siteclassification/siteclassification-enable.ts index 3847528c54c..69afbb7cd57 100644 --- a/src/m365/entra/commands/siteclassification/siteclassification-enable.ts +++ b/src/m365/entra/commands/siteclassification/siteclassification-enable.ts @@ -4,7 +4,6 @@ import GlobalOptions from '../../../../GlobalOptions.js'; import request, { CliRequestOptions } from '../../../../request.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -26,10 +25,6 @@ class EntraSiteClassificationEnableCommand extends GraphCommand { return 'Enables site classification configuration'; } - public alias(): string[] | undefined { - return [aadCommands.SITECLASSIFICATION_ENABLE]; - } - constructor() { super(); @@ -64,8 +59,6 @@ class EntraSiteClassificationEnableCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.SITECLASSIFICATION_ENABLE, commands.SITECLASSIFICATION_ENABLE); - try { let requestOptions: CliRequestOptions = { url: `${this.resource}/v1.0/groupSettingTemplates`, diff --git a/src/m365/entra/commands/siteclassification/siteclassification-get.spec.ts b/src/m365/entra/commands/siteclassification/siteclassification-get.spec.ts index cdc4a5ad3ea..444b2bb304e 100644 --- a/src/m365/entra/commands/siteclassification/siteclassification-get.spec.ts +++ b/src/m365/entra/commands/siteclassification/siteclassification-get.spec.ts @@ -10,7 +10,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './siteclassification-get.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.SITECLASSIFICATION_GET, () => { let log: string[]; @@ -60,16 +59,6 @@ describe(commands.SITECLASSIFICATION_GET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.SITECLASSIFICATION_GET]); - }); - it('handles Microsoft 365 Tenant siteclassification is not enabled', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/groupSettings`) { diff --git a/src/m365/entra/commands/siteclassification/siteclassification-get.ts b/src/m365/entra/commands/siteclassification/siteclassification-get.ts index dc3232003ce..ec2e5203799 100644 --- a/src/m365/entra/commands/siteclassification/siteclassification-get.ts +++ b/src/m365/entra/commands/siteclassification/siteclassification-get.ts @@ -4,7 +4,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; import { SiteClassificationSettings } from './SiteClassificationSettings.js'; -import aadCommands from '../../aadCommands.js'; class EntraSiteClassificationGetCommand extends GraphCommand { public get name(): string { @@ -15,13 +14,7 @@ class EntraSiteClassificationGetCommand extends GraphCommand { return 'Gets site classification configuration'; } - public alias(): string[] | undefined { - return [aadCommands.SITECLASSIFICATION_GET]; - } - public async commandAction(logger: Logger): Promise { - await this.showDeprecationWarning(logger, aadCommands.SITECLASSIFICATION_GET, commands.SITECLASSIFICATION_GET); - try { const requestOptions: CliRequestOptions = { url: `${this.resource}/v1.0/groupSettings`, diff --git a/src/m365/entra/commands/siteclassification/siteclassification-set.spec.ts b/src/m365/entra/commands/siteclassification/siteclassification-set.spec.ts index 59b239434ce..231cec97a2e 100644 --- a/src/m365/entra/commands/siteclassification/siteclassification-set.spec.ts +++ b/src/m365/entra/commands/siteclassification/siteclassification-set.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './siteclassification-set.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.SITECLASSIFICATION_SET, () => { let log: string[]; @@ -63,16 +62,6 @@ describe(commands.SITECLASSIFICATION_SET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.SITECLASSIFICATION_SET]); - }); - it('fails validation if none of the options are specified', async () => { const actual = await command.validate({ options: { diff --git a/src/m365/entra/commands/siteclassification/siteclassification-set.ts b/src/m365/entra/commands/siteclassification/siteclassification-set.ts index 621405ba2d5..d0322a8df28 100644 --- a/src/m365/entra/commands/siteclassification/siteclassification-set.ts +++ b/src/m365/entra/commands/siteclassification/siteclassification-set.ts @@ -4,7 +4,6 @@ import GlobalOptions from '../../../../GlobalOptions.js'; import request, { CliRequestOptions } from '../../../../request.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -26,10 +25,6 @@ class EntraSiteClassificationSetCommand extends GraphCommand { return 'Updates site classification configuration'; } - public alias(): string[] | undefined { - return [aadCommands.SITECLASSIFICATION_SET]; - } - constructor() { super(); @@ -81,8 +76,6 @@ class EntraSiteClassificationSetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.SITECLASSIFICATION_SET, commands.SITECLASSIFICATION_SET); - try { let requestOptions: CliRequestOptions = { url: `${this.resource}/v1.0/groupSettings`, diff --git a/src/m365/entra/commands/user/user-add.spec.ts b/src/m365/entra/commands/user/user-add.spec.ts index 80581d2ac93..ca1bd15add3 100644 --- a/src/m365/entra/commands/user/user-add.spec.ts +++ b/src/m365/entra/commands/user/user-add.spec.ts @@ -13,7 +13,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-add.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.USER_ADD, () => { const graphBaseUrl = 'https://graph.microsoft.com/v1.0/users'; @@ -124,16 +123,6 @@ describe(commands.USER_ADD, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_ADD]); - }); - it('creates Microsoft Entra user using a preset password but requiring the user to change it the next login', async () => { sinon.stub(request, 'post').callsFake(async (opts) => { if (opts.url === graphBaseUrl) { diff --git a/src/m365/entra/commands/user/user-add.ts b/src/m365/entra/commands/user/user-add.ts index 3f6643e892c..2af1e60bd80 100644 --- a/src/m365/entra/commands/user/user-add.ts +++ b/src/m365/entra/commands/user/user-add.ts @@ -5,7 +5,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface ExtendedUser extends User { password: string; @@ -44,10 +43,6 @@ class EntraUserAddCommand extends GraphCommand { return 'Creates a new user'; } - public alias(): string[] | undefined { - return [aadCommands.USER_ADD]; - } - public allowUnknownOptions(): boolean | undefined { return true; } @@ -206,8 +201,6 @@ class EntraUserAddCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.USER_ADD, commands.USER_ADD); - if (this.verbose) { await logger.logToStderr(`Adding user to AAD with displayName ${args.options.displayName} and userPrincipalName ${args.options.userName}`); } diff --git a/src/m365/entra/commands/user/user-get.spec.ts b/src/m365/entra/commands/user/user-get.spec.ts index 39d1652524e..991de5d6de2 100644 --- a/src/m365/entra/commands/user/user-get.spec.ts +++ b/src/m365/entra/commands/user/user-get.spec.ts @@ -14,7 +14,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-get.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; import { entraUser } from '../../../../utils/entraUser.js'; import { formatting } from '../../../../utils/formatting.js'; @@ -86,16 +85,6 @@ describe(commands.USER_GET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_GET]); - }); - it('retrieves user using id', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/users/${userId}`) { @@ -139,7 +128,7 @@ describe(commands.USER_GET, () => { it('retrieves user using user name', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { - if (opts.url === `https://graph.microsoft.com/v1.0/users/${formatting.encodeQueryParameter(userName) }`) { + if (opts.url === `https://graph.microsoft.com/v1.0/users/${formatting.encodeQueryParameter(userName)}`) { return resultValue; } @@ -185,7 +174,7 @@ describe(commands.USER_GET, () => { "mail": "john.doe@contoso.onmicrosoft.com" }; sinon.stub(request, 'get').callsFake(async (opts) => { - if (opts.url === `https://graph.microsoft.com/v1.0/users/${formatting.encodeQueryParameter(userName) }?$expand=manager($select=displayName,userPrincipalName,id,mail)`) { + if (opts.url === `https://graph.microsoft.com/v1.0/users/${formatting.encodeQueryParameter(userName)}?$expand=manager($select=displayName,userPrincipalName,id,mail)`) { return resultValueWithManger; } @@ -198,7 +187,7 @@ describe(commands.USER_GET, () => { it('retrieves user using @meusername token', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { - if (opts.url === `https://graph.microsoft.com/v1.0/users/${formatting.encodeQueryParameter(userName) }`) { + if (opts.url === `https://graph.microsoft.com/v1.0/users/${formatting.encodeQueryParameter(userName)}`) { return resultValue; } @@ -227,7 +216,7 @@ describe(commands.USER_GET, () => { it('retrieves only the specified properties', async () => { sinon.stub(request, 'get').callsFake(async (opts) => { - if (opts.url === `https://graph.microsoft.com/v1.0/users/${formatting.encodeQueryParameter(userName) }?$select=id,mail`) { + if (opts.url === `https://graph.microsoft.com/v1.0/users/${formatting.encodeQueryParameter(userName)}?$select=id,mail`) { return { "id": "userId", "mail": null }; } @@ -276,7 +265,7 @@ describe(commands.USER_GET, () => { await assert.rejects(command.action(logger, { options: { userName: userName } } as any), new CommandError(`Resource '${userName}' does not exist or one of its queried reference-property objects are not present.`)); }); - + it('fails validation if id or email or userName options are not passed', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { diff --git a/src/m365/entra/commands/user/user-get.ts b/src/m365/entra/commands/user/user-get.ts index e022aeeedaa..f59a5258116 100644 --- a/src/m365/entra/commands/user/user-get.ts +++ b/src/m365/entra/commands/user/user-get.ts @@ -5,7 +5,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; import { entraUser } from '../../../../utils/entraUser.js'; import { formatting } from '../../../../utils/formatting.js'; @@ -30,10 +29,6 @@ class EntraUserGetCommand extends GraphCommand { return 'Gets information about the specified user'; } - public alias(): string[] | undefined { - return [aadCommands.USER_GET]; - } - constructor() { super(); @@ -97,8 +92,6 @@ class EntraUserGetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.USER_GET, commands.USER_GET); - try { let userIdOrPrincipalName = args.options.id; diff --git a/src/m365/entra/commands/user/user-guest-add.spec.ts b/src/m365/entra/commands/user/user-guest-add.spec.ts index 7be7b809be1..edee1366026 100644 --- a/src/m365/entra/commands/user/user-guest-add.spec.ts +++ b/src/m365/entra/commands/user/user-guest-add.spec.ts @@ -10,7 +10,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-guest-add.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.USER_GUEST_ADD, () => { const emailAddress = 'john.doe@contoso.com'; @@ -86,16 +85,6 @@ describe(commands.USER_GUEST_ADD, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_GUEST_ADD]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['id', 'inviteRedeemUrl', 'invitedUserDisplayName', 'invitedUserEmailAddress', 'invitedUserType', 'resetRedemption', 'sendInvitationMessage', 'status']); }); diff --git a/src/m365/entra/commands/user/user-guest-add.ts b/src/m365/entra/commands/user/user-guest-add.ts index 320efed18a0..9f41a752c47 100644 --- a/src/m365/entra/commands/user/user-guest-add.ts +++ b/src/m365/entra/commands/user/user-guest-add.ts @@ -2,7 +2,6 @@ import { Logger } from '../../../../cli/Logger.js'; import GlobalOptions from '../../../../GlobalOptions.js'; import request, { CliRequestOptions } from '../../../../request.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -28,10 +27,6 @@ class EntraUserGuestAddCommand extends GraphCommand { return 'Invite an external user to the organization'; } - public alias(): string[] | undefined { - return [aadCommands.USER_GUEST_ADD]; - } - constructor() { super(); @@ -83,8 +78,6 @@ class EntraUserGuestAddCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.USER_GUEST_ADD, commands.USER_GUEST_ADD); - try { const requestOptions: CliRequestOptions = { url: `${this.resource}/v1.0/invitations`, diff --git a/src/m365/entra/commands/user/user-hibp.spec.ts b/src/m365/entra/commands/user/user-hibp.spec.ts index 71fa429da01..62c0aef613e 100644 --- a/src/m365/entra/commands/user/user-hibp.spec.ts +++ b/src/m365/entra/commands/user/user-hibp.spec.ts @@ -13,7 +13,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-hibp.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.USER_HIBP, () => { let log: string[]; @@ -63,16 +62,6 @@ describe(commands.USER_HIBP, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_HIBP]); - }); - it('fails validation if userName and apiKey is not specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { diff --git a/src/m365/entra/commands/user/user-hibp.ts b/src/m365/entra/commands/user/user-hibp.ts index 04e9567094a..70ed76b2710 100644 --- a/src/m365/entra/commands/user/user-hibp.ts +++ b/src/m365/entra/commands/user/user-hibp.ts @@ -4,7 +4,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { formatting } from '../../../../utils/formatting.js'; import { validation } from '../../../../utils/validation.js'; import AnonymousCommand from '../../../base/AnonymousCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -26,10 +25,6 @@ class EntraUserHibpCommand extends AnonymousCommand { return 'Allows you to retrieve all accounts that have been pwned with the specified username'; } - public alias(): string[] | undefined { - return [aadCommands.USER_HIBP]; - } - constructor() { super(); @@ -73,8 +68,6 @@ class EntraUserHibpCommand extends AnonymousCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.USER_HIBP, commands.USER_HIBP); - try { const requestOptions: CliRequestOptions = { url: `https://haveibeenpwned.com/api/v3/breachedaccount/${formatting.encodeQueryParameter(args.options.userName)}${(args.options.domain ? `?domain=${formatting.encodeQueryParameter(args.options.domain)}` : '')}`, diff --git a/src/m365/entra/commands/user/user-license-add.spec.ts b/src/m365/entra/commands/user/user-license-add.spec.ts index f50e59b2e62..a6648d63c90 100644 --- a/src/m365/entra/commands/user/user-license-add.spec.ts +++ b/src/m365/entra/commands/user/user-license-add.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-license-add.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.USER_LICENSE_ADD, () => { let commandInfo: CommandInfo; @@ -83,16 +82,6 @@ describe(commands.USER_LICENSE_ADD, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_LICENSE_ADD]); - }); - it('fails validation if ids is not a valid guid.', async () => { const actual = await command.validate({ options: { diff --git a/src/m365/entra/commands/user/user-license-add.ts b/src/m365/entra/commands/user/user-license-add.ts index 8471cdca5ed..9a8ed9aecc7 100644 --- a/src/m365/entra/commands/user/user-license-add.ts +++ b/src/m365/entra/commands/user/user-license-add.ts @@ -3,7 +3,6 @@ import GlobalOptions from '../../../../GlobalOptions.js'; import request, { CliRequestOptions } from '../../../../request.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -25,10 +24,6 @@ class EntraUserLicenseAddCommand extends GraphCommand { return 'Assigns a license to a user'; } - public alias(): string[] | undefined { - return [aadCommands.USER_LICENSE_ADD]; - } - constructor() { super(); @@ -84,8 +79,6 @@ class EntraUserLicenseAddCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.USER_LICENSE_ADD, commands.USER_LICENSE_ADD); - const addLicenses = args.options.ids.split(',').map(x => { return { "disabledPlans": [], "skuId": x }; }); const requestBody = { "addLicenses": addLicenses, "removeLicenses": [] }; diff --git a/src/m365/entra/commands/user/user-license-list.spec.ts b/src/m365/entra/commands/user/user-license-list.spec.ts index 4d07ff4a961..6936039da9f 100644 --- a/src/m365/entra/commands/user/user-license-list.spec.ts +++ b/src/m365/entra/commands/user/user-license-list.spec.ts @@ -13,7 +13,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-license-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.USER_LICENSE_LIST, () => { const userId = '59f80e08-24b1-41f8-8586-16765fd830d3'; @@ -103,16 +102,6 @@ describe(commands.USER_LICENSE_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_LICENSE_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['id', 'skuId', 'skuPartNumber']); }); diff --git a/src/m365/entra/commands/user/user-license-list.ts b/src/m365/entra/commands/user/user-license-list.ts index 2d3437c393e..bcb2a8d09de 100644 --- a/src/m365/entra/commands/user/user-license-list.ts +++ b/src/m365/entra/commands/user/user-license-list.ts @@ -6,7 +6,6 @@ import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; import auth from '../../../../Auth.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -26,10 +25,6 @@ class EntraUserLicenseListCommand extends GraphCommand { return 'Lists the license details for a given user'; } - public alias(): string[] | undefined { - return [aadCommands.USER_LICENSE_LIST]; - } - public defaultProperties(): string[] | undefined { return ['id', 'skuId', 'skuPartNumber']; } @@ -88,8 +83,6 @@ class EntraUserLicenseListCommand extends GraphCommand { public async commandAction(logger: Logger, args: CommandArgs): Promise { const isAppOnlyAccessToken = accessToken.isAppOnlyAccessToken(auth.connection.accessTokens[this.resource].accessToken); - await this.showDeprecationWarning(logger, aadCommands.USER_LICENSE_LIST, commands.USER_LICENSE_LIST); - if (isAppOnlyAccessToken && !args.options.userId && !args.options.userName) { this.handleError(`Specify at least 'userId' or 'userName' when using application permissions.`); } diff --git a/src/m365/entra/commands/user/user-license-remove.spec.ts b/src/m365/entra/commands/user/user-license-remove.spec.ts index 09602532ef6..c82a1ebde6a 100644 --- a/src/m365/entra/commands/user/user-license-remove.spec.ts +++ b/src/m365/entra/commands/user/user-license-remove.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-license-remove.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.USER_LICENSE_REMOVE, () => { let commandInfo: CommandInfo; @@ -77,16 +76,6 @@ describe(commands.USER_LICENSE_REMOVE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_LICENSE_REMOVE]); - }); - it('fails validation if ids is not a valid guid.', async () => { const actual = await command.validate({ options: { diff --git a/src/m365/entra/commands/user/user-license-remove.ts b/src/m365/entra/commands/user/user-license-remove.ts index 4e03576eccd..9afcbfcb811 100644 --- a/src/m365/entra/commands/user/user-license-remove.ts +++ b/src/m365/entra/commands/user/user-license-remove.ts @@ -5,7 +5,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { validation } from '../../../../utils/validation.js'; import { cli } from '../../../../cli/cli.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -28,10 +27,6 @@ class EntraUserLicenseRemoveCommand extends GraphCommand { return 'Removes a license from a user'; } - public alias(): string[] | undefined { - return [aadCommands.USER_LICENSE_REMOVE]; - } - constructor() { super(); @@ -95,8 +90,6 @@ class EntraUserLicenseRemoveCommand extends GraphCommand { } public async commandAction(logger: Logger, args: any): Promise { - await this.showDeprecationWarning(logger, aadCommands.USER_LICENSE_REMOVE, commands.USER_LICENSE_REMOVE); - if (this.verbose) { await logger.logToStderr(`Removing the licenses for the user '${args.options.userId || args.options.userName}'...`); } diff --git a/src/m365/entra/commands/user/user-list.spec.ts b/src/m365/entra/commands/user/user-list.spec.ts index df51e8622d7..36120d661ba 100644 --- a/src/m365/entra/commands/user/user-list.spec.ts +++ b/src/m365/entra/commands/user/user-list.spec.ts @@ -13,7 +13,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.USER_LIST, () => { let commandInfo: CommandInfo; @@ -65,16 +64,6 @@ describe(commands.USER_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_LIST]); - }); - it('fails validation if type is not a valid user type', async () => { const actual = await command.validate({ options: { type: 'invalid' } }, commandInfo); assert.notStrictEqual(actual, true); diff --git a/src/m365/entra/commands/user/user-list.ts b/src/m365/entra/commands/user/user-list.ts index 1edfd4b30ca..fdce96baafc 100644 --- a/src/m365/entra/commands/user/user-list.ts +++ b/src/m365/entra/commands/user/user-list.ts @@ -5,7 +5,6 @@ import { formatting } from '../../../../utils/formatting.js'; import { odata } from '../../../../utils/odata.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -27,10 +26,6 @@ class EntraUserListCommand extends GraphCommand { return 'Lists users matching specified criteria'; } - public alias(): string[] | undefined { - return [aadCommands.USER_LIST]; - } - public allowUnknownOptions(): boolean | undefined { return true; } @@ -86,8 +81,6 @@ class EntraUserListCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.USER_LIST, commands.USER_LIST); - try { let url = `${this.resource}/v1.0/users`; diff --git a/src/m365/entra/commands/user/user-password-validate.spec.ts b/src/m365/entra/commands/user/user-password-validate.spec.ts index 6e3facf5272..8834d5f6d43 100644 --- a/src/m365/entra/commands/user/user-password-validate.spec.ts +++ b/src/m365/entra/commands/user/user-password-validate.spec.ts @@ -10,7 +10,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-password-validate.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.USER_PASSWORD_VALIDATE, () => { let log: string[]; @@ -61,16 +60,6 @@ describe(commands.USER_PASSWORD_VALIDATE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_PASSWORD_VALIDATE]); - }); - it('password is too short', async () => { sinon.stub(request, 'post').callsFake(async opts => { if (opts.url === 'https://graph.microsoft.com/beta/users/validatePassword' && diff --git a/src/m365/entra/commands/user/user-password-validate.ts b/src/m365/entra/commands/user/user-password-validate.ts index 30ea1a691ae..ed88f2d94b1 100644 --- a/src/m365/entra/commands/user/user-password-validate.ts +++ b/src/m365/entra/commands/user/user-password-validate.ts @@ -2,7 +2,6 @@ import { Logger } from '../../../../cli/Logger.js'; import GlobalOptions from '../../../../GlobalOptions.js'; import request, { CliRequestOptions } from '../../../../request.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -22,10 +21,6 @@ class EntraUserPasswordValidateCommand extends GraphCommand { return "Check a user's password against the organization's password validation policy"; } - public alias(): string[] | undefined { - return [aadCommands.USER_PASSWORD_VALIDATE]; - } - constructor() { super(); @@ -41,8 +36,6 @@ class EntraUserPasswordValidateCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.USER_PASSWORD_VALIDATE, commands.USER_PASSWORD_VALIDATE); - try { const requestOptions: CliRequestOptions = { url: `${this.resource}/beta/users/validatePassword`, diff --git a/src/m365/entra/commands/user/user-recyclebinitem-clear.spec.ts b/src/m365/entra/commands/user/user-recyclebinitem-clear.spec.ts index 5d52c4b76f3..9e5e59a2008 100644 --- a/src/m365/entra/commands/user/user-recyclebinitem-clear.spec.ts +++ b/src/m365/entra/commands/user/user-recyclebinitem-clear.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-recyclebinitem-clear.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.USER_RECYCLEBINITEM_CLEAR, () => { let log: string[]; @@ -74,16 +73,6 @@ describe(commands.USER_RECYCLEBINITEM_CLEAR, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_RECYCLEBINITEM_CLEAR]); - }); - it('removes a single user when prompt confirmed', async () => { let amountOfBatches = 0; diff --git a/src/m365/entra/commands/user/user-recyclebinitem-clear.ts b/src/m365/entra/commands/user/user-recyclebinitem-clear.ts index 861fb46e7d4..91a6bc37006 100644 --- a/src/m365/entra/commands/user/user-recyclebinitem-clear.ts +++ b/src/m365/entra/commands/user/user-recyclebinitem-clear.ts @@ -6,7 +6,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { odata } from '../../../../utils/odata.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -25,10 +24,6 @@ class EntraUserRecycleBinItemClearCommand extends GraphCommand { return 'Removes all users from the tenant recycle bin'; } - public alias(): string[] | undefined { - return [aadCommands.USER_RECYCLEBINITEM_CLEAR]; - } - constructor() { super(); @@ -53,8 +48,6 @@ class EntraUserRecycleBinItemClearCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.USER_RECYCLEBINITEM_CLEAR, commands.USER_RECYCLEBINITEM_CLEAR); - const clearRecycleBinUsers = async (): Promise => { try { const users = await odata.getAllItems(`${this.resource}/v1.0/directory/deletedItems/microsoft.graph.user?$select=id`); diff --git a/src/m365/entra/commands/user/user-recyclebinitem-list.spec.ts b/src/m365/entra/commands/user/user-recyclebinitem-list.spec.ts index 7c68be3cb6b..a49b69cfdf5 100644 --- a/src/m365/entra/commands/user/user-recyclebinitem-list.spec.ts +++ b/src/m365/entra/commands/user/user-recyclebinitem-list.spec.ts @@ -10,7 +10,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-recyclebinitem-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.USER_RECYCLEBINITEM_LIST, () => { const deletedUsersResponse = [{ "businessPhones": [], "displayName": "John Doe", "givenName": "John Doe", "jobTitle": "Developer", "mail": "john@contoso.com", "mobilePhone": "0476345130", "officeLocation": "Washington", "preferredLanguage": "nl-BE", "surname": "John", "userPrincipalName": "7e06b56615f340138bf879874d52e68ajohn@contoso.com", "id": "7e06b566-15f3-4013-8bf8-79874d52e68a" }]; @@ -63,16 +62,6 @@ describe(commands.USER_RECYCLEBINITEM_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_RECYCLEBINITEM_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['id', 'displayName', 'userPrincipalName']); }); diff --git a/src/m365/entra/commands/user/user-recyclebinitem-list.ts b/src/m365/entra/commands/user/user-recyclebinitem-list.ts index e43e6f910c2..a9da1950cac 100644 --- a/src/m365/entra/commands/user/user-recyclebinitem-list.ts +++ b/src/m365/entra/commands/user/user-recyclebinitem-list.ts @@ -3,7 +3,6 @@ import { Logger } from '../../../../cli/Logger.js'; import { odata } from '../../../../utils/odata.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; class EntraUserRecycleBinItemListCommand extends GraphCommand { public get name(): string { @@ -14,17 +13,11 @@ class EntraUserRecycleBinItemListCommand extends GraphCommand { return 'Lists users from the recycle bin in the current tenant'; } - public alias(): string[] | undefined { - return [aadCommands.USER_RECYCLEBINITEM_LIST]; - } - public defaultProperties(): string[] | undefined { return ['id', 'displayName', 'userPrincipalName']; } public async commandAction(logger: Logger): Promise { - await this.showDeprecationWarning(logger, aadCommands.USER_RECYCLEBINITEM_LIST, commands.USER_RECYCLEBINITEM_LIST); - if (this.verbose) { await logger.logToStderr('Retrieving users from the recycle bin...'); } diff --git a/src/m365/entra/commands/user/user-recyclebinitem-remove.spec.ts b/src/m365/entra/commands/user/user-recyclebinitem-remove.spec.ts index 5fb87f6542d..3c5725df198 100644 --- a/src/m365/entra/commands/user/user-recyclebinitem-remove.spec.ts +++ b/src/m365/entra/commands/user/user-recyclebinitem-remove.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-recyclebinitem-remove.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.USER_RECYCLEBINITEM_REMOVE, () => { const validUserId = 'd839826a-81bf-4c38-8f80-f150d11ce6c7'; @@ -73,16 +72,6 @@ describe(commands.USER_RECYCLEBINITEM_REMOVE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_RECYCLEBINITEM_REMOVE]); - }); - it('removes the user when prompt confirmed', async () => { sinonUtil.restore(cli.promptForConfirmation); sinon.stub(cli, 'promptForConfirmation').resolves(true); diff --git a/src/m365/entra/commands/user/user-recyclebinitem-remove.ts b/src/m365/entra/commands/user/user-recyclebinitem-remove.ts index 56f8c39f213..191c3ec74f7 100644 --- a/src/m365/entra/commands/user/user-recyclebinitem-remove.ts +++ b/src/m365/entra/commands/user/user-recyclebinitem-remove.ts @@ -4,7 +4,6 @@ import GlobalOptions from '../../../../GlobalOptions.js'; import request, { CliRequestOptions } from '../../../../request.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -25,10 +24,6 @@ class EntraUserRecycleBinItemRemoveCommand extends GraphCommand { return 'Removes a user from the recycle bin in the current tenant'; } - public alias(): string[] | undefined { - return [aadCommands.USER_RECYCLEBINITEM_REMOVE]; - } - constructor() { super(); @@ -69,8 +64,6 @@ class EntraUserRecycleBinItemRemoveCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.USER_RECYCLEBINITEM_REMOVE, commands.USER_RECYCLEBINITEM_REMOVE); - const clearRecycleBinItem: () => Promise = async (): Promise => { if (this.verbose) { await logger.logToStderr(`Permanently deleting user with id ${args.options.id} from Microsoft Entra ID`); diff --git a/src/m365/entra/commands/user/user-recyclebinitem-restore.spec.ts b/src/m365/entra/commands/user/user-recyclebinitem-restore.spec.ts index 41acd7cda87..79a12f9b9d6 100644 --- a/src/m365/entra/commands/user/user-recyclebinitem-restore.spec.ts +++ b/src/m365/entra/commands/user/user-recyclebinitem-restore.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-recyclebinitem-restore.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.USER_RECYCLEBINITEM_RESTORE, () => { const validUserId = 'd839826a-81bf-4c38-8f80-f150d11ce6c7'; @@ -82,16 +81,6 @@ describe(commands.USER_RECYCLEBINITEM_RESTORE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_RECYCLEBINITEM_RESTORE]); - }); - it('restores the user from the recycle bin', async () => { sinon.stub(request, 'post').callsFake(async (opts) => { if (opts.url === `https://graph.microsoft.com/v1.0/directory/deletedItems/${validUserId}/restore`) { diff --git a/src/m365/entra/commands/user/user-recyclebinitem-restore.ts b/src/m365/entra/commands/user/user-recyclebinitem-restore.ts index f66f0c16f05..52e392cfd98 100644 --- a/src/m365/entra/commands/user/user-recyclebinitem-restore.ts +++ b/src/m365/entra/commands/user/user-recyclebinitem-restore.ts @@ -5,7 +5,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -24,10 +23,6 @@ class EntraUserRecycleBinItemRestoreCommand extends GraphCommand { return 'Restores a user from the tenant recycle bin'; } - public alias(): string[] | undefined { - return [aadCommands.USER_RECYCLEBINITEM_RESTORE]; - } - constructor() { super(); @@ -56,8 +51,6 @@ class EntraUserRecycleBinItemRestoreCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.USER_RECYCLEBINITEM_RESTORE, commands.USER_RECYCLEBINITEM_RESTORE); - if (this.verbose) { await logger.logToStderr(`Restoring user with id ${args.options.id} from the recycle bin.`); } diff --git a/src/m365/entra/commands/user/user-registrationdetails-list.spec.ts b/src/m365/entra/commands/user/user-registrationdetails-list.spec.ts index b3c87ee1dcf..e5ee0099f85 100644 --- a/src/m365/entra/commands/user/user-registrationdetails-list.spec.ts +++ b/src/m365/entra/commands/user/user-registrationdetails-list.spec.ts @@ -2,7 +2,6 @@ import assert from 'assert'; import sinon from 'sinon'; import auth from '../../../../Auth.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; import request from '../../../../request.js'; import command from './user-registrationdetails-list.js'; import { telemetry } from '../../../../telemetry.js'; @@ -133,16 +132,6 @@ describe(commands.USER_REGISTRATIONDETAILS_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_REGISTRATIONDETAILS_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['userPrincipalName', 'methodsRegistered', 'lastUpdatedDateTime']); }); diff --git a/src/m365/entra/commands/user/user-registrationdetails-list.ts b/src/m365/entra/commands/user/user-registrationdetails-list.ts index 960ff6cf6bb..9d8b8507c1c 100644 --- a/src/m365/entra/commands/user/user-registrationdetails-list.ts +++ b/src/m365/entra/commands/user/user-registrationdetails-list.ts @@ -2,7 +2,6 @@ import GlobalOptions from '../../../../GlobalOptions.js'; import { Logger } from '../../../../cli/Logger.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; import { odata } from '../../../../utils/odata.js'; import { UserRegistrationDetails } from '@microsoft/microsoft-graph-types'; import { entraUser } from '../../../../utils/entraUser.js'; @@ -42,10 +41,6 @@ class EntraUserRegistrationDetailsListCommand extends GraphCommand { return 'Retrieves a list of the authentication methods registered for users'; } - public alias(): string[] | undefined { - return [aadCommands.USER_REGISTRATIONDETAILS_LIST]; - } - public defaultProperties(): string[] | undefined { return ['userPrincipalName', 'methodsRegistered', 'lastUpdatedDateTime']; } diff --git a/src/m365/entra/commands/user/user-remove.spec.ts b/src/m365/entra/commands/user/user-remove.spec.ts index 3bbe35bcb3e..b18c879a3be 100644 --- a/src/m365/entra/commands/user/user-remove.spec.ts +++ b/src/m365/entra/commands/user/user-remove.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-remove.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.USER_REMOVE, () => { let commandInfo: CommandInfo; @@ -75,16 +74,6 @@ describe(commands.USER_REMOVE, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_REMOVE]); - }); - it('fails validation if id is not a valid guid.', async () => { const actual = await command.validate({ options: { diff --git a/src/m365/entra/commands/user/user-remove.ts b/src/m365/entra/commands/user/user-remove.ts index 2279e334076..76025701f98 100644 --- a/src/m365/entra/commands/user/user-remove.ts +++ b/src/m365/entra/commands/user/user-remove.ts @@ -5,7 +5,6 @@ import request, { CliRequestOptions } from '../../../../request.js'; import { validation } from '../../../../utils/validation.js'; import { cli } from '../../../../cli/cli.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -27,10 +26,6 @@ class EntraUserRemoveCommand extends GraphCommand { return 'Removes a specific user'; } - public alias(): string[] | undefined { - return [aadCommands.USER_REMOVE]; - } - constructor() { super(); @@ -87,8 +82,6 @@ class EntraUserRemoveCommand extends GraphCommand { } public async commandAction(logger: Logger, args: any): Promise { - await this.showDeprecationWarning(logger, aadCommands.USER_REMOVE, commands.USER_REMOVE); - if (this.verbose) { await logger.logToStderr(`Removing user '${args.options.id || args.options.userName}'...`); } diff --git a/src/m365/entra/commands/user/user-set.spec.ts b/src/m365/entra/commands/user/user-set.spec.ts index 12c30875988..3da3de2bf43 100644 --- a/src/m365/entra/commands/user/user-set.spec.ts +++ b/src/m365/entra/commands/user/user-set.spec.ts @@ -15,7 +15,6 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-set.js'; import { settingsNames } from '../../../../settingsNames.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.USER_SET, () => { const currentPassword = '9%9OLUg6p@Ra'; @@ -95,16 +94,6 @@ describe(commands.USER_SET, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_SET]); - }); - it('fails validation if neither the id nor the userName are specified', async () => { sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => { if (settingName === settingsNames.prompt) { diff --git a/src/m365/entra/commands/user/user-set.ts b/src/m365/entra/commands/user/user-set.ts index 84cf11eadfe..677261a7477 100644 --- a/src/m365/entra/commands/user/user-set.ts +++ b/src/m365/entra/commands/user/user-set.ts @@ -6,7 +6,6 @@ import { accessToken } from '../../../../utils/accessToken.js'; import { formatting } from '../../../../utils/formatting.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; -import aadCommands from '../../aadCommands.js'; import commands from '../../commands.js'; interface CommandArgs { @@ -45,10 +44,6 @@ class EntraUserSetCommand extends GraphCommand { return 'Updates information about the specified user'; } - public alias(): string[] | undefined { - return [aadCommands.USER_SET]; - } - public allowUnknownOptions(): boolean | undefined { return true; } @@ -249,8 +244,6 @@ class EntraUserSetCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.USER_SET, commands.USER_SET); - try { if (args.options.currentPassword) { if (args.options.id && args.options.id !== accessToken.getUserIdFromAccessToken(auth.connection.accessTokens[auth.defaultResource].accessToken)) { diff --git a/src/m365/entra/commands/user/user-signin-list.spec.ts b/src/m365/entra/commands/user/user-signin-list.spec.ts index 0515ced18e8..632be3d30cc 100644 --- a/src/m365/entra/commands/user/user-signin-list.spec.ts +++ b/src/m365/entra/commands/user/user-signin-list.spec.ts @@ -12,7 +12,6 @@ import { session } from '../../../../utils/session.js'; import { sinonUtil } from '../../../../utils/sinonUtil.js'; import commands from '../../commands.js'; import command from './user-signin-list.js'; -import aadCommands from '../../aadCommands.js'; describe(commands.USER_SIGNIN_LIST, () => { let log: string[]; @@ -192,16 +191,6 @@ describe(commands.USER_SIGNIN_LIST, () => { assert.notStrictEqual(command.description, null); }); - it('defines alias', () => { - const alias = command.alias(); - assert.notStrictEqual(typeof alias, 'undefined'); - }); - - it('defines correct alias', () => { - const alias = command.alias(); - assert.deepStrictEqual(alias, [aadCommands.USER_SIGNIN_LIST]); - }); - it('defines correct properties for the default output', () => { assert.deepStrictEqual(command.defaultProperties(), ['id', 'userPrincipalName', 'appId', 'appDisplayName', 'createdDateTime']); }); diff --git a/src/m365/entra/commands/user/user-signin-list.ts b/src/m365/entra/commands/user/user-signin-list.ts index f34dd17cace..afa9ee5eab8 100644 --- a/src/m365/entra/commands/user/user-signin-list.ts +++ b/src/m365/entra/commands/user/user-signin-list.ts @@ -6,7 +6,6 @@ import { odata } from '../../../../utils/odata.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; -import aadCommands from '../../aadCommands.js'; interface CommandArgs { options: Options; @@ -28,10 +27,6 @@ class EntraUserSigninListCommand extends GraphCommand { return 'Retrieves the Entra ID user sign-ins for the tenant'; } - public alias(): string[] | undefined { - return [aadCommands.USER_SIGNIN_LIST]; - } - constructor() { super(); @@ -101,8 +96,6 @@ class EntraUserSigninListCommand extends GraphCommand { } public async commandAction(logger: Logger, args: CommandArgs): Promise { - await this.showDeprecationWarning(logger, aadCommands.USER_SIGNIN_LIST, commands.USER_SIGNIN_LIST); - try { let endpoint: string = `${this.resource}/v1.0/auditLogs/signIns`; let filter: string = ""; diff --git a/src/m365/spo/commands/group/group-member-remove.spec.ts b/src/m365/spo/commands/group/group-member-remove.spec.ts index cbccf4c3882..303e4d65037 100644 --- a/src/m365/spo/commands/group/group-member-remove.spec.ts +++ b/src/m365/spo/commands/group/group-member-remove.spec.ts @@ -130,6 +130,40 @@ describe(commands.GROUP_MEMBER_REMOVE, () => { assert(postStub.called); }); + it('Removes Microsoft Entra group from SharePoint group using Microsoft Entra Group Name', async () => { + sinonUtil.restore(cli.promptForConfirmation); + sinon.stub(cli, 'promptForConfirmation').resolves(true); + + sinon.stub(cli, 'executeCommandWithOutput').callsFake(async (command): Promise => { + if (command === spoGroupMemberListCommand) { + return ({ + stdout: spoGroupMemberListCommandOutput + }); + } + + throw new CommandError('Unknown case'); + }); + + const postStub = sinon.stub(request, 'post').callsFake(async opts => { + if ((opts.url as string).indexOf('/_api/web/sitegroups/GetByName') > -1) { + return UserRemovalJSONResponse; + } + + throw `Invalid request ${JSON.stringify(opts)}`; + }); + + await command.action(logger, { + options: { + debug: true, + webUrl: "https://contoso.sharepoint.com/sites/SiteA", + groupName: "Site A Visitors", + entraGroupName: "Microsoft Entra Security Group" + } + }); + + assert(postStub.called); + }); + it('Removes Entra group from SharePoint group using Entra Group ID - Without Confirmation Prompt', async () => { sinon.stub(cli, 'executeCommandWithOutput').callsFake(async (command): Promise => { if (command === spoGroupMemberListCommand) { @@ -160,6 +194,36 @@ describe(commands.GROUP_MEMBER_REMOVE, () => { assert(postStub.called); }); + it('Removes Microsoft Entra group from SharePoint group using Microsoft Entra Group ID - Without Confirmation Prompt', async () => { + sinon.stub(cli, 'executeCommandWithOutput').callsFake(async (command): Promise => { + if (command === spoGroupMemberListCommand) { + return ({ + stdout: spoGroupMemberListCommandOutput + }); + } + + throw new CommandError('Unknown case'); + }); + + const postStub = sinon.stub(request, 'post').callsFake(async opts => { + if ((opts.url as string).indexOf('/_api/web/sitegroups/GetByName') > -1) { + return UserRemovalJSONResponse; + } + + throw `Invalid request ${JSON.stringify(opts)}`; + }); + await command.action(logger, { + options: { + debug: true, + webUrl: "https://contoso.sharepoint.com/sites/SiteA", + groupName: "Site A Visitors", + entraGroupId: "5786b8e8-c495-4734-b345-756733960730", + force: true + } + }); + assert(postStub.called); + }); + it('Removes Entra group from SharePoint group using Entra Group ID and SharePoint Group ID', async () => { sinonUtil.restore(cli.promptForConfirmation); sinon.stub(cli, 'promptForConfirmation').resolves(true);