From 9c43d33732cb4812af9d5bb677d3f262dbbd97ad Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Tue, 15 Mar 2022 01:19:18 +0100 Subject: [PATCH 001/133] configure use of vue i18n eslint plugin --- frontend/.eslintrc.js | 15 ++- frontend/package.json | 1 + frontend/yarn.lock | 212 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 213 insertions(+), 15 deletions(-) diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index 96c602ef3..1cd68b9b6 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -8,7 +8,12 @@ module.exports = { parserOptions: { parser: 'babel-eslint', }, - extends: ['standard', 'plugin:vue/essential', 'plugin:prettier/recommended'], + extends: [ + 'standard', + 'plugin:vue/essential', + 'plugin:prettier/recommended', + 'plugin:@intlify/vue-i18n/recommended', + ], // required to lint *.vue files plugins: ['vue', 'prettier', 'jest'], // add your custom rules here @@ -29,4 +34,12 @@ module.exports = { }, ], }, + settings: { + 'vue-i18n': { + localeDir: './src/locales/*.json', + // Specify the version of `vue-i18n` you are using. + // If not specified, the message will be parsed twice. + messageSyntaxVersion: '^8.22.4', + }, + }, } diff --git a/frontend/package.json b/frontend/package.json index 69c843bf5..a948a8fec 100755 --- a/frontend/package.json +++ b/frontend/package.json @@ -67,6 +67,7 @@ "vuex-persistedstate": "^4.0.0-beta.3" }, "devDependencies": { + "@intlify/eslint-plugin-vue-i18n": "^1.4.0", "@vue/cli-plugin-babel": "^3.7.0", "@vue/cli-plugin-eslint": "^3.7.0", "@vue/cli-service": "^3.7.0", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index d0c486d4e..cd833a3df 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -1726,6 +1726,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.14.0": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.7.tgz#a5f3328dc41ff39d803f311cfe17703418cf9825" + integrity sha512-L6rvG9GDxaLgFjg41K+5Yv9OMrU98sWe+Ykmc6FDJW/+vYZMhdOMKkISgzptMaERHvS2Y2lw9MDRm2gHhlQQoA== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@7", "@babel/template@^7.12.13", "@babel/template@^7.16.0", "@babel/template@^7.3.3": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6" @@ -1875,6 +1882,21 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@eslint/eslintrc@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6" + integrity sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.3.1" + globals "^13.9.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + "@hapi/address@2.x.x": version "2.1.4" resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" @@ -1916,6 +1938,83 @@ cssnano-preset-default "^4.0.0" postcss "^7.0.0" +"@intlify/core-base@^9.1.9": + version "9.1.9" + resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-9.1.9.tgz#e4e8c951010728e4af3a0d13d74cf3f9e7add7f6" + integrity sha512-x5T0p/Ja0S8hs5xs+ImKyYckVkL4CzcEXykVYYV6rcbXxJTe2o58IquSqX9bdncVKbRZP7GlBU1EcRaQEEJ+vw== + dependencies: + "@intlify/devtools-if" "9.1.9" + "@intlify/message-compiler" "9.1.9" + "@intlify/message-resolver" "9.1.9" + "@intlify/runtime" "9.1.9" + "@intlify/shared" "9.1.9" + "@intlify/vue-devtools" "9.1.9" + +"@intlify/devtools-if@9.1.9": + version "9.1.9" + resolved "https://registry.yarnpkg.com/@intlify/devtools-if/-/devtools-if-9.1.9.tgz#a30e1dd1256ff2c5c98d8d75d075384fba898e5d" + integrity sha512-oKSMKjttG3Ut/1UGEZjSdghuP3fwA15zpDPcjkf/1FjlOIm6uIBGMNS5jXzsZy593u+P/YcnrZD6cD3IVFz9vQ== + dependencies: + "@intlify/shared" "9.1.9" + +"@intlify/eslint-plugin-vue-i18n@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@intlify/eslint-plugin-vue-i18n/-/eslint-plugin-vue-i18n-1.4.0.tgz#f8fe791892c2dce7d189a364b6a908c87e1c3ac9" + integrity sha512-anB1eBf6rpxpWyW883gi6O1hozQy4Q02VyzyodOUnohOqT07GATVSxnr2J9/qQSV47xWukV+9LiRErJcU7d/uA== + dependencies: + "@eslint/eslintrc" "^1.2.0" + "@intlify/core-base" "^9.1.9" + "@intlify/message-compiler" "^9.1.9" + debug "^4.3.1" + glob "^7.1.3" + ignore "^5.0.5" + is-language-code "^3.1.0" + js-yaml "^4.0.0" + json5 "^2.1.3" + jsonc-eslint-parser "^2.0.0" + lodash "^4.17.11" + parse5 "^6.0.0" + semver "^7.3.4" + vue-eslint-parser "^8.0.0" + yaml-eslint-parser "^0.5.0" + +"@intlify/message-compiler@9.1.9", "@intlify/message-compiler@^9.1.9": + version "9.1.9" + resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-9.1.9.tgz#1193cbd224a71c2fb981455b8534a3c766d2948d" + integrity sha512-6YgCMF46Xd0IH2hMRLCssZI3gFG4aywidoWQ3QP4RGYQXQYYfFC54DxhSgfIPpVoPLQ+4AD29eoYmhiHZ+qLFQ== + dependencies: + "@intlify/message-resolver" "9.1.9" + "@intlify/shared" "9.1.9" + source-map "0.6.1" + +"@intlify/message-resolver@9.1.9": + version "9.1.9" + resolved "https://registry.yarnpkg.com/@intlify/message-resolver/-/message-resolver-9.1.9.tgz#3155ccd2f5e6d0dc16cad8b7f1d8e97fcda05bfc" + integrity sha512-Lx/DBpigeK0sz2BBbzv5mu9/dAlt98HxwbG7xLawC3O2xMF9MNWU5FtOziwYG6TDIjNq0O/3ZbOJAxwITIWXEA== + +"@intlify/runtime@9.1.9": + version "9.1.9" + resolved "https://registry.yarnpkg.com/@intlify/runtime/-/runtime-9.1.9.tgz#2c12ce29518a075629efed0a8ed293ee740cb285" + integrity sha512-XgPw8+UlHCiie3fI41HPVa/VDJb3/aSH7bLhY1hJvlvNV713PFtb4p4Jo+rlE0gAoMsMCGcsiT982fImolSltg== + dependencies: + "@intlify/message-compiler" "9.1.9" + "@intlify/message-resolver" "9.1.9" + "@intlify/shared" "9.1.9" + +"@intlify/shared@9.1.9": + version "9.1.9" + resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.1.9.tgz#0baaf96128b85560666bec784ffb01f6623cc17a" + integrity sha512-xKGM1d0EAxdDFCWedcYXOm6V5Pfw/TMudd6/qCdEb4tv0hk9EKeg7lwQF1azE0dP2phvx0yXxrt7UQK+IZjNdw== + +"@intlify/vue-devtools@9.1.9": + version "9.1.9" + resolved "https://registry.yarnpkg.com/@intlify/vue-devtools/-/vue-devtools-9.1.9.tgz#2be8f4dbe7f7ed4115676eb32348141d411e426b" + integrity sha512-YPehH9uL4vZcGXky4Ev5qQIITnHKIvsD2GKGXgqf+05osMUI6WSEQHaN9USRa318Rs8RyyPCiDfmA0hRu3k7og== + dependencies: + "@intlify/message-resolver" "9.1.9" + "@intlify/runtime" "9.1.9" + "@intlify/shared" "9.1.9" + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -3192,6 +3291,11 @@ acorn@^8.2.4: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== +acorn@^8.5.0, acorn@^8.7.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== + address@^1.0.3: version "1.1.2" resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" @@ -3466,6 +3570,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -5504,7 +5613,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4.1.0, debug@^4.3.3: +debug@4, debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3: version "4.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== @@ -6409,6 +6518,14 @@ eslint-scope@^5.0.0, eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" +eslint-scope@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" + integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + eslint-utils@^2.0.0, eslint-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" @@ -6426,6 +6543,11 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== +eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.1.0, eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== + eslint@^4.19.1: version "4.19.1" resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" @@ -6544,6 +6666,15 @@ espree@^7.3.0, espree@^7.3.1: acorn-jsx "^5.3.1" eslint-visitor-keys "^1.3.0" +espree@^9.0.0, espree@^9.3.1: + version "9.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.1.tgz#8793b4bc27ea4c778c19908e0719e7b8f4115bcd" + integrity sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ== + dependencies: + acorn "^8.7.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^3.3.0" + esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -7401,6 +7532,13 @@ globals@^13.6.0: dependencies: type-fest "^0.20.2" +globals@^13.9.0: + version "13.12.1" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.1.tgz#ec206be932e6c77236677127577aa8e50bf1c5cb" + integrity sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw== + dependencies: + type-fest "^0.20.2" + globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -7939,16 +8077,16 @@ ignore@^4.0.3, ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +ignore@^5.0.5, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + ignore@^5.1.1, ignore@^5.1.4: version "5.1.8" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== -ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== - import-cwd@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" @@ -8329,6 +8467,13 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-language-code@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-language-code/-/is-language-code-3.1.0.tgz#b2386b49227e7010636f16d0c2c681ca40136ab5" + integrity sha512-zJdQ3QTeLye+iphMeK3wks+vXSRFKh68/Pnlw7aOfApFSEIOhYa8P9vwwa6QrImNNBMJTiL1PpYF0f4BxDuEgA== + dependencies: + "@babel/runtime" "^7.14.0" + is-negative-zero@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" @@ -9551,6 +9696,13 @@ js-yaml@^3.13.1, js-yaml@^3.9.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.0.0, js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -9740,7 +9892,7 @@ json3@^3.3.3: resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== -json5@2.x, json5@^2.1.2: +json5@2.x, json5@^2.1.2, json5@^2.1.3: version "2.2.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== @@ -9759,6 +9911,16 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +jsonc-eslint-parser@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/jsonc-eslint-parser/-/jsonc-eslint-parser-2.1.0.tgz#4c126b530aa583d85308d0b3041ff81ce402bbb2" + integrity sha512-qCRJWlbP2v6HbmKW7R3lFbeiVWHo+oMJ0j+MizwvauqnCV/EvtAeEeuCgoc/ErtsuoKgYB8U4Ih8AxJbXoE6/g== + dependencies: + acorn "^8.5.0" + eslint-visitor-keys "^3.0.0" + espree "^9.0.0" + semver "^7.3.5" + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -11104,7 +11266,7 @@ parse5@5.1.0: resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== -parse5@6.0.1, parse5@^6.0.1: +parse5@6.0.1, parse5@^6.0.0, parse5@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== @@ -12968,16 +13130,16 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== +source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - source-map@^0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" @@ -14340,6 +14502,19 @@ vue-eslint-parser@^7.6.0: esquery "^1.4.0" lodash "^4.17.15" +vue-eslint-parser@^8.0.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz#5d31129a1b3dd89c0069ca0a1c88f970c360bd0d" + integrity sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g== + dependencies: + debug "^4.3.2" + eslint-scope "^7.0.0" + eslint-visitor-keys "^3.1.0" + espree "^9.0.0" + esquery "^1.4.0" + lodash "^4.17.21" + semver "^7.3.5" + vue-flatpickr-component@^8.1.2: version "8.1.6" resolved "https://registry.yarnpkg.com/vue-flatpickr-component/-/vue-flatpickr-component-8.1.6.tgz#8fb25dc72946ceb1ab005b871a8151461c0883f6" @@ -14979,7 +15154,16 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.10.0: +yaml-eslint-parser@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/yaml-eslint-parser/-/yaml-eslint-parser-0.5.0.tgz#01d4e4d992a820769ea85ef5fd526dfc20ebc6f5" + integrity sha512-nJeyLA3YHAzhBTZbRAbu3W6xrSCucyxExmA+ZDtEdUFpGllxAZpto2Zxo2IG0r0eiuEiBM4e+wiAdxTziTq94g== + dependencies: + eslint-visitor-keys "^3.0.0" + lodash "^4.17.21" + yaml "^1.10.2" + +yaml@^1.10.0, yaml@^1.10.2: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== From 15981da64b6bb39f83667bdc75f158aaac64af1b Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Tue, 15 Mar 2022 02:53:59 +0100 Subject: [PATCH 002/133] no more lint warnings --- .../DecayInformation-Decay.vue | 2 +- .../DecayInformation-DecayStartblock.vue | 3 +- .../DecayInformation-Long.vue | 1 - frontend/src/components/GddSend/QrCode.vue | 2 + .../GddSend/TransactionConfirmationLink.vue | 6 ++- .../GddSend/TransactionConfirmationSend.vue | 4 +- .../components/GddSend/TransactionForm.vue | 2 +- .../GddSend/TransactionResultSendError.vue | 2 +- .../components/GddTransactionListFooter.vue | 4 +- frontend/src/components/Menu/Navbar.spec.js | 26 ++++----- frontend/src/components/Menu/Navbar.vue | 24 +++++---- frontend/src/components/Menu/Sidebar.spec.js | 26 ++++----- frontend/src/components/Menu/Sidebar.vue | 18 ++++--- frontend/src/components/PaginationButtons.vue | 2 +- frontend/src/components/Status.vue | 2 +- frontend/src/components/Transaction.vue | 2 +- .../components/TransactionRows/DateRow.vue | 1 - frontend/src/components/UserCard.vue | 6 +-- frontend/src/layouts/ContentFooter.spec.js | 2 +- frontend/src/layouts/ContentFooter.vue | 20 +++---- frontend/src/locales/de.json | 51 ++++++++++++------ frontend/src/locales/en.json | 53 ++++++++++++------- frontend/src/pages/Login.vue | 2 +- frontend/src/pages/Register.vue | 7 ++- frontend/src/validation-rules.js | 4 ++ 25 files changed, 158 insertions(+), 114 deletions(-) diff --git a/frontend/src/components/DecayInformations/DecayInformation-Decay.vue b/frontend/src/components/DecayInformations/DecayInformation-Decay.vue index 19aac9e98..7377b6fa8 100644 --- a/frontend/src/components/DecayInformations/DecayInformation-Decay.vue +++ b/frontend/src/components/DecayInformations/DecayInformation-Decay.vue @@ -14,7 +14,7 @@
{{ (Number(balance) - Number(decay.decay)) | GDD }} - {{ decay.decay | GDD }} = + {{ decay.decay | GDD }} {{ $t('math.equal') }} {{ balance | GDD }}
diff --git a/frontend/src/components/DecayInformations/DecayInformation-DecayStartblock.vue b/frontend/src/components/DecayInformations/DecayInformation-DecayStartblock.vue index 2ee9ecc2c..b7d8a42c0 100644 --- a/frontend/src/components/DecayInformations/DecayInformation-DecayStartblock.vue +++ b/frontend/src/components/DecayInformations/DecayInformation-DecayStartblock.vue @@ -4,12 +4,11 @@
{{ $t('decay.Starting_block_decay') }}
-
{{ $t('decay.decay_introduced') }} :
+
{{ $t('decay.decay_introduced') }}
{{ $d(new Date(decay.start), 'long') }} - {{ $i18n.locale === 'de' ? 'Uhr' : '' }}
diff --git a/frontend/src/components/DecayInformations/DecayInformation-Long.vue b/frontend/src/components/DecayInformations/DecayInformation-Long.vue index b5e1bbbe5..033d73560 100644 --- a/frontend/src/components/DecayInformations/DecayInformation-Long.vue +++ b/frontend/src/components/DecayInformations/DecayInformation-Long.vue @@ -15,7 +15,6 @@
{{ $d(new Date(decay.start), 'long') }} - {{ $i18n.locale === 'de' ? 'Uhr' : '' }}
diff --git a/frontend/src/components/GddSend/QrCode.vue b/frontend/src/components/GddSend/QrCode.vue index 0146621ed..32e527cfe 100644 --- a/frontend/src/components/GddSend/QrCode.vue +++ b/frontend/src/components/GddSend/QrCode.vue @@ -1,5 +1,6 @@ From 83b1c4c9e19517bccd0e59ea8040888de07b6a18 Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 15 Mar 2022 15:55:23 +0100 Subject: [PATCH 030/133] change position from visible on collapse in TransactionLinksSummary.vue --- .../src/components/Transactions/TransactionLinksSummary.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/Transactions/TransactionLinksSummary.vue b/frontend/src/components/Transactions/TransactionLinksSummary.vue index d10311e3a..dff7cff3a 100644 --- a/frontend/src/components/Transactions/TransactionLinksSummary.vue +++ b/frontend/src/components/Transactions/TransactionLinksSummary.vue @@ -1,9 +1,9 @@ From 81df36a3fb65b4133e8edcd9f74934135b2f0f22 Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 15 Mar 2022 17:15:47 +0100 Subject: [PATCH 038/133] ad function deleteLink and bvModal confirm --- .../TransactionLinks/TransactionLink.vue | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/TransactionLinks/TransactionLink.vue b/frontend/src/components/TransactionLinks/TransactionLink.vue index 966fc3f54..d6dfb84f0 100644 --- a/frontend/src/components/TransactionLinks/TransactionLink.vue +++ b/frontend/src/components/TransactionLinks/TransactionLink.vue @@ -18,7 +18,7 @@ {{ $moment(item.validUntil).fromNow() }} kopieren - löschen + löschen @@ -41,7 +41,8 @@ export default { }, }) .then((result) => { - console.log(result.data) + this.toastSuccess('Link gelöscht') + this.$emit('update-list-transaction-links') }) .catch((err) => { this.toastError(err.message) @@ -58,6 +59,16 @@ export default { this.toastError(this.$t('gdd_per_link.not-copied')) }) }, + deleteLink(id) { + this.$bvModal + .msgBoxConfirm('Den Link löschen?') + .then(() => { + this.deleteTransactionLink(id) + }) + .catch((err) => { + console.log(err) + }) + }, }, } From baf4f66604a0f7d220e0e653974512d1fd32c4c9 Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 15 Mar 2022 17:16:35 +0100 Subject: [PATCH 039/133] ad function updateListTransactionLinks on TransactionLinksSummary.vue --- .../Transactions/TransactionLinksSummary.vue | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/Transactions/TransactionLinksSummary.vue b/frontend/src/components/Transactions/TransactionLinksSummary.vue index dff7cff3a..c4496ed0d 100644 --- a/frontend/src/components/Transactions/TransactionLinksSummary.vue +++ b/frontend/src/components/Transactions/TransactionLinksSummary.vue @@ -24,7 +24,10 @@ - + @@ -69,7 +72,7 @@ export default { } }, methods: { - async listTransactionLinks() { + async updateListTransactionLinks() { this.$apollo .query({ query: listTransactionLinks, @@ -81,6 +84,7 @@ export default { }) .then((result) => { this.transactionLinks = result.data.listTransactionLinks + this.$emit('update-transactions') }) .catch((err) => { this.toastError(err.message) @@ -88,7 +92,7 @@ export default { }, }, created() { - this.listTransactionLinks() + this.updateListTransactionLinks() }, } From 9bd74cb1488bf76ed9bd0f7a150752fcd90b49f5 Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 15 Mar 2022 17:18:32 +0100 Subject: [PATCH 040/133] yarn lint --fix --- frontend/src/components/TransactionLinks/TransactionLink.vue | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frontend/src/components/TransactionLinks/TransactionLink.vue b/frontend/src/components/TransactionLinks/TransactionLink.vue index d6dfb84f0..0ff13a1a0 100644 --- a/frontend/src/components/TransactionLinks/TransactionLink.vue +++ b/frontend/src/components/TransactionLinks/TransactionLink.vue @@ -65,9 +65,7 @@ export default { .then(() => { this.deleteTransactionLink(id) }) - .catch((err) => { - console.log(err) - }) + .catch(() => {}) }, }, } From 7e645e08fa4f572156b149f6fa21d39b708f197b Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 15 Mar 2022 17:40:37 +0100 Subject: [PATCH 041/133] pass ApolloServerTestClient as first argument of factories --- backend/src/seeds/factory/user.ts | 11 +++++++---- backend/src/seeds/index.ts | 7 +++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/backend/src/seeds/factory/user.ts b/backend/src/seeds/factory/user.ts index 89bff6852..6d81f26a6 100644 --- a/backend/src/seeds/factory/user.ts +++ b/backend/src/seeds/factory/user.ts @@ -1,13 +1,16 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ - import { createUser, setPassword } from '@/seeds/graphql/mutations' import { User } from '@entity/User' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' import { ServerUser } from '@entity/ServerUser' import { UserInterface } from '@/seeds/users/UserInterface' +import { ApolloServerTestClient } from 'apollo-server-testing' + +export const userFactory = async ( + client: ApolloServerTestClient, + user: UserInterface, +): Promise => { + const { mutate } = client -export const createUserFactory = async (mutate: any, user: UserInterface): Promise => { await mutate({ mutation: createUser, variables: user }) let dbUser = await User.findOneOrFail({ where: { email: user.email } }) diff --git a/backend/src/seeds/index.ts b/backend/src/seeds/index.ts index b68bcbdd9..28660912a 100644 --- a/backend/src/seeds/index.ts +++ b/backend/src/seeds/index.ts @@ -7,7 +7,7 @@ import { createTestClient } from 'apollo-server-testing' import { name, internet, random } from 'faker' import { users } from './users/index' -import { createUserFactory } from './factory/user' +import { userFactory } from './factory/user' import { entities } from '@entity/index' const context = { @@ -39,18 +39,17 @@ const resetEntity = async (entity: any) => { const run = async () => { const server = await createServer(context) const testClient = createTestClient(server.apollo) - const { mutate } = testClient const { con } = server await cleanDB() // seed the standard users for (let i = 0; i < users.length; i++) { - await createUserFactory(mutate, users[i]) + await userFactory(testClient, users[i]) } // seed 100 random users for (let i = 0; i < 100; i++) { - await createUserFactory(mutate, { + await userFactory(testClient, { firstName: name.firstName(), lastName: name.lastName(), email: internet.email(), From fef7c6b8cc1fc52b5f25df6041b1bbe49286257e Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 15 Mar 2022 17:41:22 +0100 Subject: [PATCH 042/133] rename userFactory --- backend/src/graphql/resolver/UserResolver.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 61625a8ae..983dff52a 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -2,7 +2,7 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { testEnvironment, headerPushMock, resetToken, cleanDB } from '@test/helpers' -import { createUserFactory } from '@/seeds/factory/user' +import { userFactory } from '@/seeds/factory/user' import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' import { createUser, setPassword } from '@/seeds/graphql/mutations' import { login, logout } from '@/seeds/graphql/queries' @@ -312,7 +312,7 @@ describe('UserResolver', () => { describe('user is in database and correct login data', () => { beforeAll(async () => { - await createUserFactory(mutate, bibiBloxberg) + await userFactory(mutate, bibiBloxberg) result = await query({ query: login, variables }) }) @@ -349,7 +349,7 @@ describe('UserResolver', () => { describe('user is in database and wrong password', () => { beforeAll(async () => { - await createUserFactory(mutate, bibiBloxberg) + await userFactory(mutate, bibiBloxberg) }) afterAll(async () => { @@ -387,7 +387,7 @@ describe('UserResolver', () => { } beforeAll(async () => { - await createUserFactory(mutate, bibiBloxberg) + await userFactory(mutate, bibiBloxberg) await query({ query: login, variables }) }) From 05a65aa98f56248bfddbf42e4d22d90636609779 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 15 Mar 2022 17:41:54 +0100 Subject: [PATCH 043/133] add mutations from admin interface --- backend/src/seeds/graphql/mutations.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index 8f425cdec..32232e410 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -69,3 +69,29 @@ export const createTransactionLink = gql` } } ` + +// from admin interface + +export const createPendingCreation = gql` + mutation ( + $email: String! + $amount: Float! + $memo: String! + $creationDate: String! + $moderator: Int! + ) { + createPendingCreation( + email: $email + amount: $amount + memo: $memo + creationDate: $creationDate + moderator: $moderator + ) + } +` + +export const confirmPendingCreation = gql` + mutation ($id: Float!) { + confirmPendingCreation(id: $id) + } +` From a23426649374cafc8d73791c5301be8a0ee03a47 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 15 Mar 2022 19:28:46 +0100 Subject: [PATCH 044/133] seed simple confired creations --- .../src/seeds/creation/CreationInterface.ts | 7 ++++ backend/src/seeds/creation/index.ts | 29 ++++++++++++++ backend/src/seeds/factory/creation.ts | 38 +++++++++++++++++++ backend/src/seeds/index.ts | 17 ++++++--- 4 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 backend/src/seeds/creation/CreationInterface.ts create mode 100644 backend/src/seeds/creation/index.ts create mode 100644 backend/src/seeds/factory/creation.ts diff --git a/backend/src/seeds/creation/CreationInterface.ts b/backend/src/seeds/creation/CreationInterface.ts new file mode 100644 index 000000000..8723f441d --- /dev/null +++ b/backend/src/seeds/creation/CreationInterface.ts @@ -0,0 +1,7 @@ +export interface CreationInterface { + email: string + amount: number + memo: string + creationDate: string + confirmed?: boolean +} diff --git a/backend/src/seeds/creation/index.ts b/backend/src/seeds/creation/index.ts new file mode 100644 index 000000000..7396a7ec8 --- /dev/null +++ b/backend/src/seeds/creation/index.ts @@ -0,0 +1,29 @@ +import { CreationInterface } from './CreationInterface' + +const lastMonth = (date: Date): string => { + return new Date(date.getFullYear(), date.getMonth() - 1, 1).toISOString() +} + +export const creations: CreationInterface[] = [ + { + email: 'bibi@bloxberg.de', + amount: 1000, + memo: 'Herzlich Willkommen bei Gradido!', + creationDate: lastMonth(new Date()), + confirmed: true, + }, + { + email: 'bob@baumeister.de', + amount: 1000, + memo: 'Herzlich Willkommen bei Gradido!', + creationDate: lastMonth(new Date()), + confirmed: true, + }, + { + email: 'raeuber@hotzenplotz.de', + amount: 1000, + memo: 'Herzlich Willkommen bei Gradido!', + creationDate: lastMonth(new Date()), + confirmed: true, + }, +] diff --git a/backend/src/seeds/factory/creation.ts b/backend/src/seeds/factory/creation.ts new file mode 100644 index 000000000..52b63b193 --- /dev/null +++ b/backend/src/seeds/factory/creation.ts @@ -0,0 +1,38 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ + +import { createPendingCreation, confirmPendingCreation } from '@/seeds/graphql/mutations' +import { login } from '@/seeds/graphql/queries' +import { CreationInterface } from '@/seeds/creation/CreationInterface' +import { ApolloServerTestClient } from 'apollo-server-testing' +import { User } from '@entity/User' +import { AdminPendingCreation } from '@entity/AdminPendingCreation' +// import CONFIG from '@/config/index' + +export const creationFactory = async ( + client: ApolloServerTestClient, + creation: CreationInterface, +): Promise => { + const { mutate, query } = client + + // get Peter Lustig + const peterLustig = await User.findOneOrFail({ where: { email: 'peter@lustig.de' } }) + const variables = { ...creation, moderator: peterLustig.id } + + // login as Peter Lustig (admin) + await query({ query: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' } }) + + await mutate({ mutation: createPendingCreation, variables }) + + // get User + const user = await User.findOneOrFail({ where: { email: creation.email } }) + + if (creation.confirmed) { + const pendingCreation = await AdminPendingCreation.findOneOrFail({ + where: { userId: user.id }, + order: { created: 'DESC' }, + }) + + await mutate({ mutation: confirmPendingCreation, variables: { id: pendingCreation.id } }) + } +} diff --git a/backend/src/seeds/index.ts b/backend/src/seeds/index.ts index 28660912a..3943a63e0 100644 --- a/backend/src/seeds/index.ts +++ b/backend/src/seeds/index.ts @@ -7,14 +7,16 @@ import { createTestClient } from 'apollo-server-testing' import { name, internet, random } from 'faker' import { users } from './users/index' +import { creations } from './creation/index' import { userFactory } from './factory/user' +import { creationFactory } from './factory/creation' import { entities } from '@entity/index' const context = { token: '', setHeaders: { - push: (value: string): void => { - context.token = value + push: (value: { key: string; value: string }): void => { + context.token = value.value }, // eslint-disable-next-line @typescript-eslint/no-empty-function forEach: (): void => {}, @@ -38,18 +40,18 @@ const resetEntity = async (entity: any) => { const run = async () => { const server = await createServer(context) - const testClient = createTestClient(server.apollo) + const seedClient = createTestClient(server.apollo) const { con } = server await cleanDB() // seed the standard users for (let i = 0; i < users.length; i++) { - await userFactory(testClient, users[i]) + await userFactory(seedClient, users[i]) } // seed 100 random users for (let i = 0; i < 100; i++) { - await userFactory(testClient, { + await userFactory(seedClient, { firstName: name.firstName(), lastName: name.lastName(), email: internet.email(), @@ -57,6 +59,11 @@ const run = async () => { }) } + // create GDD + for (let i = 0; i < creations.length; i++) { + await creationFactory(seedClient, creations[i]) + } + await con.close() } From 5e8e885841157abb2ebe48b495b983b207a72792 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 15 Mar 2022 20:32:33 +0100 Subject: [PATCH 045/133] fix test --- backend/src/graphql/resolver/UserResolver.test.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 983dff52a..1e1e266fb 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -11,6 +11,7 @@ import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' import { User } from '@entity/User' import CONFIG from '@/config' import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail' + // import { klicktippSignIn } from '@/apis/KlicktippController' jest.mock('@/mailer/sendAccountActivationEmail', () => { @@ -30,9 +31,10 @@ jest.mock('@/apis/KlicktippController', () => { */ let mutate: any, query: any, con: any +let testEnv: any beforeAll(async () => { - const testEnv = await testEnvironment() + testEnv = await testEnvironment() mutate = testEnv.mutate query = testEnv.query con = testEnv.con @@ -312,7 +314,7 @@ describe('UserResolver', () => { describe('user is in database and correct login data', () => { beforeAll(async () => { - await userFactory(mutate, bibiBloxberg) + await userFactory(testEnv, bibiBloxberg) result = await query({ query: login, variables }) }) @@ -349,7 +351,7 @@ describe('UserResolver', () => { describe('user is in database and wrong password', () => { beforeAll(async () => { - await userFactory(mutate, bibiBloxberg) + await userFactory(testEnv, bibiBloxberg) }) afterAll(async () => { @@ -387,7 +389,7 @@ describe('UserResolver', () => { } beforeAll(async () => { - await userFactory(mutate, bibiBloxberg) + await userFactory(testEnv, bibiBloxberg) await query({ query: login, variables }) }) From 12f3a7ab4abe56cae81664757070db4508753088 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 15 Mar 2022 21:03:55 +0100 Subject: [PATCH 046/133] set up seed for transaction links --- backend/src/seeds/factory/transactionLink.ts | 21 +++++++++++++++++++ backend/src/seeds/index.ts | 7 +++++++ .../TransactionLinkInterface.ts | 5 +++++ backend/src/seeds/transactionLink/index.ts | 10 +++++++++ 4 files changed, 43 insertions(+) create mode 100644 backend/src/seeds/factory/transactionLink.ts create mode 100644 backend/src/seeds/transactionLink/TransactionLinkInterface.ts create mode 100644 backend/src/seeds/transactionLink/index.ts diff --git a/backend/src/seeds/factory/transactionLink.ts b/backend/src/seeds/factory/transactionLink.ts new file mode 100644 index 000000000..c1ea13915 --- /dev/null +++ b/backend/src/seeds/factory/transactionLink.ts @@ -0,0 +1,21 @@ +import { ApolloServerTestClient } from 'apollo-server-testing' +import { createTransactionLink } from '@/seeds/graphql/mutations' +import { login } from '@/seeds/graphql/queries' +import { TransactionLinkInterface } from '@/seeds/transactionLink/TransactionLinkInterface' + +export const transactionLinkFactory = async ( + client: ApolloServerTestClient, + transactionLink: TransactionLinkInterface, +): Promise => { + const { mutate, query } = client + + // login + await query({ query: login, variables: { email: transactionLink.email, password: 'Aa12345_' } }) + + const variables = { + amount: transactionLink.amount, + memo: transactionLink.memo, + } + + await mutate({ mutation: createTransactionLink, variables }) +} diff --git a/backend/src/seeds/index.ts b/backend/src/seeds/index.ts index 3943a63e0..37c9992a7 100644 --- a/backend/src/seeds/index.ts +++ b/backend/src/seeds/index.ts @@ -8,8 +8,10 @@ import { name, internet, random } from 'faker' import { users } from './users/index' import { creations } from './creation/index' +import { transactionLinks } from './transactionLink/index' import { userFactory } from './factory/user' import { creationFactory } from './factory/creation' +import { transactionLinkFactory } from './factory/transactionLink' import { entities } from '@entity/index' const context = { @@ -64,6 +66,11 @@ const run = async () => { await creationFactory(seedClient, creations[i]) } + // create Transaction Links + for (let i = 0; i < transactionLinks.length; i++) { + await transactionLinkFactory(seedClient, transactionLinks[i]) + } + await con.close() } diff --git a/backend/src/seeds/transactionLink/TransactionLinkInterface.ts b/backend/src/seeds/transactionLink/TransactionLinkInterface.ts new file mode 100644 index 000000000..94b14992b --- /dev/null +++ b/backend/src/seeds/transactionLink/TransactionLinkInterface.ts @@ -0,0 +1,5 @@ +export interface TransactionLinkInterface { + email: string + amount: number + memo: string +} diff --git a/backend/src/seeds/transactionLink/index.ts b/backend/src/seeds/transactionLink/index.ts new file mode 100644 index 000000000..cd952c47f --- /dev/null +++ b/backend/src/seeds/transactionLink/index.ts @@ -0,0 +1,10 @@ +import { TransactionLinkInterface } from './TransactionLinkInterface' + +export const transactionLinks: TransactionLinkInterface[] = [ + { + email: 'bibi@bloxberg.de', + amount: 19.99, + memo: `Kein Trick, keine Zauberrei, +bei Gradidio sei dabei!`, + }, +] From 5b9463ca2a20b31278d99b7244d0fadd7058ee27 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 15 Mar 2022 21:24:44 +0100 Subject: [PATCH 047/133] seed deleted and outdated transaction links --- .../resolver/TransactionLinkResolver.ts | 2 +- backend/src/seeds/factory/transactionLink.ts | 22 ++++++++++ .../TransactionLinkInterface.ts | 2 + backend/src/seeds/transactionLink/index.ts | 42 +++++++++++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts index 9e2af6111..32f30807b 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts @@ -29,7 +29,7 @@ export const transactionLinkCode = (date: Date): string => { const CODE_VALID_DAYS_DURATION = 14 -const transactionLinkExpireDate = (date: Date): Date => { +export const transactionLinkExpireDate = (date: Date): Date => { const validUntil = new Date(date) return new Date(validUntil.setDate(date.getDate() + CODE_VALID_DAYS_DURATION)) } diff --git a/backend/src/seeds/factory/transactionLink.ts b/backend/src/seeds/factory/transactionLink.ts index c1ea13915..665ae03f3 100644 --- a/backend/src/seeds/factory/transactionLink.ts +++ b/backend/src/seeds/factory/transactionLink.ts @@ -2,6 +2,9 @@ import { ApolloServerTestClient } from 'apollo-server-testing' import { createTransactionLink } from '@/seeds/graphql/mutations' import { login } from '@/seeds/graphql/queries' import { TransactionLinkInterface } from '@/seeds/transactionLink/TransactionLinkInterface' +import { transactionLinkExpireDate } from '@/graphql/resolver/TransactionLinkResolver' +import { TransactionLink } from '@entity/TransactionLink' +import { User } from '@entity/User' export const transactionLinkFactory = async ( client: ApolloServerTestClient, @@ -18,4 +21,23 @@ export const transactionLinkFactory = async ( } await mutate({ mutation: createTransactionLink, variables }) + + if (transactionLink.createdAt || transactionLink.deletedAt) { + const user = await User.findOneOrFail({ where: { email: transactionLink.email } }) + const dbTransactionLink = await TransactionLink.findOneOrFail({ + where: { userId: user.id }, + order: { createdAt: 'DESC' }, + }) + + if (transactionLink.createdAt) { + dbTransactionLink.createdAt = transactionLink.createdAt + dbTransactionLink.validUntil = transactionLinkExpireDate(transactionLink.createdAt) + await dbTransactionLink.save() + } + + if (transactionLink.deletedAt) { + dbTransactionLink.deletedAt = new Date() + await dbTransactionLink.save() + } + } } diff --git a/backend/src/seeds/transactionLink/TransactionLinkInterface.ts b/backend/src/seeds/transactionLink/TransactionLinkInterface.ts index 94b14992b..ddc835b33 100644 --- a/backend/src/seeds/transactionLink/TransactionLinkInterface.ts +++ b/backend/src/seeds/transactionLink/TransactionLinkInterface.ts @@ -2,4 +2,6 @@ export interface TransactionLinkInterface { email: string amount: number memo: string + createdAt?: Date + deletedAt?: boolean } diff --git a/backend/src/seeds/transactionLink/index.ts b/backend/src/seeds/transactionLink/index.ts index cd952c47f..25755c0f2 100644 --- a/backend/src/seeds/transactionLink/index.ts +++ b/backend/src/seeds/transactionLink/index.ts @@ -1,10 +1,52 @@ import { TransactionLinkInterface } from './TransactionLinkInterface' export const transactionLinks: TransactionLinkInterface[] = [ + { + email: 'bibi@bloxberg.de', + amount: 19.99, + memo: 'Leider wollte niemand meine Gradidos zum Neujahr haben :(', + createdAt: new Date(2022, 0, 1), + }, { email: 'bibi@bloxberg.de', amount: 19.99, memo: `Kein Trick, keine Zauberrei, bei Gradidio sei dabei!`, }, + { + email: 'bibi@bloxberg.de', + amount: 19.99, + memo: `Kein Trick, keine Zauberrei, +bei Gradidio sei dabei!`, + }, + { + email: 'bibi@bloxberg.de', + amount: 19.99, + memo: `Kein Trick, keine Zauberrei, +bei Gradidio sei dabei!`, + }, + { + email: 'bibi@bloxberg.de', + amount: 19.99, + memo: `Kein Trick, keine Zauberrei, +bei Gradidio sei dabei!`, + }, + { + email: 'bibi@bloxberg.de', + amount: 19.99, + memo: `Kein Trick, keine Zauberrei, +bei Gradidio sei dabei!`, + }, + { + email: 'bibi@bloxberg.de', + amount: 19.99, + memo: `Kein Trick, keine Zauberrei, +bei Gradidio sei dabei!`, + }, + { + email: 'bibi@bloxberg.de', + amount: 19.99, + memo: 'Da habe ich mich wohl etwas übernommen.', + deletedAt: true, + }, ] From 0f97dc60a35cf94a97fdeb152b2f8854aa0f0281 Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 15 Mar 2022 22:13:50 +0100 Subject: [PATCH 048/133] Duplicate id app deleted --- frontend/public/index.html | 4 ---- 1 file changed, 4 deletions(-) diff --git a/frontend/public/index.html b/frontend/public/index.html index a15b46916..b9abe3876 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -52,10 +52,6 @@ -
- -
- From fe733c3f7705a1afd95a969ccd787af5c4838121 Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 15 Mar 2022 22:14:20 +0100 Subject: [PATCH 049/133] toast rendering error fixed --- frontend/src/mixins/toaster.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/mixins/toaster.js b/frontend/src/mixins/toaster.js index 68fd78ff9..f6e61e5be 100644 --- a/frontend/src/mixins/toaster.js +++ b/frontend/src/mixins/toaster.js @@ -14,7 +14,7 @@ export const toasters = { }, toast(message, options) { if (message.replace) message = message.replace(/^GraphQL error: /, '') - this.$bvToast.toast(message, { + this.$root.$bvToast.toast(message, { autoHideDelay: 5000, appendToast: true, solid: true, From cf601fc5b31842056f32af426d06d39cdcb8b262 Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 15 Mar 2022 22:15:30 +0100 Subject: [PATCH 050/133] toast rendering error fixed in adminarea --- admin/src/mixins/toaster.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/src/mixins/toaster.js b/admin/src/mixins/toaster.js index 9f79b91e8..2db632a81 100644 --- a/admin/src/mixins/toaster.js +++ b/admin/src/mixins/toaster.js @@ -15,7 +15,7 @@ export const toasters = { toast(message, options) { // for unit tests, check that replace is present if (message.replace) message = message.replace(/^GraphQL error: /, '') - this.$bvToast.toast(message, { + this.$root.$bvToast.toast(message, { autoHideDelay: 5000, appendToast: true, solid: true, From 41295bb9744e59752cc87ad7732ab4a9a0f0befb Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 16 Mar 2022 02:33:52 +0100 Subject: [PATCH 051/133] fix missing locale --- frontend/src/locales/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 85e0f8702..ef1cb1498 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -22,7 +22,7 @@ "Starting_block_decay": "Starting Block Decay", "total": "Total", "types": { - "creation": "Created", + "created": "Created", "noDecay": "No Decay", "receive": "Received", "send": "Sent" From cede263dc44c63ecf68331c22a3b6c21772644c5 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 16 Mar 2022 02:34:09 +0100 Subject: [PATCH 052/133] use .gitignore as .eslintignore --- frontend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/package.json b/frontend/package.json index 6ccf37d09..17b35739c 100755 --- a/frontend/package.json +++ b/frontend/package.json @@ -8,7 +8,7 @@ "build": "vue-cli-service build", "dev": "yarn run serve", "analyse-bundle": "yarn build && webpack-bundle-analyzer dist/webpack.stats.json", - "lint": "eslint --max-warnings=0 --ext .js,.vue,.json .", + "lint": "eslint --max-warnings=0 --ext .js,.vue,.json --ignore-path .gitignore .", "stylelint": "stylelint --max-warnings=0 '**/*.{scss,vue}'", "test": "TZ=UTC jest --coverage", "locales": "scripts/sort.sh" From 90287eff17f28cfec861b85861061f4c1cc62166 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 16 Mar 2022 03:13:32 +0100 Subject: [PATCH 053/133] have all dynamic keys ignored and readded to the language files --- frontend/.eslintrc.js | 15 ++++++++++++-- frontend/src/locales/de.json | 16 +++++++++++++-- frontend/src/locales/en.json | 16 +++++++++++++-- frontend/src/pages/ForgotPassword.vue | 29 +++++---------------------- 4 files changed, 46 insertions(+), 30 deletions(-) diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index f3b213295..4e45ede62 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -38,13 +38,24 @@ module.exports = { }, ], '@intlify/vue-i18n/no-dynamic-keys': 'error', - // TODO: no ignores '@intlify/vue-i18n/no-unused-keys': [ 'error', { src: './src', extensions: ['.js', '.vue'], - ignores: ['/site.thx./', '/form./', '/time./', '/decay.types./'], + // TODO: remove ignores + ignores: [ + '/site.thx./', + '/form./', + '/time./', + '/decay.types./', + 'settings.password.resend_subtitle', + 'settings.password.reset-password.text', + 'settings.password.set', + 'settings.password.set-password.text', + 'settings.password.subtitle', + 'site.login.signin', + ], enableFix: false, }, ], diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 1875ecce6..47076886d 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -165,7 +165,18 @@ }, "password": { "change-password": "Passwort ändern", - "forgot_pwd": "Passwort vergessen?" + "forgot_pwd": "Passwort vergessen?", + "resend_subtitle": "Dein Aktivierungslink ist abgelaufen. Du kannst hier ein neuen anfordern.", + "reset": "Passwort zurücksetzen", + "reset-password": { + "text": "Gib nun ein neues Passwort ein, mit dem du dich zukünftig in deinem Gradido-Konto anmelden willst." + }, + "send_now": "Jetzt senden", + "set": "Passwort festlegen", + "set-password": { + "text": "Speichere nun dein neues Passwort, mit dem du dich zukünftig in deinem Gradido-Konto anmelden kannst." + }, + "subtitle": "Wenn du dein Passwort vergessen hast, kannst du es hier zurücksetzen." } }, "signup": "Registrieren", @@ -173,7 +184,8 @@ "login": { "community": "Tausend Dank, weil du bei uns bist!", "heading": "Gradido", - "new_wallet": "Neues Konto erstellen" + "new_wallet": "Neues Konto erstellen", + "signin": "Anmelden" }, "signup": { "agree": "Ich stimme der Datenschutzerklärung zu.", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index ef1cb1498..fe227cb9d 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -165,7 +165,18 @@ }, "password": { "change-password": "Change password", - "forgot_pwd": "Forgot password?" + "forgot_pwd": "Forgot password?", + "resend_subtitle": "Your activation link has expired, here you can order a new one.", + "reset": "Reset password", + "reset-password": { + "text": "Enter a new password that you will use to log in to your Gradido account in the future.." + }, + "set": "Set password", + "set-password": { + "text": "Now save your new password, which you can use to log in to your Gradido account in the future." + }, + "send_now": "Send now", + "subtitle": "If you have forgotten your password, you can reset it here." } }, "signup": "Sign up", @@ -173,7 +184,8 @@ "login": { "community": "A thousand thanks for being with us!", "heading": "Gradido", - "new_wallet": "Create new account" + "new_wallet": "Create new account", + "signin": "Sign in" }, "signup": { "agree": "I agree to the privacy policy.", diff --git a/frontend/src/pages/ForgotPassword.vue b/frontend/src/pages/ForgotPassword.vue index f06c561a3..81121fbe7 100644 --- a/frontend/src/pages/ForgotPassword.vue +++ b/frontend/src/pages/ForgotPassword.vue @@ -5,10 +5,9 @@
+

{{ $t('settings.password.reset') }}

-

{{ $t(displaySetup.headline) }}

- -

{{ $t(displaySetup.subtitle) }}

+

{{ $t(subtitle) }}

@@ -24,8 +23,7 @@
- - {{ $t(displaySetup.button) }} + {{ $t('settings.password.send_now') }}
@@ -44,21 +42,6 @@ import { sendResetPasswordEmail } from '@/graphql/queries' import InputEmail from '@/components/Inputs/InputEmail' -const textFields = { - resetPassword: { - headline: 'settings.password.reset', - subtitle: 'settings.password.resend_subtitle', - button: 'settings.password.send_now', - cancel: 'back', - }, - login: { - headline: 'settings.password.reset', - subtitle: 'settings.password.subtitle', - button: 'settings.password.send_now', - cancel: 'back', - }, -} - export default { name: 'ForgotPassword', components: { @@ -70,7 +53,7 @@ export default { form: { email: '', }, - displaySetup: {}, + subtitle: 'settings.password.subtitle', } }, methods: { @@ -92,9 +75,7 @@ export default { }, created() { if (this.$route.params.comingFrom) { - this.displaySetup = textFields[this.$route.params.comingFrom] - } else { - this.displaySetup = textFields.login + this.subtitle = 'settings.password.resend_subtitle' } }, } From 652babd191dc542418d003ec1af643540d000eab Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 16 Mar 2022 03:16:05 +0100 Subject: [PATCH 054/133] renamed `dash` to `em-dash` --- frontend/src/components/GddSend/TransactionConfirmationSend.vue | 2 +- frontend/src/components/Menu/Navbar.vue | 2 +- frontend/src/components/Status.spec.js | 2 +- frontend/src/components/Status.vue | 2 +- frontend/src/components/UserCard.vue | 2 +- frontend/src/locales/de.json | 2 +- frontend/src/locales/en.json | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/GddSend/TransactionConfirmationSend.vue b/frontend/src/components/GddSend/TransactionConfirmationSend.vue index 5e945ec20..2d85fa33f 100644 --- a/frontend/src/components/GddSend/TransactionConfirmationSend.vue +++ b/frontend/src/components/GddSend/TransactionConfirmationSend.vue @@ -27,7 +27,7 @@ -
{{ memo ? memo : $t('dash') }}
+
{{ memo ? memo : $t('em-dash') }}
diff --git a/frontend/src/components/Menu/Navbar.vue b/frontend/src/components/Menu/Navbar.vue index 2163ae945..3542c1cd1 100644 --- a/frontend/src/components/Menu/Navbar.vue +++ b/frontend/src/components/Menu/Navbar.vue @@ -10,7 +10,7 @@ - {{ pending ? $t('dash') : balance | amount }} {{ $t('GDD') }} + {{ pending ? $t('em-dash') : balance | amount }} {{ $t('GDD') }} {{ $store.state.firstName }} {{ $store.state.lastName }} diff --git a/frontend/src/components/Status.spec.js b/frontend/src/components/Status.spec.js index 1dbb05493..ba7b03fa4 100644 --- a/frontend/src/components/Status.spec.js +++ b/frontend/src/components/Status.spec.js @@ -27,7 +27,7 @@ describe('Status', () => { describe('balance is pending', () => { it('it displays an en-dash', () => { - expect(wrapper.find('div.gdd-status-div').text()).toEqual('dash GDD') + expect(wrapper.find('div.gdd-status-div').text()).toEqual('em-dash GDD') }) }) diff --git a/frontend/src/components/Status.vue b/frontend/src/components/Status.vue index cde1afbdb..9ebe48e09 100644 --- a/frontend/src/components/Status.vue +++ b/frontend/src/components/Status.vue @@ -1,7 +1,7 @@ diff --git a/frontend/src/components/UserCard.vue b/frontend/src/components/UserCard.vue index 915632860..beca89532 100755 --- a/frontend/src/components/UserCard.vue +++ b/frontend/src/components/UserCard.vue @@ -26,7 +26,7 @@ -
{{ $t('dash') }}
+
{{ $t('em-dash') }}
{{ $t('community.community') }}
diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 47076886d..93752b92d 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -9,7 +9,7 @@ "other-communities": "Weitere Gemeinschaften", "switch-to-this-community": "zu dieser Gemeinschaft wechseln" }, - "dash": "—", + "em-dash": "—", "decay": { "before_startblock_transaction": "Diese Transaktion beinhaltet keine Vergänglichkeit.", "calculation_decay": "Berechnung der Vergänglichkeit", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index fe227cb9d..48e761eda 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -9,7 +9,7 @@ "other-communities": "Other communities", "switch-to-this-community": "Switch to this community" }, - "dash": "—", + "em-dash": "—", "decay": { "before_startblock_transaction": "This transaction does not include decay.", "calculation_decay": "Calculation of Decay", From 5115063e47a98875c5151fd736f8c1934276aff8 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 16 Mar 2022 03:16:22 +0100 Subject: [PATCH 055/133] order language keys --- frontend/src/locales/de.json | 4 ++-- frontend/src/locales/en.json | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 93752b92d..e6296f26e 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -9,7 +9,6 @@ "other-communities": "Weitere Gemeinschaften", "switch-to-this-community": "zu dieser Gemeinschaft wechseln" }, - "em-dash": "—", "decay": { "before_startblock_transaction": "Diese Transaktion beinhaltet keine Vergänglichkeit.", "calculation_decay": "Berechnung der Vergänglichkeit", @@ -28,6 +27,7 @@ "send": "Gesendet" } }, + "em-dash": "—", "error": { "empty-transactionlist": "Es gab einen Fehler mit der Übermittlung der Anzahl deiner Transaktionen.", "error": "Fehler!", @@ -130,8 +130,8 @@ "admin_area": "Adminbereich", "logout": "Abmelden", "members_area": "Mitgliederbereich", - "profile": "Mein Profil", "overview": "Übersicht", + "profile": "Mein Profil", "send": "Senden", "support": "Support", "transactions": "Transaktionen" diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 48e761eda..0809d1b8f 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -9,7 +9,6 @@ "other-communities": "Other communities", "switch-to-this-community": "Switch to this community" }, - "em-dash": "—", "decay": { "before_startblock_transaction": "This transaction does not include decay.", "calculation_decay": "Calculation of Decay", @@ -28,6 +27,7 @@ "send": "Sent" } }, + "em-dash": "—", "error": { "empty-transactionlist": "There was an error with the transmission of the number of your transactions.", "error": "Error!", @@ -130,8 +130,8 @@ "admin_area": "Admin Area", "logout": "Logout", "members_area": "Members area", - "profile": "My profile", "overview": "Overview", + "profile": "My profile", "send": "Send", "support": "Support", "transactions": "Transactions" @@ -171,11 +171,11 @@ "reset-password": { "text": "Enter a new password that you will use to log in to your Gradido account in the future.." }, + "send_now": "Send now", "set": "Set password", "set-password": { "text": "Now save your new password, which you can use to log in to your Gradido account in the future." }, - "send_now": "Send now", "subtitle": "If you have forgotten your password, you can reset it here." } }, From a8dfb27fbce30e04c64d5a6c67f1a7b5cfe3e1b9 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 16 Mar 2022 03:37:41 +0100 Subject: [PATCH 056/133] fixed tests, moved ContentFooter to components --- .../{layouts => components}/ContentFooter.spec.js | 14 +++++++------- .../src/{layouts => components}/ContentFooter.vue | 0 frontend/src/layouts/AuthLayout_gdd.vue | 2 +- frontend/src/layouts/DashboardLayout_gdd.vue | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) rename frontend/src/{layouts => components}/ContentFooter.spec.js (91%) rename frontend/src/{layouts => components}/ContentFooter.vue (100%) diff --git a/frontend/src/layouts/ContentFooter.spec.js b/frontend/src/components/ContentFooter.spec.js similarity index 91% rename from frontend/src/layouts/ContentFooter.spec.js rename to frontend/src/components/ContentFooter.spec.js index 4fe16c030..f67560e44 100644 --- a/frontend/src/layouts/ContentFooter.spec.js +++ b/frontend/src/components/ContentFooter.spec.js @@ -11,7 +11,7 @@ describe('ContentFooter', () => { $i18n: { locale: 'en', }, - $t: jest.fn((t) => t), + $t: jest.fn((t, options) => (options ? [t, options] : t)), } const Wrapper = () => { @@ -32,8 +32,8 @@ describe('ContentFooter', () => { expect(wrapper.find('div.copyright').exists()).toBeTruthy() }) - it.skip('renders the copyright year', () => { - expect(wrapper.find('div.copyright').text()).toMatch(/©\s*2[0-9]{3,3}\s+/) + it('renders the copyright year', () => { + expect(mocks.$t).toBeCalledWith('footer.copyright.year', { year: 2022 }) }) it('renders a link to Gradido-Akademie', () => { @@ -48,10 +48,10 @@ describe('ContentFooter', () => { }) describe('version', () => { - it.skip('shows the current version', async () => { + it('shows the current version', async () => { wrapper.setData({ version: 1.23 }) await wrapper.vm.$nextTick() - expect(wrapper.find('div.copyright').findAll('a').at(1).text()).toEqual('App version 1.23') + expect(mocks.$t).toBeCalledWith('footer.app_version', { version: 1.23 }) }) it('links to latest release on GitHub', () => { @@ -60,11 +60,11 @@ describe('ContentFooter', () => { ) }) - it.skip('has last commit hash', async () => { + it('has last commit hash', async () => { wrapper.setData({ shortHash: 'ACCEDED' }) wrapper.setData({ hash: 'ACCEDEDC001D00DC001D00DC001D00DC001CAFA' }) await wrapper.vm.$nextTick() - expect(wrapper.find('div.copyright').findAll('a').at(2).text()).toEqual('(ACCEDED)') + expect(mocks.$t).toBeCalledWith('footer.short_hash', { shortHash: 'ACCEDED' }) }) it('links to last release commit', async () => { diff --git a/frontend/src/layouts/ContentFooter.vue b/frontend/src/components/ContentFooter.vue similarity index 100% rename from frontend/src/layouts/ContentFooter.vue rename to frontend/src/components/ContentFooter.vue diff --git a/frontend/src/layouts/AuthLayout_gdd.vue b/frontend/src/layouts/AuthLayout_gdd.vue index 4d0f8cb78..e87ebe06a 100644 --- a/frontend/src/layouts/AuthLayout_gdd.vue +++ b/frontend/src/layouts/AuthLayout_gdd.vue @@ -8,7 +8,7 @@ From 54b7e58a5ea58c27a2fb7130894e24c1e13a9f21 Mon Sep 17 00:00:00 2001 From: ogerly Date: Wed, 16 Mar 2022 18:32:28 +0100 Subject: [PATCH 084/133] add props diffNow, add computed dateString --- .../components/TransactionRows/DateRow.vue | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/TransactionRows/DateRow.vue b/frontend/src/components/TransactionRows/DateRow.vue index 5daccfa69..0c72907fe 100644 --- a/frontend/src/components/TransactionRows/DateRow.vue +++ b/frontend/src/components/TransactionRows/DateRow.vue @@ -2,12 +2,11 @@
-
{{ $t('form.date') }}
+
{{ diffNow ? $t('gdd_per_link.expired') : $t('form.date') }}
- {{ $d(new Date(balanceDate), 'long') }} - {{ $i18n.locale === 'de' ? 'Uhr' : '' }} + {{ dateString }}
@@ -17,10 +16,22 @@ export default { name: 'DateRow', props: { - balanceDate: { + date: { type: String, required: true, }, + diffNow: { + type: Boolean, + required: false, + default: false, + }, + }, + computed: { + dateString() { + return this.diffNow + ? this.$moment(this.date).locale(this.$i18n.locale).fromNow() + : this.$d(new Date(this.date), 'long') + }, }, } From 555addb26cca91f2b5503c668b59886e1617d322 Mon Sep 17 00:00:00 2001 From: ogerly Date: Wed, 16 Mar 2022 18:34:03 +0100 Subject: [PATCH 085/133] add props memo required: true --- frontend/src/components/TransactionRows/MemoRow.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/TransactionRows/MemoRow.vue b/frontend/src/components/TransactionRows/MemoRow.vue index ef79fb38e..26b421bf9 100644 --- a/frontend/src/components/TransactionRows/MemoRow.vue +++ b/frontend/src/components/TransactionRows/MemoRow.vue @@ -16,7 +16,7 @@ export default { props: { memo: { type: String, - required: false, + required: true, }, }, } From d4ca15a28a3f798b8961ddf6e75232b9121c27b9 Mon Sep 17 00:00:00 2001 From: ogerly Date: Wed, 16 Mar 2022 18:36:08 +0100 Subject: [PATCH 086/133] change props balanceDate to date --- frontend/src/components/Transactions/TransactionCreation.vue | 2 +- frontend/src/components/Transactions/TransactionReceive.vue | 2 +- frontend/src/components/Transactions/TransactionSend.vue | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/Transactions/TransactionCreation.vue b/frontend/src/components/Transactions/TransactionCreation.vue index 43178e5f2..579bf06a5 100644 --- a/frontend/src/components/Transactions/TransactionCreation.vue +++ b/frontend/src/components/Transactions/TransactionCreation.vue @@ -18,7 +18,7 @@ - + diff --git a/frontend/src/components/Transactions/TransactionReceive.vue b/frontend/src/components/Transactions/TransactionReceive.vue index e9dc23cdb..bffd61eab 100644 --- a/frontend/src/components/Transactions/TransactionReceive.vue +++ b/frontend/src/components/Transactions/TransactionReceive.vue @@ -19,7 +19,7 @@ - + diff --git a/frontend/src/components/Transactions/TransactionSend.vue b/frontend/src/components/Transactions/TransactionSend.vue index 18112f8e1..b7c6fefe6 100644 --- a/frontend/src/components/Transactions/TransactionSend.vue +++ b/frontend/src/components/Transactions/TransactionSend.vue @@ -19,7 +19,7 @@ - + From 291fb29528966037aaa305aa639a4866c3e9ab9e Mon Sep 17 00:00:00 2001 From: ogerly Date: Wed, 16 Mar 2022 18:39:03 +0100 Subject: [PATCH 087/133] remove unused code --- .../src/components/Transactions/TransactionLinksSummary.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/src/components/Transactions/TransactionLinksSummary.vue b/frontend/src/components/Transactions/TransactionLinksSummary.vue index 74251fc4b..8c5cace4a 100644 --- a/frontend/src/components/Transactions/TransactionLinksSummary.vue +++ b/frontend/src/components/Transactions/TransactionLinksSummary.vue @@ -25,9 +25,8 @@
- + Date: Wed, 16 Mar 2022 20:39:21 +0100 Subject: [PATCH 088/133] remove unused props item, add props from v-bind, remove id in function --- .../TransactionLinks/TransactionLink.vue | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/TransactionLinks/TransactionLink.vue b/frontend/src/components/TransactionLinks/TransactionLink.vue index 800e7b01c..75d87897e 100644 --- a/frontend/src/components/TransactionLinks/TransactionLink.vue +++ b/frontend/src/components/TransactionLinks/TransactionLink.vue @@ -5,9 +5,9 @@
- - - + + + @@ -26,7 +26,7 @@ class="p-2 mt-3" size="sm" variant="outline-danger" - @click="deleteLink(item.id)" + @click="deleteLink()" :title="$t('delete')" > @@ -53,11 +53,16 @@ export default { DecayRow, }, props: { - item: { type: Object, required: true }, + amount: { type: String, required: true }, + code: { type: String, required: true }, + holdAvailableAmount: { type: String, required: true }, + id: { type: Number, required: true }, + memo: { type: String, required: true }, + validUntil: { type: String, required: true }, }, methods: { copy() { - const link = `${window.location.origin}/redeem/${this.item.code}` + const link = `${window.location.origin}/redeem/${this.code}` navigator.clipboard .writeText(link) .then(() => { @@ -67,14 +72,14 @@ export default { this.toastError(this.$t('gdd_per_link.not-copied')) }) }, - deleteLink(id) { + deleteLink() { this.$bvModal.msgBoxConfirm(this.$t('gdd_per_link.delete-the-link')).then(async (value) => { if (value) await this.$apollo .mutate({ mutation: deleteTransactionLink, variables: { - id: id, + id: this.id, }, }) .then((result) => { @@ -89,7 +94,7 @@ export default { }, computed: { decayObject() { - return { decay: this.item.amount - this.item.holdAvailableAmount } + return { decay: this.amount - this.holdAvailableAmount } }, }, } From f07ed70f308416c38f3900b8f092057ef2d6c1b2 Mon Sep 17 00:00:00 2001 From: ogerly Date: Wed, 16 Mar 2022 20:40:59 +0100 Subject: [PATCH 089/133] add class on loadMoreLinks button, refactor static 5 to value.pageSize --- .../src/components/DecayInformations/CollapseLinksList.vue | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/DecayInformations/CollapseLinksList.vue b/frontend/src/components/DecayInformations/CollapseLinksList.vue index f9adf0f8d..f219a127a 100644 --- a/frontend/src/components/DecayInformations/CollapseLinksList.vue +++ b/frontend/src/components/DecayInformations/CollapseLinksList.vue @@ -7,11 +7,12 @@
Date: Wed, 16 Mar 2022 20:43:27 +0100 Subject: [PATCH 090/133] test for CollapseLinksList.vue --- .../CollapseLinksList.spec.js | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 frontend/src/components/DecayInformations/CollapseLinksList.spec.js diff --git a/frontend/src/components/DecayInformations/CollapseLinksList.spec.js b/frontend/src/components/DecayInformations/CollapseLinksList.spec.js new file mode 100644 index 000000000..5407df2fe --- /dev/null +++ b/frontend/src/components/DecayInformations/CollapseLinksList.spec.js @@ -0,0 +1,112 @@ +import { mount } from '@vue/test-utils' +import CollapseLinksList from './CollapseLinksList' + +const localVue = global.localVue + +const mocks = { + $i18n: { + locale: 'en', + }, + $tc: jest.fn((tc) => tc), + $t: jest.fn((t) => t), +} + +const propsData = { + transactionLinks: [ + { + amount: '5', + code: 'ce28664b5308c17f931c0367', + createdAt: '2022-03-16T14:22:40.000Z', + holdAvailableAmount: '5.13109484759482747111', + id: 87, + memo: 'asdasdaadsdd asd asdadss', + redeemedAt: null, + validUntil: '2022-03-30T14:22:40.000Z', + }, + ], + transactionLinkCount: 3, + value: { currentPage: 1, pending: false, pageSize: 5, itemsShown: 0 }, +} + +describe('CollapseLinksList', () => { + let wrapper + + const Wrapper = () => { + return mount(CollapseLinksList, { localVue, mocks, propsData }) + } + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('renders the component div.collapse-links-list', () => { + expect(wrapper.find('div.collapse-links-list').exists()).toBeTruthy() + }) + + describe('load more links', () => { + beforeEach(async () => { + await wrapper.find('button.test-button-load-more').trigger('click') + }) + + it('emits input', () => { + expect(wrapper.emitted('input')).toEqual([ + [{ currentPage: 2, itemsShown: 0, pageSize: 5, pending: false }], + ]) + }) + }) + + describe('reset transaction link list', () => { + beforeEach(async () => { + await wrapper + .findComponent({ name: 'TransactionLink' }) + .vm.$emit('reset-transaction-link-list') + }) + + it('emits input ', () => { + expect(wrapper.emitted('input')).toEqual([ + [{ currentPage: 0, itemsShown: 0, pageSize: 5, pending: false }], + ]) + }) + }) + + describe('button text', () => { + describe('one more link to load', () => { + beforeEach(async () => { + await wrapper.setProps({ + value: { currentPage: 1, pending: false, pageSize: 5, itemsShown: 2 }, + }) + }) + + it('renders text in singular', () => { + expect(mocks.$tc).toBeCalledWith('link-load', 0) + }) + }) + + describe('less than pageSize links to load', () => { + beforeEach(async () => { + await wrapper.setProps({ + value: { currentPage: 1, pending: false, pageSize: 5, itemsShown: 2 }, + transactionLinkCount: 6, + }) + }) + + it('renders text in singular', () => { + expect(mocks.$tc).toBeCalledWith('link-load', 1, { n: 4 }) + }) + }) + + describe('more than pageSize links to load', () => { + beforeEach(async () => { + await wrapper.setProps({ + value: { currentPage: 1, pending: false, pageSize: 5, itemsShown: 2 }, + transactionLinkCount: 16, + }) + }) + + it('renders text in singular', () => { + expect(mocks.$tc).toBeCalledWith('link-load', 2, { n: 5 }) + }) + }) + }) + }) +}) From 691d734c50cd9b5211598d35919c5536cebcdd58 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 16 Mar 2022 21:12:08 +0100 Subject: [PATCH 091/133] Update backend/src/seeds/factory/creation.ts Co-authored-by: Ulf Gebhardt --- backend/src/seeds/factory/creation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/seeds/factory/creation.ts b/backend/src/seeds/factory/creation.ts index 52b63b193..92bc224f6 100644 --- a/backend/src/seeds/factory/creation.ts +++ b/backend/src/seeds/factory/creation.ts @@ -15,7 +15,7 @@ export const creationFactory = async ( ): Promise => { const { mutate, query } = client - // get Peter Lustig + // get Peter Lustig's user id const peterLustig = await User.findOneOrFail({ where: { email: 'peter@lustig.de' } }) const variables = { ...creation, moderator: peterLustig.id } From abcaad720700a94cc0b9d12ac8d662060f2fbbfd Mon Sep 17 00:00:00 2001 From: ogerly Date: Wed, 16 Mar 2022 21:16:33 +0100 Subject: [PATCH 092/133] delete unused keys in locales --- frontend/src/locales/de.json | 3 --- frontend/src/locales/en.json | 3 --- 2 files changed, 6 deletions(-) diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 3f59525ae..7f606e827 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -125,9 +125,6 @@ }, "language": "Sprache", "link-load": "den letzten Link nachladen | die letzten {n} Links nachladen | weitere {n} Links nachladen", - "links-list": { - "header": "Liste deiner aktiven Links" - }, "login": "Anmeldung", "math": { "aprox": "~", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 24e8c0c29..8377fc0b0 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -125,9 +125,6 @@ }, "language": "Language", "link-load": "Load the last link | Load the last {n} links | Load more {n} links", - "links-list": { - "header": "List of your active links" - }, "login": "Login", "math": { "aprox": "~", From 3c04cf062173e104133aad7fce44bf7e4dd093da Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 16 Mar 2022 21:18:01 +0100 Subject: [PATCH 093/133] move db call to get admin id before mutation --- backend/src/seeds/factory/creation.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/seeds/factory/creation.ts b/backend/src/seeds/factory/creation.ts index 92bc224f6..980e0b3af 100644 --- a/backend/src/seeds/factory/creation.ts +++ b/backend/src/seeds/factory/creation.ts @@ -15,13 +15,13 @@ export const creationFactory = async ( ): Promise => { const { mutate, query } = client + // login as Peter Lustig (admin) + await query({ query: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' } }) + // get Peter Lustig's user id const peterLustig = await User.findOneOrFail({ where: { email: 'peter@lustig.de' } }) const variables = { ...creation, moderator: peterLustig.id } - // login as Peter Lustig (admin) - await query({ query: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' } }) - await mutate({ mutation: createPendingCreation, variables }) // get User From 1182b94075e2b1d0ba2865400dcd680c83a1a728 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 17 Mar 2022 08:40:02 +0100 Subject: [PATCH 094/133] createUser returns User object, adopt mutations, reduce db calls in seed --- backend/src/graphql/resolver/UserResolver.ts | 6 +-- backend/src/seeds/factory/user.ts | 47 +++++++++++--------- backend/src/seeds/graphql/mutations.ts | 4 +- frontend/src/graphql/mutations.js | 4 +- 4 files changed, 35 insertions(+), 26 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 9896ddc97..a18833d58 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -313,10 +313,10 @@ export class UserResolver { } @Authorized([RIGHTS.CREATE_USER]) - @Mutation(() => String) + @Mutation(() => User) async createUser( @Args() { email, firstName, lastName, language, publisherId }: CreateUserArgs, - ): Promise { + ): Promise { // TODO: wrong default value (should be null), how does graphql work here? Is it an required field? // default int publisher_id = 0; @@ -396,7 +396,7 @@ export class UserResolver { } finally { await queryRunner.release() } - return 'success' + return new User(dbUser) } // THis is used by the admin only - should we move it to the admin resolver? diff --git a/backend/src/seeds/factory/user.ts b/backend/src/seeds/factory/user.ts index 6d81f26a6..ff4c1d6c9 100644 --- a/backend/src/seeds/factory/user.ts +++ b/backend/src/seeds/factory/user.ts @@ -11,36 +11,41 @@ export const userFactory = async ( ): Promise => { const { mutate } = client - await mutate({ mutation: createUser, variables: user }) - let dbUser = await User.findOneOrFail({ where: { email: user.email } }) + const { + data: { + createUser: { id }, + }, + } = await mutate({ mutation: createUser, variables: user }) if (user.emailChecked) { - const optin = await LoginEmailOptIn.findOneOrFail({ where: { userId: dbUser.id } }) + const optin = await LoginEmailOptIn.findOneOrFail({ userId: id }) await mutate({ mutation: setPassword, variables: { password: 'Aa12345_', code: optin.verificationCode }, }) } - // refetch data - dbUser = await User.findOneOrFail({ where: { email: user.email } }) + if (user.createdAt || user.deletedAt || user.isAdmin) { + // get user from database + const dbUser = await User.findOneOrFail({ id }) - if (user.createdAt || user.deletedAt) { - if (user.createdAt) dbUser.createdAt = user.createdAt - if (user.deletedAt) dbUser.deletedAt = user.deletedAt - await dbUser.save() - } + if (user.createdAt || user.deletedAt) { + if (user.createdAt) dbUser.createdAt = user.createdAt + if (user.deletedAt) dbUser.deletedAt = user.deletedAt + await dbUser.save() + } - if (user.isAdmin) { - const admin = new ServerUser() - admin.username = dbUser.firstName - admin.password = 'please_refactor' - admin.email = dbUser.email - admin.role = 'admin' - admin.activated = 1 - admin.lastLogin = new Date() - admin.created = dbUser.createdAt - admin.modified = dbUser.createdAt - await admin.save() + if (user.isAdmin) { + const admin = new ServerUser() + admin.username = dbUser.firstName + admin.password = 'please_refactor' + admin.email = dbUser.email + admin.role = 'admin' + admin.activated = 1 + admin.lastLogin = new Date() + admin.created = dbUser.createdAt + admin.modified = dbUser.createdAt + await admin.save() + } } } diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index 32232e410..306f4350b 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -52,7 +52,9 @@ export const createUser = gql` lastName: $lastName language: $language publisherId: $publisherId - ) + ) { + id + } } ` diff --git a/frontend/src/graphql/mutations.js b/frontend/src/graphql/mutations.js index d4bf8c1da..98905e8d6 100644 --- a/frontend/src/graphql/mutations.js +++ b/frontend/src/graphql/mutations.js @@ -52,7 +52,9 @@ export const createUser = gql` lastName: $lastName language: $language publisherId: $publisherId - ) + ) { + id + } } ` From 8a350e7cab44bfda90c62f14c9745b782588c3ce Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 17 Mar 2022 08:48:49 +0100 Subject: [PATCH 095/133] get user id by login query in seeds --- backend/src/seeds/factory/creation.ts | 14 +++++++------- backend/src/seeds/graphql/queries.ts | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/backend/src/seeds/factory/creation.ts b/backend/src/seeds/factory/creation.ts index 980e0b3af..d4d4c8101 100644 --- a/backend/src/seeds/factory/creation.ts +++ b/backend/src/seeds/factory/creation.ts @@ -15,14 +15,14 @@ export const creationFactory = async ( ): Promise => { const { mutate, query } = client - // login as Peter Lustig (admin) - await query({ query: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' } }) + // login as Peter Lustig (admin) and get his user ID + const { + data: { + login: { id }, + }, + } = await query({ query: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' } }) - // get Peter Lustig's user id - const peterLustig = await User.findOneOrFail({ where: { email: 'peter@lustig.de' } }) - const variables = { ...creation, moderator: peterLustig.id } - - await mutate({ mutation: createPendingCreation, variables }) + await mutate({ mutation: createPendingCreation, variables: { ...creation, moderator: id } }) // get User const user = await User.findOneOrFail({ where: { email: creation.email } }) diff --git a/backend/src/seeds/graphql/queries.ts b/backend/src/seeds/graphql/queries.ts index 942258fde..04f849727 100644 --- a/backend/src/seeds/graphql/queries.ts +++ b/backend/src/seeds/graphql/queries.ts @@ -3,6 +3,7 @@ import gql from 'graphql-tag' export const login = gql` query ($email: String!, $password: String!, $publisherId: Int) { login(email: $email, password: $password, publisherId: $publisherId) { + id email firstName lastName From 689d6c3fb87ba5b36eddc6bd0d6c8f81b6981f94 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 17 Mar 2022 08:58:07 +0100 Subject: [PATCH 096/133] get transaction link id by mutation call --- backend/src/seeds/factory/transactionLink.ts | 14 +++++++------- backend/src/seeds/graphql/mutations.ts | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/backend/src/seeds/factory/transactionLink.ts b/backend/src/seeds/factory/transactionLink.ts index 665ae03f3..2f54dc70c 100644 --- a/backend/src/seeds/factory/transactionLink.ts +++ b/backend/src/seeds/factory/transactionLink.ts @@ -4,7 +4,6 @@ import { login } from '@/seeds/graphql/queries' import { TransactionLinkInterface } from '@/seeds/transactionLink/TransactionLinkInterface' import { transactionLinkExpireDate } from '@/graphql/resolver/TransactionLinkResolver' import { TransactionLink } from '@entity/TransactionLink' -import { User } from '@entity/User' export const transactionLinkFactory = async ( client: ApolloServerTestClient, @@ -20,14 +19,15 @@ export const transactionLinkFactory = async ( memo: transactionLink.memo, } - await mutate({ mutation: createTransactionLink, variables }) + // get the transaction links's id + const { + data: { + createTransactionLink: { id }, + }, + } = await mutate({ mutation: createTransactionLink, variables }) if (transactionLink.createdAt || transactionLink.deletedAt) { - const user = await User.findOneOrFail({ where: { email: transactionLink.email } }) - const dbTransactionLink = await TransactionLink.findOneOrFail({ - where: { userId: user.id }, - order: { createdAt: 'DESC' }, - }) + const dbTransactionLink = await TransactionLink.findOneOrFail({ id }) if (transactionLink.createdAt) { dbTransactionLink.createdAt = transactionLink.createdAt diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index 306f4350b..19ca2a8d0 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -67,6 +67,7 @@ export const sendCoins = gql` export const createTransactionLink = gql` mutation ($amount: Decimal!, $memo: String!) { createTransactionLink(amount: $amount, memo: $memo) { + id code } } From 51c06741fcb31879f12c3191870fc8a516728ce7 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 17 Mar 2022 09:06:40 +0100 Subject: [PATCH 097/133] get test working with chages to the schema --- backend/src/graphql/resolver/UserResolver.test.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 1e1e266fb..66e435207 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -69,7 +69,9 @@ describe('UserResolver', () => { }) it('returns success', () => { - expect(result).toEqual(expect.objectContaining({ data: { createUser: 'success' } })) + expect(result).toEqual( + expect.objectContaining({ data: { createUser: { id: expect.any(Number) } } }), + ) }) describe('valid input data', () => { @@ -331,6 +333,7 @@ describe('UserResolver', () => { email: 'bibi@bloxberg.de', firstName: 'Bibi', hasElopage: false, + id: expect.any(Number), isAdmin: false, klickTipp: { newsletterState: false, From ac11d1fa6019b386112c4beef96908638d8a1193 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 17 Mar 2022 09:55:15 +0100 Subject: [PATCH 098/133] store user entity created on authentication check in context to avoid further DB calls --- backend/src/graphql/directive/isAuthorized.ts | 1 + backend/src/graphql/resolver/UserResolver.ts | 10 +++------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/backend/src/graphql/directive/isAuthorized.ts b/backend/src/graphql/directive/isAuthorized.ts index 159a1614c..84756c45a 100644 --- a/backend/src/graphql/directive/isAuthorized.ts +++ b/backend/src/graphql/directive/isAuthorized.ts @@ -35,6 +35,7 @@ const isAuthorized: AuthChecker = async ({ context }, rights) => { const userRepository = await getCustomRepository(UserRepository) try { const user = await userRepository.findByPubkeyHex(context.pubKey) + context.user = user const countServerUsers = await ServerUser.count({ email: user.email }) context.role = countServerUsers > 0 ? ROLE_ADMIN : ROLE_USER } catch { diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 9896ddc97..39a983c2b 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -14,7 +14,6 @@ import UpdateUserInfosArgs from '@arg/UpdateUserInfosArgs' import { klicktippNewsletterStateMiddleware } from '@/middleware/klicktippMiddleware' import { UserSettingRepository } from '@repository/UserSettingRepository' import { Setting } from '@enum/Setting' -import { UserRepository } from '@repository/User' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' import { sendResetPasswordEmail } from '@/mailer/sendResetPasswordEmail' import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail' @@ -214,8 +213,7 @@ export class UserResolver { @UseMiddleware(klicktippNewsletterStateMiddleware) async verifyLogin(@Ctx() context: any): Promise { // TODO refactor and do not have duplicate code with login(see below) - const userRepository = getCustomRepository(UserRepository) - const userEntity = await userRepository.findByPubkeyHex(context.pubKey) + const userEntity = context.user const user = new User(userEntity) // user.pubkey = userEntity.pubKey.toString('hex') // Elopage Status & Stored PublisherId @@ -585,8 +583,7 @@ export class UserResolver { }: UpdateUserInfosArgs, @Ctx() context: any, ): Promise { - const userRepository = getCustomRepository(UserRepository) - const userEntity = await userRepository.findByPubkeyHex(context.pubKey) + const userEntity = context.user if (firstName) { userEntity.firstName = firstName @@ -664,8 +661,7 @@ export class UserResolver { @Authorized([RIGHTS.HAS_ELOPAGE]) @Query(() => Boolean) async hasElopage(@Ctx() context: any): Promise { - const userRepository = getCustomRepository(UserRepository) - const userEntity = await userRepository.findByPubkeyHex(context.pubKey).catch() + const userEntity = context.user if (!userEntity) { return false } From fd9292b3d5ca6f97658f840d425e086ad4f1694b Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 17 Mar 2022 09:57:19 +0100 Subject: [PATCH 099/133] user context in admin interface --- backend/src/graphql/resolver/AdminResolver.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index f116c3968..f0210dc8d 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -129,8 +129,7 @@ export class AdminResolver { throw new Error(`Could not find user with userId: ${userId}`) } // moderator user disabled own account? - const userRepository = getCustomRepository(UserRepository) - const moderatorUser = await userRepository.findByPubkeyHex(context.pubKey) + const moderatorUser = context.user if (moderatorUser.id === userId) { throw new Error('Moderator can not delete his own account!') } @@ -294,8 +293,7 @@ export class AdminResolver { @Mutation(() => Boolean) async confirmPendingCreation(@Arg('id') id: number, @Ctx() context: any): Promise { const pendingCreation = await AdminPendingCreation.findOneOrFail(id) - const userRepository = getCustomRepository(UserRepository) - const moderatorUser = await userRepository.findByPubkeyHex(context.pubKey) + const moderatorUser = context.user if (moderatorUser.id === pendingCreation.userId) throw new Error('Moderator can not confirm own pending creation') From b44ef7175616a9956eec4e7f0d9d49306fa76425 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 17 Mar 2022 10:05:07 +0100 Subject: [PATCH 100/133] no double DB calls to get user from db in resolvers --- backend/src/graphql/resolver/BalanceResolver.ts | 6 +----- backend/src/graphql/resolver/GdtResolver.ts | 5 +---- .../graphql/resolver/TransactionLinkResolver.ts | 14 ++++---------- .../src/graphql/resolver/TransactionResolver.ts | 3 +-- 4 files changed, 7 insertions(+), 21 deletions(-) diff --git a/backend/src/graphql/resolver/BalanceResolver.ts b/backend/src/graphql/resolver/BalanceResolver.ts index 12d5b2ba4..09d2fdc92 100644 --- a/backend/src/graphql/resolver/BalanceResolver.ts +++ b/backend/src/graphql/resolver/BalanceResolver.ts @@ -2,9 +2,7 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { Resolver, Query, Ctx, Authorized } from 'type-graphql' -import { getCustomRepository } from '@dbTools/typeorm' import { Balance } from '@model/Balance' -import { UserRepository } from '@repository/User' import { calculateDecay } from '@/util/decay' import { RIGHTS } from '@/auth/RIGHTS' import { Transaction } from '@entity/Transaction' @@ -16,9 +14,7 @@ export class BalanceResolver { @Query(() => Balance) async balance(@Ctx() context: any): Promise { // load user and balance - const userRepository = getCustomRepository(UserRepository) - - const user = await userRepository.findByPubkeyHex(context.pubKey) + const { user } = context const now = new Date() const lastTransaction = await Transaction.findOne( diff --git a/backend/src/graphql/resolver/GdtResolver.ts b/backend/src/graphql/resolver/GdtResolver.ts index c8c4cb331..26ae9b210 100644 --- a/backend/src/graphql/resolver/GdtResolver.ts +++ b/backend/src/graphql/resolver/GdtResolver.ts @@ -2,12 +2,10 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { Resolver, Query, Args, Ctx, Authorized, Arg } from 'type-graphql' -import { getCustomRepository } from '@dbTools/typeorm' import CONFIG from '@/config' import { GdtEntryList } from '@model/GdtEntryList' import Paginated from '@arg/Paginated' import { apiGet } from '@/apis/HttpRequest' -import { UserRepository } from '@repository/User' import { Order } from '@enum/Order' import { RIGHTS } from '@/auth/RIGHTS' @@ -22,8 +20,7 @@ export class GdtResolver { @Ctx() context: any, ): Promise { // load user - const userRepository = getCustomRepository(UserRepository) - const userEntity = await userRepository.findByPubkeyHex(context.pubKey) + const userEntity = context.user try { const resultGDT = await apiGet( diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts index 9e2af6111..ead82e182 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts @@ -2,11 +2,9 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { Resolver, Args, Arg, Authorized, Ctx, Mutation, Query } from 'type-graphql' -import { getCustomRepository } from '@dbTools/typeorm' import { TransactionLink } from '@model/TransactionLink' import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink' import { User as dbUser } from '@entity/User' -import { UserRepository } from '@repository/User' import TransactionLinkArgs from '@arg/TransactionLinkArgs' import Paginated from '@arg/Paginated' import { calculateBalance } from '@/util/validate' @@ -42,8 +40,7 @@ export class TransactionLinkResolver { @Args() { amount, memo }: TransactionLinkArgs, @Ctx() context: any, ): Promise { - const userRepository = getCustomRepository(UserRepository) - const user = await userRepository.findByPubkeyHex(context.pubKey) + const { user } = context const createdDate = new Date() const validUntil = transactionLinkExpireDate(createdDate) @@ -74,8 +71,7 @@ export class TransactionLinkResolver { @Authorized([RIGHTS.DELETE_TRANSACTION_LINK]) @Mutation(() => Boolean) async deleteTransactionLink(@Arg('id') id: number, @Ctx() context: any): Promise { - const userRepository = getCustomRepository(UserRepository) - const user = await userRepository.findByPubkeyHex(context.pubKey) + const { user } = context const transactionLink = await dbTransactionLink.findOne({ id }) if (!transactionLink) { @@ -116,8 +112,7 @@ export class TransactionLinkResolver { { currentPage = 1, pageSize = 5, order = Order.DESC }: Paginated, @Ctx() context: any, ): Promise { - const userRepository = getCustomRepository(UserRepository) - const user = await userRepository.findByPubkeyHex(context.pubKey) + const { user } = context // const now = new Date() const transactionLinks = await dbTransactionLink.find({ where: { @@ -137,8 +132,7 @@ export class TransactionLinkResolver { @Authorized([RIGHTS.REDEEM_TRANSACTION_LINK]) @Mutation(() => Boolean) async redeemTransactionLink(@Arg('id') id: number, @Ctx() context: any): Promise { - const userRepository = getCustomRepository(UserRepository) - const user = await userRepository.findByPubkeyHex(context.pubKey) + const { user } = context const transactionLink = await dbTransactionLink.findOneOrFail({ id }) const linkedUser = await dbUser.findOneOrFail({ id: transactionLink.userId }) diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index f64ba19e9..258ea9da6 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -256,8 +256,7 @@ export class TransactionResolver { @Ctx() context: any, ): Promise { // TODO this is subject to replay attacks - const userRepository = getCustomRepository(UserRepository) - const senderUser = await userRepository.findByPubkeyHex(context.pubKey) + const senderUser = context.user if (senderUser.pubKey.length !== 32) { throw new Error('invalid sender public key') } From 577ca00c460f2f30b77df77029f93f91f38d926d Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 17 Mar 2022 10:46:29 +0100 Subject: [PATCH 101/133] refactor transaction list query, do not allow user id an only creations as args any more. this query only return the transactions of the logged in user --- backend/src/graphql/arg/Paginated.ts | 6 ------ .../graphql/resolver/TransactionResolver.ts | 19 +++---------------- frontend/src/graphql/queries.js | 14 ++------------ 3 files changed, 5 insertions(+), 34 deletions(-) diff --git a/backend/src/graphql/arg/Paginated.ts b/backend/src/graphql/arg/Paginated.ts index f365165de..97326caf2 100644 --- a/backend/src/graphql/arg/Paginated.ts +++ b/backend/src/graphql/arg/Paginated.ts @@ -11,10 +11,4 @@ export default class Paginated { @Field(() => Order, { nullable: true }) order?: Order - - @Field(() => Boolean, { nullable: true }) - onlyCreations?: boolean - - @Field(() => Int, { nullable: true }) - userId?: number } diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index 258ea9da6..03640817f 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -17,7 +17,6 @@ import Paginated from '@arg/Paginated' import { Order } from '@enum/Order' -import { UserRepository } from '@repository/User' import { TransactionRepository } from '@repository/Transaction' import { TransactionLinkRepository } from '@repository/TransactionLink' @@ -131,22 +130,11 @@ export class TransactionResolver { @Query(() => TransactionList) async transactionList( @Args() - { - currentPage = 1, - pageSize = 25, - order = Order.DESC, - onlyCreations = false, - userId, - }: Paginated, + { currentPage = 1, pageSize = 25, order = Order.DESC }: Paginated, @Ctx() context: any, ): Promise { const now = new Date() - // find user - const userRepository = getCustomRepository(UserRepository) - // TODO: separate those usecases - this is a security issue - const user = userId - ? await userRepository.findOneOrFail({ id: userId }, { withDeleted: true }) - : await userRepository.findByPubkeyHex(context.pubKey) + const user = context.user // find current balance const lastTransaction = await dbTransaction.findOne( @@ -182,7 +170,6 @@ export class TransactionResolver { pageSize, offset, order, - onlyCreations, ) // find involved users; I am involved @@ -208,7 +195,7 @@ export class TransactionResolver { await transactionLinkRepository.summary(user.id, now) // decay & link transactions - if (!onlyCreations && currentPage === 1 && order === Order.DESC) { + if (currentPage === 1 && order === Order.DESC) { transactions.push( virtualDecayTransaction(lastTransaction.balance, lastTransaction.balanceDate, now, self), ) diff --git a/frontend/src/graphql/queries.js b/frontend/src/graphql/queries.js index 5887d585a..c2efe34d8 100644 --- a/frontend/src/graphql/queries.js +++ b/frontend/src/graphql/queries.js @@ -43,18 +43,8 @@ export const logout = gql` ` export const transactionsQuery = gql` - query( - $currentPage: Int = 1 - $pageSize: Int = 25 - $order: Order = DESC - $onlyCreations: Boolean = false - ) { - transactionList( - currentPage: $currentPage - pageSize: $pageSize - order: $order - onlyCreations: $onlyCreations - ) { + query($currentPage: Int = 1, $pageSize: Int = 25, $order: Order = DESC) { + transactionList(currentPage: $currentPage, pageSize: $pageSize, order: $order) { balanceGDT count linkCount From f21e0ed038340e5999af830b49a1dc74707d60db Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 17 Mar 2022 11:20:26 +0100 Subject: [PATCH 102/133] only creations transaction list with admin rights --- .../CreationTransactionListFormular.vue | 7 ++- admin/src/graphql/creationTransactionList.js | 22 ++++++++ admin/src/graphql/transactionList.js | 31 ------------ backend/src/auth/RIGHTS.ts | 1 + backend/src/graphql/resolver/AdminResolver.ts | 50 +++++++++++++++---- 5 files changed, 65 insertions(+), 46 deletions(-) create mode 100644 admin/src/graphql/creationTransactionList.js delete mode 100644 admin/src/graphql/transactionList.js diff --git a/admin/src/components/CreationTransactionListFormular.vue b/admin/src/components/CreationTransactionListFormular.vue index 0b78ca4b8..ce2b136a4 100644 --- a/admin/src/components/CreationTransactionListFormular.vue +++ b/admin/src/components/CreationTransactionListFormular.vue @@ -5,7 +5,7 @@