expressa 1.2.1 → 1.2.4
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/controllers/install.js +34 -27
- package/db/postgres.js +100 -103
- package/index.js +3 -4
- package/middleware/permissions.js +53 -49
- package/modules/admin/build/webpack.prod.conf.js +5 -3
- package/modules/admin/config/index.js +2 -2
- package/modules/admin/dist/index.html +1 -1
- package/modules/admin/dist/index.html.gz +0 -0
- package/modules/admin/dist/static/css/chunk-1dff.39c7634b.css +1 -0
- package/modules/admin/dist/static/css/chunk-1dff.39c7634b.css.gz +0 -0
- package/modules/admin/dist/static/css/{chunk-5cee.ce0e4bdb.css → chunk-5cee.9685afb8.css} +0 -0
- package/modules/admin/dist/static/css/{chunk-5cee.ce0e4bdb.css.gz → chunk-5cee.9685afb8.css.gz} +0 -0
- package/modules/admin/dist/static/css/{chunk-621e.97323951.css → chunk-621e.f3d0eab6.css} +0 -0
- package/modules/admin/dist/static/css/{chunk-621e.97323951.css.gz → chunk-621e.f3d0eab6.css.gz} +0 -0
- package/modules/admin/dist/static/css/{chunk-bd5f.aefa49d7.css → chunk-bd5f.6ab011ba.css} +0 -0
- package/modules/admin/dist/static/css/{chunk-bd5f.aefa49d7.css.gz → chunk-bd5f.6ab011ba.css.gz} +0 -0
- package/modules/admin/dist/static/css/chunk-f691.4817ca73.css +1 -0
- package/modules/admin/dist/static/css/chunk-f691.4817ca73.css.gz +0 -0
- package/modules/admin/dist/static/js/{app.03e8afa3.js → app.ebe90d64.js} +1 -1
- package/modules/admin/dist/static/js/{app.03e8afa3.js.gz → app.ebe90d64.js.gz} +0 -0
- package/modules/admin/dist/static/js/{chunk-8bab.7052832d.js → chunk-09d8.561880e0.js} +2 -2
- package/modules/admin/dist/static/js/{chunk-8bab.7052832d.js.LICENSE.txt → chunk-09d8.561880e0.js.LICENSE.txt} +0 -0
- package/modules/admin/dist/static/js/{chunk-8bab.7052832d.js.LICENSE.txt.gz → chunk-09d8.561880e0.js.LICENSE.txt.gz} +0 -0
- package/modules/admin/dist/static/js/{chunk-8bab.7052832d.js.gz → chunk-09d8.561880e0.js.gz} +0 -0
- package/modules/admin/dist/static/js/chunk-1dff.1f1c0999.js +1 -0
- package/modules/admin/dist/static/js/chunk-1dff.1f1c0999.js.gz +0 -0
- package/modules/admin/dist/static/js/{chunk-5cee.a3b03f7a.js → chunk-5cee.a6f0e769.js} +0 -0
- package/modules/admin/dist/static/js/{chunk-5cee.a3b03f7a.js.gz → chunk-5cee.a6f0e769.js.gz} +0 -0
- package/modules/admin/dist/static/js/{chunk-621e.a9ed86e2.js → chunk-621e.6fe293e9.js} +0 -0
- package/modules/admin/dist/static/js/{chunk-621e.a9ed86e2.js.gz → chunk-621e.6fe293e9.js.gz} +0 -0
- package/modules/admin/dist/static/js/{chunk-bd5f.e9509f10.js → chunk-bd5f.af5f2197.js} +0 -0
- package/modules/admin/dist/static/js/{chunk-bd5f.e9509f10.js.gz → chunk-bd5f.af5f2197.js.gz} +0 -0
- package/modules/admin/dist/static/js/chunk-f691.c0cbf5c1.js +1 -0
- package/modules/admin/dist/static/js/chunk-f691.c0cbf5c1.js.gz +0 -0
- package/modules/admin/package.json +1 -0
- package/modules/admin/src/views/ListDocuments2.vue +112 -14
- package/package.json +1 -1
- package/modules/admin/dist/static/css/chunk-318c.ffb0d81e.css +0 -1
- package/modules/admin/dist/static/css/chunk-318c.ffb0d81e.css.gz +0 -0
- package/modules/admin/dist/static/css/chunk-6644.69ccf1a7.css +0 -1
- package/modules/admin/dist/static/css/chunk-6644.69ccf1a7.css.gz +0 -0
- package/modules/admin/dist/static/js/chunk-318c.03fa0032.js +0 -1
- package/modules/admin/dist/static/js/chunk-318c.03fa0032.js.gz +0 -0
- package/modules/admin/dist/static/js/chunk-6644.9c6f5c7b.js +0 -1
- package/modules/admin/dist/static/js/chunk-6644.9c6f5c7b.js.gz +0 -0
package/controllers/install.js
CHANGED
|
@@ -27,39 +27,46 @@ exports.install = async (req, api) => {
|
|
|
27
27
|
|
|
28
28
|
const modules = selectedModules.map((name) => req.modules[name])
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
settings._id = process.env.NODE_ENV
|
|
32
|
-
settings.jwt_secret = util.createSecureRandomId()
|
|
33
|
-
// Remove fields that are not real settings
|
|
34
|
-
delete settings.email
|
|
35
|
-
delete settings.user_storage
|
|
36
|
-
delete settings.password
|
|
37
|
-
Object.assign(req.settings, settings)
|
|
38
|
-
await req.db.settings.create(settings)
|
|
30
|
+
let settings = await api.db.settings.get(process.env.NODE_ENV).catch(() => {})
|
|
39
31
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
32
|
+
if (!settings) {
|
|
33
|
+
settings = JSON.parse(JSON.stringify(req.body.settings))
|
|
34
|
+
settings._id = process.env.NODE_ENV
|
|
35
|
+
settings.jwt_secret = util.createSecureRandomId()
|
|
36
|
+
// Remove fields that are not real settings
|
|
37
|
+
delete settings.email
|
|
38
|
+
delete settings.user_storage
|
|
39
|
+
delete settings.password
|
|
40
|
+
Object.assign(req.settings, settings)
|
|
41
|
+
await req.db.settings.create(settings)
|
|
42
|
+
|
|
43
|
+
for (const m of modules) {
|
|
44
|
+
const colls = await util.resolve(m.collections, api)
|
|
45
|
+
if (colls) {
|
|
46
|
+
for (const coll of colls) {
|
|
47
|
+
if (!coll.storage) {
|
|
48
|
+
coll.storage = 'file'
|
|
49
|
+
}
|
|
50
|
+
if (coll._id == 'users') {
|
|
51
|
+
if (req.body.settings.user_storage) {
|
|
52
|
+
coll.storage = req.body.settings.user_storage
|
|
53
|
+
}
|
|
54
|
+
coll.enableLogin = true
|
|
50
55
|
}
|
|
51
|
-
coll
|
|
56
|
+
await req.db.collection.create(coll)
|
|
57
|
+
await api.notify('changed', req, 'collection', coll)
|
|
58
|
+
// await collectionsApi.insert(Object.assign({}, req, { body: coll }))
|
|
52
59
|
}
|
|
53
|
-
await req.db.collection.create(coll)
|
|
54
|
-
await api.notify('changed', req, 'collection', coll)
|
|
55
|
-
// await collectionsApi.insert(Object.assign({}, req, { body: coll }))
|
|
56
60
|
}
|
|
61
|
+
await util.resolve(m.install, api)
|
|
62
|
+
}
|
|
63
|
+
await exports.updateAdminPermissions(api)
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
if (settings.installed) {
|
|
67
|
+
throw new Error(`${process.env.NODE_ENV}.json exists and indicates expressa is already installed. Try setting 'installed' to false if you are attempting to reinstall.`)
|
|
57
68
|
}
|
|
58
|
-
|
|
59
|
-
await util.resolve(m.install, api)
|
|
60
69
|
}
|
|
61
|
-
|
|
62
|
-
await exports.updateAdminPermissions(api)
|
|
63
70
|
|
|
64
71
|
settings.installed = true
|
|
65
72
|
settings.enforce_permissions = true
|
package/db/postgres.js
CHANGED
|
@@ -1,103 +1,100 @@
|
|
|
1
|
-
const mongoToPostgres = require('mongo-query-to-postgres-jsonb')
|
|
2
|
-
const util = require('../util')
|
|
3
|
-
|
|
4
|
-
module.exports = function (settings, collectionId, collection) {
|
|
5
|
-
const pool = util.getPgPool(settings.postgresql_uri)
|
|
6
|
-
|
|
7
|
-
return {
|
|
8
|
-
init: async function () {
|
|
9
|
-
if (collection.plainStringIds) {
|
|
10
|
-
await pool.query('CREATE TABLE IF NOT EXISTS ' + collectionId + ' (id text primary key, data jsonb)')
|
|
11
|
-
} else {
|
|
12
|
-
await pool.query('CREATE TABLE IF NOT EXISTS ' + collectionId + ' (id uuid primary key, data jsonb)')
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
all: async function () {
|
|
16
|
-
return this.find({})
|
|
17
|
-
},
|
|
18
|
-
find: async function (rawQuery, offset, limit, orderby, fields) {
|
|
19
|
-
const arrayFields = util.getArrayPaths('', collection.schema)
|
|
20
|
-
const pgQuery = mongoToPostgres('data', rawQuery || {}, arrayFields)
|
|
21
|
-
const select = fields ? mongoToPostgres.convertSelect('data', fields, arrayFields) : '*'
|
|
22
|
-
let query = 'SELECT ' + select + ' FROM ' + collectionId + (pgQuery ? ' WHERE ' + pgQuery : '')
|
|
23
|
-
if (typeof orderby !== 'undefined') {
|
|
24
|
-
query += ' ORDER BY '
|
|
25
|
-
query += orderby.map((ordering) => {
|
|
26
|
-
return mongoToPostgres.convertDotNotation('data', ordering[0]) + (ordering[1] > 0 ? ' ASC' : ' DESC')
|
|
27
|
-
}).join(', ')
|
|
28
|
-
}
|
|
29
|
-
if (typeof offset !== 'undefined') {
|
|
30
|
-
query += ' OFFSET ' + offset
|
|
31
|
-
}
|
|
32
|
-
if (typeof limit !== 'undefined') {
|
|
33
|
-
query += ' LIMIT ' + limit
|
|
34
|
-
}
|
|
35
|
-
const result = await pool.query(query)
|
|
36
|
-
return result.rows.map((row) => row.data)
|
|
37
|
-
},
|
|
38
|
-
count: async function(rawQuery, offset, limit) {
|
|
39
|
-
const arrayFields = util.getArrayPaths('', collection.schema)
|
|
40
|
-
const pgQuery = mongoToPostgres('data', rawQuery || {}, arrayFields)
|
|
41
|
-
let query = 'SELECT COUNT(*) FROM ' + collectionId + (pgQuery ? ' WHERE ' + pgQuery : '')
|
|
42
|
-
if (typeof offset !== 'undefined') {
|
|
43
|
-
query += ' OFFSET ' + offset
|
|
44
|
-
}
|
|
45
|
-
if (typeof limit !== 'undefined') {
|
|
46
|
-
query += ' LIMIT ' + limit
|
|
47
|
-
}
|
|
48
|
-
const result = await pool.query(query)
|
|
49
|
-
return parseInt(result.rows[0].count)
|
|
50
|
-
},
|
|
51
|
-
get: async function (id, fields) {
|
|
52
|
-
const arrayFields = util.getArrayPaths('', collection.schema)
|
|
53
|
-
const select = fields ? mongoToPostgres.convertSelect('data', fields, arrayFields) : '*'
|
|
54
|
-
const result = await pool.query(`SELECT ${select} FROM ${collectionId} WHERE id = $1`, [id])
|
|
55
|
-
if (result.rowCount === 0) {
|
|
56
|
-
throw new util.ApiError(404, 'document not found')
|
|
57
|
-
}
|
|
58
|
-
return result.rows[0].data
|
|
59
|
-
},
|
|
60
|
-
create: async function (data) {
|
|
61
|
-
util.addIdIfMissing(data)
|
|
62
|
-
try {
|
|
63
|
-
await pool.query('INSERT INTO ' + collectionId + ' (id, data) VALUES ($1, $2)', [data._id, data])
|
|
64
|
-
} catch (e) {
|
|
65
|
-
if (e.message.includes('duplicate key')) {
|
|
66
|
-
throw new util.ApiError(409, 'document already exists')
|
|
67
|
-
}
|
|
68
|
-
throw e
|
|
69
|
-
}
|
|
70
|
-
return data._id
|
|
71
|
-
},
|
|
72
|
-
update: async function (id, data) {
|
|
73
|
-
if (typeof data._id === 'undefined') {
|
|
74
|
-
data._id = id
|
|
75
|
-
}
|
|
76
|
-
const result = await pool.query('UPDATE ' + collectionId + ' SET data=$2,id=$3 WHERE id=$1', [id, data, data._id])
|
|
77
|
-
if (result.rowCount === 0) {
|
|
78
|
-
throw new util.ApiError(404, 'document not found')
|
|
79
|
-
}
|
|
80
|
-
return data
|
|
81
|
-
},
|
|
82
|
-
// eslint-disable-next-line no-unused-vars
|
|
83
|
-
updateWithQuery: async function (query, update, options) {
|
|
84
|
-
const arrayFields = util.getArrayPaths('', collection.schema)
|
|
85
|
-
const pgQuery = mongoToPostgres('data', query || {}, arrayFields)
|
|
86
|
-
const updateSql = mongoToPostgres.convertUpdate('data', update,false)
|
|
87
|
-
const result = await pool.query('UPDATE ' + collectionId + ' SET data=' + updateSql + ' WHERE ' + pgQuery)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
1
|
+
const mongoToPostgres = require('mongo-query-to-postgres-jsonb')
|
|
2
|
+
const util = require('../util')
|
|
3
|
+
|
|
4
|
+
module.exports = function (settings, collectionId, collection) {
|
|
5
|
+
const pool = util.getPgPool(settings.postgresql_uri)
|
|
6
|
+
|
|
7
|
+
return {
|
|
8
|
+
init: async function () {
|
|
9
|
+
if (collection.plainStringIds) {
|
|
10
|
+
await pool.query('CREATE TABLE IF NOT EXISTS ' + collectionId + ' (id text primary key, data jsonb)')
|
|
11
|
+
} else {
|
|
12
|
+
await pool.query('CREATE TABLE IF NOT EXISTS ' + collectionId + ' (id uuid primary key, data jsonb)')
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
all: async function () {
|
|
16
|
+
return this.find({})
|
|
17
|
+
},
|
|
18
|
+
find: async function (rawQuery, offset, limit, orderby, fields) {
|
|
19
|
+
const arrayFields = util.getArrayPaths('', collection.schema)
|
|
20
|
+
const pgQuery = mongoToPostgres('data', rawQuery || {}, arrayFields)
|
|
21
|
+
const select = fields ? mongoToPostgres.convertSelect('data', fields, arrayFields) : '*'
|
|
22
|
+
let query = 'SELECT ' + select + ' FROM ' + collectionId + (pgQuery ? ' WHERE ' + pgQuery : '')
|
|
23
|
+
if (typeof orderby !== 'undefined') {
|
|
24
|
+
query += ' ORDER BY '
|
|
25
|
+
query += orderby.map((ordering) => {
|
|
26
|
+
return mongoToPostgres.convertDotNotation('data', ordering[0]) + (ordering[1] > 0 ? ' ASC' : ' DESC')
|
|
27
|
+
}).join(', ')
|
|
28
|
+
}
|
|
29
|
+
if (typeof offset !== 'undefined') {
|
|
30
|
+
query += ' OFFSET ' + offset
|
|
31
|
+
}
|
|
32
|
+
if (typeof limit !== 'undefined') {
|
|
33
|
+
query += ' LIMIT ' + limit
|
|
34
|
+
}
|
|
35
|
+
const result = await pool.query(query)
|
|
36
|
+
return result.rows.map((row) => row.data)
|
|
37
|
+
},
|
|
38
|
+
count: async function(rawQuery, offset, limit) {
|
|
39
|
+
const arrayFields = util.getArrayPaths('', collection.schema)
|
|
40
|
+
const pgQuery = mongoToPostgres('data', rawQuery || {}, arrayFields)
|
|
41
|
+
let query = 'SELECT COUNT(*) FROM ' + collectionId + (pgQuery ? ' WHERE ' + pgQuery : '')
|
|
42
|
+
if (typeof offset !== 'undefined') {
|
|
43
|
+
query += ' OFFSET ' + offset
|
|
44
|
+
}
|
|
45
|
+
if (typeof limit !== 'undefined') {
|
|
46
|
+
query += ' LIMIT ' + limit
|
|
47
|
+
}
|
|
48
|
+
const result = await pool.query(query)
|
|
49
|
+
return parseInt(result.rows[0].count)
|
|
50
|
+
},
|
|
51
|
+
get: async function (id, fields) {
|
|
52
|
+
const arrayFields = util.getArrayPaths('', collection.schema)
|
|
53
|
+
const select = fields ? mongoToPostgres.convertSelect('data', fields, arrayFields) : '*'
|
|
54
|
+
const result = await pool.query(`SELECT ${select} FROM ${collectionId} WHERE id = $1`, [id])
|
|
55
|
+
if (result.rowCount === 0) {
|
|
56
|
+
throw new util.ApiError(404, 'document not found')
|
|
57
|
+
}
|
|
58
|
+
return result.rows[0].data
|
|
59
|
+
},
|
|
60
|
+
create: async function (data) {
|
|
61
|
+
util.addIdIfMissing(data)
|
|
62
|
+
try {
|
|
63
|
+
await pool.query('INSERT INTO ' + collectionId + ' (id, data) VALUES ($1, $2)', [data._id, data])
|
|
64
|
+
} catch (e) {
|
|
65
|
+
if (e.message.includes('duplicate key')) {
|
|
66
|
+
throw new util.ApiError(409, 'document already exists')
|
|
67
|
+
}
|
|
68
|
+
throw e
|
|
69
|
+
}
|
|
70
|
+
return data._id
|
|
71
|
+
},
|
|
72
|
+
update: async function (id, data) {
|
|
73
|
+
if (typeof data._id === 'undefined') {
|
|
74
|
+
data._id = id
|
|
75
|
+
}
|
|
76
|
+
const result = await pool.query('UPDATE ' + collectionId + ' SET data=$2,id=$3 WHERE id=$1', [id, data, data._id])
|
|
77
|
+
if (result.rowCount === 0) {
|
|
78
|
+
throw new util.ApiError(404, 'document not found')
|
|
79
|
+
}
|
|
80
|
+
return data
|
|
81
|
+
},
|
|
82
|
+
// eslint-disable-next-line no-unused-vars
|
|
83
|
+
updateWithQuery: async function (query, update, options) {
|
|
84
|
+
const arrayFields = util.getArrayPaths('', collection.schema)
|
|
85
|
+
const pgQuery = mongoToPostgres('data', query || {}, arrayFields)
|
|
86
|
+
const updateSql = mongoToPostgres.convertUpdate('data', update,false)
|
|
87
|
+
const result = await pool.query('UPDATE ' + collectionId + ' SET data=' + updateSql + ' WHERE ' + pgQuery)
|
|
88
|
+
return {
|
|
89
|
+
matchedCount: result.rowCount
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
delete: async function (id) {
|
|
93
|
+
const result = await pool.query('DELETE FROM ' + collectionId + ' WHERE id=$1', [id])
|
|
94
|
+
if (result.rowCount === 0) {
|
|
95
|
+
throw new util.ApiError(404, 'document not found')
|
|
96
|
+
}
|
|
97
|
+
return 'OK'
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
package/index.js
CHANGED
|
@@ -33,8 +33,6 @@ async function bootstrapCollections (router) {
|
|
|
33
33
|
}))
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
let initialized = false
|
|
37
|
-
|
|
38
36
|
async function initCollections (db, router) {
|
|
39
37
|
debug('init collections')
|
|
40
38
|
try {
|
|
@@ -103,6 +101,7 @@ function ph (requestHandler) {
|
|
|
103
101
|
|
|
104
102
|
module.exports.api = function (settings) {
|
|
105
103
|
const router = express.Router()
|
|
104
|
+
router.initialized = false
|
|
106
105
|
router.custom = express.Router()
|
|
107
106
|
router.dbTypes = dbTypes
|
|
108
107
|
router.settings = settings || {}
|
|
@@ -139,7 +138,7 @@ module.exports.api = function (settings) {
|
|
|
139
138
|
}
|
|
140
139
|
router.eventListeners[event].push(listener)
|
|
141
140
|
router.eventListeners[event].sort((a, b) => a.priority - b.priority)
|
|
142
|
-
if (event === 'ready' && initialized) {
|
|
141
|
+
if (event === 'ready' && router.initialized) {
|
|
143
142
|
listener(router)
|
|
144
143
|
}
|
|
145
144
|
}
|
|
@@ -207,7 +206,7 @@ module.exports.api = function (settings) {
|
|
|
207
206
|
console.error(e)
|
|
208
207
|
}
|
|
209
208
|
|
|
210
|
-
initialized = true
|
|
209
|
+
router.initialized = true
|
|
211
210
|
await util.notify('ready', router)
|
|
212
211
|
})()
|
|
213
212
|
|
|
@@ -1,49 +1,53 @@
|
|
|
1
|
-
const util = require('../util')
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
roleDocs.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
1
|
+
const util = require('../util')
|
|
2
|
+
let authenticatedRoleExists
|
|
3
|
+
|
|
4
|
+
async function addRolePermissions (req, roles) {
|
|
5
|
+
req.permissions = req.permissions || {}
|
|
6
|
+
const roleDocs = await Promise.all(roles.map((name) => req.db.role.get(name)))
|
|
7
|
+
roleDocs.forEach((roleDoc) => {
|
|
8
|
+
for (const permission in roleDoc.permissions) {
|
|
9
|
+
if (roleDoc.permissions[permission]) {
|
|
10
|
+
req.permissions[permission] = true
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function doesAuthenticatedRoleExist(req) {
|
|
17
|
+
if (typeof authenticatedRoleExists === 'undefined') {
|
|
18
|
+
try {
|
|
19
|
+
await req.db.role.get('Authenticated')
|
|
20
|
+
authenticatedRoleExists = true
|
|
21
|
+
} catch (e) {
|
|
22
|
+
authenticatedRoleExists = false
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return authenticatedRoleExists
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports.addRolePermissionsAsync = async function addRolePermissionsMiddlewareAsync(req) {
|
|
29
|
+
if (!req.settings || !req.settings.enforce_permissions) {
|
|
30
|
+
// Use a dummy permission getter
|
|
31
|
+
req.hasPermission = () => true
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
req.hasPermission = (permission) => req.permissions && req.permissions[permission]
|
|
35
|
+
let roles = ['Anonymous']
|
|
36
|
+
const isAuthenticatedRole = await doesAuthenticatedRoleExist(req)
|
|
37
|
+
if (req.uid) {
|
|
38
|
+
try {
|
|
39
|
+
const user = await req.db[req.ucollection].get(req.uid)
|
|
40
|
+
req.user = user
|
|
41
|
+
roles = (user.roles || []).concat(isAuthenticatedRole ? ['Authenticated'] : [])
|
|
42
|
+
} catch (e) {
|
|
43
|
+
throw new util.ApiError(404, 'User no longer exists')
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
req.user = {}
|
|
47
|
+
}
|
|
48
|
+
await addRolePermissions(req, roles)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports.middleware = function addRolePermissionsMiddleware (req, res, next) {
|
|
52
|
+
module.exports.addRolePermissionsAsync(req).then(next).catch(next)
|
|
53
|
+
}
|
|
@@ -131,13 +131,15 @@ if (config.build.productionGzip) {
|
|
|
131
131
|
|
|
132
132
|
webpackConfig.plugins.push(
|
|
133
133
|
new CompressionWebpackPlugin({
|
|
134
|
-
|
|
134
|
+
filename: '[path][base].gz',
|
|
135
135
|
algorithm: 'gzip',
|
|
136
136
|
test: new RegExp(
|
|
137
137
|
'\\.(' + config.build.productionGzipExtensions.join('|') + ')$'
|
|
138
138
|
),
|
|
139
|
-
|
|
140
|
-
|
|
139
|
+
compressionOptions: {
|
|
140
|
+
level: 9,
|
|
141
|
+
},
|
|
142
|
+
minRatio: Infinity,
|
|
141
143
|
})
|
|
142
144
|
)
|
|
143
145
|
}
|
|
@@ -71,8 +71,8 @@ module.exports = {
|
|
|
71
71
|
// Surge or Netlify already gzip all static assets for you.
|
|
72
72
|
// Before setting to `true`, make sure to:
|
|
73
73
|
// npm install --save-dev compression-webpack-plugin
|
|
74
|
-
productionGzip:
|
|
75
|
-
productionGzipExtensions: ['js',
|
|
74
|
+
productionGzip: true,
|
|
75
|
+
productionGzipExtensions: ['json','js','js.map','css','html','svg','xml','txt'],
|
|
76
76
|
|
|
77
77
|
// Run the build command with an extra argument to
|
|
78
78
|
// View the bundle analyzer report after build finishes:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><script crossorigin src=https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react.min.js></script><script crossorigin src=https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-dom.min.js></script><link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel=stylesheet><script src=settings.js></script><title>Expressa Admin</title><link rel=icon href=/admin/favicon.ico><link href=/admin/static/css/chunk-elementUI.3d004d9f.css rel=stylesheet><link href=/admin/static/css/chunk-libs.327ad89e.css rel=stylesheet><link href=/admin/static/css/app.9dd57eea.css rel=stylesheet></head><body><div id=app></div><script>!function(e){function n(n){for(var r,c,a=n[0],
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><script crossorigin src=https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react.min.js></script><script crossorigin src=https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-dom.min.js></script><link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel=stylesheet><script src=settings.js></script><title>Expressa Admin</title><link rel=icon href=/admin/favicon.ico><link href=/admin/static/css/chunk-elementUI.3d004d9f.css rel=stylesheet><link href=/admin/static/css/chunk-libs.327ad89e.css rel=stylesheet><link href=/admin/static/css/app.9dd57eea.css rel=stylesheet></head><body><div id=app></div><script>!function(e){function n(n){for(var r,c,a=n[0],f=n[1],i=n[2],h=0,s=[];h<a.length;h++)c=a[h],Object.prototype.hasOwnProperty.call(u,c)&&u[c]&&s.push(u[c][0]),u[c]=0;for(r in f)Object.prototype.hasOwnProperty.call(f,r)&&(e[r]=f[r]);for(l&&l(n);s.length;)s.shift()();return o.push.apply(o,i||[]),t()}function t(){for(var e,n=0;n<o.length;n++){for(var t=o[n],r=!0,c=1;c<t.length;c++){var f=t[c];0!==u[f]&&(r=!1)}r&&(o.splice(n--,1),e=a(a.s=t[0]))}return e}var r={},c={runtime:0},u={runtime:0},o=[];function a(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var n=[];c[e]?n.push(c[e]):0!==c[e]&&{"chunk-621e":1,"chunk-e375":1,"chunk-3bc2":1,"chunk-5cee":1,"chunk-7291":1,"chunk-b423":1,"chunk-bd5f":1,"chunk-f075":1,"chunk-f691":1,"chunk-1dff":1}[e]&&n.push(c[e]=new Promise((function(n,t){for(var r="static/css/"+({}[e]||e)+"."+{"chunk-09d8":"31d6cfe0","chunk-621e":"f3d0eab6","chunk-e375":"1d849865","chunk-3bc2":"89632b9d","chunk-5cee":"9685afb8","chunk-7291":"13514e45","chunk-b423":"5f239333","chunk-bd5f":"6ab011ba","chunk-e7c3":"31d6cfe0","chunk-f075":"3a895a1e","chunk-f691":"4817ca73","chunk-1dff":"39c7634b"}[e]+".css",c=a.p+r,u=document.getElementsByTagName("link"),o=0;o<u.length;o++){var f=(h=u[o]).getAttribute("data-href")||h.getAttribute("href");if("stylesheet"===h.rel&&(f===r||f===c))return n()}var i=document.getElementsByTagName("style");for(o=0;o<i.length;o++){var h;if((f=(h=i[o]).getAttribute("data-href"))===r||f===c)return n()}var l=document.createElement("link");l.rel="stylesheet",l.type="text/css",l.onload=n,l.onerror=function(n){var r=n&&n.target&&n.target.src||c,u=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");u.request=r,t(u)},l.href=c,document.getElementsByTagName("head")[0].appendChild(l)})).then((function(){c[e]=0})));var t=u[e];if(0!==t)if(t)n.push(t[2]);else{var r=new Promise((function(n,r){t=u[e]=[n,r]}));n.push(t[2]=r);var o,f=document.createElement("script");f.charset="utf-8",f.timeout=120,a.nc&&f.setAttribute("nonce",a.nc),f.src=function(e){return a.p+"static/js/"+({}[e]||e)+"."+{"chunk-09d8":"561880e0","chunk-621e":"6fe293e9","chunk-e375":"089d85cd","chunk-3bc2":"028748b7","chunk-5cee":"a6f0e769","chunk-7291":"590524e9","chunk-b423":"387c504c","chunk-bd5f":"af5f2197","chunk-e7c3":"e5df8ceb","chunk-f075":"315ceec1","chunk-f691":"c0cbf5c1","chunk-1dff":"1f1c0999"}[e]+".js"}(e);var i=new Error;o=function(n){f.onerror=f.onload=null,clearTimeout(h);var t=u[e];if(0!==t){if(t){var r=n&&("load"===n.type?"missing":n.type),c=n&&n.target&&n.target.src;i.message="Loading chunk "+e+" failed.\n("+r+": "+c+")",i.name="ChunkLoadError",i.type=r,i.request=c,t[1](i)}u[e]=void 0}};var h=setTimeout((function(){o({type:"timeout",target:f})}),12e4);f.onerror=f.onload=o,document.head.appendChild(f)}return Promise.all(n)},a.m=e,a.c=r,a.d=function(e,n,t){a.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,n){if(1&n&&(e=a(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)a.d(t,r,function(n){return e[n]}.bind(null,r));return t},a.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(n,"a",n),n},a.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},a.p="/admin/",a.oe=function(e){throw console.error(e),e};var f=window.webpackJsonp=window.webpackJsonp||[],i=f.push.bind(f);f.push=n,f=f.slice();for(var h=0;h<f.length;h++)n(f[h]);var l=i;t()}([]);</script><script src=/admin/static/js/chunk-elementUI.b0c99c08.js></script><script src=/admin/static/js/chunk-libs.06c38828.js></script><script src=/admin/static/js/app.ebe90d64.js></script></body></html>
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.dashboard-container[data-v-5d163182]{margin:30px}.dashboard-text[data-v-5d163182]{font-size:30px;line-height:46px}a#settings-link[data-v-5d163182]{color:#35a;padding-left:25px}
|
|
Binary file
|
|
File without changes
|
package/modules/admin/dist/static/css/{chunk-5cee.ce0e4bdb.css.gz → chunk-5cee.9685afb8.css.gz}
RENAMED
|
File without changes
|
|
File without changes
|
package/modules/admin/dist/static/css/{chunk-621e.97323951.css.gz → chunk-621e.f3d0eab6.css.gz}
RENAMED
|
File without changes
|
|
File without changes
|
package/modules/admin/dist/static/css/{chunk-bd5f.aefa49d7.css.gz → chunk-bd5f.6ab011ba.css.gz}
RENAMED
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.el-table[data-v-1b5bf4c5] th{background-color:#343a40!important;border-color:#454d55;color:#fff}
|
|
Binary file
|