mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
Merge branch 'master' of github.com:Human-Connection/Human-Connection into 17-Admin-Remove-user-profile
This commit is contained in:
commit
dcc5b74038
241
CHANGELOG.md
241
CHANGELOG.md
@ -4,10 +4,141 @@ All notable changes to this project will be documented in this file. Dates are d
|
||||
|
||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
#### [v0.6.1](https://github.com/Human-Connection/Human-Connection/compare/v0.6.0...v0.6.1)
|
||||
|
||||
> 4 May 2020
|
||||
|
||||
- feat: FollowerList [1741] [`#3293`](https://github.com/Human-Connection/Human-Connection/pull/3293)
|
||||
- fix: Text of editor embeds disappearing on click [2727] [`#3356`](https://github.com/Human-Connection/Human-Connection/pull/3356)
|
||||
- build(deps-dev): bump css-loader from 3.5.1 to 3.5.2 in /webapp [`#3475`](https://github.com/Human-Connection/Human-Connection/pull/3475)
|
||||
- build(deps): bump apollo-link-context from 1.0.19 to 1.0.20 in /backend [`#3472`](https://github.com/Human-Connection/Human-Connection/pull/3472)
|
||||
- build(deps): bump date-fns from 2.11.1 to 2.12.0 in /webapp [`#3467`](https://github.com/Human-Connection/Human-Connection/pull/3467)
|
||||
- build(deps-dev): bump jest from 25.2.7 to 25.3.0 in /webapp [`#3459`](https://github.com/Human-Connection/Human-Connection/pull/3459)
|
||||
- build(deps-dev): bump date-fns from 2.11.1 to 2.12.0 [`#3464`](https://github.com/Human-Connection/Human-Connection/pull/3464)
|
||||
- build(deps): bump apollo-link-http from 1.5.16 to 1.5.17 in /backend [`#3465`](https://github.com/Human-Connection/Human-Connection/pull/3465)
|
||||
- build(deps-dev): bump babel-jest from 25.2.6 to 25.3.0 in /webapp [`#3456`](https://github.com/Human-Connection/Human-Connection/pull/3456)
|
||||
- build(deps-dev): bump prettier from 2.0.2 to 2.0.4 in /backend [`#3454`](https://github.com/Human-Connection/Human-Connection/pull/3454)
|
||||
- build(deps-dev): bump jest from 25.2.7 to 25.3.0 in /backend [`#3453`](https://github.com/Human-Connection/Human-Connection/pull/3453)
|
||||
- build(deps-dev): bump expect from 25.2.7 to 25.3.0 [`#3452`](https://github.com/Human-Connection/Human-Connection/pull/3452)
|
||||
- build(deps-dev): bump @vue/cli-shared-utils from 4.3.0 to 4.3.1 in /webapp [`#3446`](https://github.com/Human-Connection/Human-Connection/pull/3446)
|
||||
- build(deps-dev): bump css-loader from 3.5.0 to 3.5.1 in /webapp [`#3448`](https://github.com/Human-Connection/Human-Connection/pull/3448)
|
||||
- build(deps): bump apollo-server-express from 2.11.0 to 2.12.0 in /backend [`#3443`](https://github.com/Human-Connection/Human-Connection/pull/3443)
|
||||
- build(deps-dev): bump @babel/preset-env from 7.9.0 to 7.9.5 in /backend [`#3441`](https://github.com/Human-Connection/Human-Connection/pull/3441)
|
||||
- build(deps): bump metascraper-image from 5.11.6 to 5.11.8 in /backend [`#3439`](https://github.com/Human-Connection/Human-Connection/pull/3439)
|
||||
- build(deps-dev): bump cypress-cucumber-preprocessor from 2.1.0 to 2.2.1 [`#3438`](https://github.com/Human-Connection/Human-Connection/pull/3438)
|
||||
- build(deps): bump metascraper-youtube from 5.11.6 to 5.11.8 in /backend [`#3435`](https://github.com/Human-Connection/Human-Connection/pull/3435)
|
||||
- build(deps): bump metascraper-soundcloud from 5.11.7 to 5.11.8 in /backend [`#3432`](https://github.com/Human-Connection/Human-Connection/pull/3432)
|
||||
- refactor: favor CSS over syleguide components SearchPost.vue [`#3377`](https://github.com/Human-Connection/Human-Connection/pull/3377)
|
||||
- chore: removed unused fuse.js [`#3411`](https://github.com/Human-Connection/Human-Connection/pull/3411)
|
||||
- build(deps-dev): bump jest from 25.2.6 to 25.2.7 in /backend [`#3434`](https://github.com/Human-Connection/Human-Connection/pull/3434)
|
||||
- build(deps): bump merge-graphql-schemas from 1.7.6 to 1.7.7 in /backend [`#3397`](https://github.com/Human-Connection/Human-Connection/pull/3397)
|
||||
- chore: Update docs for spaces backups [`#3428`](https://github.com/Human-Connection/Human-Connection/pull/3428)
|
||||
- build(deps): bump metascraper-date from 5.11.6 to 5.11.8 in /backend [`#3431`](https://github.com/Human-Connection/Human-Connection/pull/3431)
|
||||
- build(deps): bump metascraper-publisher from 5.11.6 to 5.11.8 in /backend [`#3430`](https://github.com/Human-Connection/Human-Connection/pull/3430)
|
||||
- build(deps-dev): bump css-loader from 3.4.2 to 3.5.0 in /webapp [`#3436`](https://github.com/Human-Connection/Human-Connection/pull/3436)
|
||||
- build(deps): bump metascraper-lang from 5.11.6 to 5.11.8 in /backend [`#3433`](https://github.com/Human-Connection/Human-Connection/pull/3433)
|
||||
- build(deps-dev): bump prettier from 2.0.2 to 2.0.4 in /webapp [`#3429`](https://github.com/Human-Connection/Human-Connection/pull/3429)
|
||||
- build(deps): bump metascraper-url from 5.11.6 to 5.11.8 in /backend [`#3420`](https://github.com/Human-Connection/Human-Connection/pull/3420)
|
||||
- build(deps): bump metascraper from 5.11.6 to 5.11.8 in /backend [`#3419`](https://github.com/Human-Connection/Human-Connection/pull/3419)
|
||||
- build(deps-dev): bump storybook-design-token from 0.7.0 to 0.7.2 in /webapp [`#3422`](https://github.com/Human-Connection/Human-Connection/pull/3422)
|
||||
- build(deps-dev): bump eslint-loader from 3.0.3 to 4.0.0 in /webapp [`#3424`](https://github.com/Human-Connection/Human-Connection/pull/3424)
|
||||
- build(deps-dev): bump @vue/cli-shared-utils from 4.2.3 to 4.3.0 in /webapp [`#3423`](https://github.com/Human-Connection/Human-Connection/pull/3423)
|
||||
- build(deps): bump metascraper-author from 5.11.6 to 5.11.8 in /backend [`#3417`](https://github.com/Human-Connection/Human-Connection/pull/3417)
|
||||
- build(deps): bump metascraper-title from 5.11.6 to 5.11.8 in /backend [`#3415`](https://github.com/Human-Connection/Human-Connection/pull/3415)
|
||||
- build(deps): bump metascraper-audio from 5.11.6 to 5.11.8 in /backend [`#3418`](https://github.com/Human-Connection/Human-Connection/pull/3418)
|
||||
- build(deps): bump metascraper-video from 5.11.6 to 5.11.8 in /backend [`#3416`](https://github.com/Human-Connection/Human-Connection/pull/3416)
|
||||
- build(deps-dev): bump jest from 25.2.4 to 25.2.7 in /webapp [`#3410`](https://github.com/Human-Connection/Human-Connection/pull/3410)
|
||||
- build(deps-dev): bump expect from 25.2.4 to 25.2.7 [`#3409`](https://github.com/Human-Connection/Human-Connection/pull/3409)
|
||||
- build(deps-dev): bump storybook-design-token from 0.5.1 to 0.7.0 in /webapp [`#3407`](https://github.com/Human-Connection/Human-Connection/pull/3407)
|
||||
- build(deps-dev): bump babel-jest from 25.2.3 to 25.2.6 in /webapp [`#3403`](https://github.com/Human-Connection/Human-Connection/pull/3403)
|
||||
- build(deps-dev): bump jest from 25.2.4 to 25.2.6 in /backend [`#3401`](https://github.com/Human-Connection/Human-Connection/pull/3401)
|
||||
- build(deps): bump tiptap-extensions from 1.28.7 to 1.28.8 in /webapp [`#3404`](https://github.com/Human-Connection/Human-Connection/pull/3404)
|
||||
- build(deps): bump aws-sdk from 2.651.0 to 2.652.0 in /backend [`#3402`](https://github.com/Human-Connection/Human-Connection/pull/3402)
|
||||
- build(deps-dev): bump auto-changelog from 1.16.3 to 1.16.4 [`#3400`](https://github.com/Human-Connection/Human-Connection/pull/3400)
|
||||
- build(deps-dev): bump babel-jest from 25.2.4 to 25.2.6 in /backend [`#3399`](https://github.com/Human-Connection/Human-Connection/pull/3399)
|
||||
- build(deps): bump tiptap-extensions from 1.28.6 to 1.28.7 in /webapp [`#3393`](https://github.com/Human-Connection/Human-Connection/pull/3393)
|
||||
- build(deps): bump aws-sdk from 2.650.0 to 2.651.0 in /backend [`#3391`](https://github.com/Human-Connection/Human-Connection/pull/3391)
|
||||
- build(deps-dev): bump @storybook/vue from 5.3.17 to 5.3.18 in /webapp [`#3387`](https://github.com/Human-Connection/Human-Connection/pull/3387)
|
||||
- build(deps-dev): bump @storybook/addon-actions from 5.3.17 to 5.3.18 in /webapp [`#3386`](https://github.com/Human-Connection/Human-Connection/pull/3386)
|
||||
- refactor(tests): return errors [`#3390`](https://github.com/Human-Connection/Human-Connection/pull/3390)
|
||||
- build(deps): bump ioredis from 4.16.0 to 4.16.1 in /backend [`#3365`](https://github.com/Human-Connection/Human-Connection/pull/3365)
|
||||
- build(deps-dev): bump @storybook/addon-a11y from 5.3.17 to 5.3.18 in /webapp [`#3384`](https://github.com/Human-Connection/Human-Connection/pull/3384)
|
||||
- build(deps-dev): bump @storybook/addon-notes from 5.3.17 to 5.3.18 in /webapp [`#3385`](https://github.com/Human-Connection/Human-Connection/pull/3385)
|
||||
- build(deps): bump uuid from 7.0.2 to 7.0.3 in /backend [`#3383`](https://github.com/Human-Connection/Human-Connection/pull/3383)
|
||||
- build(deps): bump graphql-shield from 7.2.1 to 7.2.2 in /backend [`#3382`](https://github.com/Human-Connection/Human-Connection/pull/3382)
|
||||
- build(deps): bump aws-sdk from 2.649.0 to 2.650.0 in /backend [`#3381`](https://github.com/Human-Connection/Human-Connection/pull/3381)
|
||||
- build(deps-dev): bump eslint-plugin-import from 2.20.1 to 2.20.2 in /webapp [`#3370`](https://github.com/Human-Connection/Human-Connection/pull/3370)
|
||||
- build(deps): bump @nuxtjs/axios from 5.9.6 to 5.9.7 in /webapp [`#3380`](https://github.com/Human-Connection/Human-Connection/pull/3380)
|
||||
- build(deps): bump aws-sdk from 2.648.0 to 2.649.0 in /backend [`#3379`](https://github.com/Human-Connection/Human-Connection/pull/3379)
|
||||
- build(deps-dev): bump jest from 25.2.3 to 25.2.4 in /backend [`#3366`](https://github.com/Human-Connection/Human-Connection/pull/3366)
|
||||
- build(deps-dev): bump eslint-plugin-node from 11.0.0 to 11.1.0 in /backend [`#3362`](https://github.com/Human-Connection/Human-Connection/pull/3362)
|
||||
- build(deps-dev): bump eslint-plugin-import from 2.20.1 to 2.20.2 in /backend [`#3367`](https://github.com/Human-Connection/Human-Connection/pull/3367)
|
||||
- build(deps-dev): bump jest from 25.2.3 to 25.2.4 in /webapp [`#3373`](https://github.com/Human-Connection/Human-Connection/pull/3373)
|
||||
- fix(migration): Set maxSockets to avoid rate limit [`#3375`](https://github.com/Human-Connection/Human-Connection/pull/3375)
|
||||
- build(deps-dev): bump eslint-plugin-node from 11.0.0 to 11.1.0 in /webapp [`#3374`](https://github.com/Human-Connection/Human-Connection/pull/3374)
|
||||
- build(deps): bump @nuxtjs/axios from 5.9.5 to 5.9.6 in /webapp [`#3371`](https://github.com/Human-Connection/Human-Connection/pull/3371)
|
||||
- build(deps): bump aws-sdk from 2.647.0 to 2.648.0 in /backend [`#3368`](https://github.com/Human-Connection/Human-Connection/pull/3368)
|
||||
- build(deps): bump @sentry/node from 5.15.2 to 5.15.4 in /backend [`#3364`](https://github.com/Human-Connection/Human-Connection/pull/3364)
|
||||
- build(deps-dev): bump babel-jest from 25.2.3 to 25.2.4 in /backend [`#3363`](https://github.com/Human-Connection/Human-Connection/pull/3363)
|
||||
- build(deps-dev): bump expect from 25.2.3 to 25.2.4 [`#3360`](https://github.com/Human-Connection/Human-Connection/pull/3360)
|
||||
- build(deps-dev): bump auto-changelog from 1.16.2 to 1.16.3 [`#3334`](https://github.com/Human-Connection/Human-Connection/pull/3334)
|
||||
- Fix: filter not preferring full matches in back + [`b05cc30`](https://github.com/Human-Connection/Human-Connection/commit/b05cc303b4925c26a3e7a86606764888abf5790b)
|
||||
- Refactor: move following/followedBy updating to page component [`e6361c9`](https://github.com/Human-Connection/Human-Connection/commit/e6361c9b740f104c0a0d86b463be835f10311f3d)
|
||||
- build(deps-dev): bump @storybook/addon-notes in /webapp [`93f43e2`](https://github.com/Human-Connection/Human-Connection/commit/93f43e26653ee9faeed1a8c096f9b8a5a04422a9)
|
||||
|
||||
#### [v0.6.0](https://github.com/Human-Connection/Human-Connection/compare/v0.5.0...v0.6.0)
|
||||
|
||||
> 27 March 2020
|
||||
|
||||
- chore: upgrade to v0.6.0 [`#3359`](https://github.com/Human-Connection/Human-Connection/pull/3359)
|
||||
- build(deps): bump helmet from 3.21.3 to 3.22.0 in /backend [`#3337`](https://github.com/Human-Connection/Human-Connection/pull/3337)
|
||||
- build(deps-dev): bump jest from 25.2.1 to 25.2.3 in /webapp [`#3354`](https://github.com/Human-Connection/Human-Connection/pull/3354)
|
||||
- build(deps-dev): bump cypress-cucumber-preprocessor from 2.0.1 to 2.1.0 [`#3349`](https://github.com/Human-Connection/Human-Connection/pull/3349)
|
||||
- build(deps): bump aws-sdk from 2.638.0 to 2.647.0 in /backend [`#3352`](https://github.com/Human-Connection/Human-Connection/pull/3352)
|
||||
- refactor: FilterMenu as a first step to remove ds-flex [`#3257`](https://github.com/Human-Connection/Human-Connection/pull/3257)
|
||||
- build(deps): bump date-fns from 2.11.0 to 2.11.1 in /webapp [`#3355`](https://github.com/Human-Connection/Human-Connection/pull/3355)
|
||||
- Remove dangling image urls [`#3343`](https://github.com/Human-Connection/Human-Connection/pull/3343)
|
||||
- build(deps-dev): bump expect from 25.2.0 to 25.2.3 [`#3347`](https://github.com/Human-Connection/Human-Connection/pull/3347)
|
||||
- build(deps-dev): bump babel-jest from 25.2.1 to 25.2.3 in /backend [`#3350`](https://github.com/Human-Connection/Human-Connection/pull/3350)
|
||||
- build(deps-dev): bump babel-jest from 25.2.0 to 25.2.3 in /webapp [`#3353`](https://github.com/Human-Connection/Human-Connection/pull/3353)
|
||||
- build(deps): bump date-fns from 2.11.0 to 2.11.1 in /backend [`#3351`](https://github.com/Human-Connection/Human-Connection/pull/3351)
|
||||
- build(deps): bump @sentry/node from 5.15.0 to 5.15.2 in /backend [`#3348`](https://github.com/Human-Connection/Human-Connection/pull/3348)
|
||||
- build(deps-dev): bump jest from 25.2.0 to 25.2.3 in /backend [`#3346`](https://github.com/Human-Connection/Human-Connection/pull/3346)
|
||||
- build(deps-dev): bump date-fns from 2.11.0 to 2.11.1 [`#3345`](https://github.com/Human-Connection/Human-Connection/pull/3345)
|
||||
- build(deps-dev): bump @babel/preset-env from 7.8.7 to 7.9.0 [`#3309`](https://github.com/Human-Connection/Human-Connection/pull/3309)
|
||||
- build(deps-dev): bump @babel/preset-env from 7.8.7 to 7.9.0 in /backend [`#3314`](https://github.com/Human-Connection/Human-Connection/pull/3314)
|
||||
- build(deps-dev): bump babel-jest from 25.2.0 to 25.2.1 in /backend [`#3341`](https://github.com/Human-Connection/Human-Connection/pull/3341)
|
||||
- build(deps-dev): bump jest from 25.1.0 to 25.2.1 in /webapp [`#3342`](https://github.com/Human-Connection/Human-Connection/pull/3342)
|
||||
- feat(backend): upload original image files on S3 object storage [`#3262`](https://github.com/Human-Connection/Human-Connection/pull/3262)
|
||||
- chore: fix lint w/ new linting rules [`06985c2`](https://github.com/Human-Connection/Human-Connection/commit/06985c2dbbc6699cc5c3dfd6e55cac8d28e9019b)
|
||||
- chore: upgreade to v0.6.0 [`29f49a8`](https://github.com/Human-Connection/Human-Connection/commit/29f49a85c0b49fa0b3a34cb016a4a1d4734d5ae6)
|
||||
- build(deps-dev): bump auto-changelog from 1.16.2 to 1.16.3 [`5d8ab84`](https://github.com/Human-Connection/Human-Connection/commit/5d8ab84df03d1324832cad1d4a2a6b4953706d86)
|
||||
|
||||
#### [v0.5.0](https://github.com/Human-Connection/Human-Connection/compare/v0.4.2...v0.5.0)
|
||||
|
||||
> 20 March 2020
|
||||
> 26 March 2020
|
||||
|
||||
- build(deps-dev): bump babel-jest from 25.1.0 to 25.2.0 in /backend [`#3336`](https://github.com/Human-Connection/Human-Connection/pull/3336)
|
||||
- build(deps): bump nuxt from 2.12.0 to 2.12.1 in /webapp [`#3338`](https://github.com/Human-Connection/Human-Connection/pull/3338)
|
||||
- build(deps-dev): bump babel-jest from 25.1.0 to 25.2.0 in /webapp [`#3340`](https://github.com/Human-Connection/Human-Connection/pull/3340)
|
||||
- build(deps-dev): bump jest from 25.1.0 to 25.2.0 in /backend [`#3335`](https://github.com/Human-Connection/Human-Connection/pull/3335)
|
||||
- build(deps-dev): bump expect from 25.1.0 to 25.2.0 [`#3333`](https://github.com/Human-Connection/Human-Connection/pull/3333)
|
||||
- build(deps): bump @nuxtjs/sentry from 3.3.1 to 4.0.0 in /webapp [`#3332`](https://github.com/Human-Connection/Human-Connection/pull/3332)
|
||||
- build(deps-dev): bump @babel/core from 7.8.7 to 7.9.0 in /webapp [`#3316`](https://github.com/Human-Connection/Human-Connection/pull/3316)
|
||||
- build(deps-dev): bump @babel/core from 7.8.7 to 7.9.0 in /backend [`#3313`](https://github.com/Human-Connection/Human-Connection/pull/3313)
|
||||
- build(deps-dev): bump @babel/preset-env from 7.8.7 to 7.9.0 in /webapp [`#3319`](https://github.com/Human-Connection/Human-Connection/pull/3319)
|
||||
- build(deps-dev): bump @babel/register from 7.8.6 to 7.9.0 in /backend [`#3305`](https://github.com/Human-Connection/Human-Connection/pull/3305)
|
||||
- build(deps): bump @sentry/node from 5.14.2 to 5.15.0 in /backend [`#3331`](https://github.com/Human-Connection/Human-Connection/pull/3331)
|
||||
- build(deps-dev): bump prettier from 1.19.1 to 2.0.2 in /webapp [`#3327`](https://github.com/Human-Connection/Human-Connection/pull/3327)
|
||||
- build(deps-dev): bump babel-loader from 8.0.6 to 8.1.0 in /webapp [`#3315`](https://github.com/Human-Connection/Human-Connection/pull/3315)
|
||||
- build(deps-dev): bump @babel/register from 7.8.6 to 7.9.0 [`#3310`](https://github.com/Human-Connection/Human-Connection/pull/3310)
|
||||
- build(deps-dev): bump @babel/core from 7.8.7 to 7.9.0 [`#3304`](https://github.com/Human-Connection/Human-Connection/pull/3304)
|
||||
- fix(migration): return null for Image.url [`#3323`](https://github.com/Human-Connection/Human-Connection/pull/3323)
|
||||
- build(deps): bump graphql-shield from 7.2.0 to 7.2.1 in /backend [`#3296`](https://github.com/Human-Connection/Human-Connection/pull/3296)
|
||||
- fix(build): make locations spec more resilient [`#3324`](https://github.com/Human-Connection/Human-Connection/pull/3324)
|
||||
- fix(migration): Avoid unique constraint violation [`#3303`](https://github.com/Human-Connection/Human-Connection/pull/3303)
|
||||
- chore: upgrade to v0.5.0 [`#3302`](https://github.com/Human-Connection/Human-Connection/pull/3302)
|
||||
- build(deps): bump validator from 12.2.0 to 13.0.0 in /webapp [`#3301`](https://github.com/Human-Connection/Human-Connection/pull/3301)
|
||||
- feat: Search for Hashtags [`#3297`](https://github.com/Human-Connection/Human-Connection/pull/3297)
|
||||
- build(deps): bump metascraper-soundcloud from 5.11.6 to 5.11.7 in /backend [`#3300`](https://github.com/Human-Connection/Human-Connection/pull/3300)
|
||||
- build(deps): bump validator from 12.2.0 to 13.0.0 in /backend [`#3299`](https://github.com/Human-Connection/Human-Connection/pull/3299)
|
||||
@ -36,6 +167,14 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- build(deps-dev): bump date-fns from 2.10.0 to 2.11.0 [`#3273`](https://github.com/Human-Connection/Human-Connection/pull/3273)
|
||||
- build(deps): [security] bump acorn from 6.3.0 to 6.4.1 in /backend [`#3270`](https://github.com/Human-Connection/Human-Connection/pull/3270)
|
||||
- build(deps): [security] bump acorn from 6.1.1 to 6.4.1 [`#3269`](https://github.com/Human-Connection/Human-Connection/pull/3269)
|
||||
- Update prettier to v2 [`276ea79`](https://github.com/Human-Connection/Human-Connection/commit/276ea79e8ff2de2d02698b486671aee7cfda860e)
|
||||
- refactor: CategoriesFilter to not use ds-flex [`1ffde6b`](https://github.com/Human-Connection/Human-Connection/commit/1ffde6bf1034d1a1d9b7bca62fe66fe64527314c)
|
||||
- Changes requested by @mattwr18 [`9c08db2`](https://github.com/Human-Connection/Human-Connection/commit/9c08db22dcd0ca1ad6e59be8fb0f287935b45537)
|
||||
|
||||
#### [v0.4.2](https://github.com/Human-Connection/Human-Connection/compare/v0.4.1...v0.4.2)
|
||||
|
||||
> 13 March 2020
|
||||
|
||||
- build(deps): bump graphql-shield from 7.1.0 to 7.2.0 in /backend [`#3265`](https://github.com/Human-Connection/Human-Connection/pull/3265)
|
||||
- build(deps): bump sanitize-html from 1.22.0 to 1.22.1 in /backend [`#3264`](https://github.com/Human-Connection/Human-Connection/pull/3264)
|
||||
- build(deps): bump @sentry/node from 5.14.0 to 5.14.1 in /backend [`#3263`](https://github.com/Human-Connection/Human-Connection/pull/3263)
|
||||
@ -45,14 +184,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- build(deps): bump @nuxtjs/sentry from 3.2.4 to 3.3.1 in /webapp [`#3237`](https://github.com/Human-Connection/Human-Connection/pull/3237)
|
||||
- build(deps-dev): bump eslint-plugin-jest from 23.8.1 to 23.8.2 in /webapp [`#3228`](https://github.com/Human-Connection/Human-Connection/pull/3228)
|
||||
- chore: Update to version 0.4.2 [`#3261`](https://github.com/Human-Connection/Human-Connection/pull/3261)
|
||||
- Changes requested by @mattwr18 [`9c08db2`](https://github.com/Human-Connection/Human-Connection/commit/9c08db22dcd0ca1ad6e59be8fb0f287935b45537)
|
||||
- search specs refactored [`46fca22`](https://github.com/Human-Connection/Human-Connection/commit/46fca229ec35047eda9ac7809e7bc456785a6c70)
|
||||
- Search for Hashtags works due watching route in pages/index.vue [`1c43d5f`](https://github.com/Human-Connection/Human-Connection/commit/1c43d5fe6f44c7b11168af8bd765b8d785a6641a)
|
||||
|
||||
#### [v0.4.2](https://github.com/Human-Connection/Human-Connection/compare/v0.4.1...v0.4.2)
|
||||
|
||||
> 12 March 2020
|
||||
|
||||
- build(deps): bump @sentry/node from 5.13.1 to 5.14.0 in /backend [`#3260`](https://github.com/Human-Connection/Human-Connection/pull/3260)
|
||||
- build(deps): bump graphql-shield from 7.0.14 to 7.1.0 in /backend [`#3259`](https://github.com/Human-Connection/Human-Connection/pull/3259)
|
||||
- feat: more prominent output of ./scripts/translations/sort.sh and hint to --fix feature of the script on errors [`#3251`](https://github.com/Human-Connection/Human-Connection/pull/3251)
|
||||
@ -71,7 +202,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- build(deps): bump metascraper-description from 5.11.1 to 5.11.6 in /backend [`#3233`](https://github.com/Human-Connection/Human-Connection/pull/3233)
|
||||
- build(deps): bump cross-env from 7.0.1 to 7.0.2 in /backend [`#3245`](https://github.com/Human-Connection/Human-Connection/pull/3245)
|
||||
- build(deps): bump metascraper-title from 5.11.1 to 5.11.6 in /backend [`#3244`](https://github.com/Human-Connection/Human-Connection/pull/3244)
|
||||
- chore: Update to v0.4.1 [`#3243`](https://github.com/Human-Connection/Human-Connection/pull/3243)
|
||||
- DRY user.spec.js [`da16590`](https://github.com/Human-Connection/Human-Connection/commit/da165906e2ed12baddd902b43064103ab3adfa06)
|
||||
- test deleteuser as admin, moderator, another user and as I myself, fix lint [`3983612`](https://github.com/Human-Connection/Human-Connection/commit/3983612c56ac92473a192a318959e4c691a3e7b8)
|
||||
- feature: test delete user as admin [`84c1547`](https://github.com/Human-Connection/Human-Connection/commit/84c154798efac0cec4c13dfefae18a6a9542058a)
|
||||
@ -80,6 +210,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
> 9 March 2020
|
||||
|
||||
- chore: Update to v0.4.1 [`#3243`](https://github.com/Human-Connection/Human-Connection/pull/3243)
|
||||
- build(deps): bump metascraper-publisher from 5.11.1 to 5.11.6 in /backend [`#3226`](https://github.com/Human-Connection/Human-Connection/pull/3226)
|
||||
- build(deps-dev): bump eslint-plugin-vue from 6.2.1 to 6.2.2 in /webapp [`#3238`](https://github.com/Human-Connection/Human-Connection/pull/3238)
|
||||
- build(deps): bump metascraper-date from 5.11.1 to 5.11.6 in /backend [`#3236`](https://github.com/Human-Connection/Human-Connection/pull/3236)
|
||||
@ -148,6 +279,14 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- build(deps): bump sanitize-html from 1.21.1 to 1.22.0 in /backend [`#3145`](https://github.com/Human-Connection/Human-Connection/pull/3145)
|
||||
- build(deps): bump nodemailer from 6.4.2 to 6.4.3 in /backend [`#3144`](https://github.com/Human-Connection/Human-Connection/pull/3144)
|
||||
- build(deps): bump metascraper-video from 5.10.7 to 5.11.1 in /backend [`#3143`](https://github.com/Human-Connection/Human-Connection/pull/3143)
|
||||
- build(deps-dev): bump @storybook/addon-notes in /webapp [`5ef2b25`](https://github.com/Human-Connection/Human-Connection/commit/5ef2b25ee6a3402a2ebe2f3f55dd65a6e0a1111e)
|
||||
- build(deps-dev): bump @storybook/addon-a11y in /webapp [`f209436`](https://github.com/Human-Connection/Human-Connection/commit/f209436147fbf9afacfbd6edb6135847e6c4faed)
|
||||
- build(deps): bump apollo-server-express in /backend [`3b35487`](https://github.com/Human-Connection/Human-Connection/commit/3b35487f0671490dee1e636fb938c408722bfd45)
|
||||
|
||||
#### [v0.4.0](https://github.com/Human-Connection/Human-Connection/compare/v0.3.1...v0.4.0)
|
||||
|
||||
> 22 February 2020
|
||||
|
||||
- feat: the point -no political use - added [`#3138`](https://github.com/Human-Connection/Human-Connection/pull/3138)
|
||||
- build(deps): bump metascraper-lang from 5.10.7 to 5.11.1 in /backend [`#3071`](https://github.com/Human-Connection/Human-Connection/pull/3071)
|
||||
- build(deps): bump metascraper from 5.11.0 to 5.11.4 in /backend [`#3136`](https://github.com/Human-Connection/Human-Connection/pull/3136)
|
||||
@ -157,14 +296,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- chore(cypress): Favor firefox in cypress [`#3121`](https://github.com/Human-Connection/Human-Connection/pull/3121)
|
||||
- build(deps): bump graphql-shield from 7.0.11 to 7.0.13 in /backend [`#3127`](https://github.com/Human-Connection/Human-Connection/pull/3127)
|
||||
- build(deps): bump ioredis from 4.14.1 to 4.16.0 in /backend [`#3128`](https://github.com/Human-Connection/Human-Connection/pull/3128)
|
||||
- build(deps-dev): bump @storybook/addon-notes in /webapp [`5ef2b25`](https://github.com/Human-Connection/Human-Connection/commit/5ef2b25ee6a3402a2ebe2f3f55dd65a6e0a1111e)
|
||||
- build(deps-dev): bump @storybook/addon-a11y in /webapp [`f209436`](https://github.com/Human-Connection/Human-Connection/commit/f209436147fbf9afacfbd6edb6135847e6c4faed)
|
||||
- build(deps): bump apollo-server-express in /backend [`3b35487`](https://github.com/Human-Connection/Human-Connection/commit/3b35487f0671490dee1e636fb938c408722bfd45)
|
||||
|
||||
#### [v0.4.0](https://github.com/Human-Connection/Human-Connection/compare/v0.3.1...v0.4.0)
|
||||
|
||||
> 21 February 2020
|
||||
|
||||
- build(deps): bump apollo-server from 2.10.0 to 2.10.1 in /backend [`#3125`](https://github.com/Human-Connection/Human-Connection/pull/3125)
|
||||
- fix: Favor Cypress.Promise over async/await in e2e tests [`#3115`](https://github.com/Human-Connection/Human-Connection/pull/3115)
|
||||
- docs(setup): Fix links in tests [`#3120`](https://github.com/Human-Connection/Human-Connection/pull/3120)
|
||||
@ -270,15 +401,15 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- fix: Remove github release script breaking build [`#2971`](https://github.com/Human-Connection/Human-Connection/pull/2971)
|
||||
- Use original createdAt for merged users/emails [`#2969`](https://github.com/Human-Connection/Human-Connection/pull/2969)
|
||||
- Fix typo [`#2966`](https://github.com/Human-Connection/Human-Connection/pull/2966)
|
||||
- chore: Update to v0.3.0 [`#2941`](https://github.com/Human-Connection/Human-Connection/pull/2941)
|
||||
- Replace buildList with array of Promises [`46edc3f`](https://github.com/Human-Connection/Human-Connection/commit/46edc3fdd5b83c2f00506f595b1254d7597767e0)
|
||||
- refactor TeaserImage component [`e14cbf8`](https://github.com/Human-Connection/Human-Connection/commit/e14cbf8173e3040b5285ba6a5c73e2d2d2a47860)
|
||||
- refactor DeleteData template and CSS [`509892b`](https://github.com/Human-Connection/Human-Connection/commit/509892b6caee6c4ca8384fb0090122ced98edfd4)
|
||||
|
||||
#### [v0.3.0](https://github.com/Human-Connection/Human-Connection/compare/v0.2.1...v0.3.0)
|
||||
#### [v0.3.0](https://github.com/Human-Connection/Human-Connection/compare/0.2.2...v0.3.0)
|
||||
|
||||
> 31 January 2020
|
||||
> 3 February 2020
|
||||
|
||||
- chore: Update to v0.3.0 [`#2941`](https://github.com/Human-Connection/Human-Connection/pull/2941)
|
||||
- build(deps-dev): bump @babel/core from 7.8.3 to 7.8.4 in /webapp [`#2939`](https://github.com/Human-Connection/Human-Connection/pull/2939)
|
||||
- feat: 🍰 Direct Reply On Comment [`#2608`](https://github.com/Human-Connection/Human-Connection/pull/2608)
|
||||
- build(deps-dev): bump @babel/core from 7.8.3 to 7.8.4 in /backend [`#2938`](https://github.com/Human-Connection/Human-Connection/pull/2938)
|
||||
@ -343,6 +474,15 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- build(deps-dev): bump jest from 24.9.0 to 25.1.0 in /backend [`#2862`](https://github.com/Human-Connection/Human-Connection/pull/2862)
|
||||
- docs(deployment): Explain how to setup metrics [`#2825`](https://github.com/Human-Connection/Human-Connection/pull/2825)
|
||||
- refactor(styleguide): Migrate Avatar component to monorepo [`#2700`](https://github.com/Human-Connection/Human-Connection/pull/2700)
|
||||
- docs(deployment): Explain how to setup metrics (#2825) [`#2411`](https://github.com/Human-Connection/Human-Connection/issues/2411) [`#2777`](https://github.com/Human-Connection/Human-Connection/issues/2777)
|
||||
- Get rid of different factory files [`fc36729`](https://github.com/Human-Connection/Human-Connection/commit/fc367297e3e054f09b7f8f31788ab68d87f6babf)
|
||||
- Refactor factory for comments [`2fc71d7`](https://github.com/Human-Connection/Human-Connection/commit/2fc71d75a5d5eab9c3467e94e00257ef6dd7d8a0)
|
||||
- Refactor user factory [`2a79c53`](https://github.com/Human-Connection/Human-Connection/commit/2a79c53765b73f9b91691eb75f55cf8c9e48306e)
|
||||
|
||||
#### [0.2.2](https://github.com/Human-Connection/Human-Connection/compare/v0.2.2...0.2.2)
|
||||
|
||||
> 21 January 2020
|
||||
|
||||
- feat: Convert block/unblock to mute/unmute [`#2686`](https://github.com/Human-Connection/Human-Connection/pull/2686)
|
||||
- removed obsolete German keys [`#2845`](https://github.com/Human-Connection/Human-Connection/pull/2845)
|
||||
- build(deps-dev): bump @vue/server-test-utils in /webapp [`#2852`](https://github.com/Human-Connection/Human-Connection/pull/2852)
|
||||
@ -360,6 +500,14 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- build(deps): bump @hapi/joi from 17.0.2 to 17.1.0 in /backend [`#2846`](https://github.com/Human-Connection/Human-Connection/pull/2846)
|
||||
- Release 0.2.2 [`#2844`](https://github.com/Human-Connection/Human-Connection/pull/2844)
|
||||
- build(deps-dev): bump @storybook/addon-actions in /webapp [`#2842`](https://github.com/Human-Connection/Human-Connection/pull/2842)
|
||||
- Generate changelog with auto-changelog [`02367f9`](https://github.com/Human-Connection/Human-Connection/commit/02367f93e0ad635d5f43adf01695f85f06f4c0d2)
|
||||
- clean up UserAvatar a little [`d20421c`](https://github.com/Human-Connection/Human-Connection/commit/d20421cb70c4bda51fdaf59f28c3a060b59bb0cd)
|
||||
- display username below slug when there is no date-time [`e93332b`](https://github.com/Human-Connection/Human-Connection/commit/e93332b17361d2c59a841e7c03e93647ec76918f)
|
||||
|
||||
#### [v0.2.2](https://github.com/Human-Connection/Human-Connection/compare/v0.2.1...v0.2.2)
|
||||
|
||||
> 20 January 2020
|
||||
|
||||
- build(deps): bump metascraper-title from 5.10.3 to 5.10.5 in /backend [`#2835`](https://github.com/Human-Connection/Human-Connection/pull/2835)
|
||||
- build(deps): bump metascraper-publisher in /backend [`#2836`](https://github.com/Human-Connection/Human-Connection/pull/2836)
|
||||
- build(deps): bump metascraper-audio from 5.10.3 to 5.10.5 in /backend [`#2840`](https://github.com/Human-Connection/Human-Connection/pull/2840)
|
||||
@ -449,13 +597,12 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- Update yarn.lock after dependabot update [`#2724`](https://github.com/Human-Connection/Human-Connection/pull/2724)
|
||||
- build(deps): bump @nuxtjs/axios from 5.8.0 to 5.9.2 in /webapp [`#2657`](https://github.com/Human-Connection/Human-Connection/pull/2657)
|
||||
- Update to version 0.2.1 [`#2722`](https://github.com/Human-Connection/Human-Connection/pull/2722)
|
||||
- docs(deployment): Explain how to setup metrics (#2825) [`#2411`](https://github.com/Human-Connection/Human-Connection/issues/2411) [`#2777`](https://github.com/Human-Connection/Human-Connection/issues/2777)
|
||||
- refactor(modules): Various import fixes [`#2773`](https://github.com/Human-Connection/Human-Connection/issues/2773) [`#2774`](https://github.com/Human-Connection/Human-Connection/issues/2774)
|
||||
- feat(webapp): Display deployed version in footer [`#1831`](https://github.com/Human-Connection/Human-Connection/issues/1831)
|
||||
- fix #2229 [`#2229`](https://github.com/Human-Connection/Human-Connection/issues/2229)
|
||||
- Get rid of different factory files [`fc36729`](https://github.com/Human-Connection/Human-Connection/commit/fc367297e3e054f09b7f8f31788ab68d87f6babf)
|
||||
- Refactor factory for comments [`2fc71d7`](https://github.com/Human-Connection/Human-Connection/commit/2fc71d75a5d5eab9c3467e94e00257ef6dd7d8a0)
|
||||
- Refactor user factory [`2a79c53`](https://github.com/Human-Connection/Human-Connection/commit/2a79c53765b73f9b91691eb75f55cf8c9e48306e)
|
||||
- build(deps-dev): bump @storybook/addon-actions in /webapp [`d0124bf`](https://github.com/Human-Connection/Human-Connection/commit/d0124bf2b4b4a641c9af76d6d2f7b5aa075ade90)
|
||||
- refactor: Make `db:setup` init stage of `migrate` [`b063847`](https://github.com/Human-Connection/Human-Connection/commit/b063847849a84db885337dc8e84e75ddaf87011f)
|
||||
- refactor and use base-button in SearchableInput [`fcbe612`](https://github.com/Human-Connection/Human-Connection/commit/fcbe6125f35c0dd23e2ba1ae63f539f5ef5990ea)
|
||||
|
||||
#### [v0.2.1](https://github.com/Human-Connection/Human-Connection/compare/v0.2.0...v0.2.1)
|
||||
|
||||
@ -560,16 +707,16 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- build(deps): bump metascraper-publisher from 5.8.7 to 5.8.12 in /backend [`#2592`](https://github.com/Human-Connection/Human-Connection/pull/2592)
|
||||
- build(deps-dev): bump @babel/preset-env from 7.7.6 to 7.7.7 in /backend [`#2568`](https://github.com/Human-Connection/Human-Connection/pull/2568)
|
||||
- Fix imageAspectRatio set to null UpdatePost [`#2588`](https://github.com/Human-Connection/Human-Connection/pull/2588)
|
||||
- Update to version 0.2.0 [`#2584`](https://github.com/Human-Connection/Human-Connection/pull/2584)
|
||||
- fixes #2659 [`#2659`](https://github.com/Human-Connection/Human-Connection/issues/2659)
|
||||
- Convert block/unblock to blacklist/whitelist [`c297b83`](https://github.com/Human-Connection/Human-Connection/commit/c297b83f873edc61ddec370633b9b65896c56591)
|
||||
- Rename blacklist/whitelist to mute/unmute [`ba3e9e1`](https://github.com/Human-Connection/Human-Connection/commit/ba3e9e1025bf432151c9bf1002045179b338ff7f)
|
||||
- manage button states and color schemes with mixin [`1b9249c`](https://github.com/Human-Connection/Human-Connection/commit/1b9249c685e34eb2e94b31ee0ec22421c6aa6a73)
|
||||
- build(deps-dev): bump storybook-design-token in /webapp [`88d39c4`](https://github.com/Human-Connection/Human-Connection/commit/88d39c4a427cb86527b06201f3f5e96d53ac09a0)
|
||||
|
||||
#### [v0.2.0](https://github.com/Human-Connection/Human-Connection/compare/v0.1.13...v0.2.0)
|
||||
|
||||
> 19 December 2019
|
||||
|
||||
- Update to version 0.2.0 [`#2584`](https://github.com/Human-Connection/Human-Connection/pull/2584)
|
||||
- build(deps): bump metascraper-image from 5.8.10 to 5.8.12 in /backend [`#2556`](https://github.com/Human-Connection/Human-Connection/pull/2556)
|
||||
- build(deps-dev): bump @babel/core from 7.7.5 to 7.7.7 [`#2569`](https://github.com/Human-Connection/Human-Connection/pull/2569)
|
||||
- build(deps-dev): bump @babel/cli from 7.7.5 to 7.7.7 in /backend [`#2576`](https://github.com/Human-Connection/Human-Connection/pull/2576)
|
||||
@ -656,7 +803,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- Fix search by adding result id [`ebc5cf3`](https://github.com/Human-Connection/Human-Connection/commit/ebc5cf392d92acf3a9e22c8967d02ea2cf6fd7fb)
|
||||
- Write test/refactor tests/resolvers/middleware [`d375ebe`](https://github.com/Human-Connection/Human-Connection/commit/d375ebe7d90e3251b17f59ffba8fb1470923ebe8)
|
||||
|
||||
#### [v0.1.12](https://github.com/Human-Connection/Human-Connection/compare/v0.1.10...v0.1.12)
|
||||
#### [v0.1.12](https://github.com/Human-Connection/Human-Connection/compare/v0.1.11...v0.1.12)
|
||||
|
||||
> 10 December 2019
|
||||
|
||||
@ -766,6 +913,16 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- 2329 normalize emails in login form [`#2330`](https://github.com/Human-Connection/Human-Connection/pull/2330)
|
||||
- Lokalise: Translations update [`#2327`](https://github.com/Human-Connection/Human-Connection/pull/2327)
|
||||
- Changed translation must change test :( [`#2310`](https://github.com/Human-Connection/Human-Connection/pull/2310)
|
||||
- Merge pull request #2443 from Human-Connection/2237-longer-comments [`#2237`](https://github.com/Human-Connection/Human-Connection/issues/2237)
|
||||
- fix #2329: Normalize email on login in the backend [`#2329`](https://github.com/Human-Connection/Human-Connection/issues/2329)
|
||||
- Move components to components/features [`2357028`](https://github.com/Human-Connection/Human-Connection/commit/235702867d97b44dac37f8059f9194e23ba7f47d)
|
||||
- Refactor tests/resolvers [`d18d922`](https://github.com/Human-Connection/Human-Connection/commit/d18d9228b0057fae22b4b846f9d41f5223cd6e69)
|
||||
- [WIP] Extract code into own components [`9401d4e`](https://github.com/Human-Connection/Human-Connection/commit/9401d4e1e1894d1be490b07a72e1ae7ef9bf22d9)
|
||||
|
||||
#### [v0.1.11](https://github.com/Human-Connection/Human-Connection/compare/v0.1.10...v0.1.11)
|
||||
|
||||
> 22 November 2019
|
||||
|
||||
- build(deps-dev): bump apollo-server-testing from 2.9.9 to 2.9.12 in /backend [`#2318`](https://github.com/Human-Connection/Human-Connection/pull/2318)
|
||||
- build(deps-dev): bump fuse.js from 3.4.5 to 3.4.6 in /webapp [`#2314`](https://github.com/Human-Connection/Human-Connection/pull/2314)
|
||||
- build(deps-dev): bump eslint-config-prettier from 6.6.0 to 6.7.0 in /webapp [`#2302`](https://github.com/Human-Connection/Human-Connection/pull/2302)
|
||||
@ -815,13 +972,11 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- build(deps-dev): bump eslint from 5.16.0 to 6.6.0 in /webapp [`#2205`](https://github.com/Human-Connection/Human-Connection/pull/2205)
|
||||
- Add locale to undefined to null [`#2233`](https://github.com/Human-Connection/Human-Connection/pull/2233)
|
||||
- Update to version 0.1.10 [`#2231`](https://github.com/Human-Connection/Human-Connection/pull/2231)
|
||||
- Merge pull request #2443 from Human-Connection/2237-longer-comments [`#2237`](https://github.com/Human-Connection/Human-Connection/issues/2237)
|
||||
- fix #2329: Normalize email on login in the backend [`#2329`](https://github.com/Human-Connection/Human-Connection/issues/2329)
|
||||
- Fix #2294 [`#2294`](https://github.com/Human-Connection/Human-Connection/issues/2294)
|
||||
- Merge pull request #2078 from Human-Connection/fix-2042-back-link [`#2042`](https://github.com/Human-Connection/Human-Connection/issues/2042)
|
||||
- Move components to components/features [`2357028`](https://github.com/Human-Connection/Human-Connection/commit/235702867d97b44dac37f8059f9194e23ba7f47d)
|
||||
- Basic Search Is Working For Users And Posts [`72e4d0a`](https://github.com/Human-Connection/Human-Connection/commit/72e4d0abbcb9abab07f3fd12876453eb1de5da4c)
|
||||
- Add missing unit tests/refactor code [`b364065`](https://github.com/Human-Connection/Human-Connection/commit/b3640659bb608cc34edc6f2aca350f07dd2b9ce6)
|
||||
- Tell github-linguists to ignore snapshots [`978347b`](https://github.com/Human-Connection/Human-Connection/commit/978347ba7b5a6aa1bc915ada972ffffa2816d37c)
|
||||
- Lokalise: update of webapp/locales/ru.json [`906e851`](https://github.com/Human-Connection/Human-Connection/commit/906e8518bf060134150187fb1574ac50ffd502f6)
|
||||
- set up global localVue [`77f4810`](https://github.com/Human-Connection/Human-Connection/commit/77f4810ddc963386bc68d3e8a5e078ef4cf270b2)
|
||||
|
||||
#### [v0.1.10](https://github.com/Human-Connection/Human-Connection/compare/v0.1.9...v0.1.10)
|
||||
|
||||
@ -952,7 +1107,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
#### [v0.1.8](https://github.com/Human-Connection/Human-Connection/compare/v0.1.7...v0.1.8)
|
||||
|
||||
> 25 October 2019
|
||||
> 24 October 2019
|
||||
|
||||
- add FAQ _blank-href in Footer [`#2028`](https://github.com/Human-Connection/Human-Connection/pull/2028)
|
||||
- fix: Don't attempt to save locale if not authenticated [`#2025`](https://github.com/Human-Connection/Human-Connection/pull/2025)
|
||||
@ -968,9 +1123,9 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- build(deps-dev): bump @storybook/addon-a11y from 5.2.4 to 5.2.5 in /webapp [`#1989`](https://github.com/Human-Connection/Human-Connection/pull/1989)
|
||||
- build(deps-dev): bump @vue/cli-shared-utils from 4.0.4 to 4.0.5 in /webapp [`#2002`](https://github.com/Human-Connection/Human-Connection/pull/2002)
|
||||
- Update to version 0.1.7 [`#2015`](https://github.com/Human-Connection/Human-Connection/pull/2015)
|
||||
- Update to version 0.1.8 [`d45264b`](https://github.com/Human-Connection/Human-Connection/commit/d45264b3afa1557c2205e7ca1b77c778ee37ab5a)
|
||||
- build(deps): bump @nuxtjs/apollo in /webapp [`26c21b5`](https://github.com/Human-Connection/Human-Connection/commit/26c21b5b76c96206d98ff6bbfdbd1ca973ffcd4f)
|
||||
- Finish redesign of moderators report list [`15d28aa`](https://github.com/Human-Connection/Human-Connection/commit/15d28aa8ef84788aa640aac67838380bfacf63b7)
|
||||
- build(deps-dev): bump @storybook/addon-actions in /webapp [`7e95d37`](https://github.com/Human-Connection/Human-Connection/commit/7e95d376a311a5ede6351d577d30e25aea9cb65d)
|
||||
|
||||
#### [v0.1.7](https://github.com/Human-Connection/Human-Connection/compare/v0.1.6...v0.1.7)
|
||||
|
||||
@ -1271,7 +1426,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- Run with tag 0.1.0 [`c634ad2`](https://github.com/Human-Connection/Human-Connection/commit/c634ad264bd99dd1a87a86f870d7877aa751dc38)
|
||||
- zwischenspeichern [`e4c7c11`](https://github.com/Human-Connection/Human-Connection/commit/e4c7c1125da6f8fa259241b4d3838b1e7b1e24a2)
|
||||
|
||||
#### v0.1.0
|
||||
#### [v0.1.0](https://github.com/Human-Connection/Human-Connection/compare/0.1.0...v0.1.0)
|
||||
|
||||
> 18 September 2019
|
||||
|
||||
@ -1318,6 +1473,16 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- Add styleguide as submodule [`#1559`](https://github.com/Human-Connection/Human-Connection/pull/1559)
|
||||
- Push all docker images at VERSION to dockerhub [`#1558`](https://github.com/Human-Connection/Human-Connection/pull/1558)
|
||||
- II Add Date to Terms and Conditions #1535 [`#1556`](https://github.com/Human-Connection/Human-Connection/pull/1556)
|
||||
- Fix #1616 [`#1616`](https://github.com/Human-Connection/Human-Connection/issues/1616)
|
||||
- Fix #1555 [`#1555`](https://github.com/Human-Connection/Human-Connection/issues/1555)
|
||||
- Refactor Moderator spec tp use apollo-server-testing [`a6f4362`](https://github.com/Human-Connection/Human-Connection/commit/a6f4362a3f439bc3962c736aec517b7c8172a2d8)
|
||||
- Delete dead code [`94599c6`](https://github.com/Human-Connection/Human-Connection/commit/94599c624b77253720b6a3a7f87069737e621e1a)
|
||||
- adapt template to follow human connection styleguide (wip) [`61ce274`](https://github.com/Human-Connection/Human-Connection/commit/61ce27464c68836ba6e73638889694c5e3e88dbf)
|
||||
|
||||
#### 0.1.0
|
||||
|
||||
> 12 September 2019
|
||||
|
||||
- 🍰 [Helper] Message for backend tests failed by missing constraints [`#1553`](https://github.com/Human-Connection/Human-Connection/pull/1553)
|
||||
- Various changes to build pipeline [`#1543`](https://github.com/Human-Connection/Human-Connection/pull/1543)
|
||||
- Fix navbar styling [`#1557`](https://github.com/Human-Connection/Human-Connection/pull/1557)
|
||||
@ -2373,8 +2538,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- Delete docker-compose.yml [`#23`](https://github.com/Human-Connection/Human-Connection/pull/23)
|
||||
- Create .gitignore [`#22`](https://github.com/Human-Connection/Human-Connection/pull/22)
|
||||
- Update README.md [`#13`](https://github.com/Human-Connection/Human-Connection/pull/13)
|
||||
- Fix #1616 [`#1616`](https://github.com/Human-Connection/Human-Connection/issues/1616)
|
||||
- Fix #1555 [`#1555`](https://github.com/Human-Connection/Human-Connection/issues/1555)
|
||||
- Merge pull request #1508 from Human-Connection/1505_remove_html_in_moderation_view [`#1505`](https://github.com/Human-Connection/Human-Connection/issues/1505)
|
||||
- Fix #1506 [`#1506`](https://github.com/Human-Connection/Human-Connection/issues/1506)
|
||||
- Fix #1505 remove html [`#1505`](https://github.com/Human-Connection/Human-Connection/issues/1505)
|
||||
@ -2408,6 +2571,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- Merge pull request #104 from DakshMiglani/master [`#41`](https://github.com/Human-Connection/Human-Connection/issues/41)
|
||||
- Merge pull request #93 from Gerald1614/500_error_on_login [`#49`](https://github.com/Human-Connection/Human-Connection/issues/49)
|
||||
- Update schema.graphql [`#7`](https://github.com/Human-Connection/Human-Connection/issues/7)
|
||||
- Refactore the import and hashtags to all unicode characters [`0bc4c55`](https://github.com/Human-Connection/Human-Connection/commit/0bc4c558ae8f01d6d975b8ee1ea7f0f42b056d91)
|
||||
- Change strategy, only build docker image [`d6b7374`](https://github.com/Human-Connection/Human-Connection/commit/d6b7374ddbf497bdb5cbc935b88ae085c38b3237)
|
||||
- Copy package.json from webapp/ [`f3a9996`](https://github.com/Human-Connection/Human-Connection/commit/f3a9996962e5dd8b2e365a032c1a5766fe666103)
|
||||
- Suggestions implemented II [`a5f4480`](https://github.com/Human-Connection/Human-Connection/commit/a5f448036c6fe14015154e462a1381a01df55b15)
|
||||
|
||||
@ -17,3 +17,9 @@ PRIVATE_KEY_PASSPHRASE="a7dsf78sadg87ad87sfagsadg78"
|
||||
SENTRY_DSN_BACKEND=
|
||||
COMMIT=
|
||||
PUBLIC_REGISTRATION=false
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_ENDPOINT=
|
||||
AWS_REGION=
|
||||
AWS_BUCKET=
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "human-connection-backend",
|
||||
"version": "0.5.0",
|
||||
"version": "0.6.1",
|
||||
"description": "GraphQL Backend for Human Connection",
|
||||
"main": "src/index.js",
|
||||
"scripts": {
|
||||
@ -38,19 +38,20 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@hapi/joi": "^17.1.1",
|
||||
"@sentry/node": "^5.14.2",
|
||||
"@sentry/node": "^5.15.4",
|
||||
"apollo-cache-inmemory": "~1.6.5",
|
||||
"apollo-client": "~2.6.8",
|
||||
"apollo-link-context": "~1.0.19",
|
||||
"apollo-link-http": "~1.5.16",
|
||||
"apollo-link-context": "~1.0.20",
|
||||
"apollo-link-http": "~1.5.17",
|
||||
"apollo-server": "~2.11.0",
|
||||
"apollo-server-express": "^2.11.0",
|
||||
"apollo-server-express": "^2.12.0",
|
||||
"aws-sdk": "^2.652.0",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"bcryptjs": "~2.4.3",
|
||||
"cheerio": "~1.0.0-rc.3",
|
||||
"cors": "~2.8.5",
|
||||
"cross-env": "~7.0.2",
|
||||
"date-fns": "2.11.0",
|
||||
"date-fns": "2.11.1",
|
||||
"debug": "~4.1.1",
|
||||
"dotenv": "~8.2.0",
|
||||
"express": "^4.17.1",
|
||||
@ -61,31 +62,32 @@
|
||||
"graphql-middleware": "~4.0.2",
|
||||
"graphql-middleware-sentry": "^3.2.1",
|
||||
"graphql-redis-subscriptions": "^2.2.1",
|
||||
"graphql-shield": "~7.2.1",
|
||||
"graphql-shield": "~7.2.2",
|
||||
"graphql-tag": "~2.10.3",
|
||||
"helmet": "~3.21.3",
|
||||
"ioredis": "^4.16.0",
|
||||
"helmet": "~3.22.0",
|
||||
"ioredis": "^4.16.1",
|
||||
"jsonwebtoken": "~8.5.1",
|
||||
"linkifyjs": "~2.1.8",
|
||||
"lodash": "~4.17.14",
|
||||
"merge-graphql-schemas": "^1.7.6",
|
||||
"metascraper": "^5.11.6",
|
||||
"metascraper-audio": "^5.11.6",
|
||||
"metascraper-author": "^5.11.6",
|
||||
"merge-graphql-schemas": "^1.7.7",
|
||||
"metascraper": "^5.11.8",
|
||||
"metascraper-audio": "^5.11.8",
|
||||
"metascraper-author": "^5.11.8",
|
||||
"metascraper-clearbit-logo": "^5.3.0",
|
||||
"metascraper-date": "^5.11.6",
|
||||
"metascraper-date": "^5.11.8",
|
||||
"metascraper-description": "^5.11.6",
|
||||
"metascraper-image": "^5.11.6",
|
||||
"metascraper-lang": "^5.11.6",
|
||||
"metascraper-image": "^5.11.8",
|
||||
"metascraper-lang": "^5.11.8",
|
||||
"metascraper-lang-detector": "^4.10.2",
|
||||
"metascraper-logo": "^5.11.6",
|
||||
"metascraper-publisher": "^5.11.6",
|
||||
"metascraper-soundcloud": "^5.11.7",
|
||||
"metascraper-title": "^5.11.6",
|
||||
"metascraper-url": "^5.11.6",
|
||||
"metascraper-video": "^5.11.6",
|
||||
"metascraper-youtube": "^5.11.6",
|
||||
"metascraper-publisher": "^5.11.8",
|
||||
"metascraper-soundcloud": "^5.11.8",
|
||||
"metascraper-title": "^5.11.8",
|
||||
"metascraper-url": "^5.11.8",
|
||||
"metascraper-video": "^5.11.8",
|
||||
"metascraper-youtube": "^5.11.8",
|
||||
"migrate": "^1.6.2",
|
||||
"mime-types": "^2.1.26",
|
||||
"minimatch": "^3.0.4",
|
||||
"mustache": "^4.0.1",
|
||||
"neo4j-driver": "^4.0.2",
|
||||
@ -100,36 +102,36 @@
|
||||
"slug": "~2.1.1",
|
||||
"subscriptions-transport-ws": "^0.9.16",
|
||||
"trunc-html": "~1.1.2",
|
||||
"uuid": "~7.0.2",
|
||||
"uuid": "~7.0.3",
|
||||
"validator": "^13.0.0",
|
||||
"wait-on": "~4.0.1",
|
||||
"xregexp": "^4.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "~7.8.4",
|
||||
"@babel/core": "~7.8.7",
|
||||
"@babel/core": "~7.9.0",
|
||||
"@babel/node": "~7.8.7",
|
||||
"@babel/plugin-proposal-throw-expressions": "^7.8.3",
|
||||
"@babel/preset-env": "~7.8.7",
|
||||
"@babel/register": "^7.8.6",
|
||||
"@babel/preset-env": "~7.9.5",
|
||||
"@babel/register": "^7.9.0",
|
||||
"apollo-server-testing": "~2.11.0",
|
||||
"babel-core": "~7.0.0-0",
|
||||
"babel-eslint": "~10.1.0",
|
||||
"babel-jest": "~25.1.0",
|
||||
"babel-jest": "~25.2.6",
|
||||
"chai": "~4.2.0",
|
||||
"cucumber": "~6.0.5",
|
||||
"eslint": "~6.8.0",
|
||||
"eslint-config-prettier": "~6.10.0",
|
||||
"eslint-config-standard": "~14.1.0",
|
||||
"eslint-plugin-import": "~2.20.1",
|
||||
"eslint-config-prettier": "~6.10.1",
|
||||
"eslint-config-standard": "~14.1.1",
|
||||
"eslint-plugin-import": "~2.20.2",
|
||||
"eslint-plugin-jest": "~23.8.2",
|
||||
"eslint-plugin-node": "~11.0.0",
|
||||
"eslint-plugin-node": "~11.1.0",
|
||||
"eslint-plugin-prettier": "~3.1.2",
|
||||
"eslint-plugin-promise": "~4.2.1",
|
||||
"eslint-plugin-standard": "~4.0.1",
|
||||
"jest": "~25.1.0",
|
||||
"jest": "~25.3.0",
|
||||
"nodemon": "~2.0.2",
|
||||
"prettier": "~1.19.1",
|
||||
"prettier": "~2.0.4",
|
||||
"rosie": "^2.0.1",
|
||||
"supertest": "~4.0.2"
|
||||
},
|
||||
|
||||
@ -202,14 +202,14 @@ export default class ActivityPub {
|
||||
debug('is public addressed')
|
||||
const sharedInboxEndpoints = await this.dataSource.getSharedInboxEndpoints()
|
||||
// serve shared inbox endpoints
|
||||
sharedInboxEndpoints.map(sharedInbox => {
|
||||
sharedInboxEndpoints.map((sharedInbox) => {
|
||||
return this.trySend(activity, fromName, new URL(sharedInbox).host, sharedInbox)
|
||||
})
|
||||
activity.to = activity.to.filter(recipient => {
|
||||
activity.to = activity.to.filter((recipient) => {
|
||||
return !isPublicAddressed({ to: recipient })
|
||||
})
|
||||
// serve the rest
|
||||
activity.to.map(async recipient => {
|
||||
activity.to.map(async (recipient) => {
|
||||
debug('serve rest')
|
||||
const actorObject = await this.getActorObject(recipient)
|
||||
return this.trySend(activity, fromName, new URL(recipient).host, actorObject.inbox)
|
||||
@ -219,7 +219,7 @@ export default class ActivityPub {
|
||||
const actorObject = await this.getActorObject(activity.to)
|
||||
return this.trySend(activity, fromName, new URL(activity.to).host, actorObject.inbox)
|
||||
} else if (Array.isArray(activity.to)) {
|
||||
activity.to.map(async recipient => {
|
||||
activity.to.map(async (recipient) => {
|
||||
const actorObject = await this.getActorObject(recipient)
|
||||
return this.trySend(activity, fromName, new URL(recipient).host, actorObject.inbox)
|
||||
})
|
||||
@ -231,7 +231,7 @@ export default class ActivityPub {
|
||||
return await signAndSend(activity, fromName, host, url)
|
||||
} catch (e) {
|
||||
if (tries > 0) {
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
return this.trySend(activity, fromName, host, url, --tries)
|
||||
}, 20000)
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ export default class NitroDataSource {
|
||||
followersCollection.totalItems = followersCount
|
||||
debug(`followers = ${JSON.stringify(followers, null, 2)}`)
|
||||
await Promise.all(
|
||||
followers.map(async follower => {
|
||||
followers.map(async (follower) => {
|
||||
followersCollection.orderedItems.push(constructIdFromName(follower.slug))
|
||||
}),
|
||||
)
|
||||
@ -161,7 +161,7 @@ export default class NitroDataSource {
|
||||
followingCollection.totalItems = followingCount
|
||||
|
||||
await Promise.all(
|
||||
following.map(async user => {
|
||||
following.map(async (user) => {
|
||||
followingCollection.orderedItems.push(await constructIdFromName(user.slug))
|
||||
}),
|
||||
)
|
||||
@ -238,7 +238,7 @@ export default class NitroDataSource {
|
||||
const outboxCollection = createOrderedCollectionPage(slug, 'outbox')
|
||||
outboxCollection.totalItems = posts.length
|
||||
await Promise.all(
|
||||
posts.map(async post => {
|
||||
posts.map(async (post) => {
|
||||
outboxCollection.orderedItems.push(
|
||||
await createArticleObject(
|
||||
post.activityId,
|
||||
@ -283,7 +283,7 @@ export default class NitroDataSource {
|
||||
orderedItems = onlyNewestItem ? [orderedItems.pop()] : orderedItems
|
||||
|
||||
return Promise.all(
|
||||
orderedItems.map(async follower => {
|
||||
orderedItems.map(async (follower) => {
|
||||
debug(`follower = ${follower}`)
|
||||
const fromUserId = await this.ensureUser(follower)
|
||||
debug(`fromUserId = ${fromUserId}`)
|
||||
@ -311,7 +311,7 @@ export default class NitroDataSource {
|
||||
const fromUserId = await this.ensureUser(constructIdFromName(fromUserName))
|
||||
orderedItems = onlyNewestItem ? [orderedItems.pop()] : orderedItems
|
||||
return Promise.all(
|
||||
orderedItems.map(async following => {
|
||||
orderedItems.map(async (following) => {
|
||||
debug(`follower = ${following}`)
|
||||
const toUserId = await this.ensureUser(following)
|
||||
debug(`fromUserId = ${fromUserId}`)
|
||||
@ -343,10 +343,7 @@ export default class NitroDataSource {
|
||||
}
|
||||
const title = postObject.summary
|
||||
? postObject.summary
|
||||
: postObject.content
|
||||
.split(' ')
|
||||
.slice(0, 5)
|
||||
.join(' ')
|
||||
: postObject.content.split(' ').slice(0, 5).join(' ')
|
||||
const postId = extractIdFromActivityId(postObject.id)
|
||||
debug('inside create post')
|
||||
let result = await this.client.mutate({
|
||||
@ -560,10 +557,7 @@ export default class NitroDataSource {
|
||||
debug('ensureUser: user not exists.. createUser')
|
||||
// user does not exist.. create it
|
||||
const pw = crypto.randomBytes(16).toString('hex')
|
||||
const slug = name
|
||||
.toLowerCase()
|
||||
.split(' ')
|
||||
.join('-')
|
||||
const slug = name.toLowerCase().split(' ').join('-')
|
||||
const result = await this.client.mutate({
|
||||
mutation: gql`
|
||||
mutation {
|
||||
|
||||
@ -7,7 +7,7 @@ const router = express.Router()
|
||||
|
||||
// Shared Inbox endpoint (federated Server)
|
||||
// For now its only able to handle Note Activities!!
|
||||
router.post('/', async function(req, res, next) {
|
||||
router.post('/', async function (req, res, next) {
|
||||
debug(`Content-Type = ${req.get('Content-Type')}`)
|
||||
debug(`body = ${JSON.stringify(req.body, null, 2)}`)
|
||||
debug(`Request headers = ${JSON.stringify(req.headers, null, 2)}`)
|
||||
|
||||
@ -4,7 +4,7 @@ import express from 'express'
|
||||
import cors from 'cors'
|
||||
import verify from './verify'
|
||||
|
||||
export default function() {
|
||||
export default function () {
|
||||
const router = express.Router()
|
||||
router.use(
|
||||
'/activitypub/users',
|
||||
|
||||
@ -21,7 +21,7 @@ export async function serveUser(req, res, next) {
|
||||
}
|
||||
`,
|
||||
})
|
||||
.catch(reason => {
|
||||
.catch((reason) => {
|
||||
debug(`serveUser User fetch error: ${reason}`)
|
||||
})
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import verify from './verify'
|
||||
const router = express.Router()
|
||||
const debug = require('debug')('ea:user')
|
||||
|
||||
router.get('/:name', async function(req, res, next) {
|
||||
router.get('/:name', async function (req, res, next) {
|
||||
debug('inside user.js -> serveUser')
|
||||
await serveUser(req, res, next)
|
||||
})
|
||||
@ -45,7 +45,7 @@ router.get('/:name/outbox', (req, res) => {
|
||||
}
|
||||
})
|
||||
|
||||
router.post('/:name/inbox', verify, async function(req, res, next) {
|
||||
router.post('/:name/inbox', verify, async function (req, res, next) {
|
||||
debug(`body = ${JSON.stringify(req.body, null, 2)}`)
|
||||
debug(`actorId = ${req.body.actor}`)
|
||||
// const result = await saveActorId(req.body.actor)
|
||||
|
||||
@ -5,7 +5,7 @@ import cors from 'cors'
|
||||
const debug = require('debug')('ea:webfinger')
|
||||
const regex = /acct:([a-z0-9_-]*)@([a-z0-9_-]*)/
|
||||
|
||||
const createWebFinger = name => {
|
||||
const createWebFinger = (name) => {
|
||||
const { host } = new URL(CONFIG.CLIENT_URI)
|
||||
return {
|
||||
subject: `acct:${name}@${host}`,
|
||||
@ -30,11 +30,11 @@ export async function handler(req, res) {
|
||||
|
||||
const session = req.app.get('driver').session()
|
||||
try {
|
||||
const [slug] = await session.readTransaction(async t => {
|
||||
const [slug] = await session.readTransaction(async (t) => {
|
||||
const result = await t.run('MATCH (u:User {slug: $slug}) RETURN u.slug AS slug', {
|
||||
slug: name,
|
||||
})
|
||||
return result.records.map(record => record.get('slug'))
|
||||
return result.records.map((record) => record.get('slug'))
|
||||
})
|
||||
if (!slug)
|
||||
return res.status(404).json({
|
||||
@ -52,7 +52,7 @@ export async function handler(req, res) {
|
||||
}
|
||||
}
|
||||
|
||||
export default function() {
|
||||
export default function () {
|
||||
const router = express.Router()
|
||||
router.use('/webfinger', cors(), express.urlencoded({ extended: true }), handler)
|
||||
return router
|
||||
|
||||
@ -13,7 +13,7 @@ const request = () => {
|
||||
res = { status, contentType }
|
||||
const req = {
|
||||
app: {
|
||||
get: key => {
|
||||
get: (key) => {
|
||||
return {
|
||||
driver,
|
||||
}[key]
|
||||
|
||||
@ -69,7 +69,7 @@ export function verifySignature(url, headers) {
|
||||
|
||||
const usedHeaders = headersString.split(' ')
|
||||
const verifyHeaders = {}
|
||||
Object.keys(headers).forEach(key => {
|
||||
Object.keys(headers).forEach((key) => {
|
||||
if (usedHeaders.includes(key.toLowerCase())) {
|
||||
verifyHeaders[key.toLowerCase()] = headers[key]
|
||||
}
|
||||
@ -119,7 +119,7 @@ function httpVerify(pubKey, signature, signingString, algorithm) {
|
||||
// This function can be used to extract the signature,headers,algorithm etc. out of the Signature Header.
|
||||
// Just pass what you want as key
|
||||
function extractKeyValueFromSignatureHeader(signatureHeader, key) {
|
||||
const keyString = signatureHeader.split(',').filter(el => {
|
||||
const keyString = signatureHeader.split(',').filter((el) => {
|
||||
return !!el.startsWith(key)
|
||||
})[0]
|
||||
|
||||
|
||||
@ -60,13 +60,10 @@ export function sendCollection(collectionName, req, res) {
|
||||
|
||||
function attachThenCatch(promise, res) {
|
||||
return promise
|
||||
.then(collection => {
|
||||
res
|
||||
.status(200)
|
||||
.contentType('application/activity+json')
|
||||
.send(collection)
|
||||
.then((collection) => {
|
||||
res.status(200).contentType('application/activity+json').send(collection)
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
debug(`error getting a Collection: = ${err}`)
|
||||
res.status(500).end()
|
||||
})
|
||||
|
||||
@ -53,7 +53,7 @@ export function signAndSend(activity, fromName, targetDomain, url) {
|
||||
}
|
||||
`,
|
||||
})
|
||||
.then(result => {
|
||||
.then((result) => {
|
||||
if (result.error) {
|
||||
reject(result.error)
|
||||
} else {
|
||||
|
||||
@ -18,6 +18,11 @@ const {
|
||||
SMTP_PASSWORD,
|
||||
SENTRY_DSN_BACKEND,
|
||||
COMMIT,
|
||||
AWS_ACCESS_KEY_ID,
|
||||
AWS_SECRET_ACCESS_KEY,
|
||||
AWS_ENDPOINT,
|
||||
AWS_REGION,
|
||||
AWS_BUCKET,
|
||||
NEO4J_URI = 'bolt://localhost:7687',
|
||||
NEO4J_USERNAME = 'neo4j',
|
||||
NEO4J_PASSWORD = 'neo4j',
|
||||
@ -36,7 +41,7 @@ export const requiredConfigs = {
|
||||
|
||||
if (require.resolve) {
|
||||
// are we in a nodejs environment?
|
||||
Object.entries(requiredConfigs).map(entry => {
|
||||
Object.entries(requiredConfigs).map((entry) => {
|
||||
if (!entry[1]) {
|
||||
throw new Error(`ERROR: "${entry[0]}" env variable is missing.`)
|
||||
}
|
||||
@ -64,7 +69,20 @@ export const developmentConfigs = {
|
||||
}
|
||||
|
||||
export const sentryConfigs = { SENTRY_DSN_BACKEND, COMMIT }
|
||||
export const redisConfiig = { REDIS_DOMAIN, REDIS_PORT, REDIS_PASSWORD }
|
||||
export const redisConfigs = { REDIS_DOMAIN, REDIS_PORT, REDIS_PASSWORD }
|
||||
|
||||
const S3_CONFIGURED =
|
||||
AWS_ACCESS_KEY_ID && AWS_SECRET_ACCESS_KEY && AWS_ENDPOINT && AWS_REGION && AWS_BUCKET
|
||||
|
||||
export const s3Configs = {
|
||||
AWS_ACCESS_KEY_ID,
|
||||
AWS_SECRET_ACCESS_KEY,
|
||||
AWS_ENDPOINT,
|
||||
AWS_REGION,
|
||||
AWS_BUCKET,
|
||||
S3_CONFIGURED,
|
||||
}
|
||||
|
||||
export default {
|
||||
...requiredConfigs,
|
||||
...smtpConfigs,
|
||||
@ -72,5 +90,6 @@ export default {
|
||||
...serverConfigs,
|
||||
...developmentConfigs,
|
||||
...sentryConfigs,
|
||||
...redisConfiig,
|
||||
...redisConfigs,
|
||||
...s3Configs,
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ if (process.env.NODE_ENV === 'production') {
|
||||
throw new Error(`You cannot clean the database in production environment!`)
|
||||
}
|
||||
|
||||
;(async function() {
|
||||
;(async function () {
|
||||
try {
|
||||
await cleanDatabase()
|
||||
console.log('Successfully deleted all nodes and relations!') // eslint-disable-line no-console
|
||||
|
||||
@ -8,7 +8,7 @@ import CONFIG from '../config/index.js'
|
||||
|
||||
const neode = getNeode()
|
||||
|
||||
const uniqueImageUrl = imageUrl => {
|
||||
const uniqueImageUrl = (imageUrl) => {
|
||||
const newUrl = new URL(imageUrl, CONFIG.CLIENT_URI)
|
||||
newUrl.search = `random=${uuid()}`
|
||||
return newUrl.toString()
|
||||
@ -18,7 +18,7 @@ export const cleanDatabase = async (options = {}) => {
|
||||
const { driver = getDriver() } = options
|
||||
const session = driver.session()
|
||||
try {
|
||||
await session.writeTransaction(transaction => {
|
||||
await session.writeTransaction((transaction) => {
|
||||
return transaction.run(
|
||||
`
|
||||
MATCH (everything)
|
||||
@ -73,7 +73,7 @@ Factory.define('basicUser')
|
||||
.attr('slug', ['slug', 'name'], (slug, name) => {
|
||||
return slug || slugify(name, { lower: true })
|
||||
})
|
||||
.attr('encryptedPassword', ['password'], password => {
|
||||
.attr('encryptedPassword', ['password'], (password) => {
|
||||
return hashSync(password, 10)
|
||||
})
|
||||
|
||||
@ -104,17 +104,17 @@ Factory.define('user')
|
||||
|
||||
Factory.define('post')
|
||||
.option('categoryIds', [])
|
||||
.option('categories', ['categoryIds'], categoryIds => {
|
||||
if (categoryIds.length) return Promise.all(categoryIds.map(id => neode.find('Category', id)))
|
||||
.option('categories', ['categoryIds'], (categoryIds) => {
|
||||
if (categoryIds.length) return Promise.all(categoryIds.map((id) => neode.find('Category', id)))
|
||||
// there must be at least one category
|
||||
return Promise.all([Factory.build('category')])
|
||||
})
|
||||
.option('tagIds', [])
|
||||
.option('tags', ['tagIds'], tagIds => {
|
||||
return Promise.all(tagIds.map(id => neode.find('Tag', id)))
|
||||
.option('tags', ['tagIds'], (tagIds) => {
|
||||
return Promise.all(tagIds.map((id) => neode.find('Tag', id)))
|
||||
})
|
||||
.option('authorId', null)
|
||||
.option('author', ['authorId'], authorId => {
|
||||
.option('author', ['authorId'], (authorId) => {
|
||||
if (authorId) return neode.find('User', authorId)
|
||||
return Factory.build('user')
|
||||
})
|
||||
@ -129,7 +129,7 @@ Factory.define('post')
|
||||
imageBlurred: false,
|
||||
imageAspectRatio: 1.333,
|
||||
})
|
||||
.attr('pinned', ['pinned'], pinned => {
|
||||
.attr('pinned', ['pinned'], (pinned) => {
|
||||
// Convert false to null
|
||||
return pinned || null
|
||||
})
|
||||
@ -139,7 +139,7 @@ Factory.define('post')
|
||||
.attr('slug', ['slug', 'title'], (slug, title) => {
|
||||
return slug || slugify(title, { lower: true })
|
||||
})
|
||||
.attr('language', ['language'], language => {
|
||||
.attr('language', ['language'], (language) => {
|
||||
return language || 'en'
|
||||
})
|
||||
.after(async (buildObject, options) => {
|
||||
@ -152,8 +152,8 @@ Factory.define('post')
|
||||
])
|
||||
await Promise.all([
|
||||
post.relateTo(author, 'author'),
|
||||
Promise.all(categories.map(c => c.relateTo(post, 'post'))),
|
||||
Promise.all(tags.map(t => t.relateTo(post, 'post'))),
|
||||
Promise.all(categories.map((c) => c.relateTo(post, 'post'))),
|
||||
Promise.all(tags.map((t) => t.relateTo(post, 'post'))),
|
||||
])
|
||||
if (image) await post.relateTo(image, 'image')
|
||||
if (buildObject.pinned) {
|
||||
@ -165,12 +165,12 @@ Factory.define('post')
|
||||
|
||||
Factory.define('comment')
|
||||
.option('postId', null)
|
||||
.option('post', ['postId'], postId => {
|
||||
.option('post', ['postId'], (postId) => {
|
||||
if (postId) return neode.find('Post', postId)
|
||||
return Factory.build('post')
|
||||
})
|
||||
.option('authorId', null)
|
||||
.option('author', ['authorId'], authorId => {
|
||||
.option('author', ['authorId'], (authorId) => {
|
||||
if (authorId) return neode.find('User', authorId)
|
||||
return Factory.build('user')
|
||||
})
|
||||
|
||||
@ -6,14 +6,14 @@ class Store {
|
||||
const { driver } = neode
|
||||
const session = driver.session()
|
||||
// eslint-disable-next-line no-console
|
||||
const writeTxResultPromise = session.writeTransaction(async txc => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (txc) => {
|
||||
await txc.run('CALL apoc.schema.assert({},{},true)') // drop all indices
|
||||
return Promise.all(
|
||||
[
|
||||
'CALL db.index.fulltext.createNodeIndex("post_fulltext_search",["Post"],["title", "content"])',
|
||||
'CALL db.index.fulltext.createNodeIndex("user_fulltext_search",["User"],["name", "slug"])',
|
||||
'CALL db.index.fulltext.createNodeIndex("tag_fulltext_search",["Tag"],["id"])',
|
||||
].map(statement => txc.run(statement)),
|
||||
].map((statement) => txc.run(statement)),
|
||||
)
|
||||
})
|
||||
try {
|
||||
@ -34,11 +34,11 @@ class Store {
|
||||
async load(next) {
|
||||
const driver = getDriver()
|
||||
const session = driver.session()
|
||||
const readTxResultPromise = session.readTransaction(async txc => {
|
||||
const readTxResultPromise = session.readTransaction(async (txc) => {
|
||||
const result = await txc.run(
|
||||
'MATCH (migration:Migration) RETURN migration {.*} ORDER BY migration.timestamp DESC',
|
||||
)
|
||||
return result.records.map(r => r.get('migration'))
|
||||
return result.records.map((r) => r.get('migration'))
|
||||
})
|
||||
try {
|
||||
const migrations = await readTxResultPromise
|
||||
@ -63,9 +63,9 @@ class Store {
|
||||
const driver = getDriver()
|
||||
const session = driver.session()
|
||||
const { migrations } = set
|
||||
const writeTxResultPromise = session.writeTransaction(txc => {
|
||||
const writeTxResultPromise = session.writeTransaction((txc) => {
|
||||
return Promise.all(
|
||||
migrations.map(async migration => {
|
||||
migrations.map(async (migration) => {
|
||||
const { title, description, timestamp } = migration
|
||||
const properties = { title, description, timestamp }
|
||||
const migrationResult = await txc.run(
|
||||
|
||||
@ -18,13 +18,13 @@ export function up(next) {
|
||||
rxSession
|
||||
.beginTransaction()
|
||||
.pipe(
|
||||
flatMap(txc =>
|
||||
flatMap((txc) =>
|
||||
concat(
|
||||
txc
|
||||
.run('MATCH (email:EmailAddress) RETURN email {.email}')
|
||||
.records()
|
||||
.pipe(
|
||||
map(record => {
|
||||
map((record) => {
|
||||
const { email } = record.get('email')
|
||||
const normalizedEmail = normalizeEmail(email)
|
||||
return { email, normalizedEmail }
|
||||
@ -45,7 +45,7 @@ export function up(next) {
|
||||
)
|
||||
.records()
|
||||
.pipe(
|
||||
map(r => ({
|
||||
map((r) => ({
|
||||
oldEmail: email,
|
||||
email: r.get('email'),
|
||||
user: r.get('user'),
|
||||
@ -54,7 +54,7 @@ export function up(next) {
|
||||
}),
|
||||
),
|
||||
txc.commit(),
|
||||
).pipe(catchError(err => txc.rollback().pipe(throwError(err)))),
|
||||
).pipe(catchError((err) => txc.rollback().pipe(throwError(err)))),
|
||||
),
|
||||
)
|
||||
.subscribe({
|
||||
@ -72,7 +72,7 @@ export function up(next) {
|
||||
console.log('Merging of duplicate users completed')
|
||||
next()
|
||||
},
|
||||
error: error => {
|
||||
error: (error) => {
|
||||
next(new Error(error), null)
|
||||
},
|
||||
})
|
||||
|
||||
@ -12,7 +12,7 @@ export function up(next) {
|
||||
rxSession
|
||||
.beginTransaction()
|
||||
.pipe(
|
||||
flatMap(transaction =>
|
||||
flatMap((transaction) =>
|
||||
concat(
|
||||
transaction
|
||||
.run(
|
||||
@ -23,7 +23,7 @@ export function up(next) {
|
||||
)
|
||||
.records()
|
||||
.pipe(
|
||||
map(record => {
|
||||
map((record) => {
|
||||
const { id: locationId } = record.get('location')
|
||||
return { locationId }
|
||||
}),
|
||||
@ -40,7 +40,7 @@ export function up(next) {
|
||||
)
|
||||
.records()
|
||||
.pipe(
|
||||
map(record => ({
|
||||
map((record) => ({
|
||||
location: record.get('location'),
|
||||
updatedLocation: record.get('updatedLocation'),
|
||||
})),
|
||||
@ -48,7 +48,7 @@ export function up(next) {
|
||||
}),
|
||||
),
|
||||
transaction.commit(),
|
||||
).pipe(catchError(error => transaction.rollback().pipe(throwError(error)))),
|
||||
).pipe(catchError((error) => transaction.rollback().pipe(throwError(error)))),
|
||||
),
|
||||
)
|
||||
.subscribe({
|
||||
@ -66,7 +66,7 @@ export function up(next) {
|
||||
console.log('Merging of duplicate locations completed')
|
||||
next()
|
||||
},
|
||||
error: error => {
|
||||
error: (error) => {
|
||||
next(new Error(error), null)
|
||||
},
|
||||
})
|
||||
|
||||
@ -8,7 +8,7 @@ values lat=10.0 and lng=53.55, which is close to the horn of Africa,
|
||||
but it is lat=53.55 and lng=10.0
|
||||
`
|
||||
|
||||
const swap = async function(next) {
|
||||
const swap = async function (next) {
|
||||
const driver = getDriver()
|
||||
const session = driver.session()
|
||||
const transaction = session.beginTransaction()
|
||||
|
||||
@ -15,12 +15,18 @@ export async function up(next) {
|
||||
await transaction.commit()
|
||||
next()
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error)
|
||||
await transaction.rollback()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('rolled back')
|
||||
throw new Error(error)
|
||||
const { message } = error
|
||||
if (message.includes('There already exists an index')) {
|
||||
// all fine
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(message)
|
||||
next()
|
||||
} else {
|
||||
await transaction.rollback()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('rolled back')
|
||||
throw new Error(error)
|
||||
}
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
|
||||
@ -19,11 +19,18 @@ export async function up(next) {
|
||||
await transaction.commit()
|
||||
next()
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error)
|
||||
await transaction.rollback()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('rolled back')
|
||||
const { message } = error
|
||||
if (message.includes('There already exists an index')) {
|
||||
// all fine
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(message)
|
||||
next()
|
||||
} else {
|
||||
await transaction.rollback()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('rolled back')
|
||||
throw new Error(error)
|
||||
}
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
|
||||
107
backend/src/db/migrations/20200312140328-bulk_upload_to_s3.js
Normal file
107
backend/src/db/migrations/20200312140328-bulk_upload_to_s3.js
Normal file
@ -0,0 +1,107 @@
|
||||
import { getDriver } from '../../db/neo4j'
|
||||
import { existsSync, createReadStream } from 'fs'
|
||||
import path from 'path'
|
||||
import { S3 } from 'aws-sdk'
|
||||
import mime from 'mime-types'
|
||||
import { s3Configs } from '../../config'
|
||||
import https from 'https'
|
||||
|
||||
export const description = `
|
||||
Upload all image files to a S3 compatible object storage in order to reduce
|
||||
load on our backend.
|
||||
`
|
||||
|
||||
export async function up(next) {
|
||||
const driver = getDriver()
|
||||
const session = driver.session()
|
||||
const transaction = session.beginTransaction()
|
||||
const agent = new https.Agent({
|
||||
maxSockets: 5,
|
||||
})
|
||||
|
||||
const {
|
||||
AWS_ENDPOINT: endpoint,
|
||||
AWS_REGION: region,
|
||||
AWS_BUCKET: Bucket,
|
||||
S3_CONFIGURED,
|
||||
} = s3Configs
|
||||
|
||||
if (!S3_CONFIGURED) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('No S3 given, cannot upload image files')
|
||||
return
|
||||
}
|
||||
|
||||
const s3 = new S3({ region, endpoint, httpOptions: { agent } })
|
||||
try {
|
||||
// Implement your migration here.
|
||||
const { records } = await transaction.run('MATCH (image:Image) RETURN image.url as url')
|
||||
let urls = records.map((r) => r.get('url'))
|
||||
urls = urls.filter((url) => url.startsWith('/uploads'))
|
||||
const locations = await Promise.all(
|
||||
urls
|
||||
.map((url) => {
|
||||
return async () => {
|
||||
const { pathname } = new URL(url, 'http://example.org')
|
||||
const fileLocation = path.join(__dirname, `../../../public/${pathname}`)
|
||||
const s3Location = `original${pathname}`
|
||||
if (existsSync(fileLocation)) {
|
||||
const mimeType = mime.lookup(fileLocation)
|
||||
const params = {
|
||||
Bucket,
|
||||
Key: s3Location,
|
||||
ACL: 'public-read',
|
||||
ContentType: mimeType || 'image/jpeg',
|
||||
Body: createReadStream(fileLocation),
|
||||
}
|
||||
|
||||
const data = await s3.upload(params).promise()
|
||||
const { Location: spacesUrl } = data
|
||||
|
||||
const updatedRecord = await transaction.run(
|
||||
'MATCH (image:Image {url: $url}) SET image.url = $spacesUrl RETURN image.url as url',
|
||||
{ url, spacesUrl },
|
||||
)
|
||||
const [updatedUrl] = updatedRecord.records.map((record) => record.get('url'))
|
||||
return updatedUrl
|
||||
}
|
||||
}
|
||||
})
|
||||
.map((p) => p()),
|
||||
)
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('this is locations', locations)
|
||||
await transaction.commit()
|
||||
next()
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error)
|
||||
await transaction.rollback()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('rolled back')
|
||||
throw new Error(error)
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
}
|
||||
|
||||
export async function down(next) {
|
||||
const driver = getDriver()
|
||||
const session = driver.session()
|
||||
const transaction = session.beginTransaction()
|
||||
|
||||
try {
|
||||
// Implement your migration here.
|
||||
await transaction.run(``)
|
||||
await transaction.commit()
|
||||
next()
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error)
|
||||
await transaction.rollback()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('rolled back')
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
}
|
||||
@ -6,9 +6,9 @@ export const description = `
|
||||
"Image" which contains metadata and image file urls.
|
||||
`
|
||||
|
||||
const printSummaries = summaries => {
|
||||
const printSummaries = (summaries) => {
|
||||
console.log('=========================================')
|
||||
summaries.forEach(stat => {
|
||||
summaries.forEach((stat) => {
|
||||
console.log(stat.query.text)
|
||||
console.log(JSON.stringify(stat.counters, null, 2))
|
||||
})
|
||||
@ -18,7 +18,7 @@ const printSummaries = summaries => {
|
||||
export async function up() {
|
||||
const driver = getDriver()
|
||||
const session = driver.session()
|
||||
const writeTxResultPromise = session.writeTransaction(async txc => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (txc) => {
|
||||
const runs = await Promise.all(
|
||||
[
|
||||
`
|
||||
@ -48,7 +48,7 @@ export async function up() {
|
||||
CREATE (user)-[:COVER_IMAGE]->(coverImage)
|
||||
REMOVE user.coverImg
|
||||
`,
|
||||
].map(s => txc.run(s)),
|
||||
].map((s) => txc.run(s)),
|
||||
)
|
||||
return runs.map(({ summary }) => summary)
|
||||
})
|
||||
@ -65,7 +65,7 @@ export async function up() {
|
||||
export async function down() {
|
||||
const driver = getDriver()
|
||||
const session = driver.session()
|
||||
const writeTxResultPromise = session.writeTransaction(async txc => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (txc) => {
|
||||
const runs = await Promise.all(
|
||||
[
|
||||
`
|
||||
@ -86,7 +86,7 @@ export async function down() {
|
||||
SET user.coverImg = coverImage.url
|
||||
DETACH DELETE coverImage
|
||||
`,
|
||||
].map(s => txc.run(s)),
|
||||
].map((s) => txc.run(s)),
|
||||
)
|
||||
return runs.map(({ summary }) => summary)
|
||||
})
|
||||
|
||||
@ -20,7 +20,7 @@ export async function up(next) {
|
||||
`)
|
||||
try {
|
||||
// Implement your migration here.
|
||||
const users = await updateDeletedUserAttributes.records.map(record => record.get('user'))
|
||||
const users = await updateDeletedUserAttributes.records.map((record) => record.get('user'))
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(users)
|
||||
await transaction.commit()
|
||||
|
||||
@ -22,7 +22,7 @@ export async function up(next) {
|
||||
`)
|
||||
try {
|
||||
// Implement your migration here.
|
||||
const posts = await updateDeletedPostsAttributes.records.map(record => record.get('post'))
|
||||
const posts = await updateDeletedPostsAttributes.records.map((record) => record.get('post'))
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(posts)
|
||||
await transaction.commit()
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
import { getDriver } from '../../db/neo4j'
|
||||
import { existsSync } from 'fs'
|
||||
|
||||
export const description = `
|
||||
In this review:
|
||||
https://github.com/Human-Connection/Human-Connection/pull/3262#discussion_r398634249
|
||||
I brought up that we may have image nodes with danling urls (urls that don't
|
||||
point to local file on disk). I would prefer to remove those urls to avoid
|
||||
unnecessary 404 errors.
|
||||
`
|
||||
|
||||
export async function up(next) {
|
||||
const driver = getDriver()
|
||||
const session = driver.session()
|
||||
const transaction = session.beginTransaction()
|
||||
|
||||
try {
|
||||
// Implement your migration here.
|
||||
const { records } = await transaction.run(`
|
||||
MATCH(image:Image)
|
||||
WHERE image.url STARTS WITH '/'
|
||||
RETURN image.url as url
|
||||
`)
|
||||
const urls = records.map((record) => record.get('url'))
|
||||
const danglingUrls = urls.filter((url) => {
|
||||
const fileLocation = `public${url}`
|
||||
return !existsSync(fileLocation)
|
||||
})
|
||||
await transaction.run(
|
||||
`
|
||||
MATCH(image:Image)
|
||||
WHERE image.url IN $danglingUrls
|
||||
DETACH DELETE image
|
||||
`,
|
||||
{ danglingUrls },
|
||||
)
|
||||
await transaction.commit()
|
||||
if (danglingUrls.length) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`
|
||||
Removed ${danglingUrls.length} dangling urls.\n
|
||||
===============================================
|
||||
${danglingUrls.join('\n')}
|
||||
`)
|
||||
}
|
||||
next()
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error)
|
||||
await transaction.rollback()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('rolled back')
|
||||
throw new Error(error)
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
}
|
||||
|
||||
export async function down() {
|
||||
throw new Error('Irreversible migration')
|
||||
}
|
||||
@ -9,7 +9,7 @@ import { gql } from '../helpers/jest'
|
||||
const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
|
||||
|
||||
/* eslint-disable no-multi-spaces */
|
||||
;(async function() {
|
||||
;(async function () {
|
||||
let authenticatedUser = null
|
||||
const driver = getDriver()
|
||||
const neode = getNeode()
|
||||
@ -598,7 +598,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
|
||||
}),
|
||||
])
|
||||
const [p2, p7, p8, p12] = await Promise.all(
|
||||
['p2', 'p7', 'p8', 'p12'].map(id => neode.find('Post', id)),
|
||||
['p2', 'p7', 'p8', 'p12'].map((id) => neode.find('Post', id)),
|
||||
)
|
||||
authenticatedUser = null
|
||||
|
||||
@ -928,7 +928,15 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
|
||||
trollingComment.update({ disabled: true, updatedAt: new Date().toISOString(), closed: true }),
|
||||
])
|
||||
|
||||
await Promise.all([...Array(30).keys()].map(() => Factory.build('user')))
|
||||
const additionalUsers = await Promise.all(
|
||||
[...Array(30).keys()].map(() => Factory.build('user')),
|
||||
)
|
||||
await Promise.all(
|
||||
additionalUsers.map(async (user) => {
|
||||
await jennyRostock.relateTo(user, 'following')
|
||||
await user.relateTo(jennyRostock, 'following')
|
||||
}),
|
||||
)
|
||||
|
||||
await Promise.all(
|
||||
[...Array(30).keys()].map(() =>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { hashSync } from 'bcryptjs'
|
||||
|
||||
export default function(args) {
|
||||
export default function (args) {
|
||||
args.encryptedPassword = hashSync(args.password, 10)
|
||||
delete args.password
|
||||
return args
|
||||
|
||||
@ -18,7 +18,7 @@ function walkRecursive(data, fields, callback, _key) {
|
||||
})
|
||||
} else if (data && typeof data === 'object') {
|
||||
// lets get some keys and stir them
|
||||
Object.keys(data).forEach(k => {
|
||||
Object.keys(data).forEach((k) => {
|
||||
data[k] = walkRecursive(data[k], fields, callback, k)
|
||||
})
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ export default async (driver, authorizationHeader) => {
|
||||
}
|
||||
const session = driver.session()
|
||||
|
||||
const writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const updateUserLastActiveTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (user:User {id: $id, deleted: false, disabled: false })
|
||||
@ -23,7 +23,7 @@ export default async (driver, authorizationHeader) => {
|
||||
`,
|
||||
{ id },
|
||||
)
|
||||
return updateUserLastActiveTransactionResponse.records.map(record => record.get('user'))
|
||||
return updateUserLastActiveTransactionResponse.records.map((record) => record.get('user'))
|
||||
})
|
||||
try {
|
||||
const [currentUser] = await writeTxResultPromise
|
||||
|
||||
@ -18,7 +18,7 @@ if (!hasEmailConfig) {
|
||||
console.log('Warning: Email middleware will not try to send mails.')
|
||||
}
|
||||
} else {
|
||||
sendMail = async templateArgs => {
|
||||
sendMail = async (templateArgs) => {
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: CONFIG.SMTP_HOST,
|
||||
port: CONFIG.SMTP_PORT,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
const readFile = fileName => fs.readFileSync(path.join(__dirname, fileName), 'utf-8')
|
||||
const readFile = (fileName) => fs.readFileSync(path.join(__dirname, fileName), 'utf-8')
|
||||
|
||||
export const signup = readFile('./signup.html')
|
||||
export const passwordReset = readFile('./resetPassword.html')
|
||||
|
||||
@ -8,7 +8,7 @@ import { exec, build } from 'xregexp/xregexp-all.js'
|
||||
// 2. If it starts with a digit '0-9' than a unicode letter has to follow.
|
||||
const regX = build('^((\\pL+[\\pL0-9]*)|([0-9]+\\pL+[\\pL0-9]*))$')
|
||||
|
||||
export default function(content) {
|
||||
export default function (content) {
|
||||
if (!content) return []
|
||||
const $ = cheerio.load(content)
|
||||
// We can not search for class '.hashtag', because the classes are removed at the 'xss' middleware.
|
||||
@ -19,7 +19,7 @@ export default function(content) {
|
||||
})
|
||||
.get()
|
||||
const hashtags = []
|
||||
ids.forEach(id => {
|
||||
ids.forEach((id) => {
|
||||
const match = exec(id, regX)
|
||||
if (match != null) {
|
||||
hashtags.push(match[1])
|
||||
|
||||
@ -5,7 +5,7 @@ const updateHashtagsOfPost = async (postId, hashtags, context) => {
|
||||
const session = context.driver.session()
|
||||
|
||||
try {
|
||||
await session.writeTransaction(txc => {
|
||||
await session.writeTransaction((txc) => {
|
||||
return txc.run(
|
||||
`
|
||||
MATCH (post:Post { id: $postId})
|
||||
|
||||
@ -2,21 +2,21 @@ import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
const _includeFieldsRecursively = (selectionSet, includedFields) => {
|
||||
if (!selectionSet) return
|
||||
includedFields.forEach(includedField => {
|
||||
includedFields.forEach((includedField) => {
|
||||
selectionSet.selections.unshift({
|
||||
kind: 'Field',
|
||||
name: { kind: 'Name', value: includedField },
|
||||
})
|
||||
})
|
||||
selectionSet.selections.forEach(selection => {
|
||||
selectionSet.selections.forEach((selection) => {
|
||||
_includeFieldsRecursively(selection.selectionSet, includedFields)
|
||||
})
|
||||
}
|
||||
|
||||
const includeFieldsRecursively = includedFields => {
|
||||
const includeFieldsRecursively = (includedFields) => {
|
||||
return (resolve, root, args, context, resolveInfo) => {
|
||||
const copy = cloneDeep(resolveInfo)
|
||||
copy.fieldNodes.forEach(fieldNode => {
|
||||
copy.fieldNodes.forEach((fieldNode) => {
|
||||
_includeFieldsRecursively(fieldNode.selectionSet, includedFields)
|
||||
})
|
||||
return resolve(root, args, context, copy)
|
||||
|
||||
@ -15,7 +15,7 @@ import hashtags from './hashtags/hashtagsMiddleware'
|
||||
import email from './email/emailMiddleware'
|
||||
import sentry from './sentryMiddleware'
|
||||
|
||||
export default schema => {
|
||||
export default (schema) => {
|
||||
const middlewares = {
|
||||
sentry,
|
||||
permissions,
|
||||
@ -51,7 +51,7 @@ export default schema => {
|
||||
// add permisions middleware at the first position (unless we're seeding)
|
||||
if (CONFIG.DISABLED_MIDDLEWARES) {
|
||||
const disabledMiddlewares = CONFIG.DISABLED_MIDDLEWARES.split(',')
|
||||
order = order.filter(key => {
|
||||
order = order.filter((key) => {
|
||||
if (disabledMiddlewares.includes(key)) {
|
||||
/* eslint-disable-next-line no-console */
|
||||
console.log(`Warning: Disabled "${disabledMiddlewares}" middleware.`)
|
||||
@ -60,6 +60,6 @@ export default schema => {
|
||||
})
|
||||
}
|
||||
|
||||
const appliedMiddlewares = order.map(key => middlewares[key])
|
||||
const appliedMiddlewares = order.map((key) => middlewares[key])
|
||||
return applyMiddleware(schema, ...appliedMiddlewares)
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import cheerio from 'cheerio'
|
||||
|
||||
export default content => {
|
||||
export default (content) => {
|
||||
if (!content) return []
|
||||
const $ = cheerio.load(content)
|
||||
const userIds = $('a.mention[data-mention-id]')
|
||||
@ -9,7 +9,7 @@ export default content => {
|
||||
})
|
||||
.get()
|
||||
return userIds
|
||||
.map(id => id.trim())
|
||||
.filter(id => !!id)
|
||||
.map((id) => id.trim())
|
||||
.filter((id) => !!id)
|
||||
.filter((id, index, allIds) => allIds.indexOf(id) === index)
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ const publishNotifications = async (...promises) => {
|
||||
const notifications = await Promise.all(promises)
|
||||
notifications
|
||||
.flat()
|
||||
.forEach(notificationAdded => pubsub.publish(NOTIFICATION_ADDED, { notificationAdded }))
|
||||
.forEach((notificationAdded) => pubsub.publish(NOTIFICATION_ADDED, { notificationAdded }))
|
||||
}
|
||||
|
||||
const handleContentDataOfPost = async (resolve, root, args, context, resolveInfo) => {
|
||||
@ -25,7 +25,7 @@ const handleContentDataOfComment = async (resolve, root, args, context, resolveI
|
||||
let idsOfUsers = extractMentionedUsers(content)
|
||||
const comment = await resolve(root, args, context, resolveInfo)
|
||||
const [postAuthor] = await postAuthorOfComment(comment.id, { context })
|
||||
idsOfUsers = idsOfUsers.filter(id => id !== postAuthor.id)
|
||||
idsOfUsers = idsOfUsers.filter((id) => id !== postAuthor.id)
|
||||
await publishNotifications(
|
||||
notifyUsersOfMention('Comment', comment.id, idsOfUsers, 'mentioned_in_comment', context),
|
||||
notifyUsersOfComment('Comment', comment.id, postAuthor.id, 'commented_on_post', context),
|
||||
@ -37,7 +37,7 @@ const postAuthorOfComment = async (commentId, { context }) => {
|
||||
const session = context.driver.session()
|
||||
let postAuthorId
|
||||
try {
|
||||
postAuthorId = await session.readTransaction(transaction => {
|
||||
postAuthorId = await session.readTransaction((transaction) => {
|
||||
return transaction.run(
|
||||
`
|
||||
MATCH (author:User)-[:WROTE]->(:Post)<-[:COMMENTS]-(:Comment { id: $commentId })
|
||||
@ -46,7 +46,7 @@ const postAuthorOfComment = async (commentId, { context }) => {
|
||||
{ commentId },
|
||||
)
|
||||
})
|
||||
return postAuthorId.records.map(record => record.get('authorId'))
|
||||
return postAuthorId.records.map((record) => record.get('authorId'))
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
@ -93,13 +93,13 @@ const notifyUsersOfMention = async (label, id, idsOfUsers, reason, context) => {
|
||||
RETURN notification {.*, from: finalResource, to: properties(user)}
|
||||
`
|
||||
const session = context.driver.session()
|
||||
const writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const notificationTransactionResponse = await transaction.run(mentionedCypher, {
|
||||
id,
|
||||
idsOfUsers,
|
||||
reason,
|
||||
})
|
||||
return notificationTransactionResponse.records.map(record => record.get('notification'))
|
||||
return notificationTransactionResponse.records.map((record) => record.get('notification'))
|
||||
})
|
||||
try {
|
||||
const notifications = await writeTxResultPromise
|
||||
@ -115,7 +115,7 @@ const notifyUsersOfComment = async (label, commentId, postAuthorId, reason, cont
|
||||
if (context.user.id === postAuthorId) return []
|
||||
await validateNotifyUsers(label, reason)
|
||||
const session = context.driver.session()
|
||||
const writeTxResultPromise = await session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = await session.writeTransaction(async (transaction) => {
|
||||
const notificationTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (postAuthor:User {id: $postAuthorId})-[:WROTE]->(post:Post)<-[:COMMENTS]-(comment:Comment { id: $commentId })<-[:WROTE]-(commenter:User)
|
||||
@ -130,7 +130,7 @@ const notifyUsersOfComment = async (label, commentId, postAuthorId, reason, cont
|
||||
`,
|
||||
{ commentId, postAuthorId, reason },
|
||||
)
|
||||
return notificationTransactionResponse.records.map(record => record.get('notification'))
|
||||
return notificationTransactionResponse.records.map((record) => record.get('notification'))
|
||||
})
|
||||
try {
|
||||
const notifications = await writeTxResultPromise
|
||||
|
||||
@ -47,7 +47,7 @@ const isAuthor = rule({
|
||||
if (!user) return false
|
||||
const { id: resourceId } = args
|
||||
const session = driver.session()
|
||||
const authorReadTxPromise = session.readTransaction(async transaction => {
|
||||
const authorReadTxPromise = session.readTransaction(async (transaction) => {
|
||||
const authorTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (resource {id: $resourceId})<-[:WROTE]-(author {id: $userId})
|
||||
@ -55,7 +55,7 @@ const isAuthor = rule({
|
||||
`,
|
||||
{ resourceId, userId: user.id },
|
||||
)
|
||||
return authorTransactionResponse.records.map(record => record.get('author'))
|
||||
return authorTransactionResponse.records.map((record) => record.get('author'))
|
||||
})
|
||||
try {
|
||||
const [author] = await authorReadTxPromise
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import uniqueSlug from './slugify/uniqueSlug'
|
||||
|
||||
const isUniqueFor = (context, type) => {
|
||||
return async slug => {
|
||||
return async (slug) => {
|
||||
const session = context.driver.session()
|
||||
try {
|
||||
const existingSlug = await session.readTransaction(transaction => {
|
||||
const existingSlug = await session.readTransaction((transaction) => {
|
||||
return transaction.run(
|
||||
`
|
||||
MATCH(p:${type} {slug: $slug })
|
||||
|
||||
@ -9,10 +9,7 @@ describe('uniqueSlug', () => {
|
||||
|
||||
it('increments slugified string until unique', () => {
|
||||
const string = 'Hello World'
|
||||
const isUnique = jest
|
||||
.fn()
|
||||
.mockResolvedValueOnce(false)
|
||||
.mockResolvedValueOnce(true)
|
||||
const isUnique = jest.fn().mockResolvedValueOnce(false).mockResolvedValueOnce(true)
|
||||
expect(uniqueSlug(string, isUnique)).resolves.toEqual('hello-world-1')
|
||||
})
|
||||
|
||||
|
||||
@ -121,7 +121,7 @@ describe('slugifyMiddleware', () => {
|
||||
})
|
||||
|
||||
describe('but if the client specifies a slug', () => {
|
||||
it('rejects CreatePost', async done => {
|
||||
it('rejects CreatePost', async (done) => {
|
||||
variables = {
|
||||
...variables,
|
||||
title: 'Pre-existing post',
|
||||
|
||||
@ -14,7 +14,7 @@ const validateCreateComment = async (resolve, root, args, context, info) => {
|
||||
}
|
||||
const session = context.driver.session()
|
||||
try {
|
||||
const postQueryRes = await session.readTransaction(transaction => {
|
||||
const postQueryRes = await session.readTransaction((transaction) => {
|
||||
return transaction.run(
|
||||
`
|
||||
MATCH (post:Post {id: $postId})
|
||||
@ -23,7 +23,7 @@ const validateCreateComment = async (resolve, root, args, context, info) => {
|
||||
{ postId },
|
||||
)
|
||||
})
|
||||
const [post] = postQueryRes.records.map(record => {
|
||||
const [post] = postQueryRes.records.map((record) => {
|
||||
return record.get('post')
|
||||
})
|
||||
|
||||
@ -73,7 +73,7 @@ const validateReview = async (resolve, root, args, context, info) => {
|
||||
const { user, driver } = context
|
||||
if (resourceId === user.id) throw new Error('You cannot review yourself!')
|
||||
const session = driver.session()
|
||||
const reportReadTxPromise = session.readTransaction(async transaction => {
|
||||
const reportReadTxPromise = session.readTransaction(async (transaction) => {
|
||||
const validateReviewTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (resource {id: $resourceId})
|
||||
@ -87,7 +87,7 @@ const validateReview = async (resolve, root, args, context, info) => {
|
||||
submitterId: user.id,
|
||||
},
|
||||
)
|
||||
return validateReviewTransactionResponse.records.map(record => ({
|
||||
return validateReviewTransactionResponse.records.map((record) => ({
|
||||
label: record.get('label'),
|
||||
author: record.get('author'),
|
||||
filed: record.get('filed'),
|
||||
|
||||
@ -28,7 +28,7 @@ describe('slug', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('must be unique', async done => {
|
||||
it('must be unique', async (done) => {
|
||||
await neode.create('User', { slug: 'Matt' })
|
||||
try {
|
||||
await expect(neode.create('User', { slug: 'Matt' })).rejects.toThrow('already exists')
|
||||
@ -52,8 +52,8 @@ describe('slug', () => {
|
||||
})
|
||||
|
||||
describe('characters', () => {
|
||||
const createUser = attrs => {
|
||||
return neode.create('User', attrs).then(user => user.toJson())
|
||||
const createUser = (attrs) => {
|
||||
return neode.create('User', attrs).then((user) => user.toJson())
|
||||
}
|
||||
|
||||
it('-', async () => {
|
||||
|
||||
@ -15,7 +15,7 @@ export default {
|
||||
|
||||
const session = driver.session()
|
||||
|
||||
const writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const createCommentTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (post:Post {id: $postId})
|
||||
@ -30,7 +30,7 @@ export default {
|
||||
{ userId: user.id, postId, params },
|
||||
)
|
||||
return createCommentTransactionResponse.records.map(
|
||||
record => record.get('comment').properties,
|
||||
(record) => record.get('comment').properties,
|
||||
)
|
||||
})
|
||||
try {
|
||||
@ -42,7 +42,7 @@ export default {
|
||||
},
|
||||
UpdateComment: async (_parent, params, context, _resolveInfo) => {
|
||||
const session = context.driver.session()
|
||||
const writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const updateCommentTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (comment:Comment {id: $params.id})
|
||||
@ -53,7 +53,7 @@ export default {
|
||||
{ params },
|
||||
)
|
||||
return updateCommentTransactionResponse.records.map(
|
||||
record => record.get('comment').properties,
|
||||
(record) => record.get('comment').properties,
|
||||
)
|
||||
})
|
||||
try {
|
||||
@ -65,7 +65,7 @@ export default {
|
||||
},
|
||||
DeleteComment: async (_parent, args, context, _resolveInfo) => {
|
||||
const session = context.driver.session()
|
||||
const writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const deleteCommentTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (comment:Comment {id: $commentId})
|
||||
@ -77,7 +77,7 @@ export default {
|
||||
{ commentId: args.id },
|
||||
)
|
||||
return deleteCommentTransactionResponse.records.map(
|
||||
record => record.get('comment').properties,
|
||||
(record) => record.get('comment').properties,
|
||||
)
|
||||
})
|
||||
try {
|
||||
|
||||
@ -4,7 +4,7 @@ export default {
|
||||
const { driver } = context
|
||||
let donations
|
||||
const session = driver.session()
|
||||
const writeTxResultPromise = session.writeTransaction(async txc => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (txc) => {
|
||||
const updateDonationsTransactionResponse = await txc.run(
|
||||
`
|
||||
MATCH (donations:Donations)
|
||||
@ -16,7 +16,7 @@ export default {
|
||||
{ params },
|
||||
)
|
||||
return updateDonationsTransactionResponse.records.map(
|
||||
record => record.get('donations').properties,
|
||||
(record) => record.get('donations').properties,
|
||||
)
|
||||
})
|
||||
try {
|
||||
|
||||
@ -27,7 +27,7 @@ export default {
|
||||
} = context
|
||||
|
||||
const session = context.driver.session()
|
||||
const writeTxResultPromise = session.writeTransaction(async txc => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (txc) => {
|
||||
const result = await txc.run(
|
||||
`
|
||||
MATCH (user:User {id: $userId})
|
||||
@ -37,7 +37,7 @@ export default {
|
||||
`,
|
||||
{ userId, email: args.email, nonce },
|
||||
)
|
||||
return result.records.map(record => ({
|
||||
return result.records.map((record) => ({
|
||||
name: record.get('user').properties.name,
|
||||
...record.get('email').properties,
|
||||
}))
|
||||
@ -57,7 +57,7 @@ export default {
|
||||
} = context
|
||||
const { nonce, email } = args
|
||||
const session = context.driver.session()
|
||||
const writeTxResultPromise = session.writeTransaction(async txc => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (txc) => {
|
||||
const result = await txc.run(
|
||||
`
|
||||
MATCH (user:User {id: $userId})-[:PRIMARY_EMAIL]->(previous:EmailAddress)
|
||||
@ -71,7 +71,7 @@ export default {
|
||||
`,
|
||||
{ userId, email, nonce },
|
||||
)
|
||||
return result.records.map(record => record.get('email').properties)
|
||||
return result.records.map((record) => record.get('email').properties)
|
||||
})
|
||||
try {
|
||||
const txResult = await writeTxResultPromise
|
||||
|
||||
@ -48,7 +48,7 @@ describe('Query', () => {
|
||||
let embedAction
|
||||
|
||||
beforeEach(() => {
|
||||
embedAction = async variables => {
|
||||
embedAction = async (variables) => {
|
||||
const { server } = createServer({
|
||||
context: () => {},
|
||||
})
|
||||
|
||||
@ -12,11 +12,11 @@ let oEmbedProvidersFile = fs.readFileSync(
|
||||
oEmbedProvidersFile = oEmbedProvidersFile.replace(/\{format\}/g, 'json')
|
||||
const oEmbedProviders = JSON.parse(oEmbedProvidersFile)
|
||||
|
||||
export default function(embedUrl) {
|
||||
export default function (embedUrl) {
|
||||
for (const provider of oEmbedProviders) {
|
||||
for (const endpoint of provider.endpoints) {
|
||||
const { schemes = [], url } = endpoint
|
||||
if (schemes.some(scheme => minimatch(embedUrl, scheme))) return url
|
||||
if (schemes.some((scheme) => minimatch(embedUrl, scheme))) return url
|
||||
}
|
||||
const { hostname } = new URL(embedUrl)
|
||||
if (provider.provider_url.includes(hostname)) {
|
||||
|
||||
@ -29,7 +29,7 @@ const metascraper = Metascraper([
|
||||
// require('./rules/metascraper-embed')()
|
||||
])
|
||||
|
||||
const fetchEmbed = async url => {
|
||||
const fetchEmbed = async (url) => {
|
||||
let endpointUrl = findProvider(url)
|
||||
if (!endpointUrl) return {}
|
||||
endpointUrl = new URL(endpointUrl)
|
||||
@ -53,7 +53,7 @@ const fetchEmbed = async url => {
|
||||
}
|
||||
}
|
||||
|
||||
const fetchResource = async url => {
|
||||
const fetchResource = async (url) => {
|
||||
const response = await fetch(url)
|
||||
const html = await response.text()
|
||||
const resource = await metascraper({ html, url })
|
||||
|
||||
@ -81,7 +81,7 @@ beforeEach(async () => {
|
||||
email: 'test@example.org',
|
||||
password: '1234',
|
||||
},
|
||||
).then(user => user.toJson())
|
||||
).then((user) => user.toJson())
|
||||
user2 = await Factory.build(
|
||||
'user',
|
||||
{
|
||||
@ -92,7 +92,7 @@ beforeEach(async () => {
|
||||
email: 'test2@example.org',
|
||||
password: '1234',
|
||||
},
|
||||
).then(user => user.toJson())
|
||||
).then((user) => user.toJson())
|
||||
|
||||
authenticatedUser = user1
|
||||
variables = { id: user2.id }
|
||||
@ -146,7 +146,7 @@ describe('follow', () => {
|
||||
{ id: 'u1' },
|
||||
)
|
||||
const relationshipProperties = relation.records.map(
|
||||
record => record.get('relationship').properties.createdAt,
|
||||
(record) => record.get('relationship').properties.createdAt,
|
||||
)
|
||||
expect(relationshipProperties[0]).toEqual(expect.any(String))
|
||||
})
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import log from './databaseLogger'
|
||||
|
||||
export const undefinedToNullResolver = list => {
|
||||
export const undefinedToNullResolver = (list) => {
|
||||
const resolvers = {}
|
||||
list.forEach(key => {
|
||||
resolvers[key] = async parent => {
|
||||
list.forEach((key) => {
|
||||
resolvers[key] = async (parent) => {
|
||||
return typeof parent[key] === 'undefined' ? null : parent[key]
|
||||
}
|
||||
})
|
||||
@ -25,14 +25,14 @@ export default function Resolver(type, options = {}) {
|
||||
if (typeof parent[key] !== 'undefined') return parent[key]
|
||||
const id = parent[idAttribute]
|
||||
const session = driver.session()
|
||||
const readTxResultPromise = session.readTransaction(async txc => {
|
||||
const readTxResultPromise = session.readTransaction(async (txc) => {
|
||||
const cypher = `
|
||||
MATCH(:${type} {${idAttribute}: $id})${connection}
|
||||
RETURN related {.*} as related
|
||||
`
|
||||
const result = await txc.run(cypher, { id, cypherParams })
|
||||
log(result)
|
||||
return result.records.map(r => r.get('related'))
|
||||
return result.records.map((r) => r.get('related'))
|
||||
})
|
||||
try {
|
||||
let response = await readTxResultPromise
|
||||
@ -44,19 +44,19 @@ export default function Resolver(type, options = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
const booleanResolver = obj => {
|
||||
const booleanResolver = (obj) => {
|
||||
const resolvers = {}
|
||||
for (const [key, condition] of Object.entries(obj)) {
|
||||
resolvers[key] = async (parent, params, { cypherParams, driver }, resolveInfo) => {
|
||||
if (typeof parent[key] !== 'undefined') return parent[key]
|
||||
const id = parent[idAttribute]
|
||||
const session = driver.session()
|
||||
const readTxResultPromise = session.readTransaction(async txc => {
|
||||
const readTxResultPromise = session.readTransaction(async (txc) => {
|
||||
const nodeCondition = condition.replace('this', 'this {id: $id}')
|
||||
const cypher = `${nodeCondition} as ${key}`
|
||||
const result = await txc.run(cypher, { id, cypherParams })
|
||||
log(result)
|
||||
const [response] = result.records.map(r => r.get(key))
|
||||
const [response] = result.records.map((r) => r.get(key))
|
||||
return response
|
||||
})
|
||||
try {
|
||||
@ -69,13 +69,13 @@ export default function Resolver(type, options = {}) {
|
||||
return resolvers
|
||||
}
|
||||
|
||||
const countResolver = obj => {
|
||||
const countResolver = (obj) => {
|
||||
const resolvers = {}
|
||||
for (const [key, connection] of Object.entries(obj)) {
|
||||
resolvers[key] = async (parent, params, { driver, cypherParams }, resolveInfo) => {
|
||||
if (typeof parent[key] !== 'undefined') return parent[key]
|
||||
const session = driver.session()
|
||||
const readTxResultPromise = session.readTransaction(async txc => {
|
||||
const readTxResultPromise = session.readTransaction(async (txc) => {
|
||||
const id = parent[idAttribute]
|
||||
const cypher = `
|
||||
MATCH(u:${type} {${idAttribute}: $id})${connection}
|
||||
@ -83,7 +83,7 @@ export default function Resolver(type, options = {}) {
|
||||
`
|
||||
const result = await txc.run(cypher, { id, cypherParams })
|
||||
log(result)
|
||||
const [response] = result.records.map(r => r.get('count').toNumber())
|
||||
const [response] = result.records.map((r) => r.get('count').toNumber())
|
||||
return response
|
||||
})
|
||||
try {
|
||||
@ -96,7 +96,7 @@ export default function Resolver(type, options = {}) {
|
||||
return resolvers
|
||||
}
|
||||
|
||||
const hasManyResolver = obj => {
|
||||
const hasManyResolver = (obj) => {
|
||||
const resolvers = {}
|
||||
for (const [key, connection] of Object.entries(obj)) {
|
||||
resolvers[key] = _hasResolver(resolvers, { key, connection }, { returnType: 'iterable' })
|
||||
@ -104,7 +104,7 @@ export default function Resolver(type, options = {}) {
|
||||
return resolvers
|
||||
}
|
||||
|
||||
const hasOneResolver = obj => {
|
||||
const hasOneResolver = (obj) => {
|
||||
const resolvers = {}
|
||||
for (const [key, connection] of Object.entries(obj)) {
|
||||
resolvers[key] = _hasResolver(resolvers, { key, connection }, { returnType: 'object' })
|
||||
|
||||
@ -5,7 +5,7 @@ export default async function createPasswordReset(options) {
|
||||
const normalizedEmail = normalizeEmail(email)
|
||||
const session = driver.session()
|
||||
try {
|
||||
const createPasswordResetTxPromise = session.writeTransaction(async transaction => {
|
||||
const createPasswordResetTxPromise = session.writeTransaction(async (transaction) => {
|
||||
const createPasswordResetTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (user:User)-[:PRIMARY_EMAIL]->(email:EmailAddress {email:$email})
|
||||
@ -19,7 +19,7 @@ export default async function createPasswordReset(options) {
|
||||
email: normalizedEmail,
|
||||
},
|
||||
)
|
||||
return createPasswordResetTransactionResponse.records.map(record => {
|
||||
return createPasswordResetTransactionResponse.records.map((record) => {
|
||||
const { email } = record.get('email').properties
|
||||
const { nonce } = record.get('passwordReset').properties
|
||||
const { name } = record.get('user').properties
|
||||
|
||||
@ -3,7 +3,7 @@ import { UserInputError } from 'apollo-server'
|
||||
export default async function alreadyExistingMail({ args, context }) {
|
||||
const session = context.driver.session()
|
||||
try {
|
||||
const existingEmailAddressTxPromise = session.writeTransaction(async transaction => {
|
||||
const existingEmailAddressTxPromise = session.writeTransaction(async (transaction) => {
|
||||
const existingEmailAddressTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (email:EmailAddress {email: $email})
|
||||
@ -12,7 +12,7 @@ export default async function alreadyExistingMail({ args, context }) {
|
||||
`,
|
||||
{ email: args.email },
|
||||
)
|
||||
return existingEmailAddressTransactionResponse.records.map(record => {
|
||||
return existingEmailAddressTransactionResponse.records.map((record) => {
|
||||
return {
|
||||
alreadyExistingEmail: record.get('email').properties,
|
||||
user: record.get('user') && record.get('user').properties,
|
||||
|
||||
@ -4,7 +4,7 @@ import { mergeWith, isArray } from 'lodash'
|
||||
export const filterForMutedUsers = async (params, context) => {
|
||||
if (!context.user) return params
|
||||
const [mutedUsers] = await Promise.all([getMutedUsers(context)])
|
||||
const mutedUsersIds = [...mutedUsers.map(user => user.id)]
|
||||
const mutedUsersIds = [...mutedUsers.map((user) => user.id)]
|
||||
if (!mutedUsersIds.length) return params
|
||||
|
||||
params.filter = mergeWith(
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { normalizeEmail } from 'validator'
|
||||
|
||||
export default email =>
|
||||
export default (email) =>
|
||||
normalizeEmail(email, {
|
||||
// gmail_remove_dots: true, default
|
||||
gmail_remove_subaddress: false,
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
import path from 'path'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
import { S3 } from 'aws-sdk'
|
||||
import slug from 'slug'
|
||||
import { existsSync, unlinkSync, createWriteStream } from 'fs'
|
||||
import { getDriver } from '../../../db/neo4j'
|
||||
import { UserInputError } from 'apollo-server'
|
||||
import { getDriver } from '../../../db/neo4j'
|
||||
import { s3Configs } from '../../../config'
|
||||
|
||||
// const widths = [34, 160, 320, 640, 1024]
|
||||
const { AWS_ENDPOINT: endpoint, AWS_REGION: region, AWS_BUCKET: Bucket, S3_CONFIGURED } = s3Configs
|
||||
|
||||
export async function deleteImage(resource, relationshipType, opts = {}) {
|
||||
sanitizeRelationshipType(relationshipType)
|
||||
@ -20,7 +23,7 @@ export async function deleteImage(resource, relationshipType, opts = {}) {
|
||||
`,
|
||||
{ resource },
|
||||
)
|
||||
const [image] = txResult.records.map(record => record.get('imageProps'))
|
||||
const [image] = txResult.records.map((record) => record.get('imageProps'))
|
||||
// This behaviour differs from `mergeImage`. If you call `mergeImage`
|
||||
// with metadata for an image that does not exist, it's an indicator
|
||||
// of an error (so throw an error). If we bulk delete an image, it
|
||||
@ -45,7 +48,7 @@ export async function mergeImage(resource, relationshipType, imageInput, opts =
|
||||
`,
|
||||
{ resource },
|
||||
)
|
||||
const [existingImage] = txResult.records.map(record => record.get('image'))
|
||||
const [existingImage] = txResult.records.map((record) => record.get('image'))
|
||||
const { upload } = imageInput
|
||||
if (!(existingImage || upload)) throw new UserInputError('Cannot find image for given resource')
|
||||
if (existingImage && upload) deleteImageFile(existingImage, deleteCallback)
|
||||
@ -63,14 +66,14 @@ export async function mergeImage(resource, relationshipType, imageInput, opts =
|
||||
`,
|
||||
{ resource, image },
|
||||
)
|
||||
const [mergedImage] = txResult.records.map(record => record.get('image'))
|
||||
const [mergedImage] = txResult.records.map((record) => record.get('image'))
|
||||
return mergedImage
|
||||
}
|
||||
|
||||
const wrapTransaction = async (wrappedCallback, args, opts) => {
|
||||
const session = getDriver().session()
|
||||
try {
|
||||
const result = await session.writeTransaction(async transaction => {
|
||||
const result = await session.writeTransaction(async (transaction) => {
|
||||
return wrappedCallback(...args, { ...opts, transaction })
|
||||
})
|
||||
return result
|
||||
@ -79,26 +82,27 @@ const wrapTransaction = async (wrappedCallback, args, opts) => {
|
||||
}
|
||||
}
|
||||
|
||||
const deleteImageFile = (image, deleteCallback = localFileDelete) => {
|
||||
const deleteImageFile = (image, deleteCallback) => {
|
||||
if (!deleteCallback) {
|
||||
deleteCallback = S3_CONFIGURED ? s3Delete : localFileDelete
|
||||
}
|
||||
const { url } = image
|
||||
deleteCallback(url)
|
||||
return url
|
||||
}
|
||||
|
||||
const uploadImageFile = async (upload, uploadCallback = localFileUpload) => {
|
||||
const uploadImageFile = async (upload, uploadCallback) => {
|
||||
if (!upload) return undefined
|
||||
if (!uploadCallback) {
|
||||
uploadCallback = S3_CONFIGURED ? s3Upload : localFileUpload
|
||||
}
|
||||
const { createReadStream, filename, mimetype } = await upload
|
||||
const { name, ext } = path.parse(filename)
|
||||
const uniqueFilename = `${uuid()}-${slug(name)}${ext}`
|
||||
|
||||
return uploadCallback({
|
||||
createReadStream,
|
||||
destination: `/uploads/${uniqueFilename}`,
|
||||
mimetype,
|
||||
})
|
||||
return uploadCallback({ createReadStream, uniqueFilename, mimetype })
|
||||
}
|
||||
|
||||
const sanitizeRelationshipType = relationshipType => {
|
||||
const sanitizeRelationshipType = (relationshipType) => {
|
||||
// Cypher query language does not allow to parameterize relationship types
|
||||
// See: https://github.com/neo4j/neo4j/issues/340
|
||||
if (!['HERO_IMAGE', 'AVATAR_IMAGE'].includes(relationshipType)) {
|
||||
@ -106,7 +110,8 @@ const sanitizeRelationshipType = relationshipType => {
|
||||
}
|
||||
}
|
||||
|
||||
const localFileUpload = ({ createReadStream, destination }) => {
|
||||
const localFileUpload = ({ createReadStream, uniqueFilename }) => {
|
||||
const destination = `/uploads/${uniqueFilename}`
|
||||
return new Promise((resolve, reject) =>
|
||||
createReadStream()
|
||||
.pipe(createWriteStream(`public${destination}`))
|
||||
@ -115,7 +120,34 @@ const localFileUpload = ({ createReadStream, destination }) => {
|
||||
)
|
||||
}
|
||||
|
||||
const localFileDelete = async url => {
|
||||
const s3Upload = async ({ createReadStream, uniqueFilename, mimetype }) => {
|
||||
const s3 = new S3({ region, endpoint })
|
||||
const s3Location = `original/${uniqueFilename}`
|
||||
|
||||
const params = {
|
||||
Bucket,
|
||||
Key: s3Location,
|
||||
ACL: 'public-read',
|
||||
ContentType: mimetype,
|
||||
Body: createReadStream(),
|
||||
}
|
||||
const data = await s3.upload(params).promise()
|
||||
const { Location } = data
|
||||
return Location
|
||||
}
|
||||
|
||||
const localFileDelete = async (url) => {
|
||||
const location = `public${url}`
|
||||
if (existsSync(location)) unlinkSync(location)
|
||||
}
|
||||
|
||||
const s3Delete = async (url) => {
|
||||
const s3 = new S3({ region, endpoint })
|
||||
let { pathname } = new URL(url, 'http://example.org') // dummy domain to avoid invalid URL error
|
||||
pathname = pathname.substring(1) // remove first character '/'
|
||||
const params = {
|
||||
Bucket,
|
||||
Key: pathname,
|
||||
}
|
||||
await s3.deleteObject(params).promise()
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ let deleteCallback
|
||||
|
||||
beforeEach(async () => {
|
||||
await cleanDatabase()
|
||||
uploadCallback = jest.fn(({ destination }) => destination)
|
||||
uploadCallback = jest.fn(({ uniqueFilename }) => `/uploads/${uniqueFilename}`)
|
||||
deleteCallback = jest.fn()
|
||||
})
|
||||
|
||||
@ -50,13 +50,13 @@ describe('deleteImage', () => {
|
||||
const session = driver.session()
|
||||
let someString
|
||||
try {
|
||||
someString = await session.writeTransaction(async transaction => {
|
||||
someString = await session.writeTransaction(async (transaction) => {
|
||||
await deleteImage(user, 'AVATAR_IMAGE', {
|
||||
deleteCallback,
|
||||
transaction,
|
||||
})
|
||||
const txResult = await transaction.run('RETURN "Hello" as result')
|
||||
const [result] = txResult.records.map(record => record.get('result'))
|
||||
const [result] = txResult.records.map((record) => record.get('result'))
|
||||
return result
|
||||
})
|
||||
} finally {
|
||||
@ -66,11 +66,11 @@ describe('deleteImage', () => {
|
||||
await expect(someString).toEqual('Hello')
|
||||
})
|
||||
|
||||
it('rolls back the transaction in case of errors', async done => {
|
||||
it('rolls back the transaction in case of errors', async (done) => {
|
||||
await expect(neode.all('Image')).resolves.toHaveLength(1)
|
||||
const session = driver.session()
|
||||
try {
|
||||
await session.writeTransaction(async transaction => {
|
||||
await session.writeTransaction(async (transaction) => {
|
||||
await deleteImage(user, 'AVATAR_IMAGE', {
|
||||
deleteCallback,
|
||||
transaction,
|
||||
@ -99,34 +99,34 @@ describe('mergeImage', () => {
|
||||
}
|
||||
})
|
||||
|
||||
describe('on existing resource', () => {
|
||||
beforeEach(async () => {
|
||||
post = await Factory.build(
|
||||
'post',
|
||||
{ id: 'p99' },
|
||||
{
|
||||
author: Factory.build('user', {}, { avatar: null }),
|
||||
image: null,
|
||||
describe('given image.upload', () => {
|
||||
beforeEach(() => {
|
||||
imageInput = {
|
||||
...imageInput,
|
||||
upload: {
|
||||
filename: 'image.jpg',
|
||||
mimetype: 'image/jpeg',
|
||||
encoding: '7bit',
|
||||
createReadStream: () => ({
|
||||
pipe: () => ({
|
||||
on: (_, callback) => callback(),
|
||||
}),
|
||||
}),
|
||||
},
|
||||
)
|
||||
post = await post.toJson()
|
||||
}
|
||||
})
|
||||
|
||||
describe('given image.upload', () => {
|
||||
beforeEach(() => {
|
||||
imageInput = {
|
||||
...imageInput,
|
||||
upload: {
|
||||
filename: 'image.jpg',
|
||||
mimetype: 'image/jpeg',
|
||||
encoding: '7bit',
|
||||
createReadStream: () => ({
|
||||
pipe: () => ({
|
||||
on: (_, callback) => callback(),
|
||||
}),
|
||||
}),
|
||||
describe('on existing resource', () => {
|
||||
beforeEach(async () => {
|
||||
post = await Factory.build(
|
||||
'post',
|
||||
{ id: 'p99' },
|
||||
{
|
||||
author: Factory.build('user', {}, { avatar: null }),
|
||||
image: null,
|
||||
},
|
||||
}
|
||||
)
|
||||
post = await post.toJson()
|
||||
})
|
||||
|
||||
it('returns new image', async () => {
|
||||
@ -203,7 +203,7 @@ describe('mergeImage', () => {
|
||||
it('executes cypher statements within the transaction', async () => {
|
||||
const session = driver.session()
|
||||
try {
|
||||
await session.writeTransaction(async transaction => {
|
||||
await session.writeTransaction(async (transaction) => {
|
||||
const image = await mergeImage(post, 'HERO_IMAGE', imageInput, {
|
||||
uploadCallback,
|
||||
deleteCallback,
|
||||
@ -227,10 +227,10 @@ describe('mergeImage', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('rolls back the transaction in case of errors', async done => {
|
||||
it('rolls back the transaction in case of errors', async (done) => {
|
||||
const session = driver.session()
|
||||
try {
|
||||
await session.writeTransaction(async transaction => {
|
||||
await session.writeTransaction(async (transaction) => {
|
||||
const image = await mergeImage(post, 'HERO_IMAGE', imageInput, {
|
||||
uploadCallback,
|
||||
deleteCallback,
|
||||
@ -330,7 +330,7 @@ describe('mergeImage', () => {
|
||||
})
|
||||
|
||||
it('updates metadata', async () => {
|
||||
await mergeImage(post, 'HERO_IMAGE', imageInput)
|
||||
await mergeImage(post, 'HERO_IMAGE', imageInput, { uploadCallback, deleteCallback })
|
||||
const images = await neode.all('Image')
|
||||
expect(images).toHaveLength(1)
|
||||
await expect(images.first().toJson()).resolves.toMatchObject({
|
||||
|
||||
@ -21,14 +21,14 @@ export default {
|
||||
WITH review, report, resource {.*, __typename: labels(resource)[0]} AS finalResource
|
||||
RETURN review {.*, report: properties(report), resource: properties(finalResource)}
|
||||
`
|
||||
const reviewWriteTxResultPromise = session.writeTransaction(async txc => {
|
||||
const reviewWriteTxResultPromise = session.writeTransaction(async (txc) => {
|
||||
const reviewTransactionResponse = await txc.run(cypher, {
|
||||
params,
|
||||
moderatorId: moderator.id,
|
||||
dateTime: new Date().toISOString(),
|
||||
})
|
||||
log(reviewTransactionResponse)
|
||||
return reviewTransactionResponse.records.map(record => record.get('review'))
|
||||
return reviewTransactionResponse.records.map((record) => record.get('review'))
|
||||
})
|
||||
const [reviewed] = await reviewWriteTxResultPromise
|
||||
return reviewed || null
|
||||
|
||||
@ -42,7 +42,7 @@ export default {
|
||||
const offset = args.offset && typeof args.offset === 'number' ? `SKIP ${args.offset}` : ''
|
||||
const limit = args.first && typeof args.first === 'number' ? `LIMIT ${args.first}` : ''
|
||||
|
||||
const readTxResultPromise = session.readTransaction(async transaction => {
|
||||
const readTxResultPromise = session.readTransaction(async (transaction) => {
|
||||
const notificationsTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (resource {deleted: false, disabled: false})-[notification:NOTIFIED]->(user:User {id:$id})
|
||||
@ -59,7 +59,7 @@ export default {
|
||||
{ id: currentUser.id },
|
||||
)
|
||||
log(notificationsTransactionResponse)
|
||||
return notificationsTransactionResponse.records.map(record => record.get('notification'))
|
||||
return notificationsTransactionResponse.records.map((record) => record.get('notification'))
|
||||
})
|
||||
try {
|
||||
const notifications = await readTxResultPromise
|
||||
@ -73,7 +73,7 @@ export default {
|
||||
markAsRead: async (parent, args, context, resolveInfo) => {
|
||||
const { user: currentUser } = context
|
||||
const session = context.driver.session()
|
||||
const writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const markNotificationAsReadTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (resource {id: $resourceId})-[notification:NOTIFIED {read: FALSE}]->(user:User {id:$id})
|
||||
@ -88,7 +88,7 @@ export default {
|
||||
{ resourceId: args.id, id: currentUser.id },
|
||||
)
|
||||
log(markNotificationAsReadTransactionResponse)
|
||||
return markNotificationAsReadTransactionResponse.records.map(record =>
|
||||
return markNotificationAsReadTransactionResponse.records.map((record) =>
|
||||
record.get('notification'),
|
||||
)
|
||||
})
|
||||
@ -101,7 +101,7 @@ export default {
|
||||
},
|
||||
},
|
||||
NOTIFIED: {
|
||||
id: async parent => {
|
||||
id: async (parent) => {
|
||||
// serialize an ID to help the client update the cache
|
||||
return `${parent.reason}/${parent.from.id}/${parent.to.id}`
|
||||
},
|
||||
|
||||
@ -14,7 +14,7 @@ export default {
|
||||
const encryptedNewPassword = await bcrypt.hashSync(newPassword, 10)
|
||||
const session = driver.session()
|
||||
try {
|
||||
const passwordResetTxPromise = session.writeTransaction(async transaction => {
|
||||
const passwordResetTxPromise = session.writeTransaction(async (transaction) => {
|
||||
const passwordResetTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (passwordReset:PasswordReset {nonce: $nonce})
|
||||
@ -32,7 +32,9 @@ export default {
|
||||
encryptedNewPassword,
|
||||
},
|
||||
)
|
||||
return passwordResetTransactionResponse.records.map(record => record.get('passwordReset'))
|
||||
return passwordResetTransactionResponse.records.map((record) =>
|
||||
record.get('passwordReset'),
|
||||
)
|
||||
})
|
||||
const [reset] = await passwordResetTxPromise
|
||||
return !!(reset && reset.properties.usedAt)
|
||||
|
||||
@ -16,7 +16,7 @@ const getAllPasswordResets = async () => {
|
||||
const passwordResetQuery = await neode.cypher(
|
||||
'MATCH (passwordReset:PasswordReset) RETURN passwordReset',
|
||||
)
|
||||
const resets = passwordResetQuery.records.map(record => record.get('passwordReset'))
|
||||
const resets = passwordResetQuery.records.map((record) => record.get('passwordReset'))
|
||||
return resets
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import { mergeImage, deleteImage } from './images/images'
|
||||
import Resolver from './helpers/Resolver'
|
||||
import { filterForMutedUsers } from './helpers/filterForMutedUsers'
|
||||
|
||||
const maintainPinnedPosts = params => {
|
||||
const maintainPinnedPosts = (params) => {
|
||||
const pinnedPostFilter = { pinned: true }
|
||||
if (isEmpty(params.filter)) {
|
||||
params.filter = { OR: [pinnedPostFilter, {}] }
|
||||
@ -34,7 +34,7 @@ export default {
|
||||
PostsEmotionsCountByEmotion: async (object, params, context, resolveInfo) => {
|
||||
const { postId, data } = params
|
||||
const session = context.driver.session()
|
||||
const readTxResultPromise = session.readTransaction(async transaction => {
|
||||
const readTxResultPromise = session.readTransaction(async (transaction) => {
|
||||
const emotionsCountTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (post:Post {id: $postId})<-[emoted:EMOTED {emotion: $data.emotion}]-()
|
||||
@ -43,7 +43,7 @@ export default {
|
||||
{ postId, data },
|
||||
)
|
||||
return emotionsCountTransactionResponse.records.map(
|
||||
record => record.get('emotionsCount').low,
|
||||
(record) => record.get('emotionsCount').low,
|
||||
)
|
||||
})
|
||||
try {
|
||||
@ -56,7 +56,7 @@ export default {
|
||||
PostsEmotionsByCurrentUser: async (object, params, context, resolveInfo) => {
|
||||
const { postId } = params
|
||||
const session = context.driver.session()
|
||||
const readTxResultPromise = session.readTransaction(async transaction => {
|
||||
const readTxResultPromise = session.readTransaction(async (transaction) => {
|
||||
const emotionsTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (user:User {id: $userId})-[emoted:EMOTED]->(post:Post {id: $postId})
|
||||
@ -64,7 +64,7 @@ export default {
|
||||
`,
|
||||
{ userId: context.user.id, postId },
|
||||
)
|
||||
return emotionsTransactionResponse.records.map(record => record.get('emotion'))
|
||||
return emotionsTransactionResponse.records.map((record) => record.get('emotion'))
|
||||
})
|
||||
try {
|
||||
const [emotions] = await readTxResultPromise
|
||||
@ -82,7 +82,7 @@ export default {
|
||||
delete params.image
|
||||
params.id = params.id || uuid()
|
||||
const session = context.driver.session()
|
||||
const writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const createPostTransactionResponse = await transaction.run(
|
||||
`
|
||||
CREATE (post:Post)
|
||||
@ -100,7 +100,7 @@ export default {
|
||||
`,
|
||||
{ userId: context.user.id, categoryIds, params },
|
||||
)
|
||||
const [post] = createPostTransactionResponse.records.map(record => record.get('post'))
|
||||
const [post] = createPostTransactionResponse.records.map((record) => record.get('post'))
|
||||
if (imageInput) {
|
||||
await mergeImage(post, 'HERO_IMAGE', imageInput, { transaction })
|
||||
}
|
||||
@ -137,7 +137,7 @@ export default {
|
||||
RETURN post, category
|
||||
`
|
||||
|
||||
await session.writeTransaction(transaction => {
|
||||
await session.writeTransaction((transaction) => {
|
||||
return transaction.run(cypherDeletePreviousRelations, { params })
|
||||
})
|
||||
|
||||
@ -152,12 +152,12 @@ export default {
|
||||
updatePostCypher += `RETURN post {.*}`
|
||||
const updatePostVariables = { categoryIds, params }
|
||||
try {
|
||||
const writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const updatePostTransactionResponse = await transaction.run(
|
||||
updatePostCypher,
|
||||
updatePostVariables,
|
||||
)
|
||||
const [post] = updatePostTransactionResponse.records.map(record => record.get('post'))
|
||||
const [post] = updatePostTransactionResponse.records.map((record) => record.get('post'))
|
||||
await mergeImage(post, 'HERO_IMAGE', imageInput, { transaction })
|
||||
return post
|
||||
})
|
||||
@ -170,7 +170,7 @@ export default {
|
||||
|
||||
DeletePost: async (object, args, context, resolveInfo) => {
|
||||
const session = context.driver.session()
|
||||
const writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const deletePostTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (post:Post {id: $postId})
|
||||
@ -184,7 +184,7 @@ export default {
|
||||
`,
|
||||
{ postId: args.id },
|
||||
)
|
||||
const [post] = deletePostTransactionResponse.records.map(record => record.get('post'))
|
||||
const [post] = deletePostTransactionResponse.records.map((record) => record.get('post'))
|
||||
await deleteImage(post, 'HERO_IMAGE', { transaction })
|
||||
return post
|
||||
})
|
||||
@ -199,7 +199,7 @@ export default {
|
||||
const { to, data } = params
|
||||
const { user } = context
|
||||
const session = context.driver.session()
|
||||
const writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const addPostEmotionsTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (userFrom:User {id: $user.id}), (postTo:Post {id: $to.id})
|
||||
@ -207,7 +207,7 @@ export default {
|
||||
RETURN userFrom, postTo, emotedRelation`,
|
||||
{ user, to, data },
|
||||
)
|
||||
return addPostEmotionsTransactionResponse.records.map(record => {
|
||||
return addPostEmotionsTransactionResponse.records.map((record) => {
|
||||
return {
|
||||
from: { ...record.get('userFrom').properties },
|
||||
to: { ...record.get('postTo').properties },
|
||||
@ -226,7 +226,7 @@ export default {
|
||||
const { to, data } = params
|
||||
const { id: from } = context.user
|
||||
const session = context.driver.session()
|
||||
const writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const removePostEmotionsTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (userFrom:User {id: $from})-[emotedRelation:EMOTED {emotion: $data.emotion}]->(postTo:Post {id: $to.id})
|
||||
@ -235,7 +235,7 @@ export default {
|
||||
`,
|
||||
{ from, to, data },
|
||||
)
|
||||
return removePostEmotionsTransactionResponse.records.map(record => {
|
||||
return removePostEmotionsTransactionResponse.records.map((record) => {
|
||||
return {
|
||||
from: { ...record.get('userFrom').properties },
|
||||
to: { ...record.get('postTo').properties },
|
||||
@ -255,7 +255,7 @@ export default {
|
||||
const { driver, user } = context
|
||||
const session = driver.session()
|
||||
const { id: userId } = user
|
||||
let writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
let writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const deletePreviousRelationsResponse = await transaction.run(
|
||||
`
|
||||
MATCH (:User)-[previousRelations:PINNED]->(post:Post)
|
||||
@ -264,12 +264,14 @@ export default {
|
||||
RETURN post
|
||||
`,
|
||||
)
|
||||
return deletePreviousRelationsResponse.records.map(record => record.get('post').properties)
|
||||
return deletePreviousRelationsResponse.records.map(
|
||||
(record) => record.get('post').properties,
|
||||
)
|
||||
})
|
||||
try {
|
||||
await writeTxResultPromise
|
||||
|
||||
writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const pinPostTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (user:User {id: $userId}) WHERE user.role = 'admin'
|
||||
@ -280,7 +282,7 @@ export default {
|
||||
`,
|
||||
{ userId, params },
|
||||
)
|
||||
return pinPostTransactionResponse.records.map(record => ({
|
||||
return pinPostTransactionResponse.records.map((record) => ({
|
||||
pinnedPost: record.get('post').properties,
|
||||
pinnedAt: record.get('pinnedAt'),
|
||||
}))
|
||||
@ -299,7 +301,7 @@ export default {
|
||||
unpinPost: async (_parent, params, context, _resolveInfo) => {
|
||||
let unpinnedPost
|
||||
const session = context.driver.session()
|
||||
const writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const unpinPostTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (:User)-[previousRelations:PINNED]->(post:Post {id: $params.id})
|
||||
@ -309,7 +311,7 @@ export default {
|
||||
`,
|
||||
{ params },
|
||||
)
|
||||
return unpinPostTransactionResponse.records.map(record => record.get('post').properties)
|
||||
return unpinPostTransactionResponse.records.map((record) => record.get('post').properties)
|
||||
})
|
||||
try {
|
||||
;[unpinnedPost] = await writeTxResultPromise
|
||||
@ -351,7 +353,7 @@ export default {
|
||||
const { id } = parent
|
||||
const session = context.driver.session()
|
||||
|
||||
const writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const relatedContributionsTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (p:Post {id: $id})-[:TAGGED|CATEGORIZED]->(categoryOrTag)<-[:TAGGED|CATEGORIZED]-(post:Post)
|
||||
@ -362,7 +364,7 @@ export default {
|
||||
{ id },
|
||||
)
|
||||
return relatedContributionsTransactionResponse.records.map(
|
||||
record => record.get('post').properties,
|
||||
(record) => record.get('post').properties,
|
||||
)
|
||||
})
|
||||
try {
|
||||
|
||||
@ -37,7 +37,7 @@ export default {
|
||||
|
||||
const { driver } = context
|
||||
const session = driver.session()
|
||||
const writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const createUserTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH(email:EmailAddress {nonce: $nonce, email: $email})
|
||||
@ -57,7 +57,7 @@ export default {
|
||||
`,
|
||||
{ args, nonce, email },
|
||||
)
|
||||
const [user] = createUserTransactionResponse.records.map(record => record.get('user'))
|
||||
const [user] = createUserTransactionResponse.records.map((record) => record.get('user'))
|
||||
if (!user) throw new UserInputError('Invalid email or nonce')
|
||||
return user
|
||||
})
|
||||
|
||||
@ -6,7 +6,7 @@ export default {
|
||||
const { resourceId, reasonCategory, reasonDescription } = params
|
||||
const { driver, user } = context
|
||||
const session = driver.session()
|
||||
const fileReportWriteTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const fileReportWriteTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const fileReportTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (submitter:User {id: $submitterId})
|
||||
@ -29,7 +29,7 @@ export default {
|
||||
},
|
||||
)
|
||||
log(fileReportTransactionResponse)
|
||||
return fileReportTransactionResponse.records.map(record => record.get('filedReport'))
|
||||
return fileReportTransactionResponse.records.map((record) => record.get('filedReport'))
|
||||
})
|
||||
try {
|
||||
const [filedReport] = await fileReportWriteTxResultPromise
|
||||
@ -81,7 +81,7 @@ export default {
|
||||
params.offset && typeof params.offset === 'number' ? `SKIP ${params.offset}` : ''
|
||||
const limit = params.first && typeof params.first === 'number' ? `LIMIT ${params.first}` : ''
|
||||
|
||||
const reportsReadTxPromise = session.readTransaction(async transaction => {
|
||||
const reportsReadTxPromise = session.readTransaction(async (transaction) => {
|
||||
const reportsTransactionResponse = await transaction.run(
|
||||
// !!! this Cypher query returns multiple reports on the same resource! i will create an issue for refactoring (bug fixing)
|
||||
`
|
||||
@ -102,7 +102,7 @@ export default {
|
||||
`,
|
||||
)
|
||||
log(reportsTransactionResponse)
|
||||
return reportsTransactionResponse.records.map(record => record.get('report'))
|
||||
return reportsTransactionResponse.records.map((record) => record.get('report'))
|
||||
})
|
||||
try {
|
||||
const reports = await reportsReadTxPromise
|
||||
@ -118,7 +118,7 @@ export default {
|
||||
const session = context.driver.session()
|
||||
const { id } = parent
|
||||
let filed
|
||||
const readTxPromise = session.readTransaction(async transaction => {
|
||||
const readTxPromise = session.readTransaction(async (transaction) => {
|
||||
const filedReportsTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (submitter:User)-[filed:FILED]->(report:Report {id: $id})
|
||||
@ -127,14 +127,14 @@ export default {
|
||||
{ id },
|
||||
)
|
||||
log(filedReportsTransactionResponse)
|
||||
return filedReportsTransactionResponse.records.map(record => ({
|
||||
return filedReportsTransactionResponse.records.map((record) => ({
|
||||
submitter: record.get('submitter').properties,
|
||||
filed: record.get('filed').properties,
|
||||
}))
|
||||
})
|
||||
try {
|
||||
const filedReports = await readTxPromise
|
||||
filed = filedReports.map(reportedRecord => {
|
||||
filed = filedReports.map((reportedRecord) => {
|
||||
const { submitter, filed } = reportedRecord
|
||||
const relationshipWithNestedAttributes = {
|
||||
...filed,
|
||||
@ -152,7 +152,7 @@ export default {
|
||||
const session = context.driver.session()
|
||||
const { id } = parent
|
||||
let reviewed
|
||||
const readTxPromise = session.readTransaction(async transaction => {
|
||||
const readTxPromise = session.readTransaction(async (transaction) => {
|
||||
const reviewedReportsTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (resource)<-[:BELONGS_TO]-(report:Report {id: $id})<-[review:REVIEWED]-(moderator:User)
|
||||
@ -162,14 +162,14 @@ export default {
|
||||
{ id },
|
||||
)
|
||||
log(reviewedReportsTransactionResponse)
|
||||
return reviewedReportsTransactionResponse.records.map(record => ({
|
||||
return reviewedReportsTransactionResponse.records.map((record) => ({
|
||||
review: record.get('review').properties,
|
||||
moderator: record.get('moderator').properties,
|
||||
}))
|
||||
})
|
||||
try {
|
||||
const reviewedReports = await readTxPromise
|
||||
reviewed = reviewedReports.map(reportedRecord => {
|
||||
reviewed = reviewedReports.map((reportedRecord) => {
|
||||
const { review, moderator } = reportedRecord
|
||||
const relationshipWithNestedAttributes = {
|
||||
...review,
|
||||
|
||||
@ -246,7 +246,7 @@ describe('file a report on a resource', () => {
|
||||
})
|
||||
expect(reportsCypherQueryResponse.records).toHaveLength(1)
|
||||
const [reportProperties] = reportsCypherQueryResponse.records.map(
|
||||
record => record.get('report').properties,
|
||||
(record) => record.get('report').properties,
|
||||
)
|
||||
expect(reportProperties).toMatchObject({ rule: 'latestReviewUpdatedAtRules' })
|
||||
})
|
||||
@ -264,7 +264,7 @@ describe('file a report on a resource', () => {
|
||||
})
|
||||
expect(reportsCypherQueryResponse.records).toHaveLength(1)
|
||||
const [reportProperties] = reportsCypherQueryResponse.records.map(
|
||||
record => record.get('report').properties,
|
||||
(record) => record.get('report').properties,
|
||||
)
|
||||
expect(reportProperties).toMatchObject({ disable: false })
|
||||
})
|
||||
@ -297,7 +297,7 @@ describe('file a report on a resource', () => {
|
||||
})
|
||||
expect(reportsCypherQueryResponse.records).toHaveLength(1)
|
||||
const [reportProperties] = reportsCypherQueryResponse.records.map(
|
||||
record => record.get('report').properties,
|
||||
(record) => record.get('report').properties,
|
||||
)
|
||||
expect(reportProperties).toMatchObject({ disable: true })
|
||||
})
|
||||
|
||||
@ -24,7 +24,7 @@ export default {
|
||||
const { user } = await getUserAndBadge(params)
|
||||
const session = context.driver.session()
|
||||
try {
|
||||
await session.writeTransaction(transaction => {
|
||||
await session.writeTransaction((transaction) => {
|
||||
return transaction.run(
|
||||
`
|
||||
MATCH (badge:Badge {id: $badgeKey})-[reward:REWARDED]->(rewardedUser:User {id: $userId})
|
||||
|
||||
@ -54,7 +54,7 @@ export default {
|
||||
const myQuery = queryString(query)
|
||||
|
||||
const session = context.driver.session()
|
||||
const searchResultPromise = session.readTransaction(async transaction => {
|
||||
const searchResultPromise = session.readTransaction(async (transaction) => {
|
||||
const postTransactionResponse = transaction.run(postCypher, {
|
||||
query: myQuery,
|
||||
limit,
|
||||
@ -81,7 +81,7 @@ export default {
|
||||
log(postResults)
|
||||
log(userResults)
|
||||
log(tagResults)
|
||||
return [...postResults.records, ...userResults.records, ...tagResults.records].map(r =>
|
||||
return [...postResults.records, ...userResults.records, ...tagResults.records].map((r) =>
|
||||
r.get('resource'),
|
||||
)
|
||||
} finally {
|
||||
|
||||
@ -104,6 +104,7 @@ describe('resolvers/searches', () => {
|
||||
},
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -122,6 +123,7 @@ describe('resolvers/searches', () => {
|
||||
},
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -202,6 +204,7 @@ und hinter tausend Stäben keine Welt.`,
|
||||
},
|
||||
]),
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -222,6 +225,7 @@ und hinter tausend Stäben keine Welt.`,
|
||||
},
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -240,6 +244,7 @@ und hinter tausend Stäben keine Welt.`,
|
||||
},
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -262,6 +267,7 @@ und hinter tausend Stäben keine Welt.`,
|
||||
},
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -282,6 +288,7 @@ und hinter tausend Stäben keine Welt.`,
|
||||
},
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -302,6 +309,7 @@ und hinter tausend Stäben keine Welt.`,
|
||||
},
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -331,6 +339,7 @@ und hinter tausend Stäben keine Welt.`,
|
||||
},
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -358,6 +367,7 @@ und hinter tausend Stäben keine Welt.`,
|
||||
},
|
||||
]),
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -400,6 +410,7 @@ und hinter tausend Stäben keine Welt.`,
|
||||
},
|
||||
]),
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -438,6 +449,7 @@ und hinter tausend Stäben keine Welt.`,
|
||||
},
|
||||
]),
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -460,6 +472,7 @@ und hinter tausend Stäben keine Welt.`,
|
||||
},
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -26,15 +26,15 @@ const matchSomeWordsExactly = (str, boost = 2) => {
|
||||
if (!str.includes(' ')) return ''
|
||||
return str
|
||||
.split(' ')
|
||||
.map(s => `"${s}"^${boost}`)
|
||||
.map((s) => `"${s}"^${boost}`)
|
||||
.join(' ')
|
||||
}
|
||||
|
||||
const matchBeginningOfWords = str => {
|
||||
const matchBeginningOfWords = (str) => {
|
||||
return str
|
||||
.split(' ')
|
||||
.filter(s => s.length > 3)
|
||||
.map(s => s + '*')
|
||||
.filter((s) => s.length > 3)
|
||||
.map((s) => s + '*')
|
||||
.join(' ')
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ export default {
|
||||
|
||||
const session = context.driver.session()
|
||||
try {
|
||||
const shoutWriteTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const shoutWriteTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const shoutTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (node {id: $id})<-[:WROTE]-(userWritten:User), (user:User {id: $userId})
|
||||
@ -22,7 +22,7 @@ export default {
|
||||
},
|
||||
)
|
||||
log(shoutTransactionResponse)
|
||||
return shoutTransactionResponse.records.map(record => record.get('isShouted'))
|
||||
return shoutTransactionResponse.records.map((record) => record.get('isShouted'))
|
||||
})
|
||||
const [isShouted] = await shoutWriteTxResultPromise
|
||||
return isShouted
|
||||
@ -35,7 +35,7 @@ export default {
|
||||
const { id, type } = params
|
||||
const session = context.driver.session()
|
||||
try {
|
||||
const unshoutWriteTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const unshoutWriteTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const unshoutTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (user:User {id: $userId})-[relation:SHOUTED]->(node {id: $id})
|
||||
@ -50,7 +50,7 @@ export default {
|
||||
},
|
||||
)
|
||||
log(unshoutTransactionResponse)
|
||||
return unshoutTransactionResponse.records.map(record => record.get('isShouted'))
|
||||
return unshoutTransactionResponse.records.map((record) => record.get('isShouted'))
|
||||
})
|
||||
const [isShouted] = await unshoutWriteTxResultPromise
|
||||
return isShouted
|
||||
|
||||
@ -132,7 +132,7 @@ describe('shout and unshout posts', () => {
|
||||
},
|
||||
)
|
||||
const relationshipProperties = relation.records.map(
|
||||
record => record.get('relationship').properties.createdAt,
|
||||
(record) => record.get('relationship').properties.createdAt,
|
||||
)
|
||||
expect(relationshipProperties[0]).toEqual(expect.any(String))
|
||||
})
|
||||
|
||||
@ -15,7 +15,7 @@ export default {
|
||||
countFollows: 'FOLLOWS',
|
||||
countShouts: 'SHOUTED',
|
||||
}
|
||||
const statisticsReadTxResultPromise = session.readTransaction(async transaction => {
|
||||
const statisticsReadTxResultPromise = session.readTransaction(async (transaction) => {
|
||||
const statisticsTransactionResponse = await transaction.run(
|
||||
`
|
||||
CALL apoc.meta.stats() YIELD labels, relTypesCount
|
||||
@ -23,7 +23,7 @@ export default {
|
||||
`,
|
||||
)
|
||||
log(statisticsTransactionResponse)
|
||||
return statisticsTransactionResponse.records.map(record => {
|
||||
return statisticsTransactionResponse.records.map((record) => {
|
||||
return {
|
||||
...record.get('labels'),
|
||||
...record.get('relTypesCount'),
|
||||
@ -31,7 +31,7 @@ export default {
|
||||
})
|
||||
})
|
||||
const [statistics] = await statisticsReadTxResultPromise
|
||||
Object.keys(mapping).forEach(key => {
|
||||
Object.keys(mapping).forEach((key) => {
|
||||
const stat = statistics[mapping[key]]
|
||||
counts[key] = stat ? stat.toNumber() : 0
|
||||
})
|
||||
|
||||
@ -16,7 +16,7 @@ export default {
|
||||
const { user, driver } = context
|
||||
if (!user) return null
|
||||
const session = driver.session()
|
||||
const currentUserTransactionPromise = session.readTransaction(async transaction => {
|
||||
const currentUserTransactionPromise = session.readTransaction(async (transaction) => {
|
||||
const result = await transaction.run(
|
||||
`
|
||||
MATCH (user:User {id: $id})
|
||||
@ -26,7 +26,7 @@ export default {
|
||||
{ id: user.id },
|
||||
)
|
||||
log(result)
|
||||
return result.records.map(record => record.get('user'))
|
||||
return result.records.map((record) => record.get('user'))
|
||||
})
|
||||
try {
|
||||
const [currentUser] = await currentUserTransactionPromise
|
||||
@ -44,7 +44,7 @@ export default {
|
||||
email = normalizeEmail(email)
|
||||
const session = driver.session()
|
||||
try {
|
||||
const loginReadTxResultPromise = session.readTransaction(async transaction => {
|
||||
const loginReadTxResultPromise = session.readTransaction(async (transaction) => {
|
||||
const loginTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (user:User {deleted: false})-[:PRIMARY_EMAIL]->(e:EmailAddress {email: $userEmail})
|
||||
@ -53,7 +53,7 @@ export default {
|
||||
{ userEmail: email },
|
||||
)
|
||||
log(loginTransactionResponse)
|
||||
return loginTransactionResponse.records.map(record => record.get('user'))
|
||||
return loginTransactionResponse.records.map((record) => record.get('user'))
|
||||
})
|
||||
const [currentUser] = await loginReadTxResultPromise
|
||||
if (
|
||||
|
||||
@ -10,7 +10,7 @@ import { getNeode } from '../../db/neo4j'
|
||||
const neode = getNeode()
|
||||
let query, mutate, variables, req, user
|
||||
|
||||
const disable = async id => {
|
||||
const disable = async (id) => {
|
||||
const moderator = await Factory.build('user', { id: 'u2', role: 'moderator' })
|
||||
const user = await neode.find('User', id)
|
||||
const reportAgainstUser = await Factory.build('report')
|
||||
@ -56,7 +56,7 @@ describe('isLoggedIn', () => {
|
||||
isLoggedIn
|
||||
}
|
||||
`
|
||||
const respondsWith = async expected => {
|
||||
const respondsWith = async (expected) => {
|
||||
await expect(query({ query: isLoggedInQuery })).resolves.toMatchObject(expected)
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@ describe('currentUser', () => {
|
||||
}
|
||||
`
|
||||
|
||||
const respondsWith = async expected => {
|
||||
const respondsWith = async (expected) => {
|
||||
await expect(query({ query: currentUserQuery, variables })).resolves.toMatchObject(expected)
|
||||
}
|
||||
|
||||
@ -176,7 +176,7 @@ describe('login', () => {
|
||||
}
|
||||
`
|
||||
|
||||
const respondsWith = async expected => {
|
||||
const respondsWith = async (expected) => {
|
||||
await expect(mutate({ mutation: loginMutation, variables })).resolves.toMatchObject(expected)
|
||||
}
|
||||
|
||||
@ -193,7 +193,7 @@ describe('login', () => {
|
||||
|
||||
describe('ask for a `token`', () => {
|
||||
describe('with a valid email/password combination', () => {
|
||||
it('responds with a JWT bearer token', async done => {
|
||||
it('responds with a JWT bearer token', async (done) => {
|
||||
const {
|
||||
data: { login: token },
|
||||
} = await mutate({ mutation: loginMutation, variables })
|
||||
@ -292,7 +292,7 @@ describe('change password', () => {
|
||||
}
|
||||
`
|
||||
|
||||
const respondsWith = async expected => {
|
||||
const respondsWith = async (expected) => {
|
||||
await expect(mutate({ mutation: changePasswordMutation, variables })).resolves.toMatchObject(
|
||||
expected,
|
||||
)
|
||||
|
||||
@ -8,7 +8,7 @@ import createOrUpdateLocations from './users/location'
|
||||
|
||||
const neode = getNeode()
|
||||
|
||||
export const getMutedUsers = async context => {
|
||||
export const getMutedUsers = async (context) => {
|
||||
const { neode } = context
|
||||
const userModel = neode.model('User')
|
||||
let mutedUsers = neode
|
||||
@ -19,11 +19,11 @@ export const getMutedUsers = async context => {
|
||||
.to('muted', userModel)
|
||||
.return('muted')
|
||||
mutedUsers = await mutedUsers.execute()
|
||||
mutedUsers = mutedUsers.records.map(r => r.get('muted').properties)
|
||||
mutedUsers = mutedUsers.records.map((r) => r.get('muted').properties)
|
||||
return mutedUsers
|
||||
}
|
||||
|
||||
export const getBlockedUsers = async context => {
|
||||
export const getBlockedUsers = async (context) => {
|
||||
const { neode } = context
|
||||
const userModel = neode.model('User')
|
||||
let blockedUsers = neode
|
||||
@ -34,7 +34,7 @@ export const getBlockedUsers = async context => {
|
||||
.to('blocked', userModel)
|
||||
.return('blocked')
|
||||
blockedUsers = await blockedUsers.execute()
|
||||
blockedUsers = blockedUsers.records.map(r => r.get('blocked').properties)
|
||||
blockedUsers = blockedUsers.records.map((r) => r.get('blocked').properties)
|
||||
return blockedUsers
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ export default {
|
||||
let session
|
||||
try {
|
||||
session = context.driver.session()
|
||||
const readTxResult = await session.readTransaction(txc => {
|
||||
const readTxResult = await session.readTransaction((txc) => {
|
||||
const result = txc.run(
|
||||
`
|
||||
MATCH (user:User)-[:PRIMARY_EMAIL]->(e:EmailAddress {email: $args.email})
|
||||
@ -69,7 +69,7 @@ export default {
|
||||
)
|
||||
return result
|
||||
})
|
||||
return readTxResult.records.map(r => r.get('user').properties)
|
||||
return readTxResult.records.map((r) => r.get('user').properties)
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
@ -151,7 +151,7 @@ export default {
|
||||
}
|
||||
const session = context.driver.session()
|
||||
|
||||
const writeTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const updateUserTransactionResponse = await transaction.run(
|
||||
`
|
||||
MATCH (user:User {id: $params.id})
|
||||
@ -161,7 +161,7 @@ export default {
|
||||
`,
|
||||
{ params },
|
||||
)
|
||||
const [user] = updateUserTransactionResponse.records.map(record => record.get('user'))
|
||||
const [user] = updateUserTransactionResponse.records.map((record) => record.get('user'))
|
||||
if (avatarInput) {
|
||||
await mergeImage(user, 'AVATAR_IMAGE', avatarInput, { transaction })
|
||||
}
|
||||
@ -181,10 +181,10 @@ export default {
|
||||
const { resource, id: userId } = params
|
||||
const session = context.driver.session()
|
||||
|
||||
const deleteUserTxResultPromise = session.writeTransaction(async transaction => {
|
||||
const deleteUserTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
if (resource && resource.length) {
|
||||
await Promise.all(
|
||||
resource.map(async node => {
|
||||
resource.map(async (node) => {
|
||||
const txResult = await transaction.run(
|
||||
`
|
||||
MATCH (resource:${node})<-[:WROTE]-(author:User {id: $userId})
|
||||
@ -204,8 +204,8 @@ export default {
|
||||
)
|
||||
return Promise.all(
|
||||
txResult.records
|
||||
.map(record => record.get('resource'))
|
||||
.map(resource => deleteImage(resource, 'HERO_IMAGE', { transaction })),
|
||||
.map((record) => record.get('resource'))
|
||||
.map((resource) => deleteImage(resource, 'HERO_IMAGE', { transaction })),
|
||||
)
|
||||
}),
|
||||
)
|
||||
@ -233,7 +233,7 @@ export default {
|
||||
{ userId },
|
||||
)
|
||||
log(deleteUserTransactionResponse)
|
||||
const [user] = deleteUserTransactionResponse.records.map(record => record.get('user'))
|
||||
const [user] = deleteUserTransactionResponse.records.map((record) => record.get('user'))
|
||||
await deleteImage(user, 'AVATAR_IMAGE', { transaction })
|
||||
return user
|
||||
})
|
||||
@ -251,7 +251,7 @@ export default {
|
||||
const { id } = parent
|
||||
const statement = `MATCH(u:User {id: {id}})-[:PRIMARY_EMAIL]->(e:EmailAddress) RETURN e`
|
||||
const result = await neode.cypher(statement, { id })
|
||||
const [{ email }] = result.records.map(r => r.get('e').properties)
|
||||
const [{ email }] = result.records.map((r) => r.get('e').properties)
|
||||
return email
|
||||
},
|
||||
...Resolver('User', {
|
||||
|
||||
@ -7,9 +7,9 @@ import CONFIG from '../../../config'
|
||||
|
||||
const debug = Debug('human-connection:location')
|
||||
|
||||
const fetch = url => {
|
||||
const fetch = (url) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
request(url, function(error, response, body) {
|
||||
request(url, function (error, response, body) {
|
||||
if (error) {
|
||||
reject(error)
|
||||
} else {
|
||||
@ -57,7 +57,7 @@ const createLocation = async (session, mapboxData) => {
|
||||
}
|
||||
mutation += ' RETURN l.id'
|
||||
|
||||
await session.writeTransaction(transaction => {
|
||||
await session.writeTransaction((transaction) => {
|
||||
return transaction.run(mutation, data)
|
||||
})
|
||||
}
|
||||
@ -82,7 +82,7 @@ const createOrUpdateLocations = async (userId, locationName, session) => {
|
||||
|
||||
let data
|
||||
|
||||
res.features.forEach(item => {
|
||||
res.features.forEach((item) => {
|
||||
if (item.matching_place_name === locationName) {
|
||||
data = item
|
||||
}
|
||||
@ -103,9 +103,9 @@ const createOrUpdateLocations = async (userId, locationName, session) => {
|
||||
let parent = data
|
||||
|
||||
if (data.context) {
|
||||
await asyncForEach(data.context, async ctx => {
|
||||
await asyncForEach(data.context, async (ctx) => {
|
||||
await createLocation(session, ctx)
|
||||
await session.writeTransaction(transaction => {
|
||||
await session.writeTransaction((transaction) => {
|
||||
return transaction.run(
|
||||
`
|
||||
MATCH (parent:Location {id: $parentId}), (child:Location {id: $childId})
|
||||
@ -122,7 +122,7 @@ const createOrUpdateLocations = async (userId, locationName, session) => {
|
||||
})
|
||||
}
|
||||
// delete all current locations from user and add new location
|
||||
await session.writeTransaction(transaction => {
|
||||
await session.writeTransaction((transaction) => {
|
||||
return transaction.run(
|
||||
`
|
||||
MATCH (user:User {id: $userId})-[relationship:IS_IN]->(location:Location)
|
||||
|
||||
@ -107,7 +107,7 @@ describe('userMiddleware', () => {
|
||||
`MATCH (city:Location)-[:IS_IN]->(state:Location)-[:IS_IN]->(country:Location) return city {.*}, state {.*}, country {.*}`,
|
||||
)
|
||||
expect(
|
||||
locations.records.map(record => {
|
||||
locations.records.map((record) => {
|
||||
return {
|
||||
city: record.get('city'),
|
||||
state: record.get('state'),
|
||||
|
||||
@ -90,7 +90,7 @@ describe('muteUser', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
currentUser = undefined
|
||||
muteAction = variables => {
|
||||
muteAction = (variables) => {
|
||||
const { mutate } = createTestClient(server)
|
||||
const muteUserMutation = gql`
|
||||
mutation($id: ID!) {
|
||||
@ -307,7 +307,7 @@ describe('unmuteUser', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
currentUser = undefined
|
||||
unmuteAction = variables => {
|
||||
unmuteAction = (variables) => {
|
||||
const { mutate } = createTestClient(server)
|
||||
const unmuteUserMutation = gql`
|
||||
mutation($id: ID!) {
|
||||
|
||||
@ -20,7 +20,7 @@ const options = {
|
||||
host: REDIS_DOMAIN,
|
||||
port: REDIS_PORT,
|
||||
password: REDIS_PASSWORD,
|
||||
retryStrategy: times => {
|
||||
retryStrategy: (times) => {
|
||||
return Math.min(times * 50, 2000)
|
||||
},
|
||||
}
|
||||
@ -36,7 +36,7 @@ export const pubsub = prodPubsub || devPubsub
|
||||
const driver = getDriver()
|
||||
const neode = getNeode()
|
||||
|
||||
const getContext = async req => {
|
||||
const getContext = async (req) => {
|
||||
const user = await decode(driver, req.headers.authorization)
|
||||
return {
|
||||
driver,
|
||||
@ -48,7 +48,7 @@ const getContext = async req => {
|
||||
},
|
||||
}
|
||||
}
|
||||
export const context = async options => {
|
||||
export const context = async (options) => {
|
||||
const { connection, req } = options
|
||||
if (connection) {
|
||||
return connection.context
|
||||
@ -57,7 +57,7 @@ export const context = async options => {
|
||||
}
|
||||
}
|
||||
|
||||
const createServer = options => {
|
||||
const createServer = (options) => {
|
||||
const defaults = {
|
||||
context,
|
||||
schema: middleware(schema),
|
||||
@ -68,9 +68,9 @@ const createServer = options => {
|
||||
},
|
||||
debug: !!CONFIG.DEBUG,
|
||||
tracing: !!CONFIG.DEBUG,
|
||||
formatError: error => {
|
||||
formatError: (error) => {
|
||||
if (error.message === 'ERROR_VALIDATION') {
|
||||
return new Error(error.originalError.details.map(d => d.message))
|
||||
return new Error(error.originalError.details.map((d) => d.message))
|
||||
}
|
||||
return error
|
||||
},
|
||||
|
||||
2039
backend/yarn.lock
2039
backend/yarn.lock
File diff suppressed because it is too large
Load Diff
@ -24,3 +24,15 @@ Digital Ocean kubernetes clusters don't have a graphical interface, so I suggest
|
||||
to setup the [kubernetes dashboard](./dashboard/README.md) as a next step.
|
||||
Configuring [HTTPS](./https/README.md) is bit tricky and therefore I suggest to
|
||||
do this as a last step.
|
||||
|
||||
## Spaces
|
||||
|
||||
We are storing our images in the s3-compatible [DigitalOcean Spaces](https://www.digitalocean.com/docs/spaces/).
|
||||
|
||||
We still want to take backups of our images in case something happens to the images in the cloud. See these [instructions](https://www.digitalocean.com/docs/spaces/resources/s3cmd-usage/) about getting set up with `s3cmd` to take a copy of all images in a `Spaces` namespace, ie `human-connection-uploads`.
|
||||
|
||||
After configuring `s3cmd` with your credentials, etc. you should be able to make a backup with this command.
|
||||
|
||||
```sh
|
||||
s3cmg get --recursive s3://human-connection-uploads --skip-existing
|
||||
```
|
||||
16
package.json
16
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "human-connection",
|
||||
"version": "0.5.0",
|
||||
"version": "0.6.1",
|
||||
"description": "Fullstack and API tests with cypress and cucumber for Human Connection",
|
||||
"author": "Human Connection gGmbh",
|
||||
"license": "MIT",
|
||||
@ -26,21 +26,21 @@
|
||||
"generate:changelog": "yarn version && auto-changelog"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.8.7",
|
||||
"@babel/preset-env": "^7.8.7",
|
||||
"@babel/register": "^7.8.6",
|
||||
"auto-changelog": "^1.16.2",
|
||||
"@babel/core": "^7.9.0",
|
||||
"@babel/preset-env": "^7.9.0",
|
||||
"@babel/register": "^7.9.0",
|
||||
"auto-changelog": "^1.16.4",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"codecov": "^3.6.5",
|
||||
"cross-env": "^7.0.2",
|
||||
"cucumber": "^6.0.5",
|
||||
"cypress": "^4.2.0",
|
||||
"cypress-cucumber-preprocessor": "^2.0.1",
|
||||
"cypress-cucumber-preprocessor": "^2.2.1",
|
||||
"cypress-file-upload": "^3.5.3",
|
||||
"cypress-plugin-retries": "^1.5.2",
|
||||
"date-fns": "^2.11.0",
|
||||
"date-fns": "^2.12.0",
|
||||
"dotenv": "^8.2.0",
|
||||
"expect": "^25.1.0",
|
||||
"expect": "^25.3.0",
|
||||
"faker": "Marak/faker.js#master",
|
||||
"graphql-request": "^1.8.2",
|
||||
"import": "^0.0.6",
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function(to, from, savedPosition) {
|
||||
export default function (to, from, savedPosition) {
|
||||
if (savedPosition) return savedPosition
|
||||
|
||||
// Edge case: If you click on a notification from a comment and then on the
|
||||
|
||||
@ -2,7 +2,7 @@ const svgFileList = require.context('./svgs', true, /\.svg/)
|
||||
const icons = {}
|
||||
const iconNames = []
|
||||
|
||||
svgFileList.keys().forEach(fileName => {
|
||||
svgFileList.keys().forEach((fileName) => {
|
||||
const svgCode = svgFileList(fileName)
|
||||
const iconName = fileName.replace('./', '').replace('.svg', '')
|
||||
icons[iconName] = svgCode
|
||||
|
||||
@ -19,3 +19,10 @@ h6,
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@ -230,6 +230,7 @@ $space-small: 16px;
|
||||
$space-x-small: 8px;
|
||||
$space-xx-small: 4px;
|
||||
$space-xxx-small: 2px;
|
||||
$space-none: 0;
|
||||
|
||||
/**
|
||||
* @tokens Size Height
|
||||
@ -240,6 +241,7 @@ $size-height-base: 42px;
|
||||
$size-height-large: 50px;
|
||||
$size-height-xlarge: 60px;
|
||||
$size-height-footer: 64px;
|
||||
$size-height-connections: 315px;
|
||||
$size-tappable-square: 44px;
|
||||
$size-ribbon: 6px;
|
||||
|
||||
@ -248,7 +250,9 @@ $size-ribbon: 6px;
|
||||
* @presenter Spacing
|
||||
*/
|
||||
|
||||
$size-width-filter-sidebar: 85px;
|
||||
$size-width-paginate: 100px;
|
||||
$size-max-width-filter-menu: 1026px;
|
||||
|
||||
/**
|
||||
* @tokens Size Avatar
|
||||
|
||||
@ -21,7 +21,7 @@ describe('AvatarMenu.vue', () => {
|
||||
return { href: '/profile/u343/matt' }
|
||||
}),
|
||||
},
|
||||
$t: jest.fn(a => a),
|
||||
$t: jest.fn((a) => a),
|
||||
}
|
||||
getters = {
|
||||
'auth/user': () => {
|
||||
@ -86,21 +86,21 @@ describe('AvatarMenu.vue', () => {
|
||||
it('displays a link to user profile', () => {
|
||||
const profileLink = wrapper
|
||||
.findAll('.ds-menu-item span')
|
||||
.at(wrapper.vm.routes.findIndex(route => route.path === '/profile/u343/matt'))
|
||||
.at(wrapper.vm.routes.findIndex((route) => route.path === '/profile/u343/matt'))
|
||||
expect(profileLink.exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('displays a link to the notifications page', () => {
|
||||
const notificationsLink = wrapper
|
||||
.findAll('.ds-menu-item span')
|
||||
.at(wrapper.vm.routes.findIndex(route => route.path === '/notifications'))
|
||||
.at(wrapper.vm.routes.findIndex((route) => route.path === '/notifications'))
|
||||
expect(notificationsLink.exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('displays a link to the settings page', () => {
|
||||
const settingsLink = wrapper
|
||||
.findAll('.ds-menu-item span')
|
||||
.at(wrapper.vm.routes.findIndex(route => route.path === '/settings'))
|
||||
.at(wrapper.vm.routes.findIndex((route) => route.path === '/settings'))
|
||||
expect(settingsLink.exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
@ -121,7 +121,7 @@ describe('AvatarMenu.vue', () => {
|
||||
it('displays a link to moderation page', () => {
|
||||
const moderationLink = wrapper
|
||||
.findAll('.ds-menu-item span')
|
||||
.at(wrapper.vm.routes.findIndex(route => route.path === '/moderation'))
|
||||
.at(wrapper.vm.routes.findIndex((route) => route.path === '/moderation'))
|
||||
expect(moderationLink.exists()).toBe(true)
|
||||
})
|
||||
|
||||
@ -147,7 +147,7 @@ describe('AvatarMenu.vue', () => {
|
||||
it('displays a link to admin page', () => {
|
||||
const adminLink = wrapper
|
||||
.findAll('.ds-menu-item span')
|
||||
.at(wrapper.vm.routes.findIndex(route => route.path === '/admin'))
|
||||
.at(wrapper.vm.routes.findIndex((route) => route.path === '/admin'))
|
||||
expect(adminLink.exists()).toBe(true)
|
||||
})
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
{{ $t('login.hello') }}
|
||||
<b>{{ userName }}</b>
|
||||
<template v-if="user.role !== 'user'">
|
||||
<ds-text color="softer" size="small" style="margin-bottom: 0">
|
||||
<ds-text color="softer" size="small" style="margin-bottom: 0;">
|
||||
{{ user.role | camelCase }}
|
||||
</ds-text>
|
||||
</template>
|
||||
|
||||
@ -29,8 +29,8 @@ describe('CommentCard.vue', () => {
|
||||
locale: () => 'en',
|
||||
},
|
||||
$filters: {
|
||||
truncate: a => a,
|
||||
removeHtml: a => a,
|
||||
truncate: (a) => a,
|
||||
removeHtml: (a) => a,
|
||||
},
|
||||
$route: { hash: '' },
|
||||
$scrollTo: jest.fn(),
|
||||
|
||||
@ -25,7 +25,7 @@ describe('CommentForm.vue', () => {
|
||||
success: jest.fn(),
|
||||
},
|
||||
$filters: {
|
||||
removeHtml: a => a,
|
||||
removeHtml: (a) => a,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
@ -104,7 +104,7 @@ export default {
|
||||
this.disabled = true
|
||||
this.$apollo
|
||||
.mutate(mutateParams)
|
||||
.then(res => {
|
||||
.then((res) => {
|
||||
this.loading = false
|
||||
if (!this.update) {
|
||||
const {
|
||||
@ -125,7 +125,7 @@ export default {
|
||||
this.closeEditWindow()
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
this.$toast.error(err.message)
|
||||
})
|
||||
},
|
||||
|
||||
@ -6,7 +6,7 @@ import Vue from 'vue'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
localVue.filter('truncate', string => string)
|
||||
localVue.filter('truncate', (string) => string)
|
||||
localVue.directive('scrollTo', jest.fn())
|
||||
|
||||
config.stubs['v-popover'] = '<span><slot /></span>'
|
||||
@ -42,8 +42,8 @@ describe('CommentList.vue', () => {
|
||||
mocks = {
|
||||
$t: jest.fn(),
|
||||
$filters: {
|
||||
truncate: a => a,
|
||||
removeHtml: a => a,
|
||||
truncate: (a) => a,
|
||||
removeHtml: (a) => a,
|
||||
},
|
||||
$scrollTo: jest.fn(),
|
||||
$route: { hash: '' },
|
||||
|
||||
@ -6,7 +6,7 @@ import faker from 'faker'
|
||||
|
||||
helpers.init()
|
||||
|
||||
const commentMock = fields => {
|
||||
const commentMock = (fields) => {
|
||||
return {
|
||||
id: faker.random.uuid(),
|
||||
title: faker.lorem.sentence(),
|
||||
|
||||
@ -48,7 +48,7 @@ export default {
|
||||
return anchor === '#comments'
|
||||
},
|
||||
updateCommentList(updatedComment) {
|
||||
this.postComments = this.postComments.map(comment => {
|
||||
this.postComments = this.postComments.map((comment) => {
|
||||
return comment.id === updatedComment.id ? updatedComment : comment
|
||||
})
|
||||
},
|
||||
|
||||
@ -17,7 +17,7 @@ let getters, mutations, mocks, menuToggle, openModalSpy
|
||||
describe('ContentMenu.vue', () => {
|
||||
beforeEach(() => {
|
||||
mocks = {
|
||||
$t: jest.fn(str => str),
|
||||
$t: jest.fn((str) => str),
|
||||
$i18n: {
|
||||
locale: () => 'en',
|
||||
},
|
||||
@ -68,7 +68,7 @@ describe('ContentMenu.vue', () => {
|
||||
expect(
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'post.menu.edit')
|
||||
.filter((item) => item.text() === 'post.menu.edit')
|
||||
.at(0)
|
||||
.find('span.ds-menu-item-link')
|
||||
.attributes('to'),
|
||||
@ -78,7 +78,7 @@ describe('ContentMenu.vue', () => {
|
||||
it('can delete the contribution', () => {
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'post.menu.delete')
|
||||
.filter((item) => item.text() === 'post.menu.delete')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(openModalSpy).toHaveBeenCalledWith('confirm', 'delete')
|
||||
@ -98,7 +98,7 @@ describe('ContentMenu.vue', () => {
|
||||
})
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'post.menu.pin')
|
||||
.filter((item) => item.text() === 'post.menu.pin')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(wrapper.emitted('pinPost')).toEqual([
|
||||
@ -122,7 +122,7 @@ describe('ContentMenu.vue', () => {
|
||||
})
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'post.menu.unpin')
|
||||
.filter((item) => item.text() === 'post.menu.unpin')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(wrapper.emitted('unpinPost')).toEqual([
|
||||
@ -151,7 +151,7 @@ describe('ContentMenu.vue', () => {
|
||||
it('edit the comment', () => {
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'comment.menu.edit')
|
||||
.filter((item) => item.text() === 'comment.menu.edit')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(wrapper.emitted('editComment')).toBeTruthy()
|
||||
@ -159,7 +159,7 @@ describe('ContentMenu.vue', () => {
|
||||
it('delete the comment', () => {
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'comment.menu.delete')
|
||||
.filter((item) => item.text() === 'comment.menu.delete')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(openModalSpy).toHaveBeenCalledWith('confirm', 'delete')
|
||||
@ -180,7 +180,7 @@ describe('ContentMenu.vue', () => {
|
||||
openModalSpy = jest.spyOn(wrapper.vm, 'openModal')
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'report.contribution.title')
|
||||
.filter((item) => item.text() === 'report.contribution.title')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(openModalSpy).toHaveBeenCalledWith('report')
|
||||
@ -197,7 +197,7 @@ describe('ContentMenu.vue', () => {
|
||||
openModalSpy = jest.spyOn(wrapper.vm, 'openModal')
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'report.comment.title')
|
||||
.filter((item) => item.text() === 'report.comment.title')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(openModalSpy).toHaveBeenCalledWith('report')
|
||||
@ -214,7 +214,7 @@ describe('ContentMenu.vue', () => {
|
||||
openModalSpy = jest.spyOn(wrapper.vm, 'openModal')
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'report.user.title')
|
||||
.filter((item) => item.text() === 'report.user.title')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(openModalSpy).toHaveBeenCalledWith('report')
|
||||
@ -231,7 +231,7 @@ describe('ContentMenu.vue', () => {
|
||||
openModalSpy = jest.spyOn(wrapper.vm, 'openModal')
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'report.organization.title')
|
||||
.filter((item) => item.text() === 'report.organization.title')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(openModalSpy).toHaveBeenCalledWith('report')
|
||||
@ -253,7 +253,7 @@ describe('ContentMenu.vue', () => {
|
||||
openModalSpy = jest.spyOn(wrapper.vm, 'openModal')
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'disable.contribution.title')
|
||||
.filter((item) => item.text() === 'disable.contribution.title')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(openModalSpy).toHaveBeenCalledWith('disable')
|
||||
@ -271,7 +271,7 @@ describe('ContentMenu.vue', () => {
|
||||
openModalSpy = jest.spyOn(wrapper.vm, 'openModal')
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'disable.comment.title')
|
||||
.filter((item) => item.text() === 'disable.comment.title')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(openModalSpy).toHaveBeenCalledWith('disable')
|
||||
@ -289,7 +289,7 @@ describe('ContentMenu.vue', () => {
|
||||
openModalSpy = jest.spyOn(wrapper.vm, 'openModal')
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'disable.user.title')
|
||||
.filter((item) => item.text() === 'disable.user.title')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(openModalSpy).toHaveBeenCalledWith('disable')
|
||||
@ -307,7 +307,7 @@ describe('ContentMenu.vue', () => {
|
||||
openModalSpy = jest.spyOn(wrapper.vm, 'openModal')
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'disable.organization.title')
|
||||
.filter((item) => item.text() === 'disable.organization.title')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(openModalSpy).toHaveBeenCalledWith('disable')
|
||||
@ -325,7 +325,7 @@ describe('ContentMenu.vue', () => {
|
||||
openModalSpy = jest.spyOn(wrapper.vm, 'openModal')
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'release.contribution.title')
|
||||
.filter((item) => item.text() === 'release.contribution.title')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(openModalSpy).toHaveBeenCalledWith('release')
|
||||
@ -343,7 +343,7 @@ describe('ContentMenu.vue', () => {
|
||||
openModalSpy = jest.spyOn(wrapper.vm, 'openModal')
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'release.comment.title')
|
||||
.filter((item) => item.text() === 'release.comment.title')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(openModalSpy).toHaveBeenCalledWith('release')
|
||||
@ -361,7 +361,7 @@ describe('ContentMenu.vue', () => {
|
||||
openModalSpy = jest.spyOn(wrapper.vm, 'openModal')
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'release.user.title')
|
||||
.filter((item) => item.text() === 'release.user.title')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(openModalSpy).toHaveBeenCalledWith('release')
|
||||
@ -379,7 +379,7 @@ describe('ContentMenu.vue', () => {
|
||||
openModalSpy = jest.spyOn(wrapper.vm, 'openModal')
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'release.organization.title')
|
||||
.filter((item) => item.text() === 'release.organization.title')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(openModalSpy).toHaveBeenCalledWith('release')
|
||||
@ -400,7 +400,7 @@ describe('ContentMenu.vue', () => {
|
||||
expect(
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'settings.name')
|
||||
.filter((item) => item.text() === 'settings.name')
|
||||
.at(0)
|
||||
.find('span.ds-menu-item-link')
|
||||
.attributes('to'),
|
||||
@ -418,7 +418,7 @@ describe('ContentMenu.vue', () => {
|
||||
})
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'settings.muted-users.mute')
|
||||
.filter((item) => item.text() === 'settings.muted-users.mute')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(wrapper.emitted('mute')).toEqual([
|
||||
@ -442,7 +442,7 @@ describe('ContentMenu.vue', () => {
|
||||
})
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter(item => item.text() === 'settings.muted-users.unmute')
|
||||
.filter((item) => item.text() === 'settings.muted-users.unmute')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(wrapper.emitted('unmute')).toEqual([
|
||||
|
||||
@ -46,7 +46,7 @@ export default {
|
||||
resourceType: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator: value => {
|
||||
validator: (value) => {
|
||||
return value.match(/(contribution|comment|organization|user)/)
|
||||
},
|
||||
},
|
||||
|
||||
@ -140,7 +140,9 @@ describe('ContributionForm.vue', () => {
|
||||
postTitleInput = wrapper.find('.ds-input')
|
||||
postTitleInput.setValue(postTitle)
|
||||
await wrapper.vm.updateEditorContent(postContent)
|
||||
englishLanguage = wrapper.findAll('li').filter(language => language.text() === 'English')
|
||||
englishLanguage = wrapper
|
||||
.findAll('li')
|
||||
.filter((language) => language.text() === 'English')
|
||||
englishLanguage.trigger('click')
|
||||
dataPrivacyButton = await wrapper
|
||||
.find(CategoriesSelect)
|
||||
@ -206,7 +208,9 @@ describe('ContributionForm.vue', () => {
|
||||
postTitleInput.setValue(postTitle)
|
||||
await wrapper.vm.updateEditorContent(postContent)
|
||||
wrapper.find(CategoriesSelect).setData({ categories })
|
||||
englishLanguage = wrapper.findAll('li').filter(language => language.text() === 'English')
|
||||
englishLanguage = wrapper
|
||||
.findAll('li')
|
||||
.filter((language) => language.text() === 'English')
|
||||
englishLanguage.trigger('click')
|
||||
await Vue.nextTick()
|
||||
dataPrivacyButton = await wrapper
|
||||
@ -223,7 +227,9 @@ describe('ContributionForm.vue', () => {
|
||||
|
||||
it('supports changing the language', async () => {
|
||||
expectedParams.variables.language = 'de'
|
||||
deutschLanguage = wrapper.findAll('li').filter(language => language.text() === 'Deutsch')
|
||||
deutschLanguage = wrapper
|
||||
.findAll('li')
|
||||
.filter((language) => language.text() === 'Deutsch')
|
||||
deutschLanguage.trigger('click')
|
||||
wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
|
||||
@ -237,7 +243,7 @@ describe('ContributionForm.vue', () => {
|
||||
}
|
||||
const spy = jest
|
||||
.spyOn(FileReader.prototype, 'readAsDataURL')
|
||||
.mockImplementation(function() {
|
||||
.mockImplementation(function () {
|
||||
this.onload({ target: { result: 'someUrlToImage' } })
|
||||
})
|
||||
wrapper.find(ImageUploader).vm.$emit('addHeroImage', imageUpload)
|
||||
@ -288,7 +294,9 @@ describe('ContributionForm.vue', () => {
|
||||
await wrapper.vm.updateEditorContent(postContent)
|
||||
categoryIds = ['cat12']
|
||||
wrapper.find(CategoriesSelect).setData({ categories })
|
||||
englishLanguage = wrapper.findAll('li').filter(language => language.text() === 'English')
|
||||
englishLanguage = wrapper
|
||||
.findAll('li')
|
||||
.filter((language) => language.text() === 'English')
|
||||
englishLanguage.trigger('click')
|
||||
await Vue.nextTick()
|
||||
dataPrivacyButton = await wrapper
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user