sumba 2.28.0 → 2.30.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.
- package/extend/bajo/hook.js +40 -42
- package/extend/bajo/intl/en-US.json +6 -5
- package/extend/bajo/intl/id.json +6 -5
- package/extend/dobo/feature/status.js +3 -1
- package/extend/dobo/fixture/site.json +1 -1
- package/extend/dobo/fixture/team-user.json +1 -1
- package/extend/dobo/fixture/team.json +2 -2
- package/extend/dobo/fixture/user.json +1 -1
- package/extend/dobo/model.js +113 -122
- package/extend/dobo/model.json +2 -40
- package/extend/sumba/route/anonymous.json +5 -0
- package/extend/sumba/route/secure.json +8 -0
- package/extend/waibuDb/schema/anonymous-guard.js +15 -0
- package/extend/waibuDb/schema/{route-guard.js → secure-guard.js} +2 -2
- package/extend/waibuDb/schema/team.json +1 -1
- package/extend/waibuDb/schema/ticket.js +32 -0
- package/extend/waibuMpa/extend/waibuAdmin/route/{x/model-guard → anonymous-guard}/@action.js +2 -3
- package/extend/waibuMpa/extend/waibuAdmin/route/{route-guard → secure-guard}/@action.js +2 -2
- package/extend/waibuMpa/route/access-token.js +3 -1
- package/extend/waibuRestApi/route/manage/anonymous-guard/model-builder.json +4 -0
- package/extend/waibuRestApi/route/manage/{route-guard → secure-guard}/model-builder.json +1 -1
- package/index.js +153 -98
- package/lib/get-user.js +1 -1
- package/lib/util.js +28 -67
- package/package.json +1 -1
- package/wiki/CHANGES.md +13 -0
- package/extend/dobo/fixture/x-route-guard.js +0 -24
- package/extend/waibuDb/schema/ticket.json +0 -16
- package/extend/waibuDb/schema/x-attrib-guard.js +0 -15
- package/extend/waibuDb/schema/x-model-guard.js +0 -15
- package/extend/waibuDb/schema/x-route-guard.js +0 -15
- package/extend/waibuMpa/extend/waibuAdmin/route/x/attrib-guard/@action.js +0 -12
- package/extend/waibuMpa/extend/waibuAdmin/route/x/route-guard/@action.js +0 -12
package/extend/bajo/hook.js
CHANGED
|
@@ -22,45 +22,30 @@ async function clearCacheUser (id, result) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
async function applyModelGuard ({ model, q, teamIds, options }) {
|
|
25
|
-
const { get, set, orderBy,
|
|
25
|
+
const { get, set, orderBy, without } = this.app.lib._
|
|
26
26
|
const { includes } = this.app.lib.aneka
|
|
27
27
|
const { req } = options
|
|
28
28
|
const results = []
|
|
29
29
|
|
|
30
30
|
const guards = await this.getModelGuards()
|
|
31
|
-
const
|
|
31
|
+
const fields = model.getNonVirtualProperties().map(prop => prop.name)
|
|
32
32
|
const filterFn = item => {
|
|
33
|
-
const bySiteId = item.
|
|
33
|
+
const bySiteId = item.siteId === req.site.id + ''
|
|
34
34
|
const byModel = item.models.includes(model.name)
|
|
35
|
-
const byTeamId =
|
|
36
|
-
const
|
|
37
|
-
return bySiteId && byModel && byTeamId &&
|
|
35
|
+
const byTeamId = includes(item.teamIds, teamIds)
|
|
36
|
+
const byFields = fields.includes(item.field)
|
|
37
|
+
return bySiteId && byModel && byTeamId && byFields
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
for (const col of columns) {
|
|
40
|
+
const rules = orderBy(guards.filter(filterFn), ['field'])
|
|
41
|
+
for (const field of fields) {
|
|
43
42
|
let values = []
|
|
44
|
-
|
|
43
|
+
const items = rules.filter(item => item.field === field)
|
|
45
44
|
for (const item of items) {
|
|
46
|
-
values
|
|
45
|
+
if (item.behavior === 'NIN') values = without(values, ...item.value)
|
|
46
|
+
else if (item.behavior === 'IN') values.push(...item.value)
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
for (const item of items) {
|
|
50
|
-
values = without(values, ...item.value)
|
|
51
|
-
}
|
|
52
|
-
items = guards.local.filter(item => item.column === col && !item.negation)
|
|
53
|
-
const newValues = []
|
|
54
|
-
for (const item of items) {
|
|
55
|
-
newValues.push(...item.value)
|
|
56
|
-
}
|
|
57
|
-
if (values.length === 0) values = newValues
|
|
58
|
-
else if (newValues.length > 0) values = intersection(values, newValues)
|
|
59
|
-
items = guards.local.filter(item => item.column === col && item.negation)
|
|
60
|
-
for (const item of items) {
|
|
61
|
-
values = without(values, ...item.value)
|
|
62
|
-
}
|
|
63
|
-
if (values.length) results.push(set({}, col, { $in: values }))
|
|
48
|
+
if (values.length) results.push(set({}, field, { $in: values }))
|
|
64
49
|
}
|
|
65
50
|
|
|
66
51
|
const allowEmpty = get(this, `config.dobo.model.${model.name}.allowEmptyQuery`, true)
|
|
@@ -76,16 +61,14 @@ export async function applyAttribGuard ({ model, teamIds, options }) {
|
|
|
76
61
|
|
|
77
62
|
const guards = await this.getAttribGuards()
|
|
78
63
|
const filterFn = item => {
|
|
79
|
-
const bySiteId = item.
|
|
64
|
+
const bySiteId = item.siteId === req.site.id + ''
|
|
80
65
|
const byModel = item.models.includes(model.name)
|
|
81
|
-
const byTeamId =
|
|
66
|
+
const byTeamId = includes(item.teamIds, teamIds)
|
|
82
67
|
return bySiteId && byModel && byTeamId
|
|
83
68
|
}
|
|
84
69
|
|
|
85
|
-
|
|
86
|
-
if (item) results.push(...item.
|
|
87
|
-
item = guards.local.filter(filterFn)[0]
|
|
88
|
-
if (item) results.push(...item.hiddenCols)
|
|
70
|
+
const item = guards.filter(filterFn)[0]
|
|
71
|
+
if (item) results.push(...item.hiddenFields)
|
|
89
72
|
options.hidden = options.hidden ?? []
|
|
90
73
|
if (results.length > 0) options.hidden.push(...results)
|
|
91
74
|
options.hidden = uniq(options.hidden)
|
|
@@ -168,7 +151,7 @@ async function hook () {
|
|
|
168
151
|
}
|
|
169
152
|
}
|
|
170
153
|
}, {
|
|
171
|
-
name: ['dobo.sumbaAttribGuard:afterTransaction'
|
|
154
|
+
name: ['dobo.sumbaAttribGuard:afterTransaction'],
|
|
172
155
|
handler: async function (action, ...args) {
|
|
173
156
|
if (!['createRecord', 'updateRecord', 'removeRecord'].includes(action)) return
|
|
174
157
|
await this.getAttribGuards(true)
|
|
@@ -205,16 +188,22 @@ async function hook () {
|
|
|
205
188
|
options.checksumId = true
|
|
206
189
|
}
|
|
207
190
|
}, {
|
|
208
|
-
name: ['dobo.sumbaModelGuard:afterTransaction'
|
|
191
|
+
name: ['dobo.sumbaModelGuard:afterTransaction'],
|
|
209
192
|
handler: async function (action, ...args) {
|
|
210
193
|
if (!['createRecord', 'updateRecord', 'removeRecord'].includes(action)) return
|
|
211
194
|
await this.getModelGuards(true)
|
|
212
195
|
}
|
|
213
196
|
}, {
|
|
214
|
-
name: ['dobo.
|
|
197
|
+
name: ['dobo.sumbaSecureGuard:afterTransaction'],
|
|
215
198
|
handler: async function (action, ...args) {
|
|
216
199
|
if (!['createRecord', 'updateRecord', 'removeRecord'].includes(action)) return
|
|
217
|
-
await this.
|
|
200
|
+
await this.getSecureGuards(true)
|
|
201
|
+
}
|
|
202
|
+
}, {
|
|
203
|
+
name: ['dobo.sumbaAnonymousGuard:afterTransaction'],
|
|
204
|
+
handler: async function (action, ...args) {
|
|
205
|
+
if (!['createRecord', 'updateRecord', 'removeRecord'].includes(action)) return
|
|
206
|
+
await this.getAnonymousGuards(true)
|
|
218
207
|
}
|
|
219
208
|
}, {
|
|
220
209
|
name: 'dobo.sumbaSite:afterCreateRecord',
|
|
@@ -237,7 +226,7 @@ async function hook () {
|
|
|
237
226
|
name: ['dobo.sumbaTeam:afterTransaction', 'dobo.sumbaSite:afterTransaction'],
|
|
238
227
|
handler: async function (action, ...args) {
|
|
239
228
|
if (!['createRecord', 'updateRecord', 'removeRecord'].includes(action)) return
|
|
240
|
-
await this.
|
|
229
|
+
await this.getSecureGuards(true)
|
|
241
230
|
await this.getModelGuards(true)
|
|
242
231
|
await this.getAttribGuards(true)
|
|
243
232
|
}
|
|
@@ -353,7 +342,7 @@ async function hook () {
|
|
|
353
342
|
await checkIconset.call(this, req, reply)
|
|
354
343
|
const secure = await checkUserId.call(this, req, reply, 'waibuMpa')
|
|
355
344
|
if (!secure) return
|
|
356
|
-
await checkTeam.call(this, req, reply
|
|
345
|
+
await checkTeam.call(this, req, reply)
|
|
357
346
|
await checkXSite.call(this, req, reply)
|
|
358
347
|
}
|
|
359
348
|
}, {
|
|
@@ -362,7 +351,7 @@ async function hook () {
|
|
|
362
351
|
handler: async function (req, reply) {
|
|
363
352
|
const secure = await checkUserId.call(this, req, reply, 'waibuRestApi')
|
|
364
353
|
if (!secure) return
|
|
365
|
-
await checkTeam.call(this, req, reply
|
|
354
|
+
await checkTeam.call(this, req, reply)
|
|
366
355
|
await checkXSite.call(this, req, reply)
|
|
367
356
|
}
|
|
368
357
|
}, {
|
|
@@ -371,13 +360,14 @@ async function hook () {
|
|
|
371
360
|
handler: async function (req, reply) {
|
|
372
361
|
const secure = await checkUserId.call(this, req, reply, 'waibuStatic')
|
|
373
362
|
if (!secure) return
|
|
374
|
-
await checkTeam.call(this, req, reply
|
|
363
|
+
await checkTeam.call(this, req, reply)
|
|
375
364
|
await checkXSite.call(this, req, reply)
|
|
376
365
|
}
|
|
377
366
|
}, {
|
|
378
367
|
name: 'waibu:afterAppBoot',
|
|
379
368
|
handler: async function () {
|
|
380
|
-
await this.
|
|
369
|
+
await this.getAnonymousGuards(true)
|
|
370
|
+
await this.getSecureGuards(true)
|
|
381
371
|
await this.getModelGuards(true)
|
|
382
372
|
await this.getAttribGuards(true)
|
|
383
373
|
}
|
|
@@ -392,6 +382,14 @@ async function hook () {
|
|
|
392
382
|
handler: async function (req, reply) {
|
|
393
383
|
const { getHostname } = this.app.waibu
|
|
394
384
|
req.site = await this.getSite(getHostname(req))
|
|
385
|
+
req.user = {}
|
|
386
|
+
}
|
|
387
|
+
}, {
|
|
388
|
+
name: 'waibu:beforeStart',
|
|
389
|
+
handler: async function () {
|
|
390
|
+
if (this.app.sumba.config.multiSite.enabled) return
|
|
391
|
+
const routes = ['waibuAdmin:/site/x/site/*']
|
|
392
|
+
this.app.waibu.config.route.disabled.push(...routes)
|
|
395
393
|
}
|
|
396
394
|
}]
|
|
397
395
|
}
|
|
@@ -132,14 +132,14 @@
|
|
|
132
132
|
"statusClosed": "Closed",
|
|
133
133
|
"allSites": "All Sites",
|
|
134
134
|
"permission": "Permission",
|
|
135
|
-
"
|
|
135
|
+
"anonymousGuard": "Anonymous Guard",
|
|
136
|
+
"secureGuard": "Secure Guard",
|
|
136
137
|
"modelGuard": "Model Guard",
|
|
137
138
|
"attribGuard": "Attribute Guard",
|
|
138
|
-
"xRouteGuard": "Route Guard",
|
|
139
|
-
"xModelGuard": "Model Guard",
|
|
140
|
-
"xAttribGuard": "Attribute Guard",
|
|
141
139
|
"xSite": "Cross-Site",
|
|
142
140
|
"xSiteAdminArea": "Cross-Site Admin Area",
|
|
141
|
+
"x": "Cross-Site",
|
|
142
|
+
"misc": "Miscellaneous",
|
|
143
143
|
"field": {
|
|
144
144
|
"currentPassword": "Current Password",
|
|
145
145
|
"newPassword": "New Password",
|
|
@@ -172,7 +172,8 @@
|
|
|
172
172
|
"column": "Column",
|
|
173
173
|
"hiddenCols": "Hidden Columns",
|
|
174
174
|
"models": "Models",
|
|
175
|
-
"siteIds": "Sites"
|
|
175
|
+
"siteIds": "Sites",
|
|
176
|
+
"allTeams": "All Teams?"
|
|
176
177
|
},
|
|
177
178
|
"validation": {
|
|
178
179
|
"password": {
|
package/extend/bajo/intl/id.json
CHANGED
|
@@ -138,14 +138,14 @@
|
|
|
138
138
|
"statusClosed": "Tertutup",
|
|
139
139
|
"allSites": "Semua Situs",
|
|
140
140
|
"permission": "Permisi",
|
|
141
|
-
"
|
|
141
|
+
"anonymousGuard": "Pelindung Rute Anonim",
|
|
142
|
+
"secureGuard": "Pelindung Rute Aman",
|
|
142
143
|
"modelGuard": "Pelindung Model",
|
|
143
144
|
"attribGuard": "Pelindung Atribut",
|
|
144
|
-
"xRouteGuard": "Pelindung Rute",
|
|
145
|
-
"xModelGuard": "Pelindung Model",
|
|
146
|
-
"xAttribGuard": "Pelindung Atribut",
|
|
147
145
|
"xSite": "Antar Situs",
|
|
148
146
|
"xSiteAdminArea": "Area Admin Antar Situs",
|
|
147
|
+
"x": "Antar Situs",
|
|
148
|
+
"misc": "Lain-lain",
|
|
149
149
|
"field": {
|
|
150
150
|
"currentPassword": "Kata Sandi Saat Ini",
|
|
151
151
|
"newPassword": "Kata Sandi Baru",
|
|
@@ -178,7 +178,8 @@
|
|
|
178
178
|
"column": "Kolom",
|
|
179
179
|
"hiddenCols": "Kolom Tersembunyi",
|
|
180
180
|
"models": "Model",
|
|
181
|
-
"siteIds": "Situs"
|
|
181
|
+
"siteIds": "Situs",
|
|
182
|
+
"allTeams": "Semua Tim?"
|
|
182
183
|
},
|
|
183
184
|
"validation": {
|
|
184
185
|
"password": {
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
async function status (opts = {}) {
|
|
2
2
|
opts.field = opts.field ?? 'status'
|
|
3
3
|
opts.required = opts.required ?? true
|
|
4
|
-
opts.
|
|
4
|
+
opts.default = opts.default ?? 'ACTIVE'
|
|
5
|
+
opts.values = opts.values ?? ['ACTIVE', 'INACTIVE']
|
|
5
6
|
return {
|
|
6
7
|
properties: [{
|
|
7
8
|
name: opts.field ?? 'status',
|
|
8
9
|
type: 'string',
|
|
9
10
|
maxLength: 50,
|
|
10
11
|
index: true,
|
|
12
|
+
default: opts.default,
|
|
11
13
|
required: opts.required,
|
|
12
14
|
values: opts.values
|
|
13
15
|
}],
|
package/extend/dobo/model.js
CHANGED
|
@@ -3,142 +3,102 @@ const buildEnd = async function (model) {
|
|
|
3
3
|
if (prop) prop.values = this.getModelNames(true)
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
const mgProperties = [
|
|
7
|
-
{
|
|
8
|
-
name: 'models',
|
|
9
|
-
type: 'array',
|
|
10
|
-
required: true
|
|
11
|
-
},
|
|
12
|
-
'column,,50,true,true',
|
|
13
|
-
{
|
|
14
|
-
name: 'negation',
|
|
15
|
-
type: 'boolean',
|
|
16
|
-
required: true,
|
|
17
|
-
default: false
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
name: 'status',
|
|
21
|
-
type: 'sumba:status',
|
|
22
|
-
values: ['ACTIVE', 'INACTIVE'],
|
|
23
|
-
default: 'ACTIVE'
|
|
24
|
-
},
|
|
25
|
-
'value,array,,,true',
|
|
26
|
-
'siteId,sumba:siteId',
|
|
27
|
-
'teamIds,sumba:teamIds'
|
|
28
|
-
]
|
|
29
|
-
|
|
30
6
|
const options = {
|
|
31
7
|
attachment: false,
|
|
32
8
|
cache: { ttlDur: 0 }
|
|
33
9
|
}
|
|
34
10
|
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
name: 'models',
|
|
42
|
-
type: 'array',
|
|
43
|
-
required: true
|
|
44
|
-
},
|
|
45
|
-
'hiddenCols,array',
|
|
46
|
-
'siteId,sumba:siteId',
|
|
47
|
-
'teamIds,sumba:teamIds'
|
|
48
|
-
]
|
|
49
|
-
|
|
50
|
-
const agFeatures = [
|
|
51
|
-
{
|
|
52
|
-
name: 'sumba:status',
|
|
53
|
-
values: ['ACTIVE', 'INACTIVE'],
|
|
54
|
-
default: 'ACTIVE'
|
|
55
|
-
},
|
|
56
|
-
'dobo:updatedAt'
|
|
57
|
-
]
|
|
58
|
-
|
|
59
|
-
export const rgProperties = [
|
|
60
|
-
'path,,255,true,true',
|
|
61
|
-
{
|
|
62
|
-
name: 'methods',
|
|
63
|
-
type: 'array',
|
|
64
|
-
required: true,
|
|
65
|
-
default: ['GET', 'POST', 'UPDATE', 'DELETE'],
|
|
66
|
-
values: ['GET', 'POST', 'UPDATE', 'DELETE']
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
name: 'weight',
|
|
70
|
-
type: 'smallint',
|
|
71
|
-
default: 0
|
|
72
|
-
}, {
|
|
73
|
-
name: 'negation',
|
|
74
|
-
type: 'boolean',
|
|
75
|
-
required: true,
|
|
76
|
-
default: false
|
|
77
|
-
}, {
|
|
78
|
-
name: 'anonymous',
|
|
79
|
-
type: 'boolean',
|
|
80
|
-
required: true,
|
|
81
|
-
default: false
|
|
82
|
-
},
|
|
83
|
-
'siteId,sumba:siteId',
|
|
84
|
-
'teamIds,sumba:teamIds'
|
|
85
|
-
]
|
|
11
|
+
const allTeams = {
|
|
12
|
+
name: 'allTeams',
|
|
13
|
+
type: 'boolean',
|
|
14
|
+
default: true,
|
|
15
|
+
required: true
|
|
16
|
+
}
|
|
86
17
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
18
|
+
const routeGuard = {
|
|
19
|
+
properties: [
|
|
20
|
+
{
|
|
21
|
+
name: 'path',
|
|
22
|
+
maxLength: 255,
|
|
23
|
+
required: true
|
|
24
|
+
},
|
|
25
|
+
allTeams,
|
|
26
|
+
'teamIds,sumba:teamIds',
|
|
27
|
+
{
|
|
28
|
+
name: 'weight',
|
|
29
|
+
type: 'smallint',
|
|
30
|
+
index: true,
|
|
31
|
+
default: 0
|
|
32
|
+
},
|
|
33
|
+
'siteId,sumba:siteId'
|
|
34
|
+
],
|
|
35
|
+
features: [
|
|
36
|
+
'sumba:status',
|
|
37
|
+
'dobo:updatedAt',
|
|
38
|
+
'dobo:immutable'
|
|
39
|
+
],
|
|
40
|
+
indexes: [{
|
|
41
|
+
type: 'unique',
|
|
42
|
+
fields: ['siteId', 'path']
|
|
43
|
+
}],
|
|
44
|
+
options: { ...options }
|
|
45
|
+
}
|
|
95
46
|
|
|
96
47
|
async function model () {
|
|
97
|
-
const {
|
|
48
|
+
const { merge, cloneDeep } = this.app.lib._
|
|
98
49
|
return [{
|
|
99
|
-
baseName: 'route-guard',
|
|
100
|
-
properties: rgProperties,
|
|
101
|
-
features: rgFeatures,
|
|
102
|
-
options
|
|
103
|
-
}, {
|
|
104
|
-
baseName: 'x-route-guard',
|
|
105
|
-
properties: rgProperties.filter(prop => {
|
|
106
|
-
if (!isString(prop)) return true
|
|
107
|
-
return !(prop.startsWith('teamIds') || prop.startsWith('siteId'))
|
|
108
|
-
}).concat('siteIds,sumba:siteIds'),
|
|
109
|
-
features: rgFeatures,
|
|
110
|
-
options
|
|
111
|
-
}, {
|
|
112
50
|
baseName: 'attrib-guard',
|
|
113
|
-
properties:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
51
|
+
properties: [
|
|
52
|
+
{
|
|
53
|
+
name: 'models',
|
|
54
|
+
type: 'array',
|
|
55
|
+
required: true
|
|
56
|
+
},
|
|
57
|
+
'hiddenFields,array',
|
|
58
|
+
allTeams,
|
|
59
|
+
'teamIds,sumba:teamIds',
|
|
60
|
+
'siteId,sumba:siteId'
|
|
61
|
+
],
|
|
62
|
+
features: [
|
|
63
|
+
'sumba:status',
|
|
64
|
+
'dobo:updatedAt',
|
|
65
|
+
'dobo:immutable'
|
|
66
|
+
],
|
|
67
|
+
options: { ...options },
|
|
125
68
|
buildEnd
|
|
126
69
|
}, {
|
|
127
70
|
baseName: 'model-guard',
|
|
128
|
-
properties:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
71
|
+
properties: [
|
|
72
|
+
{
|
|
73
|
+
name: 'models',
|
|
74
|
+
type: 'array',
|
|
75
|
+
required: true
|
|
76
|
+
},
|
|
77
|
+
'field,,50,true,true',
|
|
78
|
+
{
|
|
79
|
+
name: 'behavior',
|
|
80
|
+
type: 'string',
|
|
81
|
+
maxLength: 20,
|
|
82
|
+
required: true,
|
|
83
|
+
values: ['IN', 'NIN'],
|
|
84
|
+
default: 'IN'
|
|
85
|
+
},
|
|
86
|
+
'value,array,,,true',
|
|
87
|
+
allTeams,
|
|
88
|
+
'teamIds,sumba:teamIds',
|
|
89
|
+
'siteId,sumba:siteId'
|
|
90
|
+
],
|
|
91
|
+
features: [
|
|
92
|
+
'sumba:status',
|
|
93
|
+
'dobo:updatedAt',
|
|
94
|
+
'dobo:immutable'
|
|
95
|
+
],
|
|
96
|
+
options: { ...options },
|
|
140
97
|
buildEnd
|
|
141
|
-
},
|
|
98
|
+
},
|
|
99
|
+
merge(cloneDeep(routeGuard), { baseName: 'anonymous-guard' }),
|
|
100
|
+
merge(cloneDeep(routeGuard), { baseName: 'secure-guard' }),
|
|
101
|
+
{
|
|
142
102
|
buildLevel: 2,
|
|
143
103
|
baseName: 'user',
|
|
144
104
|
properties: [{
|
|
@@ -251,6 +211,37 @@ async function model () {
|
|
|
251
211
|
}
|
|
252
212
|
}
|
|
253
213
|
}]
|
|
214
|
+
}, {
|
|
215
|
+
baseName: 'ticket',
|
|
216
|
+
properties: [
|
|
217
|
+
'subject,,255,true,true',
|
|
218
|
+
{
|
|
219
|
+
name: 'cat',
|
|
220
|
+
type: 'string',
|
|
221
|
+
maxLength: 50,
|
|
222
|
+
index: true,
|
|
223
|
+
required: true,
|
|
224
|
+
values: async function ({ req } = {}) {
|
|
225
|
+
const { getModel } = this.app.dobo
|
|
226
|
+
const model = await getModel('SumbaTicketCat')
|
|
227
|
+
const opts = { req, noMagic: true, dataOnly: true, fields: ['name'] }
|
|
228
|
+
const results = await model.findAllRecords({ sort: { level: 1, name: 1 } }, opts)
|
|
229
|
+
return results.map(r => r.name)
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
'message,text,,,true'
|
|
233
|
+
],
|
|
234
|
+
features: [
|
|
235
|
+
'dobo:createdAt',
|
|
236
|
+
'dobo:updatedAt',
|
|
237
|
+
'sumba:siteId',
|
|
238
|
+
'sumba:userId',
|
|
239
|
+
{
|
|
240
|
+
name: 'sumba:status',
|
|
241
|
+
default: 'OPEN',
|
|
242
|
+
values: ['OPEN', 'CLOSED']
|
|
243
|
+
}
|
|
244
|
+
]
|
|
254
245
|
}]
|
|
255
246
|
}
|
|
256
247
|
|
package/extend/dobo/model.json
CHANGED
|
@@ -88,10 +88,7 @@
|
|
|
88
88
|
"sumba:personInCharge",
|
|
89
89
|
"sumba:address",
|
|
90
90
|
"sumba:social",
|
|
91
|
-
|
|
92
|
-
"name": "sumba:status",
|
|
93
|
-
"default": "ACTIVE"
|
|
94
|
-
},
|
|
91
|
+
"sumba:status",
|
|
95
92
|
"dobo:createdAt",
|
|
96
93
|
"dobo:updatedAt",
|
|
97
94
|
"dobo:immutable"
|
|
@@ -146,11 +143,7 @@
|
|
|
146
143
|
"dobo:updatedAt",
|
|
147
144
|
"dobo:immutable",
|
|
148
145
|
"sumba:siteId",
|
|
149
|
-
|
|
150
|
-
"name": "sumba:status",
|
|
151
|
-
"default": "ENABLED",
|
|
152
|
-
"values": ["ENABLED", "DISABLED"]
|
|
153
|
-
},
|
|
146
|
+
"sumba:status",
|
|
154
147
|
"dobo:immutable"
|
|
155
148
|
]
|
|
156
149
|
}, {
|
|
@@ -163,37 +156,6 @@
|
|
|
163
156
|
"message,text"
|
|
164
157
|
],
|
|
165
158
|
"features": ["dobo:createdAt", "sumba:userId", "sumba:siteId"]
|
|
166
|
-
}, {
|
|
167
|
-
"baseName": "ticket",
|
|
168
|
-
"properties": [
|
|
169
|
-
"subject,,255,true,true",
|
|
170
|
-
{
|
|
171
|
-
"name": "cat",
|
|
172
|
-
"type": "string",
|
|
173
|
-
"maxLength": 50,
|
|
174
|
-
"index": true,
|
|
175
|
-
"required": true,
|
|
176
|
-
"ref": {
|
|
177
|
-
"cat": {
|
|
178
|
-
"model": "SumbaTicketCat",
|
|
179
|
-
"searchField": "name",
|
|
180
|
-
"labelField": "name"
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
},
|
|
184
|
-
"message,text,,,true"
|
|
185
|
-
],
|
|
186
|
-
"features": [
|
|
187
|
-
"dobo:createdAt",
|
|
188
|
-
"dobo:updatedAt",
|
|
189
|
-
"sumba:siteId",
|
|
190
|
-
"sumba:userId",
|
|
191
|
-
{
|
|
192
|
-
"name": "sumba:status",
|
|
193
|
-
"default": "OPEN",
|
|
194
|
-
"values": ["OPEN", "CLOSED"]
|
|
195
|
-
}
|
|
196
|
-
]
|
|
197
159
|
}, {
|
|
198
160
|
"buildLevel": 5,
|
|
199
161
|
"baseName": "user-setting",
|