diff --git a/backend/Dockerfile b/backend/Dockerfile index dc2e6da87..556b6c48e 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,4 +1,4 @@ -FROM node:12.10.0-alpine as base +FROM node:12.11.0-alpine as base LABEL Description="Backend of the Social Network Human-Connection.org" Vendor="Human Connection gGmbH" Version="0.0.1" Maintainer="Human Connection gGmbH (developer@human-connection.org)" EXPOSE 4000 diff --git a/backend/package.json b/backend/package.json index 44f51709f..3ddfa8d23 100644 --- a/backend/package.json +++ b/backend/package.json @@ -41,13 +41,13 @@ ] }, "dependencies": { - "@hapi/joi": "^16.1.5", + "@hapi/joi": "^16.1.7", "@sentry/node": "^5.6.2", "apollo-cache-inmemory": "~1.6.3", "apollo-client": "~2.6.4", "apollo-link-context": "~1.0.19", "apollo-link-http": "~1.5.16", - "apollo-server": "~2.9.4", + "apollo-server": "~2.9.5", "apollo-server-express": "^2.9.4", "babel-plugin-transform-runtime": "^6.23.0", "bcryptjs": "~2.4.3", @@ -105,20 +105,20 @@ "xregexp": "^4.2.4" }, "devDependencies": { - "@babel/cli": "~7.6.2", + "@babel/cli": "~7.6.3", "@babel/core": "~7.6.2", - "@babel/node": "~7.6.2", + "@babel/node": "~7.6.3", "@babel/plugin-proposal-throw-expressions": "^7.2.0", - "@babel/preset-env": "~7.6.2", + "@babel/preset-env": "~7.6.3", "@babel/register": "~7.6.2", - "apollo-server-testing": "~2.9.4", + "apollo-server-testing": "~2.9.5", "babel-core": "~7.0.0-0", "babel-eslint": "~10.0.3", "babel-jest": "~24.9.0", "chai": "~4.2.0", - "cucumber": "~5.1.0", + "cucumber": "~6.0.2", "eslint": "~6.5.1", - "eslint-config-prettier": "~6.3.0", + "eslint-config-prettier": "~6.4.0", "eslint-config-standard": "~14.1.0", "eslint-plugin-import": "~2.18.2", "eslint-plugin-jest": "~22.17.0", diff --git a/backend/src/middleware/email/templates/emailVerification.html b/backend/src/middleware/email/templates/emailVerification.html index 5b5564ebf..939ceccdb 100644 --- a/backend/src/middleware/email/templates/emailVerification.html +++ b/backend/src/middleware/email/templates/emailVerification.html @@ -57,7 +57,7 @@

Falls Du deine E-Mail Adresse doch nicht ändern möchtest, kannst du diese Nachricht - einfach ignorieren. Mlde Dich gerne bei + einfach ignorieren. Melde Dich gerne bei unserem Support Team, wenn du noch Fragen hast!

diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.js index 59ae06c07..8343443c9 100644 --- a/backend/src/middleware/permissionsMiddleware.js +++ b/backend/src/middleware/permissionsMiddleware.js @@ -174,7 +174,7 @@ const permissions = shield( VerifyEmailAddress: isAuthenticated, }, User: { - email: isMyOwn, + email: or(isMyOwn, isAdmin), }, }, { diff --git a/backend/src/middleware/permissionsMiddleware.spec.js b/backend/src/middleware/permissionsMiddleware.spec.js index 6cf9dc302..da703fb11 100644 --- a/backend/src/middleware/permissionsMiddleware.spec.js +++ b/backend/src/middleware/permissionsMiddleware.spec.js @@ -1,22 +1,63 @@ -import { GraphQLClient } from 'graphql-request' +import { createTestClient } from 'apollo-server-testing' +import createServer from '../server' import Factory from '../seed/factories' -import { host, login } from '../jest/helpers' +import { gql } from '../jest/helpers' +import { getDriver, neode as getNeode } from '../bootstrap/neo4j' const factory = Factory() +const instance = getNeode() +const driver = getDriver() + +let query, authenticatedUser, owner, anotherRegularUser, administrator, variables, moderator + +const userQuery = gql` + query($name: String) { + User(name: $name) { + email + } + } +` describe('authorization', () => { + beforeAll(async () => { + await factory.cleanDatabase() + const { server } = createServer({ + context: () => ({ + driver, + instance, + user: authenticatedUser, + }), + }) + query = createTestClient(server).query + }) + describe('given two existing users', () => { beforeEach(async () => { - await factory.create('User', { - email: 'owner@example.org', - name: 'Owner', - password: 'iamtheowner', - }) - await factory.create('User', { - email: 'someone@example.org', - name: 'Someone else', - password: 'else', - }) + ;[owner, anotherRegularUser, administrator, moderator] = await Promise.all([ + factory.create('User', { + email: 'owner@example.org', + name: 'Owner', + password: 'iamtheowner', + }), + factory.create('User', { + email: 'another.regular.user@example.org', + name: 'Another Regular User', + password: 'else', + }), + factory.create('User', { + email: 'admin@example.org', + name: 'Admin', + password: 'admin', + role: 'admin', + }), + factory.create('User', { + email: 'moderator@example.org', + name: 'Moderator', + password: 'moderator', + role: 'moderator', + }), + ]) + variables = {} }) afterEach(async () => { @@ -24,66 +65,77 @@ describe('authorization', () => { }) describe('access email address', () => { - let headers = {} - let loginCredentials = null - const action = async () => { - if (loginCredentials) { - headers = await login(loginCredentials) - } - const graphQLClient = new GraphQLClient(host, { headers }) - return graphQLClient.request('{User(name: "Owner") { email } }') - } - - describe('not logged in', () => { - it('rejects', async () => { - await expect(action()).rejects.toThrow('Not Authorised!') - }) - - it("does not expose the owner's email address", async () => { - let response = {} - try { - await action() - } catch (error) { - response = error.response.data - } finally { - expect(response).toEqual({ User: [null] }) - } - }) - }) - - describe('as owner', () => { + describe('unauthenticated', () => { beforeEach(() => { - loginCredentials = { - email: 'owner@example.org', - password: 'iamtheowner', - } + authenticatedUser = null }) - - it("exposes the owner's email address", async () => { - await expect(action()).resolves.toEqual({ User: [{ email: 'owner@example.org' }] }) + it("throws an error and does not expose the owner's email address", async () => { + await expect( + query({ query: userQuery, variables: { name: 'Owner' } }), + ).resolves.toMatchObject({ + errors: [{ message: 'Not Authorised!' }], + data: { User: [null] }, + }) }) }) - describe('authenticated as another user', () => { - beforeEach(async () => { - loginCredentials = { - email: 'someone@example.org', - password: 'else', - } + describe('authenticated', () => { + describe('as the owner', () => { + beforeEach(async () => { + authenticatedUser = await owner.toJson() + }) + + it("exposes the owner's email address", async () => { + variables = { name: 'Owner' } + await expect(query({ query: userQuery, variables })).resolves.toMatchObject({ + data: { User: [{ email: 'owner@example.org' }] }, + errors: undefined, + }) + }) }) - it('rejects', async () => { - await expect(action()).rejects.toThrow('Not Authorised!') + describe('as another regular user', () => { + beforeEach(async () => { + authenticatedUser = await anotherRegularUser.toJson() + }) + + it("throws an error and does not expose the owner's email address", async () => { + await expect( + query({ query: userQuery, variables: { name: 'Owner' } }), + ).resolves.toMatchObject({ + errors: [{ message: 'Not Authorised!' }], + data: { User: [null] }, + }) + }) }) - it("does not expose the owner's email address", async () => { - let response - try { - await action() - } catch (error) { - response = error.response.data - } - expect(response).toEqual({ User: [null] }) + describe('as a moderator', () => { + beforeEach(async () => { + authenticatedUser = await moderator.toJson() + }) + + it("throws an error and does not expose the owner's email address", async () => { + await expect( + query({ query: userQuery, variables: { name: 'Owner' } }), + ).resolves.toMatchObject({ + errors: [{ message: 'Not Authorised!' }], + data: { User: [null] }, + }) + }) + }) + + describe('administrator', () => { + beforeEach(async () => { + authenticatedUser = await administrator.toJson() + }) + + it("exposes the owner's email address", async () => { + variables = { name: 'Owner' } + await expect(query({ query: userQuery, variables })).resolves.toMatchObject({ + data: { User: [{ email: 'owner@example.org' }] }, + errors: undefined, + }) + }) }) }) }) diff --git a/backend/yarn.lock b/backend/yarn.lock index 990464fdb..ea3a38991 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -14,10 +14,10 @@ resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.24.tgz#3ce939cb127fb8aaa3ffc1e90dff9b8af9f2e3dc" integrity sha512-8GqG48m1XqyXh4mIZrtB5xOhUwSsh1WsrrsaZQOEYYql3YN9DEu9OOSg0ILzXHZo/h2Q74777YE4YzlArQzQEQ== -"@babel/cli@~7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.6.2.tgz#4ce8b5b4b2e4b4c1b7bd841cec62085e2dfc4465" - integrity sha512-JDZ+T/br9pPfT2lmAMJypJDTTTHM9ePD/ED10TRjRzJVdEVy+JB3iRlhzYmTt5YkNgHvxWGlUVnLtdv6ruiDrQ== +"@babel/cli@~7.6.3": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.6.3.tgz#1b0c62098c8a5e01e4a4a59a52cba9682e7e0906" + integrity sha512-kWKOEeuylpa781yCeA5//eEx1u3WtLZqbi2VWXLKmb3QDPb5T2f7Yk311MK7bvvjR70dluAeiu4VXXsG1WwJsw== dependencies: commander "^2.8.1" convert-source-map "^1.1.0" @@ -27,7 +27,7 @@ mkdirp "^0.5.1" output-file-sync "^2.0.0" slash "^2.0.0" - source-map "^0.5.0" + source-map "^0.6.1" optionalDependencies: chokidar "^2.1.8" @@ -241,10 +241,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/node@~7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.6.2.tgz#a94479f95ee2008342f4847346c8bb8ff2770f44" - integrity sha512-59UxvVtRpVpL5i0KTcw41FqLNPT/Jc9k/48Rq00wfN49lAIQeRKGwZ6xX1FWlCfcIGP+5l4rfZajORvmYkhfGg== +"@babel/node@~7.6.3": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.6.3.tgz#f175ab6718dde55431cbd4d9dee95f65c38be527" + integrity sha512-+nHje5AcE9TPlB/TRGYyOSQyTfhfU/WXniG6SkVf+V5+ibAjEqkH79lYdiEcytBTH4KeSf25IriySXs6TjaLjg== dependencies: "@babel/register" "^7.6.2" commander "^2.8.1" @@ -382,10 +382,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-block-scoping@^7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.2.tgz#96c33ab97a9ae500cc6f5b19e04a7e6553360a79" - integrity sha512-zZT8ivau9LOQQaOGC7bQLQOT4XPkPXgN2ERfUgk1X8ql+mVkLc4E8eKk+FO3o0154kxzqenWCorfmEXpEZcrSQ== +"@babel/plugin-transform-block-scoping@^7.6.3": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.3.tgz#6e854e51fbbaa84351b15d4ddafe342f3a5d542a" + integrity sha512-7hvrg75dubcO3ZI2rjYTzUrEuh1E9IyDEhhB6qfcooxhDA33xx2MasuLVgdxzcP6R/lipAC6n9ub9maNW6RKdw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.13" @@ -507,10 +507,10 @@ "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-named-capturing-groups-regex@^7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.2.tgz#c1ca0bb84b94f385ca302c3932e870b0fb0e522b" - integrity sha512-xBdB+XOs+lgbZc2/4F5BVDVcDNS4tcSKQc96KmlqLEAwz6tpYPEvPdmDfvVG0Ssn8lAhronaRs6Z6KSexIpK5g== +"@babel/plugin-transform-named-capturing-groups-regex@^7.6.3": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.3.tgz#aaa6e409dd4fb2e50b6e2a91f7e3a3149dbce0cf" + integrity sha512-jTkk7/uE6H2s5w6VlMHeWuH+Pcy2lmdwFoeWCVnvIrDUnB5gQqTVI8WfmEAhF2CDEarGrknZcmSFg1+bkfCoSw== dependencies: regexpu-core "^4.6.0" @@ -605,18 +605,10 @@ "@babel/helper-regex" "^7.4.4" regexpu-core "^4.6.0" -"@babel/polyfill@^7.2.3": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.6.0.tgz#6d89203f8b6cd323e8d946e47774ea35dc0619cc" - integrity sha512-q5BZJI0n/B10VaQQvln1IlDK3BTBJFbADx7tv+oXDPIDZuTo37H5Adb9jhlXm/fEN4Y7/64qD9mnrJJG7rmaTw== - dependencies: - core-js "^2.6.5" - regenerator-runtime "^0.13.2" - -"@babel/preset-env@~7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.6.2.tgz#abbb3ed785c7fe4220d4c82a53621d71fc0c75d3" - integrity sha512-Ru7+mfzy9M1/YTEtlDS8CD45jd22ngb9tXnn64DvQK3ooyqSw9K4K9DUWmYknTTVk4TqygL9dqCrZgm1HMea/Q== +"@babel/preset-env@~7.6.3": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.6.3.tgz#9e1bf05a2e2d687036d24c40e4639dc46cef2271" + integrity sha512-CWQkn7EVnwzlOdR5NOm2+pfgSNEZmvGjOhlCHBDq0J8/EStr+G+FvPEiz9B56dR6MoiUFjXhfE4hjLoAKKJtIQ== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -634,7 +626,7 @@ "@babel/plugin-transform-arrow-functions" "^7.2.0" "@babel/plugin-transform-async-to-generator" "^7.5.0" "@babel/plugin-transform-block-scoped-functions" "^7.2.0" - "@babel/plugin-transform-block-scoping" "^7.6.2" + "@babel/plugin-transform-block-scoping" "^7.6.3" "@babel/plugin-transform-classes" "^7.5.5" "@babel/plugin-transform-computed-properties" "^7.2.0" "@babel/plugin-transform-destructuring" "^7.6.0" @@ -649,7 +641,7 @@ "@babel/plugin-transform-modules-commonjs" "^7.6.0" "@babel/plugin-transform-modules-systemjs" "^7.5.0" "@babel/plugin-transform-modules-umd" "^7.2.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.6.2" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.6.3" "@babel/plugin-transform-new-target" "^7.4.4" "@babel/plugin-transform-object-super" "^7.5.5" "@babel/plugin-transform-parameters" "^7.4.4" @@ -662,7 +654,7 @@ "@babel/plugin-transform-template-literals" "^7.4.4" "@babel/plugin-transform-typeof-symbol" "^7.2.0" "@babel/plugin-transform-unicode-regex" "^7.6.2" - "@babel/types" "^7.6.0" + "@babel/types" "^7.6.3" browserslist "^4.6.0" core-js-compat "^3.1.1" invariant "^2.2.2" @@ -719,10 +711,10 @@ globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0": - version "7.6.1" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.1.tgz#53abf3308add3ac2a2884d539151c57c4b3ac648" - integrity sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g== +"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0", "@babel/types@^7.6.3": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.3.tgz#3f07d96f854f98e2fbd45c64b0cb942d11e8ba09" + integrity sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA== dependencies: esutils "^2.0.2" lodash "^4.17.13" @@ -766,10 +758,10 @@ "@hapi/hoek" "8.x.x" "@hapi/topo" "3.x.x" -"@hapi/joi@^16.1.5": - version "16.1.5" - resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-16.1.5.tgz#06bdfec1084f46bff6be8f6b4076d8314c81cea2" - integrity sha512-FnVe0t1YQbF0H4fhFM6qBL7lIP4wdVHdFFBkloxgCkpKKdaCB6Z2UaNI0UalaDRHbRM9BvfTfyUKJg7tGtBSXg== +"@hapi/joi@^16.1.7": + version "16.1.7" + resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-16.1.7.tgz#360857223a87bb1f5f67691537964c1b4908ed93" + integrity sha512-anaIgnZhNooG3LJLrTFzgGALTiO97zRA1UkvQHm9KxxoSiIzCozB3RCNCpDnfhTJD72QlrHA8nwGmNgpFFCIeg== dependencies: "@hapi/address" "^2.1.2" "@hapi/formula" "^1.2.0" @@ -1668,10 +1660,10 @@ apollo-server-caching@^0.5.0: dependencies: lru-cache "^5.0.0" -apollo-server-core@^2.9.4: - version "2.9.4" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.9.4.tgz#0404455884951804d23ea64e45514c73afd34e5e" - integrity sha512-6mzipnn9woJxgo/JQFWTlY13svS7HCr0ZsN035eRmKOsXzROfB9ugXcTuc6MP94ICM7TlB/DtJOP+bLX53mijw== +apollo-server-core@^2.9.5: + version "2.9.5" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.9.5.tgz#b2d9188d7acce5fe92a5460d276794988ffa6737" + integrity sha512-SlM/vhjhWb0ayXV3d4gnpq9gh2BsQj+UPfQXfq2X2KG9EH5I1JUH6EtlsctgMCZozirOZmEmUzlqZWSSUOUPgQ== dependencies: "@apollographql/apollo-tools" "^0.4.0" "@apollographql/graphql-playground-html" "1.6.24" @@ -1708,10 +1700,10 @@ apollo-server-errors@^2.3.3: resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.3.3.tgz#83763b00352c10dc68fbb0d41744ade66de549ff" integrity sha512-MO4oJ129vuCcbqwr5ZwgxqGGiLz3hCyowz0bstUF7MR+vNGe4oe3DWajC9lv4CxrhcqUHQOeOPViOdIo1IxE3g== -apollo-server-express@^2.9.4: - version "2.9.4" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.9.4.tgz#ae7ca0b70a644ba9fa5e3ac395d1e2d9a4b23522" - integrity sha512-diX9n81E0tIJ0Sy2bHvDGPM9QsFBsZ76Nx/dszinY00ViyWG0yIAYEYWeRbsoKTeNDWWTvlMrh/3Eu2oaCIEhQ== +apollo-server-express@^2.9.4, apollo-server-express@^2.9.5: + version "2.9.5" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.9.5.tgz#383e0a5cb80cf1172b0bc1e565797edd629d750a" + integrity sha512-6gonP7g5u2Kr+9cvKE+NuGPe+As7wRbz2yWoyLOym/TdXBmTRU4AKW2Qs+wpNanurzm2xbTa7sEfzrHGmembrQ== dependencies: "@apollographql/graphql-playground-html" "1.6.24" "@types/accepts" "^1.3.5" @@ -1719,7 +1711,7 @@ apollo-server-express@^2.9.4: "@types/cors" "^2.8.4" "@types/express" "4.17.1" accepts "^1.3.5" - apollo-server-core "^2.9.4" + apollo-server-core "^2.9.5" apollo-server-types "^0.2.4" body-parser "^1.18.3" cors "^2.8.4" @@ -1737,12 +1729,12 @@ apollo-server-plugin-base@^0.6.4: dependencies: apollo-server-types "^0.2.4" -apollo-server-testing@~2.9.4: - version "2.9.4" - resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.9.4.tgz#421783573bdc5cef70dfe574b5193db38a33b5fb" - integrity sha512-qvnA9cXRKqizfYPHBli4LeSKYXwFVsQkGF3eHgofN/RbTqnEBqW7I5L14qDYAjGZg9/Z4alJf69hFE8KPHbT0Q== +apollo-server-testing@~2.9.5: + version "2.9.5" + resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.9.5.tgz#ff5bbe3fefdf4d639bb138277d3dfc846b309438" + integrity sha512-IoElvnJ0Zex6i1QZj9v0szbDvCM6LF1gSZlQswRuIeTwvvquzixFVGMpLZKItojmjrCSxsT7DHJxeUFugZJUWA== dependencies: - apollo-server-core "^2.9.4" + apollo-server-core "^2.9.5" apollo-server-types@^0.2.4: version "0.2.4" @@ -1753,13 +1745,13 @@ apollo-server-types@^0.2.4: apollo-server-caching "^0.5.0" apollo-server-env "^2.4.3" -apollo-server@~2.9.4: - version "2.9.4" - resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.9.4.tgz#564a0d0ec6dbefc86dbabe15bd23a83e48f58314" - integrity sha512-huAgQizkmzUkREixsSJHNM4ZnJ08plkwK70dm36mX9j+yYbc0h9J5b5o4E2Fb9U5PMR8kEVto1dz2rOJ0XPApA== +apollo-server@~2.9.5: + version "2.9.5" + resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.9.5.tgz#4f616337d04f2f0886d4bbe46b047a32a649b1fd" + integrity sha512-hbWZAZ3g186NG9U9bVmMpPcbUJ+/f/CSL+/tJsK6iQPp5L3hcVYoe+/qDw3zpfDMA5R2Jq/yHZtF2LcI5ylVnQ== dependencies: - apollo-server-core "^2.9.4" - apollo-server-express "^2.9.4" + apollo-server-core "^2.9.5" + apollo-server-express "^2.9.5" express "^4.0.0" graphql-subscriptions "^1.0.0" graphql-tools "^4.0.0" @@ -1880,12 +1872,12 @@ assert@^1.4.1: object-assign "^4.1.1" util "0.10.3" -assertion-error-formatter@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/assertion-error-formatter/-/assertion-error-formatter-2.0.1.tgz#6bbdffaec8e2fa9e2b0eb158bfe353132d7c0a9b" - integrity sha512-cjC3jUCh9spkroKue5PDSKH5RFQ/KNuZJhk3GwHYmB/8qqETxLOmMdLH+ohi/VukNzxDlMvIe7zScvLoOdhb6Q== +assertion-error-formatter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/assertion-error-formatter/-/assertion-error-formatter-3.0.0.tgz#be9c8825dee6a8a6c72183d915912d9b57d5d265" + integrity sha512-6YyAVLrEze0kQ7CmJfUgrLHb+Y7XghmL2Ie7ijVa2Y9ynP3LV+VDiwFk62Dn0qtqbmY0BT0ss6p1xxpiF2PYbQ== dependencies: - diff "^3.0.0" + diff "^4.0.1" pad-right "^0.2.2" repeat-string "^1.6.1" @@ -2073,7 +2065,7 @@ bcryptjs@~2.4.3: resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms= -becke-ch--regex--s0-0-v1--base--pl--lib@^1.2.0: +becke-ch--regex--s0-0-v1--base--pl--lib@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/becke-ch--regex--s0-0-v1--base--pl--lib/-/becke-ch--regex--s0-0-v1--base--pl--lib-1.4.0.tgz#429ceebbfa5f7e936e78d73fbdc7da7162b20e20" integrity sha1-Qpzuu/pffpNueNc/vcfacWKyDiA= @@ -2487,11 +2479,16 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.8.1, commander@^2.9.0, commander@~2.20.0: +commander@^2.8.1, commander@~2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== +commander@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" + integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -2710,49 +2707,48 @@ cssstyle@^1.0.0: dependencies: cssom "0.3.x" -cucumber-expressions@^6.0.0: - version "6.6.2" - resolved "https://registry.yarnpkg.com/cucumber-expressions/-/cucumber-expressions-6.6.2.tgz#d89640eccc72a78380b6c210eae36a64e7462b81" - integrity sha512-WcFSVBiWNLJbIcAAC3t/ACU46vaOKfe1UIF5H3qveoq+Y4XQm9j3YwHurQNufRKBBg8nCnpU7Ttsx7egjS3hwA== +cucumber-expressions@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cucumber-expressions/-/cucumber-expressions-8.0.1.tgz#47eb87dcb626e90a4672986da1130f3c470b9e3d" + integrity sha512-g+A+tUEafNofe6ErwvOkqaMvDj9NuOr0GouGotpw4r5yK2d4144o9/6sQpXBr2YXbRy5ItmER/2bzAyDAzhPyQ== dependencies: - becke-ch--regex--s0-0-v1--base--pl--lib "^1.2.0" + becke-ch--regex--s0-0-v1--base--pl--lib "^1.4.0" + xregexp "^4.2.4" -cucumber-tag-expressions@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/cucumber-tag-expressions/-/cucumber-tag-expressions-1.1.1.tgz#7f5c7b70009bc2b666591bfe64854578bedee85a" - integrity sha1-f1x7cACbwrZmWRv+ZIVFeL7e6Fo= +cucumber-tag-expressions@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/cucumber-tag-expressions/-/cucumber-tag-expressions-2.0.2.tgz#aac27aae3690818ec15235bd056282dad8a2d2b8" + integrity sha512-DohmT4X641KX/sb96bdb7J2kXNcQBPrYmf3Oc5kiHCLfzFMWx/o2kB4JvjvQPZnYuA9lRt6pqtArM5gvUn4uzw== -cucumber@~5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cucumber/-/cucumber-5.1.0.tgz#7b166812c255bec7eac4b0df7007a40d089c895d" - integrity sha512-zrl2VYTBRgvxucwV2GKAvLqcfA1Naeax8plPvWgPEzl3SCJiuPPv3WxBHIRHtPYcEdbHDR6oqLpZP4bJ8UIdmA== +cucumber@~6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/cucumber/-/cucumber-6.0.2.tgz#3c4fbf1f76e60ddee79ab58f137a62c897a4d7f0" + integrity sha512-yEwPYGvgS2KG6ODdUXQwWcxjyr/l31dmpGJsZSkJIXNLNNmieKVefTpf8zLj6+0V2TCPwkmUZt4+OIXv97duEw== dependencies: - "@babel/polyfill" "^7.2.3" - assertion-error-formatter "^2.0.1" + assertion-error-formatter "^3.0.0" bluebird "^3.4.1" cli-table3 "^0.5.1" colors "^1.1.2" - commander "^2.9.0" - cross-spawn "^6.0.5" - cucumber-expressions "^6.0.0" - cucumber-tag-expressions "^1.1.1" + commander "^3.0.1" + cucumber-expressions "^8.0.1" + cucumber-tag-expressions "^2.0.2" duration "^0.2.1" - escape-string-regexp "^1.0.5" - figures "2.0.0" - gherkin "^5.0.0" + escape-string-regexp "^2.0.0" + figures "^3.0.0" + gherkin "5.0.0" glob "^7.1.3" - indent-string "^3.1.0" + indent-string "^4.0.0" is-generator "^1.0.2" - is-stream "^1.1.0" + is-stream "^2.0.0" knuth-shuffle-seeded "^1.0.6" - lodash "^4.17.10" + lodash "^4.17.14" mz "^2.4.0" progress "^2.0.0" resolve "^1.3.3" - serialize-error "^3.0.0" + serialize-error "^4.1.0" stack-chain "^2.0.0" stacktrace-js "^2.0.0" - string-argv "0.1.1" + string-argv "^0.3.0" title-case "^2.1.1" util-arity "^1.0.2" verror "^1.9.0" @@ -2937,10 +2933,10 @@ diff-sequences@^24.9.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== -diff@^3.0.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== +diff@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" + integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q== dns-prefetch-control@0.2.0: version "0.2.0" @@ -3193,6 +3189,11 @@ escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + escodegen@^1.9.1: version "1.12.0" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.0.tgz#f763daf840af172bb3a2b6dd7219c0e17f7ff541" @@ -3205,10 +3206,10 @@ escodegen@^1.9.1: optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@~6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.3.0.tgz#e73b48e59dc49d950843f3eb96d519e2248286a3" - integrity sha512-EWaGjlDAZRzVFveh2Jsglcere2KK5CJBhkNSa1xs3KfMUGdRiT7lG089eqPdvlzWHpAqaekubOsOMu8W8Yk71A== +eslint-config-prettier@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.4.0.tgz#0a04f147e31d33c6c161b2dd0971418ac52d0477" + integrity sha512-YrKucoFdc7SEko5Sxe4r6ixqXPDP1tunGw91POeZTTRKItf/AMFYt/YLEQtZMkR2LVpAVhcAcZgcWpm1oGPW7w== dependencies: get-stdin "^6.0.0" @@ -3627,13 +3628,6 @@ feature-policy@0.3.0: resolved "https://registry.yarnpkg.com/feature-policy/-/feature-policy-0.3.0.tgz#7430e8e54a40da01156ca30aaec1a381ce536069" integrity sha512-ZtijOTFN7TzCujt1fnNhfWPFPSHeZkesff9AXZj+UEjYBynWNUIYpC87Ve4wHzyexQsImicLu7WsC2LHq7/xrQ== -figures@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= - dependencies: - escape-string-regexp "^1.0.5" - figures@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.0.0.tgz#756275c964646163cc6f9197c7a0295dbfd04de9" @@ -3892,10 +3886,10 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -gherkin@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/gherkin/-/gherkin-5.1.0.tgz#684bbb03add24eaf7bdf544f58033eb28fb3c6d5" - integrity sha1-aEu7A63STq9731RPWAM+so+zxtU= +gherkin@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/gherkin/-/gherkin-5.0.0.tgz#96def41198ec3908258b511af74f655a2764d2a1" + integrity sha1-lt70EZjsOQgli1Ea909lWidk0qE= glob-parent@^3.1.0: version "3.1.0" @@ -4411,11 +4405,16 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -indent-string@^3.1.0, indent-string@^3.2.0: +indent-string@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -4771,6 +4770,11 @@ is-stream@^1.0.0, is-stream@^1.1.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + is-symbol@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" @@ -5590,7 +5594,7 @@ lodash.unescape@4.0.1: resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= -lodash@4.17.15, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.11, lodash@~4.17.14, lodash@~4.17.15: +lodash@4.17.15, lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.11, lodash@~4.17.14, lodash@~4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -7437,10 +7441,12 @@ send@0.17.1: range-parser "~1.2.1" statuses "~1.5.0" -serialize-error@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-3.0.0.tgz#80100282b09be33c611536f50033481cb9cc87cf" - integrity sha512-+y3nkkG/go1Vdw+2f/+XUXM1DXX1XcxTl99FfiD/OEPUNw4uo0i6FKABfTAN5ZcgGtjTRZcEbxcE/jtXbEY19A== +serialize-error@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-4.1.0.tgz#63e1e33ede20bcd89d9f0528ea4c15fbf0f2b78a" + integrity sha512-5j9GgyGsP9vV9Uj1S0lDCvlsd+gc2LEPVK7HHHte7IyPwOD4lVQFeaX143gx3U5AnoCi+wbcb3mvaxVysjpxEw== + dependencies: + type-fest "^0.3.0" serve-static@1.14.1: version "1.14.1" @@ -7730,10 +7736,10 @@ streamsearch@0.1.2: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= -string-argv@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.1.1.tgz#66bd5ae3823708eaa1916fa5412703150d4ddfaf" - integrity sha512-El1Va5ehZ0XTj3Ekw4WFidXvTmt9SrC0+eigdojgtJMVtPkF0qbBe9fyNSl9eQf+kUHnTSQxdQYzuHfZy8V+DQ== +string-argv@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" + integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== string-length@^2.0.0: version "2.0.0" diff --git a/package.json b/package.json index 62020c4e4..5427090dc 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "codecov": "^3.6.1", "cross-env": "^6.0.3", "cypress": "^3.4.1", - "cypress-cucumber-preprocessor": "^1.16.0", + "cypress-cucumber-preprocessor": "^1.16.1", "cypress-file-upload": "^3.3.4", "cypress-plugin-retries": "^1.3.0", "dotenv": "^8.1.0", diff --git a/webapp/Dockerfile b/webapp/Dockerfile index 87793de92..1a27e6d94 100644 --- a/webapp/Dockerfile +++ b/webapp/Dockerfile @@ -1,4 +1,4 @@ -FROM node:12.10.0-alpine as base +FROM node:12.11.1-alpine as base LABEL Description="Web Frontend of the Social Network Human-Connection.org" Vendor="Human-Connection gGmbH" Version="0.0.1" Maintainer="Human-Connection gGmbH (developer@human-connection.org)" EXPOSE 3000 diff --git a/webapp/Dockerfile.maintenance b/webapp/Dockerfile.maintenance index 116016480..e32048252 100644 --- a/webapp/Dockerfile.maintenance +++ b/webapp/Dockerfile.maintenance @@ -1,4 +1,4 @@ -FROM node:12.10.0-alpine as build +FROM node:12.11.1-alpine as build LABEL Description="Web Frontend of the Social Network Human-Connection.org" Vendor="Human-Connection gGmbH" Version="0.0.1" Maintainer="Human-Connection gGmbH (developer@human-connection.org)" EXPOSE 3000 diff --git a/webapp/components/ContributionForm/ContributionForm.spec.js b/webapp/components/ContributionForm/ContributionForm.spec.js index eaba26360..836fe3fd3 100644 --- a/webapp/components/ContributionForm/ContributionForm.spec.js +++ b/webapp/components/ContributionForm/ContributionForm.spec.js @@ -32,7 +32,7 @@ describe('ContributionForm.vue', () => { const postTitle = 'this is a title for a post' const postTitleTooShort = 'xx' let postTitleTooLong = '' - for (let i = 0; i < 65; i++) { + for (let i = 0; i < 101; i++) { postTitleTooLong += 'x' } const postContent = 'this is a post' diff --git a/webapp/components/ContributionForm/ContributionForm.vue b/webapp/components/ContributionForm/ContributionForm.vue index c783298f4..73fa0afd9 100644 --- a/webapp/components/ContributionForm/ContributionForm.vue +++ b/webapp/components/ContributionForm/ContributionForm.vue @@ -104,7 +104,7 @@ export default { categoryIds: [], }, formSchema: { - title: { required: true, min: 3, max: 64 }, + title: { required: true, min: 3, max: 100 }, content: [{ required: true }], }, id: null, diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 5034e1c4c..19340ab2e 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -281,6 +281,7 @@ "columns": { "number": "Nr.", "name": "Name", + "email": "E-mail", "slug": "Slug", "role": "Rolle", "createdAt": "Erstellt am" diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 1b2edb86f..bbd3795e0 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -281,6 +281,7 @@ "columns": { "number": "No.", "name": "Name", + "email": "E-mail", "slug": "Slug", "role": "Role", "createdAt": "Created at" diff --git a/webapp/package.json b/webapp/package.json index be343570e..de2556535 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -76,8 +76,8 @@ "stack-utils": "^1.0.2", "string-hash": "^1.1.3", "tippy.js": "^4.3.5", - "tiptap": "~1.26.0", - "tiptap-extensions": "~1.28.0", + "tiptap": "~1.26.3", + "tiptap-extensions": "~1.28.3", "trunc-html": "^1.1.2", "v-tooltip": "~2.0.2", "vue-count-to": "~1.0.13", @@ -94,8 +94,8 @@ "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/preset-env": "~7.6.2", "@storybook/addon-a11y": "^5.2.1", - "@storybook/addon-actions": "^5.2.1", - "@storybook/vue": "~5.2.1", + "@storybook/addon-actions": "^5.2.3", + "@storybook/vue": "~5.2.3", "@vue/cli-shared-utils": "~3.11.0", "@vue/eslint-config-prettier": "~5.0.0", "@vue/server-test-utils": "~1.0.0-beta.29", @@ -109,7 +109,7 @@ "core-js": "~2.6.9", "css-loader": "~3.2.0", "eslint": "~5.16.0", - "eslint-config-prettier": "~6.3.0", + "eslint-config-prettier": "~6.4.0", "eslint-config-standard": "~12.0.0", "eslint-loader": "~3.0.2", "eslint-plugin-import": "~2.18.2", diff --git a/webapp/pages/admin/users.vue b/webapp/pages/admin/users.vue index e58b413aa..d5590f474 100644 --- a/webapp/pages/admin/users.vue +++ b/webapp/pages/admin/users.vue @@ -33,6 +33,11 @@ {{ scope.row.name | truncate(20) }} +