mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-30 02:02:43 +00:00
UI: Move useOpenApi and getHelpUrl methods to util (#27764)
* Add map between model types and helpUrls, update tests * replace modelProto.getHelpUrl with new helper util * Remove all useOpenApi and getHelpUrl instances from models * Add missing auth config model type
This commit is contained in:
@@ -7,7 +7,4 @@ import Model, { belongsTo } from '@ember-data/model';
|
||||
|
||||
export default Model.extend({
|
||||
backend: belongsTo('auth-method', { inverse: 'authConfigs', readOnly: true, async: false }),
|
||||
getHelpUrl: function (backend) {
|
||||
return `/v1/auth/${backend}/config?help=1`;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -10,7 +10,6 @@ import { combineFieldGroups } from 'vault/utils/openapi-to-attrs';
|
||||
import fieldToAttrs from 'vault/utils/field-to-attrs';
|
||||
|
||||
export default AuthConfig.extend({
|
||||
useOpenAPI: true,
|
||||
tenantId: attr('string', {
|
||||
label: 'Tenant ID',
|
||||
helpText: 'The tenant ID for the Azure Active Directory organization',
|
||||
|
||||
@@ -10,7 +10,6 @@ import { combineFieldGroups } from 'vault/utils/openapi-to-attrs';
|
||||
import fieldToAttrs from 'vault/utils/field-to-attrs';
|
||||
|
||||
export default AuthConfig.extend({
|
||||
useOpenAPI: true,
|
||||
// We have to leave this here because the backend doesn't support the file type yet.
|
||||
credentials: attr('string', {
|
||||
editType: 'file',
|
||||
|
||||
@@ -10,7 +10,6 @@ import fieldToAttrs from 'vault/utils/field-to-attrs';
|
||||
import { combineFieldGroups } from 'vault/utils/openapi-to-attrs';
|
||||
|
||||
export default AuthConfig.extend({
|
||||
useOpenAPI: true,
|
||||
organization: attr('string'),
|
||||
baseUrl: attr('string', {
|
||||
label: 'Base URL',
|
||||
|
||||
@@ -10,7 +10,6 @@ import fieldToAttrs from 'vault/utils/field-to-attrs';
|
||||
import { combineFieldGroups } from 'vault/utils/openapi-to-attrs';
|
||||
|
||||
export default AuthConfig.extend({
|
||||
useOpenAPI: true,
|
||||
oidcDiscoveryUrl: attr('string', {
|
||||
label: 'OIDC discovery URL',
|
||||
helpText:
|
||||
|
||||
@@ -11,7 +11,6 @@ import { combineFieldGroups } from 'vault/utils/openapi-to-attrs';
|
||||
import fieldToAttrs from 'vault/utils/field-to-attrs';
|
||||
|
||||
export default AuthConfig.extend({
|
||||
useOpenAPI: true,
|
||||
kubernetesHost: attr('string', {
|
||||
helpText:
|
||||
'Host must be a host string, a host:port pair, or a URL to the base of the Kubernetes API server.',
|
||||
|
||||
@@ -11,7 +11,6 @@ import fieldToAttrs from 'vault/utils/field-to-attrs';
|
||||
import { combineFieldGroups } from 'vault/utils/openapi-to-attrs';
|
||||
|
||||
export default AuthConfig.extend({
|
||||
useOpenAPI: true,
|
||||
certificate: attr({
|
||||
label: 'Certificate',
|
||||
editType: 'file',
|
||||
|
||||
@@ -10,7 +10,6 @@ import fieldToAttrs from 'vault/utils/field-to-attrs';
|
||||
import { combineFieldGroups } from 'vault/utils/openapi-to-attrs';
|
||||
|
||||
export default AuthConfig.extend({
|
||||
useOpenAPI: true,
|
||||
orgName: attr('string', {
|
||||
helpText: 'Name of the organization to be used in the Okta API',
|
||||
}),
|
||||
|
||||
@@ -10,7 +10,6 @@ import { combineFieldGroups } from 'vault/utils/openapi-to-attrs';
|
||||
import fieldToAttrs from 'vault/utils/field-to-attrs';
|
||||
|
||||
export default AuthConfig.extend({
|
||||
useOpenAPI: true,
|
||||
host: attr('string'),
|
||||
secret: attr('string'),
|
||||
|
||||
|
||||
@@ -9,11 +9,7 @@ import { combineFieldGroups } from 'vault/utils/openapi-to-attrs';
|
||||
import fieldToAttrs from 'vault/utils/field-to-attrs';
|
||||
|
||||
export default Model.extend({
|
||||
useOpenAPI: true,
|
||||
ca: belongsTo('kmip/ca', { async: false, inverse: 'config' }),
|
||||
getHelpUrl(path) {
|
||||
return `/v1/${path}/config?help=1`;
|
||||
},
|
||||
|
||||
fieldGroups: computed('newFields', function () {
|
||||
let groups = [{ default: ['listenAddrs', 'connectionTimeout'] }];
|
||||
|
||||
@@ -36,13 +36,10 @@ export const COMPUTEDS = {
|
||||
};
|
||||
|
||||
export default Model.extend(COMPUTEDS, {
|
||||
useOpenAPI: true,
|
||||
backend: attr({ readOnly: true }),
|
||||
scope: attr({ readOnly: true }),
|
||||
name: attr({ readOnly: true }),
|
||||
getHelpUrl(path) {
|
||||
return `/v1/${path}/scope/example/role/example?help=1`;
|
||||
},
|
||||
|
||||
fieldGroups: computed('fields', 'defaultFields.length', 'tlsFields', function () {
|
||||
const groups = [{ TLS: this.tlsFields }];
|
||||
if (this.defaultFields.length) {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*/
|
||||
|
||||
import Model, { attr } from '@ember-data/model';
|
||||
import { assert } from '@ember/debug';
|
||||
import { service } from '@ember/service';
|
||||
import { withFormFields } from 'vault/decorators/model-form-fields';
|
||||
import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities';
|
||||
@@ -25,15 +24,9 @@ const certDisplayFields = ['certificate', 'commonName', 'revocationTime', 'seria
|
||||
export default class PkiCertificateBaseModel extends Model {
|
||||
@service secretMountPath;
|
||||
|
||||
get useOpenAPI() {
|
||||
return true;
|
||||
}
|
||||
get backend() {
|
||||
return this.secretMountPath.currentPath;
|
||||
}
|
||||
getHelpUrl() {
|
||||
assert('You must provide a helpUrl for OpenAPI', true);
|
||||
}
|
||||
|
||||
// The attributes parsed from parse-pki-cert util live here
|
||||
@attr parsedCertificate;
|
||||
|
||||
@@ -34,8 +34,5 @@ const certDisplayFields = [
|
||||
];
|
||||
@withFormFields(certDisplayFields, generateFromRole)
|
||||
export default class PkiCertificateGenerateModel extends PkiCertificateBaseModel {
|
||||
getHelpUrl(backend) {
|
||||
return `/v1/${backend}/issue/example?help=1`;
|
||||
}
|
||||
@attr('string') role; // role name to issue certificate against for request URL
|
||||
}
|
||||
|
||||
@@ -23,9 +23,6 @@ const generateFromRole = [
|
||||
];
|
||||
@withFormFields(null, generateFromRole)
|
||||
export default class PkiCertificateSignModel extends PkiCertificateBaseModel {
|
||||
getHelpUrl(backend) {
|
||||
return `/v1/${backend}/sign/example?help=1`;
|
||||
}
|
||||
@attr('string') role; // role name to create certificate against for request URL
|
||||
|
||||
@attr('string', {
|
||||
|
||||
@@ -10,16 +10,8 @@ import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities';
|
||||
@withFormFields()
|
||||
export default class PkiConfigAcmeModel extends Model {
|
||||
// This model uses the backend value as the model ID
|
||||
get useOpenAPI() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getHelpUrl(backendPath) {
|
||||
return `/v1/${backendPath}/config/acme?help=1`;
|
||||
}
|
||||
|
||||
// attrs order in the form is determined by order here
|
||||
|
||||
@attr('boolean', {
|
||||
label: 'ACME enabled',
|
||||
subText: 'When ACME is disabled, all requests to ACME directory URLs will return 404.',
|
||||
|
||||
@@ -10,13 +10,6 @@ import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities';
|
||||
@withFormFields()
|
||||
export default class PkiConfigClusterModel extends Model {
|
||||
// This model uses the backend value as the model ID
|
||||
get useOpenAPI() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getHelpUrl(backendPath) {
|
||||
return `/v1/${backendPath}/config/cluster?help=1`;
|
||||
}
|
||||
|
||||
@attr('string', {
|
||||
label: "Mount's API path",
|
||||
|
||||
@@ -10,12 +10,6 @@ import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities';
|
||||
@withFormFields()
|
||||
export default class PkiConfigUrlsModel extends Model {
|
||||
// This model uses the backend value as the model ID
|
||||
get useOpenAPI() {
|
||||
return true;
|
||||
}
|
||||
getHelpUrl(backendPath) {
|
||||
return `/v1/${backendPath}/config/urls?help=1`;
|
||||
}
|
||||
|
||||
@attr({
|
||||
label: 'Issuing certificates',
|
||||
|
||||
@@ -27,10 +27,7 @@ const displayFields = [
|
||||
@withFormFields(inputFields, displayFields)
|
||||
export default class PkiIssuerModel extends Model {
|
||||
@service secretMountPath;
|
||||
// TODO use openAPI after removing route extension (see pki/roles route for example)
|
||||
get useOpenAPI() {
|
||||
return false;
|
||||
}
|
||||
|
||||
get backend() {
|
||||
return this.secretMountPath.currentPath;
|
||||
}
|
||||
|
||||
@@ -18,14 +18,6 @@ const validations = {
|
||||
export default class PkiRoleModel extends Model {
|
||||
@service version; // noStoreMetadata is enterprise-only, so we need this available
|
||||
|
||||
get useOpenAPI() {
|
||||
// must be a getter so it can be accessed in path-help.js
|
||||
return true;
|
||||
}
|
||||
getHelpUrl(backend) {
|
||||
return `/v1/${backend}/roles/example?help=1`;
|
||||
}
|
||||
|
||||
@attr('string', { readOnly: true }) backend;
|
||||
|
||||
get formFieldGroups() {
|
||||
|
||||
@@ -25,10 +25,6 @@ const validations = {
|
||||
'maxPathLength',
|
||||
])
|
||||
export default class PkiSignIntermediateModel extends PkiCertificateBaseModel {
|
||||
getHelpUrl(backend) {
|
||||
return `/v1/${backend}/issuer/example/sign-intermediate?help=1`;
|
||||
}
|
||||
|
||||
@attr issuerRef;
|
||||
|
||||
@attr('string', {
|
||||
|
||||
@@ -125,14 +125,6 @@ export default class PkiTidyModel extends Model {
|
||||
})
|
||||
tidyRevokedCerts;
|
||||
|
||||
get useOpenAPI() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getHelpUrl(backend) {
|
||||
return `/v1/${backend}/config/auto-tidy?help=1`;
|
||||
}
|
||||
|
||||
get allGroups() {
|
||||
const groups = [{ autoTidy: ['enabled', 'intervalDuration'] }, ...this.sharedFields];
|
||||
return this._expandGroups(groups);
|
||||
|
||||
@@ -47,10 +47,6 @@ const CA_FIELDS = [
|
||||
];
|
||||
|
||||
export default Model.extend({
|
||||
useOpenAPI: true,
|
||||
getHelpUrl: function (backend) {
|
||||
return `/v1/${backend}/roles/example?help=1`;
|
||||
},
|
||||
zeroAddress: attr('boolean', {
|
||||
readOnly: true,
|
||||
}),
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
filterPathsByItemType,
|
||||
pathToHelpUrlSegment,
|
||||
reducePathsByPathName,
|
||||
getHelpUrlForModel,
|
||||
} from 'vault/utils/openapi-helpers';
|
||||
import { isPresent } from '@ember/utils';
|
||||
|
||||
@@ -53,17 +54,17 @@ export default Service.extend({
|
||||
const modelName = `model:${modelType}`;
|
||||
|
||||
const modelFactory = owner.factoryFor(modelName);
|
||||
let newModel, helpUrl;
|
||||
let helpUrl = getHelpUrlForModel(modelType, backend);
|
||||
|
||||
let newModel;
|
||||
// if we have a factory, we need to take the existing model into account
|
||||
if (modelFactory) {
|
||||
debug(`Model factory found for ${modelType}`);
|
||||
newModel = modelFactory.class;
|
||||
const modelProto = newModel.proto();
|
||||
if (newModel.merged || modelProto.useOpenAPI !== true) {
|
||||
if (newModel.merged || !helpUrl) {
|
||||
return resolve();
|
||||
}
|
||||
|
||||
helpUrl = modelProto.getHelpUrl(backend);
|
||||
return this.registerNewModelWithProps(helpUrl, backend, newModel, modelName);
|
||||
} else {
|
||||
debug(`Creating new Model for ${modelType}`);
|
||||
@@ -73,7 +74,6 @@ export default Service.extend({
|
||||
// we don't have an apiPath for dynamic secrets
|
||||
// and we don't need paths for them yet
|
||||
if (!apiPath) {
|
||||
helpUrl = newModel.proto().getHelpUrl(backend);
|
||||
return this.registerNewModelWithProps(helpUrl, backend, newModel, modelName);
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ export default Service.extend({
|
||||
return reject();
|
||||
}
|
||||
|
||||
helpUrl = `/v1/${apiPath}${path.slice(1)}?help=true` || newModel.proto().getHelpUrl(backend);
|
||||
helpUrl = `/v1/${apiPath}${path.slice(1)}?help=true`;
|
||||
pathInfo.paths = paths;
|
||||
newModel = newModel.extend({ paths: pathInfo });
|
||||
return this.registerNewModelWithProps(helpUrl, backend, newModel, modelName);
|
||||
|
||||
@@ -132,3 +132,37 @@ export function filterPathsByItemType(pathInfo: PathsInfo, itemType: string): Pa
|
||||
return itemType === path.itemType;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This object maps model names to the openAPI path that hydrates the model, given the backend path.
|
||||
*/
|
||||
const OPENAPI_POWERED_MODELS = {
|
||||
'role-ssh': (backend: string) => `/v1/${backend}/roles/example?help=1`,
|
||||
'auth-config/azure': (backend: string) => `/v1/auth/${backend}/config?help=1`,
|
||||
'auth-config/cert': (backend: string) => `/v1/auth/${backend}/config?help=1`,
|
||||
'auth-config/gcp': (backend: string) => `/v1/auth/${backend}/config?help=1`,
|
||||
'auth-config/github': (backend: string) => `/v1/auth/${backend}/config?help=1`,
|
||||
'auth-config/jwt': (backend: string) => `/v1/auth/${backend}/config?help=1`,
|
||||
'auth-config/kubernetes': (backend: string) => `/v1/auth/${backend}/config?help=1`,
|
||||
'auth-config/ldap': (backend: string) => `/v1/auth/${backend}/config?help=1`,
|
||||
'auth-config/okta': (backend: string) => `/v1/auth/${backend}/config?help=1`,
|
||||
'auth-config/radius': (backend: string) => `/v1/auth/${backend}/config?help=1`,
|
||||
'kmip/config': (backend: string) => `/v1/${backend}/config?help=1`,
|
||||
'kmip/role': (backend: string) => `/v1/${backend}/scope/example/role/example?help=1`,
|
||||
'pki/role': (backend: string) => `/v1/${backend}/roles/example?help=1`,
|
||||
'pki/tidy': (backend: string) => `/v1/${backend}/config/auto-tidy?help=1`,
|
||||
'pki/sign-intermediate': (backend: string) => `/v1/${backend}/issuer/example/sign-intermediate?help=1`,
|
||||
'pki/certificate/generate': (backend: string) => `/v1/${backend}/issue/example?help=1`,
|
||||
'pki/certificate/sign': (backend: string) => `/v1/${backend}/sign/example?help=1`,
|
||||
'pki/config/acme': (backend: string) => `/v1/${backend}/config/acme?help=1`,
|
||||
'pki/config/cluster': (backend: string) => `/v1/${backend}/config/cluster?help=1`,
|
||||
'pki/config/urls': (backend: string) => `/v1/${backend}/config/urls?help=1`,
|
||||
};
|
||||
|
||||
export function getHelpUrlForModel(modelType: string, backend: string) {
|
||||
const urlFn = OPENAPI_POWERED_MODELS[modelType as keyof typeof OPENAPI_POWERED_MODELS] as (
|
||||
backend: string
|
||||
) => string;
|
||||
if (!urlFn) return null;
|
||||
return urlFn(backend);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import authPage from 'vault/tests/pages/auth';
|
||||
import { deleteAuthCmd, deleteEngineCmd, mountAuthCmd, mountEngineCmd, runCmd } from '../helpers/commands';
|
||||
import expectedSecretAttrs from 'vault/tests/helpers/openapi/expected-secret-attrs';
|
||||
import expectedAuthAttrs from 'vault/tests/helpers/openapi/expected-auth-attrs';
|
||||
import { getHelpUrlForModel } from 'vault/utils/openapi-helpers';
|
||||
|
||||
/**
|
||||
* This set of tests is for ensuring that backend changes to the OpenAPI spec
|
||||
@@ -72,8 +73,7 @@ function secretEngineHelper(test, secretEngine) {
|
||||
// A given secret engine might have multiple models that are openApi driven
|
||||
modelNames.forEach((modelName) => {
|
||||
test(`${modelName} model getProps returns correct attributes`, async function (assert) {
|
||||
const model = this.store.createRecord(modelName, {});
|
||||
const helpUrl = model.getHelpUrl(this.backend);
|
||||
const helpUrl = getHelpUrlForModel(modelName, this.backend);
|
||||
const result = await this.pathHelp.getProps(helpUrl, this.backend);
|
||||
const expected = engineData[modelName];
|
||||
// Expected values should be updated to match "actual" (result)
|
||||
@@ -98,8 +98,7 @@ function authEngineHelper(test, authBackend) {
|
||||
if (itemName.startsWith('auth-config/')) {
|
||||
// Config test doesn't need to instantiate a new model
|
||||
test(`${itemName} model`, async function (assert) {
|
||||
const model = this.store.createRecord(itemName, {});
|
||||
const helpUrl = model.getHelpUrl(this.mount);
|
||||
const helpUrl = getHelpUrlForModel(itemName, this.mount);
|
||||
const result = await this.pathHelp.getProps(helpUrl, this.mount);
|
||||
const expected = authData[itemName];
|
||||
assert.deepEqual(
|
||||
@@ -116,9 +115,8 @@ function authEngineHelper(test, authBackend) {
|
||||
const modelName = `generated-${itemName}-${authBackend}`;
|
||||
// Generated items need to instantiate the model first via getNewModel
|
||||
await this.pathHelp.getNewModel(modelName, this.mount, `auth/${this.mount}/`, itemName);
|
||||
const model = this.store.createRecord(modelName, {});
|
||||
// Generated items don't have this method -- helpUrl is calculated in path-help.js line 101
|
||||
const helpUrl = model.getHelpUrl(this.mount);
|
||||
// Generated items don't have helpUrl method -- helpUrl is calculated in path-help.js line 101
|
||||
const helpUrl = `/v1/auth/${this.mount}?help=1`;
|
||||
const result = await this.pathHelp.getProps(helpUrl, this.mount);
|
||||
const expected = authData[modelName];
|
||||
assert.deepEqual(result, expected, `getProps returns expected attributes for ${modelName}`);
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
*/
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { _getPathParam, pathToHelpUrlSegment } from 'vault/utils/openapi-helpers';
|
||||
import { _getPathParam, getHelpUrlForModel, pathToHelpUrlSegment } from 'vault/utils/openapi-helpers';
|
||||
|
||||
module('Unit | Utility | OpenAPI helper utils', function () {
|
||||
test(`pathToHelpUrlSegment`, function (assert) {
|
||||
assert.expect(5);
|
||||
[
|
||||
{ path: '/auth/{username}', result: '/auth/example' },
|
||||
{ path: '{username}/foo', result: 'example/foo' },
|
||||
@@ -21,7 +20,6 @@ module('Unit | Utility | OpenAPI helper utils', function () {
|
||||
});
|
||||
|
||||
test(`_getPathParam`, function (assert) {
|
||||
assert.expect(7);
|
||||
[
|
||||
{ path: '/auth/{username}', result: 'username' },
|
||||
{ path: '{unicorn}/foo', result: 'unicorn' },
|
||||
@@ -34,4 +32,20 @@ module('Unit | Utility | OpenAPI helper utils', function () {
|
||||
assert.strictEqual(_getPathParam(test.path), test.result, `returns first param for ${test.path}`);
|
||||
});
|
||||
});
|
||||
|
||||
test(`getHelpUrlForModel`, function (assert) {
|
||||
[
|
||||
{ modelType: 'kmip/config', result: '/v1/foobar/config?help=1' },
|
||||
{ modelType: 'does-not-exist', result: null },
|
||||
{ modelType: 4, result: null },
|
||||
{ modelType: '', result: null },
|
||||
{ modelType: undefined, result: null },
|
||||
].forEach((test) => {
|
||||
assert.strictEqual(
|
||||
getHelpUrlForModel(test.modelType, 'foobar'),
|
||||
test.result,
|
||||
`returns first param for ${test.path}`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
import Model from '@ember-data/model';
|
||||
export default class PkiCertificateBaseModel extends Model {
|
||||
secretMountPath: class;
|
||||
get useOpenAPI(): boolean;
|
||||
get backend(): string;
|
||||
getHelpUrl(): void;
|
||||
altNames: string;
|
||||
commonName: string;
|
||||
caChain: string;
|
||||
|
||||
2
ui/types/vault/models/pki/config/urls.d.ts
vendored
2
ui/types/vault/models/pki/config/urls.d.ts
vendored
@@ -6,8 +6,6 @@
|
||||
import Model from '@ember-data/model';
|
||||
|
||||
export default class PkiConfigUrlsModel extends Model {
|
||||
get useOpenAPI(): boolean;
|
||||
getHelpUrl(backendPath: string): string;
|
||||
issuingCertificates: array;
|
||||
crlDistributionPoints: array;
|
||||
ocspServers: array;
|
||||
|
||||
1
ui/types/vault/models/pki/issuer.d.ts
vendored
1
ui/types/vault/models/pki/issuer.d.ts
vendored
@@ -8,7 +8,6 @@ import { FormField, FormFieldGroups, ModelValidations } from 'vault/app-types';
|
||||
import { ParsedCertificateData } from 'vault/vault/utils/parse-pki-cert';
|
||||
export default class PkiIssuerModel extends Model {
|
||||
secretMountPath: class;
|
||||
get useOpenAPI(): boolean;
|
||||
get backend(): string;
|
||||
get issuerRef(): string;
|
||||
certificate: string;
|
||||
|
||||
2
ui/types/vault/models/pki/role.d.ts
vendored
2
ui/types/vault/models/pki/role.d.ts
vendored
@@ -7,10 +7,8 @@ import Model from '@ember-data/model';
|
||||
import { ModelValidations } from 'vault/app-types';
|
||||
|
||||
export default class PkiRoleModel extends Model {
|
||||
get useOpenAPI(): boolean;
|
||||
name: string;
|
||||
issuerRef: string;
|
||||
getHelpUrl(backendPath: string): string;
|
||||
validate(): ModelValidations;
|
||||
isNew: boolean;
|
||||
keyType: string;
|
||||
|
||||
2
ui/types/vault/models/pki/tidy.d.ts
vendored
2
ui/types/vault/models/pki/tidy.d.ts
vendored
@@ -24,8 +24,6 @@ export default class PkiTidyModel extends Model {
|
||||
tidyRevocationQueue: boolean;
|
||||
tidyRevokedCertIssuerAssociations: boolean;
|
||||
tidyRevokedCerts: boolean;
|
||||
get useOpenAPI(): boolean;
|
||||
getHelpUrl(backend: string): string;
|
||||
allByKey: {
|
||||
intervalDuration: FormField[];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user