.gitea
apps
admin
api
apps
blog
db
follow
identity
app.js
w3.css
intro
issues
journal
room
sneaker
ssb
storage
test
todo
web
welcome
wiki
admin.json
api.json
apps.json
blog.json
db.json
follow.json
identity.json
intro.json
issues.json
journal.json
room.json
sneaker.json
ssb.json
storage.json
test.json
todo.json
web.json
welcome.json
wiki.json
core
deps
docs
metadata
src
tools
.clang-format
.dockerignore
.git-blame-ignore-revs
.gitignore
.gitmodules
.prettierignore
.prettierrc.yaml
CONTRIBUTING.md
Dockerfile
Doxyfile
GNUmakefile
LICENSE
README.md
default.nix
flake.lock
flake.nix
package-lock.json
package.json
154 lines
6.1 KiB
JavaScript
154 lines
6.1 KiB
JavaScript
import * as tfrpc from '/tfrpc.js';
|
|
|
|
const is_admin = core.user?.credentials?.permissions?.administration;
|
|
|
|
tfrpc.register(async function get_private_key(id) {
|
|
return bip39Words(await ssb.getPrivateKey(id));
|
|
});
|
|
tfrpc.register(async function create_id(id) {
|
|
return await ssb.createIdentity();
|
|
});
|
|
tfrpc.register(async function add_id(id) {
|
|
return await ssb.addIdentity(bip39Bytes(id));
|
|
});
|
|
tfrpc.register(async function delete_id(id) {
|
|
return await ssb.deleteIdentity(id);
|
|
});
|
|
tfrpc.register(async function reload() {
|
|
await main();
|
|
});
|
|
tfrpc.register(async function make_server(id) {
|
|
return await ssb.swapWithServerIdentity(id);
|
|
});
|
|
|
|
async function main() {
|
|
let ids = await ssb.getIdentities();
|
|
let server_id = await ssb.getServerIdentity();
|
|
await app.setDocument(
|
|
`
|
|
<head>
|
|
<link rel="stylesheet" href="w3.css"></link>
|
|
<style>
|
|
/* "2018 Sargasso Sea" */
|
|
.w3-theme-l5 {color:#000 !important; background-color:#f3f4f7 !important}
|
|
.w3-theme-l4 {color:#000 !important; background-color:#d7dbe3 !important}
|
|
.w3-theme-l3 {color:#000 !important; background-color:#b0b6c8 !important}
|
|
.w3-theme-l2 {color:#fff !important; background-color:#8892ac !important}
|
|
.w3-theme-l1 {color:#fff !important; background-color:#636f8e !important}
|
|
.w3-theme-d1 {color:#fff !important; background-color:#40485c !important}
|
|
.w3-theme-d2 {color:#fff !important; background-color:#394052 !important}
|
|
.w3-theme-d3 {color:#fff !important; background-color:#323848 !important}
|
|
.w3-theme-d4 {color:#fff !important; background-color:#2b303d !important}
|
|
.w3-theme-d5 {color:#fff !important; background-color:#242833 !important}
|
|
|
|
.w3-theme-light {color:#000 !important; background-color:#f3f4f7 !important}
|
|
.w3-theme-dark {color:#fff !important; background-color:#242833 !important}
|
|
.w3-theme-action {color:#fff !important; background-color:#242833 !important}
|
|
|
|
.w3-theme {color:#fff !important; background-color:#485167 !important}
|
|
.w3-text-theme {color:#485167 !important}
|
|
.w3-border-theme {border-color:#485167 !important}
|
|
|
|
.w3-hover-theme:hover {color:#fff !important; background-color:#485167 !important}
|
|
.w3-hover-text-theme:hover {color:#485167 !important}
|
|
.w3-hover-border-theme:hover {border-color:#485167 !important}
|
|
</style>
|
|
</head>
|
|
<body class="w3-theme-l3">
|
|
<script>const handler = {};</script>
|
|
<script type="module">
|
|
import * as tfrpc from '/static/tfrpc.js';
|
|
handler.export_id = async function export_id(event) {
|
|
let id = event.srcElement.dataset.id;
|
|
let element = document.createElement('textarea');
|
|
element.value = await tfrpc.rpc.get_private_key(id);
|
|
element.style = 'width: 100%; height: auto; read-only: true; resize: none';
|
|
element.classList.add('w3-input');
|
|
element.readOnly = true;
|
|
event.srcElement.parentElement.appendChild(element);
|
|
event.srcElement.onclick = event => handler.hide_id(event, element);
|
|
}
|
|
handler.add_id = async function add_id(event) {
|
|
let id = document.getElementById('add_id').value;
|
|
try {
|
|
let new_id = await tfrpc.rpc.add_id(id);
|
|
alert('Successfully imported: ' + new_id);
|
|
await tfrpc.rpc.reload();
|
|
} catch (e) {
|
|
alert('Error importing identity: ' + e);
|
|
}
|
|
}
|
|
handler.create_id = async function create_id(event) {
|
|
try {
|
|
let id = await tfrpc.rpc.create_id();
|
|
alert('Successfully created: ' + id);
|
|
await tfrpc.rpc.reload();
|
|
} catch (e) {
|
|
alert('Error creating identity: ' + e.message);
|
|
}
|
|
}
|
|
handler.hide_id = function hide_id(event, element) {
|
|
element.parentNode.removeChild(element);
|
|
event.srcElement.onclick = handler.export_id;
|
|
}
|
|
handler.delete_id = async function delete_id(event) {
|
|
let id = event.srcElement.dataset.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.delete_id(id)) {
|
|
alert('Successfully deleted ID: ' + id);
|
|
}
|
|
await tfrpc.rpc.reload();
|
|
}
|
|
} catch (e) {
|
|
alert('Error deleting ID: ' + e);
|
|
}
|
|
}
|
|
handler.make_server = async function make_server(event) {
|
|
let id = event.srcElement.dataset.id;
|
|
try {
|
|
if (confirm('Are you sure you want to make "' + id + '" the server identity?\\n\\nFor it to take effect, you will need to both sign in again and restart Tilde Friends.')) {
|
|
await tfrpc.rpc.make_server(id);
|
|
}
|
|
} catch (e) {
|
|
alert('Error making server ID: ' + e);
|
|
}
|
|
}
|
|
</script>
|
|
<header class="w3-theme w3-padding"><h1>SSB Identity Management</h1></header>
|
|
<div class="w3-card-4 w3-margin">
|
|
<header class="w3-container w3-theme-l2"><h2>Create a new identity</h2></header>
|
|
<footer class="w3-padding">
|
|
<button id="create_id" onclick="handler.create_id()" class="w3-button w3-theme">Create Identity</button>
|
|
</footer>
|
|
</div>
|
|
<div class="w3-card-4 w3-margin">
|
|
<header class="w3-container w3-theme-l2"><h2>Import an SSB Identity from 12 BIP39 English Words</h2></header>
|
|
<textarea id="add_id" style="width: 100%" rows="4" class="w3-input"></textarea>
|
|
<footer class="w3-padding">
|
|
<button id="add" onclick="handler.add_id(event)" class="w3-button w3-theme">Import Identity</button>
|
|
</footer>
|
|
</div>
|
|
<div class="w3-card-4 w3-margin">
|
|
<header class="w3-container w3-theme-l2"><h2>Identities</h2></header>
|
|
<ul class="w3-ul">` +
|
|
(ids ?? [])
|
|
.map(
|
|
(
|
|
id
|
|
) => `<li style="overflow: hidden; text-wrap: nowrap; text-overflow: ellipsis">
|
|
<button onclick="handler.export_id(event)" data-id="${id}" class="w3-button w3-theme">Export Identity</button>
|
|
<button onclick="handler.delete_id(event)" data-id="${id}" class="w3-button w3-theme">Delete Identity</button>
|
|
${is_admin && id != server_id ? `<button onclick="handler.make_server(event)" data-id="${id}" class="w3-button w3-theme">Make Server Identity</button>` : ''}
|
|
${id}${id == server_id ? ' <div class="w3-tag w3-theme-l4 w3-round">🖥 local server</div>' : ''}
|
|
</li>`
|
|
)
|
|
.join('\n') +
|
|
` </ul>
|
|
</div>
|
|
</body>`
|
|
);
|
|
}
|
|
|
|
main();
|