commit bcd3d942da966ca5648f0b68c5d6ca39d5f5b3a1
parent f3a10f861e23b7f1adfae0df9d60a9de5029d4d2
Author: lash <dev@holbrook.no>
Date:   Mon, 19 Sep 2022 17:26:09 +0000
Add option to identify oneself
Diffstat:
| M | index.html |  |  | 62 | +++++++++++++++++++++++++++++++++++++++++++++++++++----------- | 
| M | key.js |  |  | 49 | ++++++++++++++++++++++++++++++++++++++++++++++--- | 
2 files changed, 97 insertions(+), 14 deletions(-)
diff --git a/index.html b/index.html
@@ -9,6 +9,7 @@ let g_remote_key_id = '(none)';
 let g_local_key_id = '(none)';
 let g_remote_key_name = '?';
 let g_local_key_name = '?';
+let g_local_key_identified = false;
 let g_data_endpoint = window.location.href;
 let g_counter = undefined;
 		</script>
@@ -42,6 +43,15 @@ let g_counter = undefined;
 				return await rs.json();
 			}
 
+			function getEffectiveName(k) {
+				let kl = k.toPacketList();
+				let klf = kl.filterByTag(openpgp.enums.packet.userID);
+				if (klf.length > 1) {
+					g_local_key_identified = true;
+				}
+				return klf[klf.length-1].name;
+			}
+
 			async function setUp() {
 				let k = undefined;
 				try {
@@ -62,11 +72,8 @@ let g_counter = undefined;
 
 				g_local_key = k;
 				g_local_key_id = k.getKeyID().toHex();
-
-				let kl = k.toPacketList();
-				let klf = kl.filterByTag(openpgp.enums.packet.userID);
-				g_local_key_name = klf[klf.length-1].name;
-
+				g_local_key_name = getEffectiveName(k);
+				
 
 				stateChange('load settings');
 				let settings = await loadSettings();
@@ -112,9 +119,9 @@ let g_counter = undefined;
 				window.dispatchEvent(ev);
 			}
 
-			async function try_dispatch(s) {
+			async function try_dispatch(s, name, email) {
 				try {
-					return await dispatch(s)
+					return await dispatch(s, name, email)
 				} catch(e) {
 					console.error(e);
 					stateChange('send fail: ' + e);
@@ -123,7 +130,25 @@ let g_counter = undefined;
 				}
 			}
 
-			async function dispatch(s) {
+			async function tryIdentify(name, email) {
+				if (g_local_key_identified) {
+					return false;
+				}
+				g_local_key = await identify(g_local_key, name, email, 'deadbeef');
+				g_local_key_name = getEffectiveName(g_local_key);
+				await stateChange('apply name change: ' + g_local_key_name);
+				console.debug('updated public key', g_local_key.toPublic().armor());
+				g_local_key_identified = true;
+			}
+
+			async function dispatch(s, name, email) {
+				if (name) {
+					if (!validateEmail(email)) {
+						throw 'invalid email: ' + email;
+					}
+					await tryIdentify(name, email);
+				}
+
 				let pfx = msg_identifier();
 
 				stateChange('sign and encrypt message ' + g_counter);
@@ -236,13 +261,17 @@ let g_counter = undefined;
 			content: '',
 			key_armor: undefined,
 			rkey_armor: undefined,
+			defaultname: true,
+			identify: false,
+			realname: '',
+			realemail: '',
 
 			}">
 			<dl>
 				<dt>Application:</dt>
-				<dd><a href="https://git.defalsify.org/cgit/forro">forro v0.0.2 (GPLv3)</a></dt>
+				<dd><a href="https://git.defalsify.org/cgit/forro">forro v0.0.3 (GPLv3)</a></dt>
 				<dt>Status:</dt>
-				<dd x-text="message_status" x-on:messagestatechange.window="message_status = $event.detail.s; message_count = $event.detail.c; key = $event.detail.kl; rkey = $event.detail.kr; if (key_armor === undefined && g_local_key !== undefined) { key_armor = g_local_key.armor(); }; if (rkey_armor === undefined && g_remote_key !== undefined) { rkey_armor = g_remote_key.armor(); };"></dd>
+				<dd x-text="message_status" x-on:messagestatechange.window="message_status = $event.detail.s; message_count = $event.detail.c; key = $event.detail.kl; rkey = $event.detail.kr; if (key_armor === undefined && g_local_key !== undefined) { key_armor = g_local_key.armor(); }; if (rkey_armor === undefined && g_remote_key !== undefined) { rkey_armor = g_remote_key.armor(); }; defaultname = !g_local_key_identified;"></dd>
 				<dt>Your identity:</dt>
 				<dd><a x-text="key" x-bind:href="'data:text/plain;charset=utf-8,' + key_armor" download="privatekey.asc"></a></dd>
 				<dt>Their identity:</dt>
@@ -255,7 +284,18 @@ let g_counter = undefined;
 			<textarea cols=72 rows=10 x-model="content" >
 			</textarea>
 			<br/>
-			<button @click="r = await try_dispatch(content); rcpt = r;">sign, encrypt and send</button>
+			<div x-show='defaultname'>
+				<select @change='identify = true;'>
+					<option value=0>Stay anonymous</option>
+					<option value=1>Identify yourself</option>
+				</select>
+				<div x-show="identify">
+					<input name="id_name" placeholder="name" x-model="realname" /> <input name="id_email" placeholder="email" x-model="realemail" />
+				</div>
+			</div>
+			<div>
+				<button @click="r = await try_dispatch(content, realname, realemail); rcpt = r;">sign, encrypt and send</button>
+			</div>
 		</div>
 	</body>
 </html>
diff --git a/key.js b/key.js
@@ -18,14 +18,16 @@ async function generatePGPKey(pwd, uid) {
 		});
 		//console.debug('pk ' + v.privateKey );
 		console.debug('our public key', v.publicKey );
-		localStorage.setItem('pgp-key', v.privateKey);
 		let pk = await openpgp.readKey({
 			armoredKey: v.privateKey,
 		});
+		localStorage.setItem('pgp-key', pk.armor());
+		
 		let k = await openpgp.decryptKey({
 			privateKey: pk,
 			passphrase: pwd,
 		});
+
 		whohoo(k);
 	});
 }
