aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar piotrruss <mail@pruss.it> 2021-09-09 23:23:53 +0200
committerGravatar piotrruss <mail@pruss.it> 2021-09-09 23:23:53 +0200
commita863c77ea12a4c7060b9c496e5df81bbdcca2374 (patch)
tree8d38ebc21928fa973235d8829bf1c6f7d65028df
parent569bdb8c5d7538fa0ea8a99ff2f8376f7cbfa51a (diff)
downloadmy_apps-a863c77ea12a4c7060b9c496e5df81bbdcca2374.tar.gz
my_apps-a863c77ea12a4c7060b9c496e5df81bbdcca2374.tar.bz2
my_apps-a863c77ea12a4c7060b9c496e5df81bbdcca2374.zip
add db transactions, move db models
-rw-r--r--apps/Notes/models/Note.js (renamed from models/Note.js)14
-rw-r--r--apps/Notes/models/NoteList.js (renamed from models/NoteList.js)36
-rw-r--r--models/User.js55
-rw-r--r--pages/api/notes/[id].js29
-rw-r--r--pages/api/notes/index.js16
-rw-r--r--pages/api/register.js26
6 files changed, 96 insertions, 80 deletions
diff --git a/models/Note.js b/apps/Notes/models/Note.js
index d19eae8..0f4b3f9 100644
--- a/models/Note.js
+++ b/apps/Notes/models/Note.js
@@ -1,8 +1,8 @@
-const {encrypt, decrypt} = require('helpers/crypt')
+const { encrypt, decrypt } = require('helpers/crypt')
const mongoose = require('mongoose')
const noteSchema = new mongoose.Schema({
- content: {type: String, required: true, minlength: 1},
+ content: { type: String, required: true, minlength: 1 }
})
noteSchema.statics.getNote = async (id) => {
@@ -11,19 +11,19 @@ noteSchema.statics.getNote = async (id) => {
const content = decrypt(note.content)
- return {...note, content}
+ return { ...note, content }
}
noteSchema.statics.updateNote = async (id, content) => {
- const note = await Note.findByIdAndUpdate(id, {content: encrypt(content)}, {new: true})
+ const note = await Note.findByIdAndUpdate(id, { content: encrypt(content) }, { new: true })
if (!note) throw new Error('Could not update note')
- return {...note, content}
+ return { ...note, content }
}
-noteSchema.pre('save', async function(next){
- const note = this;
+noteSchema.pre('save', async function (next) {
+ const note = this
if (note.isModified('content')) {
note.content = encrypt(note.content)
diff --git a/models/NoteList.js b/apps/Notes/models/NoteList.js
index bf7b155..0af648a 100644
--- a/models/NoteList.js
+++ b/apps/Notes/models/NoteList.js
@@ -1,29 +1,29 @@
-const {encrypt, decrypt} = require('helpers/crypt')
-const mongoose = require("mongoose")
+const { encrypt, decrypt } = require('helpers/crypt')
+const mongoose = require('mongoose')
-const decryptTitles = l => ({notes: l.notes.map(n => ({ ...n, title: decrypt(n.title)}))})
+const decryptTitles = l => ({ notes: l.notes.map(n => ({ ...n, title: decrypt(n.title) })) })
const noteListSchema = new mongoose.Schema({
notes: [{
title: {
type: String,
maxlength: 1000,
- required: true,
+ required: true
},
noteId: {
type: mongoose.Schema.Types.ObjectId,
- ref: "Note",
- required: true,
+ ref: 'Note',
+ required: true
},
- created_at: {type: Date, default: Date.now},
- updated_at: {type: Date, default: Date.now}
+ created_at: { type: Date, default: Date.now },
+ updated_at: { type: Date, default: Date.now }
}]
})
noteListSchema.statics.getList = async (id) => {
const newList = await NoteList.findById(id).lean()
- return {notes: newList.notes.map(n => ({ ...n, title: decrypt(n.title)}))}
+ return { notes: newList.notes.map(n => ({ ...n, title: decrypt(n.title) })) }
}
noteListSchema.statics.getNoteId = async (_id, id) => {
@@ -34,7 +34,7 @@ noteListSchema.statics.getNoteId = async (_id, id) => {
noteListSchema.statics.addNote = async (_id, noteId, title) => {
const noteList = await NoteList.findOneAndUpdate(
- {_id}, {$push: {notes: {title: encrypt(title ? title : 'no title'), noteId}}}, {new: true}
+ { _id }, { $push: { notes: { title: encrypt(title || 'no title'), noteId } } }, { new: true }
).lean()
return decryptTitles(noteList)
@@ -42,7 +42,7 @@ noteListSchema.statics.addNote = async (_id, noteId, title) => {
noteListSchema.statics.removeNote = async (_id, id) => {
const noteList = await NoteList.findOneAndUpdate(
- {_id}, {$pull: {notes: {_id: id}}}
+ { _id }, { $pull: { notes: { _id: id } } }
).lean()
return decryptTitles(noteList)
@@ -50,12 +50,14 @@ noteListSchema.statics.removeNote = async (_id, id) => {
noteListSchema.statics.updateList = async (_id, noteId, title) => {
const noteList = await NoteList.findOneAndUpdate(
- {_id, "notes.noteId": noteId},
- {$set: {
- "notes.$.title": encrypt(title ? title : 'No title'),
- "notes.$.updated_at": Date.now(),
- }},
- {new: true}
+ { _id, 'notes.noteId': noteId },
+ {
+ $set: {
+ 'notes.$.title': encrypt(title || 'No title'),
+ 'notes.$.updated_at': Date.now()
+ }
+ },
+ { new: true }
).lean()
return decryptTitles(noteList)
diff --git a/models/User.js b/models/User.js
index 44d9619..bcf2523 100644
--- a/models/User.js
+++ b/models/User.js
@@ -1,6 +1,6 @@
-const mongoose = require("mongoose")
+const mongoose = require('mongoose')
const bcrypt = require('bcryptjs')
-const {nanoid} = require('nanoid')
+const { nanoid } = require('nanoid')
const userResponse = u => ({
_id: u._id,
@@ -20,7 +20,7 @@ const userSchema = new mongoose.Schema({
required: true,
minlength: 6,
maxlength: 255,
- validate(value) {
+ validate (value) {
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
throw new Error('Wrong email address')
}
@@ -30,29 +30,29 @@ const userSchema = new mongoose.Schema({
type: String,
required: true,
minlength: 6,
- maxlength: 1024,
+ maxlength: 1024
},
isVerified: {
type: Boolean,
- default: false,
+ default: false
},
verificationKey: {
type: String,
- default: () => nanoid(6),
+ default: () => nanoid(6)
},
noteList: {
type: mongoose.Schema.Types.ObjectId,
- ref: "NoteList",
- required: true,
+ ref: 'NoteList',
+ required: true
},
- theme: {type: String, default: () => 'green'},
- language: {type: String, default: () => 'en'},
- created_at: {type: Date, default: Date.now},
- updated_at: {type: Date, default: Date.now}
+ theme: { type: String, default: () => 'green' },
+ language: { type: String, default: () => 'en' },
+ created_at: { type: Date, default: Date.now },
+ updated_at: { type: Date, default: Date.now }
})
-userSchema.statics.findByCredentials = async function (email, password){
- const user = await User.findOne({email})
+userSchema.statics.findByCredentials = async function (email, password) {
+ const user = await User.findOne({ email })
if (!user) {
throw new Error('Unable to login')
@@ -67,8 +67,8 @@ userSchema.statics.findByCredentials = async function (email, password){
return userResponse(user)
}
-userSchema.statics.getVerificationKey = async function (email){
- const {verificationKey: key} = await User.findOne({email})
+userSchema.statics.getVerificationKey = async function (email) {
+ const { verificationKey: key } = await User.findOne({ email })
if (!key) {
throw new Error('Could not verify user')
@@ -77,8 +77,8 @@ userSchema.statics.getVerificationKey = async function (email){
return key
}
-userSchema.statics.verifyUser = async function (_id, key){
- const user = await User.findOneAndUpdate({_id, verificationKey: key}, {isVerified: true, verificationKey: nanoid(10)}, {new: true})
+userSchema.statics.verifyUser = async function (_id, key) {
+ const user = await User.findOneAndUpdate({ _id, verificationKey: key }, { isVerified: true, verificationKey: nanoid(10) }, { new: true })
if (!user) {
throw new Error('Could not verify user')
@@ -87,8 +87,8 @@ userSchema.statics.verifyUser = async function (_id, key){
return userResponse(user)
}
-userSchema.statics.saveSettings = async function ({_id, theme, language}){
- const user = await User.findOneAndUpdate({_id}, {theme, language}, {new: true})
+userSchema.statics.saveSettings = async function ({ _id, theme, language }) {
+ const user = await User.findOneAndUpdate({ _id }, { theme, language }, { new: true })
if (!user) {
throw new Error('Could not save settings')
@@ -97,24 +97,23 @@ userSchema.statics.saveSettings = async function ({_id, theme, language}){
return userResponse(user)
}
-userSchema.statics.state = async function (_id){
- const user = await User.findOne({_id})
+userSchema.statics.state = async function (_id) {
+ const user = await User.findOne({ _id })
if (!user) {
- return {isLoggedIn: false}
+ return { isLoggedIn: false }
} else if (!user.isVerified) {
- return {isVerified: false}
+ return { isVerified: false }
}
return {}
}
-
-userSchema.pre('save', async function(next){
- const user = this;
+userSchema.pre('save', async function (next) {
+ const user = this
if (user.isModified('password')) {
- user.password = await bcrypt.hash(user.password, 8);
+ user.password = await bcrypt.hash(user.password, 8)
}
user.updated_at = Date.now()
diff --git a/pages/api/notes/[id].js b/pages/api/notes/[id].js
index 12f0ba4..a2cd680 100644
--- a/pages/api/notes/[id].js
+++ b/pages/api/notes/[id].js
@@ -1,11 +1,11 @@
import dbConnect from 'configs/dbConnect'
import withSession from 'hocs/withSession'
-import NoteList from 'models/NoteList'
-import Note from 'models/Note'
+import NoteList from 'apps/Notes/models/NoteList'
+import Note from 'apps/Notes/models/Note'
export default withSession(async (req, res) => {
+ const conn = await dbConnect()
const { id: _id } = req.query
- await dbConnect()
switch (req.method) {
case 'GET':
@@ -24,12 +24,12 @@ export default withSession(async (req, res) => {
res.status(200).json(note)
} catch (error) {
- console.log(error)
res.status(400).json({ error: true })
}
break
case 'DELETE':
try {
+ const session = await conn.startSession()
const user = req.session.get('user')
if (!user || !user?.isVerified || !_id) {
@@ -39,17 +39,20 @@ export default withSession(async (req, res) => {
const noteId = await NoteList.getNoteId(user.noteList, _id)
if (!noteId) throw new Error('Something went wrong')
- await Note.findByIdAndDelete(noteId)
- const { notes } = await NoteList.removeNote(user.noteList, _id)
+ await session.withTransaction(async () => {
+ await Note.findByIdAndDelete(noteId)
+ const { notes } = await NoteList.removeNote(user.noteList, _id)
- res.status(200).json(notes)
+ session.endSession()
+ res.status(200).json(notes)
+ })
} catch (error) {
- console.log(error)
res.status(400).json([])
}
break
case 'PUT':
try {
+ const session = await conn.startSession()
const user = req.session.get('user')
const { title, noteId, content } = req.body
@@ -57,12 +60,14 @@ export default withSession(async (req, res) => {
throw new Error('Something went wrong')
}
- await Note.updateNote(noteId, content)
- const { notes } = await NoteList.updateList(user.noteList, noteId, title)
+ await session.withTransaction(async () => {
+ await Note.updateNote(noteId, content)
+ const { notes } = await NoteList.updateList(user.noteList, noteId, title)
- res.status(200).json(notes)
+ session.endSession()
+ res.status(200).json(notes)
+ })
} catch (error) {
- console.log(error)
res.status(400).json([])
}
break
diff --git a/pages/api/notes/index.js b/pages/api/notes/index.js
index 16cb88c..86369ed 100644
--- a/pages/api/notes/index.js
+++ b/pages/api/notes/index.js
@@ -1,10 +1,10 @@
import dbConnect from 'configs/dbConnect'
import withSession from 'hocs/withSession'
-import NoteList from 'models/NoteList'
-import Note from 'models/Note'
+import NoteList from 'apps/Notes/models/NoteList'
+import Note from 'apps/Notes/models/Note'
export default withSession(async (req, res) => {
- await dbConnect()
+ const conn = await dbConnect()
switch (req.method) {
case 'GET':
@@ -24,6 +24,7 @@ export default withSession(async (req, res) => {
break
case 'POST':
try {
+ const session = await conn.startSession()
const user = req.session.get('user')
const { title, content } = req.body
@@ -31,10 +32,13 @@ export default withSession(async (req, res) => {
throw new Error('Something went wrong')
}
- const note = await Note.create({ content })
- const { notes } = await NoteList.addNote(user.noteList, note._id, title)
+ await session.withTransaction(async () => {
+ const note = await Note.create({ content })
+ const { notes } = await NoteList.addNote(user.noteList, note._id, title)
- res.status(200).json(notes)
+ session.endSession()
+ res.status(200).json(notes)
+ })
} catch (error) {
res.status(400).json([])
}
diff --git a/pages/api/register.js b/pages/api/register.js
index 036cede..ba72e53 100644
--- a/pages/api/register.js
+++ b/pages/api/register.js
@@ -3,25 +3,31 @@ import sendMail from 'configs/sendMail'
import withSession from 'hocs/withSession'
import { subject, text, html } from 'helpers/email'
import User from 'models/User'
-import NoteList from 'models/NoteList'
+import NoteList from 'apps/Notes/models/NoteList'
export default withSession(async (req, res) => {
- await dbConnect()
+ const conn = await dbConnect()
switch (req.method) {
case 'POST':
try {
- const noteList = await NoteList.create({})
+ const session = await conn.startSession()
- const { _id, email, verificationKey: key, theme, language } = await User.create({ ...req.body, noteList })
- if (!email) { throw new Error('Something went wrong') }
+ await session.withTransaction(async () => {
+ const noteList = await NoteList.create({})
+ const { _id, email, verificationKey: key, theme, language } = await User.create({ ...req.body, noteList })
- sendMail(req.body.email, subject(language), text(language, key), html(language, key))
+ if (!email) { throw new Error('Something went wrong') }
- const user = { _id, email, noteList, theme, language, isVerified: false, isLoggedIn: true }
- req.session.set('user', user)
- await req.session.save()
- res.status(201).json(user)
+ sendMail(req.body.email, subject(language), text(language, key), html(language, key))
+
+ const user = { _id, email, noteList, theme, language, isVerified: false, isLoggedIn: true }
+ req.session.set('user', user)
+ await req.session.save()
+
+ session.endSession()
+ res.status(201).json(user)
+ })
} catch (error) {
res.status(400).json({ isLoggedIn: false })
}