expressa 2.0.17 → 2.0.18

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 (281) 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/index.js +76 -76
  6. package/auth/jwt.js +31 -31
  7. package/controllers/collections.js +260 -258
  8. package/controllers/install.js +105 -105
  9. package/controllers/status.js +43 -43
  10. package/controllers/users.js +52 -52
  11. package/cypress/fixtures/example.json +4 -4
  12. package/cypress/integration/0_install_spec.js +8 -8
  13. package/cypress/integration/custom_collections.js +28 -28
  14. package/cypress/integration/home.js +9 -9
  15. package/cypress/integration/settings.js +34 -34
  16. package/cypress/integration/users.js +61 -61
  17. package/cypress/plugins/index.js +17 -17
  18. package/cypress/support/commands.js +54 -54
  19. package/cypress/support/index.js +20 -20
  20. package/cypress/support/util.js +10 -10
  21. package/cypress.json +4 -4
  22. package/db/cached.js +40 -40
  23. package/db/file.js +112 -112
  24. package/db/memory.js +79 -79
  25. package/db/mongo.js +86 -86
  26. package/db/postgres.js +93 -93
  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/index.js +297 -297
  40. package/listeners.js +65 -65
  41. package/listeners_collection_permissions.js +29 -29
  42. package/listeners_users.js +96 -96
  43. package/listeners_validation.js +43 -43
  44. package/middleware/logging.js +30 -30
  45. package/middleware/permissions.js +41 -41
  46. package/modules/access_keys/access_keys.js +32 -32
  47. package/modules/admin/.babelrc +19 -19
  48. package/modules/admin/.editorconfig +14 -14
  49. package/modules/admin/.eslintignore +5 -5
  50. package/modules/admin/.eslintrc.js +197 -197
  51. package/modules/admin/.postcssrc.js +10 -10
  52. package/modules/admin/.travis.yml +5 -5
  53. package/modules/admin/LICENSE +21 -21
  54. package/modules/admin/README.md +88 -88
  55. package/modules/admin/build/build.js +45 -45
  56. package/modules/admin/build/check-versions.js +64 -64
  57. package/modules/admin/build/utils.js +108 -108
  58. package/modules/admin/build/vue-loader.conf.js +5 -5
  59. package/modules/admin/build/webpack.base.conf.js +112 -112
  60. package/modules/admin/build/webpack.dev.conf.js +95 -95
  61. package/modules/admin/build/webpack.prod.conf.js +112 -112
  62. package/modules/admin/config/dev.env.js +8 -8
  63. package/modules/admin/config/index.js +86 -86
  64. package/modules/admin/config/prod.env.js +5 -5
  65. package/modules/admin/dist/index.html +1 -1
  66. package/modules/admin/dist/index.html.gz +0 -0
  67. package/modules/admin/dist/static/css/app.9dd57eea.css +1 -0
  68. package/modules/admin/dist/static/css/app.9dd57eea.css.gz +0 -0
  69. package/modules/admin/dist/static/css/chunk-5061.ce0e4bdb.css +1 -0
  70. package/modules/admin/dist/static/css/chunk-5061.ce0e4bdb.css.gz +0 -0
  71. package/modules/admin/dist/static/css/chunk-5b97.7f9cb53e.css +1 -0
  72. package/modules/admin/dist/static/css/chunk-5b97.7f9cb53e.css.gz +0 -0
  73. package/modules/admin/dist/static/css/chunk-621e.b826be8d.css +1 -0
  74. package/modules/admin/dist/static/css/chunk-621e.b826be8d.css.gz +0 -0
  75. package/modules/admin/dist/static/css/chunk-656b.9c828b00.css +1 -0
  76. package/modules/admin/dist/static/css/chunk-656b.9c828b00.css.gz +0 -0
  77. package/modules/admin/dist/static/css/chunk-7291.13514e45.css +0 -0
  78. package/modules/admin/dist/static/css/chunk-7291.13514e45.css.gz +0 -0
  79. package/modules/admin/dist/static/css/chunk-7f29.9c828b00.css +1 -0
  80. package/modules/admin/dist/static/css/chunk-7f29.9c828b00.css.gz +0 -0
  81. package/modules/admin/dist/static/css/chunk-9a95.c647a2ef.css +1 -0
  82. package/modules/admin/dist/static/css/chunk-9a95.c647a2ef.css.gz +0 -0
  83. package/modules/admin/dist/static/css/chunk-b423.5f239333.css +0 -0
  84. package/modules/admin/dist/static/css/chunk-b423.5f239333.css.gz +0 -0
  85. package/modules/admin/dist/static/css/chunk-bd5f.aefa49d7.css +1 -0
  86. package/modules/admin/dist/static/css/chunk-bd5f.aefa49d7.css.gz +0 -0
  87. package/modules/admin/dist/static/css/chunk-e374.025d58bb.css +1 -0
  88. package/modules/admin/dist/static/css/chunk-e374.025d58bb.css.gz +0 -0
  89. package/modules/admin/dist/static/css/chunk-elementUI.3d004d9f.css +1 -0
  90. package/modules/admin/dist/static/css/chunk-elementUI.3d004d9f.css.gz +0 -0
  91. package/modules/admin/dist/static/css/chunk-f075.3a895a1e.css +1 -0
  92. package/modules/admin/dist/static/css/chunk-f075.3a895a1e.css.gz +0 -0
  93. package/modules/admin/dist/static/css/chunk-libs.327ad89e.css +14 -0
  94. package/modules/admin/dist/static/css/chunk-libs.327ad89e.css.gz +0 -0
  95. package/modules/admin/dist/static/fonts/element-icons.6f0a763.ttf +0 -0
  96. package/modules/admin/dist/static/js/app.e9461593.js +1 -0
  97. package/modules/admin/dist/static/js/app.e9461593.js.gz +0 -0
  98. package/modules/admin/dist/static/js/chunk-09d8.561880e0.js +2 -0
  99. package/modules/admin/dist/static/js/chunk-09d8.561880e0.js.LICENSE.txt +13 -0
  100. package/modules/admin/dist/static/js/chunk-09d8.561880e0.js.LICENSE.txt.gz +0 -0
  101. package/modules/admin/dist/static/js/chunk-09d8.561880e0.js.gz +0 -0
  102. package/modules/admin/dist/static/js/chunk-5061.83e6ccfa.js +1 -0
  103. package/modules/admin/dist/static/js/chunk-5061.83e6ccfa.js.gz +0 -0
  104. package/modules/admin/dist/static/js/chunk-5b97.ac360086.js +1 -0
  105. package/modules/admin/dist/static/js/chunk-5b97.ac360086.js.gz +0 -0
  106. package/modules/admin/dist/static/js/chunk-5e17.a2b69611.js +1 -0
  107. package/modules/admin/dist/static/js/chunk-5e17.a2b69611.js.gz +0 -0
  108. package/modules/admin/dist/static/js/chunk-621e.ccf42393.js +1 -0
  109. package/modules/admin/dist/static/js/chunk-621e.ccf42393.js.gz +0 -0
  110. package/modules/admin/dist/static/js/chunk-656b.9d5b03c0.js +1 -0
  111. package/modules/admin/dist/static/js/chunk-656b.9d5b03c0.js.gz +0 -0
  112. package/modules/admin/dist/static/js/chunk-7291.590524e9.js +1 -0
  113. package/modules/admin/dist/static/js/chunk-7291.590524e9.js.gz +0 -0
  114. package/modules/admin/dist/static/js/chunk-7f29.6ffc142e.js +1 -0
  115. package/modules/admin/dist/static/js/chunk-7f29.6ffc142e.js.gz +0 -0
  116. package/modules/admin/dist/static/js/chunk-9a95.bdd76583.js +1 -0
  117. package/modules/admin/dist/static/js/chunk-9a95.bdd76583.js.gz +0 -0
  118. package/modules/admin/dist/static/js/chunk-b423.387c504c.js +1 -0
  119. package/modules/admin/dist/static/js/chunk-b423.387c504c.js.gz +0 -0
  120. package/modules/admin/dist/static/js/chunk-bd5f.e9509f10.js +1 -0
  121. package/modules/admin/dist/static/js/chunk-bd5f.e9509f10.js.gz +0 -0
  122. package/modules/admin/dist/static/js/chunk-e374.7c87a0dd.js +1 -0
  123. package/modules/admin/dist/static/js/chunk-e374.7c87a0dd.js.gz +0 -0
  124. package/modules/admin/dist/static/js/chunk-e7c3.e5df8ceb.js +1 -0
  125. package/modules/admin/dist/static/js/chunk-e7c3.e5df8ceb.js.gz +0 -0
  126. package/modules/admin/dist/static/js/chunk-elementUI.b0c99c08.js +1 -0
  127. package/modules/admin/dist/static/js/chunk-elementUI.b0c99c08.js.gz +0 -0
  128. package/modules/admin/dist/static/js/chunk-f075.315ceec1.js +1 -0
  129. package/modules/admin/dist/static/js/chunk-f075.315ceec1.js.gz +0 -0
  130. package/modules/admin/dist/static/js/chunk-libs.06c38828.js +2 -0
  131. package/modules/admin/dist/static/js/{app.981e71b3.js.LICENSE.txt → chunk-libs.06c38828.js.LICENSE.txt} +18 -15
  132. package/modules/admin/dist/static/js/chunk-libs.06c38828.js.LICENSE.txt.gz +0 -0
  133. package/modules/admin/dist/static/js/chunk-libs.06c38828.js.gz +0 -0
  134. package/modules/admin/index.html +16 -16
  135. package/modules/admin/package.json +101 -101
  136. package/modules/admin/src/App.vue +11 -11
  137. package/modules/admin/src/api/login.js +26 -26
  138. package/modules/admin/src/api/table.js +9 -9
  139. package/modules/admin/src/components/Breadcrumb/index.vue +79 -79
  140. package/modules/admin/src/components/Hamburger/index.vue +62 -62
  141. package/modules/admin/src/components/JSONEditor.vue +180 -180
  142. package/modules/admin/src/components/SvgIcon/index.vue +43 -43
  143. package/modules/admin/src/icons/index.js +9 -9
  144. package/modules/admin/src/icons/svgo.yml +22 -22
  145. package/modules/admin/src/main.js +42 -42
  146. package/modules/admin/src/permission.js +49 -49
  147. package/modules/admin/src/router/index.js +200 -200
  148. package/modules/admin/src/store/getters.js +11 -11
  149. package/modules/admin/src/store/index.js +17 -17
  150. package/modules/admin/src/store/modules/app.js +43 -43
  151. package/modules/admin/src/store/modules/user.js +104 -104
  152. package/modules/admin/src/styles/element-ui.scss +29 -29
  153. package/modules/admin/src/styles/index.scss +78 -78
  154. package/modules/admin/src/styles/mixin.scss +27 -27
  155. package/modules/admin/src/styles/sidebar.scss +133 -133
  156. package/modules/admin/src/styles/transition.scss +46 -46
  157. package/modules/admin/src/styles/variables.scss +4 -4
  158. package/modules/admin/src/utils/auth.js +15 -15
  159. package/modules/admin/src/utils/index.js +74 -74
  160. package/modules/admin/src/utils/request.js +48 -48
  161. package/modules/admin/src/utils/validate.js +31 -31
  162. package/modules/admin/src/views/404.vue +235 -235
  163. package/modules/admin/src/views/Dev.vue +33 -33
  164. package/modules/admin/src/views/EditDocument.vue +116 -116
  165. package/modules/admin/src/views/Endpoints.vue +279 -279
  166. package/modules/admin/src/views/Home.vue +84 -84
  167. package/modules/admin/src/views/Install.vue +79 -79
  168. package/modules/admin/src/views/ListDocuments.vue +72 -72
  169. package/modules/admin/src/views/ListDocuments2.vue +462 -462
  170. package/modules/admin/src/views/ManageListeners.vue +67 -67
  171. package/modules/admin/src/views/ManageMiddleware.vue +43 -43
  172. package/modules/admin/src/views/ManagePermissions.vue +75 -75
  173. package/modules/admin/src/views/ViewRequest.vue +77 -77
  174. package/modules/admin/src/views/form/index.vue +91 -91
  175. package/modules/admin/src/views/layout/Layout.vue +69 -69
  176. package/modules/admin/src/views/layout/components/AppMain.vue +41 -41
  177. package/modules/admin/src/views/layout/components/Navbar.vue +97 -97
  178. package/modules/admin/src/views/layout/components/Sidebar/Item.vue +29 -29
  179. package/modules/admin/src/views/layout/components/Sidebar/Link.vue +39 -39
  180. package/modules/admin/src/views/layout/components/Sidebar/SidebarItem.vue +103 -103
  181. package/modules/admin/src/views/layout/components/Sidebar/index.vue +62 -62
  182. package/modules/admin/src/views/layout/components/index.js +3 -3
  183. package/modules/admin/src/views/layout/mixin/ResizeHandler.js +41 -41
  184. package/modules/admin/src/views/login/index.vue +195 -195
  185. package/modules/admin/src/views/tree/index.vue +77 -77
  186. package/modules/collections/collections.js +39 -39
  187. package/modules/core/core.js +197 -197
  188. package/modules/logging/logging.js +88 -88
  189. package/modules/permissions/permissions.js +106 -106
  190. package/package.json +59 -59
  191. package/scripts/expressa +12 -12
  192. package/scripts/run_cypress_tests.sh +5 -5
  193. package/scripts/run_db_tests.sh +8 -8
  194. package/test/0-install.js +96 -96
  195. package/test/collections.js +431 -431
  196. package/test/collections.querying.js +288 -288
  197. package/test/db.js +258 -258
  198. package/test/db.strings.js +73 -73
  199. package/test/db.updating.js +144 -144
  200. package/test/logging.js +29 -29
  201. package/test/test.js +93 -93
  202. package/test/testserver.js +17 -17
  203. package/test/testutils.js +136 -136
  204. package/test/users.js +425 -425
  205. package/util.js +522 -522
  206. package/modules/admin/dist/164c6167c1f3c497c07c.woff +0 -1
  207. package/modules/admin/dist/42ac07abc8473600c41f.ttf +0 -1
  208. package/modules/admin/dist/86dccb18a7eb4be8ef1a.woff +0 -1
  209. package/modules/admin/dist/c45297c558e0318fc9c5.ttf +0 -1
  210. package/modules/admin/dist/c717c9930715e24fa12c.woff +0 -1
  211. package/modules/admin/dist/ca6f07ef23f24cc2738a.ttf +0 -1
  212. package/modules/admin/dist/css/269.f7d5c7d5.css +0 -37
  213. package/modules/admin/dist/css/269.f7d5c7d5.css.gz +0 -0
  214. package/modules/admin/dist/css/451.c6646d20.css +0 -1
  215. package/modules/admin/dist/css/451.c6646d20.css.gz +0 -0
  216. package/modules/admin/dist/css/572.74d8e965.css +0 -34
  217. package/modules/admin/dist/css/572.74d8e965.css.gz +0 -0
  218. package/modules/admin/dist/css/651.e946bda7.css +0 -6
  219. package/modules/admin/dist/css/651.e946bda7.css.gz +0 -0
  220. package/modules/admin/dist/css/699.d1f90954.css +0 -8
  221. package/modules/admin/dist/css/699.d1f90954.css.gz +0 -0
  222. package/modules/admin/dist/css/750.4086915d.css +0 -2
  223. package/modules/admin/dist/css/750.4086915d.css.gz +0 -0
  224. package/modules/admin/dist/css/864.506917a4.css +0 -7
  225. package/modules/admin/dist/css/864.506917a4.css.gz +0 -0
  226. package/modules/admin/dist/css/899.506917a4.css +0 -7
  227. package/modules/admin/dist/css/899.506917a4.css.gz +0 -0
  228. package/modules/admin/dist/css/950.1fd9d57c.css +0 -7
  229. package/modules/admin/dist/css/950.1fd9d57c.css.gz +0 -0
  230. package/modules/admin/dist/css/app.11cc6245.css +0 -39
  231. package/modules/admin/dist/css/app.11cc6245.css.gz +0 -0
  232. package/modules/admin/dist/css/app.2e1b0d79.css +0 -591
  233. package/modules/admin/dist/css/app.2e1b0d79.css.gz +0 -0
  234. package/modules/admin/dist/css/app.4d43d0fd.css +0 -592
  235. package/modules/admin/dist/css/app.4d43d0fd.css.gz +0 -0
  236. package/modules/admin/dist/css/app.abace109.css +0 -1
  237. package/modules/admin/dist/css/app.abace109.css.gz +0 -0
  238. package/modules/admin/dist/css/chunk-elementUI.67ad86d7.css +0 -1
  239. package/modules/admin/dist/css/chunk-elementUI.67ad86d7.css.gz +0 -0
  240. package/modules/admin/dist/css/chunk-elementUI.9e660bfd.css +0 -1
  241. package/modules/admin/dist/css/chunk-elementUI.9e660bfd.css.gz +0 -0
  242. package/modules/admin/dist/css/chunk-elementUI.c77cf142.css +0 -1
  243. package/modules/admin/dist/css/chunk-elementUI.c77cf142.css.gz +0 -0
  244. package/modules/admin/dist/css/chunk-elementUI.f1625b35.css +0 -1
  245. package/modules/admin/dist/css/chunk-elementUI.f1625b35.css.gz +0 -0
  246. package/modules/admin/dist/css/chunk-elementUI.f25dfb9b.css +0 -1
  247. package/modules/admin/dist/css/chunk-elementUI.f25dfb9b.css.gz +0 -0
  248. package/modules/admin/dist/css/chunk-libs.de0d8484.css +0 -551
  249. package/modules/admin/dist/css/chunk-libs.de0d8484.css.gz +0 -0
  250. package/modules/admin/dist/static/fonts/element-icons.313f7da.woff +0 -0
  251. package/modules/admin/dist/static/fonts/element-icons.4520188.ttf +0 -0
  252. package/modules/admin/dist/static/js/269.7245ceaf.js +0 -1
  253. package/modules/admin/dist/static/js/269.7245ceaf.js.gz +0 -0
  254. package/modules/admin/dist/static/js/451.645974a8.js +0 -1
  255. package/modules/admin/dist/static/js/451.645974a8.js.gz +0 -0
  256. package/modules/admin/dist/static/js/460.962d5bc0.js +0 -1
  257. package/modules/admin/dist/static/js/460.962d5bc0.js.gz +0 -0
  258. package/modules/admin/dist/static/js/556.1e08866a.js +0 -1
  259. package/modules/admin/dist/static/js/556.1e08866a.js.gz +0 -0
  260. package/modules/admin/dist/static/js/572.13392e1d.js +0 -1
  261. package/modules/admin/dist/static/js/572.13392e1d.js.gz +0 -0
  262. package/modules/admin/dist/static/js/603.7b34a650.js +0 -1
  263. package/modules/admin/dist/static/js/603.7b34a650.js.gz +0 -0
  264. package/modules/admin/dist/static/js/637.26413baa.js +0 -1
  265. package/modules/admin/dist/static/js/637.26413baa.js.gz +0 -0
  266. package/modules/admin/dist/static/js/651.564b24b6.js +0 -1
  267. package/modules/admin/dist/static/js/651.564b24b6.js.gz +0 -0
  268. package/modules/admin/dist/static/js/653.02ec1098.js +0 -1
  269. package/modules/admin/dist/static/js/653.02ec1098.js.gz +0 -0
  270. package/modules/admin/dist/static/js/699.c7564884.js +0 -1
  271. package/modules/admin/dist/static/js/699.c7564884.js.gz +0 -0
  272. package/modules/admin/dist/static/js/750.50c950da.js +0 -1
  273. package/modules/admin/dist/static/js/750.50c950da.js.gz +0 -0
  274. package/modules/admin/dist/static/js/864.4f43847d.js +0 -1
  275. package/modules/admin/dist/static/js/864.4f43847d.js.gz +0 -0
  276. package/modules/admin/dist/static/js/950.d4ff0a18.js +0 -1
  277. package/modules/admin/dist/static/js/950.d4ff0a18.js.gz +0 -0
  278. package/modules/admin/dist/static/js/app.981e71b3.js +0 -2
  279. package/modules/admin/dist/static/js/app.981e71b3.js.LICENSE.txt.gz +0 -0
  280. package/modules/admin/dist/static/js/app.981e71b3.js.gz +0 -0
  281. /package/modules/admin/dist/static/img/{404.4cf6930.png → 404.a57b6f3.png} +0 -0
