wip(backend): More access control guarding
This commit is contained in:
parent
bc5a605c9b
commit
e37548fcf7
9 changed files with 325 additions and 130 deletions
|
@ -4,7 +4,6 @@ export function PersonController() {}
|
|||
|
||||
/*
|
||||
* Create a person for the authenticated user
|
||||
*
|
||||
* See: https://freesewing.dev/reference/backend/api
|
||||
*/
|
||||
PersonController.prototype.create = async (req, res, tools) => {
|
||||
|
@ -16,34 +15,44 @@ PersonController.prototype.create = async (req, res, tools) => {
|
|||
|
||||
/*
|
||||
* Read a person
|
||||
*
|
||||
* See: https://freesewing.dev/reference/backend/api
|
||||
*/
|
||||
PersonController.prototype.read = async (req, res, tools) => {
|
||||
//const Person = new PersonModel(tools)
|
||||
//await Person.read({ id: req.params.id })
|
||||
//return Person.sendResponse(res)
|
||||
const Person = new PersonModel(tools)
|
||||
await Person.readForReturn({ id: parseInt(req.params.id) }, req.user)
|
||||
|
||||
return Person.sendResponse(res)
|
||||
}
|
||||
|
||||
/*
|
||||
* Update a person
|
||||
*
|
||||
* See: https://freesewing.dev/reference/backend/api
|
||||
*/
|
||||
PersonController.prototype.update = async (req, res, tools) => {
|
||||
const Person = new PersonModel(tools)
|
||||
await Person.unsafeUpdate(req)
|
||||
await Person.guardedUpdate(req)
|
||||
|
||||
return Person.sendResponse(res)
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a person
|
||||
*
|
||||
* See: https://freesewing.dev/reference/backend/api
|
||||
*/
|
||||
PersonController.prototype.delete = async (req, res, tools) => {
|
||||
//const Person = new PersonModel(tools)
|
||||
//await Person.remove(req)
|
||||
//return Person.sendResponse(res)
|
||||
const Person = new PersonModel(tools)
|
||||
await Person.guardedDelete(req)
|
||||
|
||||
return Person.sendResponse(res)
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
//}
|
||||
|
|
|
@ -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.readAsAccount({ id: req.user.uid })
|
||||
await User.readForReturn({ id: req.user.uid })
|
||||
|
||||
return User.sendResponse(res)
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ UserController.prototype.whoami = async (req, res, tools) => {
|
|||
UserController.prototype.update = async (req, res, tools) => {
|
||||
const User = new UserModel(tools)
|
||||
await User.read({ id: req.user.uid })
|
||||
await User.unsafeUpdate(req.body)
|
||||
await User.guardedUpdate(req.body, req.user)
|
||||
|
||||
return User.sendResponse(res)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ PersonModel.prototype.create = async function ({ body, user }) {
|
|||
data.imperial = body.imperial === true ? true : false
|
||||
data.userId = user.uid
|
||||
// Set this one initially as we need the ID to create a custom img via Sanity
|
||||
data.img = this.encrypt(this.config.avatars.person)
|
||||
data.img = this.config.avatars.person
|
||||
|
||||
// Create record
|
||||
try {
|
||||
|
@ -43,7 +43,7 @@ PersonModel.prototype.create = async function ({ body, user }) {
|
|||
? await setPersonAvatar(this.record.id, body.img)
|
||||
: false
|
||||
|
||||
if (img) await this.safeUpdate(this.cloak({ img: img.url }))
|
||||
if (img) await this.unguardedUpdate(this.cloak({ img: img.url }))
|
||||
else await this.read({ id: this.record.id })
|
||||
|
||||
return this.setResponse(201, 'created', { person: this.asPerson() })
|
||||
|
@ -66,6 +66,27 @@ PersonModel.prototype.read = async function (where) {
|
|||
return this.setExists()
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads a person from the database based on the where clause you pass it
|
||||
* In addition prepares it for returning the person data
|
||||
*
|
||||
* Stores result in this.record
|
||||
*/
|
||||
PersonModel.prototype.readForReturn = async function (where, 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)
|
||||
if (this.record.userId !== user.uid && user.level < 5) {
|
||||
return this.setResponse(403, 'insufficientAccessLevel')
|
||||
}
|
||||
|
||||
return this.setResponse(200, false, {
|
||||
result: 'success',
|
||||
person: this.asPerson(),
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper method to decrypt at-rest data
|
||||
*/
|
||||
|
@ -85,55 +106,14 @@ PersonModel.prototype.reveal = async function () {
|
|||
*/
|
||||
PersonModel.prototype.cloak = function (data) {
|
||||
for (const field of this.encryptedFields) {
|
||||
if (typeof data[field] !== 'undefined') data[field] = this.encrypt(data[field])
|
||||
if (typeof data[field] !== 'undefined') {
|
||||
data[field] = this.encrypt(data[field])
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads a user from the database based on the where clause you pass it
|
||||
* In addition prepares it for returning the account data
|
||||
*
|
||||
* Stores result in this.record
|
||||
*/
|
||||
//UserModel.prototype.readAsAccount = async function (where) {
|
||||
// await this.read(where)
|
||||
//
|
||||
// return this.setResponse(200, false, {
|
||||
// result: 'success',
|
||||
// account: this.asAccount(),
|
||||
// })
|
||||
//}
|
||||
|
||||
/*
|
||||
* Finds a user based on one of the accepted unique fields which are:
|
||||
* - lusername (lowercase username)
|
||||
* - ehash
|
||||
* - id
|
||||
*
|
||||
* Stores result in this.record
|
||||
*/
|
||||
//UserModel.prototype.find = async function (body) {
|
||||
// try {
|
||||
// this.record = await this.prisma.user.findFirst({
|
||||
// where: {
|
||||
// OR: [
|
||||
// { lusername: { equals: clean(body.username) } },
|
||||
// { ehash: { equals: hash(clean(body.username)) } },
|
||||
// { id: { equals: parseInt(body.username) || -1 } },
|
||||
// ],
|
||||
// },
|
||||
// })
|
||||
// } catch (err) {
|
||||
// log.warn({ err, body }, `Error while trying to find user: ${body.username}`)
|
||||
// }
|
||||
//
|
||||
// this.reveal()
|
||||
//
|
||||
// return this.setExists()
|
||||
//}
|
||||
|
||||
/*
|
||||
* Checks this.record and sets a boolean to indicate whether
|
||||
* the user exists or not
|
||||
|
@ -150,7 +130,7 @@ PersonModel.prototype.setExists = function () {
|
|||
* Updates the person data - Used when we create the data ourselves
|
||||
* so we know it's safe
|
||||
*/
|
||||
PersonModel.prototype.safeUpdate = async function (data) {
|
||||
PersonModel.prototype.unguardedUpdate = async function (data) {
|
||||
try {
|
||||
this.record = await this.prisma.person.update({
|
||||
where: { id: this.record.id },
|
||||
|
@ -170,14 +150,14 @@ PersonModel.prototype.safeUpdate = async function (data) {
|
|||
* Updates the person data - Used when we pass through user-provided data
|
||||
* so we can't be certain it's safe
|
||||
*/
|
||||
PersonModel.prototype.unsafeUpdate = async function ({ params, body, user }) {
|
||||
PersonModel.prototype.guardedUpdate = async function ({ params, body, 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 (user.uid !== this.record.userId) return this.setResponse(403, 'accessDenied')
|
||||
if (this.record.userId !== user.uid && user.level < 8) {
|
||||
return this.setResponse(403, 'insufficientAccessLevel')
|
||||
}
|
||||
const data = {}
|
||||
/*
|
||||
img String?
|
||||
*/
|
||||
// Imperial
|
||||
if (body.imperial === true || body.imperial === false) data.imperial = body.imperial
|
||||
// Name
|
||||
|
@ -189,11 +169,15 @@ PersonModel.prototype.unsafeUpdate = async function ({ params, body, user }) {
|
|||
// Measurements
|
||||
const measies = {}
|
||||
if (typeof body.measies === 'object') {
|
||||
const remove = []
|
||||
for (const [key, val] of Object.entries(body.measies)) {
|
||||
if (this.config.measies.includes(key) && typeof val === 'number' && val > 0)
|
||||
measies[key] = val
|
||||
if (this.config.measies.includes(key)) {
|
||||
if (val === null) remove.push(key)
|
||||
else if (typeof val == 'number' && val > 0) measies[key] = val
|
||||
}
|
||||
}
|
||||
data.measies = { ...this.clear.measies, ...measies }
|
||||
for (const key of remove) delete data.measies[key]
|
||||
}
|
||||
|
||||
// Image (img)
|
||||
|
@ -203,11 +187,39 @@ PersonModel.prototype.unsafeUpdate = async function ({ params, body, user }) {
|
|||
}
|
||||
|
||||
// Now update the record
|
||||
await this.safeUpdate(this.cloak(data))
|
||||
await this.unguardedUpdate(this.cloak(data))
|
||||
|
||||
return this.setResponse(200, false, { person: this.asPerson() })
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes the person - No questions asked
|
||||
*/
|
||||
PersonModel.prototype.unguardedDelete = async function () {
|
||||
await this.prisma.person.delete({ here: { id: this.record.id } })
|
||||
this.record = null
|
||||
this.clear = null
|
||||
|
||||
return this.setExists()
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes the person - Checks permissions
|
||||
*/
|
||||
PersonModel.prototype.guardedDelete = async function ({ params, body, 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 && user.level < 8) {
|
||||
return this.setResponse(403, 'insufficientAccessLevel')
|
||||
}
|
||||
|
||||
await this.unguardedDelete()
|
||||
|
||||
return this.setResponse(204, false)
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns record data
|
||||
*/
|
||||
|
|
|
@ -67,7 +67,7 @@ UserModel.prototype.cloak = function (data) {
|
|||
*
|
||||
* Stores result in this.record
|
||||
*/
|
||||
UserModel.prototype.readAsAccount = async function (where) {
|
||||
UserModel.prototype.readForReturn = async function (where) {
|
||||
await this.read(where)
|
||||
|
||||
return this.setResponse(200, false, {
|
||||
|
@ -175,7 +175,7 @@ UserModel.prototype.create = async function ({ body }) {
|
|||
|
||||
// Update username
|
||||
try {
|
||||
await this.safeUpdate({
|
||||
await this.unguardedUpdate({
|
||||
username: `user-${this.record.id}`,
|
||||
lusername: `user-${this.record.id}`,
|
||||
})
|
||||
|
@ -243,7 +243,7 @@ UserModel.prototype.passwordLogin = async function (req) {
|
|||
// Login success
|
||||
if (updatedPasswordField) {
|
||||
// Update the password field with a v3 hash
|
||||
await this.safeUpdate({ password: updatedPasswordField })
|
||||
await this.unguardedUpdate({ password: updatedPasswordField })
|
||||
}
|
||||
|
||||
return this.isOk() ? this.loginOk() : this.setResponse(401, 'loginFailed')
|
||||
|
@ -283,7 +283,7 @@ UserModel.prototype.confirm = async function ({ body, params }) {
|
|||
if (this.error) return this
|
||||
|
||||
// Update user status, consent, and last login
|
||||
await this.safeUpdate({
|
||||
await this.unguardedUpdate({
|
||||
status: 1,
|
||||
consent: body.consent,
|
||||
lastLogin: new Date(),
|
||||
|
@ -298,7 +298,7 @@ UserModel.prototype.confirm = async function ({ body, params }) {
|
|||
* Updates the user data - Used when we create the data ourselves
|
||||
* so we know it's safe
|
||||
*/
|
||||
UserModel.prototype.safeUpdate = async function (data) {
|
||||
UserModel.prototype.unguardedUpdate = async function (data) {
|
||||
try {
|
||||
this.record = await this.prisma.user.update({
|
||||
where: { id: this.record.id },
|
||||
|
@ -318,7 +318,7 @@ UserModel.prototype.safeUpdate = async function (data) {
|
|||
* Updates the user data - Used when we pass through user-provided data
|
||||
* so we can't be certain it's safe
|
||||
*/
|
||||
UserModel.prototype.unsafeUpdate = async function (body) {
|
||||
UserModel.prototype.guardedUpdate = async function (body, user) {
|
||||
if (user.level < 3) return this.setResponse(403, 'insufficientAccessLevel')
|
||||
const data = {}
|
||||
// Bio
|
||||
|
@ -353,7 +353,7 @@ UserModel.prototype.unsafeUpdate = async function (body) {
|
|||
}
|
||||
|
||||
// Now update the record
|
||||
await this.safeUpdate(this.cloak(data))
|
||||
await this.unguardedUpdate(this.cloak(data))
|
||||
|
||||
const isUnitTest = this.isUnitTest(body)
|
||||
if (typeof body.email === 'string' && this.clear.email !== clean(body.email)) {
|
||||
|
@ -399,7 +399,7 @@ UserModel.prototype.unsafeUpdate = async function (body) {
|
|||
|
||||
const data = this.Confirmation.clear.data
|
||||
if (data.email.current === this.clear.email && typeof data.email.new === 'string') {
|
||||
await this.safeUpdate({
|
||||
await this.unguardedUpdate({
|
||||
email: this.encrypt(data.email.new),
|
||||
ehash: hash(clean(data.email.new)),
|
||||
})
|
||||
|
|
|
@ -31,6 +31,14 @@ 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)
|
||||
|
|
|
@ -85,7 +85,6 @@ export const encryption = (stringKey, salt = 'FreeSewing') => {
|
|||
if (!data.iv || typeof data.ct === 'undefined') {
|
||||
throw 'Encrypted data passed to decrypt() was malformed'
|
||||
}
|
||||
|
||||
/*
|
||||
* The thing that does the decrypting
|
||||
*/
|
||||
|
|
|
@ -5,9 +5,9 @@ import { personTests } from './person.mjs'
|
|||
import { setup } from './shared.mjs'
|
||||
|
||||
const runTests = async (...params) => {
|
||||
//await userTests(...params)
|
||||
//await apikeyTests(...params)
|
||||
//await accountTests(...params)
|
||||
await userTests(...params)
|
||||
await apikeyTests(...params)
|
||||
await accountTests(...params)
|
||||
await personTests(...params)
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,10 @@ export const personTests = async (chai, config, expect, store) => {
|
|||
jwt: {},
|
||||
key: {},
|
||||
}
|
||||
store.altperson = {
|
||||
jwt: {},
|
||||
key: {},
|
||||
}
|
||||
|
||||
for (const auth of ['jwt', 'key']) {
|
||||
describe(`${store.icon('person', auth)} Person tests (${auth})`, () => {
|
||||
|
@ -146,13 +150,169 @@ export const personTests = async (chai, config, expect, store) => {
|
|||
})
|
||||
})
|
||||
}
|
||||
|
||||
it(`${store.icon(
|
||||
'person',
|
||||
auth
|
||||
)} Should not set an non-existing measurement (${auth})`, (done) => {
|
||||
chai
|
||||
.request(config.api)
|
||||
.put(`/people/${store.person[auth].id}/${auth}`)
|
||||
.set(
|
||||
'Authorization',
|
||||
auth === 'jwt'
|
||||
? 'Bearer ' + store.account.token
|
||||
: 'Basic ' +
|
||||
new Buffer(`${store.account.apikey.key}:${store.account.apikey.secret}`).toString(
|
||||
'base64'
|
||||
)
|
||||
)
|
||||
.send({
|
||||
measies: {
|
||||
ankle: 320,
|
||||
potatoe: 12,
|
||||
},
|
||||
})
|
||||
.end((err, res) => {
|
||||
expect(err === null).to.equal(true)
|
||||
expect(res.status).to.equal(200)
|
||||
expect(res.body.result).to.equal(`success`)
|
||||
expect(res.body.person.measies.ankle).to.equal(320)
|
||||
expect(typeof res.body.person.measies.potatoe).to.equal('undefined')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it(`${store.icon('person', auth)} Should clear a measurement (${auth})`, (done) => {
|
||||
chai
|
||||
.request(config.api)
|
||||
.put(`/people/${store.person[auth].id}/${auth}`)
|
||||
.set(
|
||||
'Authorization',
|
||||
auth === 'jwt'
|
||||
? 'Bearer ' + store.account.token
|
||||
: 'Basic ' +
|
||||
new Buffer(`${store.account.apikey.key}:${store.account.apikey.secret}`).toString(
|
||||
'base64'
|
||||
)
|
||||
)
|
||||
.send({
|
||||
measies: {
|
||||
chest: null,
|
||||
},
|
||||
})
|
||||
.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.person.measies.chest).to.equal('undefined')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it(`${store.icon('person', auth)} Should read a person (${auth})`, (done) => {
|
||||
chai
|
||||
.request(config.api)
|
||||
.get(`/people/${store.person[auth].id}/${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.person.measies).to.equal('object')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it(`${store.icon(
|
||||
'person',
|
||||
auth
|
||||
)} Should not allow reading another user's person (${auth})`, (done) => {
|
||||
chai
|
||||
.request(config.api)
|
||||
.get(`/people/${store.person[auth].id}/${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) => {
|
||||
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()
|
||||
})
|
||||
})
|
||||
|
||||
it(`${store.icon(
|
||||
'person',
|
||||
auth
|
||||
)} Should not allow updating another user's person (${auth})`, (done) => {
|
||||
chai
|
||||
.request(config.api)
|
||||
.put(`/people/${store.person[auth].id}/${auth}`)
|
||||
.set(
|
||||
'Authorization',
|
||||
auth === 'jwt'
|
||||
? 'Bearer ' + store.altaccount.token
|
||||
: 'Basic ' +
|
||||
new Buffer(
|
||||
`${store.altaccount.apikey.key}:${store.altaccount.apikey.secret}`
|
||||
).toString('base64')
|
||||
)
|
||||
.send({
|
||||
bio: 'I have been taken over',
|
||||
})
|
||||
.end((err, res) => {
|
||||
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()
|
||||
})
|
||||
})
|
||||
|
||||
it(`${store.icon(
|
||||
'person',
|
||||
auth
|
||||
)} Should not allow removing another user's person (${auth})`, (done) => {
|
||||
chai
|
||||
.request(config.api)
|
||||
.delete(`/people/${store.person[auth].id}/${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) => {
|
||||
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:
|
||||
// - Add non-existing measurement
|
||||
// - Clear measurement
|
||||
// - List/get person
|
||||
// - Clone person
|
||||
// - Clone person accross accounts of they are public
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,11 @@ export const setup = async () => {
|
|||
language: 'en',
|
||||
password: randomString(),
|
||||
},
|
||||
altaccount: {
|
||||
email: `test_${randomString()}@${config.tests.domain}`,
|
||||
language: 'en',
|
||||
password: randomString(),
|
||||
},
|
||||
icons: {
|
||||
user: '🧑 ',
|
||||
jwt: '🎫 ',
|
||||
|
@ -32,32 +37,33 @@ export const setup = async () => {
|
|||
}
|
||||
store.icon = (icon1, icon2 = false) => store.icons[icon1] + (icon2 ? store.icons[icon2] : '')
|
||||
|
||||
for (const acc of ['account', 'altaccount']) {
|
||||
// Get confirmation ID
|
||||
let result
|
||||
try {
|
||||
result = await axios.post(`${store.config.api}/signup`, {
|
||||
email: store.account.email,
|
||||
language: store.account.language,
|
||||
email: store[acc].email,
|
||||
language: store[acc].language,
|
||||
unittest: true,
|
||||
})
|
||||
} catch (err) {
|
||||
console.log('Failed at first setup request', err)
|
||||
process.exit()
|
||||
}
|
||||
store.account.confirmation = result.data.confirmation
|
||||
store[acc].confirmation = result.data.confirmation
|
||||
|
||||
// Confirm account
|
||||
try {
|
||||
result = await axios.post(`${store.config.api}/confirm/signup/${store.account.confirmation}`, {
|
||||
result = await axios.post(`${store.config.api}/confirm/signup/${store[acc].confirmation}`, {
|
||||
consent: 1,
|
||||
})
|
||||
} catch (err) {
|
||||
console.log('Failed at account confirmation request', err)
|
||||
process.exit()
|
||||
}
|
||||
store.account.token = result.data.token
|
||||
store.account.username = result.data.account.username
|
||||
store.account.userid = result.data.account.id
|
||||
store[acc].token = result.data.token
|
||||
store[acc].username = result.data.account.username
|
||||
store[acc].userid = result.data.account.id
|
||||
|
||||
// Create API key
|
||||
try {
|
||||
|
@ -70,7 +76,7 @@ export const setup = async () => {
|
|||
},
|
||||
{
|
||||
headers: {
|
||||
authorization: `Bearer ${store.account.token}`,
|
||||
authorization: `Bearer ${store[acc].token}`,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
@ -78,7 +84,8 @@ export const setup = async () => {
|
|||
console.log('Failed at API key creation request', err)
|
||||
process.exit()
|
||||
}
|
||||
store.account.apikey = result.data.apikey
|
||||
store[acc].apikey = result.data.apikey
|
||||
}
|
||||
|
||||
return { chai, config, expect, store }
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue