Skip to content

Instantly share code, notes, and snippets.

@diatche
Forked from amark/li.html
Last active June 17, 2020 03:59
Show Gist options
  • Save diatche/1ea348aa7b77f6edf5c92ba3f8470a67 to your computer and use it in GitHub Desktop.
Save diatche/1ea348aa7b77f6edf5c92ba3f8470a67 to your computer and use it in GitHub Desktop.
<html><body>
<style>
html, body {
background: rgb(245, 245, 245);
margin: 0;
padding: 0;
}
div {
position: relative;
overflow: hidden;
}
#top {
background: #283e4a;
height: 52px;
width: 100%;
}
.box {
border-radius: 3px;
box-shadow: 0px 0px 3px #777;
background: white;
max-width: 36em;
margin: 0 auto;
min-height: 10em;
margin-bottom: 0.5em;
}
.color {
background: #2977b5;
height: 7em;
width: 100%;
}
.pad {
margin: 1em;
}
.none { display: none; }
input {
font-size: 1em;
margin: 0.1em;
}
</style>
<div id="top">
<center>
<input id="search" placeholder="search by pub or DID">
</center>
</div>
<div class="box">
<div class="color"></div>
<div class="pad">
<form id="sign">
<h1>Login</h1>
<input id="alias" placeholder="username">
<input id="pass" type="password" placeholder="passphrase">
<input id="in" type="submit" value="sign in">
<input id="up" type="button" value="sign up">
</form>
<form id="profile" class="none">
<h1>Profile</h1>
<p>Data is privately encrypted by default. "+" to grant access, "x" to revoke access.</p>
<input id="name" placeholder="name"> <button>+</button><br/>
<input id="born" placeholder="born"> <button>+</button><br/>
<input id="edu" placeholder="education"> <button>+</button><br/>
<input id="skills" placeholder="skills"> <button>+</button><br/>
</form>
<button id='revoke'>x</button>
</div>
</div>
<div class="box"><div class="pad">
Public Key: <input id="pub">
</div></div>
<script src="https://cdn.jsdelivr.net/npm/gun/examples/jquery.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gun/gun.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gun/sea.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gun/lib/webrtc.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gun/lib/open.js"></script>
<!-- <script src="../examples/jquery.js"></script>
<script src="../gun.js"></script>
<script src="../sea.js"></script>
<script src="../lib/open.js"></script> -->
<script>
//var gun = Gun();
var gun = Gun({
peers: ['http://localhost:8765/gun'],
localStorage: true,
multicast: true,
axe: true,
});
var user = gun.user();
var LI = {};
user.recall({sessionStorage: true});
$('#up').on('click', function(e){
user.create($('#alias').val(), $('#pass').val());
});
$('#sign').on('submit', function(e){
e.preventDefault();
user.auth($('#alias').val(), $('#pass').val());
});
gun.on('auth', function(){
$('#sign').hide();
$('#profile').show();
var pub = user._.sea.pub;
$('#pub').val(pub);
$("#search").val(pub).trigger('blur');
console.log('auth: ' + pub);
});
const updateTrustedValues = async (values) => {
let pair = user._.sea;
let trust = (await user.get('profile-trust3').then()) || {};
for (let pub of Object.keys(trust)) {
if (pub === '_') continue;
let tuser = gun.user(pub);
let epub = await tuser.get('epub');
if (!epub) continue;
let secret = await Gun.SEA.secret(epub, pair);
let encRef = user.get('profile-trust3').get(pub);
let encs = {};
let currentEncs = await user.get('profile-trust3').get(pub).get('__keys').then();
for (let key of Object.keys(values)) {
if (!currentEncs[key]) {
// Access to this key was not granted
continue;
}
let val = values[key];
let enc = await Gun.SEA.encrypt(val, secret);
encs[key] = enc;
}
await encRef.put(encs);
let sharedData = await user.get('profile-trust3').get(pub).then();
console.log('shared data: ' + JSON.stringify(sharedData, null, 2));
}
};
$('#profile input').on('keyup', function(e){
if(!user.is){ return }
var id = LI.busy = $(this).attr('id');
console.log("Huh?", id, user);
(async () => {
let pair = user._.sea;
let val = $(this).val();
let enc = await Gun.SEA.encrypt(val, pair);
let data = await Gun.SEA.sign(enc, pair);
user.get('profile').get(id).put(data);
await updateTrustedValues({ [id]: val });
})();
}).on('blur', function(){ LI.busy = false })
$('#profile button').on('click', async function(e){
e.preventDefault();
if(!user.is){ return }
var b = $(this);
var id = b.prev().attr('id');
var pub = prompt("What is the Public Key or DID you want to give read access to?");
if (!pub) {
return;
}
var to = gun.user(pub);
var who = await to.get('alias').then();
if (!who) {
alert('user not found: ' + pub);
return;
}
if(!confirm("You want to give access to " + who + "?")){ return }
let epub = await to.get('epub').then();
await user.get('profile-trust3').get(pub).get('__keys').put({ [id]: true });
console.log(`Trusted user ${who} with epub: ${epub}`);
let sharedData = await user.get('profile-trust3').get(pub).then();
console.log('shared data: ' + JSON.stringify(sharedData, null, 2));
});
const deepEmpty = async (ref) => {
let data = await ref.then();
if (!data) return;
let keys = Object.keys(data);
let reset = {};
for (let key of keys) {
if (key === '_') continue;
if (typeof data[key] === 'object') {
await deepEmpty(ref.get(key));
continue;
}
reset[key] = '';
}
ref.put(reset);
};
$('#revoke').on('click', async function(e){
e.preventDefault();
if(!user.is){ return }
if(!confirm("You want to revoke all access?")){ return }
await deepEmpty(user.get('profile-trust3'));
console.log('unshared all data');
});
$('#search').on('blur', function(e){
var s = LI.search = $(this).val();
var find = gun.user(s);
(async () => {
var user = await find.then();
if (!user) {
alert('user not found: ' + s);
}
})();
if (find._.sea) {
// own values
find.get('profile').on(function(data, key, at, ev){
if(s !== LI.search){
ev.off();
return;
}
Gun.node.is(data, async function(v, k){
if(k === LI.busy){ return }
let val = v;
if (val && val.startsWith && val.startsWith('SEA')) {
let pair = user._.sea;
let msg = await Gun.SEA.verify(v, pair.pub);
val = await Gun.SEA.decrypt(msg, pair);
}
$('#'+k).val(val || v);
});
});
} else {
// other user's values
let pair = user._.sea;
find.get('profile-trust3').get(pair.pub).on(function(data, key, at, ev){
if(s !== LI.search){
ev.off();
return;
}
Gun.node.is(data, async function(v, k){
if(k === LI.busy){ return }
let val = v;
if (val && val.startsWith && val.startsWith('SEA')) {
let pair = user._.sea;
let epub = await find.get('epub');
let secret = await Gun.SEA.secret(epub, pair);
val = await Gun.SEA.decrypt(val, secret);
}
$('#'+k).val(val || v);
// Try override other users data ^_^
// find.get('profile-trust3').get(pair.pub).get(k).put('---');
});
});
}
});
</script>
</body></html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment