Closed MarcyNash closed 7 years ago
Chris helped me solve the problem -- File is an interface in JavaScript and our back end code was very confused. Changing the name of the file model and files controller solved the problem.
Thanks Chris
Still having 404 issue even with the model and schema changes.
curl script error msg:
TOKEN=wNWpJZQFB5BqtRrS9LJsxPCv3mfAEsmGmeNYDdsMPmM=--niXML7W0No1XzTVjPZ9XM5qYD/CJnXO1wN38Ykw2E20= sh scripts/files/updateHC.sh HTTP/1.1 404 Not Found X-Powered-By: Express Access-Control-Allow-Origin: http://localhost:7165 Vary: Origin Content-Type: application/json; charset=utf-8 Content-Length: 105 ETag: W/"69-/VknNk9S1zp14HmdmkX6D61xbug" Date: Thu, 29 Jun 2017 21:29:42 GMT Connection: keep-alive
{"error":{"message":"404 Not Found","error":{"name":"HttpError","status":404,"message":"404 Not Found"}}} ~/wdi/projects/drip-drop-backend (update)
server side log --
Server listening on port 4741 inside setMongooseModel inside findOne search is { _id: '5953f97544ff1208a4f83c69' } document { _id: 5953f97544ff1208a4f83c69, _owner: 5952d923ced6a7a1f1e51eb8, name: 'junk', folder: '3myfolder', url: 'abc', updatedAt: 2017-06-29T03:05:45.639Z } inside setMongooseModel inside findOne search is { _id: '5953f97544ff1208a4f83c69', _owner: { _id: 5952d923ced6a7a1f1e51eb8, passwordDigest: '$2a$10$BCffAI4CMoH4YcW8pk5oxujZtdBxhdLIrlIBYxBu4xVnTEMKksFtC', updatedAt: 2017-06-29T18:10:24.298Z, createdAt: 2017-06-27T22:16:03.413Z, email: 'm98@email.com', token: 'oWjiNRtRqp06yvca6+FnKw==', __v: 0, password: undefined, id: '5952d923ced6a7a1f1e51eb8' } } document null PATCH /uploads/5953f97544ff1208a4f83c69 404 47.096 ms - 105
CURL script --
API="http://localhost:4741" URL_PATH="/uploads"
curl "${API}${URL_PATH}/5953f97544ff1208a4f83c69" \ --include \ --request PATCH \ --header "Content-Type: application/json" \ --header "Authorization: Token token=${TOKEN}" \ --data '{ "upload": { "name": "hello" } }'
echo
TOKEN=wNWpJZQFB5BqtRrS9LJsxPCv3mfAEsmGmeNYDdsMPmM=--niXML7W0No1XzTVjPZ9XM5qYD/CJnXO1wN38Ykw2E20= sh scripts/files/updateHC.sh
Controller code --
'use strict'
const controller = require('lib/wiring/controller') const models = require('app/models') const Upload = models.upload
const authenticate = require('./concerns/authenticate') const setUser = require('./concerns/set-current-user') const setModel = require('./concerns/set-mongoose-model')
const multer = require('multer') const multerUpload = multer({ dest: '/tmp/' })
const awsUpload = require('lib/aws-upload')
const index = (req, res, next) => { Upload.find() .then(uploads => res.json({ uploads: uploads.map((e) => e.toJSON({ virtuals: true })) })) .catch(next) }
const show = (req, res) => { res.json({ upload: req.upload.toJSON({ virtuals: true }) }) }
const create = (req, res, next) => { console.log('req body', req.body) const file = { path: req.upload.path, name: req.body.upload.name } // console.log(awsFile) awsUpload(file) .then((s3Response) => { return Upload.create({ name: req.body.upload.name, url: s3Response.Location, folder: req.body.upload.folder, _owner: req.user._id }) }) .then((file) => res.status(201).json({file})) .catch(next) }
const update = (req, res, next) => { delete req.body._owner // disallow owner reassignment. req.upload.update(req.body.upload) .then(() => res.sendStatus(204)) .catch(next) }
const destroy = (req, res, next) => { req.upload.remove() .then(() => res.sendStatus(204)) .catch(next) }
module.exports = controller({ index, show, create, update, destroy }, { before: [ { method: setUser, only: ['destroy', 'update'] }, { method: multerUpload.single('upload[file]'), only: ['create'] }, { method: authenticate, except: ['index', 'show'] }, { method: setModel(Upload), only: ['show', 'destroy', 'update'] }, { method: setModel(Upload, { forUser: true }), only: ['update', 'destroy'] } ] })
Model code
'use strict'
const mongoose = require('mongoose')
const fileSchema = new mongoose.Schema({ _owner: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }, url: { type: String, required: true }, name: { type: String, required: true }, folder: { type: String, required: true }, pendingReview: { type: Boolean, required: false }, complete: { type: Boolean, required: false } }, { timestamps: true, toJSON: { virtuals: true, transform: function (doc, ret, options) { const userId = (options.user && options.user._id) || false ret.editable = userId && userId.equals(doc._owner) return ret } } })
const Upload = mongoose.model('Upload', fileSchema)
module.exports = Upload
I've read and reread the code and can't find a typo that could cause this.
that code is tough to digest unformatted
curl script error msg:
TOKEN=wNWpJZQFB5BqtRrS9LJsxPCv3mfAEsmGmeNYDdsMPmM=--niXML7W0No1XzTVjPZ9XM5qYD/CJnXO1wN38Ykw2E20= sh scripts/files/updateHC.sh
HTTP/1.1 404 Not Found
X-Powered-By: Express
Access-Control-Allow-Origin: http://localhost:7165
Vary: Origin
Content-Type: application/json; charset=utf-8
Content-Length: 105
ETag: W/"69-/VknNk9S1zp14HmdmkX6D61xbug"
Date: Thu, 29 Jun 2017 21:29:42 GMT
Connection: keep-alive
{"error":{"message":"404 Not Found","error":{"name":"HttpError","status":404,"message":"404 Not Found"}}}
~/wdi/projects/drip-drop-backend (update)
server side log --
Server listening on port 4741
inside setMongooseModel
inside findOne
search is { _id: '5953f97544ff1208a4f83c69' }
document { _id: 5953f97544ff1208a4f83c69,
_owner: 5952d923ced6a7a1f1e51eb8,
name: 'junk',
folder: '3myfolder',
url: 'abc',
updatedAt: 2017-06-29T03:05:45.639Z }
inside setMongooseModel
inside findOne
search is { _id: '5953f97544ff1208a4f83c69',
_owner:
{ _id: 5952d923ced6a7a1f1e51eb8,
passwordDigest: '$2a$10$BCffAI4CMoH4YcW8pk5oxujZtdBxhdLIrlIBYxBu4xVnTEMKksFtC',
updatedAt: 2017-06-29T18:10:24.298Z,
createdAt: 2017-06-27T22:16:03.413Z,
email: 'm98@email.com',
token: 'oWjiNRtRqp06yvca6+FnKw==',
__v: 0,
password: undefined,
id: '5952d923ced6a7a1f1e51eb8' } }
document null
PATCH /uploads/5953f97544ff1208a4f83c69 404 47.096 ms - 105
CURL script --
#!/bin/bash
API="http://localhost:4741"
URL_PATH="/uploads"
# ID="5953f97544ff1208a4f83c69"
# TOKEN=wNWpJZQFB5BqtRrS9LJsxPCv3mfAEsmGmeNYDdsMPmM=--niXML7W0No1XzTVjPZ9XM5qYD/CJnXO1wN38Ykw2E20=
curl "${API}${URL_PATH}/5953f97544ff1208a4f83c69" \
--include \
--request PATCH \
--header "Content-Type: application/json" \
--header "Authorization: Token token=${TOKEN}" \
--data '{
"upload": {
"name": "hello"
}
}'
echo
TOKEN=wNWpJZQFB5BqtRrS9LJsxPCv3mfAEsmGmeNYDdsMPmM=--niXML7W0No1XzTVjPZ9XM5qYD/CJnXO1wN38Ykw2E20= sh scripts/files/updateHC.sh
Controller code --
'use strict'
const controller = require('lib/wiring/controller')
const models = require('app/models')
const Upload = models.upload
const authenticate = require('./concerns/authenticate')
const setUser = require('./concerns/set-current-user')
const setModel = require('./concerns/set-mongoose-model')
const multer = require('multer')
const multerUpload = multer({ dest: '/tmp/' })
const awsUpload = require('lib/aws-upload')
const index = (req, res, next) => {
Upload.find()
.then(uploads => res.json({
uploads: uploads.map((e) =>
e.toJSON({ virtuals: true }))
}))
.catch(next)
}
const show = (req, res) => {
res.json({
upload: req.upload.toJSON({ virtuals: true })
})
}
const create = (req, res, next) => {
console.log('req body', req.body)
const file = {
path: req.upload.path,
name: req.body.upload.name
}
// console.log(awsFile)
awsUpload(file)
.then((s3Response) => {
return Upload.create({
name: req.body.upload.name,
url: s3Response.Location,
folder: req.body.upload.folder,
_owner: req.user._id
})
})
.then((file) => res.status(201).json({file}))
.catch(next)
}
const update = (req, res, next) => {
delete req.body._owner // disallow owner reassignment.
req.upload.update(req.body.upload)
.then(() => res.sendStatus(204))
.catch(next)
}
const destroy = (req, res, next) => {
req.upload.remove()
.then(() => res.sendStatus(204))
.catch(next)
}
module.exports = controller({
index,
show,
create,
update,
destroy
}, { before: [
{ method: setUser, only: ['destroy', 'update'] },
{ method: multerUpload.single('upload[file]'), only: ['create'] },
{ method: authenticate, except: ['index', 'show'] },
{ method: setModel(Upload), only: ['show', 'destroy', 'update'] },
{ method: setModel(Upload, { forUser: true }), only: ['update', 'destroy'] }
] })
Model code
'use strict'
const mongoose = require('mongoose')
const fileSchema = new mongoose.Schema({
_owner: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true
},
url: {
type: String,
required: true
},
name: {
type: String,
required: true
},
folder: {
type: String,
required: true
},
pendingReview: {
type: Boolean,
required: false
},
complete: {
type: Boolean,
required: false
}
}, {
timestamps: true,
toJSON: {
virtuals: true,
transform: function (doc, ret, options) {
const userId = (options.user && options.user._id) || false
ret.editable = userId && userId.equals(doc._owner)
return ret
}
}
})
const Upload = mongoose.model('Upload', fileSchema)
module.exports = Upload
i see password: undefined
and document null
in there, is that expected?
These questions are from Jordon's email, but I don't see it in this issue thread --
-- i see password: undefined
-- and document null
-- in there, is that expected?
I believe the password isn't stored on the server; the passwordDigest is stored instead. The document should not be null; findOne in the setMongooseMode should return the document to update.
Sorry about the formatting. I'll resend the code
Controller code: uploads,js
'use strict'
const controller = require('lib/wiring/controller')
const models = require('app/models')
const Upload = models.upload
const authenticate = require('./concerns/authenticate')
const setUser = require('./concerns/set-current-user')
const setModel = require('./concerns/set-mongoose-model')
const multer = require('multer')
const multerUpload = multer({ dest: '/tmp/' })
const awsUpload = require('lib/aws-upload')
const index = (req, res, next) => {
Upload.find()
.then(uploads => res.json({
uploads: uploads.map((e) =>
e.toJSON({ virtuals: true }))
}))
.catch(next)
}
const show = (req, res) => {
res.json({
upload: req.upload.toJSON({ virtuals: true })
})
}
const create = (req, res, next) => {
console.log('req body', req.body)
const file = {
path: req.upload.path,
name: req.body.upload.name
}
// console.log(awsFile)
awsUpload(file)
.then((s3Response) => {
return Upload.create({
name: req.body.upload.name,
url: s3Response.Location,
folder: req.body.upload.folder,
_owner: req.user._id
})
})
.then((file) => res.status(201).json({file}))
.catch(next)
}
const update = (req, res, next) => {
delete req.body._owner // disallow owner reassignment.
req.upload.update(req.body.upload)
.then(() => res.sendStatus(204))
.catch(next)
}
const destroy = (req, res, next) => {
req.upload.remove()
.then(() => res.sendStatus(204))
.catch(next)
}
module.exports = controller({
index,
show,
create,
update,
destroy
}, { before: [
{ method: setUser, only: ['destroy', 'update'] },
{ method: multerUpload.single('upload[file]'), only: ['create'] },
{ method: authenticate, except: ['index', 'show'] },
{ method: setModel(Upload), only: ['show', 'destroy', 'update'] },
{ method: setModel(Upload, { forUser: true }), only: ['update', 'destroy'] }
] })
Model code: upload.js
'use strict'
const mongoose = require('mongoose')
const uploadSchema = new mongoose.Schema({
_owner: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true
},
url: {
type: String,
required: true
},
name: {
type: String,
required: true
},
folder: {
type: String,
required: true
},
pendingReview: {
type: Boolean,
required: false
},
complete: {
type: Boolean,
required: false
}
}, {
timestamps: true,
toJSON: {
virtuals: true,
transform: function (doc, ret, options) {
const userId = (options.user && options.user._id) || false
ret.editable = userId && userId.equals(doc._owner)
return ret
}
}
})
const Upload = mongoose.model('Upload', uploadSchema)
module.exports = Upload
set-mongoose-model.js
'use strict'
const HttpError = require('lib/wiring/errors/http-error')
const setMongooseModel = (model, options) =>
function (req, res, next) {
console.log('inside setMongooseModel')
const search = { _id: req.params.id }
if (options && options.forUser) {
search._owner = req.user
}
model.findOne(search, (error, document) => {
console.log('inside findOne')
console.log('search is ', search)
error = error || !document && new HttpError(404)
console.log('document ', document)
if (error) {
return next(error)
}
req[model.modelName.toLowerCase()] = document
next()
})
}
module.exports = setMongooseModel
so this part of the code
model.findOne(search, (error, document) => {
console.log('inside findOne')
console.log('search is ', search)
error = error || !document && new HttpError(404)
console.log('document ', document)
is not defining document properly
Does this mean there is something wrong in the model? The above code works for the SHOW curl script
On Fri, Jun 30, 2017 at 12:15 PM, Jordan notifications@github.com wrote:
so this part of the code
model.findOne(search, (error, document) => { console.log('inside findOne') console.log('search is ', search) error = error || !document && new HttpError(404) console.log('document ', document)
is not defining document properly
— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/ga-wdi-boston/team-project/issues/357#issuecomment-312310330, or mute the thread https://github.com/notifications/unsubscribe-auth/AIb6bT7qRj81Q04icb0chVtVYMcWREkPks5sJR8pgaJpZM4OJv-F .
its saying
search is {
_id: '5953f97544ff1208a4f83c69',
_owner: {
_id: 5952d923ced6a7a1f1e51eb8,
passwordDigest: '$2a$10$BCffAI4CMoH4YcW8pk5oxujZtdBxhdLIrlIBYxBu4xVnTEMKksFtC',
updatedAt: 2017-06-29T18:10:24.298Z,
createdAt: 2017-06-27T22:16:03.413Z,
email: 'm98@email.com',
token: 'oWjiNRtRqp06yvca6+FnKw==',
__v: 0,
password: undefined,
id: '5952d923ced6a7a1f1e51eb8'
}
}
is that what you want to be searching by?
I'm searching for a file with _id: 5953f97544ff1208a4f83c69 and whose owner is _id: .5952d923ced6a7a1f1e51eb8 since only the owner can update the files she created.
The upload model / uploads controller were modeled on Example(s). Examples can update, upload cannot.
Upload INDEX then PATCH --
TOKEN=Za9Hbo8qAP9yvOpFUN/IcMS/iZNQdy2JWCtVLiqtRGA=--arLgq4Up/QljcuBgKC6VkdRnYte0q0agPB9Tjg8cVyk= TEXT='updateagain' sh scripts/uploads/index.sh
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: http://localhost:7165
Vary: Origin
Content-Type: application/json; charset=utf-8
Content-Length: 538
ETag: W/"21a-ntz7GEQTh5kO8dZzlBbXxnZY1tM"
Date: Wed, 05 Jul 2017 17:53:51 GMT
Connection: keep-alive
{"uploads":[{"_id":"5959a31928d089b597a013be","_owner":"59599b5e13b8d26567b051c0","url":"abc","name":"3myfile","folder":"3myfolder","id":"5959a31928d089b597a013be","editable":false},{"_id":"5959a4e213b8d26567b051c2","updatedAt":"2017-07-03T01:58:58.988Z","createdAt":"2017-07-03T01:58:58.988Z","name":"screenshot1.png","url":" https://mjnbucket.s3.amazonaws.com/2017-07-03/acf984ba137e45d9cc23ee53f6d18bba ","folder":"3myfolder","tag":"Pending","_owner":"5959a3ec13b8d26567b051c1","__v":0,"id":"5959a4e213b8d26567b051c2","editable":false}]}
~/wdi/projects/drip-drop-backend (testdev)
$ ID=5959a31928d089b597a013be TOKEN=Za9Hbo8qAP9yvOpFUN/IcMS/iZNQdy2JWCtVLiqtRGA=--arLgq4Up/QljcuBgKC6VkdRnYte0q0agPB9Tjg8cVyk= TEXT='update3' sh scripts/uploads/update.sh
HTTP/1.1 404 Not Found
X-Powered-By: Express
Access-Control-Allow-Origin: http://localhost:7165
Vary: Origin
Content-Type: application/json; charset=utf-8
Content-Length: 105
ETag: W/"69-/VknNk9S1zp14HmdmkX6D61xbug"
Date: Wed, 05 Jul 2017 17:54:23 GMT
Connection: keep-alive
{"error":{"message":"404 Not Found","error":{"name":"HttpError","status":404,"message":"404 Not Found"}}} Server logs --
I put code in the upload and example models to log whether the database record is editable --
virtuals: true,
transform: function (doc, ret, options) {
console.log('transform in upload')
const userId = (options.user && options.user._id) || false
ret.editable = userId && userId.equals(doc._owner)
console.log(' userId = ' + userId)
console.log(' doc owner = ' + doc._owner)
return ret
}``
transform in upload
userId = false
doc owner = 59599b5e13b8d26567b051c0
transform in upload
userId = false
doc owner = 5959a3ec13b8d26567b051c1
GET /uploads 200 4.463 ms - 538
setMongooseModel options =
{ forUser: true }
findOne document = null
PATCH /uploads/5959a31928d089b597a013be 404 11.003 ms - 105
Examples INDEX then PATCH
TOKEN=Za9Hbo8qAP9yvOpFUN/IcMS/iZNQdy2JWCtVLiqtRGA=--arLgq4Up/QljcuBgKC6VkdRnYte0q0agPB9Tjg8cVyk=
TEXT='updateagain' sh scripts/examples/index.sh
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: http://localhost:7165
Vary: Origin
Content-Type: application/json; charset=utf-8
Content-Length: 725
ETag: W/"2d5-AmMcwY5CY8IqdvPOuMmda5eY0dk"
Date: Wed, 05 Jul 2017 18:01:30 GMT
Connection: keep-alive
{"examples":[{"_id":"595bd2bf099a2878e14cf8f8","updatedAt":"2017-07-04T17:52:52.914Z","createdAt":"2017-07-04T17:39:11.047Z","text":"updateagain","_owner":"59599b5e13b8d26567b051c0","__v":0,"length":11,"id":"595bd2bf099a2878e14cf8f8","editable":true},{"_id":"595ce8acdad547269f17f3af","updatedAt":"2017-07-05T13:25:00.859Z","createdAt":"2017-07-05T13:25:00.859Z","text":"YAExample","_owner":"59599b5e13b8d26567b051c0","__v":0,"length":9,"id":"595ce8acdad547269f17f3af","editable":true},{"_id":"595d0cb0dad547269f17f3b0","updatedAt":"2017-07-05T17:37:49.569Z","createdAt":"2017-07-05T15:58:40.529Z","text":"updateagain","_owner":"59599b5e13b8d26567b051c0","__v":0,"length":11,"id":"595d0cb0dad547269f17f3b0","editable":true}]}
~/wdi/projects/drip-drop-backend (testdev)
$ ID=595bd2bf099a2878e14cf8f8
TOKEN=Za9Hbo8qAP9yvOpFUN/IcMS/iZNQdy2JWCtVLiqtRGA=--arLgq4Up/QljcuBgKC6VkdRnYte0q0agPB9Tjg8cVyk=
TEXT='update4' sh scripts/examples/update.sh
HTTP/1.1 204 No Content
X-Powered-By: Express
Access-Control-Allow-Origin: http://localhost:7165
Vary: Origin
ETag: W/"a-bAsFyilMr4Ra1hIU5PyoyFRunpI"
Date: Wed, 05 Jul 2017 18:02:50 GMT
Connection: keep-alive
Server logs --
transform in example
userId = 59599b5e13b8d26567b051c0
doc owner = 59599b5e13b8d26567b051c0
transform in example
userId = 59599b5e13b8d26567b051c0
doc owner = 59599b5e13b8d26567b051c0
transform in example
userId = 59599b5e13b8d26567b051c0
doc owner = 59599b5e13b8d26567b051c0
GET /examples 200 6.841 ms - 725
setMongooseModel options =
{ forUser: true }
findOne document = { _id: 595bd2bf099a2878e14cf8f8,
updatedAt: 2017-07-04T17:52:52.914Z,
createdAt: 2017-07-04T17:39:11.047Z,
text: 'updateagain',
_owner: 59599b5e13b8d26567b051c0,
__v: 0 }
PATCH /examples/595bd2bf099a2878e14cf8f8 204 6.948 ms - -
I really need hlelp to figure out why example is working and uploads is not
Thanks!
On Fri, Jun 30, 2017 at 12:27 PM, Jordan <notifications@github.com> wrote:
> its saying
>
> search is {
> _id: '5953f97544ff1208a4f83c69',
> _owner: {
> _id: 5952d923ced6a7a1f1e51eb8,
> passwordDigest: '$2a$10$BCffAI4CMoH4YcW8pk5oxujZtdBxhdLIrlIBYxBu4xVnTEMKksFtC',
> updatedAt: 2017-06-29T18:10:24.298Z,
> createdAt: 2017-06-27T22:16:03.413Z,
> email: 'm98@email.com',
> token: 'oWjiNRtRqp06yvca6+FnKw==',
> __v: 0,
> password: undefined,
> id: '5952d923ced6a7a1f1e51eb8'
> }
> }
>
> is that what you want to be searching by?
>
> —
> You are receiving this because you modified the open/close state.
> Reply to this email directly, view it on GitHub
> <https://github.com/ga-wdi-boston/team-project/issues/357#issuecomment-312313151>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AIb6bYPirW1VZLSiSKwdKRVklQrCJrfUks5sJSIIgaJpZM4OJv-F>
> .
>
This issue was resolved when I went back to an earlier commit. When using Mongoose / MongoDB, changes to the database schema require a new, clean database. Also, database records created with CURL scripts behave differently than those created via the frontend.
When running a CURL script for a PATCH the result is a 404.
From the console logs in set-mongoose-model.js the File _id is not being correctly passed. I compared the examples schema to the files schema and noticed that at the bottom of the examples models file (models/example.js), module.exports = Example (Example is white) whereas the end of the files model file (models/file.js), module.exports = File (File is yellow).
DELETE should be going through the same mongoose-model code, yet still works.