From 6e37940c218acda693d5a975b35cd7000ef51e2b Mon Sep 17 00:00:00 2001 From: Jordan Reimer Date: Tue, 17 Jan 2023 11:33:34 -0700 Subject: [PATCH 1/4] adds pki certificate details page component --- ui/app/adapters/pki/certificate.js | 3 - ui/app/adapters/pki/certificate/base.js | 40 +++++- ui/app/models/pki/certificate/base.js | 18 ++- ui/app/serializers/pki/certificate/base.js | 30 +++++ .../serializers/pki/certificate/generate.js | 26 +--- ui/app/serializers/pki/certificate/sign.js | 26 +--- .../page/pki-certificate-details.hbs | 55 +++++++++ .../page/pki-certificate-details.ts | 47 +++++++ .../addon/components/pki-role-generate.hbs | 47 +------ .../pki/addon/components/pki-role-generate.ts | 27 +--- .../certificates/certificate/details.js | 21 +++- ui/lib/pki/addon/routes/certificates/index.js | 12 +- .../certificates/certificate/details.hbs | 13 +- .../addon/templates/certificates/index.hbs | 6 +- .../pki/page/pki-certificate-details-test.js | 116 ++++++++++++++++++ 15 files changed, 344 insertions(+), 143 deletions(-) delete mode 100644 ui/app/adapters/pki/certificate.js create mode 100644 ui/app/serializers/pki/certificate/base.js create mode 100644 ui/lib/pki/addon/components/page/pki-certificate-details.hbs create mode 100644 ui/lib/pki/addon/components/page/pki-certificate-details.ts create mode 100644 ui/tests/integration/components/pki/page/pki-certificate-details-test.js diff --git a/ui/app/adapters/pki/certificate.js b/ui/app/adapters/pki/certificate.js deleted file mode 100644 index 1c88c8979c53..000000000000 --- a/ui/app/adapters/pki/certificate.js +++ /dev/null @@ -1,3 +0,0 @@ -import PkiCertAdapter from './cert'; - -export default class PkiCertificateAdapter extends PkiCertAdapter {} diff --git a/ui/app/adapters/pki/certificate/base.js b/ui/app/adapters/pki/certificate/base.js index c95f678dde82..b36bb173204e 100644 --- a/ui/app/adapters/pki/certificate/base.js +++ b/ui/app/adapters/pki/certificate/base.js @@ -4,10 +4,46 @@ import ApplicationAdapter from '../../application'; export default class PkiCertificateBaseAdapter extends ApplicationAdapter { namespace = 'v1'; - deleteRecord(store, type, snapshot) { + getURL(backend, id) { + const uri = `${this.buildURL()}/${encodePath(backend)}`; + return id ? `${uri}/cert/${id}` : `${uri}/certs`; + } + + fetchByQuery(query) { + const { backend, id } = query; + const data = !id ? { list: true } : {}; + return this.ajax(this.getURL(backend, id), 'GET', { data }).then((resp) => { + resp.data.backend = backend; + if (id) { + resp.data.id = id; + resp.data.serial_number = id; + } + return resp; + }); + } + + query(store, type, query) { + return this.fetchByQuery(query); + } + + queryRecord(store, type, query) { + return this.fetchByQuery(query); + } + + // the only way to update a record is by revoking it which will set the revocationTime property + updateRecord(store, type, snapshot) { const { backend, serialNumber, certificate } = snapshot.record; // Revoke certificate requires either serial_number or certificate const data = serialNumber ? { serial_number: serialNumber } : { certificate }; - return this.ajax(`${this.buildURL()}/${encodePath(backend)}/revoke`, 'POST', { data }); + return this.ajax(`${this.buildURL()}/${encodePath(backend)}/revoke`, 'POST', { data }).then( + (response) => { + return { + data: { + ...this.serialize(snapshot), + ...response.data, + }, + }; + } + ); } } diff --git a/ui/app/models/pki/certificate/base.js b/ui/app/models/pki/certificate/base.js index 517b70cf7e8d..3453167e8c74 100644 --- a/ui/app/models/pki/certificate/base.js +++ b/ui/app/models/pki/certificate/base.js @@ -11,7 +11,15 @@ import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; * attributes and adapter methods. */ -const certDisplayFields = ['certificate', 'commonName', 'serialNumber', 'notValidAfter', 'notValidBefore']; +const certDisplayFields = [ + 'certificate', + 'commonName', + 'revocationTime', + 'issueDate', + 'serialNumber', + 'notValidBefore', + 'notValidAfter', +]; @withFormFields(certDisplayFields) export default class PkiCertificateBaseModel extends Model { @@ -31,16 +39,18 @@ export default class PkiCertificateBaseModel extends Model { // Attrs that come back from API POST request @attr() caChain; - @attr('string') certificate; + @attr('string', { masked: true }) certificate; @attr('number') expiration; + @attr('number', { formatDate: true }) revocationTime; @attr('string') issuingCa; @attr('string') privateKey; @attr('string') privateKeyType; @attr('string') serialNumber; // Parsed from cert in serializer - @attr('date') notValidAfter; - @attr('date') notValidBefore; + @attr('number', { formatDate: true }) issueDate; + @attr('number', { formatDate: true }) notValidAfter; + @attr('number', { formatDate: true }) notValidBefore; // For importing @attr('string') pemBundle; diff --git a/ui/app/serializers/pki/certificate/base.js b/ui/app/serializers/pki/certificate/base.js new file mode 100644 index 000000000000..d444eeb44234 --- /dev/null +++ b/ui/app/serializers/pki/certificate/base.js @@ -0,0 +1,30 @@ +import { parseCertificate } from 'vault/helpers/parse-pki-cert'; +import ApplicationSerializer from '../../application'; + +export default class PkiCertificateBaseSerializer extends ApplicationSerializer { + primaryKey = 'serial_number'; + + attrs = { + role: { serialize: false }, + }; + + normalizeResponse(store, primaryModelClass, payload, id, requestType) { + if (payload.data.certificate) { + // Parse certificate back from the API and add to payload + const parsedCert = parseCertificate(payload.data.certificate); + // convert issueDate to same format as other date values + if (parsedCert.issue_date) { + parsedCert.issue_date = parsedCert.issue_date.valueOf(); + } + const json = super.normalizeResponse( + store, + primaryModelClass, + { ...payload, ...parsedCert }, + id, + requestType + ); + return json; + } + return super.normalizeResponse(...arguments); + } +} diff --git a/ui/app/serializers/pki/certificate/generate.js b/ui/app/serializers/pki/certificate/generate.js index fb06f8e8cda3..332504f672ce 100644 --- a/ui/app/serializers/pki/certificate/generate.js +++ b/ui/app/serializers/pki/certificate/generate.js @@ -1,25 +1,3 @@ -import { parseCertificate } from 'vault/helpers/parse-pki-cert'; -import ApplicationSerializer from '../../application'; +import PkiCertificateBaseSerializer from './base'; -export default class PkiCertificateGenerateSerializer extends ApplicationSerializer { - primaryKey = 'serial_number'; - attrs = { - role: { serialize: false }, - }; - - normalizeResponse(store, primaryModelClass, payload, id, requestType) { - if (requestType === 'createRecord' && payload.data.certificate) { - // Parse certificate back from the API and add to payload - const parsedCert = parseCertificate(payload.data.certificate); - const json = super.normalizeResponse( - store, - primaryModelClass, - { ...payload, ...parsedCert }, - id, - requestType - ); - return json; - } - return super.normalizeResponse(...arguments); - } -} +export default class PkiCertificateGenerateSerializer extends PkiCertificateBaseSerializer {} diff --git a/ui/app/serializers/pki/certificate/sign.js b/ui/app/serializers/pki/certificate/sign.js index 367c6398a61c..332504f672ce 100644 --- a/ui/app/serializers/pki/certificate/sign.js +++ b/ui/app/serializers/pki/certificate/sign.js @@ -1,25 +1,3 @@ -import { parseCertificate } from 'vault/helpers/parse-pki-cert'; -import ApplicationSerializer from '../../application'; +import PkiCertificateBaseSerializer from './base'; -export default class PkiCertificateSignSerializer extends ApplicationSerializer { - primaryKey = 'serial_number'; - attrs = { - type: { serialize: false }, - }; - - normalizeResponse(store, primaryModelClass, payload, id, requestType) { - if (requestType === 'createRecord' && payload.data.certificate) { - // Parse certificate back from the API and add to payload - const parsedCert = parseCertificate(payload.data.certificate); - const json = super.normalizeResponse( - store, - primaryModelClass, - { ...payload, ...parsedCert }, - id, - requestType - ); - return json; - } - return super.normalizeResponse(...arguments); - } -} +export default class PkiCertificateGenerateSerializer extends PkiCertificateBaseSerializer {} diff --git a/ui/lib/pki/addon/components/page/pki-certificate-details.hbs b/ui/lib/pki/addon/components/page/pki-certificate-details.hbs new file mode 100644 index 000000000000..2394ee70d0c6 --- /dev/null +++ b/ui/lib/pki/addon/components/page/pki-certificate-details.hbs @@ -0,0 +1,55 @@ + + + + {{#if @model.canRevoke}} + + Revoke certificate + + {{/if}} + + + +{{#each @model.formFields as |field|}} + {{#if (eq field.name "certificate")}} + + + + {{else if (eq field.name "serialNumber")}} + + {{@model.serialNumber}} + + {{else}} + + {{/if}} +{{/each}} + +{{#if @onBack}} +
+
+ +
+
+{{/if}} \ No newline at end of file diff --git a/ui/lib/pki/addon/components/page/pki-certificate-details.ts b/ui/lib/pki/addon/components/page/pki-certificate-details.ts new file mode 100644 index 000000000000..c102bdc867f4 --- /dev/null +++ b/ui/lib/pki/addon/components/page/pki-certificate-details.ts @@ -0,0 +1,47 @@ +import Component from '@glimmer/component'; +import { service } from '@ember/service'; +import { action } from '@ember/object'; +import { task } from 'ember-concurrency'; +import { waitFor } from '@ember/test-waiters'; +import errorMessage from 'vault/utils/error-message'; +import FlashMessageService from 'vault/services/flash-messages'; +import DownloadService from 'vault/services/download'; +import PkiCertificateBaseModel from 'vault/models/pki/certificate/base'; + +interface Args { + model: PkiCertificateBaseModel; + onRevoke?: CallableFunction; + onBack?: CallableFunction; +} + +export default class PkiCertificateDetailsComponent extends Component { + @service declare readonly flashMessages: FlashMessageService; + @service declare readonly download: DownloadService; + + @action + downloadCert() { + try { + const formattedSerial = this.args.model.serialNumber?.replace(/(\s|:)+/g, '-'); + this.download.pem(formattedSerial, this.args.model.certificate); + this.flashMessages.info('Your download has started.'); + } catch (err) { + this.flashMessages.danger(errorMessage(err, 'Unable to prepare certificate for download.')); + } + } + + @task + @waitFor + *revoke() { + try { + yield this.args.model.save(); + this.flashMessages.success('The certificate has been revoked.'); + if (this.args.onRevoke) { + this.args.onRevoke(); + } + } catch (error) { + this.flashMessages.danger( + errorMessage(error, 'Could not revoke certificate. See Vault logs for details.') + ); + } + } +} diff --git a/ui/lib/pki/addon/components/pki-role-generate.hbs b/ui/lib/pki/addon/components/pki-role-generate.hbs index f5ea03b0dc97..3ef4b099722f 100644 --- a/ui/lib/pki/addon/components/pki-role-generate.hbs +++ b/ui/lib/pki/addon/components/pki-role-generate.hbs @@ -1,50 +1,5 @@ {{#if @model.serialNumber}} - - - - {{#if @model.canRevoke}} - - {{/if}} - - - {{#each @model.formFields as |attr|}} - {{#if (eq attr.name "certificate")}} - - - - {{else}} - - {{/if}} - {{/each}} -
-
- -
-
+ {{else}}
diff --git a/ui/lib/pki/addon/components/pki-role-generate.ts b/ui/lib/pki/addon/components/pki-role-generate.ts index beda63cdd4c1..f1968d77fa0e 100644 --- a/ui/lib/pki/addon/components/pki-role-generate.ts +++ b/ui/lib/pki/addon/components/pki-role-generate.ts @@ -24,10 +24,6 @@ export default class PkiRoleGenerate extends Component { @tracked errorBanner = ''; - transitionToRole() { - this.router.transitionTo('vault.cluster.secrets.backend.pki.roles.role.details'); - } - get verb() { return this.args.type === 'sign' ? 'sign' : 'generate'; } @@ -45,29 +41,8 @@ export default class PkiRoleGenerate extends Component { } } - @task - *revoke() { - try { - yield this.args.model.destroyRecord(); - this.flashMessages.success('The certificate has been revoked.'); - this.transitionToRole(); - } catch (err) { - this.errorBanner = errorMessage(err, 'Could not revoke certificate. See Vault logs for details.'); - } - } - - @action downloadCert() { - try { - const formattedSerial = this.args.model.serialNumber?.replace(/(\s|:)+/g, '-'); - this.download.pem(formattedSerial, this.args.model.certificate); - this.flashMessages.info('Your download has started.'); - } catch (err) { - this.flashMessages.danger(errorMessage(err, 'Unable to prepare certificate for download.')); - } - } - @action cancel() { this.args.model.unloadRecord(); - this.transitionToRole(); + this.router.transitionTo('vault.cluster.secrets.backend.pki.roles.role.details'); } } diff --git a/ui/lib/pki/addon/routes/certificates/certificate/details.js b/ui/lib/pki/addon/routes/certificates/certificate/details.js index a0bec30d0359..be77bd8de470 100644 --- a/ui/lib/pki/addon/routes/certificates/certificate/details.js +++ b/ui/lib/pki/addon/routes/certificates/certificate/details.js @@ -1,3 +1,22 @@ import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; -export default class PkiCertificateDetailsRoute extends Route {} +export default class PkiCertificateDetailsRoute extends Route { + @service store; + @service secretMountPath; + + model() { + const id = this.paramsFor('certificates/certificate').serial; + return this.store.queryRecord('pki/certificate/base', { backend: this.secretMountPath.currentPath, id }); + } + setupController(controller, model) { + super.setupController(controller, model); + const backend = this.secretMountPath.currentPath || 'pki'; + controller.breadcrumbs = [ + { label: 'secrets', route: 'secrets', linkExternal: true }, + { label: backend, route: 'overview' }, + { label: 'certificates', route: 'certificates.index' }, + { label: model.id }, + ]; + } +} diff --git a/ui/lib/pki/addon/routes/certificates/index.js b/ui/lib/pki/addon/routes/certificates/index.js index dfd49a9e493e..22045b3f8bf2 100644 --- a/ui/lib/pki/addon/routes/certificates/index.js +++ b/ui/lib/pki/addon/routes/certificates/index.js @@ -4,18 +4,12 @@ import { inject as service } from '@ember/service'; export default class PkiCertificatesIndexRoute extends Route { @service store; @service secretMountPath; - @service pathHelp; - - beforeModel() { - // Must call this promise before the model hook otherwise it doesn't add OpenApi to record. - return this.pathHelp.getNewModel('pki/certificate', this.secretMountPath.currentPath); - } model() { return this.store - .query('pki/certificate', { backend: this.secretMountPath.currentPath }) - .then((certificateModel) => { - return { certificateModel, parentModel: this.modelFor('certificates') }; + .query('pki/certificate/base', { backend: this.secretMountPath.currentPath }) + .then((certificates) => { + return { certificates, parentModel: this.modelFor('certificates') }; }) .catch((err) => { if (err.httpStatus === 404) { diff --git a/ui/lib/pki/addon/templates/certificates/certificate/details.hbs b/ui/lib/pki/addon/templates/certificates/certificate/details.hbs index 2ac0cad72c89..895f1bd0a35c 100644 --- a/ui/lib/pki/addon/templates/certificates/certificate/details.hbs +++ b/ui/lib/pki/addon/templates/certificates/certificate/details.hbs @@ -1 +1,12 @@ -route: certificate.details \ No newline at end of file + + + + + +

+ + View certificate +

+
+
+ \ No newline at end of file diff --git a/ui/lib/pki/addon/templates/certificates/index.hbs b/ui/lib/pki/addon/templates/certificates/index.hbs index 4e5a17bfee39..13c9f8b6a353 100644 --- a/ui/lib/pki/addon/templates/certificates/index.hbs +++ b/ui/lib/pki/addon/templates/certificates/index.hbs @@ -10,14 +10,14 @@ /> {{outlet}} - {{#if this.model.certificateModel.length}} + {{#if this.model.certificates.length}} {{! ARG TODO glimmerize the NavigateInput and refactor so you can use it in an engine }} {{/if}} -{{#if this.model.certificateModel.length}} - {{#each this.model.certificateModel as |pkiCertificate|}} +{{#if this.model.certificates.length}} + {{#each this.model.certificates as |pkiCertificate|}} ({ + data: { + capabilities: ['root'], + 'pki/revoke': ['root'], + }, + })); + }); + + test('it should render actions and fields', async function (assert) { + assert.expect(6); + + this.server.post('/pki/revoke', (schema, req) => { + const data = JSON.parse(req.requestBody); + assert.strictEqual( + data.serial_number, + this.model.serialNumber, + 'Revoke request made with serial number' + ); + return { + data: { + revocation_time: 1673972804, + revocation_time_rfc3339: '2023-01-17T16:26:44.960933411Z', + }, + }; + }); + + await render(hbs``, { owner: this.engine }); + + assert + .dom('[data-test-component="info-table-row"]') + .exists({ count: 6 }, 'Correct number of fields render when certificate has not been revoked'); + assert + .dom('[data-test-value-div="Certificate"] [data-test-masked-input]') + .exists('Masked input renders for certificate'); + assert.dom('[data-test-value-div="Serial number"] code').exists('Serial number renders as monospace'); + + await click('[data-test-pki-cert-download-button]'); + const { serialNumber, certificate } = this.model; + assert.ok( + this.downloadSpy.calledWith(serialNumber.replace(/(\s|:)+/g, '-'), certificate), + 'Download pem method called with correct args' + ); + + await click('[data-test-confirm-action-trigger]'); + await click('[data-test-confirm-button]'); + + assert.dom('[data-test-value-div="Revocation time"]').exists('Revocation time is displayed'); + }); + + test('it should render back button', async function (assert) { + assert.expect(1); + + this.cancel = () => assert.ok('onBack action is triggered'); + + await render(hbs``, { + owner: this.engine, + }); + await click('[data-test-pki-cert-details-back]'); + }); + + test('it should send action on revoke if provided', async function (assert) { + assert.expect(1); + + this.server.post('/pki/revoke', () => ({ + data: { + revocation_time: 1673972804, + revocation_time_rfc3339: '2023-01-17T16:26:44.960933411Z', + }, + })); + + this.revoked = () => assert.ok('onRevoke action is triggered'); + + await render(hbs``, { + owner: this.engine, + }); + await click('[data-test-confirm-action-trigger]'); + await click('[data-test-confirm-button]'); + }); +}); From 15de5bb3dce4bbfb49a54052a90e7dcf7fca7834 Mon Sep 17 00:00:00 2001 From: Jordan Reimer Date: Tue, 17 Jan 2023 13:12:23 -0700 Subject: [PATCH 2/4] adds tests for pki base adapter --- .../adapters/pki/certificate/base-test.js | 57 +++++++++++++++++++ .../adapters/pki/certificate/generate-test.js | 16 ------ .../adapters/pki/certificate/sign-test.js | 15 ----- 3 files changed, 57 insertions(+), 31 deletions(-) create mode 100644 ui/tests/unit/adapters/pki/certificate/base-test.js diff --git a/ui/tests/unit/adapters/pki/certificate/base-test.js b/ui/tests/unit/adapters/pki/certificate/base-test.js new file mode 100644 index 000000000000..6cdd0c1cbca5 --- /dev/null +++ b/ui/tests/unit/adapters/pki/certificate/base-test.js @@ -0,0 +1,57 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'vault/tests/helpers'; +import { setupMirage } from 'ember-cli-mirage/test-support'; + +module('Unit | Adapter | pki/certificate/base', function (hooks) { + setupTest(hooks); + setupMirage(hooks); + + hooks.beforeEach(function () { + this.store = this.owner.lookup('service:store'); + this.owner.lookup('service:secretMountPath').update('pki-test'); + }); + + test('it should make request to correct endpoint on queryRecord', async function (assert) { + assert.expect(1); + + this.server.get('/pki-test/cert/1234', () => { + assert.ok(true, 'Request made to correct endpoint on queryRecord'); + return { data: {} }; + }); + + await this.store.queryRecord('pki/certificate/base', { backend: 'pki-test', id: '1234' }); + }); + + test('it should make request to correct endpoint on query', async function (assert) { + assert.expect(1); + + this.server.get('/pki-test/certs', (schema, req) => { + assert.strictEqual(req.queryParams.list, 'true', 'Request made to correct endpoint on query'); + return { data: { keys: [] } }; + }); + + await this.store.query('pki/certificate/base', { backend: 'pki-test' }); + }); + + test('it should make request to correct endpoint on update', async function (assert) { + assert.expect(1); + + this.store.pushPayload('pki/certificate/base', { + modelName: 'pki/certificate/base', + data: { + serial_number: '1234', + }, + }); + + this.server.post('pki-test/revoke', (schema, req) => { + assert.deepEqual( + JSON.parse(req.requestBody), + { serial_number: '1234' }, + 'Request made to correct endpoint on update' + ); + return { data: {} }; + }); + + await this.store.peekRecord('pki/certificate/base', '1234').save(); + }); +}); diff --git a/ui/tests/unit/adapters/pki/certificate/generate-test.js b/ui/tests/unit/adapters/pki/certificate/generate-test.js index 6485465d2bcc..b809afaa6645 100644 --- a/ui/tests/unit/adapters/pki/certificate/generate-test.js +++ b/ui/tests/unit/adapters/pki/certificate/generate-test.js @@ -35,20 +35,4 @@ module('Unit | Adapter | pki/certificate/generate', function (hooks) { const model = await this.store.createRecord('pki/certificate/generate', generateData); await model.save(); }); - - test('it should make request to correct endpoint on delete', async function (assert) { - assert.expect(2); - this.store.pushPayload('pki/certificate/generate', { - modelName: 'pki/certificate/generate', - ...this.data, - }); - this.server.post(`${this.backend}/revoke`, (schema, req) => { - assert.deepEqual(JSON.parse(req.requestBody), { serial_number: 'my-serial-number' }); - assert.ok(true, 'request made to correct endpoint on delete'); - return { data: {} }; - }); - - const model = await this.store.peekRecord('pki/certificate/generate', this.data.serial_number); - await model.destroyRecord(); - }); }); diff --git a/ui/tests/unit/adapters/pki/certificate/sign-test.js b/ui/tests/unit/adapters/pki/certificate/sign-test.js index 8ee54d733057..c0b9e0893934 100644 --- a/ui/tests/unit/adapters/pki/certificate/sign-test.js +++ b/ui/tests/unit/adapters/pki/certificate/sign-test.js @@ -47,19 +47,4 @@ module('Unit | Adapter | pki/certificate/sign', function (hooks) { await this.store.createRecord('pki/certificate/sign', generateData).save(); }); - - test('it should make request to correct endpoint on delete', async function (assert) { - assert.expect(2); - this.store.pushPayload('pki/certificate/sign', { - modelName: 'pki/certificate/sign', - ...this.data, - }); - this.server.post(`${this.backend}/revoke`, (schema, req) => { - assert.deepEqual(JSON.parse(req.requestBody), { serial_number: 'my-serial-number' }); - assert.ok(true, 'request made to correct endpoint on delete'); - return { data: {} }; - }); - - await this.store.peekRecord('pki/certificate/sign', this.data.serial_number).destroyRecord(); - }); }); From 897a1f9c42032de1c51197e6c82e35c4a917c2be Mon Sep 17 00:00:00 2001 From: Jordan Reimer Date: Tue, 17 Jan 2023 16:30:15 -0700 Subject: [PATCH 3/4] adds more comments --- ui/app/serializers/pki/certificate/base.js | 1 + ui/lib/pki/addon/components/page/pki-certificate-details.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/ui/app/serializers/pki/certificate/base.js b/ui/app/serializers/pki/certificate/base.js index d444eeb44234..30e904ae7d77 100644 --- a/ui/app/serializers/pki/certificate/base.js +++ b/ui/app/serializers/pki/certificate/base.js @@ -13,6 +13,7 @@ export default class PkiCertificateBaseSerializer extends ApplicationSerializer // Parse certificate back from the API and add to payload const parsedCert = parseCertificate(payload.data.certificate); // convert issueDate to same format as other date values + // this can be moved into the parseCertificate helper once the old pki implementation is removed if (parsedCert.issue_date) { parsedCert.issue_date = parsedCert.issue_date.valueOf(); } diff --git a/ui/lib/pki/addon/components/page/pki-certificate-details.ts b/ui/lib/pki/addon/components/page/pki-certificate-details.ts index c102bdc867f4..c3860892bd42 100644 --- a/ui/lib/pki/addon/components/page/pki-certificate-details.ts +++ b/ui/lib/pki/addon/components/page/pki-certificate-details.ts @@ -33,6 +33,7 @@ export default class PkiCertificateDetailsComponent extends Component { @waitFor *revoke() { try { + // the adapter updateRecord method calls the revoke endpoint since it is the only way to update a cert yield this.args.model.save(); this.flashMessages.success('The certificate has been revoked.'); if (this.args.onRevoke) { From 8cebe2b8d6a4b265f0ea9f7cdfa64e1105184929 Mon Sep 17 00:00:00 2001 From: Jordan Reimer Date: Tue, 17 Jan 2023 17:24:23 -0700 Subject: [PATCH 4/4] updates remaining pki/certificate model references to pki/certificate/base --- ui/lib/pki/addon/components/page/pki-overview.hbs | 2 +- ui/tests/integration/components/pki/page/pki-overview-test.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/lib/pki/addon/components/page/pki-overview.hbs b/ui/lib/pki/addon/components/page/pki-overview.hbs index caf511b1ac01..4561584afbd6 100644 --- a/ui/lib/pki/addon/components/page/pki-overview.hbs +++ b/ui/lib/pki/addon/components/page/pki-overview.hbs @@ -60,7 +60,7 @@