vault/ui/app/models/totp-key.js
lane-wetmore 9998650de4
UI: Update TOTP QR default size and hide when 0 (#30636)
* update default qr size, hide when 0 and add test

* update test
2025-05-15 12:30:24 -05:00

192 lines
5.1 KiB
JavaScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import Model, { attr } from '@ember-data/model';
import { withFormFields } from 'vault/decorators/model-form-fields';
import { withModelValidations } from 'vault/decorators/model-validations';
import { withExpandedAttributes } from 'vault/decorators/model-expanded-attributes';
import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities';
import { isPresent } from '@ember/utils';
const validations = {
accountName: [
{
validator(model) {
const { generate, accountName } = model;
// this is required when generate is true
return generate && !isPresent(accountName) ? false : true;
},
message: "Account name can't be blank when the key is generated by Vault.",
},
{
type: 'containsWhiteSpace',
message:
"Account name contains whitespace. If this is desired, you'll need to encode it with %20 in API requests.",
level: 'warn',
},
],
issuer: [
{
validator(model) {
const { generate, issuer } = model;
// this is required when generate is true
return generate && !isPresent(issuer) ? false : true;
},
message: "Issuer can't be blank when when the key is generated by Vault.",
},
],
key: [
{
validator(model) {
const { generate, key, url } = model;
// this is required when generate is false and url is blank
return !generate && !isPresent(url) && !isPresent(key) ? false : true;
},
message: "Key can't be blank if key is being passed from another service and the URL is empty.",
},
],
keySize: [{ type: 'number', message: 'Key size must be a number.' }],
name: [
{ type: 'presence', message: "Name can't be blank." },
{
type: 'containsWhiteSpace',
message:
"Name contains whitespace. If this is desired, you'll need to encode it with %20 in API requests.",
level: 'warn',
},
],
qrSize: [{ type: 'number', message: 'QR size must be a number' }],
};
@withModelValidations(validations)
@withExpandedAttributes()
@withFormFields()
export default class TotpKeyModel extends Model {
@attr('string', {
readOnly: true,
})
backend;
@attr('string', {
subText: 'Specifies the name for this key.',
})
name;
@attr('string', {
subText: 'The name of the account associated with the key. Required for keys generated by Vault.',
})
accountName;
@attr('string', {
possibleValues: ['SHA1', 'SHA256', 'SHA512'],
defaultValue: 'SHA1',
})
algorithm;
@attr('number', {
possibleValues: [6, 8],
defaultValue: 6,
})
digits;
@attr('string', {
subText: `The name of the key's issuing organization. Required for keys generated by Vault.`,
})
issuer;
@attr({
editType: 'ttl',
helperTextEnabled: 'How long each generated TOTP is valid.',
defaultValue: 30, // API accepts both an integer as seconds and string with unit e.g 30 || '30s'
})
period;
// The generate attr is a boolean. The generateString getter and setter is used only in forms to get and set the boolean via
// strings values. The payload params expect the attr to be a boolean value.
@attr({
label: 'Key Provider',
defaultValue: true,
editType: 'radio',
possibleValues: ['Vault', 'Other service'],
fieldValue: 'generateString',
subText: 'Specifies if the key should be generated by Vault or passed from another service.',
})
generate;
// Used when generate is true
@attr('number', {
defaultValue: 20,
})
keySize;
@attr('number', {
possibleValues: [0, 1],
defaultValue: 1,
})
skew;
@attr('boolean', {
editType: 'toggleButton',
defaultValue: true,
helperTextDisabled: 'Vault will not return QR code and url upon key creation.',
helperTextEnabled: 'QR code and URL will be returned upon generating a key.',
})
exported;
@attr('number', {
label: 'QR size',
defaultValue: 200,
})
qrSize;
// Used when generate is false
@attr('string', {
label: 'URL',
helpText:
'If a URL is provided the other fields can be left empty. E.g. otpauth://totp/Vault:test@test.com?secret=Y64VEVMBTSXCYIWRSHRNDZW62MPGVU2G&issuer=Vault',
subText: 'The TOTP key url string that can be used to configure a key.',
})
url;
@attr('string', {
subText: 'The root key used to generate a TOTP code.',
})
key;
// Returned when a key is created as provider
@attr('string', {
readOnly: true,
})
barcode;
get attrs() {
const keys = ['accountName', 'name', 'algorithm', 'digits', 'issuer', 'period'];
return keys.map((k) => this.allByKey[k]);
}
get generatedAttrs() {
const keys = ['url'];
return keys.map((k) => this.allByKey[k]);
}
get generateString() {
return this.generate ? 'Vault' : 'Other service';
}
set generateString(value) {
this.generate = value === 'Vault' ? true : false;
}
@lazyCapabilities(apiPath`${'backend'}/keys/${'id'}`, 'backend', 'id') keyPath;
get canDelete() {
return this.keyPath.get('canDelete');
}
get canRead() {
return this.keyPath.get('canRead');
}
}