wip(backend): Renamed auth user for clarity
This commit is contained in:
parent
0313bb4572
commit
d63b7e5397
3 changed files with 54 additions and 79 deletions
|
@ -1,10 +1,5 @@
|
||||||
//import { log, email, ehash, newHandle, uniqueHandle } from '../utils'
|
|
||||||
import jwt from 'jsonwebtoken'
|
import jwt from 'jsonwebtoken'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
//import path from 'path'
|
|
||||||
//import fs from 'fs'
|
|
||||||
import Zip from 'jszip'
|
|
||||||
//import rimraf from 'rimraf'
|
|
||||||
import { hash, hashPassword, randomString, verifyPassword } from '../utils/crypto.mjs'
|
import { hash, hashPassword, randomString, verifyPassword } from '../utils/crypto.mjs'
|
||||||
import { clean, asJson } from '../utils/index.mjs'
|
import { clean, asJson } from '../utils/index.mjs'
|
||||||
import { getUserAvatar } from '../utils/sanity.mjs'
|
import { getUserAvatar } from '../utils/sanity.mjs'
|
||||||
|
|
|
@ -65,7 +65,7 @@ ApikeyModel.prototype.create = async function ({ body, user }) {
|
||||||
|
|
||||||
// Load user making the call
|
// Load user making the call
|
||||||
await this.User.loadAuthenticatedUser(user)
|
await this.User.loadAuthenticatedUser(user)
|
||||||
if (body.level > this.config.roles.levels[this.User.user.role])
|
if (body.level > this.config.roles.levels[this.User.authenticatedUser.role])
|
||||||
return this.setResponse(400, 'keyLevelExceedsRoleLevel')
|
return this.setResponse(400, 'keyLevelExceedsRoleLevel')
|
||||||
|
|
||||||
// Generate api secret
|
// Generate api secret
|
||||||
|
@ -103,7 +103,7 @@ ApikeyModel.prototype.___read = async function ({ user, params }) {
|
||||||
// Load user making the call
|
// Load user making the call
|
||||||
await this.User.loadAuthenticatedUser(user)
|
await this.User.loadAuthenticatedUser(user)
|
||||||
|
|
||||||
const key = this.User.user.apikeys.filter((key) => key.id === params.id)
|
const key = this.User.authenticatedUser.apikeys.filter((key) => key.id === params.id)
|
||||||
|
|
||||||
return key.length === 1
|
return key.length === 1
|
||||||
? this.setResponse(200, 'success', {
|
? this.setResponse(200, 'success', {
|
||||||
|
|
|
@ -1,15 +1,8 @@
|
||||||
//import jwt from 'jsonwebtoken'
|
|
||||||
//import axios from 'axios'
|
|
||||||
//import { hash, hashPassword, randomString, verifyPassword } from '../utils/crypto.mjs'
|
|
||||||
//import { clean, asJson } from '../utils/index.mjs'
|
|
||||||
//import { getUserAvatar } from '../utils/sanity.mjs'
|
|
||||||
import { log } from '../utils/log.mjs'
|
import { log } from '../utils/log.mjs'
|
||||||
import { hash, hashPassword, randomString, verifyPassword } from '../utils/crypto.mjs'
|
import { hash, hashPassword, randomString, verifyPassword } from '../utils/crypto.mjs'
|
||||||
import { clean, asJson } from '../utils/index.mjs'
|
import { clean, asJson } from '../utils/index.mjs'
|
||||||
import { ConfirmationModel } from './confirmation.mjs'
|
import { ConfirmationModel } from './confirmation.mjs'
|
||||||
import { emailTemplate } from '../utils/email.mjs'
|
import { emailTemplate } from '../utils/email.mjs'
|
||||||
// import { emailTemplate } from '../utils/email.mjs'
|
|
||||||
//import set from 'lodash.set'
|
|
||||||
|
|
||||||
export function UserModel(tools) {
|
export function UserModel(tools) {
|
||||||
this.config = tools.config
|
this.config = tools.config
|
||||||
|
@ -22,6 +15,11 @@ export function UserModel(tools) {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Loads a user from the database based on the where clause you pass it
|
||||||
|
*
|
||||||
|
* Stores result in this.record
|
||||||
|
*/
|
||||||
UserModel.prototype.load = async function (where) {
|
UserModel.prototype.load = async function (where) {
|
||||||
this.record = await this.prisma.user.findUnique({ where })
|
this.record = await this.prisma.user.findUnique({ where })
|
||||||
if (this.record?.email) this.email = this.decrypt(this.record.email)
|
if (this.record?.email) this.email = this.decrypt(this.record.email)
|
||||||
|
@ -29,10 +27,15 @@ UserModel.prototype.load = async function (where) {
|
||||||
return this.setExists()
|
return this.setExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Loads the user that is making the API request
|
||||||
|
*
|
||||||
|
* Stores result in this.authenticatedUser
|
||||||
|
*/
|
||||||
UserModel.prototype.loadAuthenticatedUser = async function (user) {
|
UserModel.prototype.loadAuthenticatedUser = async function (user) {
|
||||||
if (!user) return this
|
if (!user) return this
|
||||||
const where = user?.apikey ? { id: user.userId } : { id: user._id }
|
const where = user?.apikey ? { id: user.userId } : { id: user._id }
|
||||||
this.user = await this.prisma.user.findUnique({
|
this.authenticatedUser = await this.prisma.user.findUnique({
|
||||||
where,
|
where,
|
||||||
include: {
|
include: {
|
||||||
apikeys: true,
|
apikeys: true,
|
||||||
|
@ -42,29 +45,21 @@ UserModel.prototype.loadAuthenticatedUser = async function (user) {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks this.record and sets a boolean to indicate whether
|
||||||
|
* the user exists or not
|
||||||
|
*
|
||||||
|
* Stores result in this.exists
|
||||||
|
*/
|
||||||
UserModel.prototype.setExists = function () {
|
UserModel.prototype.setExists = function () {
|
||||||
this.exists = this.record ? true : false
|
this.exists = this.record ? true : false
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
UserModel.prototype.setResponse = function (status = 200, error = false, data = {}) {
|
/*
|
||||||
this.response = {
|
* Creates a user+confirmation and sends out signup email
|
||||||
status,
|
*/
|
||||||
body: {
|
|
||||||
result: 'success',
|
|
||||||
...data,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if (status > 201) {
|
|
||||||
this.response.body.error = error
|
|
||||||
this.response.body.result = 'error'
|
|
||||||
this.error = true
|
|
||||||
} else this.error = false
|
|
||||||
|
|
||||||
return this.setExists()
|
|
||||||
}
|
|
||||||
|
|
||||||
UserModel.prototype.create = async function (body) {
|
UserModel.prototype.create = async function (body) {
|
||||||
if (Object.keys(body) < 1) return this.setResponse(400, 'postBodyMissing')
|
if (Object.keys(body) < 1) return this.setResponse(400, 'postBodyMissing')
|
||||||
if (!body.email) return this.setResponse(400, 'emailMissing')
|
if (!body.email) return this.setResponse(400, 'emailMissing')
|
||||||
|
@ -128,6 +123,10 @@ UserModel.prototype.create = async function (body) {
|
||||||
: this.setResponse(201, false, { email: this.email })
|
: this.setResponse(201, false, { email: this.email })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sends out signup email
|
||||||
|
* FIXME: Move to utils
|
||||||
|
*/
|
||||||
UserModel.prototype.sendSignupEmail = async function () {
|
UserModel.prototype.sendSignupEmail = async function () {
|
||||||
try {
|
try {
|
||||||
this.confirmationSent = await this.mailer.send(
|
this.confirmationSent = await this.mailer.send(
|
||||||
|
@ -142,6 +141,9 @@ UserModel.prototype.sendSignupEmail = async function () {
|
||||||
return this.setResponse(200)
|
return this.setResponse(200)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Updates the user data
|
||||||
|
*/
|
||||||
UserModel.prototype.update = async function (data) {
|
UserModel.prototype.update = async function (data) {
|
||||||
try {
|
try {
|
||||||
this.record = await this.prisma.user.update({
|
this.record = await this.prisma.user.update({
|
||||||
|
@ -157,53 +159,31 @@ UserModel.prototype.update = async function (data) {
|
||||||
return this.setResponse(200)
|
return this.setResponse(200)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper method to set the response code, result, and body
|
||||||
|
*
|
||||||
|
* Will be used by this.sendResponse()
|
||||||
|
*/
|
||||||
|
UserModel.prototype.setResponse = function (status = 200, error = false, data = {}) {
|
||||||
|
this.response = {
|
||||||
|
status,
|
||||||
|
body: {
|
||||||
|
result: 'success',
|
||||||
|
...data,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if (status > 201) {
|
||||||
|
this.response.body.error = error
|
||||||
|
this.response.body.result = 'error'
|
||||||
|
this.error = true
|
||||||
|
} else this.error = false
|
||||||
|
|
||||||
|
return this.setExists()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper method to send response
|
||||||
|
*/
|
||||||
UserModel.prototype.sendResponse = async function (res) {
|
UserModel.prototype.sendResponse = async function (res) {
|
||||||
return res.status(this.response.status).send(this.response.body)
|
return res.status(this.response.status).send(this.response.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
UserModel.prototype.createApikey = async function ({ body, user }) {
|
|
||||||
if (Object.keys(body) < 1) return this.setResponse(400, 'postBodyMissing')
|
|
||||||
if (!body.name) return this.setResponse(400, 'nameMissing')
|
|
||||||
if (!body.level) return this.setResponse(400, 'levelMissing')
|
|
||||||
if (typeof body.level !== 'number') return this.setResponse(400, 'levelNotNumeric')
|
|
||||||
if (!this.config.apikeys.levels.includes(body.level)) return this.setResponse(400, 'invalidLevel')
|
|
||||||
if (!body.expiresIn) return this.setResponse(400, 'expiresInMissing')
|
|
||||||
if (typeof body.expiresIn !== 'number') return this.setResponse(400, 'expiresInNotNumeric')
|
|
||||||
if (body.expiresIn > this.config.apikeys.maxExpirySeconds)
|
|
||||||
return this.setResponse(400, 'expiresInHigherThanMaximum')
|
|
||||||
|
|
||||||
// Load user making the call
|
|
||||||
await this.loadAuthenticatedUser(user)
|
|
||||||
if (body.level > this.config.roles.levels[this.user.role])
|
|
||||||
return this.setResponse(400, 'keyLevelExceedsRoleLevel')
|
|
||||||
|
|
||||||
// Generate api secret
|
|
||||||
const secret = randomString(32)
|
|
||||||
const expiresAt = new Date(Date.now() + body.expiresIn * 1000)
|
|
||||||
|
|
||||||
try {
|
|
||||||
this.record = await this.prisma.apikey.create({
|
|
||||||
data: {
|
|
||||||
expiresAt,
|
|
||||||
name: body.name,
|
|
||||||
level: body.level,
|
|
||||||
secret: asJson(hashPassword(secret)),
|
|
||||||
userId: user._id,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
} catch (err) {
|
|
||||||
log.warn(err, 'Could not create apikey')
|
|
||||||
return this.setResponse(500, 'createApikeyFailed')
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.setResponse(200, 'success', {
|
|
||||||
apikey: {
|
|
||||||
key: this.record.id,
|
|
||||||
secret,
|
|
||||||
level: this.record.level,
|
|
||||||
expiresAt: this.record.expiresAt,
|
|
||||||
name: this.record.name,
|
|
||||||
userId: this.record.userId,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue