feat-user_settings): add ability to import and delete an identity, formatting
This commit is contained in:
parent
5474c5a101
commit
2a928dcafc
@ -1,4 +1 @@
|
||||
{
|
||||
"type": "tildefriends-app",
|
||||
"emoji": "⚙️"
|
||||
}
|
||||
{"type": "tildefriends-app", "emoji": "⚙️"}
|
||||
|
@ -9,13 +9,19 @@ tfrpc.register(async function createID(id) {
|
||||
tfrpc.register(async function getPrivateKey(id) {
|
||||
return bip39Words(await ssb.getPrivateKey(id));
|
||||
});
|
||||
tfrpc.register(async function addID(id) {
|
||||
return await ssb.addIdentity(bip39Bytes(id));
|
||||
});
|
||||
tfrpc.register(async function deleteID(id) {
|
||||
return await ssb.deleteIdentity(id);
|
||||
});
|
||||
tfrpc.register(async function getThemes() {
|
||||
// TODO
|
||||
return ['solarized', 'gruvbox', 'light'];
|
||||
});
|
||||
tfrpc.register(async function setTheme() {
|
||||
// TODO
|
||||
console.warn("setTheme called - not implemented")
|
||||
console.warn('setTheme called - not implemented');
|
||||
return null;
|
||||
});
|
||||
tfrpc.register(async function reload() {
|
||||
|
@ -1 +0,0 @@
|
||||
/* */
|
@ -1 +0,0 @@
|
||||
/* */
|
@ -20,7 +20,7 @@ class TfIdentityManagerElement extends LitElement {
|
||||
|
||||
async createIdentity() {
|
||||
try {
|
||||
let id = await tfrpc.rpc.createID();
|
||||
const id = await tfrpc.rpc.createID();
|
||||
alert('Successfully created: ' + id);
|
||||
await tfrpc.rpc.reload();
|
||||
} catch (err) {
|
||||
@ -28,13 +28,50 @@ class TfIdentityManagerElement extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
async importIdentity() {
|
||||
const words = this.renderRoot?.querySelector('#import-id-textarea').value;
|
||||
if (!words) return;
|
||||
|
||||
try {
|
||||
const newID = await tfrpc.rpc.addID(words);
|
||||
|
||||
if (newID) alert('Successfully imported a new identity');
|
||||
else alert('This identity already exists or is invalid.');
|
||||
await tfrpc.rpc.reload();
|
||||
} catch (err) {
|
||||
alert('Error importing identity: ' + err);
|
||||
}
|
||||
}
|
||||
|
||||
async exportIdentity(id) {
|
||||
alert('Your private key is:\n' + (await tfrpc.rpc.getPrivateKey(id)));
|
||||
alert(
|
||||
'Your private key is:\n' +
|
||||
(await tfrpc.rpc.getPrivateKey(id)) +
|
||||
'\nDo not share it with anyone!'
|
||||
);
|
||||
}
|
||||
|
||||
async deleteIdentity(id) {
|
||||
try {
|
||||
if (
|
||||
prompt(
|
||||
'Are you sure you want to delete "' +
|
||||
id +
|
||||
'"? It cannot be recovered without the exported phrase.\\n\\nEnter the word "DELETE" to confirm you wish to delete it.'
|
||||
) === 'DELETE'
|
||||
) {
|
||||
if (await tfrpc.rpc.deleteID(id)) {
|
||||
alert('Successfully deleted ID: ' + id);
|
||||
}
|
||||
await tfrpc.rpc.reload();
|
||||
}
|
||||
} catch (e) {
|
||||
alert('Error deleting ID: ' + e);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<link rel="stylesheet" href="/static/tildefriends-v1.css"/>
|
||||
return html` <link rel="stylesheet" href="/static/tildefriends-v1.css" />
|
||||
<style>
|
||||
.id-span {
|
||||
font-family: monospace;
|
||||
@ -43,24 +80,34 @@ class TfIdentityManagerElement extends LitElement {
|
||||
</style>
|
||||
|
||||
<h4>Create a new identity</h4>
|
||||
<button id="create-id" class="green" @click=${this.createIdentity}>Create Identity</button>
|
||||
<button id="create-id" class="green" @click=${this.createIdentity}>
|
||||
Create Identity
|
||||
</button>
|
||||
|
||||
<h4>Import an SSB Identity from 12 BIP39 English Words</h4>
|
||||
<textarea id="add-id" style="width: 100%" rows="4"></textarea>
|
||||
<button class="green">[Not implemented] Import Identity</button>
|
||||
<textarea id="import-id-textarea" style="width: 100%" rows="4"></textarea>
|
||||
<button class="green" @click=${this.importIdentity}>
|
||||
Import Identity
|
||||
</button>
|
||||
|
||||
<h4>Warning !</h4>
|
||||
<strong>Anybody that has access to your private key can gain total access over your account.</strong>
|
||||
<br><br>
|
||||
<strong
|
||||
>Anybody that knows your private key can gain total access over your
|
||||
account.</strong
|
||||
>
|
||||
<br /><br />
|
||||
Tilde Friends' contributors will never ask you for your private key !
|
||||
|
||||
<ul>
|
||||
${this.ids.map(
|
||||
(id) =>
|
||||
html`
|
||||
<li>
|
||||
<button class="blue" @click=${() => this.exportIdentity(id)}>Export Identity</button>
|
||||
<button class="red">[Not implemented] Delete Identity</button>
|
||||
html` <li>
|
||||
<button class="blue" @click=${() => this.exportIdentity(id)}>
|
||||
Export Identity
|
||||
</button>
|
||||
<button class="red" @click=${() => this.deleteIdentity(id)}>
|
||||
Delete Identity
|
||||
</button>
|
||||
<span class="id-span">${id}</span>
|
||||
</li>`
|
||||
)}
|
||||
|
@ -48,19 +48,33 @@ class TfPasswordFormElement extends LitElement {
|
||||
|
||||
<div class="grid">
|
||||
<label for="current">Current password:</label>
|
||||
<input type="password" id="current" name="current" autocomplete="current-password" />
|
||||
<input
|
||||
type="password"
|
||||
id="current"
|
||||
name="current"
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
|
||||
<label for="new">Enter new password:</label>
|
||||
<input type="password" id="new" name="new" autocomplete="new-password" />
|
||||
<input
|
||||
type="password"
|
||||
id="new"
|
||||
name="new"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
|
||||
<label for="repeat">Repeat new password:</label>
|
||||
<input type="password" id="repeat" name="repeat" autocomplete="new-password" />
|
||||
<input
|
||||
type="password"
|
||||
id="repeat"
|
||||
name="repeat"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button @click=${this.submitPassword} class="red">
|
||||
[Not implemented] Change my password
|
||||
</button>
|
||||
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
@ -30,8 +30,14 @@ class TfThemePickerElement extends LitElement {
|
||||
|
||||
<label for="theme">[Not implemented] Choose your theme:</label>
|
||||
|
||||
<select name="theme" ?hidden=${!this.themes?.length} @change=${this.changed}>
|
||||
${(this.themes ?? []).map((id) => html`<option value=${id}>${id}</option>`)}
|
||||
<select
|
||||
name="theme"
|
||||
?hidden=${!this.themes?.length}
|
||||
@change=${this.changed}
|
||||
>
|
||||
${(this.themes ?? []).map(
|
||||
(id) => html`<option value=${id}>${id}</option>`
|
||||
)}
|
||||
</select>
|
||||
`;
|
||||
}
|
||||
|
@ -18,8 +18,8 @@ body {
|
||||
|
||||
button,
|
||||
.button,
|
||||
input[type=button],
|
||||
input[type=submit],
|
||||
input[type='button'],
|
||||
input[type='submit'],
|
||||
select {
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
@ -75,7 +75,8 @@ table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
td, th {
|
||||
td,
|
||||
th {
|
||||
border: 1px solid #ffffff40;
|
||||
text-align: left;
|
||||
padding: 8px;
|
||||
|
Loading…
Reference in New Issue
Block a user