Compare commits

..

1 Commits
main ... main

Author SHA1 Message Date
jerl e34a8e7a2b celi 2025-06-27 02:31:56 -05:00
18 changed files with 102 additions and 93 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
node_modules node_modules
vybe.db celi.db

View File

@ -1,7 +1,7 @@
# NOTICE: this document is outdated # NOTICE: this document is outdated
# todo: update this document # todo: update this document
# vybe websocket protocol - sent by client # celi websocket protocol - sent by client
socket.io actions + expected msg format and other info socket.io actions + expected msg format and other info
@ -18,7 +18,7 @@ if a message fails, you get a response with the following format:
## authenticate ## authenticate
you must generate a random salt, sign a message `vybe_auth [salt]`, and then send you must generate a random salt, sign a message `celi_auth [salt]`, and then send
```json ```json
{ {

View File

@ -1,9 +1,9 @@
## vybe ## celi
vybe is a work-in-progress decentralized **communication network**. celi is a work-in-progress decentralized **communication network**.
a vybe instance (server) features user accounts and **threads**. a celi instance (server) features user accounts and **threads**.
user accounts are owned by PGP keys stored in users' clients. user accounts are owned by PGP keys stored in users' clients.
@ -30,7 +30,7 @@ after first run, the port is configured in instance.json.
**currently, you'll need to proxy it through a webserver like nginx or Caddy, which needs to have https enabled** for things to work correctly. if you want the easy option, i recommend Caddy. example Caddy config: **currently, you'll need to proxy it through a webserver like nginx or Caddy, which needs to have https enabled** for things to work correctly. if you want the easy option, i recommend Caddy. example Caddy config:
> ``` > ```
> vybe.example.domain { > celi.example.domain {
> reverse_proxy localhost:1312 > reverse_proxy localhost:1312
> header Access-Control-Allow-Origin "*" > header Access-Control-Allow-Origin "*"
> } > }
@ -38,13 +38,14 @@ after first run, the port is configured in instance.json.
(the allow-origin header isn't necessarily required but works as a fallback in case websockets don't work for whatever reason) (the allow-origin header isn't necessarily required but works as a fallback in case websockets don't work for whatever reason)
then go to `https://vybe.example.domain` to start using vybe! then go to `https://celi.example.domain` to start using celi!
## todo ## todo
- encrypt private threads (users already use pgp) - encrypt private threads (users already use pgp)
- video in calls - video in calls
- instance administration and moderation - instance administration and moderation
- notifications
let me know if you have any questions or issues. i can be reached via my website [jerl.zone](https://jerl.zone). let me know if you have any questions or issues. i can be reached via my website [jerl.zone](https://jerl.zone).
if you want to contribute, contact me :) if you want to contribute, contact me :)

View File

@ -219,7 +219,7 @@ document.body.append(html.node`
</div> </div>
<hr class='separator' color='#505050'> <hr class='separator' color='#505050'>
<div id='home' class='column'> <div id='home' class='column'>
<h3>vybe</h3> <h3>celi</h3>
<p id='instances' class='header'>instances:<button onclick=${e => { <p id='instances' class='header'>instances:<button onclick=${e => {
let div = html.node` let div = html.node`
<div> <div>

View File

@ -103,11 +103,11 @@ async function submit(event) {
render(document.body, html` render(document.body, html`
<div id='register' class='hidden'> <div id='register' class='hidden'>
<h1>welcome to vybe</h1> <h1>welcome to celi</h1>
<h3>a communication network (beta)</h3> <h3>a communication network (beta)</h3>
<p> <p>
to get started, you'll need an account. we use public key cryptography to get started, you'll need an account. we use public key cryptography
for security, rather than passwords. your keys are stored in your for security, rather than passwords, your keys are stored in your
browser storage only, so do this on a browser you can access again. browser storage only, so do this on a browser you can access again.
</p> </p>
<p> <p>

View File

@ -8,7 +8,7 @@
<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>celi</title>
<style> <style>
* { * {
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
@ -127,16 +127,14 @@
margin-block: 5px; margin-block: 5px;
word-wrap: break-word; word-wrap: break-word;
} }
.thread:hover,
.tab:hover, .tab:hover,
.instancetitle > span:hover, .instancetitle > span:hover,
#user:hover { #user:hover {
background-color: #333; background-color: #333;
} }
.thread.active,
.tab.active, .tab.active,
button:hover { button:hover {
background-color: #4f4f4f; background-color: #484848;
color: #fff; color: #fff;
} }
label.heading { label.heading {
@ -253,6 +251,13 @@
overflow-y: auto; overflow-y: auto;
} }
.thread { .thread {
&:hover {
background-color: #303030;
}
&.active {
background-color: #404040;
color: #fff;
}
padding: 2px 3px; padding: 2px 3px;
white-space: pre; white-space: pre;
cursor: default; cursor: default;
@ -293,9 +298,9 @@
} }
.tab { .tab {
padding: 5px 7px; padding: 5px 7px;
background-color: #1f1f1f; background-color: #222;
border: 0; border: 0;
color: #ddd; color: #e0e0e0;
font-weight: 500; font-weight: 500;
} }
.tabcontent { .tabcontent {

View File

@ -22,7 +22,7 @@ function loadMessages(callback) {
}); });
msg.value = ''; msg.value = '';
}}> }}>
<input id='msg' placeholder='write a message...' /> <input id='msg' placeholder='write a message...' autocomplete='off' />
<button type='submit' id='sendmsg'>send</button> <button type='submit' id='sendmsg'>send</button>
</form> </form>
`); `);

View File

@ -17,11 +17,14 @@ function setVisibility() {
function openThread(div, pushState) { function openThread(div, pushState) {
if (!document.getElementById('removemember').classList.contains('hidden')) if (!document.getElementById('removemember').classList.contains('hidden'))
document.getElementById('member').classList.add('hidden'); document.getElementById('member').classList.add('hidden');
if (window.currentThread)
window.currentThread.div.classList.remove('active');
if (!div) { if (!div) {
document.getElementById('thread').classList.add('hidden'); document.getElementById('thread').classList.add('hidden');
window.currentThread = null; window.currentThread = null;
return; return;
} }
div.classList.add('active');
document.getElementById('thread').classList.remove('hidden'); document.getElementById('thread').classList.remove('hidden');
const edit = document.getElementById('edit'); const edit = document.getElementById('edit');
if (div.thread.permissions.admin) { if (div.thread.permissions.admin) {
@ -32,9 +35,6 @@ function openThread(div, pushState) {
document.getElementById('membersadd').classList.add('hidden'); document.getElementById('membersadd').classList.add('hidden');
} }
document.getElementById('threadname').textContent = div.thread.name; document.getElementById('threadname').textContent = div.thread.name;
if (window.currentThread)
window.currentThread.div.classList.remove('active');
div.classList.add('active');
window.currentThread = div.thread; window.currentThread = div.thread;
window.currentInstance = div.thread.instance; window.currentInstance = div.thread.instance;
window.currentInstance.emit('get_thread', { thread: div.thread.id }, async msg => { window.currentInstance.emit('get_thread', { thread: div.thread.id }, async msg => {
@ -487,9 +487,9 @@ async function loadThreads(instancediv, select) {
if (el) { if (el) {
Object.assign(el.thread, thread); Object.assign(el.thread, thread);
el.children['name'].textContent = thread.name; el.children['name'].textContent = thread.name;
if (!thread.permissions.everyone.view.value && !el.children['membericon']) if (!thread.permissions.public && !el.children['membericon'])
el.insertAdjacentHTML('beforeend', `<img id='membericon' src='/members.png'>`); el.insertAdjacentHTML('beforeend', `<img id='membericon' src='/members.png'>`);
else if (el.children['membericon'] && thread.permissions.everyone.value) else if (el.children['membericon'] && thread.permissions.public)
el.children['membericon'].remove(); el.children['membericon'].remove();
if (window.currentThread?.id === thread.id) { if (window.currentThread?.id === thread.id) {
Object.assign(window.currentThread, thread); Object.assign(window.currentThread, thread);

View File

@ -1,5 +1,5 @@
{ {
"name": "vybe", "name": "celi",
"version": "1.0.0", "version": "1.0.0",
"description": "", "description": "",
"main": "server.js", "main": "server.js",

View File

@ -46,7 +46,7 @@ if (!instance.url)
it will be auto-set by the first user authentication ! it will be auto-set by the first user authentication !
it can be manually set in instance.json .`); it can be manually set in instance.json .`);
global.vybe = { global.celi = {
instance, instance,
saveSettings, saveSettings,
instances: {}, instances: {},
@ -55,7 +55,7 @@ global.vybe = {
calls: {}, // rtc peer connections go in here calls: {}, // rtc peer connections go in here
streams: {}, streams: {},
connectInstance: async url => { connectInstance: async url => {
let instance = vybe.instances[url]; let instance = celi.instances[url];
function connecting(resolve, reject) { function connecting(resolve, reject) {
instance.socket.on('connect', resolve); instance.socket.on('connect', resolve);
instance.socket.on('connect_error', error => { instance.socket.on('connect_error', error => {
@ -70,7 +70,7 @@ global.vybe = {
} }
} }
else { else {
instance = vybe.instances[url] = { instance = celi.instances[url] = {
socket: ioclient('https://' + url) socket: ioclient('https://' + url)
}; };
await new Promise(connecting); await new Promise(connecting);
@ -92,7 +92,7 @@ app.use(express.static('client'));
// todo: secure this // todo: secure this
app.get('/stream/:id', (req, res) => { app.get('/stream/:id', (req, res) => {
let stream = vybe.streams[req.params.id]; let stream = celi.streams[req.params.id];
if (!stream) { if (!stream) {
res.sendStatus(404); res.sendStatus(404);
return; return;
@ -121,17 +121,17 @@ io.on('connection', (socket) => {
}); });
} }
socket.on('disconnect', async reason => { socket.on('disconnect', async reason => {
let user = vybe.users[socket.__userid]; let user = celi.users[socket.__userid];
if (user) if (user)
user.sockets.splice(user.sockets.indexOf(socket), 1); user.sockets.splice(user.sockets.indexOf(socket), 1);
for (let id in vybe.streams) { for (let id in celi.streams) {
const stream = vybe.streams[id]; const stream = celi.streams[id];
delete stream.listeners[socket.id]; delete stream.listeners[socket.id];
if (stream.socket === socket) if (stream.socket === socket)
stream.stop(); stream.stop();
} }
for (let id in vybe.calls) { for (let id in celi.calls) {
let call = vybe.calls[id]; let call = celi.calls[id];
let connection = call[socket.__userid]; let connection = call[socket.__userid];
if (!connection) if (!connection)
continue; continue;
@ -141,8 +141,8 @@ io.on('connection', (socket) => {
} }
connection.close(); connection.close();
delete call[id]; delete call[id];
delete vybe.threads[id].call[socket.__userid]; delete celi.threads[id].call[socket.__userid];
await vybe.threads[id].emitcall(); await celi.threads[id].emitcall();
} }
}); });
}); });

View File

@ -11,7 +11,7 @@ const authwrap = (fn) => async (msg, respond, socket) => {
} }
return await fn({ return await fn({
...msg, ...msg,
auth_user: vybe.users[socket.__userid] auth_user: celi.users[socket.__userid]
}, respond, socket); }, respond, socket);
}; };

View File

@ -1,12 +1,12 @@
const sqlite3 = require('sqlite3'); const sqlite3 = require('sqlite3');
const fs = require('fs'); const fs = require('fs');
const path = 'vybe.db'; const path = 'celi.db';
const existed = fs.existsSync(path); const existed = fs.existsSync(path);
const db = new sqlite3.Database(path); const db = new sqlite3.Database(path);
db.query = function (sql, params) { db.query = function(sql, params) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
db.all(sql, params, (error, rows) => { db.all(sql, params, (error, rows) => {
if (error) if (error)
@ -17,11 +17,12 @@ db.query = function (sql, params) {
}); });
}; };
(async () => { db.ready = new Promise(async resolve => {
if (!existed) if (!existed)
for (let sql of fs.readFileSync('./db/1-init.sql').toString().split(';')) for (let sql of fs.readFileSync('./db/1-init.sql').toString().split(';'))
if (sql.trim()) if (sql.trim())
await db.query(sql); await db.query(sql);
})(); resolve();
});
module.exports = db; module.exports = db;

View File

@ -15,8 +15,8 @@ async function join(msg, respond, socket) {
success: false, success: false,
message: "user doesn't have permission" message: "user doesn't have permission"
}); });
const thread = vybe.threads[msg.thread]; const thread = celi.threads[msg.thread];
const call = vybe.calls[msg.thread]; const call = celi.calls[msg.thread];
let connection = call[msg.auth_user.id]; let connection = call[msg.auth_user.id];
if (connection) { if (connection) {
if (connection.track) { if (connection.track) {
@ -66,8 +66,8 @@ async function join(msg, respond, socket) {
connection.connected = true; connection.connected = true;
thread.call[msg.auth_user.id] = { thread.call[msg.auth_user.id] = {
id: msg.auth_user.id, id: msg.auth_user.id,
name: vybe.users[msg.auth_user.id].name, name: celi.users[msg.auth_user.id].name,
displayname: vybe.users[msg.auth_user.id].displayname, displayname: celi.users[msg.auth_user.id].displayname,
permissions: Object.fromEntries((await db.query( permissions: Object.fromEntries((await db.query(
`select permission, value from permission `select permission, value from permission
where type = 'user' and thread = ? and user = ?`, where type = 'user' and thread = ? and user = ?`,
@ -104,7 +104,7 @@ async function offer(msg, respond) {
success: false, success: false,
message: 'missing argument' message: 'missing argument'
}); });
let connection = vybe.calls[msg.thread]?.[msg.auth_user.id]; let connection = celi.calls[msg.thread]?.[msg.auth_user.id];
if (!connection) if (!connection)
return respond({ return respond({
success: false, success: false,
@ -124,7 +124,7 @@ async function ice(msg, respond) {
success: false, success: false,
message: 'missing argument' message: 'missing argument'
}); });
let connection = vybe.calls[msg.thread]?.[msg.auth_user.id]; let connection = celi.calls[msg.thread]?.[msg.auth_user.id];
if (!connection) if (!connection)
return respond({ return respond({
success: false, success: false,
@ -144,8 +144,8 @@ async function ice(msg, respond) {
} }
async function leave(msg, respond) { async function leave(msg, respond) {
let thread = vybe.threads[msg.thread]; let thread = celi.threads[msg.thread];
let call = vybe.calls[msg.thread]; let call = celi.calls[msg.thread];
let connection = call?.[msg.auth_user.id]; let connection = call?.[msg.auth_user.id];
if (!connection) if (!connection)
return respond({ return respond({

View File

@ -33,10 +33,10 @@ async function send_message(msg, respond) {
if (p.type === 'user' && p.user == msg.auth_user.id) if (p.type === 'user' && p.user == msg.auth_user.id)
userperms[p.permission] = ['admin', 'post', 'view'].includes(p.permission) userperms[p.permission] = ['admin', 'post', 'view'].includes(p.permission)
? p.value === 'true' : p.value; ? p.value === 'true' : p.value;
for (let id in vybe.users) { for (let id in celi.users) {
if (perms.find(p => p.type === 'everyone' && p.permission === 'view' && p.value === 'true') if (perms.find(p => p.type === 'everyone' && p.permission === 'view' && p.value === 'true')
|| members.includes(id)) { || members.includes(id)) {
for (let s of vybe.users[id].sockets) { for (let s of celi.users[id].sockets) {
s.emit('new_message', { s.emit('new_message', {
id, id,
user: { user: {

View File

@ -65,9 +65,9 @@ async function save_span(msg, respond, socket) {
and type = 'everyone' and value = 'true' and permission = 'view'`, and type = 'everyone' and value = 'true' and permission = 'view'`,
msg.thread msg.thread
); );
for (let userid in vybe.users) { for (let userid in celi.users) {
if (permissions.rows.length > 0 || members.includes(userid)) { if (permissions.rows.length > 0 || members.includes(userid)) {
for (let s of vybe.users[userid].sockets) { for (let s of celi.users[userid].sockets) {
if (s !== socket) if (s !== socket)
s.emit('span', { s.emit('span', {
id, id,

View File

@ -17,14 +17,14 @@ async function stream(msg, respond, socket) {
`select * from permission `select * from permission
where thread = ? and type = 'everyone' and value = 'true' and permission = 'view'`, where thread = ? and type = 'everyone' and value = 'true' and permission = 'view'`,
msg.thread)).rows.length) { msg.thread)).rows.length) {
for (let id in vybe.users) for (let id in celi.users)
for (let socket of vybe.users[id].sockets) for (let socket of celi.users[id].sockets)
socket.emit('stream', stream); socket.emit('stream', stream);
} else { } else {
for (let member of ( for (let member of (
await db.query('select user from member where member.thread = ?', msg.thread) await db.query('select user from member where member.thread = ?', msg.thread)
).rows) { ).rows) {
member = vybe.users[member.user]; member = celi.users[member.user];
if (member) if (member)
for (let socket of member.sockets) for (let socket of member.sockets)
socket.emit('stream', stream); socket.emit('stream', stream);
@ -32,7 +32,7 @@ async function stream(msg, respond, socket) {
} }
} }
if (typeof msg.id === 'number') { if (typeof msg.id === 'number') {
let vstream = vybe.streams[msg.id]; let vstream = celi.streams[msg.id];
if (!vstream) if (!vstream)
return respond({ return respond({
success: false, success: false,
@ -68,9 +68,9 @@ async function stream(msg, respond, socket) {
}, },
name: msg.name name: msg.name
}; };
let thread = vybe.threads[msg.thread]; let thread = celi.threads[msg.thread];
thread.streams.push(stream); thread.streams.push(stream);
vybe.streams[stream.id] = { celi.streams[stream.id] = {
stream, stream,
userid: msg.auth_user.id, userid: msg.auth_user.id,
listeners: {}, listeners: {},
@ -78,7 +78,7 @@ async function stream(msg, respond, socket) {
stop: async () => { stop: async () => {
stream.stopped = true; stream.stopped = true;
thread.streams.splice(thread.streams.findIndex(s => s.id === stream.id), 1); thread.streams.splice(thread.streams.findIndex(s => s.id === stream.id), 1);
delete vybe.streams[stream.id]; delete celi.streams[stream.id];
await send(); await send();
}, },
streams: new Set() streams: new Set()
@ -92,7 +92,7 @@ async function stream(msg, respond, socket) {
} }
async function streamdata(msg, respond) { async function streamdata(msg, respond) {
let stream = vybe.streams[msg.id]; let stream = celi.streams[msg.id];
if (!stream) { if (!stream) {
return respond({ return respond({
success: false, success: false,
@ -119,7 +119,7 @@ async function play_stream(msg, respond, socket) {
message: "user doesn't have permission" message: "user doesn't have permission"
}); });
} }
let stream = vybe.streams[msg.id]; let stream = celi.streams[msg.id];
if (!stream) if (!stream)
return respond({ return respond({
success: false, success: false,

View File

@ -2,11 +2,11 @@ const db = require('../db');
const authwrap = require('../authwrap'); const authwrap = require('../authwrap');
const check_permission = require('../check_permission'); const check_permission = require('../check_permission');
(async () => { db.ready.then(async () => {
for (let thread of (await db.query( for (let thread of (await db.query(
`select name, id from thread` `select name, id from thread`
)).rows) { )).rows) {
vybe.threads[thread.id] = { celi.threads[thread.id] = {
...thread, ...thread,
streams: [], streams: [],
call: {}, // list of members in call call: {}, // list of members in call
@ -19,14 +19,14 @@ const check_permission = require('../check_permission');
`select * from permission `select * from permission
where thread = ? and type = 'everyone' and value = 'true' and permission = 'view'`, where thread = ? and type = 'everyone' and value = 'true' and permission = 'view'`,
this.id)).rows.length) { this.id)).rows.length) {
for (let id in vybe.users) for (let id in celi.users)
for (let socket of vybe.users[id].sockets) for (let socket of celi.users[id].sockets)
socket.emit('call', msg); socket.emit('call', msg);
} else { } else {
for (let member of ( for (let member of (
await db.query('select user from member where member.thread = ?', this.id) await db.query('select user from member where member.thread = ?', this.id)
).rows) { ).rows) {
member = vybe.users[member.user]; member = celi.users[member.user];
if (member) if (member)
for (let socket of member.sockets) for (let socket of member.sockets)
socket.emit('call', msg); socket.emit('call', msg);
@ -34,9 +34,9 @@ const check_permission = require('../check_permission');
} }
} }
}; };
vybe.calls[thread.id] = {}; celi.calls[thread.id] = {};
} }
})(); });
async function create_thread(msg, respond) { async function create_thread(msg, respond) {
// validate inputs // validate inputs
@ -101,7 +101,7 @@ async function create_thread(msg, respond) {
let members = {}; let members = {};
for (let member of msg.members) { for (let member of msg.members) {
let id = member.id.split('@'); let id = member.id.split('@');
id = id[1] === vybe.instance.url ? id[0] : member.id; id = id[1] === celi.instance.url ? id[0] : member.id;
if (members[id]) if (members[id])
continue; continue;
await db.query( await db.query(
@ -116,19 +116,20 @@ async function create_thread(msg, respond) {
values (?, ?, ?, ?, ?, ?)`, values (?, ?, ?, ?, ?, ?)`,
[thread_id, 'user', id, true, permission, String(member.permissions[permission])]); [thread_id, 'user', id, true, permission, String(member.permissions[permission])]);
} }
let thread = vybe.threads[thread_id] = { let thread = celi.threads[thread_id] = {
id: thread_id, id: thread_id,
name: msg.name, name: msg.name,
streams: [], streams: [],
call: {} call: {}
}; };
vybe.calls[thread_id] = {}; celi.calls[thread_id] = {};
if (!msg.permissions?.view_limited) { if (!msg.permissions?.view_limited) {
for (let id in vybe.users) { for (let id in celi.users) {
for (let socket of vybe.users[id].sockets) { for (let socket of celi.users[id].sockets) {
socket.emit('thread', { socket.emit('thread', {
...thread, ...thread,
permissions: { permissions: {
public: true,
view: true, view: true,
post: !msg.permissions?.post_limited || members[id], post: !msg.permissions?.post_limited || members[id],
admin: id === msg.auth_user.id admin: id === msg.auth_user.id
@ -139,7 +140,7 @@ async function create_thread(msg, respond) {
} }
else { else {
for (let member in members) { for (let member in members) {
member = vybe.users[member]; member = celi.users[member];
if (!member) if (!member)
continue; continue;
for (let socket of member.sockets) { for (let socket of member.sockets) {
@ -180,7 +181,7 @@ async function list_threads(msg, respond) {
success: true, success: true,
threads: await Promise.all(threads.rows.map(async row => { threads: await Promise.all(threads.rows.map(async row => {
let thread = {}; let thread = {};
Object.assign(thread, vybe.threads[row.id]); Object.assign(thread, celi.threads[row.id]);
thread.permissions = await check_permission(msg.auth_user.id, row.id); thread.permissions = await check_permission(msg.auth_user.id, row.id);
thread.permissions.public = row.value === 'true'; thread.permissions.public = row.value === 'true';
return thread; return thread;
@ -248,7 +249,7 @@ async function get_thread(msg, respond) {
return respond({ return respond({
success: true, success: true,
thread: { thread: {
...vybe.threads[msg.thread], ...celi.threads[msg.thread],
permissions: perms, permissions: perms,
members: Object.values(members) members: Object.values(members)
} }
@ -276,7 +277,7 @@ async function edit_thread(msg, respond) {
message: "user doesn't have permission" message: "user doesn't have permission"
}); });
} }
let thread = vybe.threads[msg.id]; let thread = celi.threads[msg.id];
// update name // update name
await db.query( await db.query(
'update thread set name = ? where id = ?', 'update thread set name = ? where id = ?',
@ -368,11 +369,12 @@ async function edit_thread(msg, respond) {
msg.id msg.id
)).rows.map(row => [row.user, true])); )).rows.map(row => [row.user, true]));
if (!msg.permissions?.view_limited) { if (!msg.permissions?.view_limited) {
for (let id in vybe.users) for (let id in celi.users)
for (let socket of vybe.users[id].sockets) for (let socket of celi.users[id].sockets)
socket.emit('thread', { socket.emit('thread', {
...thread, ...thread,
permissions: { permissions: {
public: true,
view: true, view: true,
post: !msg.permissions?.post_limited || id in members, post: !msg.permissions?.post_limited || id in members,
admin: id === msg.auth_user.id && perms.admin, admin: id === msg.auth_user.id && perms.admin,
@ -382,7 +384,7 @@ async function edit_thread(msg, respond) {
} }
else { else {
for (let member in members) { for (let member in members) {
member = vybe.users[member]; member = celi.users[member];
if (!member) if (!member)
continue; continue;
for (let socket of member.sockets) for (let socket of member.sockets)

View File

@ -85,7 +85,7 @@ async function authenticate(msg, respond, socket) {
expectSigned: true, expectSigned: true,
date: new Date(Date.now() + 60000 * 4) // slightly in the future to compensate for some system clocks date: new Date(Date.now() + 60000 * 4) // slightly in the future to compensate for some system clocks
}); });
if (vybe.instance.url === id[1] || (!vybe.instance.url && !id[0])) { if (celi.instance.url === id[1] || (!celi.instance.url && !id[0])) {
// this should be user's home instance // this should be user's home instance
user = await getUser(id[0], msg.name); user = await getUser(id[0], msg.name);
if (!user) { if (!user) {
@ -102,13 +102,13 @@ async function authenticate(msg, respond, socket) {
); );
if (result.rows.length === 0) { if (result.rows.length === 0) {
// request auth from logged in sessions // request auth from logged in sessions
if (!vybe.users[user.id]) if (!celi.users[user.id])
vybe.users[user.id] = { celi.users[user.id] = {
...user, ...user,
sockets: [], sockets: [],
authrequests: {} authrequests: {}
}; };
user = vybe.users[user.id]; user = celi.users[user.id];
let id = key.getFingerprint().slice(0, 8); let id = key.getFingerprint().slice(0, 8);
let time = Date.now(); let time = Date.now();
if (!await new Promise(resolve => { if (!await new Promise(resolve => {
@ -129,15 +129,15 @@ async function authenticate(msg, respond, socket) {
[user.id, pubkey]); [user.id, pubkey]);
} }
// default instance url to first authenticated user's location.host // default instance url to first authenticated user's location.host
if (!vybe.instance.url) { if (!celi.instance.url) {
vybe.instance.url = id[1]; celi.instance.url = id[1];
vybe.saveSettings(); celi.saveSettings();
} }
} }
else { else {
// connect to user's home instance and ask for their key // connect to user's home instance and ask for their key
try { try {
let instance = await vybe.connectInstance(id[1]); let instance = await celi.connectInstance(id[1]);
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
instance.socket.emit('get_keys', { ids: [id[0]] }, msg => { instance.socket.emit('get_keys', { ids: [id[0]] }, msg => {
if (!msg.success) { if (!msg.success) {
@ -164,7 +164,7 @@ async function authenticate(msg, respond, socket) {
// this socket is now authenticated // this socket is now authenticated
if (!user.displayname) if (!user.displayname)
user.displayname = user.name; user.displayname = user.name;
user = vybe.users[user.id] || (vybe.users[user.id] = { user = celi.users[user.id] || (celi.users[user.id] = {
...user, ...user,
sockets: [], sockets: [],
authrequests: {} authrequests: {}
@ -175,7 +175,7 @@ async function authenticate(msg, respond, socket) {
respond({ respond({
success: true, success: true,
instance: { instance: {
id: vybe.instance.id id: celi.instance.id
}, },
id: user.id, id: user.id,
name: user.name, name: user.name,
@ -198,7 +198,7 @@ async function authenticate(msg, respond, socket) {
} }
async function authorize_key(msg, respond) { async function authorize_key(msg, respond) {
let authrequest = vybe.users[msg.auth_user.id].authrequests[msg.id]; let authrequest = celi.users[msg.auth_user.id].authrequests[msg.id];
if (!authrequest) { if (!authrequest) {
return respond({ return respond({
success: false, success: false,
@ -219,8 +219,8 @@ async function update_user(msg, respond) {
await db.query( await db.query(
`update user set displayname = ?, bio = ?, public = ? where id = ?`, `update user set displayname = ?, bio = ?, public = ? where id = ?`,
[msg.displayname, msg.bio, !!msg.public, msg.auth_user.id]); [msg.displayname, msg.bio, !!msg.public, msg.auth_user.id]);
vybe.users[msg.auth_user.id].displayname = msg.displayname; celi.users[msg.auth_user.id].displayname = msg.displayname;
vybe.users[msg.auth_user.id].bio = msg.bio; celi.users[msg.auth_user.id].bio = msg.bio;
respond({ success: true }); respond({ success: true });
} }