@@ -40,12 +42,17 @@ async function getKey(pwd) {
 		let pk = await openpgp.readKey({
 			armoredKey: pk_armor,
 		});
+//		let k = await openpgp.decryptKey({
+//			privateKey: pk,
+//			passphrase: pwd,
+//		});
+		//console.debug('pk ' + k.armor());
+		console.debug('our public key', pk.toPublic().armor());
 		let k = await openpgp.decryptKey({
 			privateKey: pk,
 			passphrase: pwd,
 		});
-		//console.debug('pk ' + k.armor());
-		console.debug('our public key', k.toPublic().armor());
+
 		whohoo(k);
 	});
 }
@@ -78,3 +85,39 @@ async function generatePointer(pk, pfx) {
 	sha.update(identity_id);
 	return sha.getHash("HEX");
 }
+
+// robbed from https://www.w3resource.com/javascript/form/email-validation.php
+function validateEmail(mail) {
+	if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(mail)) {
+		return true;
+	}
+	return false;
+}
+
+async function identify(pk, name, email, pwd) {
+	return new Promise(async (whohoo, doh) => {
+		const u = openpgp.UserIDPacket.fromObject({
+			name: name,
+			email: email,
+			comment: 'manual entry on forro',
+		});
+		let l = pk.toPacketList();
+		l.push(u);
+
+		const pk_new = new openpgp.PrivateKey(l);
+		const pk_e = await openpgp.encryptKey({
+			privateKey: pk_new,
+			passphrase: pwd,
+
+		});
+
+		localStorage.setItem('pgp-key', pk_e.armor());
+
+		const k = await openpgp.decryptKey({
+			privateKey: pk_e,
+			passphrase: pwd,
+		});
+
+		whohoo(k);
+	});
+}