diff --git a/cypress/e2e/fixtures/api/eventlog.ts b/cypress/e2e/fixtures/api/eventlog.ts index 77eafb2bf..4a13e34af 100644 --- a/cypress/e2e/fixtures/api/eventlog.ts +++ b/cypress/e2e/fixtures/api/eventlog.ts @@ -167,6 +167,67 @@ const eventLogs = { IDER: false } } + }, + remotePlatformErase: { + notSupported: { + response: { + userConsent: 'none', + optInState: 0, + redirection: true, + KVM: true, + SOL: true, + IDER: false, + kvmAvailable: false, + ocr: false, + httpsBootSupported: false, + winREBootSupported: false, + localPBABootSupported: false, + remoteEraseEnabled: false, + remoteEraseSupported: false, + pbaBootFilesPath: [], + winREBootFilesPath: { instanceID: '', biosBootString: '', bootString: '' } + } + }, + supportedDisabled: { + response: { + userConsent: 'none', + optInState: 0, + redirection: true, + KVM: true, + SOL: true, + IDER: false, + kvmAvailable: false, + ocr: false, + httpsBootSupported: false, + winREBootSupported: false, + localPBABootSupported: false, + remoteEraseEnabled: false, + remoteEraseSupported: true, + platformEraseCaps: 0x05, + pbaBootFilesPath: [], + winREBootFilesPath: { instanceID: '', biosBootString: '', bootString: '' } + } + }, + supportedEnabled: { + response: { + userConsent: 'none', + optInState: 0, + redirection: true, + KVM: true, + SOL: true, + IDER: false, + kvmAvailable: false, + ocr: false, + httpsBootSupported: false, + winREBootSupported: false, + localPBABootSupported: false, + remoteEraseEnabled: true, + remoteEraseSupported: true, + platformEraseCaps: 0x05, + pbaBootFilesPath: [], + winREBootFilesPath: { instanceID: '', biosBootString: '', bootString: '' } + } + } } } diff --git a/cypress/e2e/integration/device/remote-platform-erase.spec.ts b/cypress/e2e/integration/device/remote-platform-erase.spec.ts new file mode 100644 index 000000000..604e7bab3 --- /dev/null +++ b/cypress/e2e/integration/device/remote-platform-erase.spec.ts @@ -0,0 +1,223 @@ +/********************************************************************* + * Copyright (c) Intel Corporation 2022 + * SPDX-License-Identifier: Apache-2.0 + **********************************************************************/ + +import { httpCodes } from '../../fixtures/api/httpCodes' +import { eventLogs } from '../../fixtures/api/eventlog' + +const navigateToRemotePlatformErase = (): void => { + cy.myIntercept('GET', 'devices?$top=25&$skip=0&$count=true', { + statusCode: httpCodes.SUCCESS, + body: eventLogs.devices.success.response + }).as('get-devices') + + cy.myIntercept('GET', /devices\/.*$/, { + statusCode: httpCodes.SUCCESS, + body: eventLogs.devices.success.response + }).as('get-device-by-id') + + cy.myIntercept('GET', /devices\/tags/, { + statusCode: httpCodes.SUCCESS, + body: [] + }).as('get-tags') + + cy.myIntercept('GET', /.*power.*/, { + statusCode: httpCodes.SUCCESS, + body: { powerstate: 2 } + }).as('get-powerstate') + + cy.myIntercept('GET', /.*general.*/, { + statusCode: httpCodes.SUCCESS, + body: eventLogs.general.success.response + }).as('get-general') + + cy.myIntercept('GET', /.*version.*/, { + statusCode: httpCodes.SUCCESS, + body: eventLogs.version.success.response + }).as('get-version') + + cy.myIntercept('GET', /.*alarmOccurrences.*/, { + statusCode: httpCodes.SUCCESS, + body: eventLogs.alarmOccurrences.success.response + }).as('get-alarms') + + cy.goToPage('Devices') + cy.wait('@get-devices').its('response.statusCode').should('eq', 200) + + cy.get('mat-row').first().click() + cy.wait('@get-device-by-id').its('response.statusCode').should('eq', 200) + + cy.get('.mat-mdc-list-item-title').contains('Remote Platform Erase').click() +} + +describe('Remote Platform Erase', () => { + beforeEach(() => { + cy.setup() + }) + + it('should show "not supported" message when remoteEraseSupported is false', () => { + cy.myIntercept('GET', /.*amt\/features.*/, { + statusCode: httpCodes.SUCCESS, + body: eventLogs.remotePlatformErase.notSupported.response + }).as('get-features') + + navigateToRemotePlatformErase() + cy.wait('@get-features') + + cy.get('[data-cy="remoteEraseCheckbox"]').should('not.exist') + cy.get('mat-icon').contains('info').should('exist') + }) + + it('should show checkbox when supported but not enabled', () => { + cy.myIntercept('GET', /.*amt\/features.*/, { + statusCode: httpCodes.SUCCESS, + body: eventLogs.remotePlatformErase.supportedDisabled.response + }).as('get-features') + + navigateToRemotePlatformErase() + cy.wait('@get-features') + + cy.get('[data-cy="remoteEraseCheckbox"]').should('exist') + cy.get('[data-cy="remoteEraseCheckbox"] input[type="checkbox"]').should('not.be.checked') + cy.get('[data-cy="initiateEraseButton"]').should('not.exist') + }) + + it('should show initiate erase button when feature is already enabled', () => { + cy.myIntercept('GET', /.*amt\/features.*/, { + statusCode: httpCodes.SUCCESS, + body: eventLogs.remotePlatformErase.supportedEnabled.response + }).as('get-features') + + navigateToRemotePlatformErase() + cy.wait('@get-features') + + cy.get('[data-cy="remoteEraseCheckbox"] input[type="checkbox"]').should('be.checked') + cy.get('[data-cy="initiateEraseButton"]').should('be.visible') + }) + + it('should enable the feature and show initiate erase button after toggling on', () => { + cy.myIntercept('GET', /.*amt\/features.*/, { + statusCode: httpCodes.SUCCESS, + body: eventLogs.remotePlatformErase.supportedDisabled.response + }).as('get-features') + + cy.myIntercept('POST', /.*amt\/features.*/, { + statusCode: httpCodes.SUCCESS, + body: eventLogs.remotePlatformErase.supportedEnabled.response + }).as('post-features') + + navigateToRemotePlatformErase() + cy.wait('@get-features') + + cy.get('[data-cy="remoteEraseCheckbox"] input[type="checkbox"]').check({ force: true }) + cy.wait('@post-features').its('request.body.enablePlatformErase').should('eq', true) + + cy.get('[data-cy="initiateEraseButton"]').should('be.visible') + }) + + it('should disable the feature after toggling off', () => { + cy.myIntercept('GET', /.*amt\/features.*/, { + statusCode: httpCodes.SUCCESS, + body: eventLogs.remotePlatformErase.supportedEnabled.response + }).as('get-features') + + cy.myIntercept('POST', /.*amt\/features.*/, { + statusCode: httpCodes.SUCCESS, + body: eventLogs.remotePlatformErase.supportedDisabled.response + }).as('post-features') + + navigateToRemotePlatformErase() + cy.wait('@get-features') + + cy.get('[data-cy="remoteEraseCheckbox"] input[type="checkbox"]').uncheck({ force: true }) + cy.wait('@post-features').its('request.body.enablePlatformErase').should('eq', false) + + cy.get('[data-cy="initiateEraseButton"]').should('not.exist') + }) + + it('should call the remoteErase API when erase is confirmed in the dialog', () => { + cy.myIntercept('GET', /.*amt\/features.*/, { + statusCode: httpCodes.SUCCESS, + body: eventLogs.remotePlatformErase.supportedEnabled.response + }).as('get-features') + + cy.myIntercept('POST', /.*amt\/remoteErase.*/, { + statusCode: httpCodes.SUCCESS, + body: {} + }).as('post-erase') + + navigateToRemotePlatformErase() + cy.wait('@get-features') + + cy.get('[data-cy="initiateEraseButton"]').click() + + cy.get('mat-dialog-container').should('be.visible') + cy.get('mat-dialog-container').contains('button', 'Yes').click() + + cy.wait('@post-erase').its('response.statusCode').should('eq', 200) + }) + + it('should not call the remoteErase API when erase is cancelled', () => { + cy.myIntercept('GET', /.*amt\/features.*/, { + statusCode: httpCodes.SUCCESS, + body: eventLogs.remotePlatformErase.supportedEnabled.response + }).as('get-features') + + cy.myIntercept('POST', /.*amt\/remoteErase.*/, { + statusCode: httpCodes.SUCCESS, + body: {} + }).as('post-erase') + + navigateToRemotePlatformErase() + cy.wait('@get-features') + + cy.get('[data-cy="initiateEraseButton"]').click() + + cy.get('mat-dialog-container').should('be.visible') + cy.get('mat-dialog-container').contains('button', 'No').click() + + cy.get('@post-erase.all').should('have.length', 0) + }) + + it('should show error snackbar when toggling feature fails', () => { + cy.myIntercept('GET', /.*amt\/features.*/, { + statusCode: httpCodes.SUCCESS, + body: eventLogs.remotePlatformErase.supportedDisabled.response + }).as('get-features') + + cy.myIntercept('POST', /.*amt\/features.*/, { + statusCode: httpCodes.INTERNAL_SERVER_ERROR, + body: {} + }).as('post-features-error') + + navigateToRemotePlatformErase() + cy.wait('@get-features') + + cy.get('[data-cy="remoteEraseCheckbox"] input[type="checkbox"]').check({ force: true }) + cy.wait('@post-features-error') + + cy.get('mat-snack-bar-container').should('be.visible') + }) + + it('should show error snackbar when erase API fails', () => { + cy.myIntercept('GET', /.*amt\/features.*/, { + statusCode: httpCodes.SUCCESS, + body: eventLogs.remotePlatformErase.supportedEnabled.response + }).as('get-features') + + cy.myIntercept('POST', /.*amt\/remoteErase.*/, { + statusCode: httpCodes.INTERNAL_SERVER_ERROR, + body: {} + }).as('post-erase-error') + + navigateToRemotePlatformErase() + cy.wait('@get-features') + + cy.get('[data-cy="initiateEraseButton"]').click() + cy.get('mat-dialog-container').contains('button', 'Yes').click() + + cy.wait('@post-erase-error') + cy.get('mat-snack-bar-container').should('be.visible') + }) +}) diff --git a/src/app/devices/device-detail/device-detail.component.html b/src/app/devices/device-detail/device-detail.component.html index 28f60dbad..4670936b8 100644 --- a/src/app/devices/device-detail/device-detail.component.html +++ b/src/app/devices/device-detail/device-detail.component.html @@ -68,6 +68,9 @@

{{ item.name | translate }}

