diff --git a/src/db/dbAccess/index.js b/src/db/dbAccess/index.js
new file mode 100644
index 0000000..ee1c337
--- /dev/null
+++ b/src/db/dbAccess/index.js
@@ -0,0 +1 @@
+export * from './user.js';
diff --git a/src/db/dbAccess/user.js b/src/db/dbAccess/user.js
new file mode 100644
index 0000000..413b1cf
--- /dev/null
+++ b/src/db/dbAccess/user.js
@@ -0,0 +1,41 @@
+import { hash, compare } from 'bcrypt';
+import { DbUser } from '#db/schemas/index.js';
+
+export async function registerUser(username, password, email, type = 'user') {
+ if (!username || !password || !email) {
+ throw new Error(
+ 'Username, password, and email are required to register a user.'
+ );
+ }
+
+ const passwordHash = await hash(password, 10);
+ if (!passwordHash) {
+ throw new Error('Failed to hash password.');
+ }
+
+ return DbUser.create({
+ username,
+ passwordHash,
+ email,
+ type
+ });
+}
+
+export async function deleteUser(id, password) {
+ const user = await DbUser.findById(id);
+ DbUser.exists({ _id: id }).then(exists => {
+ if (!exists) {
+ throw new Error('User does not exist.');
+ }
+ });
+ if (!user) {
+ throw new Error('User not found.');
+ }
+
+ const isPasswordValid = await compare(password, user.passwordHash);
+ if (!isPasswordValid) {
+ throw new Error('Invalid password.');
+ }
+
+ await DbUser.findByIdAndDelete(id);
+}
diff --git a/src/db/dbAccess/user.test.js b/src/db/dbAccess/user.test.js
new file mode 100644
index 0000000..e8e1af5
--- /dev/null
+++ b/src/db/dbAccess/user.test.js
@@ -0,0 +1,44 @@
+import * as dotenv from 'dotenv';
+import { it } from 'node:test';
+import { deleteUser, registerUser } from '#db/index.js';
+import * as assert from 'node:assert';
+import { initDb } from '#db/db.js';
+import { disconnect } from 'mongoose';
+
+dotenv.config();
+
+await initDb();
+
+async function createTestUser() {
+ const username = (Math.random() * 1000000).toString();
+ const password = (Math.random() * 1000000).toString();
+ const email = (Math.random() * 1000000).toString() + '@example.com';
+ return {
+ username,
+ password,
+ email,
+ user: await registerUser(username, password, email)
+ };
+}
+
+await it('Can create user', async () => {
+ await assert.doesNotReject(createTestUser());
+});
+
+await it('Can delete user', async () => {
+ const { username, password, email, user } = await createTestUser();
+
+ const deletePromise = deleteUser(user._id, password);
+ await assert.doesNotReject(deletePromise);
+});
+
+await it('Cant delete nonexistant user', async () => {
+ await assert.rejects(deleteUser('abc', ''));
+});
+
+await it('Cant delete user with invalid password', async () => {
+ const user = await createTestUser();
+ await assert.rejects(deleteUser(user.user._id, 'wrongpassword'));
+});
+
+await disconnect();
diff --git a/src/db/index.js b/src/db/index.js
index cd306b7..0680880 100644
--- a/src/db/index.js
+++ b/src/db/index.js
@@ -1,2 +1,3 @@
export * from './db.js';
export * from './schemas/index.js';
+export * from './dbAccess/index.js';
diff --git a/src/db/schemas/user.js b/src/db/schemas/user.js
index 1a7e048..9d08680 100644
--- a/src/db/schemas/user.js
+++ b/src/db/schemas/user.js
@@ -1,4 +1,5 @@
import { model, Schema } from 'mongoose';
+import { hash, compare } from 'bcrypt';
/**
* User schema for MongoDB.
|