summary refs log tree commit diff
path: root/src/db
diff options
context:
space:
mode:
Diffstat (limited to 'src/db')
-rw-r--r--src/db/db.js7
-rw-r--r--src/db/dbAccess/user.js83
-rw-r--r--src/db/schemas/user.js22
3 files changed, 91 insertions, 21 deletions
diff --git a/src/db/db.js b/src/db/db.js

index b9a425c..2035731 100644 --- a/src/db/db.js +++ b/src/db/db.js
@@ -1,11 +1,14 @@ -import { connect } from 'mongoose'; +import mongoose, { connect } from 'mongoose'; import { readSecret } from '#util/secretUtils.js'; export async function initDb() { const connectionString = await readSecret( - "MongoDB connection string", + 'MongoDB connection string', process.env['DATABASE_SECRET_PATH'] ); + + if (process.env['LOG_QUERIES']) mongoose.set('debug', true); + try { const res = await connect(connectionString); if (res.connection.readyState === 1) { diff --git a/src/db/dbAccess/user.js b/src/db/dbAccess/user.js
index 6301cb5..a461f3e 100644 --- a/src/db/dbAccess/user.js +++ b/src/db/dbAccess/user.js
@@ -1,16 +1,53 @@ -import { hash, compare } from 'bcrypt'; -import { DbUser } from '#db/schemas/index.js'; -import { RegisterDto } from '#dto/auth/index.js'; +import { hash, compare, genSalt } from 'bcrypt'; +import { DbUser, deviceSchema } from '#db/schemas/index.js'; +import { AuthDto, RegisterDto } from '#dto/index.js'; +import { SafeNSoundError } from '#util/error.js'; +import { WhoAmIDto } from '#dto/auth/WhoAmIDto.js'; + +async function whoAmI(token) {} + +async function getUserByAuth(data) { + if (!(data instanceof AuthDto)) + throw new Error('Invalid data type. Expected AuthDto.'); + + let user; + + if (data.email) { + user = await DbUser.findOne({ email: data.email }); + } else if (data.username) { + user = await DbUser.findOne({ username: data.username }); + } + + console.log('user', user); + if (!user) { + // Sneaky: prevent user enumeration + throw new SafeNSoundError({ + errCode: 'INVALID_AUTH', + message: 'Invalid username or password.' + }); + } + + const isPasswordValid = await compare(data.password, user.passwordHash); + if (!isPasswordValid) { + throw new SafeNSoundError({ + errCode: 'INVALID_AUTH', + message: 'Invalid username or password.' + }); + } + + return user; +} /** * @param data {RegisterDto} - * @returns {Promise<(Error | HydratedDocument<InferSchemaType<module:mongoose.Schema>, ObtainSchemaGeneric<module:mongoose.Schema, "TVirtuals"> & ObtainSchemaGeneric<module:mongoose.Schema, "TInstanceMethods">, ObtainSchemaGeneric<module:mongoose.Schema, "TQueryHelpers">, ObtainSchemaGeneric<module:mongoose.Schema, "TVirtuals">>)[]>} + * @returns {Promise<DbUser>} */ export async function registerUser(data) { if (!(data instanceof RegisterDto)) throw new Error('Invalid data type. Expected RegisterDto.'); - const passwordHash = await hash(data.password, 10); + const salt = await genSalt(12); + const passwordHash = await hash(data.password, salt); if (!passwordHash) { throw new Error('Failed to hash password.'); } @@ -23,21 +60,29 @@ export async function registerUser(data) { }); } -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.'); - } +export async function deleteUser(data) { + var user = await getUserByAuth(data); + + await DbUser.findByIdAndDelete(data._id); +} + +/** + * @param data {AuthDto} + * @param deviceName {string} + * @returns {Promise<WhoAmIDto>} + */ +export async function loginUser(data, deviceName) { + const user = await getUserByAuth(data); + const device = await user.devices.create({ + name: deviceName }); - if (!user) { - throw new Error('User not found.'); - } - const isPasswordValid = await compare(password, user.passwordHash); - if (!isPasswordValid) { - throw new Error('Invalid password.'); - } + user.devices.push(device); + await user.save(); - await DbUser.findByIdAndDelete(id); + return WhoAmIDto.create({ + userId: user._id, + username: user.username, + deviceId: device._id + }); } diff --git a/src/db/schemas/user.js b/src/db/schemas/user.js
index 9d08680..f490966 100644 --- a/src/db/schemas/user.js +++ b/src/db/schemas/user.js
@@ -1,6 +1,24 @@ import { model, Schema } from 'mongoose'; import { hash, compare } from 'bcrypt'; +export const deviceSchema = new Schema({ + name: { + type: String, + required: true, + trim: true + }, + createdAt: { + type: Date, + default: Date.now, + immutable: true + }, + lastSeen: { + type: Date, + default: Date.now, + required: true + } +}); + /** * User schema for MongoDB. * @type {module:mongoose.Schema} @@ -31,6 +49,10 @@ export const userSchema = new Schema({ type: Date, default: Date.now, immutable: true + }, + devices: { + type: [deviceSchema], + default: [] } });