vybe/client/auth.js

118 lines
2.8 KiB
JavaScript

import { render, html } from '/uhtml.js';
function rand() {
let str = '';
const lookups =
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.split('');
while (str.length < 16) {
const n = Math.random() * lookups.length;
str += lookups[Math.floor(n)];
}
return str;
}
async function auth() {
const sig = await openpgp.sign({
message: new openpgp.CleartextMessage('vybe_auth ' + window.session, ''),
signingKeys: window.keys.priv
});
window.socket.emit(
'authenticate',
{ name: window.name, message: sig },
msg => {
let register = document.getElementById('register');
if (!msg.success) {
console.log('authenticate failed', msg);
register.classList.remove('hidden');
return;
}
if (register) {
register.remove();
import('/app.js');
}
}
);
}
render(document.body, html`
<div id='register' class='hidden'>
<h1>welcome to vybe</h1>
<h3>a communication network (beta)</h3>
<p>
to get started, you'll need an account. we use public key cryptography
for security, rather than passwords. your keys are stored in your
browser storage only, so do this on a browser you can access again.
</p>
<form onsubmit=${async e => {
e.preventDefault();
const name = document.getElementById('name').value;
if (!name)
return;
const keys = await openpgp.generateKey({
userIDs: [{ name }],
});
const priv = await openpgp.readKey({ armoredKey: keys.privateKey });
const pub = await openpgp.readKey({ armoredKey: keys.publicKey });
window.emit(
'create_user',
{ name, pubkey: keys.publicKey },
(msg) => {
if (!msg.success) {
document.querySelector('#message').innerText = msg.message;
return;
}
window.keys = { priv, pub };
localStorage.setItem('keys', JSON.stringify(keys));
localStorage.setItem('name', name);
window.name = name;
auth();
}
);
}} id='registerform'>
<label for='name'>username: </label>
<input id='name' type='text' />
<button id='submit' type='submit'>generate keys & register</button>
</form>
<p id='message'></p>
</div>
`);
async function gensession() {
window.session = rand();
window.emit = (type, data, callback) =>
window.socket.emit(
type,
{
...data,
__session: window.session,
},
callback
);
}
window.onload = async () => {
window.socket = io();
await gensession();
let keys = localStorage.getItem('keys');
if (keys) {
window.name = localStorage.getItem('name');
keys = JSON.parse(keys);
window.keys = {
priv: await openpgp.readKey({ armoredKey: keys.privateKey }),
pub: await openpgp.readKey({ armoredKey: keys.publicKey })
};
await auth();
}
else
document.getElementById('register').classList.remove('hidden');
window.socket.io.on('reconnect', async attempt => {
await gensession();
if (localStorage.getItem('keys'))
await auth();
});
};