Signup tentatively works

This commit is contained in:
metacryst
2025-11-22 23:12:01 -06:00
parent 525642d04e
commit c3ed5ac5ac
21 changed files with 461 additions and 287 deletions

View File

@@ -1,29 +1,21 @@
const fs = require('fs/promises');
const chalk = require('chalk');
const path = require('path');
import QuillDB from "../_/quilldb.js"
import fs from 'fs/promises'
import path from 'path'
import Title from "./model/Title.js"
import Member from './model/Member.js'
import Token from './model/Token.js'
import Titles from "./model/Titles.js"
import Members from './model/Members.js'
import Tokens from './model/Tokens.js'
export default class Database {
nodes = [];
types = [
{
validate: Title,
start: 0,
end: null,
},
{
validate: Member,
start: null,
end: null,
},
{
validate: Token,
start: null,
end: null,
},
]
titles = new Titles()
members = new Members()
tokens = new Tokens()
fromID = {
"HY": this.titles,
"MEMBER": this.members,
"TOKEN": this.tokens
}
constructor() {
this.loadData()
@@ -38,82 +30,25 @@ export default class Database {
dbJson = []
}
let nodes = dbJson["nodes"];
this.validateNodes(nodes)
}
validateNodes(nodes) {
nodes = Object.entries(nodes)
let t = 0
let currentType = () => {return this.types[t]}
let nextType = () => {return this.types[t+1]}
let selectNextType = () => {
currentType().end = t
t += 1;
currentType().start = t
}
let lastNode = (i=null) => {
if(i == null) throw new Error("must pass a param to lastNode()")
return i+1 === nodes.length
}
for(let i=0; i<nodes.length; i++) {
if(this.validateNode(currentType(), nodes[i])) {
if(lastNode(i)) {
currentType().end = i
break;
let entries = Object.entries(nodes)
for(let i=0; i<entries.length; i++) {
let entry = entries[i]
let id = entry[0]; let node = entry[1];
let type = id.split("-")[0]
try {
let collection = this.fromID[type]
if(collection) {
collection.add(node)
} else {
continue;
throw new Error("Type does not exist for node: ", id)
}
} else if(this.validateNode(nextType(), nodes[i])) {
selectNextType()
continue;
} else {
throw new Error("Nodes are out of order or corrupted!")
} catch(e) {
throw e
}
}
}
validateNode(type, node) {
let [key, value] = node
return type.validate(key, value)
}
get = {
user: (id) => {
return this.nodes[id]
},
userByEmail: (email) => {
for (const id of this.labels["User"]) {
const user = this.get.user(id);
if (user.email === email) {
return { id, ...user }
}
}
return null;
},
token: (id) => {
return this.nodes[`TOKEN-${id}`]
}
}
add = {
user: (node) => {
let lastUser = {}
}
}
submitNewUser(qrCodeID, userInfo) {
let newUser = {
labels: ["User"],
...userInfo
}
if(User(newUser))
this.add.user(newUser)
}
generateUserID() {
let id = this.labels["User"].length + 1;
while (this.get.user(`user-${id}`)) {

View File

@@ -1,43 +0,0 @@
export default function Member(id, node) {
let idTraits = {
firstWord: "MEMBER",
length: 2
}
let fields = [
"firstName",
"lastName",
"email",
"password"
]
let checkID = () => {
let split = id.split("-")
return (
split.length === idTraits.length
&& split[0] === idTraits.firstWord
&& !isNaN(Number(split[1]))
)
}
let idres = checkID()
if(!idres) {
return false
}
let checkFields = () => {
for(let i = 0; i < fields.length; i++) {
if(!node[fields[i]]) {
throw new Error(`Member ${node.email} is missing trait ${fields[i]}`)
return false
} else {
return true
}
}
}
let fieldres = checkFields()
if(!fieldres) {
return false
}
return true
}

View File

@@ -0,0 +1,64 @@
import OrderedObject from "./OrderedObject.js"
export default class Members extends OrderedObject {
add(newMember) {
console.log("adding ", newMember)
let id = `MEMBER-${newMember.email}`
if(this.validate(id, newMember)) {
try {
super.add(id, newMember)
} catch(e) {
console.error(e)
throw e
}
} else {
throw new global.ServerError(400, "Invalid Member Data!");
}
}
validate(id, node) {
let idTraits = {
firstWord: "MEMBER"
}
let fields = [
"firstName",
"lastName",
"email",
"password"
]
let checkID = () => {
let split = id.split("-")
return (
split[0] === idTraits.firstWord
&& split[1].includes("@")
&& split[1].includes(".")
)
}
let idres = checkID()
if(!idres) {
console.log("id failed: ", id)
return false
}
let checkFields = () => {
for(let i = 0; i < fields.length; i++) {
if(!node[fields[i]]) {
throw new Error(`Member ${node.email} is missing trait ${fields[i]}`)
return false
} else {
return true
}
}
}
let fieldres = checkFields()
if(!fieldres) {
console.log("fields failed")
return false
}
return true
}
}

View File

@@ -0,0 +1,29 @@
export default class OrderedObject {
entries = []
ids = {}
add(id, data) {
if(this.get(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
}
delete(key) {
if (typeof key === "number") {
return this.entries[key]
} else {
return this.entries[this.ids[key]]
}
}
get(key) {
if (typeof key === "number") {
return this.entries[key]
} else {
return this.entries[this.ids[key]]
}
}
}

View File

@@ -1,33 +0,0 @@
export default function Title(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
}

53
server/db/model/Titles.js Normal file
View File

@@ -0,0 +1,53 @@
import OrderedObject from "./OrderedObject.js"
export default class Titles extends OrderedObject {
add(newTitle) {
let id = `HY-${this.entries.length+1}`
console.log(id)
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
}
}

View File

@@ -1,39 +0,0 @@
export default function Token(id, node) {
let idTraits = {
firstWord: "TOKEN"
}
let fields = [
"index",
"url",
"used"
]
let checkID = () => {
let split = id.split("-")
return (
split[0] === idTraits.firstWord
)
}
let idres = checkID()
if(!idres) {
return false
}
let checkFields = () => {
for(let i = 0; i < fields.length; i++) {
if(!node[fields[i]]) {
throw new Error(`Token ${node.email} is missing trait ${fields[i]}`)
return false
} else {
return true
}
}
}
let fieldres = checkFields()
if(!fieldres) {
return false
}
return true
}

62
server/db/model/Tokens.js Normal file
View File

@@ -0,0 +1,62 @@
import OrderedObject from "./OrderedObject.js"
export default class Tokens extends OrderedObject {
add(token) {
let id = `TOKEN-${token.uuid}`
if(this.validate(id, token)) {
try {
super.add(id, token)
} catch(e) {
console.error(e)
throw e
}
} else {
throw new global.ServerError(400, "Invalid Member Data!");
}
}
get(uuid) {
return super.get(`TOKEN-${uuid}`)
}
validate(id, node) {
let idTraits = {
firstWord: "TOKEN"
}
let fields = [
"index",
"url",
"used"
]
let checkID = () => {
let split = id.split("-")
return (
split[0] === idTraits.firstWord
)
}
let idres = checkID()
if(!idres) {
return false
}
let checkFields = () => {
for(let i = 0; i < fields.length; i++) {
if(!node[fields[i]]) {
throw new Error(`Token ${node.email} is missing trait ${fields[i]}`)
return false
} else {
return true
}
}
}
let fieldres = checkFields()
if(!fieldres) {
return false
}
return true
}
}