sumba 1.1.4 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  async function doboSumbaUserAfterRecordValidation (body, options) {
2
- const { isBcrypt, isMd5, hash } = this.app.bajoExtra
2
+ const { isBcrypt, hash } = this.app.bajoExtra
3
3
  const { has } = this.app.bajo.lib._
4
4
 
5
5
  if (has(body, 'password') && !isBcrypt(body.password)) body.password = await hash(body.password, 'bcrypt')
6
- if (has(body, 'token') && !isMd5(body.token)) body.token = await hash(body.password ?? body.token)
6
+ // if (has(body, 'token') && !isMd5(body.token)) body.token = await hash(body.token)
7
7
  }
8
8
 
9
9
  export default doboSumbaUserAfterRecordValidation
@@ -0,0 +1,9 @@
1
+ import resetToken from '../../lib/reset-token.js'
2
+
3
+ async function afterRecordCreate (body, options = {}) {
4
+ const { token, salt } = await resetToken.call(this)
5
+ body.token = token
6
+ body.salt = salt
7
+ }
8
+
9
+ export default afterRecordCreate
@@ -0,0 +1,11 @@
1
+ import resetToken from '../../lib/reset-token.js'
2
+
3
+ async function beforeRecordUpdate (id, body, options = {}) {
4
+ if (body.salt) {
5
+ const { token, salt } = await resetToken.call(this, body.salt)
6
+ body.token = token
7
+ body.salt = salt
8
+ }
9
+ }
10
+
11
+ export default beforeRecordUpdate
@@ -15,6 +15,11 @@
15
15
  "type": "string",
16
16
  "maxLength": 50,
17
17
  "index": true
18
+ }, {
19
+ "name": "salt",
20
+ "type": "string",
21
+ "maxLength": 50,
22
+ "required": true
18
23
  }, {
19
24
  "name": "email",
20
25
  "type": "string",
@@ -43,7 +48,7 @@
43
48
  "fields": ["email", "siteId"],
44
49
  "unique": true
45
50
  }],
46
- "hidden": ["password"],
51
+ "hidden": ["password", "token"],
47
52
  "feature": {
48
53
  "sumba.address": true,
49
54
  "sumba.social": true,
@@ -0,0 +1,9 @@
1
+ async function resetToken (salt) {
2
+ const { generateId } = this.app.bajo
3
+ const { hash } = this.app.bajoExtra
4
+ salt = salt ?? generateId()
5
+ const token = await hash(await hash(salt))
6
+ return { salt, token }
7
+ }
8
+
9
+ export default resetToken
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sumba",
3
- "version": "1.1.4",
3
+ "version": "1.1.5",
4
4
  "description": "Bajo Framework's Biz Suite",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -6,7 +6,7 @@ const profile = {
6
6
  const options = { forceNoHidden: true, noHook: true, noCache: true, attachment: true, mimeType: true }
7
7
  const resp = await recordGet({ model: 'SumbaUser', req, id: req.user.id, options })
8
8
  const form = resp.data
9
- form.token = await hash(form.token)
9
+ form.token = await hash(form.salt)
10
10
  return reply.view('sumba.template:/my-stuff/profile/view.html', { form })
11
11
  }
12
12
  }
