sumba 2.5.0 → 2.7.0

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,7 +1,7 @@
1
1
  import checkUserId from '../../../lib/check-user-id.js'
2
2
  import checkTeam from '../../../lib/check-team.js'
3
3
 
4
- const onRequest = {
4
+ const preParsing = {
5
5
  level: 10,
6
6
  handler: async function (req, reply) {
7
7
  await checkUserId.call(this, req, reply, 'waibuRestApi')
@@ -9,4 +9,4 @@ const onRequest = {
9
9
  }
10
10
  }
11
11
 
12
- export default onRequest
12
+ export default preParsing
@@ -1,7 +1,7 @@
1
1
  import checkUserId from '../../../lib/check-user-id.js'
2
2
  import checkTeam from '../../../lib/check-team.js'
3
3
 
4
- const onRequest = {
4
+ const preParsing = {
5
5
  level: 10,
6
6
  handler: async function (req, reply) {
7
7
  await checkUserId.call(this, req, reply, 'waibuStatic')
@@ -9,4 +9,4 @@ const onRequest = {
9
9
  }
10
10
  }
11
11
 
12
- export default onRequest
12
+ export default preParsing
@@ -6,13 +6,16 @@ async function afterAppBoot () {
6
6
  await runHook(`${this.ns}:beforeBoot`)
7
7
  this.log.trace('collectingRouteGuards')
8
8
  await collectRoutes.call(this, 'secure')
9
+ await runHook(`${this.ns}:afterCollectSecureRoutes`, this.secureRoutes, this.secureNegRoutes)
9
10
  this.log.trace('secureRoutes%d', this.secureRoutes.length)
10
11
  this.log.trace('secureNegRoutes%d', this.secureNegRoutes.length)
11
12
  await collectRoutes.call(this, 'anonymous')
13
+ await runHook(`${this.ns}:afterCollectAnonymousRoutes`, this.anonymousRoutes, this.anonymousNegRoutes)
12
14
  this.log.trace('anonRoutes%d', this.anonymousRoutes.length)
13
15
  this.log.trace('anonNegRoutes%d', this.anonymousNegRoutes.length)
14
16
  this.log.trace('collectingTeamGuards')
15
17
  await collectTeam.call(this)
18
+ await runHook(`${this.ns}:afterCollectTeamRoutes`, this.teamRoutes, this.teamNegRoutes)
16
19
  this.log.trace('teamRoutes%d', this.teamRoutes.length)
17
20
  this.log.trace('teamNegRoutes%d', this.teamNegRoutes.length)
18
21
  await runHook(`${this.ns}:afterBoot`)
@@ -10,7 +10,7 @@ const contactForm = {
10
10
  let error
11
11
  if (req.method === 'POST') {
12
12
  try {
13
- const { data } = await createRecord({ model: 'SumbaContactForm', req, reply, options: { noFlash: true } })
13
+ const { data } = await createRecord({ model: 'SumbaContactForm', req, reply, transaction: true, options: { noFlash: true } })
14
14
  req.flash('notify', req.t('contactFormSubmitted'))
15
15
  return await reply.view('sumba.template:/help/contact-form/success.html', { form: req.body, data })
16
16
  } catch (err) {
@@ -10,7 +10,9 @@ const userActivation = {
10
10
  const query = { status: 'UNVERIFIED', token: req.body.key }
11
11
  const result = await model.findRecord({ query, limit: 1 })
12
12
  if (result.length === 0) throw this.error('validationError', { details: [{ field: 'key', error: 'invalidActivationKey' }] })
13
- await model.updateRecord(result[0].id, { status: 'ACTIVE' }, { req, noValidation: true, noFlash: true })
13
+ await model.transaction(async (trx) => {
14
+ await model.updateRecord(result[0].id, { status: 'ACTIVE' }, { req, noValidation: true, noFlash: true, trx })
15
+ })
14
16
  req.flash('notify', req.t('userActivated'))
15
17
  return reply.redirectTo(this.config.redirect.signin, req)
16
18
  } catch (err) {
@@ -40,15 +40,17 @@ const forgotPasswordLink = {
40
40
  } catch (err) {
41
41
  throw this.error('validationError', { details: err.details, values: err.values, ns: this.ns, statusCode: 422, code: 'DB_VALIDATION' })
42
42
  }
43
- await model.updateRecord(user.id, { password: req.body.newPassword }, { noFlash: true })
44
- const to = `${user.firstName} ${user.lastName} <${user.email}>`
45
- const subject = req.t('forgotPasswordChanged')
46
- const options = { req, reply, tpl: '' }
47
- const payload = { to, subject, data: user }
48
- await this.sendMail(
49
- 'sumba.template:/_mail/user-forgot-password-changed.html',
50
- { payload, options, source: this.ns }
51
- )
43
+ await model.transaction(async trx => {
44
+ await model.updateRecord(user.id, { password: req.body.newPassword }, { noFlash: true, trx })
45
+ const to = `${user.firstName} ${user.lastName} <${user.email}>`
46
+ const subject = req.t('forgotPasswordChanged')
47
+ const options = { req, reply, tpl: '' }
48
+ const payload = { to, subject, data: user }
49
+ await this.sendMail(
50
+ 'sumba.template:/_mail/user-forgot-password-changed.html',
51
+ { payload, options, source: this.ns }
52
+ )
53
+ })
52
54
  req.flash('notify', req.t('passwordChangedReSignin'))
53
55
  return reply.redirectTo(this.config.redirect.signin)
54
56
  } catch (err) {
@@ -24,7 +24,7 @@ const signup = {
24
24
  const validation = { ns: ['sumba', 'dobo'], fields, extFields }
25
25
  req.body.token = generateId()
26
26
  req.body.provider = 'local'
27
- const { data } = await createRecord({ model: 'SumbaUser', req, reply, options: { validation, noFlash: true, forceNoHidden: true } })
27
+ const { data } = await createRecord({ model: 'SumbaUser', req, reply, transaction: true, options: { validation, noFlash: true, forceNoHidden: true } })
28
28
  req.flash('notify', req.t('userCreated'))
29
29
  return await reply.view('sumba.template:/user/signup/success.html', { form: req.body, data })
30
30
  } catch (err) {
@@ -26,7 +26,9 @@ const profile = {
26
26
  const rec = await model.getRecord(req.user.id, { forceNoHidden: true })
27
27
  const verified = await bcrypt.compare(req.body.currentPassword, rec.password)
28
28
  if (!verified) throw this.error('invalidCurrentPassword', { details: [{ field: 'currentPassword', error: 'invalidPassword' }], statusCode: 400 })
29
- await model.updateRecord(req.user.id, { password: req.body.newPassword }, { req, reply, noFlash: true })
29
+ await model.transaction(async (trx) => {
30
+ await model.updateRecord(req.user.id, { password: req.body.newPassword }, { req, reply, noFlash: true, trx })
31
+ })
30
32
  // signout and redirect to signin
31
33
  req.session.userId = null
32
34
  req.flash('notify', req.t('passwordChangedReSignin'))
@@ -1,3 +1,5 @@
1
+ const fields = ['email', 'firstName', 'lastName', 'address1', 'address2', 'city', 'zipCode', 'provinceState', 'country', 'phone', 'website']
2
+
1
3
  const profile = {
2
4
  method: ['GET', 'POST'],
3
5
  handler: async function (req, reply) {
@@ -7,13 +9,13 @@ const profile = {
7
9
  const { omit, pick } = this.app.lib._
8
10
  const { hash } = this.app.bajoExtra
9
11
  const resp = await getRecord({ model: 'SumbaUser', req, id: req.user.id, options: { forceNoHidden: true, noHook: true, noCache: true } })
10
- let form = defaultsDeep(req.body, omit(resp.data, ['password']))
12
+ let form = defaultsDeep(req.body, omit(resp.data, ['password', 'salt']))
11
13
  form.token = await hash(form.token)
12
14
  let error
13
15
  if (req.method === 'POST') {
14
16
  try {
15
- const body = pick(form, ['firstName', 'lastName', 'address1', 'address2', 'city', 'zipCode', 'provinceState', 'country', 'phone', 'website'])
16
- const options = { noFlash: true, hidden: [], setField: 'profile', setFile: 'main.png' }
17
+ const body = pick(form, fields)
18
+ const options = { noFlash: true, hidden: [], setField: 'profile', setFile: 'main.png', partial: true, fields }
17
19
  const resp = await updateRecord({ req, reply, model: 'SumbaUser', id: req.user.id, body, options })
18
20
  form = resp.data
19
21
  req.flash('notify', req.t('profileUpdated'))
@@ -24,7 +24,9 @@ const resetApiKey = {
24
24
  const rec = await model.getRecord(req.user.id, { forceNoHidden: true })
25
25
  const verified = await bcrypt.compare(form.password, rec.password)
26
26
  if (!verified) throw this.error('validationError', { details: [{ field: 'password', error: 'invalidPassword' }], statusCode: 400 })
27
- await model.updateRecord(req.user.id, { salt: generateId() }, { req, reply, noFlash: true, forceNoHidden: true })
27
+ await model.transaction(async (trx) => {
28
+ await model.updateRecord(req.user.id, { salt: generateId() }, { req, reply, noFlash: true, forceNoHidden: true, trx })
29
+ })
28
30
  await delay(2000) // ensure req.user cache is expired
29
31
  req.flash('notify', req.t('resetApiKeySuccessfull'))
30
32
  return reply.redirectTo('sumba:/your-stuff/profile')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sumba",
3
- "version": "2.5.0",
3
+ "version": "2.7.0",
4
4
  "description": "Biz Suite for Bajo Framework",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/wiki/CHANGES.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-03-05
4
+
5
+ - [2.6.0] Update multiple endpoints to support dobo's transaction
6
+ - [2.6.0] Bug fix on ```profile.edit``` route
7
+ - [2.7.0] Add hook ```sumba:afterCollectSecureRoutes```
8
+ - [2.7.0] Add hook ```sumba:afterCollectAnonymousRoutes```
9
+ - [2.7.0] Add hook ```sumba:afterCollectTeamRoutes```
10
+
3
11
  ## 2026-03-02
4
12
 
5
13
  - [2.5.0] Add ```sendMail()``` to send mail using ```masohiMail```