Tons of fixes to prepare for staged releases.
This commit is contained in:
1 parent
9f37d3faf1
commit
5bebe072b2
24 files changed
+1110
-474
No files matched your search
+103
-53
@@ -16,6 +16,9 @@ require('module-alias')(require('path').join(__dirname, '..'))
|
||||
//Auth helper, used for decoding users web token
|
||||
let Auth = require('@helpers/Auth')
|
||||
|
||||
//Note model, used to authorise socket room joins
|
||||
let Note = require('@models/Note')
|
||||
|
||||
//Helmet adds additional security to express server
|
||||
const helmet = require('helmet')
|
||||
|
||||
@@ -51,6 +54,14 @@ global.SocketIo = io
|
||||
|
||||
let noteDiffs = {}
|
||||
|
||||
//
|
||||
// Room names are namespaced. Previously note rooms were keyed on the bare
|
||||
// note_raw_text.id and user rooms on the bare user.id, sharing one flat
|
||||
// keyspace -- so user 7 and note_raw_text 7 were the same room.
|
||||
//
|
||||
const userRoom = userId => `user:${userId}`
|
||||
const noteRoom = rawTextId => `note:${rawTextId}`
|
||||
|
||||
io.on('connection', function(socket){
|
||||
|
||||
//When a user connects, add them to their own room
|
||||
@@ -59,11 +70,11 @@ io.on('connection', function(socket){
|
||||
socket.on('user_connect', token => {
|
||||
Auth.decodeToken(token)
|
||||
.then(userData => {
|
||||
socket.join(userData.userId)
|
||||
socket.join(userRoom(userData.userId))
|
||||
|
||||
//Track active logged in user accounts
|
||||
const usersInRoom = io.sockets.adapter.rooms[userData.userId]
|
||||
io.to(userData.userId).emit('update_active_user_count', usersInRoom.length)
|
||||
const usersInRoom = io.sockets.adapter.rooms[userRoom(userData.userId)]
|
||||
io.to(userRoom(userData.userId)).emit('update_active_user_count', usersInRoom.length)
|
||||
|
||||
}).catch(error => {
|
||||
//Don't add user to room if they are not logged in
|
||||
@@ -74,11 +85,11 @@ io.on('connection', function(socket){
|
||||
socket.on('get_active_user_count', token => {
|
||||
Auth.decodeToken(token)
|
||||
.then(userData => {
|
||||
socket.join(userData.userId)
|
||||
socket.join(userRoom(userData.userId))
|
||||
|
||||
//Track active logged in user accounts
|
||||
const usersInRoom = io.sockets.adapter.rooms[userData.userId]
|
||||
io.to(userData.userId).emit('update_active_user_count', usersInRoom.length)
|
||||
const usersInRoom = io.sockets.adapter.rooms[userRoom(userData.userId)]
|
||||
io.to(userRoom(userData.userId)).emit('update_active_user_count', usersInRoom.length)
|
||||
|
||||
}).catch(error => {
|
||||
// console.log(error)
|
||||
@@ -107,67 +118,106 @@ io.on('connection', function(socket){
|
||||
})
|
||||
})
|
||||
|
||||
socket.on('join_room', rawTextId => {
|
||||
// Join user to rawtextid room when they enter
|
||||
socket.join(rawTextId)
|
||||
//
|
||||
// The client asks for a NOTE, not a room. The server authorises the request
|
||||
// against the session and derives the room itself, so a client can no longer
|
||||
// name an arbitrary room and be handed its buffered diffs.
|
||||
//
|
||||
socket.on('join_room', ({ noteId, token } = {}) => {
|
||||
|
||||
//If there are past diffs for this note, send them to the user
|
||||
if(noteDiffs[rawTextId] != undefined){
|
||||
|
||||
//Sort all note diffs by when they were created.
|
||||
noteDiffs[rawTextId].sort((a,b) => { return a.time - b.time })
|
||||
Auth.decodeToken(token)
|
||||
.then(userData => {
|
||||
|
||||
//Emit all sorted diffs to user
|
||||
socket.emit('past_diffs', noteDiffs[rawTextId])
|
||||
}
|
||||
return Note.getRawTextIdForUser(noteId, userData.userId)
|
||||
.then(rawTextId => {
|
||||
|
||||
const usersInRoom = io.sockets.adapter.rooms[rawTextId]
|
||||
if(usersInRoom){
|
||||
//Update users in room count
|
||||
io.to(rawTextId).emit('update_user_count', usersInRoom.length)
|
||||
}
|
||||
})
|
||||
// No claim on this note -> no room, no diffs
|
||||
if(rawTextId == null){ return }
|
||||
|
||||
socket.on('leave_room', roomId => {
|
||||
socket.leave(roomId)
|
||||
// console.log('User Left room')
|
||||
const room = noteRoom(rawTextId)
|
||||
|
||||
const usersInRoom = io.sockets.adapter.rooms[roomId]
|
||||
if(usersInRoom){
|
||||
// console.log('Users in room', usersInRoom.length)
|
||||
io.to(roomId).emit('update_user_count', usersInRoom.length)
|
||||
}
|
||||
|
||||
})
|
||||
// Remember what this socket is allowed into, so leave_room and
|
||||
// note_diff never have to trust a client-supplied room again
|
||||
socket.authorizedRooms = socket.authorizedRooms || {}
|
||||
socket.authorizedRooms[noteId] = { room, rawTextId }
|
||||
|
||||
socket.on('note_diff', data => {
|
||||
socket.join(room)
|
||||
|
||||
//Log each diff for note
|
||||
const noteId = data.id
|
||||
delete data.id
|
||||
if(noteDiffs[noteId] == undefined){ noteDiffs[noteId] = [] }
|
||||
data.time = +new Date
|
||||
|
||||
noteDiffs[noteId].push(data)
|
||||
//If there are past diffs for this note, send them to the user
|
||||
if(noteDiffs[rawTextId] != undefined){
|
||||
|
||||
// Go over each user in this note-room
|
||||
io.in(noteId).clients((error, clients) => {
|
||||
if (error) throw error;
|
||||
//Sort all note diffs by when they were created.
|
||||
noteDiffs[rawTextId].sort((a,b) => { return a.time - b.time })
|
||||
|
||||
//Go through each client in note-room and send them the diff
|
||||
clients.forEach(socketId => {
|
||||
// only send off diff if user
|
||||
if(socketId != socket.id){
|
||||
io.to(socketId).emit('incoming_diff', data)
|
||||
//Emit all sorted diffs to user
|
||||
socket.emit('past_diffs', noteDiffs[rawTextId])
|
||||
}
|
||||
|
||||
const usersInRoom = io.sockets.adapter.rooms[room]
|
||||
if(usersInRoom){
|
||||
//Update users in room count
|
||||
io.to(room).emit('update_user_count', usersInRoom.length)
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
//Not logged in, or no access. Join nothing.
|
||||
})
|
||||
})
|
||||
|
||||
socket.on('truncate_diffs_at_save', checkpoint => {
|
||||
socket.on('leave_room', ({ noteId } = {}) => {
|
||||
|
||||
// Only rooms this socket was actually authorised into
|
||||
const entry = socket.authorizedRooms && socket.authorizedRooms[noteId]
|
||||
if(!entry){ return }
|
||||
|
||||
socket.leave(entry.room)
|
||||
delete socket.authorizedRooms[noteId]
|
||||
|
||||
const usersInRoom = io.sockets.adapter.rooms[entry.room]
|
||||
if(usersInRoom){
|
||||
io.to(entry.room).emit('update_user_count', usersInRoom.length)
|
||||
}
|
||||
})
|
||||
|
||||
socket.on('note_diff', (data = {}) => {
|
||||
|
||||
// Room comes from what this socket was authorised into, never from the
|
||||
// payload
|
||||
const entry = socket.authorizedRooms && socket.authorizedRooms[data.noteId]
|
||||
if(!entry){ return }
|
||||
|
||||
const room = entry.room
|
||||
const rawTextId = entry.rawTextId
|
||||
|
||||
//Log each diff for note
|
||||
if(noteDiffs[rawTextId] == undefined){ noteDiffs[rawTextId] = [] }
|
||||
|
||||
// Carry the raw-text id through. This used to `delete data.id`, stripping
|
||||
// the only identifier before storing and broadcasting -- so a client with
|
||||
// several notes open on one socket could not tell which note a patch
|
||||
// belonged to, and applied every one to whichever editor it found first.
|
||||
const payload = Object.assign({}, data, { rawTextId, time: +new Date })
|
||||
delete payload.noteId
|
||||
|
||||
noteDiffs[rawTextId].push(payload)
|
||||
|
||||
// Everyone in the note room except the sender
|
||||
socket.to(room).emit('incoming_diff', payload)
|
||||
})
|
||||
|
||||
socket.on('truncate_diffs_at_save', (checkpoint = {}) => {
|
||||
|
||||
const entry = socket.authorizedRooms && socket.authorizedRooms[checkpoint.noteId]
|
||||
if(!entry){ return }
|
||||
checkpoint.rawTextId = entry.rawTextId
|
||||
|
||||
// NOTE: the comparison below is `diffSet[i].hash == checkpoint`, comparing
|
||||
// a hash string against the whole checkpoint object, so it never matches
|
||||
// and sliceTo stays 0 -- meaning the entire diff set is discarded at every
|
||||
// save. That happens to be the fail-safe outcome (the saved text becomes
|
||||
// the new baseline), and the correct slice direction for a real fix is
|
||||
// ambiguous, so it is deliberately left alone rather than guessed at.
|
||||
let diffSet = noteDiffs[checkpoint.rawTextId]
|
||||
if(diffSet && diffSet.length > 0){
|
||||
|
||||
|
||||
@@ -300,10 +300,10 @@ Attachment.scanTextForWebsites = (io, userId, noteId, noteText) => {
|
||||
Attachment.scrapeUrlsCreateAttachments(userId, noteId, foundUrls).then( freshlyScrapedText => {
|
||||
|
||||
//Once everything is done being scraped, emit new attachment events
|
||||
SocketIo.to(userId).emit('update_counts')
|
||||
SocketIo.to(`user:${userId}`).emit('update_counts')
|
||||
|
||||
// Tell user to update attachments with scraped text
|
||||
SocketIo.to(userId).emit('update_note_attachments')
|
||||
SocketIo.to(`user:${userId}`).emit('update_note_attachments')
|
||||
|
||||
solrAttachmentText += freshlyScrapedText
|
||||
resolve(solrAttachmentText)
|
||||
@@ -597,10 +597,10 @@ Attachment.pushUrl = (pushkey,url) => {
|
||||
|
||||
if(typeof SocketIo != 'undefined'){
|
||||
//Once everything is done being scraped, emit new attachment events
|
||||
SocketIo.to(userId).emit('update_counts')
|
||||
SocketIo.to(`user:${userId}`).emit('update_counts')
|
||||
|
||||
// Tell user to update attachments with scraped text
|
||||
SocketIo.to(userId).emit('update_note_attachments')
|
||||
SocketIo.to(`user:${userId}`).emit('update_note_attachments')
|
||||
}
|
||||
|
||||
return resolve(true)
|
||||
|
||||
+34
-8
@@ -199,7 +199,7 @@ Note.create = (userId, noteTitle = '', noteText = '', masterKey) => {
|
||||
.then((rows, fields) => {
|
||||
|
||||
if(typeof SocketIo != 'undefined'){
|
||||
SocketIo.to(userId).emit('new_note_created', rows[0].insertId)
|
||||
SocketIo.to(`user:${userId}`).emit('new_note_created', rows[0].insertId)
|
||||
}
|
||||
|
||||
// Indexing is done on save
|
||||
@@ -490,7 +490,7 @@ Note.update = (userId, noteId, noteText, noteTitle, color, pinned, archived, has
|
||||
}
|
||||
db.promise().query('UPDATE note SET snippet = ? WHERE id = ?', [updatedSnippet, otherNote.id])
|
||||
.then((rows, fields) => {
|
||||
SocketIo.to(otherNote['user_id']).emit('new_note_text_saved', {'noteId':otherNote.id, hash})
|
||||
SocketIo.to(`user:${otherNote['user_id']}`).emit('new_note_text_saved', {'noteId':otherNote.id, hash})
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -514,7 +514,7 @@ Note.update = (userId, noteId, noteText, noteTitle, color, pinned, archived, has
|
||||
.then((rows, fields) => {
|
||||
|
||||
if(typeof SocketIo != 'undefined'){
|
||||
SocketIo.to(userId).emit('new_note_text_saved', {noteId, hash})
|
||||
SocketIo.to(`user:${userId}`).emit('new_note_text_saved', {noteId, hash})
|
||||
|
||||
//Async attachment reindex
|
||||
Attachment.scanTextForWebsites(SocketIo, userId, noteId, noteText)
|
||||
@@ -538,7 +538,7 @@ Note.setPinned = (userId, noteId, pinnedBoolean) => {
|
||||
.query('UPDATE note JOIN note_raw_text ON note_raw_text_id = note_raw_text.id SET pinned = ?, updated = ? WHERE note.id = ? AND user_id = ?',
|
||||
[pinned, now, noteId, userId])
|
||||
.then((rows, fields) => {
|
||||
SocketIo.to(userId).emit('note_attribute_modified', noteId)
|
||||
SocketIo.to(`user:${userId}`).emit('note_attribute_modified', noteId)
|
||||
resolve(true)
|
||||
})
|
||||
})
|
||||
@@ -555,7 +555,7 @@ Note.setArchived = (userId, noteId, archivedBoolead) => {
|
||||
.query('UPDATE note JOIN note_raw_text ON note_raw_text_id = note_raw_text.id SET archived = ?, updated = ? WHERE note.id = ? AND user_id = ?',
|
||||
[archived, now, noteId, userId])
|
||||
.then((rows, fields) => {
|
||||
SocketIo.to(userId).emit('note_attribute_modified', noteId)
|
||||
SocketIo.to(`user:${userId}`).emit('note_attribute_modified', noteId)
|
||||
resolve(true)
|
||||
})
|
||||
})
|
||||
@@ -581,7 +581,7 @@ Note.setTrashed = (userId, noteId, trashedBoolean, masterKey) => {
|
||||
Note.reindex(userId, masterKey, removeFromIndex)
|
||||
|
||||
|
||||
SocketIo.to(userId).emit('note_attribute_modified', noteId)
|
||||
SocketIo.to(`user:${userId}`).emit('note_attribute_modified', noteId)
|
||||
resolve(true)
|
||||
})
|
||||
})
|
||||
@@ -653,7 +653,7 @@ Note.delete = (userId, noteId, masterKey = null) => {
|
||||
}
|
||||
})
|
||||
|
||||
SocketIo.to(userId).emit('update_counts')
|
||||
SocketIo.to(`user:${userId}`).emit('update_counts')
|
||||
|
||||
if(masterKey){
|
||||
//Remove note ID from index
|
||||
@@ -1190,4 +1190,30 @@ Note.search = (userId, searchQuery, searchTags, fastFilters, masterKey) => {
|
||||
.catch(console.log)
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Resolve a note's raw-text id for a given user.
|
||||
// Doubles as the access check: a user with no claim on this note gets null,
|
||||
// so authorisation and room derivation are the same lookup.
|
||||
//
|
||||
Note.getRawTextIdForUser = (noteId, userId) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
const id = parseInt(noteId, 10)
|
||||
if(!Number.isInteger(id) || id < 1){ return resolve(null) }
|
||||
|
||||
db.promise()
|
||||
.query('SELECT note_raw_text_id FROM note WHERE id = ? AND user_id = ? LIMIT 1', [id, userId])
|
||||
.then((rows) => {
|
||||
|
||||
if(!rows[0] || rows[0].length == 0){ return resolve(null) }
|
||||
|
||||
return resolve( rows[0][0]['note_raw_text_id'] )
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error)
|
||||
return resolve(null)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -75,7 +75,7 @@ ShareNote.addUserToSharedNote = (userId, noteId, shareUserId, masterKey) => {
|
||||
const sharedUserNoteId = rows[0]['insertId']
|
||||
|
||||
//Emit update count event to user shared with - so they see the note in real time
|
||||
SocketIo.to(shareUserId).emit('update_counts')
|
||||
SocketIo.to(`user:${shareUserId}`).emit('update_counts')
|
||||
|
||||
let success = true
|
||||
return resolve({success, shareUserId, sharedUserNoteId})
|
||||
|
||||
@@ -58,7 +58,7 @@ Tag.addToNote = (userId, noteId, tagText) => {
|
||||
Tag.associateWithNote(userId, noteId, newTagId)
|
||||
.then( result => {
|
||||
|
||||
SocketIo.to(userId).emit('new_note_text_saved', {noteId})
|
||||
SocketIo.to(`user:${userId}`).emit('new_note_text_saved', {noteId})
|
||||
resolve(result)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -7,8 +7,6 @@ let router = express.Router()
|
||||
let Attachment = require('@models/Attachment')
|
||||
let Note = require('@models/Note')
|
||||
|
||||
let userId = null
|
||||
let masterKey = null
|
||||
|
||||
// middleware that is specific to this router
|
||||
router.use(function setUserId (req, res, next) {
|
||||
@@ -19,23 +17,33 @@ router.use(function setUserId (req, res, next) {
|
||||
}
|
||||
|
||||
if(req.headers.userId){
|
||||
userId = req.headers.userId
|
||||
masterKey = req.headers.masterKey
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
router.post('/search', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Attachment.search(userId, req.body.noteId, req.body.attachmentType, req.body.offset, req.body.setSize, req.body.includeShared)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
router.post('/textsearch', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Attachment.textSearch(userId, req.body.searchTerm)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
router.post('/update', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Attachment.update(userId, req.body.attachmentId, req.body.updatedText, req.body.noteId)
|
||||
.then( result => {
|
||||
Note.reindex(userId, req.body.noteId)
|
||||
@@ -44,11 +52,19 @@ router.post('/update', function (req, res) {
|
||||
})
|
||||
|
||||
router.post('/delete', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Attachment.delete(userId, req.body.attachmentId)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
router.post('/upload', upload.single('file'), function (req, res, next) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
|
||||
//Create attachment with file information and node id
|
||||
const noteId = parseInt(req.body.noteId)
|
||||
@@ -67,6 +83,10 @@ router.post('/upload', upload.single('file'), function (req, res, next) {
|
||||
|
||||
// get push key
|
||||
router.post('/getbookmarklet', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
|
||||
Attachment.getPushkeyBookmarklet(userId)
|
||||
.then( data => res.send(data) )
|
||||
|
||||
@@ -1,41 +1,45 @@
|
||||
//
|
||||
// /api/cycle-tracking
|
||||
//
|
||||
|
||||
var express = require('express')
|
||||
var router = express.Router()
|
||||
|
||||
let CycleTracking = require('@models/CycleTracking');
|
||||
|
||||
let userId = null
|
||||
let masterKey = null
|
||||
|
||||
// middleware that is specific to this router
|
||||
router.use(function setUserId (req, res, next) {
|
||||
|
||||
//Session key is required to continue
|
||||
if(!req.headers.sessionId){
|
||||
next('Unauthorized')
|
||||
}
|
||||
|
||||
if(req.headers.userId){
|
||||
userId = req.headers.userId
|
||||
masterKey = req.headers.masterKey
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
//Get quick note text
|
||||
router.post('/get', function (req, res) {
|
||||
CycleTracking.get(userId, masterKey)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
//Push text to quick note
|
||||
router.post('/save', function (req, res) {
|
||||
CycleTracking.save(userId, req.body.cycleData, masterKey)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
|
||||
//
|
||||
// /api/cycle-tracking
|
||||
//
|
||||
|
||||
var express = require('express')
|
||||
var router = express.Router()
|
||||
|
||||
let CycleTracking = require('@models/CycleTracking');
|
||||
|
||||
|
||||
// middleware that is specific to this router
|
||||
router.use(function setUserId (req, res, next) {
|
||||
|
||||
//Session key is required to continue
|
||||
if(!req.headers.sessionId){
|
||||
next('Unauthorized')
|
||||
}
|
||||
|
||||
if(req.headers.userId){
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
//Get quick note text
|
||||
router.post('/get', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
CycleTracking.get(userId, masterKey)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
//Push text to quick note
|
||||
router.post('/save', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
CycleTracking.save(userId, req.body.cycleData, masterKey)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
|
||||
module.exports = router
|
||||
@@ -1,45 +1,53 @@
|
||||
//
|
||||
// /api/metric-tracking
|
||||
//
|
||||
|
||||
var express = require('express')
|
||||
var router = express.Router()
|
||||
|
||||
let MetricTracking = require('@models/MetricTracking');
|
||||
|
||||
let userId = null
|
||||
let masterKey = null
|
||||
|
||||
// middleware that is specific to this router
|
||||
router.use(function setUserId (req, res, next) {
|
||||
|
||||
//Session key is required to continue
|
||||
if(!req.headers.sessionId){
|
||||
next('Unauthorized')
|
||||
}
|
||||
|
||||
if(req.headers.userId){
|
||||
userId = req.headers.userId
|
||||
masterKey = req.headers.masterKey
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
router.post('/get', function (req, res) {
|
||||
MetricTracking.get(userId, masterKey)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
router.post('/create', function (req, res) {
|
||||
MetricTracking.create(userId, masterKey)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
//Push text to quick note
|
||||
router.post('/save', function (req, res) {
|
||||
MetricTracking.save(userId, req.body.cycleData, masterKey)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
|
||||
//
|
||||
// /api/metric-tracking
|
||||
//
|
||||
|
||||
var express = require('express')
|
||||
var router = express.Router()
|
||||
|
||||
let MetricTracking = require('@models/MetricTracking');
|
||||
|
||||
|
||||
// middleware that is specific to this router
|
||||
router.use(function setUserId (req, res, next) {
|
||||
|
||||
//Session key is required to continue
|
||||
if(!req.headers.sessionId){
|
||||
next('Unauthorized')
|
||||
}
|
||||
|
||||
if(req.headers.userId){
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
router.post('/get', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
MetricTracking.get(userId, masterKey)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
router.post('/create', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
MetricTracking.create(userId, masterKey)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
//Push text to quick note
|
||||
router.post('/save', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
MetricTracking.save(userId, req.body.cycleData, masterKey)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
|
||||
module.exports = router
|
||||
@@ -5,8 +5,6 @@ let Note = require('@models/Note')
|
||||
let User = require('@models/User')
|
||||
let ShareNote = require('@models/ShareNote')
|
||||
|
||||
let userId = null
|
||||
let masterKey = null
|
||||
|
||||
// middleware that is specific to this router
|
||||
router.use(function setUserId (req, res, next) {
|
||||
@@ -17,8 +15,6 @@ router.use(function setUserId (req, res, next) {
|
||||
}
|
||||
|
||||
if(req.headers.userId){
|
||||
userId = req.headers.userId
|
||||
masterKey = req.headers.masterKey
|
||||
next()
|
||||
}
|
||||
})
|
||||
@@ -27,6 +23,10 @@ router.use(function setUserId (req, res, next) {
|
||||
// Note actions
|
||||
//
|
||||
router.post('/get', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Note.get(userId, req.body.noteId, masterKey)
|
||||
.then( noteObject => {
|
||||
|
||||
@@ -39,21 +39,37 @@ router.post('/get', function (req, res) {
|
||||
})
|
||||
|
||||
router.post('/delete', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Note.delete(userId, req.body.noteId, masterKey)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
router.post('/create', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Note.create(userId, req.body.title, req.body.text, masterKey)
|
||||
.then( id => res.send({id}) )
|
||||
})
|
||||
|
||||
router.post('/update', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Note.update(userId, req.body.noteId, req.body.text, req.body.title, req.body.color, req.body.pinned, req.body.archived, req.body.hash, masterKey)
|
||||
.then( id => res.send({id}) )
|
||||
})
|
||||
|
||||
router.post('/search', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Note.search(userId, req.body.searchQuery, req.body.searchTags, req.body.fastFilters, masterKey)
|
||||
.then( NoteAndTags => {
|
||||
res.send(NoteAndTags)
|
||||
@@ -61,6 +77,10 @@ router.post('/search', function (req, res) {
|
||||
})
|
||||
|
||||
router.post('/reindex', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Note.reindex(userId, masterKey)
|
||||
.then( data => {
|
||||
res.send(data)
|
||||
@@ -72,18 +92,30 @@ router.post('/reindex', function (req, res) {
|
||||
// Update single note attributes
|
||||
//
|
||||
router.post('/setpinned', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Note.setPinned(userId, req.body.noteId, req.body.pinned)
|
||||
.then( results => {
|
||||
res.send(results)
|
||||
})
|
||||
})
|
||||
router.post('/setarchived', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Note.setArchived(userId, req.body.noteId, req.body.archived)
|
||||
.then( results => {
|
||||
res.send(results)
|
||||
})
|
||||
})
|
||||
router.post('/settrashed', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Note.setTrashed(userId, req.body.noteId, req.body.trashed, masterKey)
|
||||
.then( results => {
|
||||
res.send(results)
|
||||
@@ -94,11 +126,19 @@ router.post('/settrashed', function (req, res) {
|
||||
// Share Note Actions
|
||||
//
|
||||
router.post('/getshareinfo', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
ShareNote.getShareInfo(userId, req.body.noteId, req.body.rawTextId)
|
||||
.then(results => res.send(results))
|
||||
})
|
||||
|
||||
router.post('/shareadduser', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
// ShareNote.addUser(userId, req.body.noteId, req.body.rawTextId, req.body.username, masterKey)
|
||||
User.getByUserName(req.body.username)
|
||||
.then( user => {
|
||||
@@ -111,22 +151,38 @@ router.post('/shareadduser', function (req, res) {
|
||||
})
|
||||
|
||||
router.post('/shareremoveuser', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
// (userId, noteId, shareNoteUserId, shareUserId, masterKey)
|
||||
ShareNote.removeUserFromSharedNote(userId, req.body.noteId, req.body.shareUserNoteId, masterKey)
|
||||
.then(results => res.send(results))
|
||||
})
|
||||
|
||||
router.post('/enableshare', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
//Create Shared Encryption Key for Note
|
||||
ShareNote.migrateToShared(userId, req.body.noteId, masterKey)
|
||||
.then(results => res.send(true))
|
||||
})
|
||||
router.post('/getsharekey', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
//Get Shared Key for a note
|
||||
ShareNote.decryptSharedKey(userId, req.body.noteId, masterKey)
|
||||
.then(results => res.send(results))
|
||||
})
|
||||
router.post('/disableshare', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
//Removed shared encryption key from note
|
||||
ShareNote.migrateToNormal(userId, req.body.noteId, masterKey)
|
||||
.then(results => res.send(true))
|
||||
|
||||
@@ -3,8 +3,6 @@ var router = express.Router()
|
||||
|
||||
let QuickNote = require('@models/QuickNote');
|
||||
|
||||
let userId = null
|
||||
let masterKey = null
|
||||
|
||||
// middleware that is specific to this router
|
||||
router.use(function setUserId (req, res, next) {
|
||||
@@ -15,26 +13,36 @@ router.use(function setUserId (req, res, next) {
|
||||
}
|
||||
|
||||
if(req.headers.userId){
|
||||
userId = req.headers.userId
|
||||
masterKey = req.headers.masterKey
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
//Get quick note text
|
||||
router.post('/get', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
QuickNote.get(userId, masterKey)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
//Push text to quick note
|
||||
router.post('/update', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
QuickNote.update(userId, req.body.pushText, masterKey)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
//Push text to quick note
|
||||
router.post('/new', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
QuickNote.newNote(userId)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
@@ -3,8 +3,6 @@ var router = express.Router()
|
||||
|
||||
let Tags = require('@models/Tag')
|
||||
|
||||
let userId = null
|
||||
let masterKey = null
|
||||
|
||||
// middleware that is specific to this router
|
||||
router.use(function setUserId (req, res, next) {
|
||||
@@ -15,49 +13,75 @@ router.use(function setUserId (req, res, next) {
|
||||
}
|
||||
|
||||
if(req.headers.userId){
|
||||
userId = req.headers.userId
|
||||
masterKey = req.headers.masterKey
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
//Get the latest notes the user has created
|
||||
router.post('/suggest', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Tags.suggest(userId, req.body.noteId, req.body.tagText)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
//Get latest tags based on when it was put on a note
|
||||
router.post('/latest', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Tags.latest(userId, req.body.noteId)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
//Get the latest notes the user has created
|
||||
router.post('/addtonote', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Tags.addToNote(userId, req.body.noteId, req.body.tagText.toLowerCase())
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
router.post('/removefromnote', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Tags.removeTagFromNote(userId, req.body.tagId)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
//Get the latest notes the user has created
|
||||
router.post('/get', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Tags.get(userId, req.body.noteId)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
//Get the latest notes the user has created
|
||||
router.post('/fornote', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Tags.fornote(userId, req.body.noteId)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
//Get all the tags for this user in order of usage
|
||||
router.post('/usertags', function (req, res) {
|
||||
//Bind per request. These were module-level singletons shared by every
|
||||
//concurrent request, so one user's masterKey could overwrite another's.
|
||||
const { userId, masterKey } = req.headers
|
||||
|
||||
Tags.userTags(userId, req.body.searchQuery, req.body.searchTags, req.body.fastFilters)
|
||||
.then( data => res.send(data) )
|
||||
})
|
||||
|
||||
@@ -5,8 +5,6 @@ const User = require('@models/User')
|
||||
const Auth = require('@helpers/Auth')
|
||||
const cs = require('@helpers/CryptoString')
|
||||
|
||||
let userId = null
|
||||
let masterKey = null
|
||||
|
||||
// middleware that is specific to this router
|
||||
router.use(function setUserId (req, res, next) {
|
||||
@@ -17,8 +15,6 @@ router.use(function setUserId (req, res, next) {
|
||||
}
|
||||
|
||||
if(req.headers.userId){
|
||||
userId = req.headers.userId
|
||||
masterKey = req.headers.masterKey
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user