named passphrases (+deletion by name)

This commit is contained in:
Mikaël Cluseau
2023-09-10 16:47:54 +02:00
parent 34afe03818
commit ee5629643c
11 changed files with 200 additions and 113 deletions

View File

@ -21,21 +21,3 @@
.cluster {
max-width: 50%;
}
#store-infos {
display: flex;
flex-flow: row wrap;
align-content: center;
justify-content: flex-start;
border-bottom: dashed 1pt;
margin-bottom: 1ex;
}
#store-infos > * {
display: block;
font-size: medium;
padding: 2pt 1ex;
margin: 0 0 0 1ex;
}
#store-infos > *:first-child {
margin-left: 0;
}

View File

@ -41,8 +41,9 @@
<p>Store is new.</p>
<p>Option 1: initialize a new store</p>
<form @submit="unlockStore">
<input type="password" v-model="forms.store.pass1" name="passphrase" required />
<input type="password" v-model="forms.store.pass2" required />
<input type="text" v-model="forms.store.name" name="name" placeholder="Name" /><br/>
<input type="password" v-model="forms.store.pass1" name="passphrase" required placeholder="Passphrase" />
<input type="password" v-model="forms.store.pass2" required placeholder="Passphrase confirmation" />
<input type="submit" value="initialize" :disabled="!forms.store.pass1 || forms.store.pass1 != forms.store.pass2" />
</form>
<p>Option 2: upload a previously downloaded store</p>
@ -54,7 +55,7 @@
<template v-else-if="!publicState.Store.Open">
<p>Store is not open.</p>
<form @submit="unlockStore">
<input type="password" name="passphrase" v-model="forms.store.pass1" required />
<input type="password" name="passphrase" v-model="forms.store.pass1" required placeholder="Passphrase" />
<input type="submit" value="unlock" :disabled="!forms.store.pass1" />
</form>
</template>
@ -63,28 +64,12 @@
<p v-else>Invalid token</p>
<form @submit="setToken">
<input type="password" v-model="forms.setToken" required />
<input type="password" v-model="forms.setToken" required placeholder="Token" />
<input type="submit" value="set token"/>
</form>
</template>
<template v-else>
<div id="store-infos">
<h2>Config</h2>
<form @submit="uploadConfig">
<input type="file" ref="configUpload" required />
<input type="submit" value="upload config" />
</form>
<h2>Store</h2>
<a :href="'/public/store.tar?token='+state.Store.DownloadToken" target="_blank">download</a>
<form @submit="storeAddKey" action="/store/add-key">
<input type="password" v-model="forms.store.pass1" name="passphrase" autocomplete="new-password" required />
<input type="password" v-model="forms.store.pass2" autocomplete="new-password" required />
<input type="submit" value="add unlock phrase" :disabled="!forms.store.pass1 || forms.store.pass1 != forms.store.pass2" />
</form>
</div>
<div v-if="state.Clusters" id="clusters">
<h2>Clusters</h2>
<div class="sheets">
@ -100,7 +85,29 @@
</div>
</div>
<pre v-if="false">{{ state }}</pre>
<h2>Admin actions</h2>
<h3>Config</h3>
<form @submit="uploadConfig">
<input type="file" ref="configUpload" required />
<input type="submit" value="upload config" />
</form>
<h3>Store</h3>
<p><a :href="'/public/store.tar?token='+state.Store.DownloadToken" target="_blank">Download</a></p>
<form @submit="storeAddKey" action="/store/add-key">
<p>Add an unlock phrase:</p>
<input type="text" v-model="forms.store.name" name="name" required placeholder="Name" /><br/>
<input type="password" v-model="forms.store.pass1" name="passphrase" autocomplete="new-password" required placeholder="Phrase" />
<input type="password" v-model="forms.store.pass2" autocomplete="new-password" required placeholder="Phrase confirmation" />
<input type="submit" value="add unlock phrase" :disabled="!forms.store.pass1 || forms.store.pass1 != forms.store.pass2" />
</form>
<form @submit="storeDelKey" action="/store/delete-key">
<p>Remove an unlock phrase:</p>
<input type="text" v-model="forms.delKey.name" name="name" required placeholder="Name" />
<input type="submit" value="remove unlock phrase" />
<p v-if="state.Store.KeyNames">Available names:
<template v-for="k,i in state.Store.KeyNames">{{i?", ":""}}<code @click="forms.delKey.name=k">{{k}}</code></template>.</p>
</form>
</template>
</div>

View File

@ -9,8 +9,9 @@ createApp({
data() {
return {
forms: {
store: { },
store: {},
storeUpload: {},
delKey: {},
},
session: {},
error: null,
@ -67,13 +68,26 @@ createApp({
this.forms.store = {}
}, "application/tar")
},
namedPassphrase(name, passphrase) {
return {Name: this.forms.store.name, Passphrase: btoa(this.forms.store.pass1)}
},
storeAddKey() {
this.apiPost('/store/add-key', this.forms.store.pass1, (v) => {
this.apiPost('/store/add-key', this.namedPassphrase(), (v) => {
this.forms.store = {}
})
},
storeDelKey() {
let name = this.forms.delKey.name
if (!confirm("Remove key named "+JSON.stringify(name)+"?")) {
return
}
this.apiPost('/store/delete-key', name , (v) => {
this.forms.delKey = {}
})
},
unlockStore() {
this.apiPost('/public/unlock-store', this.forms.store.pass1, (v) => {
this.apiPost('/public/unlock-store', this.namedPassphrase(), (v) => {
this.forms.store = {}
if (v) {