@case ('tls') { } + @case ('remote-platform-erase') { + + } } diff --git a/src/app/devices/device-detail/device-detail.component.ts b/src/app/devices/device-detail/device-detail.component.ts index 09c6830a1..7752c4218 100644 --- a/src/app/devices/device-detail/device-detail.component.ts +++ b/src/app/devices/device-detail/device-detail.component.ts @@ -24,6 +24,7 @@ import { GeneralComponent } from '../general/general.component' import { NetworkSettingsComponent } from '../network-settings/network-settings.component' import { environment } from 'src/environments/environment' import { TLSComponent } from '../tls/tls.component' +import { RemotePlatformEraseComponent } from '../remote-platform-erase/remote-platform-erase.component' import { TranslateModule } from '@ngx-translate/core' @Component({ @@ -57,6 +58,7 @@ import { TranslateModule } from '@ngx-translate/core' RouterLinkActive, NetworkSettingsComponent, TLSComponent, + RemotePlatformEraseComponent, TranslateModule ] }) @@ -115,6 +117,12 @@ export class DeviceDetailComponent implements OnInit { description: 'deviceDetail.certificatesDescription.value', component: 'certificates', icon: 'verified' + }, + { + name: 'deviceDetail.remotePlatformErase.value', + description: 'deviceDetail.remotePlatformEraseDescription.value', + component: 'remote-platform-erase', + icon: 'phonelink_erase' } ] diff --git a/src/app/devices/device-toolbar/device-toolbar.component.spec.ts b/src/app/devices/device-toolbar/device-toolbar.component.spec.ts index ef1b4de34..0989eb3a6 100644 --- a/src/app/devices/device-toolbar/device-toolbar.component.spec.ts +++ b/src/app/devices/device-toolbar/device-toolbar.component.spec.ts @@ -67,7 +67,7 @@ describe('DeviceToolbarComponent', () => { kvmAvailable: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', diff --git a/src/app/devices/devices.service.spec.ts b/src/app/devices/devices.service.spec.ts index e608e619e..6b2867249 100644 --- a/src/app/devices/devices.service.spec.ts +++ b/src/app/devices/devices.service.spec.ts @@ -93,7 +93,7 @@ describe('DevicesService', () => { httpsBootSupported: false, winREBootSupported: false, localPBABootSupported: false, - remoteErase: false, + remoteEraseEnabled: false, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -516,7 +516,7 @@ describe('DevicesService', () => { httpsBootSupported: false, winREBootSupported: false, localPBABootSupported: false, - remoteErase: false, + remoteEraseEnabled: false, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -533,7 +533,7 @@ describe('DevicesService', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true + enablePlatformErase: true } service.setAmtFeatures('device1', payload).subscribe((response) => { diff --git a/src/app/devices/devices.service.ts b/src/app/devices/devices.service.ts index fbdd0a555..7fd8c7aee 100644 --- a/src/app/devices/devices.service.ts +++ b/src/app/devices/devices.service.ts @@ -361,6 +361,14 @@ export class DevicesService { } } + sendRemotePlatformErase(deviceId: string, eraseMask: number): Observable { + return this.http.post(`${environment.mpsServer}/api/v1/amt/remoteErase/${deviceId}`, { eraseMask }).pipe( + catchError((err) => { + throw err + }) + ) + } + getTags(): Observable { return this.http.get(`${environment.mpsServer}/api/v1/devices/tags`).pipe( map((tags) => tags.sort(caseInsensitiveCompare)), @@ -425,7 +433,7 @@ export class DevicesService { enableSOL: true, enableIDER: true, ocr: true, - remoteErase: true + enablePlatformErase: true } ): Observable { return this.http diff --git a/src/app/devices/general/general.component.html b/src/app/devices/general/general.component.html index 5f67c3613..deaa00399 100644 --- a/src/app/devices/general/general.component.html +++ b/src/app/devices/general/general.component.html @@ -156,6 +156,16 @@ }} } +
+

{{ 'general.remotePlatformErase.value' | translate }}

+
+
+ +

{{ 'general.ideRedirection.value' | translate }}

diff --git a/src/app/devices/general/general.component.spec.ts b/src/app/devices/general/general.component.spec.ts index 4e473514f..b7bce64b9 100644 --- a/src/app/devices/general/general.component.spec.ts +++ b/src/app/devices/general/general.component.spec.ts @@ -46,7 +46,7 @@ describe('GeneralComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', diff --git a/src/app/devices/general/general.component.ts b/src/app/devices/general/general.component.ts index f48518227..09016a2c1 100644 --- a/src/app/devices/general/general.component.ts +++ b/src/app/devices/general/general.component.ts @@ -57,7 +57,7 @@ export class GeneralComponent implements OnInit { httpsBootSupported: false, winREBootSupported: false, localPBABootSupported: false, - remoteErase: false, + remoteEraseEnabled: false, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', biosBootString: '', bootString: '' } } @@ -74,7 +74,8 @@ export class GeneralComponent implements OnInit { httpsBootSupported: false, winREBootSupported: false, localPBABootSupported: false, - ocr: false + ocr: false, + enablePlatformErase: false }) public isLoading = signal(true) @@ -153,7 +154,13 @@ export class GeneralComponent implements OnInit { ], httpsBootSupported: [{ value: results.amtFeatures.httpsBootSupported, disabled: true }], winREBootSupported: [{ value: results.amtFeatures.winREBootSupported, disabled: true }], - localPBABootSupported: [{ value: results.amtFeatures.localPBABootSupported, disabled: true }] + localPBABootSupported: [{ value: results.amtFeatures.localPBABootSupported, disabled: true }], + enablePlatformErase: [ + { + value: results.amtFeatures.remoteEraseEnabled, + disabled: !(results.amtFeatures.remoteEraseSupported ?? false) + } + ] }) }) } @@ -170,8 +177,7 @@ export class GeneralComponent implements OnInit { this.isLoading.set(true) this.devicesService .setAmtFeatures(this.deviceId(), { - ...this.amtEnabledFeatures.getRawValue(), - remoteErase: this.amtFeatures.remoteErase + ...this.amtEnabledFeatures.getRawValue() } as AMTFeaturesRequest) .pipe( finalize(() => { diff --git a/src/app/devices/hardware-information/hardware-information.component.spec.ts b/src/app/devices/hardware-information/hardware-information.component.spec.ts index 8750b51f0..ef87b6354 100644 --- a/src/app/devices/hardware-information/hardware-information.component.spec.ts +++ b/src/app/devices/hardware-information/hardware-information.component.spec.ts @@ -46,7 +46,7 @@ describe('HardwareInformationComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', diff --git a/src/app/devices/kvm/kvm.component.spec.ts b/src/app/devices/kvm/kvm.component.spec.ts index b321c0e9d..8e80f051f 100644 --- a/src/app/devices/kvm/kvm.component.spec.ts +++ b/src/app/devices/kvm/kvm.component.spec.ts @@ -70,7 +70,7 @@ describe('KvmComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -92,7 +92,7 @@ describe('KvmComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -371,7 +371,7 @@ describe('KvmComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -448,7 +448,7 @@ describe('KvmComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -477,7 +477,7 @@ describe('KvmComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -522,7 +522,7 @@ describe('KvmComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -550,7 +550,7 @@ describe('KvmComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -580,7 +580,7 @@ describe('KvmComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -609,7 +609,7 @@ describe('KvmComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -638,7 +638,7 @@ describe('KvmComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -667,7 +667,7 @@ describe('KvmComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', diff --git a/src/app/devices/kvm/kvm.component.ts b/src/app/devices/kvm/kvm.component.ts index 5f52c08be..b730ad56e 100644 --- a/src/app/devices/kvm/kvm.component.ts +++ b/src/app/devices/kvm/kvm.component.ts @@ -444,7 +444,7 @@ export class KvmComponent implements OnInit, OnDestroy { enableSOL: this.amtFeatures()?.SOL ?? false, enableIDER: this.amtFeatures()?.IDER ?? false, ocr: this.amtFeatures()?.ocr ?? false, - remoteErase: this.amtFeatures()?.remoteErase ?? false + enablePlatformErase: this.amtFeatures()?.remoteEraseEnabled ?? false } return this.devicesService.setAmtFeatures(this.deviceId(), payload) } diff --git a/src/app/devices/remote-platform-erase/remote-platform-erase.component.html b/src/app/devices/remote-platform-erase/remote-platform-erase.component.html new file mode 100644 index 000000000..32ba1d753 --- /dev/null +++ b/src/app/devices/remote-platform-erase/remote-platform-erase.component.html @@ -0,0 +1,77 @@ +@if (isLoading()) { + +} +
+ + + {{ 'remotePlatformErase.title.value' | translate }} + {{ 'remotePlatformErase.description.value' | translate }} + + + + @if (isRemoteEraseSupported()) { + + {{ 'remotePlatformErase.featureEnabled.value' | translate }} + + } @else { +
+ + {{ 'remotePlatformErase.notSupported.value' | translate }} +
+ } +
+
+ + @if (isRemoteEraseSupported()) { + + + {{ 'remotePlatformErase.caps.title.value' | translate }} + {{ 'remotePlatformErase.caps.description.value' | translate }} + + + @for (cap of eraseCaps(); track cap.key; let i = $index) { +
+ +
+ {{ 'remotePlatformErase.cap.' + cap.key + '.label.value' | translate }} +

+ {{ 'remotePlatformErase.cap.' + cap.key + '.desc.value' | translate }} +

+
+
+ } +
+
+ } + + @if (remoteEraseEnabled()) { + + + {{ 'remotePlatformErase.initiateTitle.value' | translate }} + {{ 'remotePlatformErase.initiateDescription.value' | translate }} + + + + + + + } +
diff --git a/src/app/devices/remote-platform-erase/remote-platform-erase.component.scss b/src/app/devices/remote-platform-erase/remote-platform-erase.component.scss new file mode 100644 index 000000000..761fa31af --- /dev/null +++ b/src/app/devices/remote-platform-erase/remote-platform-erase.component.scss @@ -0,0 +1,8 @@ +:host { + display: block; +} + +.warn-border { + border: 1px solid var(--mat-sys-error); + border-radius: 4px; +} diff --git a/src/app/devices/remote-platform-erase/remote-platform-erase.component.spec.ts b/src/app/devices/remote-platform-erase/remote-platform-erase.component.spec.ts new file mode 100644 index 000000000..f6a3a140c --- /dev/null +++ b/src/app/devices/remote-platform-erase/remote-platform-erase.component.spec.ts @@ -0,0 +1,280 @@ +/********************************************************************* + * Copyright (c) Intel Corporation 2022 + * SPDX-License-Identifier: Apache-2.0 + **********************************************************************/ + +import { ComponentFixture, TestBed } from '@angular/core/testing' +import { RemotePlatformEraseComponent } from './remote-platform-erase.component' +import { DevicesService } from '../devices.service' +import { MatDialog } from '@angular/material/dialog' +import { MatSnackBar } from '@angular/material/snack-bar' +import { of, throwError } from 'rxjs' +import { TranslateModule } from '@ngx-translate/core' +import { AMTFeaturesResponse } from 'src/models/models' +import { parsePlatformEraseCaps, PLATFORM_ERASE_CAPABILITIES } from './remote-platform-erase.constants' + +const mockAMTFeatures: AMTFeaturesResponse = { + userConsent: 'none', + KVM: true, + SOL: true, + IDER: true, + redirection: true, + optInState: 1, + kvmAvailable: true, + httpsBootSupported: false, + ocr: false, + winREBootSupported: false, + localPBABootSupported: false, + remoteEraseEnabled: false, + remoteEraseSupported: true, + platformEraseCaps: 0x05, + pbaBootFilesPath: [], + winREBootFilesPath: { instanceID: '', biosBootString: '', bootString: '' } +} + +describe('RemotePlatformEraseComponent', () => { + let component: RemotePlatformEraseComponent + let fixture: ComponentFixture + let devicesServiceSpy: jasmine.SpyObj + let matDialogSpy: jasmine.SpyObj + let snackBarSpy: jasmine.SpyObj + + beforeEach(async () => { + devicesServiceSpy = jasmine.createSpyObj('DevicesService', [ + 'getAMTFeatures', + 'setAmtFeatures', + 'sendRemotePlatformErase' + ]) + matDialogSpy = jasmine.createSpyObj('MatDialog', ['open']) + snackBarSpy = jasmine.createSpyObj('MatSnackBar', ['open']) + + devicesServiceSpy.getAMTFeatures.and.returnValue(of({ ...mockAMTFeatures })) + devicesServiceSpy.setAmtFeatures.and.returnValue(of({ ...mockAMTFeatures })) + devicesServiceSpy.sendRemotePlatformErase.and.returnValue(of({})) + + await TestBed.configureTestingModule({ + imports: [RemotePlatformEraseComponent, TranslateModule.forRoot()], + providers: [ + { provide: DevicesService, useValue: devicesServiceSpy }, + { provide: MatDialog, useValue: matDialogSpy }, + { provide: MatSnackBar, useValue: snackBarSpy } + ] + }).compileComponents() + + fixture = TestBed.createComponent(RemotePlatformEraseComponent) + component = fixture.componentInstance + fixture.detectChanges() + }) + + it('should create', () => { + expect(component).toBeTruthy() + }) + + it('should call getAMTFeatures on init', () => { + expect(devicesServiceSpy.getAMTFeatures).toHaveBeenCalled() + }) + + it('should set isLoading to false after init completes', () => { + expect(component.isLoading()).toBeFalse() + }) + + it('should show feature-enabled status when remoteEraseEnabled is true', () => { + devicesServiceSpy.getAMTFeatures.and.returnValue(of({ ...mockAMTFeatures, remoteEraseEnabled: true })) + component.ngOnInit() + fixture.detectChanges() + const checkbox = fixture.nativeElement.querySelector('[data-cy="remoteEraseCheckbox"] input[type="checkbox"]') + expect(checkbox).not.toBeNull() + expect(checkbox.checked).toBeTrue() + }) + + it('should show feature-disabled status when remoteEraseEnabled is false', () => { + fixture.detectChanges() + const checkbox = fixture.nativeElement.querySelector('[data-cy="remoteEraseCheckbox"] input[type="checkbox"]') + expect(checkbox).not.toBeNull() + expect(checkbox.checked).toBeFalse() + }) + + it('should show error snackbar when getAMTFeatures fails', () => { + devicesServiceSpy.getAMTFeatures.and.returnValue(throwError(() => new Error('error'))) + component.ngOnInit() + expect(snackBarSpy.open).toHaveBeenCalled() + }) + + it('should open confirmation dialog when initiateErase is called', () => { + matDialogSpy.open.and.returnValue({ afterClosed: () => of(false) } as any) + component.initiateErase() + expect(matDialogSpy.open).toHaveBeenCalled() + }) + + it('should call sendRemotePlatformErase when erase is confirmed', () => { + matDialogSpy.open.and.returnValue({ afterClosed: () => of(true) } as any) + component.initiateErase() + // mockAMTFeatures.platformEraseCaps = 0x05 → secureErase(0x01) + storageDrives(0x04) + expect(devicesServiceSpy.sendRemotePlatformErase).toHaveBeenCalledWith('', 0x05) + }) + + it('should not call sendRemotePlatformErase when erase is cancelled', () => { + matDialogSpy.open.and.returnValue({ afterClosed: () => of(false) } as any) + component.initiateErase() + expect(devicesServiceSpy.sendRemotePlatformErase).not.toHaveBeenCalled() + }) + + it('should pass deselected capability bitmask to sendRemotePlatformErase', () => { + devicesServiceSpy.getAMTFeatures.and.returnValue(of({ ...mockAMTFeatures, remoteEraseEnabled: true })) + component.ngOnInit() + // uncheck secureErase (index 0) — only storageDrives (0x04) remains + component.eraseCapControl(0).setValue(false) + matDialogSpy.open.and.returnValue({ afterClosed: () => of(true) } as any) + component.initiateErase() + expect(devicesServiceSpy.sendRemotePlatformErase).toHaveBeenCalledWith('', 0x04) + }) + + it('should show success snackbar after erase succeeds', () => { + matDialogSpy.open.and.returnValue({ afterClosed: () => of(true) } as any) + component.initiateErase() + expect(snackBarSpy.open).toHaveBeenCalled() + }) + + it('should show error snackbar when sendRemotePlatformErase fails', () => { + devicesServiceSpy.sendRemotePlatformErase.and.returnValue(throwError(() => new Error('error'))) + matDialogSpy.open.and.returnValue({ afterClosed: () => of(true) } as any) + component.initiateErase() + expect(snackBarSpy.open).toHaveBeenCalled() + }) + + it('should set isRemoteEraseSupported to true when remoteEraseSupported is true', () => { + expect(component.isRemoteEraseSupported()).toBeTrue() + }) + + it('should set isRemoteEraseSupported to false when remoteEraseSupported is false', () => { + devicesServiceSpy.getAMTFeatures.and.returnValue(of({ ...mockAMTFeatures, remoteEraseSupported: false })) + component.ngOnInit() + fixture.detectChanges() + expect(component.isRemoteEraseSupported()).toBeFalse() + }) + + it('should set isRemoteEraseSupported to false when remoteEraseSupported is absent', () => { + const featuresWithoutSupported = { ...mockAMTFeatures } as Partial + delete featuresWithoutSupported.remoteEraseSupported + devicesServiceSpy.getAMTFeatures.and.returnValue(of(featuresWithoutSupported as AMTFeaturesResponse)) + component.ngOnInit() + fixture.detectChanges() + expect(component.isRemoteEraseSupported()).toBeFalse() + }) + + it('should set isLoading to true during initiateErase', () => { + devicesServiceSpy.sendRemotePlatformErase.and.returnValue(of({})) + matDialogSpy.open.and.returnValue({ afterClosed: () => of(true) } as any) + component.initiateErase() + // isLoading is set true before the observable completes + expect(devicesServiceSpy.sendRemotePlatformErase).toHaveBeenCalled() + }) + + it('should set isLoading to false after initiateErase fails', () => { + devicesServiceSpy.sendRemotePlatformErase.and.returnValue(throwError(() => new Error('erase failed'))) + matDialogSpy.open.and.returnValue({ afterClosed: () => of(true) } as any) + component.initiateErase() + expect(component.isLoading()).toBeFalse() + }) + + it('should show initiate erase button when remoteEraseEnabled is true', () => { + devicesServiceSpy.getAMTFeatures.and.returnValue(of({ ...mockAMTFeatures, remoteEraseEnabled: true })) + component.ngOnInit() + fixture.detectChanges() + const button = fixture.nativeElement.querySelector('[data-cy="initiateEraseButton"]') + expect(button).not.toBeNull() + expect(button.disabled).toBeFalse() + }) + + it('should not show initiate erase button when feature is disabled', () => { + // mockAMTFeatures has remoteEraseEnabled: false but remoteEraseSupported: true + fixture.detectChanges() + const button = fixture.nativeElement.querySelector('[data-cy="initiateEraseButton"]') + expect(button).toBeNull() + }) + + describe('parsePlatformEraseCaps', () => { + it('should return all capabilities as not supported when bitmask is 0', () => { + const result = parsePlatformEraseCaps(0) + expect(result.every((c) => !c.supported)).toBeTrue() + expect(result.length).toBe(PLATFORM_ERASE_CAPABILITIES.length) + }) + + it('should correctly parse individual bits', () => { + PLATFORM_ERASE_CAPABILITIES.forEach((cap) => { + const result = parsePlatformEraseCaps(cap.bit) + const found = result.find((c) => c.key === cap.key) + expect(found?.supported).toBeTrue() + }) + }) + + it('should correctly parse combined bitmask 0x05 (bits 0 and 2)', () => { + const result = parsePlatformEraseCaps(0x05) + const byKey = Object.fromEntries(result.map((c) => [c.key, c.supported])) + expect(byKey['secureErase']).toBeTrue() + expect(byKey['ecStorage']).toBeFalse() + expect(byKey['storageDrives']).toBeTrue() + expect(byKey['meRegion']).toBeFalse() + }) + + it('should return all capabilities as supported when all bits are set', () => { + const allBits = PLATFORM_ERASE_CAPABILITIES.reduce((acc, c) => acc | c.bit, 0) + const result = parsePlatformEraseCaps(allBits) + expect(result.every((c) => c.supported)).toBeTrue() + }) + }) + + it('should populate eraseCaps from platformEraseCaps bitmask on init', () => { + expect(component.eraseCaps().length).toBe(PLATFORM_ERASE_CAPABILITIES.length) + }) + + it('should show capabilities card when remoteEraseSupported is true', () => { + devicesServiceSpy.getAMTFeatures.and.returnValue( + of({ ...mockAMTFeatures, remoteEraseEnabled: true, platformEraseCaps: 0x05 }) + ) + component.ngOnInit() + fixture.detectChanges() + const capItems = fixture.nativeElement.querySelectorAll('[data-cy="eraseCapItem"]') + expect(capItems.length).toBe(PLATFORM_ERASE_CAPABILITIES.length) + }) + + it('should show a checkbox for each capability, disabled for unsupported ones', () => { + devicesServiceSpy.getAMTFeatures.and.returnValue(of({ ...mockAMTFeatures, remoteEraseEnabled: true })) + component.ngOnInit() + fixture.detectChanges() + const checkboxes = fixture.nativeElement.querySelectorAll('[data-cy="eraseCapCheckbox"]') + expect(checkboxes.length).toBe(PLATFORM_ERASE_CAPABILITIES.length) + // ecStorage (index 1) and meRegion (index 3) not supported — always disabled + expect(component.eraseCapControl(1).disabled).toBeTrue() + expect(component.eraseCapControl(3).disabled).toBeTrue() + // secureErase (index 0) and storageDrives (index 2) supported + feature on — enabled + expect(component.eraseCapControl(0).disabled).toBeFalse() + expect(component.eraseCapControl(2).disabled).toBeFalse() + }) + + it('should disable all capability checkboxes when remoteEraseEnabled is false', () => { + // mockAMTFeatures.remoteEraseEnabled = false — all caps disabled regardless of support + fixture.detectChanges() + PLATFORM_ERASE_CAPABILITIES.forEach((_, i) => { + expect(component.eraseCapControl(i).disabled).toBeTrue() + }) + }) + + it('should enable only supported capability checkboxes when remoteEraseEnabled is true', () => { + devicesServiceSpy.getAMTFeatures.and.returnValue(of({ ...mockAMTFeatures, remoteEraseEnabled: true })) + component.ngOnInit() + // 0x05: secureErase(0) + storageDrives(2) supported + expect(component.eraseCapControl(0).disabled).toBeFalse() + expect(component.eraseCapControl(1).disabled).toBeTrue() // ecStorage not supported + expect(component.eraseCapControl(2).disabled).toBeFalse() + expect(component.eraseCapControl(3).disabled).toBeTrue() // meRegion not supported + }) + + it('should default eraseCaps to all-unsupported when platformEraseCaps is absent', () => { + const featuresWithoutCaps = { ...mockAMTFeatures } as Partial + delete featuresWithoutCaps.platformEraseCaps + devicesServiceSpy.getAMTFeatures.and.returnValue(of(featuresWithoutCaps as AMTFeaturesResponse)) + component.ngOnInit() + expect(component.eraseCaps().every((c) => !c.supported)).toBeTrue() + }) +}) diff --git a/src/app/devices/remote-platform-erase/remote-platform-erase.component.ts b/src/app/devices/remote-platform-erase/remote-platform-erase.component.ts new file mode 100644 index 000000000..b67df1208 --- /dev/null +++ b/src/app/devices/remote-platform-erase/remote-platform-erase.component.ts @@ -0,0 +1,176 @@ +/********************************************************************* + * Copyright (c) Intel Corporation 2022 + * SPDX-License-Identifier: Apache-2.0 + **********************************************************************/ + +import { Component, OnInit, inject, signal, input } from '@angular/core' +import { FormArray, FormBuilder, FormControl, ReactiveFormsModule } from '@angular/forms' +import { MatCardModule } from '@angular/material/card' +import { MatCheckboxModule } from '@angular/material/checkbox' +import { MatProgressBar } from '@angular/material/progress-bar' +import { MatIcon } from '@angular/material/icon' +import { MatButton } from '@angular/material/button' +import { MatTooltipModule } from '@angular/material/tooltip' +import { MatDialog } from '@angular/material/dialog' +import { MatSnackBar } from '@angular/material/snack-bar' +import { finalize, throwError } from 'rxjs' +import { DevicesService } from '../devices.service' +import { AMTFeaturesRequest, AMTFeaturesResponse } from 'src/models/models' +import { + ParsedPlatformEraseCapability, + parsePlatformEraseCaps, + PLATFORM_ERASE_CAPABILITIES +} from './remote-platform-erase.constants' +import SnackbarDefaults from 'src/app/shared/config/snackBarDefault' +import { AreYouSureDialogComponent } from 'src/app/shared/are-you-sure/are-you-sure.component' +import { TranslateModule, TranslateService } from '@ngx-translate/core' + +@Component({ + selector: 'app-remote-platform-erase', + templateUrl: './remote-platform-erase.component.html', + styleUrl: './remote-platform-erase.component.scss', + imports: [ + MatProgressBar, + MatCardModule, + MatCheckboxModule, + ReactiveFormsModule, + MatIcon, + MatButton, + MatTooltipModule, + TranslateModule + ] +}) +export class RemotePlatformEraseComponent implements OnInit { + private readonly devicesService = inject(DevicesService) + private readonly snackBar = inject(MatSnackBar) + private readonly matDialog = inject(MatDialog) + private readonly fb = inject(FormBuilder) + private readonly translate = inject(TranslateService) + + public readonly deviceId = input('') + public isLoading = signal(true) + public isRemoteEraseSupported = signal(false) + public remoteEraseEnabled = signal(false) + public eraseCaps = signal([]) + public eraseCapsArray: FormArray> = this.fb.array([]) + + public amtFeatures: AMTFeaturesResponse = { + KVM: false, + SOL: false, + IDER: false, + kvmAvailable: false, + redirection: false, + optInState: 0, + userConsent: 'none', + ocr: false, + httpsBootSupported: false, + winREBootSupported: false, + localPBABootSupported: false, + remoteEraseEnabled: false, + pbaBootFilesPath: [], + winREBootFilesPath: { instanceID: '', biosBootString: '', bootString: '' } + } + + ngOnInit(): void { + this.devicesService + .getAMTFeatures(this.deviceId()) + .pipe( + finalize(() => { + this.isLoading.set(false) + }) + ) + .subscribe({ + next: (features) => { + this.amtFeatures = features + const supported = features.remoteEraseSupported ?? false + this.isRemoteEraseSupported.set(supported) + this.remoteEraseEnabled.set(features.remoteEraseEnabled) + const caps = parsePlatformEraseCaps(features.platformEraseCaps ?? 0) + this.eraseCaps.set(caps) + this.eraseCapsArray = this.fb.array( + caps.map((cap) => this.fb.control({ value: cap.supported, disabled: !cap.supported })) + ) + this.updateCapControlStates(features.remoteEraseEnabled) + }, + error: (err) => { + const msg: string = this.translate.instant('remotePlatformErase.errorLoad.value') + this.snackBar.open(msg, undefined, SnackbarDefaults.defaultError) + return throwError(() => err) + } + }) + } + + eraseCapControl(index: number): FormControl { + return this.eraseCapsArray.at(index) as FormControl + } + + toggleFeature(enabled: boolean): void { + const payload: AMTFeaturesRequest = { + userConsent: this.amtFeatures.userConsent, + enableKVM: this.amtFeatures.KVM, + enableSOL: this.amtFeatures.SOL, + enableIDER: this.amtFeatures.IDER, + ocr: this.amtFeatures.ocr, + enablePlatformErase: enabled + } + this.isLoading.set(true) + this.devicesService + .setAmtFeatures(this.deviceId(), payload) + .pipe(finalize(() => this.isLoading.set(false))) + .subscribe({ + next: (features) => { + this.amtFeatures = features + this.remoteEraseEnabled.set(features.remoteEraseEnabled) + this.updateCapControlStates(features.remoteEraseEnabled) + }, + error: (err) => { + this.remoteEraseEnabled.set(!enabled) + const msg: string = this.translate.instant('remotePlatformErase.updateError.value') + this.snackBar.open(msg, undefined, SnackbarDefaults.defaultError) + return throwError(() => err) + } + }) + } + + private updateCapControlStates(featureEnabled: boolean): void { + this.eraseCaps().forEach((cap, i) => { + const ctrl = this.eraseCapsArray.at(i) + if (!featureEnabled || !cap.supported) { + ctrl.disable({ emitEvent: false }) + } else { + ctrl.enable({ emitEvent: false }) + } + }) + } + + initiateErase(): void { + const dialogRef = this.matDialog.open(AreYouSureDialogComponent) + dialogRef.afterClosed().subscribe((result) => { + if (result === true) { + const eraseMask = PLATFORM_ERASE_CAPABILITIES.reduce( + (acc, cap, i) => ((this.eraseCapsArray.at(i)?.value ?? false) ? acc | cap.bit : acc), + 0 + ) + this.isLoading.set(true) + this.devicesService + .sendRemotePlatformErase(this.deviceId(), eraseMask) + .pipe( + finalize(() => { + this.isLoading.set(false) + }) + ) + .subscribe({ + next: () => { + const msg: string = this.translate.instant('remotePlatformErase.eraseSuccess.value') + this.snackBar.open(msg, undefined, SnackbarDefaults.defaultSuccess) + }, + error: (err) => { + const msg: string = this.translate.instant('remotePlatformErase.eraseError.value') + this.snackBar.open(msg, undefined, SnackbarDefaults.defaultError) + return throwError(() => err) + } + }) + } + }) + } +} diff --git a/src/app/devices/remote-platform-erase/remote-platform-erase.constants.ts b/src/app/devices/remote-platform-erase/remote-platform-erase.constants.ts new file mode 100644 index 000000000..7015b082f --- /dev/null +++ b/src/app/devices/remote-platform-erase/remote-platform-erase.constants.ts @@ -0,0 +1,34 @@ +/********************************************************************* + * Copyright (c) Intel Corporation 2022 + * SPDX-License-Identifier: Apache-2.0 + **********************************************************************/ + +/** + * Bitmask definitions for AMT_BootCapabilities.PlatformErase. + * Capabilities vary by AMT/CSME version. + * Reference: https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/ + * default.htm?turl=HTMLDocuments%2FWS-Management_Class_Reference%2FAMT_BootCapabilities.htm%23PlatformErase + */ +export interface PlatformEraseCapability { + bit: number + key: string +} + +export const PLATFORM_ERASE_CAPABILITIES: PlatformEraseCapability[] = [ + { bit: 0x01, key: 'secureErase' }, + { bit: 0x02, key: 'ecStorage' }, + { bit: 0x04, key: 'storageDrives' }, + { bit: 0x08, key: 'meRegion' } +] + +export interface ParsedPlatformEraseCapability { + key: string + supported: boolean +} + +export function parsePlatformEraseCaps(bitmask: number): ParsedPlatformEraseCapability[] { + return PLATFORM_ERASE_CAPABILITIES.map((cap) => ({ + key: cap.key, + supported: (bitmask & cap.bit) !== 0 + })) +} diff --git a/src/app/devices/sol/sol.component.spec.ts b/src/app/devices/sol/sol.component.spec.ts index 2b8a2f90d..3b527c150 100644 --- a/src/app/devices/sol/sol.component.spec.ts +++ b/src/app/devices/sol/sol.component.spec.ts @@ -63,7 +63,7 @@ describe('SolComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -85,7 +85,7 @@ describe('SolComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -273,7 +273,7 @@ describe('SolComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -320,7 +320,7 @@ describe('SolComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -361,7 +361,7 @@ describe('SolComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -388,7 +388,7 @@ describe('SolComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -417,7 +417,7 @@ describe('SolComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -447,7 +447,7 @@ describe('SolComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -476,7 +476,7 @@ describe('SolComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', @@ -505,7 +505,7 @@ describe('SolComponent', () => { ocr: true, winREBootSupported: true, localPBABootSupported: true, - remoteErase: true, + remoteEraseEnabled: true, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', diff --git a/src/app/devices/sol/sol.component.ts b/src/app/devices/sol/sol.component.ts index 5f8ee0159..e6d5ae6ce 100644 --- a/src/app/devices/sol/sol.component.ts +++ b/src/app/devices/sol/sol.component.ts @@ -206,7 +206,7 @@ export class SolComponent implements OnInit, OnDestroy { enableSOL: true, enableIDER: this.amtFeatures()?.IDER ?? false, ocr: this.amtFeatures()?.ocr ?? false, - remoteErase: this.amtFeatures()?.remoteErase ?? false + enablePlatformErase: this.amtFeatures()?.remoteEraseEnabled ?? false } return this.devicesService.setAmtFeatures(this.deviceId(), payload) } diff --git a/src/app/devices/user-consent.service.spec.ts b/src/app/devices/user-consent.service.spec.ts index 045695a34..c3f286747 100644 --- a/src/app/devices/user-consent.service.spec.ts +++ b/src/app/devices/user-consent.service.spec.ts @@ -79,7 +79,7 @@ describe('UserConsentService', () => { httpsBootSupported: false, winREBootSupported: false, localPBABootSupported: false, - remoteErase: false, + remoteEraseEnabled: false, pbaBootFilesPath: [], winREBootFilesPath: { instanceID: '', diff --git a/src/assets/i18n/ar.json b/src/assets/i18n/ar.json index 2ec49f0a8..3ab9618d0 100644 --- a/src/assets/i18n/ar.json +++ b/src/assets/i18n/ar.json @@ -1419,6 +1419,10 @@ "description": "تسمية لـ HTTPS تشغيل الشبكة", "value": "HTTPS تشغيل الشبكة:" }, + "general.remotePlatformErase": { + "description": "تسمية لمسح المنصة عن بُعد", + "value": "مسح المنصة عن بُعد:" + }, "general.ideRedirection": { "description": "تسمية لإعادة توجيه IDE", "value": "إعادة توجيه IDE:" @@ -2808,5 +2812,69 @@ "common.noData": { "value": "لا توجد بيانات متاحة", "description": "رسالة عند عدم توفر بيانات" + }, + "deviceDetail.remotePlatformErase": { + "description": "اسم الفئة لمسح المنصة عن بُعد", + "value": "مسح المنصة عن بُعد" + }, + "deviceDetail.remotePlatformEraseDescription": { + "description": "وصف لمسح المنصة عن بُعد", + "value": "مسح بيانات المنصة بشكل آمن" + }, + "remotePlatformErase.title": { + "description": "عنوان بطاقة ميزة مسح المنصة عن بُعد", + "value": "مسح المنصة عن بُعد" + }, + "remotePlatformErase.description": { + "description": "عنوان فرعي لبطاقة ميزة مسح المنصة عن بُعد", + "value": "تمكين أو تعطيل ميزة مسح المنصة عن بُعد على هذا الجهاز" + }, + "remotePlatformErase.warning": { + "description": "رسالة تحذير حول تمكين مسح المنصة عن بُعد", + "value": "تمكين هذه الميزة يسمح بمسح بيانات المنصة عن بُعد. استخدمها بحذر." + }, + "remotePlatformErase.enableFeature": { + "description": "تسمية خانة الاختيار لتمكين مسح المنصة عن بُعد", + "value": "تمكين مسح المنصة عن بُعد" + }, + "remotePlatformErase.initiateTitle": { + "description": "عنوان بطاقة إجراء بدء المسح", + "value": "بدء المسح عن بُعد" + }, + "remotePlatformErase.initiateDescription": { + "description": "عنوان فرعي لبطاقة إجراء بدء المسح", + "value": "مسح جميع البيانات المخزنة على هذه المنصة نهائيًا" + }, + "remotePlatformErase.initiateWarning": { + "description": "تحذير قبل بدء مسح المنصة عن بُعد", + "value": "هذا الإجراء لا يمكن التراجع عنه. سيتم مسح جميع بيانات المنصة نهائيًا." + }, + "remotePlatformErase.initiateButton": { + "description": "تسمية زر بدء مسح المنصة عن بُعد", + "value": "بدء المسح عن بُعد" + }, + "remotePlatformErase.updateSuccess": { + "description": "رسالة النجاح عند تبديل ميزة مسح المنصة عن بُعد", + "value": "تم تحديث ميزة مسح المنصة عن بُعد بنجاح" + }, + "remotePlatformErase.updateError": { + "description": "رسالة خطأ عند فشل تحديث ميزة مسح المنصة عن بُعد", + "value": "فشل تحديث ميزة مسح المنصة عن بُعد" + }, + "remotePlatformErase.eraseSuccess": { + "description": "رسالة نجاح بعد بدء مسح المنصة عن بُعد", + "value": "تم بدء مسح المنصة عن بُعد بنجاح" + }, + "remotePlatformErase.eraseError": { + "description": "رسالة خطأ عند فشل بدء مسح المنصة عن بُعد", + "value": "فشل بدء مسح المنصة عن بُعد" + }, + "remotePlatformErase.errorLoad": { + "description": "رسالة خطأ عند فشل تحميل حالة ميزة مسح المنصة عن بُعد", + "value": "فشل تحميل حالة ميزة مسح المنصة عن بُعد" + }, + "remotePlatformErase.notSupported": { + "description": "الرسالة المعروضة عندما لا يدعم الجهاز مسح المنصة عن بُعد", + "value": "مسح المنصة عن بُعد غير مدعوم" } } diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index 645d61455..bf93e8860 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -1419,6 +1419,10 @@ "description": "Bezeichnung für HTTPS-Netzwerkstart", "value": "HTTPS-Netzwerkstart:" }, + "general.remotePlatformErase": { + "description": "Bezeichnung für Remote-Plattformlöschung", + "value": "Remote-Plattformlöschung:" + }, "general.ideRedirection": { "description": "Bezeichnung für IDE-Umleitung", "value": "IDE-Umleitung:" @@ -2808,5 +2812,69 @@ "common.noData": { "value": "Keine Daten verfügbar", "description": "Meldung, wenn keine Daten verfügbar sind" + }, + "deviceDetail.remotePlatformErase": { + "description": "Kategoriename für Remote-Plattformlöschung", + "value": "Remote-Plattformlöschung" + }, + "deviceDetail.remotePlatformEraseDescription": { + "description": "Beschreibung für Remote-Plattformlöschung", + "value": "Plattformdaten sicher löschen" + }, + "remotePlatformErase.title": { + "description": "Titel der Funktionskarte für Remote-Plattformlöschung", + "value": "Remote-Plattformlöschung" + }, + "remotePlatformErase.description": { + "description": "Untertitel der Funktionskarte für Remote-Plattformlöschung", + "value": "Remote-Plattformlöschungsfunktion für dieses Gerät aktivieren oder deaktivieren" + }, + "remotePlatformErase.warning": { + "description": "Warnmeldung zur Aktivierung der Remote-Plattformlöschung", + "value": "Das Aktivieren dieser Funktion ermöglicht die Remote-Löschung von Plattformdaten. Mit Vorsicht verwenden." + }, + "remotePlatformErase.enableFeature": { + "description": "Bezeichnung der Checkbox zur Aktivierung der Remote-Plattformlöschung", + "value": "Remote-Plattformlöschung aktivieren" + }, + "remotePlatformErase.initiateTitle": { + "description": "Titel der Aktionskarte zum Einleiten der Löschung", + "value": "Remote-Löschung einleiten" + }, + "remotePlatformErase.initiateDescription": { + "description": "Untertitel der Aktionskarte zum Einleiten der Löschung", + "value": "Alle auf dieser Plattform gespeicherten Daten dauerhaft löschen" + }, + "remotePlatformErase.initiateWarning": { + "description": "Warnung vor dem Einleiten der Remote-Plattformlöschung", + "value": "Diese Aktion ist unwiderruflich. Alle Plattformdaten werden dauerhaft gelöscht." + }, + "remotePlatformErase.initiateButton": { + "description": "Schaltflächenbeschriftung zum Einleiten der Remote-Plattformlöschung", + "value": "Remote-Löschung einleiten" + }, + "remotePlatformErase.updateSuccess": { + "description": "Erfolgsmeldung beim Umschalten der Remote-Plattformlöschungsfunktion", + "value": "Remote-Plattformlöschungsfunktion erfolgreich aktualisiert" + }, + "remotePlatformErase.updateError": { + "description": "Fehlermeldung wenn die Aktualisierung der Remote-Plattformlöschungsfunktion fehlschlägt", + "value": "Fehler beim Aktualisieren der Remote-Plattformlöschungsfunktion" + }, + "remotePlatformErase.eraseSuccess": { + "description": "Erfolgsmeldung nach dem Einleiten der Remote-Plattformlöschung", + "value": "Remote-Plattformlöschung erfolgreich eingeleitet" + }, + "remotePlatformErase.eraseError": { + "description": "Fehlermeldung wenn die Remote-Plattformlöschung nicht eingeleitet werden kann", + "value": "Fehler beim Einleiten der Remote-Plattformlöschung" + }, + "remotePlatformErase.errorLoad": { + "description": "Fehlermeldung beim Laden des Status der Remote-Plattformlöschungsfunktion", + "value": "Fehler beim Laden des Status der Remote-Plattformlöschungsfunktion" + }, + "remotePlatformErase.notSupported": { + "description": "Meldung wenn Remote-Plattformlöschung auf dem Gerät nicht unterstützt wird", + "value": "Remote-Plattformlöschung wird nicht unterstützt" } } diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 934976fbc..912dde123 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -1041,6 +1041,118 @@ "description": "Description for TLS settings", "value": "View TLS configuration" }, + "deviceDetail.remotePlatformErase": { + "description": "Category name for Remote Platform Erase", + "value": "Remote Platform Erase" + }, + "deviceDetail.remotePlatformEraseDescription": { + "description": "Description for Remote Platform Erase", + "value": "Securely erase platform data" + }, + "remotePlatformErase.title": { + "description": "Title for the Remote Platform Erase feature card", + "value": "Remote Platform Erase" + }, + "remotePlatformErase.description": { + "description": "Subtitle for the Remote Platform Erase feature card", + "value": "Manage Remote Platform Erase for this device. Enable or disable this feature on the AMT Features tab." + }, + "remotePlatformErase.warning": { + "description": "Warning message about enabling Remote Platform Erase", + "value": "Enabling this feature allows remote erasure of platform data. Use with caution." + }, + "remotePlatformErase.featureEnabled": { + "description": "Status message shown when Remote Platform Erase is enabled", + "value": "Feature is enabled" + }, + "remotePlatformErase.featureDisabled": { + "description": "Status message shown when Remote Platform Erase is disabled", + "value": "Feature is disabled. Enable it on the AMT Features tab." + }, + "remotePlatformErase.initiateTitle": { + "description": "Title for the initiate erase action card", + "value": "Initiate Remote Erase" + }, + "remotePlatformErase.initiateDescription": { + "description": "Subtitle for the initiate erase action card", + "value": "Permanently erase all data stored on this platform" + }, + "remotePlatformErase.initiateWarning": { + "description": "Warning before initiating a remote platform erase", + "value": "This action is irreversible. All platform data will be permanently erased." + }, + "remotePlatformErase.initiateButton": { + "description": "Button label to initiate Remote Platform Erase", + "value": "Initiate Remote Erase" + }, + "remotePlatformErase.initiateDisabledTooltip": { + "description": "Tooltip shown on the initiate erase button when the feature is disabled", + "value": "Enable Remote Platform Erase on the AMT Features tab first" + }, + "remotePlatformErase.updateSuccess": { + "description": "Success message when Remote Platform Erase feature is toggled", + "value": "Remote Platform Erase feature updated successfully" + }, + "remotePlatformErase.updateError": { + "description": "Error message when Remote Platform Erase feature update fails", + "value": "Failed to update Remote Platform Erase feature" + }, + "remotePlatformErase.eraseSuccess": { + "description": "Success message after initiating Remote Platform Erase", + "value": "Remote Platform Erase initiated successfully" + }, + "remotePlatformErase.eraseError": { + "description": "Error message when Remote Platform Erase fails to initiate", + "value": "Failed to initiate Remote Platform Erase" + }, + "remotePlatformErase.errorLoad": { + "description": "Error message when loading Remote Platform Erase feature status fails", + "value": "Failed to load Remote Platform Erase feature status" + }, + "remotePlatformErase.notSupported": { + "description": "Message shown when Remote Platform Erase is not supported on the device", + "value": "Remote Platform Erase is not supported" + }, + "remotePlatformErase.caps.title": { + "description": "Title for the platform erase capabilities card", + "value": "Erase Capabilities" + }, + "remotePlatformErase.caps.description": { + "description": "Subtitle for the platform erase capabilities card", + "value": "Select which capabilities to include in the erase operation. Unsupported capabilities cannot be selected." + }, + "remotePlatformErase.cap.secureErase.label": { + "description": "Label for the Secure Erase capability", + "value": "Secure Erase" + }, + "remotePlatformErase.cap.secureErase.desc": { + "description": "Description for the Secure Erase capability", + "value": "Secure erase of self-encrypting storage via device security commands (ATA, NVMe, TCG)" + }, + "remotePlatformErase.cap.ecStorage.label": { + "description": "Label for the Embedded Controller Storage capability", + "value": "EC Storage Erase" + }, + "remotePlatformErase.cap.ecStorage.desc": { + "description": "Description for the Embedded Controller Storage erase capability", + "value": "Erase Embedded Controller (EC) non-volatile storage" + }, + "remotePlatformErase.cap.storageDrives.label": { + "description": "Label for the Storage Drives erase capability", + "value": "Storage Drive Erase" + }, + "remotePlatformErase.cap.storageDrives.desc": { + "description": "Description for the Storage Drives erase capability", + "value": "Erase all connected storage drives" + }, + "remotePlatformErase.cap.meRegion.label": { + "description": "Label for the ME/CSME Region erase capability", + "value": "ME/CSME Region Erase" + }, + "remotePlatformErase.cap.meRegion.desc": { + "description": "Description for the ME/CSME Region erase capability", + "value": "Erase Management Engine (CSME) storage region" + }, "devices.actions.deactivate": { "description": "Tooltip for deactivating/removing a device", "value": "Deactivate the device" @@ -1583,6 +1695,10 @@ "description": "Label for HTTPS Network boot", "value": "HTTPS Network boot:" }, + "general.remotePlatformErase": { + "description": "Label for Remote Platform Erase", + "value": "Remote Platform Erase:" + }, "general.ideRedirection": { "description": "Label for IDE Redirection", "value": "IDE Redirection:" diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index f0109ecf5..f101ea5d9 100644 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -1419,6 +1419,10 @@ "description": "Etiqueta para HTTPS Arranque de red", "value": "HTTPS Arranque de red:" }, + "general.remotePlatformErase": { + "description": "Etiqueta para el borrado remoto de plataforma", + "value": "Borrado remoto de plataforma:" + }, "general.ideRedirection": { "description": "Etiqueta para la redirección IDE", "value": "Redirección IDE:" @@ -2808,5 +2812,69 @@ "common.noData": { "value": "No hay datos disponibles", "description": "Mensaje cuando no hay datos disponibles" + }, + "deviceDetail.remotePlatformErase": { + "description": "Nombre de categoría para el borrado remoto de plataforma", + "value": "Borrado remoto de plataforma" + }, + "deviceDetail.remotePlatformEraseDescription": { + "description": "Descripción para el borrado remoto de plataforma", + "value": "Borrar datos de plataforma de forma segura" + }, + "remotePlatformErase.title": { + "description": "Título para la tarjeta de función de borrado remoto de plataforma", + "value": "Borrado remoto de plataforma" + }, + "remotePlatformErase.description": { + "description": "Subtítulo para la tarjeta de función de borrado remoto de plataforma", + "value": "Habilitar o deshabilitar la función de borrado remoto de plataforma en este dispositivo" + }, + "remotePlatformErase.warning": { + "description": "Mensaje de advertencia sobre la habilitación del borrado remoto de plataforma", + "value": "Habilitar esta función permite el borrado remoto de datos de la plataforma. Úsela con precaución." + }, + "remotePlatformErase.enableFeature": { + "description": "Etiqueta de la casilla para habilitar el borrado remoto de plataforma", + "value": "Habilitar borrado remoto de plataforma" + }, + "remotePlatformErase.initiateTitle": { + "description": "Título de la tarjeta de acción para iniciar el borrado", + "value": "Iniciar borrado remoto" + }, + "remotePlatformErase.initiateDescription": { + "description": "Subtítulo de la tarjeta de acción para iniciar el borrado", + "value": "Borrar permanentemente todos los datos almacenados en esta plataforma" + }, + "remotePlatformErase.initiateWarning": { + "description": "Advertencia antes de iniciar un borrado remoto de plataforma", + "value": "Esta acción es irreversible. Todos los datos de la plataforma se borrarán permanentemente." + }, + "remotePlatformErase.initiateButton": { + "description": "Etiqueta del botón para iniciar el borrado remoto de plataforma", + "value": "Iniciar borrado remoto" + }, + "remotePlatformErase.updateSuccess": { + "description": "Mensaje de éxito al activar o desactivar la función de borrado remoto de plataforma", + "value": "Función de borrado remoto de plataforma actualizada correctamente" + }, + "remotePlatformErase.updateError": { + "description": "Mensaje de error cuando falla la actualización de la función de borrado remoto de plataforma", + "value": "Error al actualizar la función de borrado remoto de plataforma" + }, + "remotePlatformErase.eraseSuccess": { + "description": "Mensaje de éxito tras iniciar el borrado remoto de plataforma", + "value": "Borrado remoto de plataforma iniciado correctamente" + }, + "remotePlatformErase.eraseError": { + "description": "Mensaje de error cuando el borrado remoto de plataforma no puede iniciarse", + "value": "Error al iniciar el borrado remoto de plataforma" + }, + "remotePlatformErase.errorLoad": { + "description": "Mensaje de error cuando falla la carga del estado de la función de borrado remoto de plataforma", + "value": "Error al cargar el estado de la función de borrado remoto de plataforma" + }, + "remotePlatformErase.notSupported": { + "description": "Mensaje que se muestra cuando el borrado remoto de plataforma no es compatible con el dispositivo", + "value": "El borrado remoto de plataforma no es compatible" } } diff --git a/src/assets/i18n/fi.json b/src/assets/i18n/fi.json index bf52b2393..c315e1126 100644 --- a/src/assets/i18n/fi.json +++ b/src/assets/i18n/fi.json @@ -1419,6 +1419,10 @@ "description": "HTTPS-verkon käynnistysmerkki", "value": "HTTPS-verkkokäynnistys:" }, + "general.remotePlatformErase": { + "description": "Etäalustan pyyhinnän etiketti", + "value": "Etäalustan pyyhintä:" + }, "general.ideRedirection": { "description": "IDE-uudelleenohjauksen etiketti", "value": "IDE-uudelleenohjaus:" @@ -2808,5 +2812,69 @@ "common.noData": { "value": "Ei saatavilla olevaa dataa", "description": "Viesti, kun dataa ei ole saatavilla" + }, + "deviceDetail.remotePlatformErase": { + "description": "Etäalustan pyyhinnän kategorianimeke", + "value": "Etäalustan pyyhintä" + }, + "deviceDetail.remotePlatformEraseDescription": { + "description": "Etäalustan pyyhinnän kuvaus", + "value": "Tyhjennä alustan tiedot turvallisesti" + }, + "remotePlatformErase.title": { + "description": "Etäalustan pyyhintäominaisuuden kortin otsikko", + "value": "Etäalustan pyyhintä" + }, + "remotePlatformErase.description": { + "description": "Etäalustan pyyhintäominaisuuden kortin alaotsikko", + "value": "Ota etäalustan pyyhintä käyttöön tai poista se käytöstä tässä laitteessa" + }, + "remotePlatformErase.warning": { + "description": "Varoitusviesti etäalustan pyyhinnän käyttöönotosta", + "value": "Tämän ominaisuuden ottaminen käyttöön mahdollistaa alustan tietojen etäpyyhinnan. Käytä varoen." + }, + "remotePlatformErase.enableFeature": { + "description": "Etäalustan pyyhinnän käyttöönotto-valintaruudun etiketti", + "value": "Ota etäalustan pyyhintä käyttöön" + }, + "remotePlatformErase.initiateTitle": { + "description": "Pyyhinnan käynnistyskortin otsikko", + "value": "Käynnistä etäpyyhintä" + }, + "remotePlatformErase.initiateDescription": { + "description": "Pyyhinnan käynnistyskortin alaotsikko", + "value": "Tyhjennä pysyvästi kaikki tähän alustaan tallennetut tiedot" + }, + "remotePlatformErase.initiateWarning": { + "description": "Varoitus ennen etäalustan pyyhinnan aloittamista", + "value": "Tämä toimenpide on peruuttamaton. Kaikki alustan tiedot poistetaan pysyvästi." + }, + "remotePlatformErase.initiateButton": { + "description": "Etäalustan pyyhinnan käynnistyspainikkeen etiketti", + "value": "Käynnistä etäpyyhintä" + }, + "remotePlatformErase.updateSuccess": { + "description": "Onnistumisviesti etäalustan pyyhintäominaisuuden vaihtamisesta", + "value": "Etäalustan pyyhintäominaisuus päivitetty onnistuneesti" + }, + "remotePlatformErase.updateError": { + "description": "Virheviesti etäalustan pyyhintäominaisuuden päivityksen epäonnistuessa", + "value": "Etäalustan pyyhintäominaisuuden päivitys epäonnistui" + }, + "remotePlatformErase.eraseSuccess": { + "description": "Onnistumisviesti etäalustan pyyhinnan aloittamisen jälkeen", + "value": "Etäalustan pyyhintä käynnistetty onnistuneesti" + }, + "remotePlatformErase.eraseError": { + "description": "Virheviesti etäalustan pyyhinnan käynnistyksen epäonnistuessa", + "value": "Etäalustan pyyhinnan käynnistys epäonnistui" + }, + "remotePlatformErase.errorLoad": { + "description": "Virheviesti etäalustan pyyhintäominaisuuden tilan latauksen epäonnistuessa", + "value": "Etäalustan pyyhintäominaisuuden tilan lataus epäonnistui" + }, + "remotePlatformErase.notSupported": { + "description": "Viesti laitteen etäalustan pyyhinnän tuen puuttuessa", + "value": "Etäalustan pyyhintää ei tueta" } } diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 5f97bd5a6..5d0bfe7b6 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -1419,6 +1419,10 @@ "description": "Étiquette pour le démarrage réseau HTTPS", "value": "HTTPS Démarrage réseau :" }, + "general.remotePlatformErase": { + "description": "Étiquette pour l'effacement distant de la plateforme", + "value": "Effacement distant de la plateforme :" + }, "general.ideRedirection": { "description": "Étiquette pour la redirection IDE", "value": "Redirection IDE :" @@ -2808,5 +2812,69 @@ "common.noData": { "value": "Aucune donnée disponible", "description": "Message indiquant qu’aucune donnée n’est disponible" + }, + "deviceDetail.remotePlatformErase": { + "description": "Nom de catégorie pour l'effacement distant de la plateforme", + "value": "Effacement distant de la plateforme" + }, + "deviceDetail.remotePlatformEraseDescription": { + "description": "Description pour l'effacement distant de la plateforme", + "value": "Effacer les données de la plateforme en toute sécurité" + }, + "remotePlatformErase.title": { + "description": "Titre de la carte de fonctionnalité d'effacement distant de la plateforme", + "value": "Effacement distant de la plateforme" + }, + "remotePlatformErase.description": { + "description": "Sous-titre de la carte de fonctionnalité d'effacement distant de la plateforme", + "value": "Activer ou désactiver la fonctionnalité d'effacement distant de la plateforme sur cet appareil" + }, + "remotePlatformErase.warning": { + "description": "Message d'avertissement concernant l'activation de l'effacement distant de la plateforme", + "value": "L'activation de cette fonctionnalité permet l'effacement à distance des données de la plateforme. À utiliser avec précaution." + }, + "remotePlatformErase.enableFeature": { + "description": "Étiquette de la case à cocher pour activer l'effacement distant de la plateforme", + "value": "Activer l'effacement distant de la plateforme" + }, + "remotePlatformErase.initiateTitle": { + "description": "Titre de la carte d'action pour lancer l'effacement", + "value": "Lancer l'effacement distant" + }, + "remotePlatformErase.initiateDescription": { + "description": "Sous-titre de la carte d'action pour lancer l'effacement", + "value": "Effacer définitivement toutes les données stockées sur cette plateforme" + }, + "remotePlatformErase.initiateWarning": { + "description": "Avertissement avant de lancer un effacement distant de la plateforme", + "value": "Cette action est irréversible. Toutes les données de la plateforme seront définitivement effacées." + }, + "remotePlatformErase.initiateButton": { + "description": "Étiquette du bouton pour lancer l'effacement distant de la plateforme", + "value": "Lancer l'effacement distant" + }, + "remotePlatformErase.updateSuccess": { + "description": "Message de succès lors de l'activation ou désactivation de l'effacement distant de la plateforme", + "value": "Fonctionnalité d'effacement distant de la plateforme mise à jour avec succès" + }, + "remotePlatformErase.updateError": { + "description": "Message d'erreur quand la mise à jour de l'effacement distant de la plateforme échoue", + "value": "Échec de la mise à jour de la fonctionnalité d'effacement distant de la plateforme" + }, + "remotePlatformErase.eraseSuccess": { + "description": "Message de succès après le lancement de l'effacement distant de la plateforme", + "value": "Effacement distant de la plateforme lancé avec succès" + }, + "remotePlatformErase.eraseError": { + "description": "Message d'erreur quand l'effacement distant de la plateforme ne peut pas être lancé", + "value": "Échec du lancement de l'effacement distant de la plateforme" + }, + "remotePlatformErase.errorLoad": { + "description": "Message d'erreur lors du chargement du statut de l'effacement distant de la plateforme", + "value": "Échec du chargement du statut de la fonctionnalité d'effacement distant de la plateforme" + }, + "remotePlatformErase.notSupported": { + "description": "Message affiché quand l'effacement distant de la plateforme n'est pas pris en charge", + "value": "L'effacement distant de la plateforme n'est pas pris en charge" } } diff --git a/src/assets/i18n/he.json b/src/assets/i18n/he.json index 148267dd5..2383fe4bb 100644 --- a/src/assets/i18n/he.json +++ b/src/assets/i18n/he.json @@ -1419,6 +1419,10 @@ "description": "תווית עבור אתחול רשת HTTPS", "value": "אתחול רשת HTTPS:" }, + "general.remotePlatformErase": { + "description": "תווית למחיקת פלטפורמה מרחוק", + "value": "מחיקת פלטפורמה מרחוק:" + }, "general.ideRedirection": { "description": "תווית לניתוב מחדש של IDE", "value": "ניתוב מחדש של IDE:" @@ -2808,5 +2812,69 @@ "common.noData": { "value": "אין נתונים זמינים", "description": "הודעה כאשר אין נתונים זמינים" + }, + "deviceDetail.remotePlatformErase": { + "description": "שם קטגוריה למחיקת פלטפורמה מרחוק", + "value": "מחיקת פלטפורמה מרחוק" + }, + "deviceDetail.remotePlatformEraseDescription": { + "description": "תיאור למחיקת פלטפורמה מרחוק", + "value": "מחיקה מאובטחת של נתוני הפלטפורמה" + }, + "remotePlatformErase.title": { + "description": "כותרת לכרטיס תכונת מחיקת פלטפורמה מרחוק", + "value": "מחיקת פלטפורמה מרחוק" + }, + "remotePlatformErase.description": { + "description": "כותרת משנה לכרטיס תכונת מחיקת פלטפורמה מרחוק", + "value": "הפעל או השבת את תכונת מחיקת הפלטפורמה מרחוק במכשיר זה" + }, + "remotePlatformErase.warning": { + "description": "הודעת אזהרה על הפעלת מחיקת פלטפורמה מרחוק", + "value": "הפעלת תכונה זו מאפשרת מחיקה מרחוק של נתוני הפלטפורמה. השתמש בזהירות." + }, + "remotePlatformErase.enableFeature": { + "description": "תווית לתיבת הסימון להפעלת מחיקת פלטפורמה מרחוק", + "value": "הפעל מחיקת פלטפורמה מרחוק" + }, + "remotePlatformErase.initiateTitle": { + "description": "כותרת לכרטיס פעולת התחלת המחיקה", + "value": "התחל מחיקה מרחוק" + }, + "remotePlatformErase.initiateDescription": { + "description": "כותרת משנה לכרטיס פעולת התחלת המחיקה", + "value": "מחק לצמיתות את כל הנתונים המאוחסנים בפלטפורמה זו" + }, + "remotePlatformErase.initiateWarning": { + "description": "אזהרה לפני התחלת מחיקת פלטפורמה מרחוק", + "value": "פעולה זו אינה הפיכה. כל נתוני הפלטפורמה יימחקו לצמיתות." + }, + "remotePlatformErase.initiateButton": { + "description": "תווית הכפתור להתחלת מחיקת פלטפורמה מרחוק", + "value": "התחל מחיקה מרחוק" + }, + "remotePlatformErase.updateSuccess": { + "description": "הודעת הצלחה בעת החלפת מצב תכונת מחיקת פלטפורמה מרחוק", + "value": "תכונת מחיקת הפלטפורמה מרחוק עודכנה בהצלחה" + }, + "remotePlatformErase.updateError": { + "description": "הודעת שגיאה כאשר עדכון תכונת מחיקת פלטפורמה מרחוק נכשל", + "value": "עדכון תכונת מחיקת הפלטפורמה מרחוק נכשל" + }, + "remotePlatformErase.eraseSuccess": { + "description": "הודעת הצלחה לאחר הפעלת מחיקת פלטפורמה מרחוק", + "value": "מחיקת הפלטפורמה מרחוק הופעלה בהצלחה" + }, + "remotePlatformErase.eraseError": { + "description": "הודעת שגיאה כאשר הפעלת מחיקת פלטפורמה מרחוק נכשלת", + "value": "הפעלת מחיקת הפלטפורמה מרחוק נכשלה" + }, + "remotePlatformErase.errorLoad": { + "description": "הודעת שגיאה בעת כשל בטעינת סטטוס תכונת מחיקת פלטפורמה מרחוק", + "value": "טעינת סטטוס תכונת מחיקת הפלטפורמה מרחוק נכשלה" + }, + "remotePlatformErase.notSupported": { + "description": "הודעה המוצגת כאשר מחיקת פלטפורמה מרחוק אינה נתמכת במכשיר", + "value": "מחיקת פלטפורמה מרחוק אינה נתמכת" } } diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json index 8204ac61a..510b64745 100644 --- a/src/assets/i18n/it.json +++ b/src/assets/i18n/it.json @@ -1419,6 +1419,10 @@ "description": "Etichetta per avvio di rete HTTPS", "value": "Avvio di rete HTTPS:" }, + "general.remotePlatformErase": { + "description": "Etichetta per la cancellazione remota della piattaforma", + "value": "Cancellazione remota della piattaforma:" + }, "general.ideRedirection": { "description": "Etichetta per il reindirizzamento IDE", "value": "Reindirizzamento IDE:" @@ -2808,5 +2812,69 @@ "common.noData": { "value": "Nessun dato disponibile", "description": "Messaggio quando non ci sono dati disponibili" + }, + "deviceDetail.remotePlatformErase": { + "description": "Nome categoria per la cancellazione remota della piattaforma", + "value": "Cancellazione remota della piattaforma" + }, + "deviceDetail.remotePlatformEraseDescription": { + "description": "Descrizione per la cancellazione remota della piattaforma", + "value": "Cancella in modo sicuro i dati della piattaforma" + }, + "remotePlatformErase.title": { + "description": "Titolo della scheda funzione di cancellazione remota della piattaforma", + "value": "Cancellazione remota della piattaforma" + }, + "remotePlatformErase.description": { + "description": "Sottotitolo della scheda funzione di cancellazione remota della piattaforma", + "value": "Abilita o disabilita la funzionalità di cancellazione remota della piattaforma su questo dispositivo" + }, + "remotePlatformErase.warning": { + "description": "Messaggio di avviso sull'abilitazione della cancellazione remota della piattaforma", + "value": "L'abilitazione di questa funzionalità consente la cancellazione remota dei dati della piattaforma. Usare con cautela." + }, + "remotePlatformErase.enableFeature": { + "description": "Etichetta della casella di controllo per abilitare la cancellazione remota della piattaforma", + "value": "Abilita cancellazione remota della piattaforma" + }, + "remotePlatformErase.initiateTitle": { + "description": "Titolo della scheda azione per avviare la cancellazione", + "value": "Avvia cancellazione remota" + }, + "remotePlatformErase.initiateDescription": { + "description": "Sottotitolo della scheda azione per avviare la cancellazione", + "value": "Cancella definitivamente tutti i dati archiviati su questa piattaforma" + }, + "remotePlatformErase.initiateWarning": { + "description": "Avviso prima di avviare la cancellazione remota della piattaforma", + "value": "Questa azione è irreversibile. Tutti i dati della piattaforma verranno cancellati definitivamente." + }, + "remotePlatformErase.initiateButton": { + "description": "Etichetta del pulsante per avviare la cancellazione remota della piattaforma", + "value": "Avvia cancellazione remota" + }, + "remotePlatformErase.updateSuccess": { + "description": "Messaggio di successo quando la funzione di cancellazione remota viene attivata", + "value": "Funzionalità di cancellazione remota della piattaforma aggiornata con successo" + }, + "remotePlatformErase.updateError": { + "description": "Messaggio di errore quando l'aggiornamento della funzione di cancellazione remota fallisce", + "value": "Impossibile aggiornare la funzionalità di cancellazione remota della piattaforma" + }, + "remotePlatformErase.eraseSuccess": { + "description": "Messaggio di successo dopo aver avviato la cancellazione remota della piattaforma", + "value": "Cancellazione remota della piattaforma avviata con successo" + }, + "remotePlatformErase.eraseError": { + "description": "Messaggio di errore quando la cancellazione remota della piattaforma non può essere avviata", + "value": "Impossibile avviare la cancellazione remota della piattaforma" + }, + "remotePlatformErase.errorLoad": { + "description": "Messaggio di errore durante il caricamento dello stato della funzione di cancellazione remota", + "value": "Impossibile caricare lo stato della funzionalità di cancellazione remota della piattaforma" + }, + "remotePlatformErase.notSupported": { + "description": "Messaggio mostrato quando la cancellazione remota della piattaforma non è supportata", + "value": "La cancellazione remota della piattaforma non è supportata" } } diff --git a/src/assets/i18n/ja.json b/src/assets/i18n/ja.json index 1c43a7524..b8d9964f6 100644 --- a/src/assets/i18n/ja.json +++ b/src/assets/i18n/ja.json @@ -1419,6 +1419,10 @@ "description": "HTTPS ネットワークブートのラベル", "value": "HTTPS ネットワークブート:" }, + "general.remotePlatformErase": { + "description": "リモートプラットフォーム消去のラベル", + "value": "リモートプラットフォーム消去:" + }, "general.ideRedirection": { "description": "IDEリダイレクト用ラベル", "value": "IDE リダイレクト:" @@ -2808,5 +2812,69 @@ "common.noData": { "value": "利用可能なデータがありません", "description": "データが利用できない場合のメッセージ" + }, + "deviceDetail.remotePlatformErase": { + "description": "リモートプラットフォーム消去のカテゴリ名", + "value": "リモートプラットフォーム消去" + }, + "deviceDetail.remotePlatformEraseDescription": { + "description": "リモートプラットフォーム消去の説明", + "value": "プラットフォームデータを安全に消去する" + }, + "remotePlatformErase.title": { + "description": "リモートプラットフォーム消去機能カードのタイトル", + "value": "リモートプラットフォーム消去" + }, + "remotePlatformErase.description": { + "description": "リモートプラットフォーム消去機能カードのサブタイトル", + "value": "このデバイスのリモートプラットフォーム消去機能を有効または無効にする" + }, + "remotePlatformErase.warning": { + "description": "リモートプラットフォーム消去の有効化に関する警告メッセージ", + "value": "この機能を有効にすると、プラットフォームデータをリモートで消去できます。慎重に使用してください。" + }, + "remotePlatformErase.enableFeature": { + "description": "リモートプラットフォーム消去を有効にするチェックボックスのラベル", + "value": "リモートプラットフォーム消去を有効にする" + }, + "remotePlatformErase.initiateTitle": { + "description": "消去開始アクションカードのタイトル", + "value": "リモート消去の開始" + }, + "remotePlatformErase.initiateDescription": { + "description": "消去開始アクションカードのサブタイトル", + "value": "このプラットフォームに保存されているすべてのデータを完全に消去する" + }, + "remotePlatformErase.initiateWarning": { + "description": "リモートプラットフォーム消去を開始する前の警告", + "value": "この操作は元に戻せません。すべてのプラットフォームデータが完全に消去されます。" + }, + "remotePlatformErase.initiateButton": { + "description": "リモートプラットフォーム消去を開始するボタンのラベル", + "value": "リモート消去を開始" + }, + "remotePlatformErase.updateSuccess": { + "description": "リモートプラットフォーム消去機能の切り替え成功メッセージ", + "value": "リモートプラットフォーム消去機能を正常に更新しました" + }, + "remotePlatformErase.updateError": { + "description": "リモートプラットフォーム消去機能の更新失敗エラーメッセージ", + "value": "リモートプラットフォーム消去機能の更新に失敗しました" + }, + "remotePlatformErase.eraseSuccess": { + "description": "リモートプラットフォーム消去開始後の成功メッセージ", + "value": "リモートプラットフォーム消去が正常に開始されました" + }, + "remotePlatformErase.eraseError": { + "description": "リモートプラットフォーム消去の開始失敗エラーメッセージ", + "value": "リモートプラットフォーム消去の開始に失敗しました" + }, + "remotePlatformErase.errorLoad": { + "description": "リモートプラットフォーム消去機能の状態読み込み失敗エラーメッセージ", + "value": "リモートプラットフォーム消去機能のステータスの読み込みに失敗しました" + }, + "remotePlatformErase.notSupported": { + "description": "デバイスでリモートプラットフォーム消去がサポートされていない場合のメッセージ", + "value": "リモートプラットフォーム消去はサポートされていません" } } diff --git a/src/assets/i18n/nl.json b/src/assets/i18n/nl.json index 3b7b4ff24..be2712c07 100644 --- a/src/assets/i18n/nl.json +++ b/src/assets/i18n/nl.json @@ -1419,6 +1419,10 @@ "description": "Label voor HTTPS Netwerkboot", "value": "HTTPS Netwerkboot:" }, + "general.remotePlatformErase": { + "description": "Label voor extern wissen van het platform", + "value": "Extern platform wissen:" + }, "general.ideRedirection": { "description": "Label voor IDE-omleiding", "value": "IDE-omleiding:" @@ -2808,5 +2812,69 @@ "common.noData": { "value": "Geen gegevens beschikbaar", "description": "Bericht wanneer er geen gegevens beschikbaar zijn" + }, + "deviceDetail.remotePlatformErase": { + "description": "Categorienaam voor extern wissen van het platform", + "value": "Extern platform wissen" + }, + "deviceDetail.remotePlatformEraseDescription": { + "description": "Beschrijving voor extern wissen van het platform", + "value": "Platformgegevens veilig wissen" + }, + "remotePlatformErase.title": { + "description": "Titel van de functiekaart voor extern wissen van het platform", + "value": "Extern platform wissen" + }, + "remotePlatformErase.description": { + "description": "Ondertitel van de functiekaart voor extern wissen van het platform", + "value": "De functie voor extern wissen van het platform op dit apparaat in- of uitschakelen" + }, + "remotePlatformErase.warning": { + "description": "Waarschuwingsbericht over het inschakelen van extern wissen van het platform", + "value": "Als u deze functie inschakelt, kunnen platformgegevens op afstand worden gewist. Gebruik met voorzichtigheid." + }, + "remotePlatformErase.enableFeature": { + "description": "Label van het selectievakje voor extern wissen van het platform", + "value": "Extern wissen van het platform inschakelen" + }, + "remotePlatformErase.initiateTitle": { + "description": "Titel van de actiekaart voor het starten van wissen", + "value": "Extern wissen starten" + }, + "remotePlatformErase.initiateDescription": { + "description": "Ondertitel van de actiekaart voor het starten van wissen", + "value": "Alle gegevens op dit platform permanent wissen" + }, + "remotePlatformErase.initiateWarning": { + "description": "Waarschuwing voor het starten van extern wissen van het platform", + "value": "Deze actie is onomkeerbaar. Alle platformgegevens worden permanent gewist." + }, + "remotePlatformErase.initiateButton": { + "description": "Knoplaabel voor het starten van extern wissen van het platform", + "value": "Extern wissen starten" + }, + "remotePlatformErase.updateSuccess": { + "description": "Succesbericht bij het in- of uitschakelen van extern wissen van het platform", + "value": "Functie voor extern wissen van het platform succesvol bijgewerkt" + }, + "remotePlatformErase.updateError": { + "description": "Foutbericht wanneer bijwerken van extern wissen van het platform mislukt", + "value": "Bijwerken van de functie voor extern wissen van het platform mislukt" + }, + "remotePlatformErase.eraseSuccess": { + "description": "Succesbericht na het starten van extern wissen van het platform", + "value": "Extern wissen van het platform succesvol gestart" + }, + "remotePlatformErase.eraseError": { + "description": "Foutbericht wanneer extern wissen van het platform niet kan worden gestart", + "value": "Starten van extern wissen van het platform mislukt" + }, + "remotePlatformErase.errorLoad": { + "description": "Foutbericht bij het laden van de status van extern wissen van het platform", + "value": "Laden van de status van de functie voor extern wissen van het platform mislukt" + }, + "remotePlatformErase.notSupported": { + "description": "Bericht dat wordt weergegeven wanneer extern wissen van het platform niet wordt ondersteund", + "value": "Extern wissen van het platform wordt niet ondersteund" } } diff --git a/src/assets/i18n/ru.json b/src/assets/i18n/ru.json index 397b4983c..040777320 100644 --- a/src/assets/i18n/ru.json +++ b/src/assets/i18n/ru.json @@ -1419,6 +1419,10 @@ "description": "Метка для HTTPS Сетевая загрузка", "value": "HTTPS Сетевая загрузка:" }, + "general.remotePlatformErase": { + "description": "Метка для удалённого стирания платформы", + "value": "Удалённое стирание платформы:" + }, "general.ideRedirection": { "description": "Метка для перенаправления IDE", "value": "Перенаправление IDE:" @@ -2808,5 +2812,69 @@ "common.noData": { "value": "Нет доступных данных", "description": "Сообщение при отсутствии данных" + }, + "deviceDetail.remotePlatformErase": { + "description": "Имя категории для удалённого стирания платформы", + "value": "Удалённое стирание платформы" + }, + "deviceDetail.remotePlatformEraseDescription": { + "description": "Описание удалённого стирания платформы", + "value": "Безопасное стирание данных платформы" + }, + "remotePlatformErase.title": { + "description": "Заголовок карточки функции удалённого стирания платформы", + "value": "Удалённое стирание платформы" + }, + "remotePlatformErase.description": { + "description": "Подзаголовок карточки функции удалённого стирания платформы", + "value": "Включить или отключить функцию удалённого стирания платформы на этом устройстве" + }, + "remotePlatformErase.warning": { + "description": "Предупреждение о включении удалённого стирания платформы", + "value": "Включение этой функции позволяет удалённо стирать данные платформы. Используйте с осторожностью." + }, + "remotePlatformErase.enableFeature": { + "description": "Метка флажка для включения удалённого стирания платформы", + "value": "Включить удалённое стирание платформы" + }, + "remotePlatformErase.initiateTitle": { + "description": "Заголовок карточки действия запуска стирания", + "value": "Запустить удалённое стирание" + }, + "remotePlatformErase.initiateDescription": { + "description": "Подзаголовок карточки действия запуска стирания", + "value": "Безвозвратно удалить все данные, хранящиеся на этой платформе" + }, + "remotePlatformErase.initiateWarning": { + "description": "Предупреждение перед запуском удалённого стирания платформы", + "value": "Это действие необратимо. Все данные платформы будут безвозвратно удалены." + }, + "remotePlatformErase.initiateButton": { + "description": "Подпись кнопки для запуска удалённого стирания платформы", + "value": "Запустить удалённое стирание" + }, + "remotePlatformErase.updateSuccess": { + "description": "Сообщение об успехе при переключении функции удалённого стирания платформы", + "value": "Функция удалённого стирания платформы успешно обновлена" + }, + "remotePlatformErase.updateError": { + "description": "Сообщение об ошибке при неудачном обновлении функции удалённого стирания платформы", + "value": "Не удалось обновить функцию удалённого стирания платформы" + }, + "remotePlatformErase.eraseSuccess": { + "description": "Сообщение об успехе после запуска удалённого стирания платформы", + "value": "Удалённое стирание платформы успешно запущено" + }, + "remotePlatformErase.eraseError": { + "description": "Сообщение об ошибке при невозможности запустить удалённое стирание платформы", + "value": "Не удалось запустить удалённое стирание платформы" + }, + "remotePlatformErase.errorLoad": { + "description": "Сообщение об ошибке при загрузке статуса функции удалённого стирания платформы", + "value": "Не удалось загрузить статус функции удалённого стирания платформы" + }, + "remotePlatformErase.notSupported": { + "description": "Сообщение, отображаемое когда удалённое стирание платформы не поддерживается устройством", + "value": "Удалённое стирание платформы не поддерживается" } } diff --git a/src/assets/i18n/sv.json b/src/assets/i18n/sv.json index 119ba343a..cd360d04a 100644 --- a/src/assets/i18n/sv.json +++ b/src/assets/i18n/sv.json @@ -1419,6 +1419,10 @@ "description": "Etikett för HTTPS Nätverksstart", "value": "HTTPS Nätverksstart:" }, + "general.remotePlatformErase": { + "description": "Etikett för fjärrradering av plattform", + "value": "Fjärrradering av plattform:" + }, "general.ideRedirection": { "description": "Etikett för IDE-omdirigering", "value": "IDE-omdirigering:" @@ -2808,5 +2812,69 @@ "common.noData": { "value": "Ingen data tillgänglig", "description": "Meddelande när ingen data är tillgänglig" + }, + "deviceDetail.remotePlatformErase": { + "description": "Kategorinamn för fjärrradering av plattform", + "value": "Fjärrradering av plattform" + }, + "deviceDetail.remotePlatformEraseDescription": { + "description": "Beskrivning för fjärrradering av plattform", + "value": "Radera plattformsdata på ett säkert sätt" + }, + "remotePlatformErase.title": { + "description": "Titel på funktionskortet för fjärrradering av plattform", + "value": "Fjärrradering av plattform" + }, + "remotePlatformErase.description": { + "description": "Underrubrik på funktionskortet för fjärrradering av plattform", + "value": "Aktivera eller inaktivera fjärrraderingsfunktionen för plattformen på den här enheten" + }, + "remotePlatformErase.warning": { + "description": "Varningsmeddelande om aktivering av fjärrradering av plattform", + "value": "Att aktivera den här funktionen tillåter fjärrradering av plattformsdata. Använd med försiktighet." + }, + "remotePlatformErase.enableFeature": { + "description": "Etikett för kryssrutan för att aktivera fjärrradering av plattform", + "value": "Aktivera fjärrradering av plattform" + }, + "remotePlatformErase.initiateTitle": { + "description": "Titel på åtgärdskortet för att starta radering", + "value": "Starta fjärrradering" + }, + "remotePlatformErase.initiateDescription": { + "description": "Underrubrik på åtgärdskortet för att starta radering", + "value": "Radera permanent alla data som lagras på den här plattformen" + }, + "remotePlatformErase.initiateWarning": { + "description": "Varning innan fjärrradering av plattform påbörjas", + "value": "Den här åtgärden är oåterkallelig. All plattformsdata kommer att raderas permanent." + }, + "remotePlatformErase.initiateButton": { + "description": "Knappetikett för att starta fjärrradering av plattform", + "value": "Starta fjärrradering" + }, + "remotePlatformErase.updateSuccess": { + "description": "Framgångsmeddelande när funktionen för fjärrradering växlas", + "value": "Fjärrraderingsfunktionen för plattformen har uppdaterats" + }, + "remotePlatformErase.updateError": { + "description": "Felmeddelande när uppdatering av fjärrradering av plattform misslyckas", + "value": "Det gick inte att uppdatera fjärrraderingsfunktionen för plattformen" + }, + "remotePlatformErase.eraseSuccess": { + "description": "Framgångsmeddelande efter att fjärrradering av plattform initierats", + "value": "Fjärrradering av plattform har startats" + }, + "remotePlatformErase.eraseError": { + "description": "Felmeddelande när fjärrradering av plattform inte kan initieras", + "value": "Det gick inte att starta fjärrraderingen av plattformen" + }, + "remotePlatformErase.errorLoad": { + "description": "Felmeddelande vid fel vid inläsning av status för fjärrradering av plattform", + "value": "Det gick inte att läsa in statusen för fjärrraderingsfunktionen för plattformen" + }, + "remotePlatformErase.notSupported": { + "description": "Meddelande som visas när fjärrradering av plattform inte stöds på enheten", + "value": "Fjärrradering av plattform stöds inte" } } diff --git a/src/models/models.ts b/src/models/models.ts index aa9af2983..d72350fc2 100644 --- a/src/models/models.ts +++ b/src/models/models.ts @@ -137,7 +137,9 @@ export interface AMTFeaturesResponse { httpsBootSupported: boolean winREBootSupported: boolean localPBABootSupported: boolean - remoteErase: boolean + remoteEraseEnabled: boolean + remoteEraseSupported?: boolean + platformEraseCaps?: number pbaBootFilesPath: BootParams[] winREBootFilesPath: BootParams } @@ -147,7 +149,7 @@ export interface AMTFeaturesRequest { enableSOL: boolean enableIDER: boolean ocr: boolean - remoteErase: boolean + enablePlatformErase: boolean } export interface PowerState {