From a5c66c6dbc69ab5e78345dc43580965366f51543 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Tue, 17 Aug 2021 13:00:14 -0400 Subject: [PATCH] cleaned up local storage handling --- static/client.js | 119 +++++++++++++++++++++++++++++++--------------- static/index.html | 3 +- 2 files changed, 82 insertions(+), 40 deletions(-) diff --git a/static/client.js b/static/client.js index 5e0ff7b..4e5863c 100644 --- a/static/client.js +++ b/static/client.js @@ -1,16 +1,68 @@ +'use strict'; + +/* Following function by 80B ; last updated 2021-08-13 */ +const L = (tag, props = {}, ...kids) => { + const el = Object.assign(document.createElement(tag), props); + typeof(props.style) === 'object' && Object.assign(el.style, props.style); + el.append(...kids); + return el; +}; + +/* The rest of the file: + + Copyright 2021 Michael D. Lowis + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/* + Local Storage Interface +*/ +const Data = { + get: (k) => JSON.parse(localStorage.getItem(k)), + put: (k, v) => localStorage.setItem(k, JSON.stringify(v)), + len: () => localStorage.length, + key: (i) => localStorage.key(i), + clr: () => localStorage.clear(), +}; + /* Chat Client Interface */ -const Client = ((state = {keys: {}})=>({ +const Client = ((state = {keys: {}, logs: {}})=>({ init: ()=>{ + /* scan storage for all keys and logs */ + for (var i = 0; i < Data.len(); i++) { + const name = Data.key(i); + const key = name.match(/(.*)\/key$/) + const log = name.match(/(.*)\/log\/(\d)$/) + if (key) { + state.keys[key[1]] = Client.loadKey(key[1], Data.get(name)); + } else if (log) { + state.logs[log[1]] ||= []; + state.logs[log[1]][Number(log[2])] = Data.get(name); + } + } + /* connect using keys from storage */ - if (localStorage.privKey && localStorage.pubKey) { - Client.privKey(localStorage.privKey); - Client.pubKey(localStorage.pubKey); + if (Data.get('keys/priv') && Data.get('keys/pub')) + { + Client.privKey(Data.get('keys/priv')); + Client.pubKey(Data.get('keys/pub')); Client.connect(); } - /* load chat logs and contacts */ - // TODO + + // TODO: Populate HTML with active contact's log }, log: (msg)=>{ @@ -33,18 +85,18 @@ const Client = ((state = {keys: {}})=>({ }, loadKey: (name, key)=>{ - localStorage[name] = key; + Data.put(name, key); const crypt = new JSEncrypt(); crypt.setKey(key); return crypt; }, privKey: (key)=>{ - state.keys.private = Client.loadKey('privKey', key); + state.keys.private = Client.loadKey('keys/priv', key); }, pubKey: (key)=>{ - state.keys.public = Client.loadKey('pubKey', key); + state.keys.public = Client.loadKey('keys/pub', key); }, keysValid: ()=> state.keys.private.decrypt(state.keys.public.encrypt("test")), @@ -54,10 +106,10 @@ const Client = ((state = {keys: {}})=>({ return resp.text(); }), - addContact: (name, cbfn = ()=>{})=>{ + addContact: (name)=>{ Client.getFile('./keys/' + name).then((key)=>{ state.keys[name] = Client.loadKey(name, key); - cbfn(); + contact.appendChild(L('OPTION', { value: name }, name)); }); }, @@ -77,13 +129,15 @@ const Client = ((state = {keys: {}})=>({ state.conn.onclose = ()=>{ Client.log('DISCONNECT'); - dialog.classList.add("visible"); +// dialog.classList.add("visible"); }; state.conn.onmessage = (event)=>{ Client.getMessage(event.data); }; - } + }, + + state: ()=> state }))(); /* @@ -99,35 +153,22 @@ message.onkeyup = (ev)=>{ } }; -connect.onclick = ()=>{ - public_key.files[0].text() - .then(key =>{ - Client.pubKey(key); - return private_key.files[0].text() - }) - .then(key => { - Client.privKey(key); - if (Client.keysValid()) - { - Client.connect(); - dialog.classList.remove("visible"); - } - }) +connect.onclick = async ()=>{ + let pubKey = await public_key.files[0].text(); + let privKey = await private_key.files[0].text(); + Client.pubKey(pubKey); + Client.privKey(privKey); + if (Client.keysValid()) + { + dialog.classList.remove("visible"); + Client.connect(); + } } addContact.onclick = ()=>{ const name = prompt("Enter name:", ""); - Client.addContact(name, ()=>{ - const el = document.createElement('OPTION'); - el.value = name; - el.textContent = name; - contact.appendChild(el); - }); -} + Client.addContact(name); +}; // Try connecting based on local storage -(()=>{ - Client.init(); -// Client.addContact("clientA"); -// Client.getMessage("0"); -})(); +(()=>{ Client.init(); })(); diff --git a/static/index.html b/static/index.html index d8116ff..4d6a809 100644 --- a/static/index.html +++ b/static/index.html @@ -13,6 +13,7 @@ + @@ -25,7 +26,7 @@ -