vault/ui/lib/pki/addon/components/pki-generate-csr.ts
hashicorp-copywrite[bot] 0b12cdcfd1
[COMPLIANCE] License changes (#22290)
* Adding explicit MPL license for sub-package.

This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository.

* Adding explicit MPL license for sub-package.

This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository.

* Updating the license from MPL to Business Source License.

Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at https://hashi.co/bsl-blog, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl.

* add missing license headers

* Update copyright file headers to BUS-1.1

* Fix test that expected exact offset on hcl file

---------

Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
Co-authored-by: Sarah Thompson <sthompson@hashicorp.com>
Co-authored-by: Brian Kassouf <bkassouf@hashicorp.com>
2023-08-10 18:14:03 -07:00

109 lines
3.7 KiB
TypeScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { task } from 'ember-concurrency';
import { waitFor } from '@ember/test-waiters';
import { expandAttributeMeta } from 'vault/utils/field-to-attrs';
import errorMessage from 'vault/utils/error-message';
import type FlashMessageService from 'vault/services/flash-messages';
import type PkiActionModel from 'vault/models/pki/action';
import type { ValidationMap } from 'vault/vault/app-types';
interface Args {
model: PkiActionModel;
useIssuer: boolean;
onComplete: CallableFunction;
onCancel: CallableFunction;
onSave?: CallableFunction;
}
/**
* @module PkiGenerateCsrComponent
* PkiGenerateCsr shows only the fields valid for the generate CSR endpoint.
* This component renders the form, handles the model save and rollback actions,
* and shows the resulting data on success. onCancel is required for the cancel
* transition, and if onSave is provided it will call that after save for any
* side effects in the parent.
*
* @example
* ```js
* <PkiGenerateRoot @model={{this.model}} @onCancel={{transition-to "vault.cluster"}} @onSave={{fn (mut this.title) "Successful"}} @adapterOptions={{hash actionType="import" useIssuer=false}} />
* ```
*
* @param {Object} model - pki/action model.
* @callback onCancel - Callback triggered when cancel button is clicked, after model is unloaded
* @callback onSave - Optional - Callback triggered after model is saved, as a side effect. Results are shown on the same component
* @callback onComplete - Callback triggered when "Done" button clicked, on results view
* @param {Object} adapterOptions - object passed as adapterOptions on the model.save method
*/
export default class PkiGenerateCsrComponent extends Component<Args> {
@service declare readonly flashMessages: FlashMessageService;
@tracked modelValidations: ValidationMap | null = null;
@tracked error: string | null = null;
@tracked alert: string | null = null;
formFields;
// fields rendered after CSR generation
showFields = ['csr', 'keyId', 'privateKey', 'privateKeyType'];
constructor(owner: unknown, args: Args) {
super(owner, args);
this.formFields = expandAttributeMeta(this.args.model, [
'type',
'commonName',
'excludeCnFromSans',
'format',
'subjectSerialNumber',
'addBasicConstraints',
]);
}
@action
cancel() {
this.args.model.unloadRecord();
this.args.onCancel();
}
async getCapability(): Promise<boolean> {
try {
const issuerCapabilities = await this.args.model.generateIssuerCsrPath;
return issuerCapabilities.get('canCreate') === true;
} catch (error) {
return false;
}
}
@task
@waitFor
*save(event: Event): Generator<Promise<boolean | PkiActionModel>> {
event.preventDefault();
try {
const { model, onSave } = this.args;
const { isValid, state, invalidFormMessage } = model.validate();
if (isValid) {
const useIssuer = yield this.getCapability();
yield model.save({ adapterOptions: { actionType: 'generate-csr', useIssuer } });
this.flashMessages.success('Successfully generated CSR.');
// This component shows the results, but call `onSave` for any side effects on parent
if (onSave) {
onSave();
}
window?.scrollTo(0, 0);
} else {
this.modelValidations = state;
this.alert = invalidFormMessage;
}
} catch (e) {
this.error = errorMessage(e);
this.alert = 'There was a problem generating the CSR.';
}
}
}