wip(backend): Better handling of data
This commit is contained in:
parent
819656815c
commit
19050ce3b7
7 changed files with 141 additions and 161 deletions
|
@ -7,42 +7,6 @@ import { log } from '../utils/log.mjs'
|
||||||
import set from 'lodash.set'
|
import set from 'lodash.set'
|
||||||
import { UserModel } from '../models/user.mjs'
|
import { UserModel } from '../models/user.mjs'
|
||||||
|
|
||||||
/*
|
|
||||||
* Prisma is not an ORM and we can't attach methods to the model
|
|
||||||
* So here's a bunch of helper methods that expect a user object
|
|
||||||
* as input
|
|
||||||
*/
|
|
||||||
const asAccount = (user, decrypt) => ({
|
|
||||||
id: user.id,
|
|
||||||
consent: user.consent,
|
|
||||||
createdAt: user.createdAt,
|
|
||||||
data: user.data,
|
|
||||||
email: decrypt(user.email),
|
|
||||||
initial: decrypt(user.initial),
|
|
||||||
lastLogin: user.lastLogin,
|
|
||||||
newsletter: user.newsletter,
|
|
||||||
patron: user.patron,
|
|
||||||
role: user.role,
|
|
||||||
status: user.status,
|
|
||||||
updatedAt: user.updatedAt,
|
|
||||||
username: user.username,
|
|
||||||
lusername: user.lusername,
|
|
||||||
})
|
|
||||||
|
|
||||||
const getToken = (user, config) =>
|
|
||||||
jwt.sign(
|
|
||||||
{
|
|
||||||
_id: user.id,
|
|
||||||
username: user.username,
|
|
||||||
role: user.role,
|
|
||||||
status: user.status,
|
|
||||||
aud: config.jwt.audience,
|
|
||||||
iss: config.jwt.issuer,
|
|
||||||
},
|
|
||||||
config.jwt.secretOrKey,
|
|
||||||
{ expiresIn: config.jwt.expiresIn }
|
|
||||||
)
|
|
||||||
|
|
||||||
const isUsernameAvailable = async (username, prisma) => {
|
const isUsernameAvailable = async (username, prisma) => {
|
||||||
const user = await prisme.user.findUnique({
|
const user = await prisme.user.findUnique({
|
||||||
where: {
|
where: {
|
||||||
|
@ -99,98 +63,20 @@ UserController.prototype.login = async function (req, res, tools) {
|
||||||
}
|
}
|
||||||
|
|
||||||
UserController.prototype.whoami = async (req, res, tools) => {
|
UserController.prototype.whoami = async (req, res, tools) => {
|
||||||
if (!req.user?._id) return res.status(400).send({ error: 'bearerMissing', result })
|
const User = new UserModel(tools)
|
||||||
|
await User.readAsAccount({ id: req.user.uid })
|
||||||
|
|
||||||
// Destructure what we need from tools
|
return User.sendResponse(res)
|
||||||
const { prisma, decrypt } = tools
|
|
||||||
|
|
||||||
// Retrieve user account
|
|
||||||
let account
|
|
||||||
try {
|
|
||||||
account = await prisma.user.findUnique({
|
|
||||||
where: {
|
|
||||||
id: req.user._id,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
} catch (err) {
|
|
||||||
log.warn(err, `Could not lookup user id ${req.user._id} from token data`)
|
|
||||||
return res.status(404).send({ error: 'failedToRetrieveUserIdFromTokenData', result })
|
|
||||||
}
|
|
||||||
if (!account) {
|
|
||||||
log.warn(err, `Could not find user id ${req.user._id} from token data`)
|
|
||||||
return res.status(404).send({ error: 'failedToLoadUserFromTokenData', result })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return account data
|
|
||||||
return res.status(200).send({
|
|
||||||
result: 'success',
|
|
||||||
account: asAccount({ ...account }, decrypt),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UserController.prototype.update = async (req, res, tools) => {
|
UserController.prototype.update = async (req, res, tools) => {
|
||||||
console.log('update please')
|
const User = new UserModel(tools)
|
||||||
|
await User.read({ id: req.user.uid })
|
||||||
// Destructure what we need from tools
|
|
||||||
const { prisma, decrypt } = tools
|
|
||||||
|
|
||||||
// Retrieve user account
|
|
||||||
let account
|
|
||||||
try {
|
|
||||||
account = await prisma.user.findUnique({
|
|
||||||
where: {
|
|
||||||
id: req.user._id,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
} catch (err) {
|
|
||||||
log.warn(err, `Could not lookup user id ${req.user._id} from token data`)
|
|
||||||
return res.status(404).send({ error: 'failedToRetrieveUserIdFromTokenData', result })
|
|
||||||
}
|
|
||||||
if (!account) {
|
|
||||||
log.warn(err, `Could not find user id ${req.user._id} from token data`)
|
|
||||||
return res.status(404).send({ error: 'failedToLoadUserFromTokenData', result })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Account loaded - Handle various updates
|
|
||||||
const data = {}
|
|
||||||
// Username
|
|
||||||
if (req.body.username) {
|
|
||||||
if (!isUsernameAvailable(req.body.username, prisma)) {
|
|
||||||
return res.status(400).send({ error: 'usernameTaken', result })
|
|
||||||
}
|
|
||||||
data.username = req.body.username
|
|
||||||
data.lusername = data.username.toLowerCase()
|
|
||||||
}
|
|
||||||
// Newsletter
|
|
||||||
if (req.body.newsletter === false) data.newsletter = false
|
|
||||||
if (req.body.newsletter === true) data.newsletter = true
|
|
||||||
// Consent
|
|
||||||
if (typeof req.body.consent !== 'undefined') data.consent = req.body.consent
|
|
||||||
// Bio
|
|
||||||
if (typeof req.body.bio === 'string') userData.bio = req.body.bio
|
|
||||||
// Password
|
|
||||||
if (typeof req.body.password === 'string')
|
|
||||||
userData.password = asJson(hashPassword(req.body.password))
|
|
||||||
// Data
|
|
||||||
const userData = JSON.parse(account.data)
|
|
||||||
const uhash = hash(account.data)
|
|
||||||
if (typeof req.body.language === 'string') set(userData, 'settings.language', req.body.language)
|
|
||||||
if (typeof req.body.units === 'string') set(userData, 'settings.units', req.body.units)
|
|
||||||
if (typeof req.body.github === 'string') set(userData, 'settings.social.github', req.body.github)
|
|
||||||
if (typeof req.body.twitter === 'string')
|
|
||||||
set(userData, 'settings.social.twitter', req.body.twitter)
|
|
||||||
if (typeof req.body.instagram === 'string')
|
|
||||||
set(userData, 'settings.social.instagram', req.body.instagram)
|
|
||||||
// Did data change?
|
|
||||||
if (uhash !== hash(userData)) data.data = JSON.stringify(userData)
|
|
||||||
|
|
||||||
// Commit
|
// Commit
|
||||||
prisma.user.update({
|
//await User.update({ id: req.user.uid }, req.body)
|
||||||
where: { id: account.id },
|
|
||||||
data,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Email change requires confirmation
|
// Email change requires confirmation
|
||||||
|
/*
|
||||||
if (typeof req.body.email === 'string') {
|
if (typeof req.body.email === 'string') {
|
||||||
const currentEmail = decrypt(account.email)
|
const currentEmail = decrypt(account.email)
|
||||||
if (req.body.email !== currentEmail) {
|
if (req.body.email !== currentEmail) {
|
||||||
|
@ -249,6 +135,7 @@ UserController.prototype.update = async (req, res, tools) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// Now handle the
|
// Now handle the
|
||||||
/*
|
/*
|
||||||
else if (typeof data.email === 'string' && data.email !== user.email) {
|
else if (typeof data.email === 'string' && data.email !== user.email) {
|
||||||
|
|
|
@ -15,7 +15,9 @@ function loadPassportMiddleware(passport, tools) {
|
||||||
new http.BasicStrategy(async (key, secret, done) => {
|
new http.BasicStrategy(async (key, secret, done) => {
|
||||||
const Apikey = new ApikeyModel(tools)
|
const Apikey = new ApikeyModel(tools)
|
||||||
await Apikey.verify(key, secret)
|
await Apikey.verify(key, secret)
|
||||||
return Apikey.verified ? done(null, { ...Apikey.record, apikey: true }) : done(false)
|
return Apikey.verified
|
||||||
|
? done(null, { ...Apikey.record, apikey: true, uid: Apikey.record.userId })
|
||||||
|
: done(false)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
passport.use(
|
passport.use(
|
||||||
|
@ -25,7 +27,7 @@ function loadPassportMiddleware(passport, tools) {
|
||||||
...tools.config.jwt,
|
...tools.config.jwt,
|
||||||
},
|
},
|
||||||
(jwt_payload, done) => {
|
(jwt_payload, done) => {
|
||||||
return done(null, jwt_payload)
|
return done(null, { ...jwt_payload, uid: jwt_payload._id })
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -125,7 +125,7 @@ ApikeyModel.prototype.create = async function ({ body, user }) {
|
||||||
name: body.name,
|
name: body.name,
|
||||||
level: body.level,
|
level: body.level,
|
||||||
secret: asJson(hashPassword(secret)),
|
secret: asJson(hashPassword(secret)),
|
||||||
userId: user._id || user.userId,
|
userId: user.uid,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
@ -4,6 +4,9 @@ import { hash } from '../utils/crypto.mjs'
|
||||||
export function ConfirmationModel(tools) {
|
export function ConfirmationModel(tools) {
|
||||||
this.config = tools.config
|
this.config = tools.config
|
||||||
this.prisma = tools.prisma
|
this.prisma = tools.prisma
|
||||||
|
this.decrypt = tools.decrypt
|
||||||
|
this.encrypt = tools.encrypt
|
||||||
|
this.clear = {}
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -15,6 +18,7 @@ ConfirmationModel.prototype.read = async function (where) {
|
||||||
user: true,
|
user: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
this.clear.data = this.record?.data ? this.decrypt(this.record.data) : {}
|
||||||
|
|
||||||
return this.setExists()
|
return this.setExists()
|
||||||
}
|
}
|
||||||
|
@ -63,7 +67,9 @@ ConfirmationModel.prototype.setResponse = function (
|
||||||
|
|
||||||
ConfirmationModel.prototype.create = async function (data = {}) {
|
ConfirmationModel.prototype.create = async function (data = {}) {
|
||||||
try {
|
try {
|
||||||
this.record = await this.prisma.confirmation.create({ data })
|
this.record = await this.prisma.confirmation.create({
|
||||||
|
data: { ...data, data: this.encrypt(data.data) },
|
||||||
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.warn(err, 'Could not create confirmation record')
|
log.warn(err, 'Could not create confirmation record')
|
||||||
return this.setResponse(500, 'createConfirmationFailed')
|
return this.setResponse(500, 'createConfirmationFailed')
|
||||||
|
|
|
@ -11,6 +11,7 @@ export function UserModel(tools) {
|
||||||
this.encrypt = tools.encrypt
|
this.encrypt = tools.encrypt
|
||||||
this.mailer = tools.email
|
this.mailer = tools.email
|
||||||
this.Confirmation = new ConfirmationModel(tools)
|
this.Confirmation = new ConfirmationModel(tools)
|
||||||
|
this.clear = {} // For holding decrypted data
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -27,12 +28,40 @@ UserModel.prototype.read = async function (where) {
|
||||||
log.warn({ err, where }, 'Could not read user')
|
log.warn({ err, where }, 'Could not read user')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.record?.email) this.email = this.decrypt(this.record.email)
|
this.reveal()
|
||||||
if (this.record?.initial) this.initial = this.decrypt(this.record.initial)
|
|
||||||
|
|
||||||
return this.setExists()
|
return this.setExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper method to decrypt at-rest data
|
||||||
|
*/
|
||||||
|
UserModel.prototype.reveal = async function (where) {
|
||||||
|
this.clear = {}
|
||||||
|
if (this.record) {
|
||||||
|
this.clear.data = JSON.parse(this.decrypt(this.record.data))
|
||||||
|
this.clear.email = this.decrypt(this.record.email)
|
||||||
|
this.clear.initial = this.decrypt(this.record.initial)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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:
|
* Finds a user based on one of the accepted unique fields which are:
|
||||||
* - lusername (lowercase username)
|
* - lusername (lowercase username)
|
||||||
|
@ -56,6 +85,8 @@ UserModel.prototype.find = async function (body) {
|
||||||
log.warn({ err, body }, `Error while trying to find user: ${body.username}`)
|
log.warn({ err, body }, `Error while trying to find user: ${body.username}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.reveal()
|
||||||
|
|
||||||
return this.setExists()
|
return this.setExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,9 +97,8 @@ UserModel.prototype.find = async function (body) {
|
||||||
*/
|
*/
|
||||||
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 }
|
|
||||||
this.authenticatedUser = await this.prisma.user.findUnique({
|
this.authenticatedUser = await this.prisma.user.findUnique({
|
||||||
where,
|
where: { id: user.uid },
|
||||||
include: {
|
include: {
|
||||||
apikeys: true,
|
apikeys: true,
|
||||||
},
|
},
|
||||||
|
@ -103,22 +133,22 @@ UserModel.prototype.create = async function ({ body }) {
|
||||||
if (this.exists) return this.setResponse(400, 'emailExists')
|
if (this.exists) return this.setResponse(400, 'emailExists')
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.email = clean(body.email)
|
this.clear.email = clean(body.email)
|
||||||
|
this.clear.initial = this.clear.email
|
||||||
this.language = body.language
|
this.language = body.language
|
||||||
const email = this.encrypt(this.email)
|
const email = this.encrypt(this.clear.email)
|
||||||
const username = clean(randomString()) // Temporary username
|
const username = clean(randomString()) // Temporary username
|
||||||
this.record = await this.prisma.user.create({
|
const data = {
|
||||||
data: {
|
ehash,
|
||||||
ehash,
|
ihash: ehash,
|
||||||
ihash: ehash,
|
email,
|
||||||
email,
|
initial: email,
|
||||||
initial: email,
|
username,
|
||||||
username,
|
lusername: username,
|
||||||
lusername: username,
|
data: this.encrypt(asJson({ settings: { language: this.language } })),
|
||||||
data: this.encrypt(asJson({ settings: { language: this.language } })),
|
password: asJson(hashPassword(body.password)),
|
||||||
password: asJson(hashPassword(body.password)),
|
}
|
||||||
},
|
this.record = await this.prisma.user.create({ data })
|
||||||
})
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.warn(err, 'Could not create user record')
|
log.warn(err, 'Could not create user record')
|
||||||
return this.setResponse(500, 'createAccountFailed')
|
return this.setResponse(500, 'createAccountFailed')
|
||||||
|
@ -126,7 +156,7 @@ UserModel.prototype.create = async function ({ body }) {
|
||||||
|
|
||||||
// Update username
|
// Update username
|
||||||
try {
|
try {
|
||||||
await this.update({
|
await this.safeUpdate({
|
||||||
username: `user-${this.record.id}`,
|
username: `user-${this.record.id}`,
|
||||||
lusername: `user-${this.record.id}`,
|
lusername: `user-${this.record.id}`,
|
||||||
})
|
})
|
||||||
|
@ -138,12 +168,12 @@ UserModel.prototype.create = async function ({ body }) {
|
||||||
// Create confirmation
|
// Create confirmation
|
||||||
this.confirmation = await this.Confirmation.create({
|
this.confirmation = await this.Confirmation.create({
|
||||||
type: 'signup',
|
type: 'signup',
|
||||||
data: this.encrypt({
|
data: {
|
||||||
language: this.language,
|
language: this.language,
|
||||||
email: this.email,
|
email: this.clear.email,
|
||||||
id: this.record.id,
|
id: this.record.id,
|
||||||
ehash: ehash,
|
ehash: ehash,
|
||||||
}),
|
},
|
||||||
userId: this.record.id,
|
userId: this.record.id,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -152,7 +182,7 @@ UserModel.prototype.create = async function ({ body }) {
|
||||||
await this.mailer.send({
|
await this.mailer.send({
|
||||||
template: 'signup',
|
template: 'signup',
|
||||||
language: this.language,
|
language: this.language,
|
||||||
to: this.email,
|
to: this.clear.email,
|
||||||
replacements: {
|
replacements: {
|
||||||
actionUrl: i18nUrl(this.language, `/confirm/signup/${this.Confirmation.record.id}`),
|
actionUrl: i18nUrl(this.language, `/confirm/signup/${this.Confirmation.record.id}`),
|
||||||
whyUrl: i18nUrl(this.language, `/docs/faq/email/why-signup`),
|
whyUrl: i18nUrl(this.language, `/docs/faq/email/why-signup`),
|
||||||
|
@ -161,8 +191,11 @@ UserModel.prototype.create = async function ({ body }) {
|
||||||
})
|
})
|
||||||
|
|
||||||
return this.isUnitTest(body)
|
return this.isUnitTest(body)
|
||||||
? this.setResponse(201, false, { email: this.email, confirmation: this.confirmation.record.id })
|
? this.setResponse(201, false, {
|
||||||
: this.setResponse(201, false, { email: this.email })
|
email: this.clear.email,
|
||||||
|
confirmation: this.confirmation.record.id,
|
||||||
|
})
|
||||||
|
: this.setResponse(201, false, { email: this.clear.email })
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -191,7 +224,7 @@ UserModel.prototype.passwordLogin = async function (req) {
|
||||||
// Login success
|
// Login success
|
||||||
if (updatedPasswordField) {
|
if (updatedPasswordField) {
|
||||||
// Update the password field with a v3 hash
|
// Update the password field with a v3 hash
|
||||||
await this.update({ password: updatedPasswordField })
|
await this.safeUpdate({ password: updatedPasswordField })
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.isOk() ? this.loginOk() : this.setResponse(401, 'loginFailed')
|
return this.isOk() ? this.loginOk() : this.setResponse(401, 'loginFailed')
|
||||||
|
@ -220,7 +253,7 @@ UserModel.prototype.confirm = async function ({ body, params }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.error) return this
|
if (this.error) return this
|
||||||
const data = await this.decrypt(this.Confirmation.record.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, 'confirmationEhashMismatch')
|
return this.setResponse(404, 'confirmationEhashMismatch')
|
||||||
if (data.id !== this.Confirmation.record.user.id)
|
if (data.id !== this.Confirmation.record.user.id)
|
||||||
|
@ -231,7 +264,7 @@ UserModel.prototype.confirm = async function ({ body, params }) {
|
||||||
if (this.error) return this
|
if (this.error) return this
|
||||||
|
|
||||||
// Update user status, consent, and last login
|
// Update user status, consent, and last login
|
||||||
await this.update({
|
await this.safeUpdate({
|
||||||
status: 1,
|
status: 1,
|
||||||
consent: body.consent,
|
consent: body.consent,
|
||||||
lastLogin: new Date(),
|
lastLogin: new Date(),
|
||||||
|
@ -243,9 +276,10 @@ UserModel.prototype.confirm = async function ({ body, params }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Updates the user data
|
* Updates the user data - Used when we create the data ourselves
|
||||||
|
* so we know it's safe
|
||||||
*/
|
*/
|
||||||
UserModel.prototype.update = async function (data) {
|
UserModel.prototype.safeUpdate = async function (data) {
|
||||||
try {
|
try {
|
||||||
this.record = await this.prisma.user.update({
|
this.record = await this.prisma.user.update({
|
||||||
where: { id: this.record.id },
|
where: { id: this.record.id },
|
||||||
|
@ -260,6 +294,49 @@ UserModel.prototype.update = async function (data) {
|
||||||
return this.setResponse(200)
|
return this.setResponse(200)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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) {
|
||||||
|
const data = {}
|
||||||
|
// Update consent
|
||||||
|
if ([0, 1, 2, 3].includes(body.consent)) data.consent = body.consent
|
||||||
|
// Update newsletter
|
||||||
|
if ([true, false].includes(body.newsletter)) data.newsletter = body.newsletter
|
||||||
|
// Update username
|
||||||
|
if (typeof body.username === 'string') {
|
||||||
|
if (await this.isAvailableUsername(body.username)) {
|
||||||
|
data.username = body.username.trim()
|
||||||
|
data.lusername = clean(body.username)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Update password
|
||||||
|
if (typeof body.password === 'string') {
|
||||||
|
data.password = asJson(hashPassword(body.password))
|
||||||
|
}
|
||||||
|
// Update data
|
||||||
|
if (typeof body.data === 'object') {
|
||||||
|
data.data = { ...this.record.data }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
data String @default("{}")
|
||||||
|
ehash String @unique
|
||||||
|
email String
|
||||||
|
*/
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.record = await this.prisma.user.update({ where, data })
|
||||||
|
} catch (err) {
|
||||||
|
log.warn(err, 'Could not update user record')
|
||||||
|
process.exit()
|
||||||
|
return this.setResponse(500, 'updateUserFailed')
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.setResponse(200)
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns account data
|
* Returns account data
|
||||||
*/
|
*/
|
||||||
|
@ -268,9 +345,9 @@ UserModel.prototype.asAccount = function () {
|
||||||
id: this.record.id,
|
id: this.record.id,
|
||||||
consent: this.record.consent,
|
consent: this.record.consent,
|
||||||
createdAt: this.record.createdAt,
|
createdAt: this.record.createdAt,
|
||||||
data: JSON.parse(this.decrypt(this.record.data)),
|
data: this.clear.data,
|
||||||
email: this.decrypt(this.record.email),
|
email: this.clear.email,
|
||||||
initial: this.decrypt(this.record.initial),
|
initial: this.clear.initial,
|
||||||
lastLogin: this.record.lastLogin,
|
lastLogin: this.record.lastLogin,
|
||||||
newsletter: this.record.newsletter,
|
newsletter: this.record.newsletter,
|
||||||
patron: this.record.patron,
|
patron: this.record.patron,
|
||||||
|
@ -334,7 +411,7 @@ UserModel.prototype.sendResponse = async function (res) {
|
||||||
* part of a unit test
|
* part of a unit test
|
||||||
*/
|
*/
|
||||||
UserModel.prototype.isUnitTest = function (body) {
|
UserModel.prototype.isUnitTest = function (body) {
|
||||||
return body.unittest && this.email.split('@').pop() === this.config.tests.domain
|
return body.unittest && this.clear.email.split('@').pop() === this.config.tests.domain
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -18,7 +18,15 @@ export const accountTests = async (config, store, chai) => {
|
||||||
.request(config.api)
|
.request(config.api)
|
||||||
.put('/account/jwt')
|
.put('/account/jwt')
|
||||||
.set('Authorization', 'Bearer ' + store.account.token)
|
.set('Authorization', 'Bearer ' + store.account.token)
|
||||||
.send({ consent: 3 })
|
.send({
|
||||||
|
consent: 3,
|
||||||
|
data: {
|
||||||
|
banana: 'Sure',
|
||||||
|
},
|
||||||
|
newsletter: true,
|
||||||
|
password: 'Something new',
|
||||||
|
username: 'new',
|
||||||
|
})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
expect(err === null).to.equal(true)
|
expect(err === null).to.equal(true)
|
||||||
expect(res.status).to.equal(200)
|
expect(res.status).to.equal(200)
|
||||||
|
|
|
@ -33,7 +33,7 @@ store.icon = (icon1, icon2 = false) => store.icons[icon1] + (icon2 ? store.icons
|
||||||
const runTests = async (config, store, chai) => {
|
const runTests = async (config, store, chai) => {
|
||||||
await setup(config, store, chai)
|
await setup(config, store, chai)
|
||||||
await userTests(config, store, chai)
|
await userTests(config, store, chai)
|
||||||
//await apikeyTests(config, store, chai)
|
await apikeyTests(config, store, chai)
|
||||||
//await accountTests(config, store, chai)
|
//await accountTests(config, store, chai)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue