Some checks failed
		
		
	
	Build Tilde Friends / Build-All (push) Has been cancelled
				
			
		
			
				
	
	
		
			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();
 |