2018-06-26 21:35:47 +00:00
|
|
|
|
<SplashPage as |Page|>
|
2019-10-14 18:23:29 +00:00
|
|
|
|
{{#if (and this.model.usingRaft (not this.prefersInit))}}
|
|
|
|
|
<Page.header>
|
|
|
|
|
<h1 class="title is-4">
|
|
|
|
|
Raft Storage
|
|
|
|
|
</h1>
|
|
|
|
|
</Page.header>
|
|
|
|
|
<Page.content>
|
|
|
|
|
<RaftJoin @onDismiss={{action (mut prefersInit) true}} />
|
|
|
|
|
</Page.content>
|
|
|
|
|
{{else if keyData}}
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<Page.header>
|
2018-09-28 14:36:18 +00:00
|
|
|
|
{{#let (or keyData.recovery_keys keyData.keys) as |keyArray|}}
|
|
|
|
|
<h1 class="title is-4">
|
|
|
|
|
Vault has been initialized!
|
|
|
|
|
{{#if (eq keyArray.length 1)}}
|
|
|
|
|
Here is your key.
|
|
|
|
|
{{else}}
|
|
|
|
|
Here are your {{pluralize keyArray.length "key"}}.
|
|
|
|
|
{{/if}}
|
|
|
|
|
</h1>
|
|
|
|
|
{{/let}}
|
2018-06-26 21:35:47 +00:00
|
|
|
|
</Page.header>
|
|
|
|
|
<Page.content>
|
2018-04-03 14:16:57 +00:00
|
|
|
|
<div class="box is-marginless is-shadowless">
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<div class="content">
|
|
|
|
|
<p>
|
2018-09-28 14:36:18 +00:00
|
|
|
|
{{#if keyData.recovery_keys}}
|
|
|
|
|
Please securely distribute the keys below. Certain privileged operations in Vault such as rekeying the
|
|
|
|
|
barrier or generating a new root token will require you to provide
|
|
|
|
|
at least <strong class="has-text-danger">{{secret_threshold}}</strong> of these keys to perform the
|
|
|
|
|
operation.
|
|
|
|
|
{{else}}
|
|
|
|
|
Please securely distribute the keys below. When the Vault is re-sealed, restarted, or stopped, you must
|
|
|
|
|
provide at least <strong class="has-text-danger">{{secret_threshold}}</strong> of these keys to unseal it
|
|
|
|
|
again.
|
|
|
|
|
Vault does not store the master key. Without at least <strong class="has-text-danger">{{secret_threshold}}</strong>
|
|
|
|
|
keys, your Vault will remain permanently sealed.
|
|
|
|
|
{{/if}}
|
2018-06-26 21:35:47 +00:00
|
|
|
|
</p>
|
2018-04-03 14:16:57 +00:00
|
|
|
|
</div>
|
2018-09-28 14:36:18 +00:00
|
|
|
|
<div
|
2018-10-31 21:41:21 +00:00
|
|
|
|
class="message is-list is-highlight"
|
2018-09-28 14:36:18 +00:00
|
|
|
|
>
|
2018-04-03 14:16:57 +00:00
|
|
|
|
<div class="message-body">
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<h4 class="title is-7 is-marginless">
|
2019-03-29 23:40:12 +00:00
|
|
|
|
Initial root token
|
2018-04-03 14:16:57 +00:00
|
|
|
|
</h4>
|
2018-10-31 21:41:21 +00:00
|
|
|
|
<MaskedInput
|
|
|
|
|
@class="is-highlight has-label"
|
|
|
|
|
@displayOnly={{true}}
|
|
|
|
|
@value={{keyData.root_token}}
|
|
|
|
|
@allowCopy={{true}}
|
|
|
|
|
/>
|
2018-04-03 14:16:57 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2018-09-28 14:36:18 +00:00
|
|
|
|
{{#each (or keyData.recovery_keys_base64 keyData.recovery_keys keyData.keys_base64 keyData.keys) as |key index|}}
|
|
|
|
|
<div
|
|
|
|
|
data-test-key-box
|
2018-10-31 21:41:21 +00:00
|
|
|
|
class="message is-list"
|
2018-09-28 14:36:18 +00:00
|
|
|
|
>
|
2018-04-03 14:16:57 +00:00
|
|
|
|
<div class="message-body">
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<h4 class="title is-7 is-marginless">
|
2018-04-03 14:16:57 +00:00
|
|
|
|
Key {{add index 1}}
|
|
|
|
|
</h4>
|
2018-10-31 21:41:21 +00:00
|
|
|
|
<MaskedInput
|
|
|
|
|
@class="has-label"
|
|
|
|
|
@displayOnly={{true}}
|
|
|
|
|
@value={{key}}
|
|
|
|
|
@allowCopy={{true}}
|
|
|
|
|
/>
|
2018-04-03 14:16:57 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{{/each}}
|
|
|
|
|
</div>
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<div class="box is-marginless is-shadowless">
|
2018-04-03 14:16:57 +00:00
|
|
|
|
<div class="field is-grouped-split">
|
2018-09-28 14:36:18 +00:00
|
|
|
|
{{#if (and model.sealed (not keyData.recovery_keys))}}
|
|
|
|
|
<div
|
|
|
|
|
data-test-advance-button
|
|
|
|
|
class="control"
|
|
|
|
|
>
|
2018-04-03 14:16:57 +00:00
|
|
|
|
{{#link-to 'vault.cluster.unseal' model.name class="button is-primary"}}
|
2018-09-28 14:36:18 +00:00
|
|
|
|
Continue to Unseal
|
2018-04-03 14:16:57 +00:00
|
|
|
|
{{/link-to}}
|
|
|
|
|
</div>
|
|
|
|
|
{{else}}
|
2018-09-28 14:36:18 +00:00
|
|
|
|
<div
|
|
|
|
|
data-test-advance-button
|
|
|
|
|
class="control"
|
|
|
|
|
>
|
|
|
|
|
{{#link-to 'vault.cluster.auth'
|
|
|
|
|
model.name
|
|
|
|
|
class=(concat (if model.sealed 'is-loading ' '') 'button is-primary')
|
|
|
|
|
disabled=model.sealed
|
|
|
|
|
}}
|
|
|
|
|
Continue to Authenticate
|
2018-04-03 14:16:57 +00:00
|
|
|
|
{{/link-to}}
|
|
|
|
|
</div>
|
|
|
|
|
{{/if}}
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<DownloadButton
|
|
|
|
|
@data={{keyData}}
|
|
|
|
|
@filename={{keyFilename}}
|
|
|
|
|
@mime="application/json"
|
|
|
|
|
@extension="json"
|
|
|
|
|
@class="button is-ghost"
|
|
|
|
|
@stringify={{true}}
|
2018-09-28 14:36:18 +00:00
|
|
|
|
>
|
2019-05-13 19:05:25 +00:00
|
|
|
|
<Icon @glyph="download" /> Download keys
|
2018-06-26 21:35:47 +00:00
|
|
|
|
</DownloadButton>
|
2018-04-03 14:16:57 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2018-06-26 21:35:47 +00:00
|
|
|
|
</Page.content>
|
|
|
|
|
{{else}}
|
|
|
|
|
<Page.header>
|
|
|
|
|
<h1 class="title h5">
|
|
|
|
|
Let's set up the initial set of master keys that you’ll need in case of an emergency
|
|
|
|
|
</h1>
|
|
|
|
|
</Page.header>
|
|
|
|
|
<Page.content>
|
2018-09-28 14:36:18 +00:00
|
|
|
|
<form
|
|
|
|
|
{{action 'initCluster' (hash
|
|
|
|
|
secret_shares=secret_shares
|
|
|
|
|
secret_threshold=secret_threshold
|
|
|
|
|
pgp_keys=pgp_keys
|
|
|
|
|
use_pgp=use_pgp
|
|
|
|
|
use_pgp_for_root=use_pgp_for_root
|
|
|
|
|
root_token_pgp_key=root_token_pgp_key
|
2018-04-17 22:04:34 +00:00
|
|
|
|
)
|
|
|
|
|
on="submit"
|
|
|
|
|
}}
|
2018-09-28 14:36:18 +00:00
|
|
|
|
id="init"
|
2018-04-17 22:04:34 +00:00
|
|
|
|
>
|
|
|
|
|
<div class="box is-marginless is-shadowless">
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<MessageError @errors={{errors}} />
|
|
|
|
|
<div class="field">
|
2018-09-28 14:36:18 +00:00
|
|
|
|
<label
|
|
|
|
|
for="key-shares"
|
|
|
|
|
class="is-label"
|
|
|
|
|
>
|
2019-03-29 23:40:12 +00:00
|
|
|
|
Key shares
|
2018-06-26 21:35:47 +00:00
|
|
|
|
</label>
|
|
|
|
|
<div class="control">
|
2018-10-31 21:41:21 +00:00
|
|
|
|
{{input
|
|
|
|
|
data-test-key-shares="true"
|
|
|
|
|
class="input"
|
|
|
|
|
autocomplete="off"
|
2019-05-16 14:54:11 +00:00
|
|
|
|
spellcheck="false"
|
2018-10-31 21:41:21 +00:00
|
|
|
|
name="key-shares"
|
2018-09-28 14:36:18 +00:00
|
|
|
|
type="number"
|
2018-10-31 21:41:21 +00:00
|
|
|
|
step="1"
|
|
|
|
|
min="1"
|
|
|
|
|
pattern="[0-9]*"
|
2018-09-28 14:36:18 +00:00
|
|
|
|
value=secret_shares
|
|
|
|
|
}}
|
2018-04-03 14:16:57 +00:00
|
|
|
|
</div>
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<p class="help has-text-grey">
|
|
|
|
|
The number of key shares to split the master key into
|
|
|
|
|
</p>
|
2018-04-03 14:16:57 +00:00
|
|
|
|
</div>
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<div class="field">
|
2018-09-28 14:36:18 +00:00
|
|
|
|
<label
|
|
|
|
|
for="key-threshold"
|
|
|
|
|
class="is-label"
|
|
|
|
|
>
|
2019-03-29 23:40:12 +00:00
|
|
|
|
Key threshold
|
2018-06-26 21:35:47 +00:00
|
|
|
|
</label>
|
|
|
|
|
<div class="control">
|
2018-10-31 21:41:21 +00:00
|
|
|
|
{{input
|
|
|
|
|
data-test-key-threshold="true"
|
2019-05-16 14:54:11 +00:00
|
|
|
|
class="input"
|
|
|
|
|
autocomplete="off"
|
|
|
|
|
spellcheck="false"
|
2018-10-31 21:41:21 +00:00
|
|
|
|
name="key-threshold"
|
2018-09-28 14:36:18 +00:00
|
|
|
|
type="number"
|
|
|
|
|
step="1"
|
|
|
|
|
min="1"
|
|
|
|
|
pattern="[0-9]*"
|
|
|
|
|
value=secret_threshold
|
|
|
|
|
}}
|
2018-04-03 14:16:57 +00:00
|
|
|
|
</div>
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<p class="help has-text-grey">
|
|
|
|
|
The number of key shares required to reconstruct the master key
|
|
|
|
|
</p>
|
2018-04-03 14:16:57 +00:00
|
|
|
|
</div>
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<ToggleButton
|
2019-03-29 23:40:12 +00:00
|
|
|
|
@openLabel="Encrypt output with PGP"
|
|
|
|
|
@closedLabel="Encrypt output with PGP"
|
2018-06-26 21:35:47 +00:00
|
|
|
|
@toggleTarget={{this}}
|
|
|
|
|
@toggleAttr="use_pgp"
|
|
|
|
|
@class="is-block"
|
2018-09-28 14:36:18 +00:00
|
|
|
|
/>
|
2018-04-03 14:16:57 +00:00
|
|
|
|
{{#if use_pgp}}
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<div class="box init-box">
|
2018-04-03 14:16:57 +00:00
|
|
|
|
<p class="help has-text-grey">
|
|
|
|
|
The output unseal keys will be encrypted and hex-encoded, in order, with the given public keys.
|
|
|
|
|
</p>
|
2018-09-28 14:36:18 +00:00
|
|
|
|
<PgpList
|
|
|
|
|
@listLength={{secret_shares}}
|
|
|
|
|
@onDataUpdate={{action 'setKeys'}}
|
|
|
|
|
/>
|
2018-04-03 14:16:57 +00:00
|
|
|
|
</div>
|
|
|
|
|
{{/if}}
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<ToggleButton
|
2019-03-29 23:40:12 +00:00
|
|
|
|
@openLabel="Encrypt root token with PGP"
|
|
|
|
|
@closedLabel="Encrypt root token with PGP"
|
2018-06-26 21:35:47 +00:00
|
|
|
|
@toggleTarget={{this}}
|
|
|
|
|
@toggleAttr="use_pgp_for_root"
|
|
|
|
|
@class="is-block"
|
|
|
|
|
/>
|
2018-04-03 14:16:57 +00:00
|
|
|
|
{{#if use_pgp_for_root}}
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<div class="box init-box">
|
2018-04-03 14:16:57 +00:00
|
|
|
|
<p class="help has-text-grey">
|
|
|
|
|
The root unseal key will be encrypted and hex-encoded with the given public key.
|
|
|
|
|
</p>
|
2018-09-28 14:36:18 +00:00
|
|
|
|
<PgpList
|
|
|
|
|
@listLength=1
|
|
|
|
|
@onDataUpdate={{action 'setRootKey'}}
|
|
|
|
|
/>
|
2018-04-03 14:16:57 +00:00
|
|
|
|
</div>
|
|
|
|
|
{{/if}}
|
2018-04-17 22:04:34 +00:00
|
|
|
|
</div>
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<div class="box is-marginless is-shadowless">
|
2018-04-17 22:04:34 +00:00
|
|
|
|
<button
|
2018-09-28 14:36:18 +00:00
|
|
|
|
data-test-init-submit
|
2018-04-17 22:04:34 +00:00
|
|
|
|
type="submit"
|
|
|
|
|
class="button is-primary {{if loading 'is-loading'}}"
|
|
|
|
|
disabled={{loading}}
|
|
|
|
|
>
|
|
|
|
|
Initialize
|
|
|
|
|
</button>
|
2018-06-26 21:35:47 +00:00
|
|
|
|
<div class="init-illustration">
|
2019-05-13 19:05:25 +00:00
|
|
|
|
{{svg-jar "initialize"}}
|
2018-06-26 21:35:47 +00:00
|
|
|
|
</div>
|
2018-04-17 22:04:34 +00:00
|
|
|
|
</div>
|
|
|
|
|
</form>
|
2018-06-26 21:35:47 +00:00
|
|
|
|
</Page.content>
|
|
|
|
|
{{/if}}
|
2018-10-31 21:41:21 +00:00
|
|
|
|
</SplashPage>
|