sumba 2.15.0 → 2.16.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/dobo@before-get-record.js +2 -3
- package/extend/bajo/intl/en-US.json +9 -5
- package/extend/bajo/intl/id.json +9 -5
- package/extend/dobo/feature/slug.js +3 -3
- package/extend/dobo/model/user-setting.json +17 -0
- package/extend/waibuDb/schema/user-setting.js +51 -0
- package/extend/waibuDb/schema/user.js +73 -0
- package/extend/waibuMpa/extend/waibuAdmin/route/site.js +1 -1
- package/extend/waibuMpa/extend/waibuAdmin/route/team/@action.js +1 -1
- package/extend/waibuMpa/extend/waibuAdmin/route/team-setting/@action.js +1 -1
- package/extend/waibuMpa/extend/waibuAdmin/route/team-user/@action.js +1 -1
- package/extend/waibuMpa/extend/waibuAdmin/route/user/@action.js +3 -2
- package/extend/waibuMpa/extend/waibuAdmin/route/user-setting/@action.js +11 -0
- package/extend/waibuMpa/route/help/contact-form.js +2 -2
- package/extend/waibuMpa/route/help/trouble-tickets/add.js +2 -2
- package/extend/waibuMpa/route/help/trouble-tickets/details/@id.js +2 -2
- package/extend/waibuMpa/route/user/activation.js +3 -3
- package/extend/waibuMpa/route/user/forgot-password/@fpl.js +4 -5
- package/extend/waibuMpa/route/user/forgot-password.js +2 -3
- package/extend/waibuMpa/route/your-stuff/profile/edit.js +1 -1
- package/extend/waibuMpa/route/your-stuff/profile.js +1 -1
- package/index.js +29 -13
- package/package.json +1 -1
- package/wiki/CHANGES.md +6 -0
- package/extend/waibuDb/schema/user.json +0 -60
|
@@ -9,9 +9,8 @@ export async function checker (modelName, id, options = {}) {
|
|
|
9
9
|
await rebuildFilter.call(this, modelName, filter, req)
|
|
10
10
|
if (filter.query.$and) filter.query.$and.push({ id })
|
|
11
11
|
else filter.query.id = id
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
if (rows.length === 0) throw this.app.dobo.error('recordNotFound%s%s', id, this.name, { statusCode: 404 })
|
|
12
|
+
const row = await model.findOneRecord(filter, { count: false })
|
|
13
|
+
if (!row) throw this.app.dobo.error('recordNotFound%s%s', id, this.name, { statusCode: 404 })
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
const doboBeforeGetRecord = {
|
|
@@ -95,12 +95,17 @@
|
|
|
95
95
|
"ticket": "Ticket",
|
|
96
96
|
"ticketCat": "Ticket Category",
|
|
97
97
|
"supportSystem": "Support System",
|
|
98
|
-
"
|
|
98
|
+
"team": "Team",
|
|
99
99
|
"manageSite": "Manage Site",
|
|
100
|
-
"manageUser": "Manage User",
|
|
101
100
|
"manageTeam": "Manage Team",
|
|
102
|
-
"
|
|
103
|
-
"
|
|
101
|
+
"manageUser": "Manage User",
|
|
102
|
+
"siteProfile": "Site Profile",
|
|
103
|
+
"siteSetting": "Site Setting",
|
|
104
|
+
"userProfile": "User Profile",
|
|
105
|
+
"userSetting": "User Setting",
|
|
106
|
+
"teamProfile": "Team Profile",
|
|
107
|
+
"teamUser": "Team User",
|
|
108
|
+
"teamSetting": "Team Setting",
|
|
104
109
|
"resetUserPassword": "Reset User Password",
|
|
105
110
|
"unknownUser": "User Unknown/Invalid",
|
|
106
111
|
"socialMedia": "Social Media",
|
|
@@ -114,7 +119,6 @@
|
|
|
114
119
|
"statusUnverified": "Unverified",
|
|
115
120
|
"statusActive": "Active",
|
|
116
121
|
"statusInactive": "Inactive",
|
|
117
|
-
"siteSetting": "Site Settings",
|
|
118
122
|
"validCountryCodeRequired": "Value must be one of valid country codes",
|
|
119
123
|
"aliasRequired": "Alias is required",
|
|
120
124
|
"aliasOrHOstnameExists%s%s": "A site with alias '%s' or hostname '%s' exists already",
|
package/extend/bajo/intl/id.json
CHANGED
|
@@ -96,12 +96,17 @@
|
|
|
96
96
|
"ticket": "Tiket",
|
|
97
97
|
"ticketCat": "Kategori Tiket",
|
|
98
98
|
"supportSystem": "Sistim Dukungan",
|
|
99
|
-
"
|
|
99
|
+
"team": "Tim",
|
|
100
100
|
"manageSite": "Kelola Situs",
|
|
101
|
-
"manageUser": "Kelola Pengguna",
|
|
102
101
|
"manageTeam": "Kelola Tim",
|
|
103
|
-
"
|
|
104
|
-
"
|
|
102
|
+
"manageUser": "Kelola Pengguna",
|
|
103
|
+
"siteProfile": "Profil Situs",
|
|
104
|
+
"siteSetting": "Pengaturan Situs",
|
|
105
|
+
"userProfile": "Profil Pengguna",
|
|
106
|
+
"userSetting": "Pengaturan Pengguna",
|
|
107
|
+
"teamProfile": "Profil Tim",
|
|
108
|
+
"teamUser": "Anggota Tim",
|
|
109
|
+
"teamSetting": "Pengaturan Tim",
|
|
105
110
|
"resetUserPassword": "Reset Kata Sandi Pengguna",
|
|
106
111
|
"unknownUser": "Pengguna Tidak Dikenal/Tidak Valid",
|
|
107
112
|
"socialMedia": "Media Sosial",
|
|
@@ -115,7 +120,6 @@
|
|
|
115
120
|
"statusUnverified": "Belum Terverifikasi",
|
|
116
121
|
"statusActive": "Aktif",
|
|
117
122
|
"statusInactive": "Non Aktif",
|
|
118
|
-
"siteSetting": "Setelan Situs",
|
|
119
123
|
"validCountryCodeRequired": "Nilai harus salah satu dari kode negara yang berlaku",
|
|
120
124
|
"aliasRequired": "Alias tidak boleh kosong",
|
|
121
125
|
"aliasOrHOstnameExists%s%s": "Situs dengan alias '%s' atau nama host '%s' telah ada",
|
|
@@ -5,9 +5,9 @@ async function autoInc (body, opts) {
|
|
|
5
5
|
const query = set({}, opts.fieldName, { $regex: new RegExp('^' + body[opts.fieldName]) })
|
|
6
6
|
const sort = set({}, opts.fieldName, -1)
|
|
7
7
|
const options = { noHook: true, skipCache: true, thrownNotFound: false }
|
|
8
|
-
const resp = await this.
|
|
9
|
-
if (resp
|
|
10
|
-
const rslugs = resp[
|
|
8
|
+
const resp = await this.findOneRecord({ query, sort }, options)
|
|
9
|
+
if (resp) return body[opts.fieldName]
|
|
10
|
+
const rslugs = resp[opts.fieldName].split('-')
|
|
11
11
|
const slugs = body[opts.fieldName].split('-')
|
|
12
12
|
let num
|
|
13
13
|
if (Number(last(rslugs)) && body[opts.fieldName] === rslugs.slice(0, rslugs.length - 1).join('-')) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"buildLevel": 5,
|
|
3
|
+
"properties": [
|
|
4
|
+
"ns,,50,true,true",
|
|
5
|
+
"key,,255,true,true",
|
|
6
|
+
"value,text"
|
|
7
|
+
],
|
|
8
|
+
"indexes": [{
|
|
9
|
+
"fields": ["ns", "key", "siteId", "userId"],
|
|
10
|
+
"type": "unique"
|
|
11
|
+
}],
|
|
12
|
+
"features": [
|
|
13
|
+
"sumba:siteId",
|
|
14
|
+
"dobo:updatedAt",
|
|
15
|
+
"sumba:userId"
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
async function teamUser ({ req } = {}) {
|
|
2
|
+
return {
|
|
3
|
+
common: {
|
|
4
|
+
layout: [
|
|
5
|
+
{ name: 'meta', fields: ['id', 'userId', 'createdAt', 'updatedAt'] },
|
|
6
|
+
{ name: 'general', fields: ['ns', 'key', 'value'] }
|
|
7
|
+
],
|
|
8
|
+
calcFields: [
|
|
9
|
+
{ name: 'user', type: 'string' }
|
|
10
|
+
],
|
|
11
|
+
valueFormatter: {
|
|
12
|
+
user: (val, rec) => {
|
|
13
|
+
return rec._ref.user.name
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
widget: {
|
|
17
|
+
userId: {
|
|
18
|
+
component: 'form-select-ext',
|
|
19
|
+
attr: {
|
|
20
|
+
remoteUrl: 'sumba.restapi:/manage/user',
|
|
21
|
+
remoteSearchField: 'name',
|
|
22
|
+
remoteLabelField: 'name',
|
|
23
|
+
remoteApiKey: true,
|
|
24
|
+
ref: 'user:name'
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
view: {
|
|
30
|
+
list: {
|
|
31
|
+
fields: ['user', 'ns', 'key', 'value', 'createdAt', 'updatedAt'],
|
|
32
|
+
stat: {
|
|
33
|
+
aggregate: [
|
|
34
|
+
{ fields: ['userId'], group: 'userId', aggregate: ['count'] },
|
|
35
|
+
{ fields: ['teamId'], group: 'teamId', aggregate: ['count'] }
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
details: {
|
|
40
|
+
},
|
|
41
|
+
add: {
|
|
42
|
+
hidden: ['id', 'createdAt', 'updatedAt']
|
|
43
|
+
},
|
|
44
|
+
edit: {
|
|
45
|
+
readonly: ['id', 'createdAt', 'updatedAt']
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export default teamUser
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
async function user ({ req } = {}) {
|
|
2
|
+
return {
|
|
3
|
+
common: {
|
|
4
|
+
layout: [
|
|
5
|
+
{ name: 'meta', fields: ['id:3', 'createdAt:3', 'updatedAt:3', 'status:3'] },
|
|
6
|
+
{ name: 'account', fields: ['username:3', 'email:3', 'provider:3', 'password:3', 'firstName:3', 'lastName:3', 'token:6'] },
|
|
7
|
+
{ name: 'address', fields: ['address1:12', 'address2:12', 'city:6-md 8-sm', 'zipCode:2-md 4-sm', 'provinceState:4-md', 'country:6-md', 'phone:6-md', 'website:12'] },
|
|
8
|
+
{ name: 'socialMedia', fields: ['socX:3-md 6-sm', 'socInstagram:3-md 6-sm', 'socFacebook:3-md 6-sm', 'socLinkedIn:3-md 6-sm'] }
|
|
9
|
+
],
|
|
10
|
+
valueFormatter: {
|
|
11
|
+
token: async function (val, rec) {
|
|
12
|
+
const { hash } = this.app.bajoExtra
|
|
13
|
+
return await hash(rec.salt)
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
widget: {
|
|
17
|
+
country: {
|
|
18
|
+
component: 'form-select-ext'
|
|
19
|
+
},
|
|
20
|
+
token: {
|
|
21
|
+
component: 'form-plaintext'
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
view: {
|
|
26
|
+
list: {
|
|
27
|
+
qs: {
|
|
28
|
+
sort: 'username:1',
|
|
29
|
+
limit: 10
|
|
30
|
+
},
|
|
31
|
+
fields: ['createdAt', 'status', 'username', 'provider', 'email', 'firstName', 'lastName', 'city', 'zipCode', 'provinceState', 'country', 'phone'],
|
|
32
|
+
stat: {
|
|
33
|
+
aggregate: [
|
|
34
|
+
{ fields: ['status'], group: 'status', aggregate: ['count'] },
|
|
35
|
+
{ fields: ['provider'], group: 'provider', aggregate: ['count'] },
|
|
36
|
+
{ fields: ['country'], group: 'country', aggregate: ['count'] }
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
details: {
|
|
41
|
+
forceVisible: ['password', 'token'],
|
|
42
|
+
widget: {
|
|
43
|
+
password: {
|
|
44
|
+
component: 'form-plaintext',
|
|
45
|
+
attr: {
|
|
46
|
+
href: 'waibuAdmin:/site/reset-user-password?username={username}',
|
|
47
|
+
value: req.t('resetPassword')
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
add: {
|
|
53
|
+
forceVisible: ['password'],
|
|
54
|
+
hidden: ['id', 'createdAt', 'updatedAt', 'provider']
|
|
55
|
+
},
|
|
56
|
+
edit: {
|
|
57
|
+
forceVisible: ['password', 'token'],
|
|
58
|
+
widget: {
|
|
59
|
+
password: {
|
|
60
|
+
component: 'form-plaintext',
|
|
61
|
+
attr: {
|
|
62
|
+
href: 'waibuAdmin:/site/reset-user-password?username={username}',
|
|
63
|
+
value: req.t('resetPassword')
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
readonly: ['id', 'createdAt', 'updatedAt', 'username', 'provider']
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export default user
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
const action = {
|
|
2
2
|
method: ['GET', 'POST'],
|
|
3
|
-
title: '
|
|
3
|
+
title: 'userProfile',
|
|
4
4
|
handler: async function (req, reply) {
|
|
5
5
|
const { importModule } = this.app.bajo
|
|
6
6
|
const crudSkel = await importModule('waibuAdmin:/lib/crud-skel.js')
|
|
7
|
-
|
|
7
|
+
const options = { modelOpts: { forceNoHidden: ['token'] } }
|
|
8
|
+
return await crudSkel.call(this, 'SumbaUser', req, reply, { options })
|
|
8
9
|
}
|
|
9
10
|
}
|
|
10
11
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const action = {
|
|
2
|
+
method: ['GET', 'POST'],
|
|
3
|
+
title: 'userSetting',
|
|
4
|
+
handler: async function (req, reply) {
|
|
5
|
+
const { importModule } = this.app.bajo
|
|
6
|
+
const crudSkel = await importModule('waibuAdmin:/lib/crud-skel.js')
|
|
7
|
+
return await crudSkel.call(this, 'SumbaUserSetting', req, reply)
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default action
|
|
@@ -3,7 +3,7 @@ const contactForm = {
|
|
|
3
3
|
handler: async function (req, reply) {
|
|
4
4
|
const { defaultsDeep } = this.app.lib.aneka
|
|
5
5
|
const { pick } = this.app.lib._
|
|
6
|
-
const { createRecord,
|
|
6
|
+
const { createRecord, findAllRecord } = this.app.waibuDb
|
|
7
7
|
|
|
8
8
|
const def = req.user ? pick(req.user, ['firstName', 'lastName', 'email']) : {}
|
|
9
9
|
const form = defaultsDeep(req.body, def)
|
|
@@ -17,7 +17,7 @@ const contactForm = {
|
|
|
17
17
|
error = err
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
const cats = await
|
|
20
|
+
const cats = await findAllRecord({ model: 'SumbaContactFormCat', req, options: { sort: 'level:1+name:1', dataOnly: true } })
|
|
21
21
|
return await reply.view('sumba.template:/help/contact-form/form.html', { form, error, cats })
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -4,7 +4,7 @@ const add = {
|
|
|
4
4
|
method: ['GET', 'POST'],
|
|
5
5
|
handler: async function (req, reply) {
|
|
6
6
|
const { defaultsDeep } = this.app.lib.aneka
|
|
7
|
-
const { createRecord,
|
|
7
|
+
const { createRecord, findAllRecord } = this.app.waibuDb
|
|
8
8
|
const options = {}
|
|
9
9
|
const form = defaultsDeep(req.body, {})
|
|
10
10
|
let error
|
|
@@ -16,7 +16,7 @@ const add = {
|
|
|
16
16
|
error = err
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
const cats = await
|
|
19
|
+
const cats = await findAllRecord({ model: 'SumbaTicketCat', req, options: { sort: 'level:1+name:1', dataOnly: true } })
|
|
20
20
|
return await reply.view('sumba.template:/help/trouble-tickets/add.html', { form, error, cats })
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -4,10 +4,10 @@ const id = {
|
|
|
4
4
|
method: ['GET', 'POST'],
|
|
5
5
|
handler: async function (req, reply) {
|
|
6
6
|
const { cloneDeep } = this.app.lib._
|
|
7
|
-
const { createRecord, findRecord, getSchemaExt } = this.app.waibuDb
|
|
7
|
+
const { createRecord, findOneRecord, findRecord, getSchemaExt } = this.app.waibuDb
|
|
8
8
|
const { schema } = await getSchemaExt(model, 'list')
|
|
9
9
|
|
|
10
|
-
const master =
|
|
10
|
+
const master = await findOneRecord({ model: 'SumbaTicket', req, options: { dataOnly: true, query: { id: req.params.id } } })
|
|
11
11
|
if (!master) throw this.error('_notFound')
|
|
12
12
|
const form = cloneDeep(req.body)
|
|
13
13
|
let error
|
|
@@ -8,10 +8,10 @@ const userActivation = {
|
|
|
8
8
|
if (req.method === 'POST') {
|
|
9
9
|
try {
|
|
10
10
|
const query = { status: 'UNVERIFIED', token: req.body.key }
|
|
11
|
-
const result = await model.
|
|
12
|
-
if (result
|
|
11
|
+
const result = await model.findOneRecord({ query })
|
|
12
|
+
if (result) throw this.error('validationError', { details: [{ field: 'key', error: 'invalidActivationKey' }] })
|
|
13
13
|
await model.transaction(async (trx) => {
|
|
14
|
-
await model.updateRecord(result
|
|
14
|
+
await model.updateRecord(result.id, { status: 'ACTIVE' }, { req, noValidation: true, noFlash: true, trx })
|
|
15
15
|
})
|
|
16
16
|
req.flash('notify', req.t('userActivated'))
|
|
17
17
|
return reply.redirectTo(this.config.redirect.signin, req)
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
|
|
2
1
|
async function getUser (req, reply) {
|
|
3
2
|
const { dayjs } = this.app.lib
|
|
4
|
-
const {
|
|
3
|
+
const { findOneRecord } = this.app.waibuDb
|
|
5
4
|
const invalidFpl = 'sumba.template:/user/fpl-invalid.html'
|
|
6
5
|
if (Buffer.from(req.params.fpl, 'base64').toString('base64') !== req.params.fpl) return invalidFpl
|
|
7
6
|
const fpToken = Buffer.from(req.params.fpl, 'base64').toString()
|
|
8
7
|
const [token, sec] = fpToken.split(':')
|
|
9
8
|
if (dayjs().unix() > Number(sec)) return invalidFpl
|
|
10
9
|
const query = { token, status: 'ACTIVE' }
|
|
11
|
-
const
|
|
12
|
-
if (
|
|
13
|
-
return
|
|
10
|
+
const user = await findOneRecord({ model: 'SumbaUser', req, options: { query, dataOnly: true, noHook: true } })
|
|
11
|
+
if (user) return invalidFpl
|
|
12
|
+
return user
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
const forgotPasswordLink = {
|
|
@@ -11,9 +11,8 @@ const profile = {
|
|
|
11
11
|
if (req.method === 'POST') {
|
|
12
12
|
try {
|
|
13
13
|
const query = { status: 'ACTIVE', $or: [{ username: req.body.usernameEmail }, { email: req.body.usernameEmail }] }
|
|
14
|
-
const
|
|
15
|
-
if (
|
|
16
|
-
const data = result[0]
|
|
14
|
+
const data = await model.findOneRecord({ query }, { dataOnly: true, noHook: true, forceNoHidden: true })
|
|
15
|
+
if (data) throw this.error('validationError', { details: [{ field: 'usernameEmail', error: 'unknownUsernameEmailOrInactive' }] })
|
|
17
16
|
const to = `${data.firstName} ${data.lastName} <${data.email}>`
|
|
18
17
|
const subject = req.t('forgotPasswordLink')
|
|
19
18
|
const options = { req, reply }
|
|
@@ -8,7 +8,7 @@ const profile = {
|
|
|
8
8
|
const { updateRecord, getRecord } = this.app.waibuDb
|
|
9
9
|
const { omit, pick } = this.app.lib._
|
|
10
10
|
const { hash } = this.app.bajoExtra
|
|
11
|
-
const resp = await getRecord({ model: 'SumbaUser', req, id: req.user.id, options: { forceNoHidden:
|
|
11
|
+
const resp = await getRecord({ model: 'SumbaUser', req, id: req.user.id, options: { forceNoHidden: ['token'], noHook: true, noCache: true } })
|
|
12
12
|
let form = defaultsDeep(req.body, omit(resp.data, ['password', 'salt']))
|
|
13
13
|
form.token = await hash(form.token)
|
|
14
14
|
let error
|
|
@@ -3,7 +3,7 @@ const profile = {
|
|
|
3
3
|
handler: async function (req, reply) {
|
|
4
4
|
const { hash } = this.app.bajoExtra
|
|
5
5
|
const { getRecord } = this.app.waibuDb
|
|
6
|
-
const options = { forceNoHidden:
|
|
6
|
+
const options = { forceNoHidden: ['token'], noHook: true, noCache: true, attachment: true, mimeType: true }
|
|
7
7
|
const resp = await getRecord({ model: 'SumbaUser', req, id: req.user.id, options })
|
|
8
8
|
const form = resp.data
|
|
9
9
|
form.token = await hash(form.salt)
|
package/index.js
CHANGED
|
@@ -205,7 +205,27 @@ async function factory (pkgName) {
|
|
|
205
205
|
if (!this.app.waibuAdmin) return
|
|
206
206
|
const { getPluginPrefix } = this.app.waibu
|
|
207
207
|
const prefix = getPluginPrefix(this.ns)
|
|
208
|
-
|
|
208
|
+
const items = [{
|
|
209
|
+
title: 'manageSite',
|
|
210
|
+
children: [
|
|
211
|
+
{ title: 'siteProfile', href: `waibuAdmin:/${prefix}/site` },
|
|
212
|
+
{ title: 'siteSetting', href: `waibuAdmin:/${prefix}/site-setting/list` }
|
|
213
|
+
]
|
|
214
|
+
}, {
|
|
215
|
+
title: 'manageUser',
|
|
216
|
+
children: [
|
|
217
|
+
{ title: 'userProfile', href: `waibuAdmin:/${prefix}/user/list` },
|
|
218
|
+
{ title: 'userSetting', href: `waibuAdmin:/${prefix}/user-setting/list` },
|
|
219
|
+
{ title: 'resetUserPassword', href: `waibuAdmin:/${prefix}/reset-user-password` }
|
|
220
|
+
]
|
|
221
|
+
}, {
|
|
222
|
+
title: 'manageTeam',
|
|
223
|
+
children: [
|
|
224
|
+
{ title: 'teamProfile', href: `waibuAdmin:/${prefix}/team/list` },
|
|
225
|
+
{ title: 'teamUser', href: `waibuAdmin:/${prefix}/team-user/list` },
|
|
226
|
+
{ title: 'teamSetting', href: `waibuAdmin:/${prefix}/team-setting/list` }
|
|
227
|
+
]
|
|
228
|
+
}, {
|
|
209
229
|
title: 'supportSystem',
|
|
210
230
|
children: [
|
|
211
231
|
{ title: 'contactForm', href: `waibuAdmin:/${prefix}/contact-form/list` },
|
|
@@ -214,17 +234,9 @@ async function factory (pkgName) {
|
|
|
214
234
|
{ title: 'ticketCat', href: `waibuAdmin:/${prefix}/ticket-cat/list` }
|
|
215
235
|
]
|
|
216
236
|
}, {
|
|
217
|
-
title: '
|
|
237
|
+
title: 'misc',
|
|
218
238
|
children: [
|
|
219
|
-
{ title: '
|
|
220
|
-
{ title: 'manageUser', href: `waibuAdmin:/${prefix}/user/list` },
|
|
221
|
-
{ title: 'manageTeam', href: `waibuAdmin:/${prefix}/team/list` },
|
|
222
|
-
{ title: 'manageTeamUser', href: `waibuAdmin:/${prefix}/team-user/list` },
|
|
223
|
-
{ title: 'manageTeamSetting', href: `waibuAdmin:/${prefix}/team-setting/list` },
|
|
224
|
-
{ title: 'manageDownload', href: `waibuAdmin:/${prefix}/download/list` },
|
|
225
|
-
{ title: '-' },
|
|
226
|
-
{ title: 'siteSetting', href: `waibuAdmin:/${prefix}/site-setting/list` },
|
|
227
|
-
{ title: 'resetUserPassword', href: `waibuAdmin:/${prefix}/reset-user-password` }
|
|
239
|
+
{ title: 'manageDownload', href: `waibuAdmin:/${prefix}/download/list` }
|
|
228
240
|
]
|
|
229
241
|
}, {
|
|
230
242
|
title: 'manageAllSite',
|
|
@@ -237,10 +249,14 @@ async function factory (pkgName) {
|
|
|
237
249
|
title: 'misc',
|
|
238
250
|
interSite: true,
|
|
239
251
|
children: [
|
|
240
|
-
{ title: 'userSession', href: `waibuAdmin:/${prefix}/_is_/session/list` }
|
|
241
|
-
{ title: 'cacheStorage', href: `waibuAdmin:/${prefix}/_is_/cache/list` }
|
|
252
|
+
{ title: 'userSession', href: `waibuAdmin:/${prefix}/_is_/session/list` }
|
|
242
253
|
]
|
|
243
254
|
}]
|
|
255
|
+
if (this.app.bajoCache) {
|
|
256
|
+
const item = items.find(i => i.title === 'misc')
|
|
257
|
+
if (item) item.children.push({ title: 'cacheStorage', href: `waibuAdmin:/${prefix}/_is_/cache/list` })
|
|
258
|
+
}
|
|
259
|
+
return items
|
|
244
260
|
}
|
|
245
261
|
|
|
246
262
|
createJwtFromUserRecord = async (rec) => {
|
package/package.json
CHANGED
package/wiki/CHANGES.md
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-04-02
|
|
4
|
+
|
|
5
|
+
- [2.16.0] Add ```SumbaUserSetting``` model and necessary handlings
|
|
6
|
+
- [2.16.0] Reorganize admin menu
|
|
7
|
+
|
|
3
8
|
## 2026-03-30
|
|
4
9
|
|
|
5
10
|
- [2.15.0] Add inter site module mechanism
|
|
6
11
|
- [2.15.0] Add admin sub route for inter site modules
|
|
7
12
|
- [2.15.0] Bug fix in ```createNewSite()```
|
|
8
13
|
- [2.15.0] Bug fix in ```removeSite()```
|
|
14
|
+
- [2.15.1] Code cleanups
|
|
9
15
|
|
|
10
16
|
## 2026-03-27
|
|
11
17
|
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"common": {
|
|
3
|
-
"layout": [
|
|
4
|
-
{ "name": "meta", "fields": ["id:3", "createdAt:3", "updatedAt:3", "status:3"] },
|
|
5
|
-
{ "name": "account", "fields": ["username", "email", "provider", "password", "firstName", "lastName"] },
|
|
6
|
-
{ "name": "address", "fields": ["address1:12", "address2:12", "city:6-md 8-sm", "zipCode:2-md 4-sm", "provinceState:4-md", "country:6-md", "phone:6-md", "website:12"] },
|
|
7
|
-
{ "name": "socialMedia", "fields": ["socX:3-md 6-sm", "socInstagram:3-md 6-sm", "socFacebook:3-md 6-sm", "socLinkedIn:3-md 6-sm"] }
|
|
8
|
-
],
|
|
9
|
-
"widget": {
|
|
10
|
-
"country": {
|
|
11
|
-
"component": "form-select-ext"
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"view": {
|
|
16
|
-
"list": {
|
|
17
|
-
"qs": {
|
|
18
|
-
"sort": "username:1",
|
|
19
|
-
"limit": 10
|
|
20
|
-
},
|
|
21
|
-
"fields": ["createdAt", "status", "username", "provider", "email", "firstName", "lastName", "city", "zipCode", "provinceState", "country", "phone"],
|
|
22
|
-
"stat": {
|
|
23
|
-
"aggregate": [
|
|
24
|
-
{ "fields": ["status"], "group": "status", "aggregate": ["count"] },
|
|
25
|
-
{ "fields": ["provider"], "group": "provider", "aggregate": ["count"] },
|
|
26
|
-
{ "fields": ["country"], "group": "country", "aggregate": ["count"] }
|
|
27
|
-
]
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
"details": {
|
|
31
|
-
"forceVisible": ["password"],
|
|
32
|
-
"widget": {
|
|
33
|
-
"password": {
|
|
34
|
-
"component": "form-plaintext",
|
|
35
|
-
"attr": {
|
|
36
|
-
"href": "waibuAdmin:/site/reset-user-password?username={username}",
|
|
37
|
-
"value": "resetPassword"
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
"add": {
|
|
43
|
-
"forceVisible": ["password"],
|
|
44
|
-
"hidden": ["id", "createdAt", "updatedAt", "provider"]
|
|
45
|
-
},
|
|
46
|
-
"edit": {
|
|
47
|
-
"forceVisible": ["password"],
|
|
48
|
-
"widget": {
|
|
49
|
-
"password": {
|
|
50
|
-
"component": "form-plaintext",
|
|
51
|
-
"attr": {
|
|
52
|
-
"href": "waibuAdmin:/site/reset-user-password?username={username}",
|
|
53
|
-
"value": "resetPassword"
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
"readonly": ["id", "createdAt", "updatedAt", "username", "provider"]
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|