sumba 1.0.26 → 1.0.28
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/bajo/hook/waibu-mpa@pre-parsing.js +2 -0
- package/bajo/hook/waibu-rest-api@pre-parsing.js +2 -0
- package/bajo/hook/waibu-static@pre-parsing.js +2 -0
- package/bajo/hook/waibu@after-app-boot.js +6 -2
- package/bajo/intl/en-US.json +6 -2
- package/bajo/intl/id.json +6 -2
- package/bajo/method/check-paths/by-guard.js +11 -0
- package/bajo/method/check-paths/by-role.js +19 -0
- package/bajo/method/check-paths/by-routes.js +15 -0
- package/bajo/method/get-user.js +1 -3
- package/bajo/method/unsafe-user-fields.js +1 -0
- package/bajoTemplate/partial/_mail/user-signup-success.html +1 -1
- package/bajoTemplate/partial/_mail/user-signup-success.id.html +1 -1
- package/dobo/feature/role-id.js +19 -0
- package/dobo/feature/site-id.js +2 -2
- package/dobo/feature/user-id.js +5 -1
- package/dobo/fixture/role-user.json +5 -0
- package/dobo/fixture/role.json +6 -0
- package/dobo/schema/role-user.json +15 -0
- package/dobo/schema/role.json +19 -0
- package/lib/check-role.js +32 -0
- package/lib/check-user-id.js +60 -67
- package/lib/collect-roles.js +44 -0
- package/lib/collect-routes.js +18 -39
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import checkUserId from '../../lib/check-user-id.js'
|
|
2
2
|
import checkTheme from '../../lib/check-theme.js'
|
|
3
3
|
import checkIconset from '../../lib/check-iconset.js'
|
|
4
|
+
import checkRole from '../../lib/check-role.js'
|
|
4
5
|
|
|
5
6
|
const preParsing = {
|
|
6
7
|
level: 10,
|
|
@@ -10,6 +11,7 @@ const preParsing = {
|
|
|
10
11
|
await checkTheme.call(this, req, reply)
|
|
11
12
|
await checkIconset.call(this, req, reply)
|
|
12
13
|
await checkUserId.call(this, req, reply, 'waibuMpa')
|
|
14
|
+
await checkRole.call(this, req, reply, 'waibuMpa')
|
|
13
15
|
req.menu = req.menu ?? {}
|
|
14
16
|
if (req.user) {
|
|
15
17
|
req.menu.user = [
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import checkUserId from '../../lib/check-user-id.js'
|
|
2
|
+
import checkRole from '../../lib/check-role.js'
|
|
2
3
|
|
|
3
4
|
const onRequest = {
|
|
4
5
|
level: 10,
|
|
5
6
|
handler: async function (req, reply) {
|
|
6
7
|
await checkUserId.call(this, req, reply, 'waibuRestApi')
|
|
8
|
+
await checkRole.call(this, req, reply, 'waibuRestApi')
|
|
7
9
|
}
|
|
8
10
|
}
|
|
9
11
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import checkUserId from '../../lib/check-user-id.js'
|
|
2
|
+
import checkRole from '../../lib/check-role.js'
|
|
2
3
|
|
|
3
4
|
const onRequest = {
|
|
4
5
|
level: 10,
|
|
5
6
|
handler: async function (req, reply) {
|
|
6
7
|
await checkUserId.call(this, req, reply, 'waibuStatic')
|
|
8
|
+
await checkRole.call(this, req, reply, 'waibuStatic')
|
|
7
9
|
}
|
|
8
10
|
}
|
|
9
11
|
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import collectRoutes from '../../lib/collect-routes.js'
|
|
2
|
+
import collectRoles from '../../lib/collect-roles.js'
|
|
2
3
|
|
|
3
4
|
async function afterAppBoot () {
|
|
4
5
|
this.log.trace('collectingRouteGuards')
|
|
5
6
|
await collectRoutes.call(this, 'secure')
|
|
6
7
|
await collectRoutes.call(this, 'anonymous')
|
|
7
8
|
this.log.trace('secureRoutes%d', this.secureRoutes.length)
|
|
8
|
-
this.log.trace('
|
|
9
|
+
this.log.trace('secureNegRoutes%d', this.secureNegRoutes.length)
|
|
9
10
|
this.log.trace('anonRoutes%d', this.anonymousRoutes.length)
|
|
10
|
-
this.log.trace('
|
|
11
|
+
this.log.trace('anonNegRoutes%d', this.anonymousNegRoutes.length)
|
|
12
|
+
this.log.trace('collectingRoleGuards')
|
|
13
|
+
await collectRoles.call(this)
|
|
14
|
+
this.log.trace('roles%d', this.roles.length)
|
|
11
15
|
}
|
|
12
16
|
|
|
13
17
|
export default afterAppBoot
|
package/bajo/intl/en-US.json
CHANGED
|
@@ -61,9 +61,9 @@
|
|
|
61
61
|
"warningMemberOnly%s": "Please authenticate yourself first, because the <a href=\"%s\">page<a> your're trying to access is a member only page",
|
|
62
62
|
"collectingRouteGuards": "Collecting route guards:",
|
|
63
63
|
"secureRoutes%d": "- Secure routes: %d",
|
|
64
|
-
"
|
|
64
|
+
"secureNegRoutes%d": "- Secure, negated routes: %d",
|
|
65
65
|
"anonRoutes%d": "- Anonymous routes: %d",
|
|
66
|
-
"
|
|
66
|
+
"anonNegRoutes%d": "- Anonymous, negated routes: %d",
|
|
67
67
|
"replies": "Replies",
|
|
68
68
|
"compose": "Compose",
|
|
69
69
|
"yourReply": "Your Reply",
|
|
@@ -74,6 +74,10 @@
|
|
|
74
74
|
"emailSent": "An email has been sent to your address",
|
|
75
75
|
"forgotPasswordLink": "Forgot Password Link",
|
|
76
76
|
"forgotPasswordChanged": "Password Successfully Changed",
|
|
77
|
+
"collectingRoleGuards": "Collecting role guards:",
|
|
78
|
+
"roles%d": "- Roles: %d",
|
|
79
|
+
"negRoles%d": "- Negated Roles: %d",
|
|
80
|
+
"permissionDenied": "Permission Denied",
|
|
77
81
|
"field": {
|
|
78
82
|
"currentPassword": "Current Password",
|
|
79
83
|
"newPassword": "New Password",
|
package/bajo/intl/id.json
CHANGED
|
@@ -61,9 +61,9 @@
|
|
|
61
61
|
"warningMemberOnly%s": "Silahkan melalukan otentikasi terlebih dahulu karena <a href=\"%s\">halaman<a> yang akan Anda akses adalah salah satu halaman khusus anggota saja",
|
|
62
62
|
"collectingRouteGuards": "Mengoleksi pertahanan jalur:",
|
|
63
63
|
"secureRoutes%d": "- Jalur aman: %d",
|
|
64
|
-
"
|
|
64
|
+
"secureNegRoutes%d": "- Jalur aman, dinegasikan: %d",
|
|
65
65
|
"anonRoutes%d": "- Jalur anonim: %d",
|
|
66
|
-
"
|
|
66
|
+
"anonNegRoutes%d": "- Jalur anonim, dinegasikan: %d",
|
|
67
67
|
"conversation": "Percakapan",
|
|
68
68
|
"replies": "Balas Berbalas",
|
|
69
69
|
"compose": "Tulis",
|
|
@@ -75,6 +75,10 @@
|
|
|
75
75
|
"emailSent": "Sebuah surel telah dikirim ke alamat Anda",
|
|
76
76
|
"forgotPasswordLink": "Tautan Lupa Kata Sandi",
|
|
77
77
|
"forgotPasswordChanged": "Kata Sandi Sukses Diubah",
|
|
78
|
+
"collectingRoleGuards": "Mengoleksi pertahanan peran:",
|
|
79
|
+
"roles%d": "- Peran: %d",
|
|
80
|
+
"negRoles%d": "- Peran, dinegasikan: %d",
|
|
81
|
+
"permissionDenied": "Permisi Ditolak",
|
|
78
82
|
"field": {
|
|
79
83
|
"currentPassword": "Kata Sandi Saat Ini",
|
|
80
84
|
"newPassword": "Kata Sandi Baru",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function byRole ({ paths = [], method = 'GET', roles = [], guards = [] }) {
|
|
2
|
+
const { includes } = this.app.bajo
|
|
3
|
+
const { outmatch } = this.app.bajo.lib
|
|
4
|
+
|
|
5
|
+
for (const item of guards) {
|
|
6
|
+
const matchPath = outmatch(item.path)
|
|
7
|
+
for (const path of paths) {
|
|
8
|
+
if (matchPath(path)) {
|
|
9
|
+
const matchMethods = outmatch(item.methods)
|
|
10
|
+
if (matchMethods(method)) {
|
|
11
|
+
if (item.values.length === 0) return item
|
|
12
|
+
if (includes(roles, item.values)) return item
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default byRole
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function byRoutes ({ paths = [], method = 'GET', guards = [] }) {
|
|
2
|
+
const { outmatch } = this.app.bajo.lib
|
|
3
|
+
|
|
4
|
+
for (const item of guards) {
|
|
5
|
+
const matchPath = outmatch(item.path)
|
|
6
|
+
for (const path of paths) {
|
|
7
|
+
if (matchPath(path)) {
|
|
8
|
+
const matchMethods = outmatch(item.values)
|
|
9
|
+
if (matchMethods(method)) return item
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default byRoutes
|
package/bajo/method/get-user.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
const unsafeFields = ['password']
|
|
2
|
-
|
|
3
1
|
async function getUser (rec, safe = true) {
|
|
4
2
|
const { recordGet } = this.app.dobo
|
|
5
3
|
const { omit, isPlainObject } = this.app.bajo.lib._
|
|
@@ -7,7 +5,7 @@ async function getUser (rec, safe = true) {
|
|
|
7
5
|
let user
|
|
8
6
|
if (isPlainObject(rec)) user = rec
|
|
9
7
|
else user = await recordGet('SumbaUser', rec, { noHook: true })
|
|
10
|
-
return safe ? omit(user,
|
|
8
|
+
return safe ? omit(user, this.unsafeUserFields) : user
|
|
11
9
|
}
|
|
12
10
|
|
|
13
11
|
export default getUser
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default ['password']
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<p>Welcome and thank your for joining us in <%=
|
|
1
|
+
<p>Welcome and thank your for joining us in <%= _meta.site.title %>.
|
|
2
2
|
Please click the following link to activate your account:</p>
|
|
3
3
|
|
|
4
4
|
<p><% const url = _meta.hostHeader + _routePath("sumba:/user/activation") + "?key=" + token %>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<p>Selamat datang dan telah bergabung di <%=
|
|
1
|
+
<p>Selamat datang dan telah bergabung di <%= _meta.site.title %>. Selanjutnya,
|
|
2
2
|
silahkan mengklik link dibawah ini untuk melakukan aktivasi akun anda:</p>
|
|
3
3
|
|
|
4
4
|
<p><% const url = _meta.hostHeader + _routePath("sumba:/user/activation") + "?key=" + token %>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
async function roleId (opts = {}) {
|
|
2
|
+
return {
|
|
3
|
+
properties: [{
|
|
4
|
+
name: 'roleId',
|
|
5
|
+
type: 'string',
|
|
6
|
+
maxLength: 50,
|
|
7
|
+
rel: {
|
|
8
|
+
site: {
|
|
9
|
+
schema: 'SumbaSite',
|
|
10
|
+
propName: 'id',
|
|
11
|
+
type: 'one-to-one'
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
index: true
|
|
15
|
+
}]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default roleId
|
package/dobo/feature/site-id.js
CHANGED
package/dobo/feature/user-id.js
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"properties": [
|
|
3
|
+
"alias::20::true",
|
|
4
|
+
"name::50:true:true"
|
|
5
|
+
],
|
|
6
|
+
"indexes": [{
|
|
7
|
+
"fields": ["alias", "siteId"],
|
|
8
|
+
"unique": true
|
|
9
|
+
}],
|
|
10
|
+
"feature": {
|
|
11
|
+
"createdAt": true,
|
|
12
|
+
"updatedAt": true,
|
|
13
|
+
"sumba.siteId": true,
|
|
14
|
+
"sumba.status": {
|
|
15
|
+
"default": "ENABLED",
|
|
16
|
+
"values": ["ENABLED", "DISABLED"]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { pathsToCheck } from './check-user-id.js'
|
|
2
|
+
|
|
3
|
+
async function mergeRoles (req) {
|
|
4
|
+
const { map } = this.app.bajo.lib._
|
|
5
|
+
const { recordFindAll } = this.app.dobo
|
|
6
|
+
req.user.roles = []
|
|
7
|
+
const query = { userId: req.user.id, siteId: req.site.id }
|
|
8
|
+
const userRoles = await recordFindAll('SumbaRoleUser', { query })
|
|
9
|
+
if (userRoles.length === 0) return
|
|
10
|
+
delete query.userId
|
|
11
|
+
query.id = { $in: map(userRoles, 'id'), status: 'ENABLED' }
|
|
12
|
+
const roles = await recordFindAll('SumbaRole', { query })
|
|
13
|
+
if (roles.length > 0) req.user.roles.push(...map(roles, 'alias'))
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function checkRole (req, reply, source) {
|
|
17
|
+
if (!req.user) return
|
|
18
|
+
const { map } = this.app.bajo.lib._
|
|
19
|
+
await mergeRoles.call(this, req)
|
|
20
|
+
const paths = pathsToCheck.call(this, req, true)
|
|
21
|
+
const match = this.checkPathsByRole({ paths, method: req.method, roles: req.user.roles, guards: this.roles })
|
|
22
|
+
if (match) return
|
|
23
|
+
const negMatch = this.checkPathsByRole({ paths, method: req.method, roles: req.user.roles, guards: this.negRoles })
|
|
24
|
+
if (negMatch) return
|
|
25
|
+
const guards = map(this.roles, r => r.path)
|
|
26
|
+
// fallback
|
|
27
|
+
const guarded = this.checkPathsByGuard({ paths, guards })
|
|
28
|
+
if (!guarded) return
|
|
29
|
+
throw this.error('permissionDenied')
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default checkRole
|
package/lib/check-user-id.js
CHANGED
|
@@ -1,51 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
const {
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (isI18n) path = `/${req.lang}${path}`
|
|
10
|
-
const matchPath = outmatch(path, { separator: false })
|
|
11
|
-
const checks = [req.routeOptions.url, req.url]
|
|
12
|
-
for (const check of checks) {
|
|
13
|
-
if (matchPath(check)) {
|
|
14
|
-
const matchMethods = outmatch(item.methods)
|
|
15
|
-
if (matchMethods(req.method)) {
|
|
16
|
-
match = item
|
|
17
|
-
break
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
if (match) break
|
|
22
|
-
}
|
|
23
|
-
return match
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async function anonymous (req) {
|
|
27
|
-
const { omit } = this.app.bajo.lib._
|
|
28
|
-
const { getUser } = this
|
|
29
|
-
const { routePath } = this.app.waibu
|
|
30
|
-
|
|
31
|
-
if (!req.session) return
|
|
32
|
-
if (req.session.user) {
|
|
33
|
-
const match = await checker.call(this, req, this.anonymousRoutes)
|
|
34
|
-
if (match) {
|
|
35
|
-
const redir = routePath(this.config.redirect.signout, req)
|
|
36
|
-
req.session.ref = req.url
|
|
37
|
-
throw this.error('_redirect', { redirect: redir })
|
|
38
|
-
}
|
|
39
|
-
req.user = omit(await getUser(req.session.user.id), ['password', 'token'])
|
|
1
|
+
export function pathsToCheck (req, withHome) {
|
|
2
|
+
const { uniq, without } = this.app.bajo.lib._
|
|
3
|
+
const checks = uniq(without([req.routeOptions.url, req.url], undefined, null))
|
|
4
|
+
/*
|
|
5
|
+
if (withHome) {
|
|
6
|
+
const homePath = get(this, 'app.waibu.config.home.path')
|
|
7
|
+
const homeForward = get(this, 'app.waibu.config.home.forward')
|
|
8
|
+
if (homePath && homeForward) checks.unshift('/')
|
|
40
9
|
}
|
|
10
|
+
*/
|
|
11
|
+
return checks
|
|
41
12
|
}
|
|
42
13
|
|
|
43
|
-
async function
|
|
44
|
-
const {
|
|
45
|
-
const
|
|
46
|
-
if (!
|
|
47
|
-
|
|
48
|
-
|
|
14
|
+
async function setUser (req) {
|
|
15
|
+
const { get } = this.app.bajo.lib._
|
|
16
|
+
const id = get(req, 'session.user.id')
|
|
17
|
+
if (!id) return
|
|
18
|
+
try {
|
|
19
|
+
const user = await this.getUser(id)
|
|
20
|
+
if (user) req.user = user
|
|
21
|
+
else req.session.user = null
|
|
22
|
+
} catch (err) {
|
|
23
|
+
req.session.user = null
|
|
49
24
|
}
|
|
50
25
|
}
|
|
51
26
|
|
|
@@ -55,38 +30,56 @@ async function mergeSetting (req) {
|
|
|
55
30
|
|
|
56
31
|
async function checkUserId (req, reply, source) {
|
|
57
32
|
const { isEmpty, camelCase } = this.app.bajo.lib._
|
|
33
|
+
const { routePath } = this.app.waibu
|
|
58
34
|
|
|
59
35
|
const ctx = this.app[source].instance
|
|
60
36
|
if (!req.routeOptions.url) {
|
|
61
|
-
|
|
37
|
+
if (!req.session) return
|
|
38
|
+
await setUser.call(this, req)
|
|
62
39
|
return
|
|
63
40
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
41
|
+
|
|
42
|
+
const paths = pathsToCheck.call(this, req)
|
|
43
|
+
let securePath = await this.checkPathsByRoutes({ paths, method: req.method, guards: this.secureRoutes })
|
|
44
|
+
if (securePath) {
|
|
45
|
+
const neg = await this.checkPathsByRoutes({ paths, method: req.method, guards: this.secureNegRoutes })
|
|
46
|
+
if (neg) securePath = undefined
|
|
68
47
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
48
|
+
let anonymousPath = await this.checkPathsByRoutes({ paths, method: req.method, guards: this.anonymousRoutes })
|
|
49
|
+
if (anonymousPath) {
|
|
50
|
+
const neg = await this.checkPathsByRoutes({ paths, method: req.method, guards: this.anonymousNegRoutes })
|
|
51
|
+
if (neg) anonymousPath = undefined
|
|
52
|
+
}
|
|
53
|
+
if (!securePath && !anonymousPath) {
|
|
54
|
+
if (req.session && req.session.user) await setUser.call(this, req)
|
|
73
55
|
return
|
|
74
56
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (
|
|
83
|
-
|
|
84
|
-
|
|
57
|
+
if (anonymousPath) {
|
|
58
|
+
if (!req.session) return // can't check, so don't care
|
|
59
|
+
if (!req.session.user) return // not authenticated, why bother
|
|
60
|
+
req.session.ref = req.url
|
|
61
|
+
return reply.redirectTo(routePath(this.config.redirect.signout))
|
|
62
|
+
}
|
|
63
|
+
if (securePath) {
|
|
64
|
+
if (req.session && req.session.user) {
|
|
65
|
+
await setUser.call(this, req)
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
const authMethods = this.config.auth[securePath.source].methods ?? []
|
|
69
|
+
if (isEmpty(authMethods)) throw this.error('noAuthMethod', { statusCode: 500 })
|
|
70
|
+
let success
|
|
71
|
+
for (const m of authMethods) {
|
|
72
|
+
const handler = this[camelCase(`verify ${m}`)]
|
|
73
|
+
if (!handler) throw this.error('invalidAuthMethod%s', m, { statusCode: 500 })
|
|
74
|
+
const check = await handler(req, reply, source, ctx)
|
|
75
|
+
if (check) {
|
|
76
|
+
success = check
|
|
77
|
+
break
|
|
78
|
+
}
|
|
85
79
|
}
|
|
80
|
+
if (!success) throw this.error('accessDenied', { statusCode: 401 })
|
|
81
|
+
await mergeSetting.call(this, req)
|
|
86
82
|
}
|
|
87
|
-
if (!success) throw this.error('accessDenied', { statusCode: 401 })
|
|
88
|
-
await mergeSetting.call(this, req)
|
|
89
|
-
return success
|
|
90
83
|
}
|
|
91
84
|
|
|
92
85
|
export default checkUserId
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
async function collect ({ file, ns, dir }) {
|
|
2
|
+
const { readConfig } = this.app.bajo
|
|
3
|
+
const { routePath } = this.app.waibu
|
|
4
|
+
const { camelCase, isString, find } = this.app.bajo.lib._
|
|
5
|
+
|
|
6
|
+
const roles = await readConfig(file, { ignoreError: true })
|
|
7
|
+
const [item] = file.replace(dir, '').split('@')
|
|
8
|
+
let [source, subNs] = item.split('.').map(s => camelCase(s))
|
|
9
|
+
subNs = subNs ? `.${subNs}` : ''
|
|
10
|
+
for (const k in roles) {
|
|
11
|
+
const values = isString(roles[k]) ? [roles[k]] : roles[k]
|
|
12
|
+
let [path, methods] = k.split(':')
|
|
13
|
+
const isNeg = path[0] === '!'
|
|
14
|
+
if (isNeg) path = path.slice(1)
|
|
15
|
+
path = routePath(`${ns}${subNs}:${path}`)
|
|
16
|
+
const item = {
|
|
17
|
+
source,
|
|
18
|
+
path,
|
|
19
|
+
methods: methods.split(','),
|
|
20
|
+
values
|
|
21
|
+
}
|
|
22
|
+
const guards = this[isNeg ? 'negRoles' : 'roles']
|
|
23
|
+
if (find(guards, { path })) continue
|
|
24
|
+
guards.push(item)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function collectRoles () {
|
|
29
|
+
const { eachPlugins } = this.app.bajo
|
|
30
|
+
|
|
31
|
+
this.roles = this.roles ?? []
|
|
32
|
+
this.negRoles = this.negRoles ?? []
|
|
33
|
+
const items = []
|
|
34
|
+
if (this.app.waibuStatic) items.push('waibuStatic.asset', 'waibuStatic.virtual', 'waibu-static.asset', 'waibu-static.virtual')
|
|
35
|
+
if (this.app.waibuRestApi) items.push('waibuRestApi', 'waibu-rest-api')
|
|
36
|
+
if (this.app.waibuMpa) items.push('waibuMpa', 'waibu-mpa')
|
|
37
|
+
const pattern = `{${items.join(',')}}@roles.*`
|
|
38
|
+
const me = this
|
|
39
|
+
await eachPlugins(async function ({ file, ns, dir }) {
|
|
40
|
+
await collect.call(me, { file, ns, dir })
|
|
41
|
+
}, { glob: pattern, prefix: this.name })
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default collectRoles
|
package/lib/collect-routes.js
CHANGED
|
@@ -1,45 +1,26 @@
|
|
|
1
|
-
const indexes = []
|
|
2
|
-
const invIndexes = []
|
|
3
|
-
|
|
4
1
|
async function collect (type, { file, ns, dir }) {
|
|
5
2
|
const { readConfig } = this.app.bajo
|
|
6
|
-
const {
|
|
7
|
-
const {
|
|
8
|
-
const { hash } = this.app.bajoExtra
|
|
3
|
+
const { routePath } = this.app.waibu
|
|
4
|
+
const { camelCase, isString, find } = this.app.bajo.lib._
|
|
9
5
|
|
|
10
6
|
const routes = await readConfig(file, { ignoreError: true })
|
|
11
|
-
|
|
12
|
-
let
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const v = routes[k]
|
|
21
|
-
const prefix = prefixHandler(ns, source)
|
|
22
|
-
const inverted = k[0] === '!'
|
|
23
|
-
if (inverted) k = k.slice(1)
|
|
24
|
-
if (k[0] !== '/') k = '/' + k
|
|
7
|
+
const [item] = file.replace(dir, '').split('@')
|
|
8
|
+
let [source, subNs] = item.split('.').map(s => camelCase(s))
|
|
9
|
+
subNs = subNs ? `.${subNs}` : ''
|
|
10
|
+
|
|
11
|
+
for (let path in routes) {
|
|
12
|
+
const values = isString(routes[path]) ? routes[path].split(',') : routes[path]
|
|
13
|
+
const isNeg = path[0] === '!'
|
|
14
|
+
if (isNeg) path = path.slice(1)
|
|
15
|
+
path = routePath(`${ns}${subNs}:${path}`)
|
|
25
16
|
const item = {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
source
|
|
30
|
-
}
|
|
31
|
-
const index = await hash(item)
|
|
32
|
-
if (inverted && type === 'secure') {
|
|
33
|
-
if (!invIndexes.includes(index)) {
|
|
34
|
-
this[`${type}InvRoutes`].push(item)
|
|
35
|
-
invIndexes.push(index)
|
|
36
|
-
}
|
|
37
|
-
} else {
|
|
38
|
-
if (!indexes.includes(index)) {
|
|
39
|
-
this[`${type}Routes`].push(item)
|
|
40
|
-
indexes.push(index)
|
|
41
|
-
}
|
|
17
|
+
source,
|
|
18
|
+
path,
|
|
19
|
+
values
|
|
42
20
|
}
|
|
21
|
+
const guards = this[`${type}${isNeg ? 'Neg' : ''}Routes`]
|
|
22
|
+
if (find(guards, { path })) continue
|
|
23
|
+
guards.push(item)
|
|
43
24
|
}
|
|
44
25
|
}
|
|
45
26
|
|
|
@@ -47,7 +28,7 @@ async function collectRoutes (type) {
|
|
|
47
28
|
const { eachPlugins } = this.app.bajo
|
|
48
29
|
|
|
49
30
|
this[`${type}Routes`] = this[`${type}Routes`] ?? []
|
|
50
|
-
this[`${type}
|
|
31
|
+
this[`${type}NegRoutes`] = this[`${type}NegRoutes`] ?? []
|
|
51
32
|
const items = []
|
|
52
33
|
if (this.app.waibuStatic) items.push('waibuStatic.asset', 'waibuStatic.virtual', 'waibu-static.asset', 'waibu-static.virtual')
|
|
53
34
|
if (this.app.waibuRestApi) items.push('waibuRestApi', 'waibu-rest-api')
|
|
@@ -57,8 +38,6 @@ async function collectRoutes (type) {
|
|
|
57
38
|
await eachPlugins(async function ({ file, ns, dir }) {
|
|
58
39
|
await collect.call(me, type, { file, ns, dir })
|
|
59
40
|
}, { glob: pattern, prefix: this.name })
|
|
60
|
-
indexes.splice(0)
|
|
61
|
-
invIndexes.splice(0)
|
|
62
41
|
}
|
|
63
42
|
|
|
64
43
|
export default collectRoutes
|