@@ -9,7 +9,7 @@ const resetApiKey = {
9
9
  const delay = await importPkg('delay')
10
10
  const bcrypt = await importPkg('bajoExtra:bcrypt')
11
11
  const Joi = await importPkg('dobo:joi')
12
- const form = defaultsDeep(req.body, { apiKey: await hash(req.user.token) })
12
+ const form = defaultsDeep(req.body, { apiKey: await hash(req.user.salt) })
13
13
  let error
14
14
  if (req.method === 'POST') {
15
15
  try {
@@ -24,7 +24,7 @@ const resetApiKey = {
24
24
  const rec = await recordGet(model, req.user.id, { forceNoHidden: true })
25
25
  const verified = await bcrypt.compare(req.body.password, rec.password)
26
26
  if (!verified) throw this.error('validationError', { details: [{ field: 'password', error: 'invalidPassword' }], statusCode: 400 })
27
- await recordUpdate(model, req.user.id, { token: generateId() }, { req, reply, noFlash: true })
27
+ await recordUpdate(model, req.user.id, { salt: generateId() }, { req, reply, noFlash: true })
28
28
  await delay(2000) // ensure req.user cache is expired
29
29
  req.flash('notify', req.t('resetApiKeySuccessfull'))
30
30
  return reply.redirectTo('sumba:/my-stuff/profile')
@@ -4,15 +4,15 @@ const userActivation = {
4
4
  method: ['GET', 'POST'],
5
5
  handler: async function (req, reply) {
6
6
  const { defaultsDeep } = this.app.bajo
7
- const { recordFind, recordUpdate } = this.app.waibuDb
7
+ const { recordFind, recordUpdate } = this.app.dobo
8
8
  const form = defaultsDeep(req.body, { key: req.query.key })
9
9
  let error
10
10
  if (req.method === 'POST') {
11
11
  try {
12
12
  const query = { status: 'UNVERIFIED', token: req.body.key }
13
- const result = await recordFind({ model, req, reply, options: { dataOnly: true, query, limit: 1, noHook: true } })
13
+ const result = await recordFind(model, { query, limit: 1 })
14
14
  if (result.length === 0) throw this.error('validationError', { details: [{ field: 'key', error: 'invalidActivationKey' }] })
15
- await recordUpdate({ model, req, reply, id: result[0].id, body: { status: 'ACTIVE' }, options: { noValidation: true, noFlash: true } })
15
+ await recordUpdate(model, result[0].id, { status: 'ACTIVE' }, { noValidation: true, noFlash: true })
16
16
  req.flash('notify', req.t('userActivated'))
17
17
  return reply.redirectTo(this.config.redirect.signin, req)
18
18
  } catch (err) {
@@ -0,0 +1,14 @@
1
+ import { response } from './update.js'
2
+
3
+ async function get ({ ctx }) {
4
+ const { hash } = this.app.bajoExtra
5
+ const { recordGet } = this.app.dobo
6
+ const schema = { response: await response.call(this) }
7
+ const handler = async function get (req, reply) {
8
+ const rec = await recordGet('SumbaUser', req.user.id, { forceNoHidden: true })
9
+ return { data: { token: await hash(rec.salt) } }
10
+ }
11
+ return { schema, handler }
12
+ }
13
+
14
+ export default get
@@ -0,0 +1,44 @@
1
+ import { data } from '../../../../lib/token-schema.js'
2
+
3
+ export function response () {
4
+ return {
5
+ '2xx': {
6
+ description: 'Successfull response',
7
+ type: 'object',
8
+ properties: this.app.waibuRestApi.transformResult({ data })
9
+ }
10
+ }
11
+ }
12
+
13
+ export const body = {
14
+ type: 'object',
15
+ properties: {
16
+ password: {
17
+ type: 'string'
18
+ }
19
+ }
20
+ }
21
+
22
+ const model = 'SumbaUser'
23
+
24
+ async function update ({ ctx }) {
25
+ const { importPkg, generateId } = this.app.bajo
26
+ const { recordGet, recordUpdate } = this.app.dobo
27
+ const { hash } = this.app.bajoExtra
28
+ const bcrypt = await importPkg('bajoExtra:bcrypt')
29
+
30
+ const schema = { body, response: await response.call(this) }
31
+
32
+ const handler = async function get (req, reply, options) {
33
+ const rec = await recordGet(model, req.user.id, { forceNoHidden: true })
34
+ const verified = await bcrypt.compare(req.body.password, rec.password)
35
+ if (!verified) throw this.error('invalidPassword', { details: [{ field: 'password', error: 'invalidPassword' }], statusCode: 400 })
36
+ const input = { salt: generateId() }
37
+ const resp = await recordUpdate(model, req.user.id, input, { forceNoHidden: true })
38
+ return { data: { token: await hash(resp.salt) } }
39
+ }
40
+
41
+ return { schema, handler }
42
+ }
43
+
44
+ export default update
@@ -40,7 +40,7 @@ async function update ({ ctx }) {
40
40
  }
41
41
 
42
42
  const handler = async function get (req, reply, options) {
43
- const rec = await recordGet(model, req.user.id)
43
+ const rec = await recordGet(model, req.user.id, { forceNoHidden: true })
44
44
  const verified = await bcrypt.compare(req.body.currentPassword, rec.password)
45
45
  if (!verified) throw this.error('invalidCurrentPassword', { details: [{ field: 'current', error: 'invalidPassword' }], statusCode: 400 })
46
46
  const input = { password: req.body.password }
@@ -1,5 +1,5 @@
1
1
  const model = 'SumbaUser'
2
- const hidden = ['password', 'token', 'siteId']
2
+ const hidden = ['password', 'token', 'siteId', 'salt']
3
3
 
4
4
  async function get ({ ctx }) {
5
5
  const { recordGet } = this.app.waibuDb
@@ -22,7 +22,7 @@ async function create () {
22
22
  const jwt = await createJwtFromUserRecord(rec)
23
23
  return { data: jwt }
24
24
  }
25
- return { data: { token: await hash(rec.password) } }
25
+ return { data: { token: await hash(rec.salt) } }
26
26
  }
27
27
  return { schema, handler }
28
28
  }