expressa 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/.circleci/config.yml +21 -21
  2. package/.eslintrc.json +29 -29
  3. package/LICENSE +21 -21
  4. package/README.md +137 -137
  5. package/auth/jwt.js +31 -31
  6. package/controllers/collections.js +299 -260
  7. package/controllers/install.js +105 -105
  8. package/controllers/status.js +43 -43
  9. package/controllers/users.js +52 -52
  10. package/cypress/fixtures/example.json +4 -4
  11. package/cypress/integration/0_install_spec.js +8 -8
  12. package/cypress/integration/custom_collections.js +30 -30
  13. package/cypress/integration/home.js +9 -9
  14. package/cypress/integration/settings.js +34 -34
  15. package/cypress/integration/users.js +61 -61
  16. package/cypress/plugins/index.js +17 -17
  17. package/cypress/support/commands.js +69 -69
  18. package/cypress/support/index.js +20 -20
  19. package/cypress/support/util.js +10 -10
  20. package/cypress.config.js +18 -18
  21. package/cypress.json +4 -4
  22. package/db/cached.js +44 -44
  23. package/db/file.js +131 -131
  24. package/db/memory.js +92 -92
  25. package/db/mongo.js +93 -93
  26. package/db/postgres.js +100 -100
  27. package/doc/authentication.md +38 -38
  28. package/doc/automatic-fields.md +12 -12
  29. package/doc/blogexample.md +16 -16
  30. package/doc/custom-endpoints.md +20 -20
  31. package/doc/database.md +23 -23
  32. package/doc/development.md +33 -33
  33. package/doc/listeners.md +103 -103
  34. package/doc/modules.md +8 -8
  35. package/doc/permissions.md +14 -14
  36. package/doc/relationships.md +65 -65
  37. package/doc/testing.md +47 -47
  38. package/doc/uploading-files.md +53 -53
  39. package/listeners.js +65 -65
  40. package/listeners_collection_permissions.js +29 -29
  41. package/listeners_users.js +96 -96
  42. package/listeners_validation.js +43 -43
  43. package/middleware/logging.js +30 -30
  44. package/middleware/permissions.js +41 -41
  45. package/modules/access_keys/access_keys.js +32 -32
  46. package/modules/admin/.babelrc +8 -8
  47. package/modules/admin/.editorconfig +14 -14
  48. package/modules/admin/.eslintignore +5 -5
  49. package/modules/admin/.eslintrc.js +197 -197
  50. package/modules/admin/.postcssrc.js +10 -10
  51. package/modules/admin/.travis.yml +5 -5
  52. package/modules/admin/LICENSE +21 -21
  53. package/modules/admin/README.md +88 -88
  54. package/modules/admin/build/build.js +46 -46
  55. package/modules/admin/build/check-versions.js +64 -64
  56. package/modules/admin/build/utils.js +109 -109
  57. package/modules/admin/build/vue-loader.conf.js +5 -5
  58. package/modules/admin/build/webpack.base.conf.js +112 -112
  59. package/modules/admin/build/webpack.dev.conf.js +95 -95
  60. package/modules/admin/build/webpack.prod.conf.js +112 -112
  61. package/modules/admin/config/dev.env.js +8 -8
  62. package/modules/admin/config/index.js +86 -86
  63. package/modules/admin/config/prod.env.js +5 -5
  64. package/modules/admin/dist/css/430.8c9b0482.css +8 -0
  65. package/modules/admin/dist/css/430.8c9b0482.css.gz +0 -0
  66. package/modules/admin/dist/css/566.7a90435e.css +7 -0
  67. package/modules/admin/dist/css/566.7a90435e.css.gz +0 -0
  68. package/modules/admin/dist/css/569.db9a10c2.css +213 -0
  69. package/modules/admin/dist/css/569.db9a10c2.css.gz +0 -0
  70. package/modules/admin/dist/css/572.513a323e.css +210 -0
  71. package/modules/admin/dist/css/572.513a323e.css.gz +0 -0
  72. package/modules/admin/dist/css/622.7a90435e.css +7 -0
  73. package/modules/admin/dist/css/622.7a90435e.css.gz +0 -0
  74. package/modules/admin/dist/css/651.e946bda7.css +6 -0
  75. package/modules/admin/dist/css/651.e946bda7.css.gz +0 -0
  76. package/modules/admin/dist/css/750.79723422.css +2 -0
  77. package/modules/admin/dist/css/750.79723422.css.gz +0 -0
  78. package/modules/admin/dist/css/798.c6646d20.css +1 -0
  79. package/modules/admin/dist/css/798.c6646d20.css.gz +0 -0
  80. package/modules/admin/dist/css/950.1fd9d57c.css +7 -0
  81. package/modules/admin/dist/css/950.1fd9d57c.css.gz +0 -0
  82. package/modules/admin/dist/css/app.c25a6c6c.css +592 -0
  83. package/modules/admin/dist/css/app.c25a6c6c.css.gz +0 -0
  84. package/modules/admin/dist/favicon.ico +0 -0
  85. package/modules/admin/dist/index.html +1 -0
  86. package/modules/admin/dist/static/fonts/element-icons.313f7da.woff +0 -0
  87. package/modules/admin/dist/static/fonts/element-icons.4520188.ttf +0 -0
  88. package/modules/admin/dist/static/img/404.4cf6930.png +0 -0
  89. package/modules/admin/dist/static/js/311.03ef5ed9.js +1 -0
  90. package/modules/admin/dist/static/js/311.03ef5ed9.js.gz +0 -0
  91. package/modules/admin/dist/static/js/430.ddfa4b9e.js +1 -0
  92. package/modules/admin/dist/static/js/430.ddfa4b9e.js.gz +0 -0
  93. package/modules/admin/dist/static/js/460.770a630c.js +1 -0
  94. package/modules/admin/dist/static/js/460.770a630c.js.gz +0 -0
  95. package/modules/admin/dist/static/js/550.e9a3a306.js +1 -0
  96. package/modules/admin/dist/static/js/550.e9a3a306.js.gz +0 -0
  97. package/modules/admin/dist/static/js/569.711f16a3.js +1 -0
  98. package/modules/admin/dist/static/js/569.711f16a3.js.gz +0 -0
  99. package/modules/admin/dist/static/js/572.5c8cfea9.js +1 -0
  100. package/modules/admin/dist/static/js/572.5c8cfea9.js.gz +0 -0
  101. package/modules/admin/dist/static/js/603.bbe5ed23.js +1 -0
  102. package/modules/admin/dist/static/js/603.bbe5ed23.js.gz +0 -0
  103. package/modules/admin/dist/static/js/622.9f06567e.js +1 -0
  104. package/modules/admin/dist/static/js/622.9f06567e.js.gz +0 -0
  105. package/modules/admin/dist/static/js/651.86d741f0.js +1 -0
  106. package/modules/admin/dist/static/js/651.86d741f0.js.gz +0 -0
  107. package/modules/admin/dist/static/js/653.7a309059.js +1 -0
  108. package/modules/admin/dist/static/js/653.7a309059.js.gz +0 -0
  109. package/modules/admin/dist/static/js/750.10551ec8.js +1 -0
  110. package/modules/admin/dist/static/js/750.10551ec8.js.gz +0 -0
  111. package/modules/admin/dist/static/js/798.93ec90bc.js +1 -0
  112. package/modules/admin/dist/static/js/798.93ec90bc.js.gz +0 -0
  113. package/modules/admin/dist/static/js/950.d7f72b66.js +1 -0
  114. package/modules/admin/dist/static/js/950.d7f72b66.js.gz +0 -0
  115. package/modules/admin/dist/static/js/app.23870b61.js +2 -0
  116. package/modules/admin/dist/static/js/app.23870b61.js.LICENSE.txt +121 -0
  117. package/modules/admin/dist/static/js/app.23870b61.js.LICENSE.txt.gz +0 -0
  118. package/modules/admin/dist/static/js/app.23870b61.js.gz +0 -0
  119. package/modules/admin/index.html +16 -16
  120. package/modules/admin/package.json +101 -101
  121. package/modules/admin/src/App.vue +11 -11
  122. package/modules/admin/src/api/login.js +26 -26
  123. package/modules/admin/src/api/table.js +9 -9
  124. package/modules/admin/src/components/Breadcrumb/index.vue +79 -79
  125. package/modules/admin/src/components/Hamburger/index.vue +62 -62
  126. package/modules/admin/src/components/JSONEditor.vue +206 -206
  127. package/modules/admin/src/components/SvgIcon/index.vue +43 -43
  128. package/modules/admin/src/icons/index.js +9 -9
  129. package/modules/admin/src/icons/svgo.yml +22 -22
  130. package/modules/admin/src/main.js +42 -42
  131. package/modules/admin/src/permission.js +49 -49
  132. package/modules/admin/src/router/index.js +200 -200
  133. package/modules/admin/src/store/getters.js +11 -11
  134. package/modules/admin/src/store/index.js +17 -17
  135. package/modules/admin/src/store/modules/app.js +43 -43
  136. package/modules/admin/src/store/modules/user.js +104 -104
  137. package/modules/admin/src/styles/element-ui.scss +29 -29
  138. package/modules/admin/src/styles/index.scss +78 -78
  139. package/modules/admin/src/styles/mixin.scss +27 -27
  140. package/modules/admin/src/styles/sidebar.scss +133 -133
  141. package/modules/admin/src/styles/transition.scss +46 -46
  142. package/modules/admin/src/styles/variables.scss +4 -4
  143. package/modules/admin/src/utils/auth.js +15 -15
  144. package/modules/admin/src/utils/index.js +74 -74
  145. package/modules/admin/src/utils/request.js +47 -47
  146. package/modules/admin/src/utils/validate.js +31 -31
  147. package/modules/admin/src/views/404.vue +235 -235
  148. package/modules/admin/src/views/Dev.vue +33 -33
  149. package/modules/admin/src/views/EditDocument.vue +121 -121
  150. package/modules/admin/src/views/Endpoints.vue +279 -279
  151. package/modules/admin/src/views/Home.vue +84 -84
  152. package/modules/admin/src/views/Install.vue +79 -79
  153. package/modules/admin/src/views/ListDocuments.vue +72 -72
  154. package/modules/admin/src/views/ListDocuments2.vue +467 -467
  155. package/modules/admin/src/views/ManageListeners.vue +67 -67
  156. package/modules/admin/src/views/ManageMiddleware.vue +43 -43
  157. package/modules/admin/src/views/ManagePermissions.vue +75 -75
  158. package/modules/admin/src/views/ViewRequest.vue +77 -77
  159. package/modules/admin/src/views/form/index.vue +91 -91
  160. package/modules/admin/src/views/layout/Layout.vue +69 -69
  161. package/modules/admin/src/views/layout/components/AppMain.vue +41 -41
  162. package/modules/admin/src/views/layout/components/Navbar.vue +97 -97
  163. package/modules/admin/src/views/layout/components/Sidebar/Item.vue +29 -29
  164. package/modules/admin/src/views/layout/components/Sidebar/Link.vue +39 -39
  165. package/modules/admin/src/views/layout/components/Sidebar/SidebarItem.vue +103 -103
  166. package/modules/admin/src/views/layout/components/Sidebar/index.vue +62 -62
  167. package/modules/admin/src/views/layout/components/index.js +3 -3
  168. package/modules/admin/src/views/layout/mixin/ResizeHandler.js +41 -41
  169. package/modules/admin/src/views/login/index.vue +195 -195
  170. package/modules/admin/src/views/tree/index.vue +77 -77
  171. package/modules/collections/collections.js +45 -39
  172. package/modules/core/core.js +197 -197
  173. package/modules/logging/logging.js +88 -88
  174. package/modules/permissions/permissions.js +106 -106
  175. package/package.json +59 -59
  176. package/scripts/expressa +12 -12
  177. package/scripts/run_cypress_tests.sh +35 -35
  178. package/scripts/run_db_tests.sh +8 -8
  179. package/test/0-install.js +96 -96
  180. package/test/collections.js +431 -431
  181. package/test/collections.querying.js +372 -288
  182. package/test/db.js +258 -258
  183. package/test/db.strings.js +73 -73
  184. package/test/db.updating.js +186 -186
  185. package/test/logging.js +29 -29
  186. package/test/test.js +93 -93
  187. package/test/testserver.js +30 -30
  188. package/test/testutils.js +136 -136
  189. package/test/users.js +425 -425
  190. package/util.js +522 -522