@@ -1,61 +1,61 @@
1
- import { randomId } from '../support/util'
2
-
3
- describe('User Management', function() {
4
- it('Lists users', function() {
5
- cy.server()
6
- cy.route('/api/users/schema').as('userschema')
7
- cy.route('/api/collection/users').as('users')
8
- cy.login()
9
- cy.visit('/')
10
-
11
- // cy.visit('#/users/list')
12
- cy.get('.hamburger-container').click();
13
- cy.wait(100)
14
- cy.get('span').contains('People').click();
15
- cy.get('span').contains('Users').click();
16
- cy.wait('@users')
17
- // cy.get('a').contains('a@example.com').click();
18
-
19
-
20
- cy.get('table tr:last-child td:first-child').click();
21
- // cy.visit()
22
- cy.wait('@userschema')
23
- cy.get('input[name="root[email]"]').should('have.value', 'test@example.com')
24
- // cy.get('a[href="#/users/list"]').click()
25
- // cy.get('form').submit()
26
- })
27
-
28
- const id = randomId()
29
- const email = `${id}@example.com`
30
- const password = 'expressa2'
31
- it('Can create a user', function () {
32
- cy.server()
33
- cy.route('/api/users/schema').as('userschema')
34
- cy.route('/api/collection/users').as('users')
35
- cy.login()
36
- cy.visit('/')
37
-
38
- cy.get('.hamburger-container').click();
39
- cy.wait(100)
40
- cy.get('span').contains('People').click();
41
- cy.wait(100)
42
- cy.get('span').contains('Add').click();
43
- cy.get('input[name="root[email]"]').type(email)
44
- cy.get('input[name="root[password]"]').type(password)
45
- cy.get('input[name="root[password]"]').blur()
46
- cy.get('.btn-primary').click()
47
- cy.wait('@users')
48
- cy.get('div').should('contain', 'test@example.com')
49
- })
50
-
51
- it('Can log in as non-admin, but cannot create users', function () {
52
- cy.login(email, password)
53
- cy.visit('/')
54
-
55
- cy.get('.hamburger-container').click();
56
- cy.get('span').contains('People').click();
57
- cy.wait(100)
58
- cy.get('span').contains('Add').click();
59
- cy.get('div.error-message').should('contain', 'Request failed')
60
- })
61
- })
1
+ import { randomId } from '../support/util'
2
+
3
+ describe('User Management', function() {
4
+ it('Lists users', function() {
5
+ cy.server()
6
+ cy.route('/api/users/schema').as('userschema')
7
+ cy.route('/api/collection/users').as('users')
8
+ cy.login()
9
+ cy.visit('/')
10
+
11
+ // cy.visit('#/users/list')
12
+ cy.get('.hamburger-container').click();
13
+ cy.wait(100)
14
+ cy.get('span').contains('People').click();
15
+ cy.get('span').contains('Users').click();
16
+ cy.wait('@users')
17
+ // cy.get('a').contains('a@example.com').click();
18
+
19
+
20
+ cy.get('table tr:last-child td:first-child').click();
21
+ // cy.visit()
22
+ cy.wait('@userschema')
23
+ cy.get('input[name="root[email]"]').should('have.value', 'test@example.com')
24
+ // cy.get('a[href="#/users/list"]').click()
25
+ // cy.get('form').submit()
26
+ })
27
+
28
+ const id = randomId()
29
+ const email = `${id}@example.com`
30
+ const password = 'expressa2'
31
+ it('Can create a user', function () {
32
+ cy.server()
33
+ cy.route('/api/users/schema').as('userschema')
34
+ cy.route('/api/collection/users').as('users')
35
+ cy.login()
36
+ cy.visit('/')
37
+
38
+ cy.get('.hamburger-container').click();
39
+ cy.wait(100)
40
+ cy.get('span').contains('People').click();
41
+ cy.wait(100)
42
+ cy.get('span').contains('Add').click();
43
+ cy.get('input[name="root[email]"]').type(email)
44
+ cy.get('input[name="root[password]"]').type(password)
45
+ cy.get('input[name="root[password]"]').blur()
46
+ cy.get('.btn-primary').click()
47
+ cy.wait('@users')
48
+ cy.get('div').should('contain', 'test@example.com')
49
+ })
50
+
51
+ it('Can log in as non-admin, but cannot create users', function () {
52
+ cy.login(email, password)
53
+ cy.visit('/')
54
+
55
+ cy.get('.hamburger-container').click();
56
+ cy.get('span').contains('People').click();
57
+ cy.wait(100)
58
+ cy.get('span').contains('Add').click();
59
+ cy.get('div.error-message').should('contain', 'Request failed')
60
+ })
61
+ })
@@ -1,17 +1,17 @@
1
- // ***********************************************************
2
- // This example plugins/index.js can be used to load plugins
3
- //
4
- // You can change the location of this file or turn off loading
5
- // the plugins file with the 'pluginsFile' configuration option.
6
- //
7
- // You can read more here:
8
- // https://on.cypress.io/plugins-guide
9
- // ***********************************************************
10
-
11
- // This function is called when a project is opened or re-opened (e.g. due to
12
- // the project's config changing)
13
-
14
- module.exports = (on, config) => {
15
- // `on` is used to hook into various events Cypress emits
16
- // `config` is the resolved Cypress config
17
- }
1
+ // ***********************************************************
2
+ // This example plugins/index.js can be used to load plugins
3
+ //
4
+ // You can change the location of this file or turn off loading
5
+ // the plugins file with the 'pluginsFile' configuration option.
6
+ //
7
+ // You can read more here:
8
+ // https://on.cypress.io/plugins-guide
9
+ // ***********************************************************
10
+
11
+ // This function is called when a project is opened or re-opened (e.g. due to
12
+ // the project's config changing)
13
+
14
+ module.exports = (on, config) => {
15
+ // `on` is used to hook into various events Cypress emits
16
+ // `config` is the resolved Cypress config
17
+ }
@@ -1,54 +1,54 @@
1
- // ***********************************************
2
- // This example commands.js shows you how to
3
- // create various custom commands and overwrite
4
- // existing commands.
5
- //
6
- // For more comprehensive examples of custom
7
- // commands please read more here:
8
- // https://on.cypress.io/custom-commands
9
- // ***********************************************
10
- //
11
- //
12
- // -- This is a parent command --
13
- // Cypress.Commands.add("login", (email, password) => { ... })
14
- //
15
- //
16
- // -- This is a child command --
17
- // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
18
- //
19
- //
20
- // -- This is a dual command --
21
- // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
22
- //
23
- //
24
- // -- This will overwrite an existing command --
25
- // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
26
-
27
- Cypress.Commands.add('randomId', (length) => {
28
- var text = "";
29
- var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
30
-
31
- for (var i = 0; i < length || 10; i++)
32
- text += possible.charAt(Math.floor(Math.random() * possible.length));
33
-
34
- return text;
35
- })
36
-
37
- Cypress.Commands.add('fillValue', (path, value) => {
38
- cy.get(`input[name="root[${path}]"]`).type(value)
39
- })
40
-
41
- Cypress.Commands.add('login', (email, password) => {
42
- cy.request({
43
- method: 'POST',
44
- url: 'http://localhost:3001/api/users/login',
45
- body: {
46
- email: email || 'test@example.com',
47
- password: password || 'expressa',
48
- }
49
- })
50
- .then((resp) => {
51
- cy.setCookie('Admin-Token', resp.body.token);
52
- })
53
-
54
- })
1
+ // ***********************************************
2
+ // This example commands.js shows you how to
3
+ // create various custom commands and overwrite
4
+ // existing commands.
5
+ //
6
+ // For more comprehensive examples of custom
7
+ // commands please read more here:
8
+ // https://on.cypress.io/custom-commands
9
+ // ***********************************************
10
+ //
11
+ //
12
+ // -- This is a parent command --
13
+ // Cypress.Commands.add("login", (email, password) => { ... })
14
+ //
15
+ //
16
+ // -- This is a child command --
17
+ // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
18
+ //
19
+ //
20
+ // -- This is a dual command --
21
+ // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
22
+ //
23
+ //
24
+ // -- This will overwrite an existing command --
25
+ // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
26
+
27
+ Cypress.Commands.add('randomId', (length) => {
28
+ var text = "";
29
+ var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
30
+
31
+ for (var i = 0; i < length || 10; i++)
32
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
33
+
34
+ return text;
35
+ })
36
+
37
+ Cypress.Commands.add('fillValue', (path, value) => {
38
+ cy.get(`input[name="root[${path}]"]`).type(value)
39
+ })
40
+
41
+ Cypress.Commands.add('login', (email, password) => {
42
+ cy.request({
43
+ method: 'POST',
44
+ url: 'http://localhost:3001/api/users/login',
45
+ body: {
46
+ email: email || 'test@example.com',
47
+ password: password || 'expressa',
48
+ }
49
+ })
50
+ .then((resp) => {
51
+ cy.setCookie('Admin-Token', resp.body.token);
52
+ })
53
+
54
+ })
@@ -1,20 +1,20 @@
1
- // ***********************************************************
2
- // This example support/index.js is processed and
3
- // loaded automatically before your test files.
4
- //
5
- // This is a great place to put global configuration and
6
- // behavior that modifies Cypress.
7
- //
8
- // You can change the location of this file or turn off
9
- // automatically serving support files with the
10
- // 'supportFile' configuration option.
11
- //
12
- // You can read more here:
13
- // https://on.cypress.io/configuration
14
- // ***********************************************************
15
-
16
- // Import commands.js using ES2015 syntax:
17
- import './commands'
18
-
19
- // Alternatively you can use CommonJS syntax:
20
- // require('./commands')
1
+ // ***********************************************************
2
+ // This example support/index.js is processed and
3
+ // loaded automatically before your test files.
4
+ //
5
+ // This is a great place to put global configuration and
6
+ // behavior that modifies Cypress.
7
+ //
8
+ // You can change the location of this file or turn off
9
+ // automatically serving support files with the
10
+ // 'supportFile' configuration option.
11
+ //
12
+ // You can read more here:
13
+ // https://on.cypress.io/configuration
14
+ // ***********************************************************
15
+
16
+ // Import commands.js using ES2015 syntax:
17
+ import './commands'
18
+
19
+ // Alternatively you can use CommonJS syntax:
20
+ // require('./commands')
@@ -1,10 +1,10 @@
1
- exports.randomId = function(length) {
2
- var text = "";
3
- var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
4
-
5
- for (var i = 0; i < (length || 10); i++) {
6
- text += possible.charAt(Math.floor(Math.random() * possible.length))
7
- }
8
-
9
- return text;
10
- }
1
+ exports.randomId = function(length) {
2
+ var text = "";
3
+ var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
4
+
5
+ for (var i = 0; i < (length || 10); i++) {
6
+ text += possible.charAt(Math.floor(Math.random() * possible.length))
7
+ }
8
+
9
+ return text;
10
+ }
package/cypress.json CHANGED
@@ -1,4 +1,4 @@
1
- {
2
- "video": false,
3
- "baseUrl": "http://localhost:3001/admin"
4
- }
1
+ {
2
+ "video": false,
3
+ "baseUrl": "http://localhost:3001/admin"
4
+ }
package/db/cached.js CHANGED
@@ -1,40 +1,40 @@
1
- module.exports = function (storage) {
2
- const cache = require('./memory')()
3
-
4
- return {
5
- cache: cache,
6
- init: async function () {
7
- await Promise.resolve(storage.init())
8
- const data = await storage.all()
9
- await Promise.all(data.map((doc) => cache.create(doc)))
10
- },
11
- all: function () {
12
- return cache.all()
13
- },
14
- find: function (query, offset, limit, orderby, fields) {
15
- return cache.find(query, offset, limit, orderby, fields)
16
- },
17
- count: async function(...params) {
18
- return await cache.count(...params)
19
- },
20
- get: function (id, fields) {
21
- return cache.get(id, fields)
22
- },
23
- create: async function (data) {
24
- await cache.create(data)
25
- return storage.create(data)
26
- },
27
- update: async function (id, data) {
28
- await cache.update(id, data)
29
- return storage.update(id, data)
30
- },
31
- updateWithQuery: async function (query, update, options) {
32
- await cache.updateWithQuery(query, update, options)
33
- return storage.updateWithQuery(query, update, options)
34
- },
35
- delete: async function (id) {
36
- await cache.delete(id)
37
- return storage.delete(id)
38
- }
39
- }
40
- }
1
+ module.exports = function (storage) {
2
+ const cache = require('./memory')()
3
+
4
+ return {
5
+ cache: cache,
6
+ init: async function () {
7
+ await Promise.resolve(storage.init())
8
+ const data = await storage.all()
9
+ await Promise.all(data.map((doc) => cache.create(doc)))
10
+ },
11
+ all: function () {
12
+ return cache.all()
13
+ },
14
+ find: function (query, offset, limit, orderby, fields) {
15
+ return cache.find(query, offset, limit, orderby, fields)
16
+ },
17
+ count: async function(...params) {
18
+ return await cache.count(...params)
19
+ },
20
+ get: function (id, fields) {
21
+ return cache.get(id, fields)
22
+ },
23
+ create: async function (data) {
24
+ await cache.create(data)
25
+ return storage.create(data)
26
+ },
27
+ update: async function (id, data) {
28
+ await cache.update(id, data)
29
+ return storage.update(id, data)
30
+ },
31
+ updateWithQuery: async function (query, update, options) {
32
+ await cache.updateWithQuery(query, update, options)
33
+ return storage.updateWithQuery(query, update, options)
34
+ },
35
+ delete: async function (id) {
36
+ await cache.delete(id)
37
+ return storage.delete(id)
38
+ }
39
+ }
40
+ }
package/db/file.js CHANGED
@@ -1,112 +1,112 @@
1
- const Store = require('jfs')
2
- const debug = require('debug')('expressa')
3
- const { promisify } = require('util')
4
- Store.prototype.allAsync = promisify(Store.prototype.all)
5
- Store.prototype.getAsync = promisify(Store.prototype.get)
6
- Store.prototype.saveAsync = promisify(Store.prototype.save)
7
-
8
- const util = require('../util')
9
-
10
- module.exports = function (settings, collection) {
11
- const store = new Store((settings.file_storage_path || 'data') + '/' + collection, {
12
- pretty: true,
13
- saveId: '_id'
14
- })
15
-
16
- return {
17
- init: function () {},
18
- all: async function () {
19
- return this.find({})
20
- },
21
- find: async function (query, offset, limit, orderby, fields) {
22
- const data = await store.allAsync()
23
- const arr = Object.keys(data).map(function (id) {
24
- return data[id]
25
- })
26
- let matches = util.mongoSearch(arr, query)
27
- if (orderby) {
28
- matches = util.orderBy(matches, orderby)
29
- }
30
- if (typeof offset !== 'undefined' && typeof limit !== 'undefined') {
31
- matches = matches.slice(offset, offset + limit)
32
- } else if (typeof offset !== 'undefined') {
33
- matches = matches.slice(offset)
34
- } else if (typeof limit !== 'undefined') {
35
- matches = matches.slice(0, limit)
36
- }
37
- if (matches) { // prevent store from being modified
38
- matches = matches.map(function (m) {
39
- return util.clone(m)
40
- })
41
- } // prevent store from being modified
42
- if (fields) {
43
- matches = matches.map((doc) => util.mongoProject(doc, fields))
44
- }
45
- return matches
46
- },
47
- count: async function(...params) {
48
- return (await this.find(...params)).length
49
- },
50
- get: async function (id, fields) {
51
- try {
52
- let data = await store.getAsync(id)
53
- if (data) {
54
- data = util.clone(data) // prevent store from getting modified
55
- }
56
- if (fields) {
57
- data = util.mongoProject(data, fields)
58
- }
59
- return data
60
- } catch (err) {
61
- debug(collection + ' ' + id)
62
- throw new util.ApiError(404, 'document not found')
63
- }
64
- },
65
- exists: async function (id) {
66
- try {
67
- await store.getAsync(id)
68
- return true
69
- } catch (err) {
70
- return false
71
- }
72
- },
73
- create: async function (data) {
74
- data = util.sortObjectKeys(data)
75
- util.addIdIfMissing(data)
76
- const id = data._id
77
- const existing = await this.exists(id)
78
- if (existing) {
79
- throw new util.ApiError(409, 'document already exists')
80
- }
81
- await store.saveAsync(id, data)
82
- return id
83
- },
84
- update: async function (id, data) {
85
- data._id = data._id || id
86
- data = util.sortObjectKeys(data)
87
- await store.saveAsync(data._id, data)
88
- if (data._id !== id) {
89
- await store.delete(id)
90
- }
91
- return data
92
- },
93
- // eslint-disable-next-line no-unused-vars
94
- updateWithQuery: async function (query, update, options) {
95
- const data = await store.allAsync()
96
- const arr = Object.keys(data).map((id) => ({ _id: id, ...data[id]}) )
97
- const matches = util.mongoSearch(arr, query)
98
- const promises = matches.map((doc) => {
99
- util.mongoUpdate(doc, update)
100
- return store.saveAsync(doc._id, doc)
101
- })
102
- await Promise.all(promises)
103
- return {
104
- matchedCount: promises.length
105
- }
106
- },
107
- delete: async function (id) {
108
- await this.get(id) // to check if exists
109
- await store.delete(id)
110
- }
111
- }
112
- }
1
+ const Store = require('jfs')
2
+ const debug = require('debug')('expressa')
3
+ const { promisify } = require('util')
4
+ Store.prototype.allAsync = promisify(Store.prototype.all)
5
+ Store.prototype.getAsync = promisify(Store.prototype.get)
6
+ Store.prototype.saveAsync = promisify(Store.prototype.save)
7
+
8
+ const util = require('../util')
9
+
10
+ module.exports = function (settings, collection) {
11
+ const store = new Store((settings.file_storage_path || 'data') + '/' + collection, {
12
+ pretty: true,
13
+ saveId: '_id'
14
+ })
15
+
16
+ return {
17
+ init: function () {},
18
+ all: async function () {
19
+ return this.find({})
20
+ },
21
+ find: async function (query, offset, limit, orderby, fields) {
22
+ const data = await store.allAsync()
23
+ const arr = Object.keys(data).map(function (id) {
24
+ return data[id]
25
+ })
26
+ let matches = util.mongoSearch(arr, query)
27
+ if (orderby) {
28
+ matches = util.orderBy(matches, orderby)
29
+ }
30
+ if (typeof offset !== 'undefined' && typeof limit !== 'undefined') {
31
+ matches = matches.slice(offset, offset + limit)
32
+ } else if (typeof offset !== 'undefined') {
33
+ matches = matches.slice(offset)
34
+ } else if (typeof limit !== 'undefined') {
35
+ matches = matches.slice(0, limit)
36
+ }
37
+ if (matches) { // prevent store from being modified
38
+ matches = matches.map(function (m) {
39
+ return util.clone(m)
40
+ })
41
+ } // prevent store from being modified
42
+ if (fields) {
43
+ matches = matches.map((doc) => util.mongoProject(doc, fields))
44
+ }
45
+ return matches
46
+ },
47
+ count: async function(...params) {
48
+ return (await this.find(...params)).length
49
+ },
50
+ get: async function (id, fields) {
51
+ try {
52
+ let data = await store.getAsync(id)
53
+ if (data) {
54
+ data = util.clone(data) // prevent store from getting modified
55
+ }
56
+ if (fields) {
57
+ data = util.mongoProject(data, fields)
58
+ }
59
+ return data
60
+ } catch (err) {
61
+ debug(collection + ' ' + id)
62
+ throw new util.ApiError(404, 'document not found')
63
+ }
64
+ },
65
+ exists: async function (id) {
66
+ try {
67
+ await store.getAsync(id)
68
+ return true
69
+ } catch (err) {
70
+ return false
71
+ }
72
+ },
73
+ create: async function (data) {
74
+ data = util.sortObjectKeys(data)
75
+ util.addIdIfMissing(data)
76
+ const id = data._id
77
+ const existing = await this.exists(id)
78
+ if (existing) {
79
+ throw new util.ApiError(409, 'document already exists')
80
+ }
81
+ await store.saveAsync(id, data)
82
+ return id
83
+ },
84
+ update: async function (id, data) {
85
+ data._id = data._id || id
86
+ data = util.sortObjectKeys(data)
87
+ await store.saveAsync(data._id, data)
88
+ if (data._id !== id) {
89
+ await store.delete(id)
90
+ }
91
+ return data
92
+ },
93
+ // eslint-disable-next-line no-unused-vars
94
+ updateWithQuery: async function (query, update, options) {
95
+ const data = await store.allAsync()
96
+ const arr = Object.keys(data).map((id) => ({ _id: id, ...data[id]}) )
97
+ const matches = util.mongoSearch(arr, query)
98
+ const promises = matches.map((doc) => {
99
+ util.mongoUpdate(doc, update)
100
+ return store.saveAsync(doc._id, doc)
101
+ })
102
+ await Promise.all(promises)
103
+ return {
104
+ matchedCount: promises.length
105
+ }
106
+ },
107
+ delete: async function (id) {
108
+ await this.get(id) // to check if exists
109
+ await store.delete(id)
110
+ }
111
+ }
112
+ }