Rowblox-V2/src/lib/database.js

82 lines
2.0 KiB
JavaScript

import { MongoClient } from "mongodb";
import { hash, compare } from "bcrypt";
import { prerendering } from "$app/environment";
import { randomBytes, randomUUID } from "crypto";
import { INVITE_KEY_PREFIX, SESSION_EXPIRE } from "$lib/constants";
if (!process.env.MONGO_URL) throw new Error("Missing MONGO_URL env variable!");
const client = new MongoClient(process.env.MONGO_URL);
if (!prerendering) await client.connect();
const db = await client.db("rowblox");
const users = await db.collection("users");
const games = await db.collection("games");
const assets = await db.collection("assets");
const invites = await db.collection("invites");
const avatars = await db.collection("avatars");
const sessions = await db.collection("sessions");
async function inc(collection) {
await collection.updateOne({ _id: "_inc" }, { $inc: { _inc: 1 } });
return (await collection.findOne({ _id: "_inc" }))._inc;
}
async function hashPassword(plaintext) {
return new Promise((resolve, reject) => {
hash(plaintext, 10, (err, hash) => resolve(hash));
});
}
async function compareHash(plaintext, hash) {
return new Promise((resolve, reject) => {
compare(plaintext, hash, (err, result) => resolve(result));
});
}
async function genSession() {
return randomBytes(64).toString("base64");
}
async function genInvite() {
return `${INVITE_KEY_PREFIX}${randomUUID()}`;
}
export async function createUser(username, password, lastip) {
const _id = await inc(users);
const user = {
_id,
username,
password: await hashPassword(password),
lastip
};
const avatar = {
_id,
BodyColors: {
HeadColor: 1,
TorsoColor: 1,
LeftArmColor: 1,
RightArmColor: 1,
LeftLegColor: 1,
RightLegColor: 1
},
Assets: {}
};
await avatars.insertOne(avatar);
return await users.insertOne(user);
}
export async function createSession(_id, lastip) {
const user = await users.findOne({ _id });
if (!user) throw new Error("That user doesn't exist");
return await sessions.insertOne({
_id,
session: genSession(),
expires: Date.now() + SESSION_EXPIRE
});
}