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 }); }