@@ -1,106 +1,106 @@
1
- const { collectionPermissions, collectionOwnerPermissions } = require('../collections/collections')
2
-
3
- exports.settingSchema = {
4
- enforce_permissions: {
5
- type: 'boolean',
6
- description: 'Whether permissions should be checked. Only turn off if needed for testing.',
7
- default: true,
8
- format: 'checkbox',
9
- }
10
- }
11
-
12
- exports.collections = [{
13
- _id: 'role',
14
- schema: {
15
- type: 'object',
16
- additionalProperties: false,
17
- properties: {
18
- _id: {
19
- type: 'string'
20
- },
21
- permissions: {
22
- type: 'object',
23
- additionalProperties: true,
24
- properties: {},
25
- description: 'list of permissions this role has'
26
- }
27
- },
28
- required: [
29
- '_id',
30
- 'permissions'
31
- ]
32
- },
33
- cacheInMemory: true,
34
- documentsHaveOwners: false
35
- }]
36
-
37
- exports.install = async function (app) {
38
- app.db.role.create({
39
- _id: 'Admin',
40
- permissions: {}
41
- })
42
-
43
- app.db.role.create({
44
- _id: 'Authenticated',
45
- permissions: {
46
- 'users: view own': 1,
47
- 'users: edit own': 1,
48
- 'users: delete own': 1,
49
- }
50
- })
51
-
52
- app.db.role.create({
53
- _id: 'Anonymous',
54
- permissions: {
55
- 'users: create': 1
56
- }
57
- })
58
- }
59
-
60
- exports.permissions = ['users: modify roles', 'login to admin']
61
-
62
- exports.init = async function (api) {
63
- api.addCollectionListener(['changed'], 'collection', async function addCollectionPerms (req, collection, data) {
64
- if (api.db.role) {
65
- try {
66
- const admin = await api.db.role.get('Admin')
67
- collectionPermissions(data._id).forEach(function (permission) {
68
- if (admin.permissions[permission] == null) {
69
- admin.permissions[permission] = 1
70
- }
71
- })
72
- collectionOwnerPermissions(data._id).forEach(function (permission) {
73
- if (data.documentsHaveOwners) {
74
- if (admin.permissions[permission] == null) {
75
- admin.permissions[permission] = 1
76
- }
77
- }
78
- else {
79
- delete admin.permissions[permission]
80
- }
81
- })
82
- await api.db.role.update('Admin', admin)
83
- } catch (e) {
84
- // This error is expected if install is not complete
85
- if (api.installed || e.message !== 'document not found') {
86
- console.error('Error updating admin role with permissions')
87
- console.error(e)
88
- console.error(e.message)
89
- }
90
- }
91
- }
92
- })
93
-
94
- api.addCollectionListener('delete', 'collection', async function removeCollectionPerms (req, collection, data) {
95
- if (api.db.role) {
96
- const coll = data._id
97
- const admin = await api.db.role.get('Admin')
98
- const permissions = collectionPermissions(coll).concat(collectionOwnerPermissions(coll))
99
- permissions.forEach((permission) => {
100
- delete admin.permissions[permission]
101
- })
102
- await api.db.role.update('Admin', admin)
103
- }
104
- })
105
-
106
- }
1
+ const { collectionPermissions, collectionOwnerPermissions } = require('../collections/collections')
2
+
3
+ exports.settingSchema = {
4
+ enforce_permissions: {
5
+ type: 'boolean',
6
+ description: 'Whether permissions should be checked. Only turn off if needed for testing.',
7
+ default: true,
8
+ format: 'checkbox',
9
+ }
10
+ }
11
+
12
+ exports.collections = [{
13
+ _id: 'role',
14
+ schema: {
15
+ type: 'object',
16
+ additionalProperties: false,
17
+ properties: {
18
+ _id: {
19
+ type: 'string'
20
+ },
21
+ permissions: {
22
+ type: 'object',
23
+ additionalProperties: true,
24
+ properties: {},
25
+ description: 'list of permissions this role has'
26
+ }
27
+ },
28
+ required: [
29
+ '_id',
30
+ 'permissions'
31
+ ]
32
+ },
33
+ cacheInMemory: true,
34
+ documentsHaveOwners: false
35
+ }]
36
+
37
+ exports.install = async function (app) {
38
+ app.db.role.create({
39
+ _id: 'Admin',
40
+ permissions: {}
41
+ })
42
+
43
+ app.db.role.create({
44
+ _id: 'Authenticated',
45
+ permissions: {
46
+ 'users: view own': 1,
47
+ 'users: edit own': 1,
48
+ 'users: delete own': 1,
49
+ }
50
+ })
51
+
52
+ app.db.role.create({
53
+ _id: 'Anonymous',
54
+ permissions: {
55
+ 'users: create': 1
56
+ }
57
+ })
58
+ }
59
+
60
+ exports.permissions = ['users: modify roles', 'login to admin']
61
+
62
+ exports.init = async function (api) {
63
+ api.addCollectionListener(['changed'], 'collection', async function addCollectionPerms (req, collection, data) {
64
+ if (api.db.role) {
65
+ try {
66
+ const admin = await api.db.role.get('Admin')
67
+ collectionPermissions(data._id).forEach(function (permission) {
68
+ if (admin.permissions[permission] == null) {
69
+ admin.permissions[permission] = 1
70
+ }
71
+ })
72
+ collectionOwnerPermissions(data._id).forEach(function (permission) {
73
+ if (data.documentsHaveOwners) {
74
+ if (admin.permissions[permission] == null) {
75
+ admin.permissions[permission] = 1
76
+ }
77
+ }
78
+ else {
79
+ delete admin.permissions[permission]
80
+ }
81
+ })
82
+ await api.db.role.update('Admin', admin)
83
+ } catch (e) {
84
+ // This error is expected if install is not complete
85
+ if (api.installed || e.message !== 'document not found') {
86
+ console.error('Error updating admin role with permissions')
87
+ console.error(e)
88
+ console.error(e.message)
89
+ }
90
+ }
91
+ }
92
+ })
93
+
94
+ api.addCollectionListener('delete', 'collection', async function removeCollectionPerms (req, collection, data) {
95
+ if (api.db.role) {
96
+ const coll = data._id
97
+ const admin = await api.db.role.get('Admin')
98
+ const permissions = collectionPermissions(coll).concat(collectionOwnerPermissions(coll))
99
+ permissions.forEach((permission) => {
100
+ delete admin.permissions[permission]
101
+ })
102
+ await api.db.role.update('Admin', admin)
103
+ }
104
+ })
105
+
106
+ }
package/package.json CHANGED
@@ -1,59 +1,59 @@
1
- {
2
- "name": "expressa",
3
- "version": "2.1.0",
4
- "description": "API framework using JSON schemas",
5
- "main": "index.js",
6
- "repository": "https://github.com/thomas4019/expressa",
7
- "bin": {
8
- "expressa": "./scripts/expressa"
9
- },
10
- "dependencies": {
11
- "ajv": "^8.1.0",
12
- "bcryptjs": "2.4.3",
13
- "body-parser": "^1.19.0",
14
- "debug": "^2.6.1",
15
- "dot-object": "^2.1.4",
16
- "express": "^4.17.1",
17
- "jfs": "^0.2.6",
18
- "jsonwebtoken": "^9.0.0",
19
- "mongo-query": "^0.5.7",
20
- "mongo-query-to-postgres-jsonb": "^0.2.17",
21
- "mongo-querystring": "4.1.1",
22
- "mongodb": "^3.5.7",
23
- "on-finished": "^2.3.0",
24
- "pg": "^8.4.2",
25
- "randomstring": "1.1.4",
26
- "sift": "^5.1.0",
27
- "uuid": "^8.3.0"
28
- },
29
- "devDependencies": {
30
- "chai": "^4.2.0",
31
- "cross-env": "^7.0.2",
32
- "cypress": "^15.3.0",
33
- "eslint": "^7.1.0",
34
- "mocha": "^11.7.2",
35
- "mocha-junit-reporter": "^2.0.2",
36
- "nodemon": "^3.1.10",
37
- "rimraf": "^3.0.2",
38
- "supertest": "^3.4.2"
39
- },
40
- "engines": {
41
- "node": ">= 8.1.4"
42
- },
43
- "author": "Thomas Hansen <th4019@example.com> (http://thomashansen.me)",
44
- "scripts": {
45
- "test": "cross-env NODE_ENV=local_test_suite mocha --exit",
46
- "testlint": "cross-env NODE_ENV=local_test_suite mocha --exit && npm run lint",
47
- "testdebug": "cross-env NODE_ENV=local_test_suite DEBUG=expressa mocha -b --exit && npm run lint",
48
- "ci-test": "cross-env NODE_ENV=local_test_suite mocha test --reporter mocha-junit-reporter --exit",
49
- "clean": "rimraf node_modules",
50
- "lint": "eslint .",
51
- "fixlint": "eslint . --fix",
52
- "testserver": "rimraf testdata && node test/testserver.js",
53
- "testserver-watch": "rimraf testdata && nodemon test/testserver.js",
54
- "cypress": "cypress open",
55
- "testdbs": "./scripts/run_db_tests.sh",
56
- "testcypress": "./scripts/run_cypress_tests.sh"
57
- },
58
- "license": "MIT"
59
- }
1
+ {
2
+ "name": "expressa",
3
+ "version": "2.1.2",
4
+ "description": "API framework using JSON schemas",
5
+ "main": "index.js",
6
+ "repository": "https://github.com/thomas4019/expressa",
7
+ "bin": {
8
+ "expressa": "./scripts/expressa"
9
+ },
10
+ "dependencies": {
11
+ "ajv": "^8.1.0",
12
+ "bcryptjs": "2.4.3",
13
+ "body-parser": "^1.19.0",
14
+ "debug": "^2.6.1",
15
+ "dot-object": "^2.1.4",
16
+ "express": "^4.17.1",
17
+ "jfs": "^0.2.6",
18
+ "jsonwebtoken": "^9.0.0",
19
+ "mongo-query": "^0.5.7",
20
+ "mongo-query-to-postgres-jsonb": "^0.2.17",
21
+ "mongo-querystring": "4.1.1",
22
+ "mongodb": "^3.5.7",
23
+ "on-finished": "^2.3.0",
24
+ "pg": "^8.4.2",
25
+ "randomstring": "1.1.4",
26
+ "sift": "^5.1.0",
27
+ "uuid": "^8.3.0"
28
+ },
29
+ "devDependencies": {
30
+ "chai": "^4.2.0",
31
+ "cross-env": "^7.0.2",
32
+ "cypress": "^15.3.0",
33
+ "eslint": "^7.1.0",
34
+ "mocha": "^11.7.2",
35
+ "mocha-junit-reporter": "^2.0.2",
36
+ "nodemon": "^3.1.10",
37
+ "rimraf": "^3.0.2",
38
+ "supertest": "^3.4.2"
39
+ },
40
+ "engines": {
41
+ "node": ">= 8.1.4"
42
+ },
43
+ "author": "Thomas Hansen <th4019@example.com> (http://thomashansen.me)",
44
+ "scripts": {
45
+ "test": "cross-env NODE_ENV=local_test_suite mocha --exit",
46
+ "testlint": "cross-env NODE_ENV=local_test_suite mocha --exit && npm run lint",
47
+ "testdebug": "cross-env NODE_ENV=local_test_suite DEBUG=expressa mocha -b --exit && npm run lint",
48
+ "ci-test": "cross-env NODE_ENV=local_test_suite mocha test --reporter mocha-junit-reporter --exit",
49
+ "clean": "rimraf node_modules",
50
+ "lint": "eslint .",
51
+ "fixlint": "eslint . --fix",
52
+ "testserver": "rimraf testdata && node test/testserver.js",
53
+ "testserver-watch": "rimraf testdata && nodemon test/testserver.js",
54
+ "cypress": "cypress open",
55
+ "testdbs": "./scripts/run_db_tests.sh",
56
+ "testcypress": "./scripts/run_cypress_tests.sh"
57
+ },
58
+ "license": "MIT"
59
+ }
package/scripts/expressa CHANGED
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
-
3
- 'use strict';
4
-
5
- var express = require('express');
6
- var app = express();
7
-
8
- var expressa = require('../');
9
- app.use('/api', expressa.api()); // optionally pass in settings
10
- app.use('/admin', expressa.admin({ apiurl: '/api/' }));
11
-
12
- app.listen(3000, function () {
13
- console.log('Example app listening on port 3000!');
2
+
3
+ 'use strict';
4
+
5
+ var express = require('express');
6
+ var app = express();
7
+
8
+ var expressa = require('../');
9
+ app.use('/api', expressa.api()); // optionally pass in settings
10
+ app.use('/admin', expressa.admin({ apiurl: '/api/' }));
11
+
12
+ app.listen(3000, function () {
13
+ console.log('Example app listening on port 3000!');
14
14
  });
@@ -1,36 +1,36 @@
1
- set -e
2
-
3
- rm -rf testdata
4
-
5
- node test/testserver.js &
6
- pid=$!
7
-
8
- cleanup() {
9
- if kill -0 "$pid" >/dev/null 2>&1; then
10
- kill "$pid" || true
11
- # give it a moment to exit gracefully
12
- sleep 1 || true
13
- if kill -0 "$pid" >/dev/null 2>&1; then
14
- kill -9 "$pid" || true
15
- fi
16
- fi
17
- }
18
- trap cleanup EXIT
19
-
20
- # Wait for server readiness
21
- attempts=0
22
- until curl -sSf "http://localhost:3001/admin" >/dev/null 2>&1; do
23
- attempts=$((attempts+1))
24
- if [ "$attempts" -gt 120 ]; then
25
- echo "Server did not become ready on http://localhost:3001/admin" >&2
26
- exit 1
27
- fi
28
- # bail out early if server died
29
- if ! kill -0 "$pid" >/dev/null 2>&1; then
30
- echo "Server process exited prematurely" >&2
31
- exit 1
32
- fi
33
- sleep 0.5
34
- done
35
-
1
+ set -e
2
+
3
+ rm -rf testdata
4
+
5
+ node test/testserver.js &
6
+ pid=$!
7
+
8
+ cleanup() {
9
+ if kill -0 "$pid" >/dev/null 2>&1; then
10
+ kill "$pid" || true
11
+ # give it a moment to exit gracefully
12
+ sleep 1 || true
13
+ if kill -0 "$pid" >/dev/null 2>&1; then
14
+ kill -9 "$pid" || true
15
+ fi
16
+ fi
17
+ }
18
+ trap cleanup EXIT
19
+
20
+ # Wait for server readiness
21
+ attempts=0
22
+ until curl -sSf "http://localhost:3001/admin" >/dev/null 2>&1; do
23
+ attempts=$((attempts+1))
24
+ if [ "$attempts" -gt 120 ]; then
25
+ echo "Server did not become ready on http://localhost:3001/admin" >&2
26
+ exit 1
27
+ fi
28
+ # bail out early if server died
29
+ if ! kill -0 "$pid" >/dev/null 2>&1; then
30
+ echo "Server process exited prematurely" >&2
31
+ exit 1
32
+ fi
33
+ sleep 0.5
34
+ done
35
+
36
36
  ./node_modules/.bin/cypress run
@@ -1,8 +1,8 @@
1
- docker run -d -p 5432:5432 --rm --name postgres -e POSTGRES_PASSWORD=expressa postgres
2
- docker run -d -p 27017:27017 --rm --name mongo mongo
3
- sleep 1
4
- docker exec -it postgres /bin/bash -c "createdb pgtest -U postgres"
5
- TEST_POSTGRES=true TEST_MONGO=true npm run test
6
-
7
- docker stop postgres
8
- docker stop mongo
1
+ docker run -d -p 5432:5432 --rm --name postgres -e POSTGRES_PASSWORD=expressa postgres
2
+ docker run -d -p 27017:27017 --rm --name mongo mongo
3
+ sleep 1
4
+ docker exec -it postgres /bin/bash -c "createdb pgtest -U postgres"
5
+ TEST_POSTGRES=true TEST_MONGO=true npm run test
6
+
7
+ docker stop postgres
8
+ docker stop mongo
package/test/0-install.js CHANGED
@@ -1,96 +1,96 @@
1
- const request = require('supertest')
2
- const chai = require('chai')
3
- const expect = chai.expect
4
- const testutils = require('./testutils')
5
- const { app, api } = testutils
6
-
7
- describe('install flow', function () {
8
- it('can get settings schema', async function() {
9
- const { body } = await request(app)
10
- .get('/install/settings/schema')
11
- .expect(200)
12
- expect(body.schema.properties.jwt_secret).to.eql({
13
- type: 'string',
14
- description: 'The secret key used to encode your json web tokens. It\'s important this is kept unique and secret.'
15
- })
16
- })
17
-
18
- it('call install', async function () {
19
- expect(api.db.collections).to.not.exist
20
-
21
- await request(app)
22
- .post('/install')
23
- .send({
24
- modules: ['collections', 'core', 'logging', 'permissions', 'access_keys'],
25
- settings: {
26
- jwt_secret: 'testing 123',
27
- jwt_expire_on_password_change: true,
28
- mongodb_uri: 'mongodb://localhost:27017/test',
29
- postgresql_uri: 'postgresql://postgres:expressa@localhost/pgtest',
30
- enforce_permissions: true,
31
- user_storage: 'mongo'
32
- }
33
- })
34
- .expect(200)
35
-
36
- expect(api.db.collection).to.exist
37
- expect(api.db.role).to.exist
38
- expect(api.db.users).to.exist
39
- expect(api.settings.jwt_secret.length).to.be.greaterThan(20)
40
-
41
- // Check storage of users set correctly and then restore to 'file'
42
- const userCollection = (await api.db.collection.find({ _id: 'users' }))[0]
43
- expect(userCollection.storage).to.eql('mongo')
44
- userCollection.storage = 'file'
45
- await api.db.collection.update(null, userCollection)
46
- api.setupCollectionDb(userCollection)
47
-
48
- const userCollection2 = (await api.db.collection.find({ _id: 'users' }))[0]
49
- expect(userCollection2.storage).to.eql('file')
50
- })
51
-
52
- it('can create admin account', async function() {
53
- const res = await request(app)
54
- .post('/users/register')
55
- .send({
56
- email: 'a@example.com',
57
- roles: ['Admin'],
58
- password: '123'
59
- })
60
- .expect(200)
61
- const id = res.body.id
62
- const u = await api.db.users.get(id)
63
- expect(u.roles || []).to.include('Admin')
64
- })
65
-
66
- it('can login admin account', async function() {
67
- const res = await request(app)
68
- .post('/users/login')
69
- .send({
70
- email: 'a@example.com',
71
- password: '123'
72
- })
73
- .expect(200)
74
- testutils.setAdminToken(res.body.token)
75
- })
76
-
77
- it('2nd account cannot be admin account', async function() {
78
- await request(app)
79
- .post('/users/register')
80
- .send({
81
- email: 'try2@example.com',
82
- roles: ['Admin'],
83
- password: 'admin2'
84
- })
85
- .expect(400)
86
- })
87
-
88
- it('admin should have many permissions set', async function () {
89
- const admin = await api.db.role.get('Admin')
90
- expect(admin.permissions).deep.include({
91
- 'view errors': 1,
92
- 'collection: create': 1,
93
- 'users: edit own': 1
94
- })
95
- })
96
- })
1
+ const request = require('supertest')
2
+ const chai = require('chai')
3
+ const expect = chai.expect
4
+ const testutils = require('./testutils')
5
+ const { app, api } = testutils
6
+
7
+ describe('install flow', function () {
8
+ it('can get settings schema', async function() {
9
+ const { body } = await request(app)
10
+ .get('/install/settings/schema')
11
+ .expect(200)
12
+ expect(body.schema.properties.jwt_secret).to.eql({
13
+ type: 'string',
14
+ description: 'The secret key used to encode your json web tokens. It\'s important this is kept unique and secret.'
15
+ })
16
+ })
17
+
18
+ it('call install', async function () {
19
+ expect(api.db.collections).to.not.exist
20
+
21
+ await request(app)
22
+ .post('/install')
23
+ .send({
24
+ modules: ['collections', 'core', 'logging', 'permissions', 'access_keys'],
25
+ settings: {
26
+ jwt_secret: 'testing 123',
27
+ jwt_expire_on_password_change: true,
28
+ mongodb_uri: 'mongodb://localhost:27017/test',
29
+ postgresql_uri: 'postgresql://postgres:expressa@localhost/pgtest',
30
+ enforce_permissions: true,
31
+ user_storage: 'mongo'
32
+ }
33
+ })
34
+ .expect(200)
35
+
36
+ expect(api.db.collection).to.exist
37
+ expect(api.db.role).to.exist
38
+ expect(api.db.users).to.exist
39
+ expect(api.settings.jwt_secret.length).to.be.greaterThan(20)
40
+
41
+ // Check storage of users set correctly and then restore to 'file'
42
+ const userCollection = (await api.db.collection.find({ _id: 'users' }))[0]
43
+ expect(userCollection.storage).to.eql('mongo')
44
+ userCollection.storage = 'file'
45
+ await api.db.collection.update(null, userCollection)
46
+ api.setupCollectionDb(userCollection)
47
+
48
+ const userCollection2 = (await api.db.collection.find({ _id: 'users' }))[0]
49
+ expect(userCollection2.storage).to.eql('file')
50
+ })
51
+
52
+ it('can create admin account', async function() {
53
+ const res = await request(app)
54
+ .post('/users/register')
55
+ .send({
56
+ email: 'a@example.com',
57
+ roles: ['Admin'],
58
+ password: '123'
59
+ })
60
+ .expect(200)
61
+ const id = res.body.id
62
+ const u = await api.db.users.get(id)
63
+ expect(u.roles || []).to.include('Admin')
64
+ })
65
+
66
+ it('can login admin account', async function() {
67
+ const res = await request(app)
68
+ .post('/users/login')
69
+ .send({
70
+ email: 'a@example.com',
71
+ password: '123'
72
+ })
73
+ .expect(200)
74
+ testutils.setAdminToken(res.body.token)
75
+ })
76
+
77
+ it('2nd account cannot be admin account', async function() {
78
+ await request(app)
79
+ .post('/users/register')
80
+ .send({
81
+ email: 'try2@example.com',
82
+ roles: ['Admin'],
83
+ password: 'admin2'
84
+ })
85
+ .expect(400)
86
+ })
87
+
88
+ it('admin should have many permissions set', async function () {
89
+ const admin = await api.db.role.get('Admin')
90
+ expect(admin.permissions).deep.include({
91
+ 'view errors': 1,
92
+ 'collection: create': 1,
93
+ 'users: edit own': 1
94
+ })
95
+ })
96
+ })