sumba 2.33.0 → 2.33.2

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.
@@ -20,6 +20,22 @@ async function clearCacheUser (id, result) {
20
20
  await clear({ key: `dobo|SumbaUser|getUserByToken|${token}` })
21
21
  }
22
22
 
23
+ function filterModelFromSetting ({ model, field, options }) {
24
+ const { isEmpty, isArray, set } = this.app.lib._
25
+ const { req } = options
26
+ const opValue = req.getSetting(`sumba:modelGuard.${field}`, {})
27
+ const results = []
28
+ for (const op of ['in', 'nin', 'inOrNull']) {
29
+ if (isEmpty(opValue[op]) || !isArray(opValue[op])) continue
30
+ if (op === 'inOrNull') {
31
+ const val = set({}, field, set({}, '$in', opValue[op]))
32
+ const nl = set({}, field, { $eq: null })
33
+ results.push({ $or: [val, nl] })
34
+ } else results.push(set({}, field, set({}, '$' + op, opValue[op])))
35
+ }
36
+ return { results, opValue }
37
+ }
38
+
23
39
  async function applyModelGuard ({ model, q, teamIds, options }) {
24
40
  const { set, orderBy, isEmpty, isArray } = this.app.lib._
25
41
  const { includes } = this.app.lib.aneka
@@ -39,15 +55,8 @@ async function applyModelGuard ({ model, q, teamIds, options }) {
39
55
  const rules = orderBy(guards.filter(filterFn), ['field'])
40
56
  for (const field of fields) {
41
57
  if (!model.getNonVirtualProperties(true).includes(field)) continue // or, should it throws exception instead?
42
- const opValue = req.getSetting(`sumba:modelGuard.${field}`, {})
43
- for (const op of ['in', 'nin', 'inOrNull']) {
44
- if (isEmpty(opValue[op]) || !isArray(opValue[op])) continue
45
- if (op === 'inOrNull') {
46
- const val = set({}, field, set({}, '$in', opValue[op]))
47
- const nl = set({}, field, { $eq: null })
48
- results.push({ $or: [val, nl] })
49
- } else results.push(set({}, field, set({}, '$' + op, opValue[op])))
50
- }
58
+ const inSetting = filterModelFromSetting.call(this, { model, field, options })
59
+ if (inSetting.results.length > 0) inSetting.results.push(...inSetting.results)
51
60
  const prop = model.getProperty(field)
52
61
  const items = rules.filter(item => item.field === field)
53
62
  for (const item of items) {
@@ -55,7 +64,7 @@ async function applyModelGuard ({ model, q, teamIds, options }) {
55
64
  return sanitizeByType(val, prop.type, { strict: true, inputFormat: 'string', model: model.name })
56
65
  })
57
66
  const op = item.condition.toLowerCase()
58
- if (['in', 'nin'].includes(op) && !isEmpty(opValue[op]) && isArray(opValue[op])) values = values.filter(val => opValue[op].includes(val))
67
+ if (['in', 'nin'].includes(op) && !isEmpty(inSetting.opValue[op]) && isArray(inSetting.opValue[op])) values = values.filter(val => inSetting.opValue[op].includes(val))
59
68
  if (isEmpty(values)) continue
60
69
  let value
61
70
  if (['in', 'nin'].includes(op)) value = set({}, '$' + op, values)
@@ -89,7 +98,7 @@ export async function applyAttribGuard ({ model, teamIds, options }) {
89
98
  }
90
99
 
91
100
  async function rebuildFilter (model, filter = {}, options = {}) {
92
- const { isEmpty, get } = this.app.lib._
101
+ const { isEmpty, get, keys } = this.app.lib._
93
102
  const { req } = options
94
103
  const allowEmpty = !get(this, `app.${model.ns}.config.sumba.noEmptyQuery`, []).includes(model.name)
95
104
  const hasSiteId = model.hasProperty('siteId')
@@ -97,7 +106,7 @@ async function rebuildFilter (model, filter = {}, options = {}) {
97
106
  const hasTeamId = model.hasProperty('teamId')
98
107
  const teams = get(req, 'user.teams', [])
99
108
  const teamIds = teams.map(team => team.id + '')
100
- // const aliases = teams.map(team => team.alias)
109
+ const aliases = teams.map(team => team.alias)
101
110
  const q = { $and: [] }
102
111
 
103
112
  filter.query = filter.query ?? {}
@@ -110,12 +119,21 @@ async function rebuildFilter (model, filter = {}, options = {}) {
110
119
  return
111
120
  }
112
121
  if (hasSiteId) q.$and.push({ siteId: req.site.id + '' })
113
- /*
114
122
  if (aliases.includes('administrator')) {
123
+ if (get(req, 'site.alias') === 'default') {
124
+ filter.query = q
125
+ return
126
+ }
127
+ const fields = keys(req.getSetting('sumba:modelGuard', {}))
128
+ const results = []
129
+ for (const field of fields) {
130
+ const inSetting = filterModelFromSetting.call(this, { model, field, options })
131
+ if (inSetting.results.length > 0) results.push(...inSetting.results)
132
+ }
133
+ if (results.length > 0) q.$and.push(...results)
115
134
  filter.query = q
116
135
  return
117
136
  }
118
- */
119
137
  if (isEmpty(req.user)) {
120
138
  if (q.$and.length === 0 && !allowEmpty) throw this.error('_emptyColumnQuery')
121
139
  filter.query = q
@@ -7,7 +7,7 @@ async function country (opts = {}) {
7
7
  type: 'string',
8
8
  maxLength: 2,
9
9
  index: opts.index ?? true,
10
- required: opts.required,
10
+ required: opts.required ?? true,
11
11
  values: 'sumba:getCountriesValues',
12
12
  rules: opts.enforceRule ? ['uppercase', { rule: 'length', params: 2 }] : [],
13
13
  rulesMsg: opts.enforceRule ? { 'any.only': 'validCountryCodeRequired' } : undefined
@@ -29,7 +29,7 @@ const id = {
29
29
  schema.view.format = {
30
30
  createdAt: async function (val, rec) {
31
31
  const message = this.app.bajoMarkdown ? this.app.bajoMarkdown.parseContent(rec.message) : rec.message
32
- const isMe = rec.userId === req.user.id
32
+ const isMe = rec.userId === req.user.id + ''
33
33
  const sentence = `<c:div margin="bottom-3"><c:badge background="color:${isMe ? 'primary' : 'secondary'}" t:content="${isMe ? 'you' : 'us'}" /> <small>${req.format(val, 'datetime')}</small></c:div>`
34
34
  return (await this.component.buildSentence(sentence)) + message
35
35
  }
package/index.js CHANGED
@@ -745,7 +745,6 @@ async function factory (pkgName) {
745
745
  const { merge, isEmpty, camelCase, get } = this.app.lib._
746
746
  const { routePath } = this.app.waibu
747
747
  const userId = get(req, 'session.userId')
748
-
749
748
  const setUser = async () => {
750
749
  if (!userId) return
751
750
  try {
@@ -806,7 +805,8 @@ async function factory (pkgName) {
806
805
  checkXSite = async (req, reply) => {
807
806
  const { get } = this.app.lib._
808
807
  if (!this.config.multiSite.enabled) return
809
- if (!get(req, 'routeOptions.config.xSite')) return
808
+ const config = get(req, 'routeOptions.config')
809
+ if (!get(config, 'xSite') || ['/dashboard'].includes(config.pathSrc)) return
810
810
  if (!get(req, 'user.isXSiteAdmin')) throw this.error('accessDenied', { statusCode: 403 })
811
811
  }
812
812
 
package/lib/get-site.js CHANGED
@@ -23,7 +23,7 @@ async function getSite (input, byId = false) {
23
23
  }
24
24
  site.setting = defaultsDeep({}, nsSetting, defSetting)
25
25
  // additional fields
26
- const country = await this.app.dobo.getModel('CdbCountry').getRecord(site.country, { noHook: true })
26
+ const country = await this.app.dobo.getModel('CdbCountry').getRecord(site.country, { noMagic: true })
27
27
  site.countryName = (country ?? {}).name ?? site.country
28
28
  }
29
29
 
package/lib/get-user.js CHANGED
@@ -2,12 +2,14 @@ export async function mergeTeam (user, req) {
2
2
  const { map, pick } = this.app.lib._
3
3
  const { getModel } = this.app.dobo
4
4
  user.teams = []
5
- const query = { userId: user.id, siteId: user.siteId, status: 'ACTIVE' }
5
+ const query = { userId: user.id + '', siteId: user.siteId, status: 'ACTIVE' }
6
6
  let mdl = getModel('SumbaTeamUser')
7
7
  const userTeam = await mdl.findAllRecord({ query })
8
8
  if (userTeam.length === 0) return
9
9
  delete query.userId
10
- query.id = { $in: map(userTeam, 'teamId') }
10
+ const idProp = mdl.getProperty('id')
11
+ const $in = userTeam.map(item => ['integer', 'smallint'].includes(idProp.type) ? parseInt(item.teamId) : item.teamId)
12
+ query.id = { $in }
11
13
  mdl = getModel('SumbaTeam')
12
14
  const teams = await mdl.findAllRecord({ query })
13
15
  if (teams.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sumba",
3
- "version": "2.33.0",
3
+ "version": "2.33.2",
4
4
  "description": "Biz Suite for Bajo Framework",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/wiki/CHANGES.md CHANGED
@@ -1,10 +1,16 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-06-18
4
+
5
+ - [2.33.2] Bug fix in ```hook.js```
6
+
3
7
  ## 2026-06-17
4
8
 
5
9
  - [2.33.0] Add ```Site Setting``` in ```Cross-Site```
6
10
  - [2.33.0] Bug fix in ```hook.js```
7
- - [2.33.0] Bug fix in ```feature:siteId```
11
+ - [2.33.0] Bug fix in ```sumba:siteId``` feature
12
+ - [2.33.1] Bug fix in ```checkUser()```, ```checkTeam()``` & ```checkXSite()```
13
+ - [2.33.1] Bug fix in ```sumba:country``` feature
8
14
 
9
15
  ## 2026-06-15
10
16