main
jerl 2024-08-20 19:32:32 -07:00
parent f413718bbf
commit f4bf071472
6 changed files with 35 additions and 1305 deletions

View File

@ -11,9 +11,9 @@ each thread features a chatroom, a **space**, and audio streams.
a space is like a text blackboard, basically. you can write text and move it around and resize it with your mouse. a space is like a text blackboard, basically. you can write text and move it around and resize it with your mouse.
once you have an account on any instance, you can connect to and interact with any other instance, right from within your home instance ui. once you have an account on any instance, you can connect to and interact with any other instance, right from within your home instance UI.
to run your own instance, clone this repo and: to run your own instance, make sure you have nodejs installed, clone this repo, and run:
> `npm install` > `npm install`
@ -27,7 +27,7 @@ it will run on port 1312 by default; you can change this by setting PORT on firs
after first-run, the port is configured in instance.json. 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.my.domain { > vybe.my.domain {
@ -37,4 +37,11 @@ currently, you'll need to proxy it through a webserver like nginx or Caddy, whic
then go to `https://vybe.my.domain` to start using vybe! then go to `https://vybe.my.domain` to start using vybe!
let me know if you have any questions or issues. my website is [jerl.zone](https://jerl.zone). ## todo
- encrypt private threads (users already use pgp)
- voice/video calls
- instance administration and moderation
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 :)

View File

@ -204,6 +204,9 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
#threadshead {
margin-block: 2px 4px;
}
#threadlist { #threadlist {
overflow: auto; overflow: auto;
} }
@ -211,6 +214,7 @@
margin: 2px; margin: 2px;
padding: 6px; padding: 6px;
background-color: #222; background-color: #222;
cursor: default;
} }
.user { .user {
white-space: pre-wrap; white-space: pre-wrap;

View File

@ -128,7 +128,7 @@ function switchTab(tab) {
document.getElementById(tab.id.slice(0, -3)).classList.remove('hidden'); document.getElementById(tab.id.slice(0, -3)).classList.remove('hidden');
} }
function newThread() { function newThread(instance) {
let form = document.getElementById('createthread'); let form = document.getElementById('createthread');
if (form) { if (form) {
form.remove(); form.remove();
@ -139,14 +139,12 @@ function newThread() {
return; return;
} }
const instancediv = this.parentElement.parentElement;
let members = [{ let members = [{
id: String(window.id), id: String(window.id),
name: window.name, name: window.name,
permissions: { admin: 'true' } permissions: { admin: 'true' }
}]; }];
if (instancediv.instance !== window.instancelist[0]) { if (instance !== window.instancelist[0]) {
members[0].id += '@' + location.host; members[0].id += '@' + location.host;
members[0].name += '@' + location.host; members[0].name += '@' + location.host;
} }
@ -156,7 +154,7 @@ function newThread() {
if (!name.value) if (!name.value)
return; return;
let at = name.value.split('@'); let at = name.value.split('@');
let url = at[1] || instancediv.instance.url; let url = at[1] || instance.url;
let error = document.getElementById('newmembererror'); let error = document.getElementById('newmembererror');
let user = await window.getUser('@' + url, at[0]); let user = await window.getUser('@' + url, at[0]);
if (!user) { if (!user) {
@ -165,7 +163,7 @@ function newThread() {
} }
error.innerText = ''; error.innerText = '';
user.id = String(user.id); user.id = String(user.id);
if (instancediv.instance.url !== url) { if (instance.url !== url) {
user.id += '@' + url; user.id += '@' + url;
user.name += '@' + url; user.name += '@' + url;
} }
@ -197,7 +195,7 @@ function newThread() {
permissions = { view_limited: true, post_limited: true }; permissions = { view_limited: true, post_limited: true };
// todo: generate key and encrypt // todo: generate key and encrypt
} }
instancediv.instance.emit('create_thread', instance.emit('create_thread',
{ name, permissions, members }, { name, permissions, members },
msg => { msg => {
if (!msg.success) { if (!msg.success) {
@ -206,7 +204,7 @@ function newThread() {
} }
// since the form exists, this will perform cleanup // since the form exists, this will perform cleanup
newThread(); newThread();
chooseThread.call(instancediv.children['threads'].children['threadlist'] chooseThread.call(this.parentElement.parentElement.children['threadlist']
.children['thread' + msg.id]); .children['thread' + msg.id]);
document.getElementById('loadmore').classList.add('hidden'); document.getElementById('loadmore').classList.add('hidden');
} }
@ -425,10 +423,12 @@ async function loadThreads(instancediv, select) {
if (!instancediv.children['threads']) { if (!instancediv.children['threads']) {
instancediv.append(html.node` instancediv.append(html.node`
<div id='threads'> <div id='threads'>
<p id='threadshead'> <div id='threadshead'>
<strong>threads</strong> <strong>threads</strong>
<button id='newthread' onclick=${newThread}>create</button> <button id='newthread' onclick=${function(e) {
</p> newThread.call(this, instancediv.instance);
}}>create</button>
</div>
<div id='threadlist'>loading...</div> <div id='threadlist'>loading...</div>
</div>`); </div>`);
const threadlist = instancediv.children['threads'].children['threadlist']; const threadlist = instancediv.children['threads'].children['threadlist'];

View File

@ -14,7 +14,7 @@ for (let file of fs.readdirSync('./src/events')) {
function rand32() { function rand32() {
let str = ''; let str = '';
const lookups = 'bcdefghjklmnpqrstvwxyz0123456789'.split(''); const lookups = 'abcdefghjklmnpqrstvwxyz0123456789'.split('');
while (str.length < 16) { while (str.length < 16) {
const n = Math.random() * lookups.length; const n = Math.random() * lookups.length;
str += lookups[Math.floor(n)]; str += lookups[Math.floor(n)];

View File

@ -21,7 +21,6 @@ async function create_user(msg, respond) {
msg.name msg.name
]); ]);
if (result.rows.length > 0) { if (result.rows.length > 0) {
console.log(`username already exists: ${result}`);
return respond({ return respond({
success: false, success: false,
message: 'a user with this name already exists on this server' message: 'a user with this name already exists on this server'
@ -113,6 +112,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])
vybe.users[user.id] = {
...user,
sockets: [],
authrequests: {}
};
user = vybe.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 => {
@ -192,7 +198,7 @@ async function authenticate(msg, respond, socket) {
}); });
} }
catch (err) { catch (err) {
console.error('error in authentication: ' + err); console.error('error in authentication: ', err);
respond({ respond({
success: false, success: false,
message: 'message signature verification failed' message: 'message signature verification failed'

1287
yarn.lock

File diff suppressed because it is too large Load Diff