wip(backend): Cloning of people
This commit is contained in:
parent
e37548fcf7
commit
d0b8572f46
6 changed files with 127 additions and 30 deletions
|
@ -8,7 +8,7 @@ export function PersonController() {}
|
|||
*/
|
||||
PersonController.prototype.create = async (req, res, tools) => {
|
||||
const Person = new PersonModel(tools)
|
||||
await Person.create(req)
|
||||
await Person.guardedCreate(req)
|
||||
|
||||
return Person.sendResponse(res)
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ PersonController.prototype.create = async (req, res, tools) => {
|
|||
*/
|
||||
PersonController.prototype.read = async (req, res, tools) => {
|
||||
const Person = new PersonModel(tools)
|
||||
await Person.readForReturn({ id: parseInt(req.params.id) }, req.user)
|
||||
await Person.guardedRead(req)
|
||||
|
||||
return Person.sendResponse(res)
|
||||
}
|
||||
|
@ -50,9 +50,9 @@ PersonController.prototype.delete = async (req, res, tools) => {
|
|||
* Clone a person
|
||||
* See: https://freesewing.dev/reference/backend/api
|
||||
*/
|
||||
//PersonController.prototype.clone = async (req, res, tools) => {
|
||||
// const Person = new PersonModel(tools)
|
||||
// await Person.unsafeUpdate(req)
|
||||
//
|
||||
// return Person.sendResponse(res)
|
||||
//}
|
||||
PersonController.prototype.clone = async (req, res, tools) => {
|
||||
const Person = new PersonModel(tools)
|
||||
await Person.guardedClone(req)
|
||||
|
||||
return Person.sendResponse(res)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ export function UserController() {}
|
|||
*/
|
||||
UserController.prototype.signup = async (req, res, tools) => {
|
||||
const User = new UserModel(tools)
|
||||
await User.create(req)
|
||||
await User.guardedCreate(req)
|
||||
|
||||
return User.sendResponse(res)
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ UserController.prototype.login = async function (req, res, tools) {
|
|||
*/
|
||||
UserController.prototype.whoami = async (req, res, tools) => {
|
||||
const User = new UserModel(tools)
|
||||
await User.readForReturn({ id: req.user.uid })
|
||||
await User.guardedRead({ id: req.user.uid })
|
||||
|
||||
return User.sendResponse(res)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ export function PersonModel(tools) {
|
|||
return this
|
||||
}
|
||||
|
||||
PersonModel.prototype.create = async function ({ body, user }) {
|
||||
PersonModel.prototype.guardedCreate = async function ({ body, user }) {
|
||||
if (user.level < 3) return this.setResponse(403, 'insufficientAccessLevel')
|
||||
if (Object.keys(body) < 1) return this.setResponse(400, 'postBodyMissing')
|
||||
if (!body.name || typeof body.name !== 'string') return this.setResponse(400, 'nameMissing')
|
||||
|
@ -28,12 +28,7 @@ PersonModel.prototype.create = async function ({ body, user }) {
|
|||
data.img = this.config.avatars.person
|
||||
|
||||
// Create record
|
||||
try {
|
||||
this.record = await this.prisma.person.create({ data: this.cloak(data) })
|
||||
} catch (err) {
|
||||
log.warn(err, 'Could not create person')
|
||||
return this.setResponse(500, 'createPersonFailed')
|
||||
}
|
||||
await this.unguardedCreate(data)
|
||||
|
||||
// Update img? (now that we have the ID)
|
||||
const img =
|
||||
|
@ -49,6 +44,17 @@ PersonModel.prototype.create = async function ({ body, user }) {
|
|||
return this.setResponse(201, 'created', { person: this.asPerson() })
|
||||
}
|
||||
|
||||
PersonModel.prototype.unguardedCreate = async function (data) {
|
||||
try {
|
||||
this.record = await this.prisma.person.create({ data: this.cloak(data) })
|
||||
} catch (err) {
|
||||
log.warn(err, 'Could not create person')
|
||||
return this.setResponse(500, 'createPersonFailed')
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads a person from the database based on the where clause you pass it
|
||||
*
|
||||
|
@ -72,11 +78,11 @@ PersonModel.prototype.read = async function (where) {
|
|||
*
|
||||
* Stores result in this.record
|
||||
*/
|
||||
PersonModel.prototype.readForReturn = async function (where, user) {
|
||||
PersonModel.prototype.guardedRead = async function ({ params, user }) {
|
||||
if (user.level < 1) return this.setResponse(403, 'insufficientAccessLevel')
|
||||
if (user.iss && user.status < 1) return this.setResponse(403, 'accountStatusLacking')
|
||||
|
||||
await this.read(where)
|
||||
await this.read({ id: parseInt(params.id) })
|
||||
if (this.record.userId !== user.uid && user.level < 5) {
|
||||
return this.setResponse(403, 'insufficientAccessLevel')
|
||||
}
|
||||
|
@ -87,6 +93,37 @@ PersonModel.prototype.readForReturn = async function (where, user) {
|
|||
})
|
||||
}
|
||||
|
||||
/*
|
||||
* Clones a person
|
||||
* In addition prepares it for returning the person data
|
||||
*
|
||||
* Stores result in this.record
|
||||
*/
|
||||
PersonModel.prototype.guardedClone = async function ({ params, user }) {
|
||||
if (user.level < 3) return this.setResponse(403, 'insufficientAccessLevel')
|
||||
if (user.iss && user.status < 1) return this.setResponse(403, 'accountStatusLacking')
|
||||
|
||||
await this.read({ id: parseInt(params.id) })
|
||||
if (this.record.userId !== user.uid && !this.record.public && user.level < 5) {
|
||||
return this.setResponse(403, 'insufficientAccessLevel')
|
||||
}
|
||||
|
||||
// Clone person
|
||||
const data = this.asPerson()
|
||||
delete data.id
|
||||
data.name += ` (cloned from #${this.record.id})`
|
||||
data.notes += ` (Note: This person was cloned from person #${this.record.id})`
|
||||
await this.unguardedCreate(data)
|
||||
|
||||
// Update unencrypted data
|
||||
this.reveal()
|
||||
|
||||
return this.setResponse(200, false, {
|
||||
result: 'success',
|
||||
person: this.asPerson(),
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper method to decrypt at-rest data
|
||||
*/
|
||||
|
|
|
@ -67,7 +67,7 @@ UserModel.prototype.cloak = function (data) {
|
|||
*
|
||||
* Stores result in this.record
|
||||
*/
|
||||
UserModel.prototype.readForReturn = async function (where) {
|
||||
UserModel.prototype.guardedRead = async function (where) {
|
||||
await this.read(where)
|
||||
|
||||
return this.setResponse(200, false, {
|
||||
|
@ -136,7 +136,7 @@ UserModel.prototype.setExists = function () {
|
|||
/*
|
||||
* Creates a user+confirmation and sends out signup email
|
||||
*/
|
||||
UserModel.prototype.create = async function ({ body }) {
|
||||
UserModel.prototype.guardedCreate = async function ({ body }) {
|
||||
if (Object.keys(body) < 1) return this.setResponse(400, 'postBodyMissing')
|
||||
if (!body.email) return this.setResponse(400, 'emailMissing')
|
||||
if (!body.language) return this.setResponse(400, 'languageMissing')
|
||||
|
|
|
@ -15,6 +15,14 @@ export function personRoutes(tools) {
|
|||
Person.create(req, res, tools)
|
||||
)
|
||||
|
||||
// Clone person
|
||||
app.post('/people/:id/clone/jwt', passport.authenticate(...jwt), (req, res) =>
|
||||
Person.clone(req, res, tools)
|
||||
)
|
||||
app.post('/people/:id/clone/key', passport.authenticate(...bsc), (req, res) =>
|
||||
Person.clone(req, res, tools)
|
||||
)
|
||||
|
||||
// Read person
|
||||
app.get('/people/:id/jwt', passport.authenticate(...jwt), (req, res) =>
|
||||
Person.read(req, res, tools)
|
||||
|
@ -31,14 +39,6 @@ export function personRoutes(tools) {
|
|||
Person.update(req, res, tools)
|
||||
)
|
||||
|
||||
// Clone person
|
||||
app.put('/people/:id/clone/jwt', passport.authenticate(...jwt), (req, res) =>
|
||||
Person.clone(req, res, tools)
|
||||
)
|
||||
app.put('/people/:id/clone/key', passport.authenticate(...bsc), (req, res) =>
|
||||
Person.clone(req, res, tools)
|
||||
)
|
||||
|
||||
// Delete person
|
||||
app.delete('/people/:id/jwt', passport.authenticate(...jwt), (req, res) =>
|
||||
Person.delete(req, res, tools)
|
||||
|
|
|
@ -95,7 +95,7 @@ export const personTests = async (chai, config, expect, store) => {
|
|||
for (const field of ['imperial', 'public']) {
|
||||
it(`${store.icon('person', auth)} Should update the ${field} field (${auth})`, (done) => {
|
||||
const data = {}
|
||||
const val = false
|
||||
const val = !store.person[auth][field]
|
||||
data[field] = val
|
||||
chai
|
||||
.request(config.api)
|
||||
|
@ -115,6 +115,7 @@ export const personTests = async (chai, config, expect, store) => {
|
|||
expect(res.status).to.equal(200)
|
||||
expect(res.body.result).to.equal(`success`)
|
||||
expect(res.body.person[field]).to.equal(val)
|
||||
store.person[auth][field] = val
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
@ -310,6 +311,65 @@ export const personTests = async (chai, config, expect, store) => {
|
|||
})
|
||||
})
|
||||
|
||||
//it(`${store.icon(
|
||||
// 'person',
|
||||
// auth
|
||||
//)} Should clone a person (${auth})`, (done) => {
|
||||
// chai
|
||||
// .request(config.api)
|
||||
// .post(`/people/${store.person[auth].id}/clone/${auth}`)
|
||||
// .set(
|
||||
// 'Authorization',
|
||||
// auth === 'jwt'
|
||||
// ? 'Bearer ' + store.account.token
|
||||
// : 'Basic ' +
|
||||
// new Buffer(
|
||||
// `${store.account.apikey.key}:${store.account.apikey.secret}`
|
||||
// ).toString('base64')
|
||||
// )
|
||||
// .end((err, res) => {
|
||||
// expect(err === null).to.equal(true)
|
||||
// expect(res.status).to.equal(200)
|
||||
// expect(res.body.result).to.equal(`success`)
|
||||
// expect(typeof res.body.error).to.equal(`undefined`)
|
||||
// expect(typeof res.body.person.id).to.equal(`number`)
|
||||
// done()
|
||||
// })
|
||||
//})
|
||||
|
||||
it(`${store.icon(
|
||||
'person',
|
||||
auth
|
||||
)} Should (not) clone a public person across accounts (${auth})`, (done) => {
|
||||
chai
|
||||
.request(config.api)
|
||||
.post(`/people/${store.person[auth].id}/clone/${auth}`)
|
||||
.set(
|
||||
'Authorization',
|
||||
auth === 'jwt'
|
||||
? 'Bearer ' + store.altaccount.token
|
||||
: 'Basic ' +
|
||||
new Buffer(
|
||||
`${store.altaccount.apikey.key}:${store.altaccount.apikey.secret}`
|
||||
).toString('base64')
|
||||
)
|
||||
.end((err, res) => {
|
||||
if (store.person[auth].public) {
|
||||
expect(err === null).to.equal(true)
|
||||
expect(res.status).to.equal(200)
|
||||
expect(res.body.result).to.equal(`success`)
|
||||
expect(typeof res.body.error).to.equal(`undefined`)
|
||||
expect(typeof res.body.person.id).to.equal(`number`)
|
||||
} else {
|
||||
expect(err === null).to.equal(true)
|
||||
expect(res.status).to.equal(403)
|
||||
expect(res.body.result).to.equal(`error`)
|
||||
expect(res.body.error).to.equal(`insufficientAccessLevel`)
|
||||
}
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
// TODO:
|
||||
// - Clone person
|
||||
// - Clone person accross accounts of they are public
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue