use socketio callbacks and uhtml
parent
99cb595e07
commit
ca78144083
|
@ -1,126 +1,65 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<script src="/openpgp.min.js"></script>
|
<script src="/openpgp.min.js"></script>
|
||||||
<script src="/socket.io.min.v4.6.1.js"></script>
|
<script src="/socket.io.min.v4.6.1.js"></script>
|
||||||
<script src="/aes.js"></script>
|
<script src="/aes.js"></script>
|
||||||
<script src="/chat.js"></script>
|
<script type="module" src="/ui.js"></script>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>vybe</title>
|
<title>vybe</title>
|
||||||
<style>
|
<style>
|
||||||
* {
|
* {
|
||||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
|
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
|
||||||
Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue",
|
Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue",
|
||||||
sans-serif;
|
sans-serif;
|
||||||
}
|
}
|
||||||
body,
|
body,
|
||||||
button,
|
button,
|
||||||
input {
|
input {
|
||||||
background: #020202;
|
background: #020202;
|
||||||
color: #eaeaea;
|
color: #eaeaea;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
min-width: min-content;
|
min-width: min-content;
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
}
|
}
|
||||||
.column {
|
#app {
|
||||||
flex: 1;
|
display: contents;
|
||||||
max-width: 50vw;
|
}
|
||||||
overflow: hidden;
|
.column {
|
||||||
}
|
flex: 1;
|
||||||
button {
|
max-width: 50vw;
|
||||||
border-color: #767676;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.hidden {
|
button {
|
||||||
display: none;
|
border-color: #767676;
|
||||||
}
|
}
|
||||||
#msginput {
|
.hidden {
|
||||||
margin-top: 15px;
|
display: none;
|
||||||
}
|
}
|
||||||
.message {
|
#msginput {
|
||||||
margin-bottom: 5px;
|
margin-top: 15px;
|
||||||
overflow-wrap: break-word;
|
}
|
||||||
}
|
.message {
|
||||||
#loadmore {
|
margin-bottom: 5px;
|
||||||
margin-bottom: 10px;
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
.channel {
|
#loadmore {
|
||||||
font-weight: normal;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
.member {
|
.channel {
|
||||||
margin: 5px 0;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
</style>
|
.member {
|
||||||
</head>
|
margin: 5px 0;
|
||||||
<body>
|
}
|
||||||
<div id="register" class="hidden">
|
</style>
|
||||||
<h1>welcome to vybe</h1>
|
</head>
|
||||||
<h3>a communication network (beta)</h3>
|
<body>
|
||||||
<p>
|
</body>
|
||||||
to get started, you'll need an account. we use public key cryptography
|
|
||||||
for security, rather than passwords. for now your keys are stored in
|
|
||||||
your browser storage only.
|
|
||||||
</p>
|
|
||||||
<form id="registerform">
|
|
||||||
<label for="name">name/username: </label>
|
|
||||||
<input type="text" id="name" />
|
|
||||||
<button id="submit" type="submit">generate keys & register</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div id="threads" class="column hidden">
|
|
||||||
<h1>vybe</h1>
|
|
||||||
<h3>threads</h3>
|
|
||||||
<div id="threadlist">loading...</div>
|
|
||||||
<h3>create thread</h3>
|
|
||||||
<form id="createthread">
|
|
||||||
<label for="newthreadname">thread name</label>
|
|
||||||
<input type="text" id="newthreadname" /><br /><br />
|
|
||||||
<span>thread permissions</span><br />
|
|
||||||
<input type="radio" id="public" name="permissions" value="public" />
|
|
||||||
<label for="public">anyone can view and post</label><br />
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
id="private_post"
|
|
||||||
name="permissions"
|
|
||||||
value="private_post"
|
|
||||||
/>
|
|
||||||
<label for="private_post">only members can post, anyone can view</label
|
|
||||||
><br />
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
id="private_view"
|
|
||||||
name="permissions"
|
|
||||||
value="private_view"
|
|
||||||
/>
|
|
||||||
<label for="private_view">only members can view and post</label
|
|
||||||
><br /><br />
|
|
||||||
<span>members</span><br />
|
|
||||||
<input type="text" id="membername" placeholder="username" /><button
|
|
||||||
id="addmember"
|
|
||||||
>
|
|
||||||
add
|
|
||||||
</button>
|
|
||||||
<div id="memberlist"></div>
|
|
||||||
<br />
|
|
||||||
<button id="submitthread" type="submit">create</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div id="chat" class="column hidden">
|
|
||||||
<h3 class="thread">
|
|
||||||
current thread: <strong id="threadname">meow</strong>
|
|
||||||
</h3>
|
|
||||||
<h3>messages will appear below as they are sent</h3>
|
|
||||||
<button id="loadmore" class="hidden">load more messages</button>
|
|
||||||
<div id="messages"></div>
|
|
||||||
<form id="msginput">
|
|
||||||
<input type="text" placeholder="write a message..." id="msg" />
|
|
||||||
<button type="submit" class="hidden" id="sendmsg"></button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,3 +1,5 @@
|
||||||
|
import { render, html } from '/uhtml.js';
|
||||||
|
|
||||||
function rand() {
|
function rand() {
|
||||||
let str = "";
|
let str = "";
|
||||||
const lookups =
|
const lookups =
|
||||||
|
@ -16,14 +18,46 @@ async function auth() {
|
||||||
signingKeys: window.keys.priv,
|
signingKeys: window.keys.priv,
|
||||||
});
|
});
|
||||||
window.session = session;
|
window.session = session;
|
||||||
window.socket.emit("authenticate", { name: window.name, message: sig });
|
window.emit = (type, data, callback) => window.socket.emit(type, {
|
||||||
|
...data,
|
||||||
|
__session: window.session,
|
||||||
|
}, callback);
|
||||||
|
window.socket.emit("authenticate", { name: window.name, message: sig },
|
||||||
|
msg => {
|
||||||
|
if (!msg.success) {
|
||||||
|
document.getElementById("register").classList.remove("hidden");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
document.getElementById("register").classList.add("hidden");
|
||||||
|
document.getElementById("app").classList.remove("hidden");
|
||||||
|
const member = document.createElement("p");
|
||||||
|
member.textContent = window.name;
|
||||||
|
member.classList.add("member");
|
||||||
|
document.getElementById("memberlist").appendChild(member);
|
||||||
|
window.emit("list_threads", {}, msg => {
|
||||||
|
document.getElementById("threadlist").innerHTML = "";
|
||||||
|
for (let thread of msg.threads)
|
||||||
|
addThread(thread);
|
||||||
|
});
|
||||||
|
loadMessages();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadKeys(keys) {
|
async function register(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 priv = await openpgp.readKey({ armoredKey: keys.privateKey });
|
||||||
const pub = await openpgp.readKey({ armoredKey: keys.publicKey });
|
const pub = await openpgp.readKey({ armoredKey: keys.publicKey });
|
||||||
window.keys = { priv, pub };
|
window.keys = { priv, pub };
|
||||||
await auth();
|
localStorage.setItem("keys", JSON.stringify(keys));
|
||||||
|
localStorage.setItem("name", name);
|
||||||
|
window.name = name;
|
||||||
|
window.emit("create_user", { name, pubkey: keys.publicKey }, auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
function chooseThread(thread) {
|
function chooseThread(thread) {
|
||||||
|
@ -34,9 +68,25 @@ function chooseThread(thread) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadMessages() {
|
function loadMessages() {
|
||||||
window.socket.emit("get_history", {
|
window.emit("get_history", {
|
||||||
before: window.earliestMessage,
|
before: window.earliestMessage,
|
||||||
thread: window.currentThreadId,
|
thread: window.currentThreadId,
|
||||||
|
}, msg => {
|
||||||
|
if (msg.messages.length > 0) {
|
||||||
|
window.earliestMessage = msg.messages[msg.messages.length - 1].id;
|
||||||
|
for (let message of msg.messages) {
|
||||||
|
const el = document.createElement("div");
|
||||||
|
el.classList.add("message");
|
||||||
|
const strong = document.createElement("strong");
|
||||||
|
strong.textContent = message.name + ": ";
|
||||||
|
el.append(strong, message.message);
|
||||||
|
document.getElementById("messages").prepend(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!msg.more)
|
||||||
|
document.getElementById("loadmore").classList.add("hidden");
|
||||||
|
else
|
||||||
|
document.getElementById("loadmore").classList.remove("hidden");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,12 +123,18 @@ function addMember() {
|
||||||
document.getElementById("membername").value = "";
|
document.getElementById("membername").value = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createThread(members) {
|
async function createThread(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
let members = window.threadmembers
|
||||||
|
? window.threadmembers.map((i) => ({ name: i }))
|
||||||
|
: [{ name: window.name }];
|
||||||
const perms = document.querySelector(
|
const perms = document.querySelector(
|
||||||
'input[name="permissions"]:checked'
|
'input[name="permissions"]:checked'
|
||||||
).value;
|
).value;
|
||||||
|
if (perms === "private_view")
|
||||||
|
members = (await new Promise(resolve =>
|
||||||
|
window.emit("get_keys", { names: members.map((i) => i.name) }, resolve))).keys;
|
||||||
let permissions;
|
let permissions;
|
||||||
let newmembers = members;
|
|
||||||
if (perms === "public") {
|
if (perms === "public") {
|
||||||
permissions = {
|
permissions = {
|
||||||
view_limited: false,
|
view_limited: false,
|
||||||
|
@ -109,11 +165,6 @@ async function createThread(members) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
window.socket.emit("create_thread", {
|
|
||||||
name: document.getElementById("newthreadname").value,
|
|
||||||
permissions,
|
|
||||||
newmembers,
|
|
||||||
});
|
|
||||||
document.getElementById(perms).checked = false;
|
document.getElementById(perms).checked = false;
|
||||||
window.threadmembers = null;
|
window.threadmembers = null;
|
||||||
document.getElementById("memberlist").innerHTML = "";
|
document.getElementById("memberlist").innerHTML = "";
|
||||||
|
@ -121,73 +172,11 @@ async function createThread(members) {
|
||||||
member.textContent = window.name;
|
member.textContent = window.name;
|
||||||
member.classList.add("member");
|
member.classList.add("member");
|
||||||
document.getElementById("memberlist").appendChild(member);
|
document.getElementById("memberlist").appendChild(member);
|
||||||
}
|
window.emit("create_thread", {
|
||||||
|
name: document.getElementById("newthreadname").value,
|
||||||
function decryptMessage(thread, message) {}
|
permissions,
|
||||||
|
members,
|
||||||
function encryptMessage(thread, message) {}
|
}, msg => {
|
||||||
|
|
||||||
window.onload = () => {
|
|
||||||
window.currentThreadId = 1;
|
|
||||||
window.socket = io();
|
|
||||||
window.socket.on("create_user", auth);
|
|
||||||
window.socket.on("new_message", (msg) => {
|
|
||||||
if (msg.thread !== window.currentThreadId) return;
|
|
||||||
const el = document.createElement("div");
|
|
||||||
el.classList.add("message");
|
|
||||||
const strong = document.createElement("strong");
|
|
||||||
strong.textContent = msg.name + ": ";
|
|
||||||
el.append(strong, msg.message);
|
|
||||||
document.getElementById("messages").appendChild(el);
|
|
||||||
if (!window.earliestMessage) window.earliestMessage = msg.id;
|
|
||||||
});
|
|
||||||
window.socket.on("get_history", (msg) => {
|
|
||||||
if (msg.messages.length > 0) {
|
|
||||||
window.earliestMessage = msg.messages[msg.messages.length - 1].id;
|
|
||||||
for (let message of msg.messages) {
|
|
||||||
const el = document.createElement("div");
|
|
||||||
el.classList.add("message");
|
|
||||||
const strong = document.createElement("strong");
|
|
||||||
strong.textContent = message.name + ": ";
|
|
||||||
el.append(strong, message.message);
|
|
||||||
document.getElementById("messages").prepend(el);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!msg.more)
|
|
||||||
document.getElementById("loadmore").classList.add("hidden");
|
|
||||||
else
|
|
||||||
document.getElementById("loadmore").classList.remove("hidden");
|
|
||||||
});
|
|
||||||
window.socket.on("authenticate", (msg) => {
|
|
||||||
if (msg.success) {
|
|
||||||
document.getElementById("register").classList.add("hidden");
|
|
||||||
document.getElementById("threads").classList.remove("hidden");
|
|
||||||
document.getElementById("chat").classList.remove("hidden");
|
|
||||||
const member = document.createElement("p");
|
|
||||||
member.textContent = window.name;
|
|
||||||
member.classList.add("member");
|
|
||||||
document.getElementById("memberlist").appendChild(member);
|
|
||||||
let emitter = window.socket.emit;
|
|
||||||
window.socket.emit = (type, data) => {
|
|
||||||
if (data)
|
|
||||||
return emitter.call(window.socket, type, {
|
|
||||||
...data,
|
|
||||||
__session: window.session,
|
|
||||||
});
|
|
||||||
else return emitter.call(window.socket, type);
|
|
||||||
};
|
|
||||||
window.socket.emit("list_threads", {});
|
|
||||||
loadMessages();
|
|
||||||
} else {
|
|
||||||
document.getElementById("register").classList.remove("hidden");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
window.socket.on("list_threads", (msg) => {
|
|
||||||
document.getElementById("threadlist").innerHTML = "";
|
|
||||||
for (let thread of msg.threads) addThread(thread);
|
|
||||||
});
|
|
||||||
window.socket.on("new_thread", addThread);
|
|
||||||
window.socket.on("create_thread", (msg) => {
|
|
||||||
chooseThread({
|
chooseThread({
|
||||||
name: document.getElementById("newthreadname").value,
|
name: document.getElementById("newthreadname").value,
|
||||||
id: msg.id,
|
id: msg.id,
|
||||||
|
@ -196,62 +185,118 @@ window.onload = () => {
|
||||||
document.getElementById("loadmore").classList.add("hidden");
|
document.getElementById("loadmore").classList.add("hidden");
|
||||||
document.getElementById("msginput").classList.remove("hidden");
|
document.getElementById("msginput").classList.remove("hidden");
|
||||||
});
|
});
|
||||||
window.socket.on("get_keys", (msg) => {
|
}
|
||||||
createThread(msg.keys);
|
|
||||||
|
function sendMessage(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const msg = document.getElementById("msg").value;
|
||||||
|
if (!msg)
|
||||||
|
return;
|
||||||
|
window.emit("send_message", {
|
||||||
|
message: msg,
|
||||||
|
thread: window.currentThreadId,
|
||||||
});
|
});
|
||||||
document.getElementById("registerform").onsubmit = async (e) => {
|
document.getElementById("msg").value = "";
|
||||||
e.preventDefault();
|
}
|
||||||
const name = document.getElementById("name").value;
|
|
||||||
if (!name) return;
|
render(document.body, html`
|
||||||
const keys = await openpgp.generateKey({
|
<div id="register" class="hidden">
|
||||||
userIDs: [{ name }],
|
<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=${register} id="registerform">
|
||||||
|
<label for="name">username: </label>
|
||||||
|
<input type="text" id="name" />
|
||||||
|
<input id="submit" type="submit" value='generate keys & register'>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div id="app" class="hidden">
|
||||||
|
<div id="threads" class="column">
|
||||||
|
<h1>vybe</h1>
|
||||||
|
<h3>threads</h3>
|
||||||
|
<div id="threadlist">loading...</div>
|
||||||
|
<form id="createthread" onsubmit=${createThread}>
|
||||||
|
<h3>create thread</h3>
|
||||||
|
<label for="newthreadname">thread name</label>
|
||||||
|
<input type="text" id="newthreadname" /><br /><br />
|
||||||
|
<span>thread permissions</span><br />
|
||||||
|
<input type="radio" id="public" name="permissions" value="public" />
|
||||||
|
<label for="public">anyone can view and post</label><br />
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
id="private_post"
|
||||||
|
name="permissions"
|
||||||
|
value="private_post"
|
||||||
|
/>
|
||||||
|
<label for="private_post">only members can post, anyone can view</label
|
||||||
|
><br />
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
id="private_view"
|
||||||
|
name="permissions"
|
||||||
|
value="private_view"
|
||||||
|
/>
|
||||||
|
<label for="private_view">only members can view and post</label
|
||||||
|
><br /><br />
|
||||||
|
<span>members</span><br />
|
||||||
|
<input type="text" id="membername" placeholder="username" onkeydown=${(e) => {
|
||||||
|
if (e.key == "Enter") {
|
||||||
|
e.preventDefault();
|
||||||
|
addMember();
|
||||||
|
}
|
||||||
|
}}/>
|
||||||
|
<button id="addmember" onclick=${addMember}>add</button>
|
||||||
|
<div id="memberlist"></div>
|
||||||
|
<br />
|
||||||
|
<input id="submitthread" type="submit" value="create" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div id="chat" class="column">
|
||||||
|
<h3 class="thread">
|
||||||
|
current thread: <strong id="threadname">meow</strong>
|
||||||
|
</h3>
|
||||||
|
<h3>messages will appear below as they are sent</h3>
|
||||||
|
<button id="loadmore" class="hidden" onclick=${loadMessages}>load more messages</button>
|
||||||
|
<div id="messages"></div>
|
||||||
|
<form id="msginput" onsubmit=${sendMessage}>
|
||||||
|
<input type="text" placeholder="write a message..." id="msg" />
|
||||||
|
<button type="submit" class="hidden" id="sendmsg"></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
|
||||||
|
window.onload = async () => {
|
||||||
|
window.currentThreadId = 1;
|
||||||
|
window.socket = io();
|
||||||
|
window.socket.on("new_message", (msg) => {
|
||||||
|
if (msg.thread !== window.currentThreadId)
|
||||||
|
return;
|
||||||
|
const el = document.createElement("div");
|
||||||
|
el.classList.add("message");
|
||||||
|
const strong = document.createElement("strong");
|
||||||
|
strong.textContent = msg.name + ": ";
|
||||||
|
el.append(strong, msg.message);
|
||||||
|
document.getElementById("messages").appendChild(el);
|
||||||
|
if (!window.earliestMessage)
|
||||||
|
window.earliestMessage = msg.id;
|
||||||
|
});
|
||||||
|
window.socket.on("new_thread", addThread);
|
||||||
|
|
||||||
|
let keys = localStorage.getItem("keys");
|
||||||
|
if (keys) {
|
||||||
|
window.name = localStorage.getItem("name");
|
||||||
|
keys = JSON.parse(keys);
|
||||||
const priv = await openpgp.readKey({ armoredKey: keys.privateKey });
|
const priv = await openpgp.readKey({ armoredKey: keys.privateKey });
|
||||||
const pub = await openpgp.readKey({ armoredKey: keys.publicKey });
|
const pub = await openpgp.readKey({ armoredKey: keys.publicKey });
|
||||||
window.keys = { priv, pub };
|
window.keys = { priv, pub };
|
||||||
localStorage.setItem("keys", JSON.stringify(keys));
|
await auth();
|
||||||
localStorage.setItem("name", name);
|
document.getElementById('app').classList.remove('hidden');
|
||||||
window.name = name;
|
}
|
||||||
window.socket.emit("create_user", { name, pubkey: keys.publicKey });
|
else
|
||||||
};
|
document.getElementById('register').classList.remove('hidden');
|
||||||
document.getElementById("msginput").onsubmit = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
const msg = document.getElementById("msg").value;
|
|
||||||
if (!msg) return;
|
|
||||||
window.socket.emit("send_message", {
|
|
||||||
message: msg,
|
|
||||||
thread: window.currentThreadId,
|
|
||||||
});
|
|
||||||
document.getElementById("msg").value = "";
|
|
||||||
};
|
|
||||||
document.getElementById("loadmore").onclick = (e) => {
|
|
||||||
loadMessages();
|
|
||||||
};
|
|
||||||
document.getElementById("createthread").onsubmit = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
const members = window.threadmembers
|
|
||||||
? window.threadmembers.map((i) => ({ name: i }))
|
|
||||||
: [{ name: window.name }];
|
|
||||||
const perms = document.querySelector(
|
|
||||||
'input[name="permissions"]:checked'
|
|
||||||
).value;
|
|
||||||
console.log(perms, members);
|
|
||||||
if (perms === "private_view") {
|
|
||||||
window.socket.emit("get_keys", { names: members.map((i) => i.name) });
|
|
||||||
} else {
|
|
||||||
createThread(members);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
document.getElementById("membername").onkeydown = (e) => {
|
|
||||||
if (e.key == "Enter") {
|
|
||||||
addMember();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
document.getElementById("addmember").onclick = addMember;
|
|
||||||
|
|
||||||
const keys = localStorage.getItem("keys");
|
|
||||||
if (keys) {
|
|
||||||
window.name = localStorage.getItem("name");
|
|
||||||
loadKeys(JSON.parse(keys)).then(() => {});
|
|
||||||
} else document.getElementById("register").classList.remove("hidden");
|
|
||||||
};
|
};
|
1
db.js
1
db.js
|
@ -1,5 +1,6 @@
|
||||||
const sqlite3 = require("sqlite3");
|
const sqlite3 = require("sqlite3");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
|
|
||||||
const db = new sqlite3.Database("vybe.db");
|
const db = new sqlite3.Database("vybe.db");
|
||||||
|
|
||||||
db.query = function (sql, params) {
|
db.query = function (sql, params) {
|
||||||
|
|
35
index.js
35
index.js
|
@ -3,36 +3,39 @@ const http = require("http");
|
||||||
const { Server } = require("socket.io");
|
const { Server } = require("socket.io");
|
||||||
const compression = require("compression");
|
const compression = require("compression");
|
||||||
|
|
||||||
|
const events = Object.fromEntries([
|
||||||
|
'create_user',
|
||||||
|
'get_history',
|
||||||
|
'send_message',
|
||||||
|
'authenticate',
|
||||||
|
'create_thread',
|
||||||
|
'list_threads',
|
||||||
|
'get_keys',
|
||||||
|
].map(event => [event, require('./src/' + event)]));
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
app.use(compression());
|
app.use(compression());
|
||||||
const server = http.createServer(app);
|
const server = http.createServer(app);
|
||||||
const io = new Server(server, {
|
const io = new Server(server, {
|
||||||
cors: {
|
cors: {
|
||||||
origin: true,
|
origin: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const PORT = process.env.PORT || 3435;
|
const PORT = process.env.PORT || 3435;
|
||||||
|
|
||||||
const actions = require("./src/actions");
|
|
||||||
|
|
||||||
io.cache = {};
|
io.cache = {};
|
||||||
|
|
||||||
io.on("connection", (socket) => {
|
io.on("connection", (socket) => {
|
||||||
for (let action in actions) {
|
for (let event in events) {
|
||||||
socket.on(action, (msg) =>
|
socket.on(event, (msg, callback) =>
|
||||||
actions[action](
|
events[event](msg, callback, socket, io)
|
||||||
msg,
|
);
|
||||||
(response) => socket.emit(action, response),
|
}
|
||||||
socket,
|
|
||||||
io
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
server.listen(PORT, () => {
|
server.listen(PORT, () => {
|
||||||
console.log("server running on port " + PORT);
|
console.log("server running on port " + PORT);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(express.static("client"));
|
app.use(express.static("client"));
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
const create_user = require("./create_user");
|
|
||||||
const get_history = require("./get_history");
|
|
||||||
const send_message = require("./send_message");
|
|
||||||
const authenticate = require("./authenticate");
|
|
||||||
const create_thread = require("./create_thread");
|
|
||||||
const list_threads = require("./list_threads");
|
|
||||||
const get_keys = require("./get_keys");
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
create_user,
|
|
||||||
get_history,
|
|
||||||
send_message,
|
|
||||||
authenticate,
|
|
||||||
create_thread,
|
|
||||||
list_threads,
|
|
||||||
get_keys,
|
|
||||||
};
|
|
|
@ -1,6 +1,8 @@
|
||||||
const db = require("../db");
|
const db = require("../db");
|
||||||
|
|
||||||
const authwrap = (fn) => async (msg, respond, socket, io) => {
|
const authwrap = (fn) => async (msg, respond, socket, io) => {
|
||||||
|
if (!respond)
|
||||||
|
respond = () => {};
|
||||||
if (!msg || !msg.__session) {
|
if (!msg || !msg.__session) {
|
||||||
return respond({
|
return respond({
|
||||||
success: false,
|
success: false,
|
||||||
|
|
Loading…
Reference in New Issue