diff --git a/db/dbmore.json b/db/dbmore.json new file mode 100644 index 0000000..ff4d9af --- /dev/null +++ b/db/dbmore.json @@ -0,0 +1,48 @@ +{ + "nodes": { + "MEMBER-1": { + "id": 1, + "email": "samrussell99@pm.me", + "firstName": "Sam", + "lastName": "Russell", + "password": "$argon2id$v=19$m=65536,t=3,p=4$PDu5qx47zzY0dX0/4iQuqw$JxePLouwOEi2Q0wA4JHQQ4GwvqAvxqWhj7n9aC8HZIk", + "address": { + "address1": "2014 E 9th St", + "address2": "Unit A", + "zip": "78702", + "state": "Texas", + "city": "Austin" + }, + "tokenUsed": "810387b6-851e-4883-b9a3-c59703dc0fc9", + "joined": "11.24.2025-12:54:360784am" + }, + "NETWORK-1": { + "id": 1, + "name": "Comal County Young Republicans", + "apps": [ + "Dashboard", + "People", + "Messages" + ], + "logo": "comalyr.svg" + }, + "NETWORK-2": { + "id": 2, + "name": "Hyperia", + "apps": [ + "Dashboard", + "People", + "Messages" + ], + "logo": "hyperia.svg" + } + }, + "edges": { + "MEMBER_IN_NETWORK-1": { + "id": 1, + "to": "NETWORK-1", + "from": "MEMBER-1", + "created": "11.24.2025-12:54:360784am" + } + } +} \ No newline at end of file diff --git a/server/auth.js b/server/auth.js index e1b860a..7196813 100644 --- a/server/auth.js +++ b/server/auth.js @@ -37,6 +37,7 @@ export default class AuthHandler { const email = payload.email; const user = db.members.getByEmail(email); + const userOrgs = db.edges.getByFrom(db.members.prefix + "-" + user.id) res.send({ email: user.email, name: user.firstName + " " + user.lastName }); } catch (err) { res.status(401).send({ error: "Invalid token" }); diff --git a/server/db/db.js b/server/db/db.js index ea184f0..6e4201c 100644 --- a/server/db/db.js +++ b/server/db/db.js @@ -1,41 +1,73 @@ import fs from 'fs/promises'; import chalk from 'chalk'; import path from 'path'; - -import Titles from "./model/Titles.js" -import Networks from "./model/Networks.js" -import Members from './model/Members.js' -import Tokens from './model/Tokens.js' -import Payments from "./model/Payments.js" -import Posts from "./model/Forum/Posts.js" -import Conversations from "./model/Messages/Conversations.js" -import Messages from "./model/Messages/Messages.js" +import {nodeModels, edgeModels} from './model/import.js' export default class Database { - titles = new Titles() - networks = new Networks() - members = new Members() - tokens = new Tokens() - payments = new Payments() - posts = new Posts() - conversations = new Conversations() - messages = new Messages() - fromID = { - "MEMBER": this.members, - "NETWORK": this.networks, - "TITLE": this.titles, - "TOKEN": this.tokens, - "PAYMENT": this.payments, - "POST": this.posts, - "CONVERSATION": this.conversations, - "DM": this.messages - } + nodes = new Array(10000).fill(0); + edges = new Array(10000).fill(0); constructor() { + let values = Object.values(nodeModels) + for(let i = 0; i < values.length; i++) { + let key = values[i].constructor.name + key = key.toLowerCase() + "s" + this[key] = values[i] + } + let eValues = Object.values(edgeModels) + for(let i = 0; i < eValues.length; i++) { + let key = eValues[i].constructor.name + key = key.toLowerCase() + "s" + this[key] = eValues[i] + } this.loadData() } + addNode(id, node) { + try { + let type = id.split("-")[0] + let model = nodeModels[type[0] + type.slice(1).toLowerCase()] + if(model) { + let schema = model.schema + let result = schema.safeParse(node) + if(result.success) { + this.nodes[model.indices[1]] = node + model.indices[1]++; + } else { + console.error(result.error) + throw new global.ServerError(400, "Invalid Data!"); + } + } else { + throw new Error("Type does not exist for node: " + id) + } + } catch(e) { + throw e + } + } + + addEdge(id, edge) { + try { + let type = id.split("-")[0] + let model = edgeModels[type] + if(model) { + let schema = model.schema + let result = schema.safeParse(edge) + if(result.success) { + this.edges[model.indices[1]] = edge + model.indices[1]++; + } else { + console.error(result.error) + throw new global.ServerError(400, "Invalid Data!"); + } + } else { + throw new Error("Type does not exist for edge: " + id) + } + } catch(e) { + throw e + } + } + async loadData() { const dbData = await fs.readFile(path.join(process.cwd(), 'db/db.json'), 'utf8'); let dbJson; @@ -44,24 +76,21 @@ export default class Database { } catch { dbJson = [] } + let nodes = dbJson["nodes"]; let entries = Object.entries(nodes) - for(let i=0; i { @@ -72,37 +101,37 @@ export default class Database { async saveData() { let data = { - "nodes": { - - }, - "edges": { - - } + "nodes": {}, + "edges": {} } - let arrs = [ - this.titles.entries, - this.members.entries, - this.tokens.entries, - this.posts.entries, - this.conversations.entries, - this.messages.entries, - this.payments.entries, - ] - let ids = [ - Object.entries(this.titles.ids), - Object.entries(this.members.ids), - Object.entries(this.tokens.ids), - Object.entries(this.posts.ids), - Object.entries(this.conversations.ids), - Object.entries(this.messages.ids), - Object.entries(this.payments.ids), - ] - for(let i=0; i { + if(entry) { + for(let j = 0; j < nModels.length; j++) { + let model = nModels[j] + let indices = model.indices + if(i >= indices[0] && i < indices[1]) { + let prefix = model.prefix + data.nodes[prefix + "-" + entry.id] = entry + } + } } - } + }) + + let eModels = Object.values(edgeModels) + this.edges.forEach((entry, i) => { + if(entry) { + for(let j = 0; j < eModels.length; j++) { + let model = eModels[j] + let indices = model.indices + if(i >= indices[0] && i < indices[1]) { + let prefix = model.prefix + data.nodes[prefix + "-" + entry.id] = entry + } + } + } + }) let string = JSON.stringify(data, null, 4) await fs.writeFile(path.join(process.cwd(), 'db/db.json'), string, "utf8"); diff --git a/server/db/model/OrderedObject.js b/server/db/model/OrderedObject.js deleted file mode 100644 index 5d174dd..0000000 --- a/server/db/model/OrderedObject.js +++ /dev/null @@ -1,27 +0,0 @@ -export default class OrderedObject { - entries = [] - ids = {} - indexes = [] - - add(id, data) { - if(this.ids[id]) { - console.error(`Can't add item ${id}: id already exists`) - throw new global.ServerError(400, `Member with this email already exists`) - } - this.entries.push(data) - this.ids[id] = this.entries.length - 1 - } - - update(id, data) { - let index = this.ids[id] - this.entries[index] = data - } - - delete(key) { - if (typeof key === "number") { - return this.entries[key] - } else { - return this.entries[this.ids[key]] - } - } -} \ No newline at end of file diff --git a/server/db/model/Titles.js b/server/db/model/Titles.js deleted file mode 100644 index b290707..0000000 --- a/server/db/model/Titles.js +++ /dev/null @@ -1,52 +0,0 @@ -import OrderedObject from "./OrderedObject.js" - -export default class Titles extends OrderedObject { - - save(newTitle) { - let id = `HY-${this.entries.length+1}` - if(this.validate(id, newTitle)) { - try { - super.add(id, newTitle) - } catch(e) { - console.error(e) - throw e - } - } else { - throw new global.ServerError(400, "Invalid Member Data!"); - } - } - - validate(id, node) { - let checkID = () => { - let split = id.split("-") - return ( - split.length === 2 - && split[0] === "HY" - && !isNaN(Number(split[1])) - ) - } - let idres = checkID() - if(!idres) { - return false - } - - let checkFields = () => { - let fields = [ - "fullName", - ] - for(let i = 0; i < fields.length; i++) { - if(!node[fields[i]]) { - throw new Error(`Title ${id} is missing trait ${fields[i]}`) - return false - } - } - return true - } - let fieldres = checkFields() - if(!fieldres) { - return false - } - - return true - } -} \ No newline at end of file diff --git a/server/db/model/Tokens.js b/server/db/model/Tokens.js deleted file mode 100644 index 21de174..0000000 --- a/server/db/model/Tokens.js +++ /dev/null @@ -1,41 +0,0 @@ -import OrderedObject from "./OrderedObject.js" -import { z } from 'zod'; - -export default class Tokens extends OrderedObject { - - schema = z.object({ - index: z.number(), - url: z.string(), - uuid: z.string().regex( - /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i, - "Invalid UUID" - ), - used: z.boolean(), - }) - - markUsed(uuid) { - let token = this.get(uuid) - token.used = true - super.update(`TOKEN-${uuid}`, token) - } - - save(token) { - let id = `TOKEN-${token.uuid}` - let result = this.schema.safeParse(token) - if(result.success) { - try { - super.add(id, token) - } catch(e) { - console.error(e) - throw e - } - } else { - console.error(result.error) - throw new global.ServerError(400, "Invalid Member Data!"); - } - } - - get(uuid) { - return this.entries[this.ids[`TOKEN-${uuid}`]] - } -} \ No newline at end of file diff --git a/server/db/model/Messages/Conversations.js b/server/db/model/dms/conversation.js similarity index 93% rename from server/db/model/Messages/Conversations.js rename to server/db/model/dms/conversation.js index aef24da..92f71a1 100644 --- a/server/db/model/Messages/Conversations.js +++ b/server/db/model/dms/conversation.js @@ -1,7 +1,11 @@ -import OrderedObject from "../OrderedObject.js" import { z } from 'zod'; -export default class Conversations extends OrderedObject { +export default class Conversation { + indices = null + + constructor(indices) { + this.indices = indices + } schema = z.object({ id: z.number(), diff --git a/server/db/model/Messages/Messages.js b/server/db/model/dms/dm.js similarity index 92% rename from server/db/model/Messages/Messages.js rename to server/db/model/dms/dm.js index ef132b5..0b7c2a1 100644 --- a/server/db/model/Messages/Messages.js +++ b/server/db/model/dms/dm.js @@ -1,7 +1,11 @@ -import OrderedObject from "../OrderedObject.js" import { z } from 'zod'; -export default class Messages extends OrderedObject { +export default class Message { + indices = null + + constructor(indices) { + this.indices = indices + } schema = z.object({ id: z.number(), diff --git a/server/db/model/edge.js b/server/db/model/edge.js new file mode 100644 index 0000000..778aa20 --- /dev/null +++ b/server/db/model/edge.js @@ -0,0 +1,36 @@ +import { z } from 'zod'; + +export default class Edge { + schema = z.object({ + id: z.number(), + from: z.string(), + to: z.string(), + created: z.string() + }) + .strict() + + save(n, id) { + let result = this.schema.safeParse(n) + if(result.success) { + try { + super.add(id, n) + } catch(e) { + console.error(e) + throw e + } + } else { + console.error(result.error) + throw new global.ServerError(400, "Invalid Member Data!"); + } + } + + getByFrom(fromID) { + let result = [] + for(let i = 0; i < this.entries.length; i++) { + if(entries[i].from === fromID) { + // let + } + } + console.log(fromID) + } +} \ No newline at end of file diff --git a/server/db/model/edges/MemberInNetwork.js b/server/db/model/edges/MemberInNetwork.js new file mode 100644 index 0000000..5198ebc --- /dev/null +++ b/server/db/model/edges/MemberInNetwork.js @@ -0,0 +1,17 @@ +import { z } from 'zod' + +export default class MemberInNetwork { + schema = z.object({ + id: z.number(), + from: z.string(), + to: z.string(), + created: z.string() + }) + .strict() + + indices = null + + constructor(indices) { + this.indices = indices + } +} \ No newline at end of file diff --git a/server/db/model/Forum/Posts.js b/server/db/model/forum/post.js similarity index 92% rename from server/db/model/Forum/Posts.js rename to server/db/model/forum/post.js index d8a2240..00d297c 100644 --- a/server/db/model/Forum/Posts.js +++ b/server/db/model/forum/post.js @@ -1,7 +1,12 @@ -import OrderedObject from "../OrderedObject.js" import { z } from 'zod'; -export default class Posts extends OrderedObject { +export default class Post { + indices = null + + constructor(indices) { + this.indices = indices + } + schema = z.object({ text: z.string(), time: z.string(), diff --git a/server/db/model/import.js b/server/db/model/import.js new file mode 100644 index 0000000..01c1f88 --- /dev/null +++ b/server/db/model/import.js @@ -0,0 +1,36 @@ +import Title from "./title.js" +import Network from "./network.js" +import Member from './member.js' +import Payment from "./payment.js" +import Post from "./forum/post.js" +import Conversation from "./dms/conversation.js" +import DM from "./dms/dm.js" +import MemberInNetwork from "./edges/MemberInNetwork.js" + +let nIndices = { + "MEMBER" : [0, 0], // [id, startIndex, nextEmptyIndex + "NETWORK" : [100, 100], + "TITLE" : [200, 200], + "PAYMENT" : [300, 300], + "POST" : [400, 400], + "CONVERSATION" : [3000, 3000], + "DM" : [6000, 6000], +} + +let eIndices = { + "MEMBER_IN_NETWORK": [0, 0] +} + +export let nodeModels = { + Member: new Member(nIndices.MEMBER), + Network: new Network(nIndices.NETWORK), + Title: new Title(nIndices.TITLE), + Payment: new Payment(nIndices.PAYMENT), + Post: new Post(nIndices.POST), + Conversation: new Conversation(nIndices.CONVERSATION), + DM: new DM(nIndices.DM), +} + +export let edgeModels = { + MEMBER_IN_NETWORK: new MemberInNetwork(eIndices.MEMBER_IN_NETWORK) +} \ No newline at end of file diff --git a/server/db/model/Members.js b/server/db/model/member.js similarity index 82% rename from server/db/model/Members.js rename to server/db/model/member.js index 7de4f51..95eaec1 100644 --- a/server/db/model/Members.js +++ b/server/db/model/member.js @@ -1,8 +1,14 @@ -import OrderedObject from "./OrderedObject.js" import argon2 from 'argon2'; import { z } from 'zod'; -export default class Members extends OrderedObject { +export default class Member { + prefix = "MEMBER" + indices = null + + constructor(indices) { + this.indices = indices + } + addressSchema = z.object({ address1: z.string(), address2: z.string().optional(), @@ -21,14 +27,13 @@ export default class Members extends OrderedObject { "Invalid UUID" ), joined: z.string(), - address: this.addressSchema, - networks: z.array(z.number()) + address: this.addressSchema }) isHashed = (s) => {return s.startsWith("$argon2")} save(member) { - let id = `MEMBER-${member.id}` + let id = `${this.prefix}-${member.id}` let result = this.schema.safeParse(member) if(result.success) { try { @@ -57,9 +62,9 @@ export default class Members extends OrderedObject { } getByEmail(email) { - for(let i=0; i { - console.log("get") let url = req.url let publicSite = () => { diff --git a/ui/public/pages/Home.js b/ui/public/pages/Home.js index b4e2ecb..e7d2127 100644 --- a/ui/public/pages/Home.js +++ b/ui/public/pages/Home.js @@ -22,7 +22,7 @@ class Home extends Shadow { VStack(() => { HStack(() => { - span("The Network OS") + span("The Community OS") .fontFamily("Canterbury") .color("var(--accent2)") .fontSize(2.5, em)