feat(backend): Added more routes
This commit is contained in:
parent
cbe95701c5
commit
1b499effdf
6 changed files with 115 additions and 17 deletions
|
@ -514,3 +514,52 @@ paths['/users/{username}'] = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check whether a username is available
|
||||||
|
const checkUsername = "Little Miss Can't Be Wrong"
|
||||||
|
paths['/available/username'] = {
|
||||||
|
post: {
|
||||||
|
tags: ['Users'],
|
||||||
|
summary: `Checks whether a username is available`,
|
||||||
|
description:
|
||||||
|
'This allows a background check to see whether a username is available during signup',
|
||||||
|
requestBody: {
|
||||||
|
required: true,
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
username: {
|
||||||
|
type: 'string',
|
||||||
|
description: 'The username to check for availability',
|
||||||
|
example: checkUsername,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description:
|
||||||
|
'**Success - Username is NOT available**\n\n' +
|
||||||
|
'Status code `200` indicates that the username exists.',
|
||||||
|
...jsonResponse({
|
||||||
|
result: 'success',
|
||||||
|
username: checkUsername,
|
||||||
|
available: false,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
401: response.status['401'],
|
||||||
|
403: {
|
||||||
|
...response.status['403'],
|
||||||
|
description:
|
||||||
|
response.status['403'].description +
|
||||||
|
errorExamples(['accountStatusLacking', 'insufficientAccessLevel']),
|
||||||
|
},
|
||||||
|
404: response.status['404'],
|
||||||
|
500: response.status['500'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
|
@ -78,3 +78,23 @@ UsersController.prototype.updateMfa = async (req, res, tools) => {
|
||||||
|
|
||||||
return User.sendResponse(res)
|
return User.sendResponse(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks whether a submitted username is available
|
||||||
|
*
|
||||||
|
* See: https://freesewing.dev/reference/backend/api
|
||||||
|
*/
|
||||||
|
UsersController.prototype.isUsernameAvailable = async (req, res, tools) => {
|
||||||
|
const User = new UserModel(tools)
|
||||||
|
await User.find(req.body)
|
||||||
|
|
||||||
|
if (User.exists)
|
||||||
|
User.setResponse(200, false, {
|
||||||
|
result: 'success',
|
||||||
|
username: req.body?.username,
|
||||||
|
available: false,
|
||||||
|
})
|
||||||
|
else User.setResponse(404)
|
||||||
|
|
||||||
|
return User.sendResponse(res)
|
||||||
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ ApikeyModel.prototype.guardedRead = async function ({ params, user }) {
|
||||||
if (user.iss && user.status < 1) return this.setResponse(403, 'accountStatusLacking')
|
if (user.iss && user.status < 1) return this.setResponse(403, 'accountStatusLacking')
|
||||||
|
|
||||||
await this.unguardedRead({ id: params.id })
|
await this.unguardedRead({ id: params.id })
|
||||||
if (!this.record) return this.setResponse(404, 'apikeyNotFound')
|
if (!this.record) return this.setResponse(404)
|
||||||
|
|
||||||
if (this.record.userId !== user.uid) {
|
if (this.record.userId !== user.uid) {
|
||||||
// Not own key - only admin can do that
|
// Not own key - only admin can do that
|
||||||
|
@ -76,7 +76,7 @@ ApikeyModel.prototype.guardedDelete = async function ({ params, user }) {
|
||||||
if (user.iss && user.status < 1) return this.setResponse(403, 'accountStatusLacking')
|
if (user.iss && user.status < 1) return this.setResponse(403, 'accountStatusLacking')
|
||||||
|
|
||||||
await this.unguardedRead({ id: params.id })
|
await this.unguardedRead({ id: params.id })
|
||||||
if (!this.record) return this.setResponse(404, 'apikeyNotFound')
|
if (!this.record) return this.setResponse(404)
|
||||||
|
|
||||||
if (this.record.userId !== user.uid) {
|
if (this.record.userId !== user.uid) {
|
||||||
// Not own key - only admin can do that
|
// Not own key - only admin can do that
|
||||||
|
|
|
@ -265,7 +265,7 @@ UserModel.prototype.passwordLogin = async function (req) {
|
||||||
* Confirms a user account
|
* Confirms a user account
|
||||||
*/
|
*/
|
||||||
UserModel.prototype.confirm = async function ({ body, params }) {
|
UserModel.prototype.confirm = async function ({ body, params }) {
|
||||||
if (!params.id) return this.setResponse(404, 'confirmationIdMissing')
|
if (!params.id) return this.setResponse(404)
|
||||||
if (Object.keys(body) < 1) return this.setResponse(400, 'postBodyMissing')
|
if (Object.keys(body) < 1) return this.setResponse(400, 'postBodyMissing')
|
||||||
if (!body.consent || typeof body.consent !== 'number' || body.consent < 1)
|
if (!body.consent || typeof body.consent !== 'number' || body.consent < 1)
|
||||||
return this.setResponse(400, 'consentRequired')
|
return this.setResponse(400, 'consentRequired')
|
||||||
|
@ -275,20 +275,18 @@ UserModel.prototype.confirm = async function ({ body, params }) {
|
||||||
|
|
||||||
if (!this.Confirmation.exists) {
|
if (!this.Confirmation.exists) {
|
||||||
log.warn(err, `Could not find confirmation id ${params.id}`)
|
log.warn(err, `Could not find confirmation id ${params.id}`)
|
||||||
return this.setResponse(404, 'failedToFindConfirmationId')
|
return this.setResponse(404)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.Confirmation.record.type !== 'signup') {
|
if (this.Confirmation.record.type !== 'signup') {
|
||||||
log.warn(err, `Confirmation mismatch; ${params.id} is not a signup id`)
|
log.warn(err, `Confirmation mismatch; ${params.id} is not a signup id`)
|
||||||
return this.setResponse(404, 'confirmationIdTypeMismatch')
|
return this.setResponse(404)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.error) return this
|
if (this.error) return this
|
||||||
const data = this.Confirmation.clear.data
|
const data = this.Confirmation.clear.data
|
||||||
if (data.ehash !== this.Confirmation.record.user.ehash)
|
if (data.ehash !== this.Confirmation.record.user.ehash) return this.setResponse(404)
|
||||||
return this.setResponse(404, 'confirmationEhashMismatch')
|
if (data.id !== this.Confirmation.record.user.id) return this.setResponse(404)
|
||||||
if (data.id !== this.Confirmation.record.user.id)
|
|
||||||
return this.setResponse(404, 'confirmationUserIdMismatch')
|
|
||||||
|
|
||||||
// Load user
|
// Load user
|
||||||
await this.read({ id: this.Confirmation.record.user.id })
|
await this.read({ id: this.Confirmation.record.user.id })
|
||||||
|
@ -404,12 +402,12 @@ UserModel.prototype.guardedUpdate = async function ({ body, user }) {
|
||||||
|
|
||||||
if (!this.Confirmation.exists) {
|
if (!this.Confirmation.exists) {
|
||||||
log.warn(err, `Could not find confirmation id ${params.id}`)
|
log.warn(err, `Could not find confirmation id ${params.id}`)
|
||||||
return this.setResponse(404, 'failedToFindConfirmationId')
|
return this.setResponse(404)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.Confirmation.record.type !== 'emailchange') {
|
if (this.Confirmation.record.type !== 'emailchange') {
|
||||||
log.warn(err, `Confirmation mismatch; ${params.id} is not an emailchange id`)
|
log.warn(err, `Confirmation mismatch; ${params.id} is not an emailchange id`)
|
||||||
return this.setResponse(404, 'confirmationIdTypeMismatch')
|
return this.setResponse(404)
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = this.Confirmation.clear.data
|
const data = this.Confirmation.clear.data
|
||||||
|
@ -570,6 +568,7 @@ UserModel.prototype.setResponse = function (status = 200, error = false, data =
|
||||||
this.response.body.result = 'error'
|
this.response.body.result = 'error'
|
||||||
this.error = true
|
this.error = true
|
||||||
} else this.error = false
|
} else this.error = false
|
||||||
|
if (status === 404) this.response.body = null
|
||||||
|
|
||||||
return this.setExists()
|
return this.setExists()
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,10 @@ export function usersRoutes(tools) {
|
||||||
app.post('/account/mfa/key', passport.authenticate(...bsc), (req, res) =>
|
app.post('/account/mfa/key', passport.authenticate(...bsc), (req, res) =>
|
||||||
Users.updateMfa(req, res, tools)
|
Users.updateMfa(req, res, tools)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Check whether a username is available
|
||||||
|
app.post('/available/username', (req, res) => Users.isUsernameAvailable(req, res, tools))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
// Remove account
|
// Remove account
|
||||||
|
@ -95,11 +99,5 @@ export function usersRoutes(tools) {
|
||||||
(req, res) => User.readProfile(req, res, params)
|
(req, res) => User.readProfile(req, res, params)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Check whether a username is available
|
|
||||||
app.post(
|
|
||||||
'/available/username',
|
|
||||||
passport.authenticate('jwt', { session: false }),
|
|
||||||
(req, res) => User.isUsernameAvailable(req, res, params)
|
|
||||||
)
|
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,4 +258,36 @@ export const userTests = async (chai, config, expect, store) => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe(`${store.icon('user')} Check for available usernames`, () => {
|
||||||
|
it(`${store.icon('user')} Should find a username is available`, (done) => {
|
||||||
|
chai
|
||||||
|
.request(config.api)
|
||||||
|
.post(`/available/username`)
|
||||||
|
.send({
|
||||||
|
username: 'haochi',
|
||||||
|
})
|
||||||
|
.end((err, res) => {
|
||||||
|
expect(err === null).to.equal(true)
|
||||||
|
expect(res.status).to.equal(404)
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
it(`${store.icon('user')} Should find a username is not available`, (done) => {
|
||||||
|
chai
|
||||||
|
.request(config.api)
|
||||||
|
.post(`/available/username`)
|
||||||
|
.send({
|
||||||
|
username: store.account.username,
|
||||||
|
})
|
||||||
|
.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.available).to.equal(false)
|
||||||
|
expect(res.body.username).to.equal(store.account.username)
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue