diff --git a/admin/.eslintignore b/admin/.eslintignore index 94934f9e7..e19e2338d 100644 --- a/admin/.eslintignore +++ b/admin/.eslintignore @@ -1,3 +1,3 @@ node_modules/ -dist/ +build/ coverage/ \ No newline at end of file diff --git a/admin/.gitignore b/admin/.gitignore index a67d270bc..3bc7bb4b2 100644 --- a/admin/.gitignore +++ b/admin/.gitignore @@ -1,5 +1,5 @@ node_modules/ -dist/ +build/ .cache/ /.env diff --git a/admin/Dockerfile b/admin/Dockerfile index ed0623a63..029339f10 100644 --- a/admin/Dockerfile +++ b/admin/Dockerfile @@ -84,7 +84,7 @@ CMD /bin/sh -c "yarn run dev" FROM base as production # Copy "binary"-files from build image -COPY --from=build ${DOCKER_WORKDIR}/dist ./dist +COPY --from=build ${DOCKER_WORKDIR}/build ./build # We also copy the node_modules express and serve-static for the run script COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules # Copy static files diff --git a/admin/package.json b/admin/package.json index 04c9a60e8..7a3b36a7a 100644 --- a/admin/package.json +++ b/admin/package.json @@ -11,7 +11,7 @@ "serve": "vue-cli-service serve --open", "build": "vue-cli-service build", "dev": "yarn run serve", - "analyse-bundle": "yarn build && webpack-bundle-analyzer dist/webpack.stats.json", + "analyse-bundle": "yarn build && webpack-bundle-analyzer build/webpack.stats.json", "lint": "eslint --max-warnings=0 --ext .js,.vue,.json .", "stylelint": "stylelint --max-warnings=0 '**/*.{scss,vue}'", "test": "cross-env TZ=UTC jest", diff --git a/admin/run/server.js b/admin/run/server.js index bccefc65c..b5078a0cf 100644 --- a/admin/run/server.js +++ b/admin/run/server.js @@ -9,10 +9,10 @@ const port = process.env.PORT || 8080 // Express Server const app = express() // Serve files -app.use(express.static(path.join(__dirname, '../dist'))) +app.use(express.static(path.join(__dirname, '../build'))) // Default to index.html app.get('*', (req, res) => { - res.sendFile(path.join(__dirname, '../dist/index.html')) + res.sendFile(path.join(__dirname, '../build/index.html')) }) app.listen(port, hostname, () => { diff --git a/admin/src/components/Fedaration/FederationVisualizeItem.vue b/admin/src/components/Fedaration/FederationVisualizeItem.vue index faace7da1..a947387f4 100644 --- a/admin/src/components/Fedaration/FederationVisualizeItem.vue +++ b/admin/src/components/Fedaration/FederationVisualizeItem.vue @@ -13,7 +13,7 @@ diff --git a/frontend/src/components/LanguageSwitch.spec.js b/frontend/src/components/LanguageSwitch.spec.js index 7f37c535a..6c733de7d 100644 --- a/frontend/src/components/LanguageSwitch.spec.js +++ b/frontend/src/components/LanguageSwitch.spec.js @@ -15,7 +15,7 @@ describe('LanguageSwitch', () => { let wrapper const state = { - email: 'he@ho.he', + gradidoID: 'current-user-id', language: null, } diff --git a/frontend/src/components/LanguageSwitch.vue b/frontend/src/components/LanguageSwitch.vue index 9d901ae9f..38194ba9c 100644 --- a/frontend/src/components/LanguageSwitch.vue +++ b/frontend/src/components/LanguageSwitch.vue @@ -31,7 +31,7 @@ export default { async saveLocale(locale) { // if (this.$i18n.locale === locale) return this.setLocale(locale) - if (this.$store.state.email) { + if (this.$store.state.gradidoID) { this.$apollo .mutate({ mutation: updateUserInfos, diff --git a/frontend/src/components/LanguageSwitch2.spec.js b/frontend/src/components/LanguageSwitch2.spec.js index 0d2b485ec..e7ff6e8c6 100644 --- a/frontend/src/components/LanguageSwitch2.spec.js +++ b/frontend/src/components/LanguageSwitch2.spec.js @@ -15,7 +15,7 @@ describe('LanguageSwitch', () => { let wrapper const state = { - email: 'he@ho.he', + gradidoID: 'current-user-id', language: null, } diff --git a/frontend/src/components/LanguageSwitch2.vue b/frontend/src/components/LanguageSwitch2.vue index d398d2fe0..46b2a5277 100644 --- a/frontend/src/components/LanguageSwitch2.vue +++ b/frontend/src/components/LanguageSwitch2.vue @@ -59,7 +59,7 @@ export default { async saveLocale(locale) { if (this.$i18n.locale === locale) return this.setLocale(locale) - if (this.$store.state.email) { + if (this.$store.state.gradidoID) { this.$apollo .mutate({ mutation: updateUserInfos, diff --git a/frontend/src/components/Menu/Navbar.spec.js b/frontend/src/components/Menu/Navbar.spec.js index 1e05df71d..a942c2644 100644 --- a/frontend/src/components/Menu/Navbar.spec.js +++ b/frontend/src/components/Menu/Navbar.spec.js @@ -20,7 +20,7 @@ const mocks = { state: { firstName: 'Testy', lastName: 'User', - email: 'testy.user@example.com', + gradidoID: 'current-user-id', }, }, } @@ -64,8 +64,8 @@ describe('AuthNavbar', () => { ) }) - it('has the email address', () => { - // expect(wrapper.find('div.small:nth-child(2)').text()).toBe(wrapper.vm.$store.state.email) + // I think this should be username + it.skip('has the email address', () => { expect(wrapper.find('div[data-test="navbar-item-email"]').text()).toBe( wrapper.vm.$store.state.email, ) diff --git a/frontend/src/components/TransactionRows/AmountAndNameRow.spec.js b/frontend/src/components/TransactionRows/AmountAndNameRow.spec.js index 172f5f401..747cefe64 100644 --- a/frontend/src/components/TransactionRows/AmountAndNameRow.spec.js +++ b/frontend/src/components/TransactionRows/AmountAndNameRow.spec.js @@ -39,37 +39,5 @@ describe('AmountAndNameRow', () => { expect(wrapper.find('div.gdd-transaction-list-item-name').find('a').exists()).toBe(false) }) }) - - describe('with linked user', () => { - beforeEach(async () => { - await wrapper.setProps({ - linkedUser: { firstName: 'Bibi', lastName: 'Bloxberg', email: 'bibi@bloxberg.de' }, - }) - }) - - it('has a link with first and last name', () => { - expect(wrapper.find('div.gdd-transaction-list-item-name').text()).toBe('Bibi Bloxberg') - }) - - it('has a link', () => { - expect(wrapper.find('div.gdd-transaction-list-item-name').find('a').exists()).toBe(true) - }) - - describe('click link', () => { - beforeEach(async () => { - await wrapper.find('div.gdd-transaction-list-item-name').find('a').trigger('click') - }) - - it('emits set tunneled email', () => { - expect(wrapper.emitted('set-tunneled-email')).toEqual([['bibi@bloxberg.de']]) - }) - - it('pushes the route with query for email', () => { - expect(mocks.$router.push).toBeCalledWith({ - path: '/send', - }) - }) - }) - }) }) }) diff --git a/frontend/src/components/TransactionRows/AmountAndNameRow.vue b/frontend/src/components/TransactionRows/AmountAndNameRow.vue index eb68d9f37..530fdf0e8 100644 --- a/frontend/src/components/TransactionRows/AmountAndNameRow.vue +++ b/frontend/src/components/TransactionRows/AmountAndNameRow.vue @@ -10,21 +10,7 @@
- - - {{ itemText }} - - - {{ itemText }} - - {{ $t('via_link') }} - - + {{ text }}
@@ -38,31 +24,9 @@ export default { type: String, required: true, }, - linkedUser: { - type: Object, - required: false, - }, text: { type: String, - required: false, - }, - linkId: { - type: Number, - required: false, - default: null, - }, - }, - methods: { - tunnelEmail() { - this.$emit('set-tunneled-email', this.linkedUser.email) - this.$router.push({ path: '/send' }) - }, - }, - computed: { - itemText() { - return this.linkedUser - ? this.linkedUser.firstName + ' ' + this.linkedUser.lastName - : this.text + required: true, }, }, } diff --git a/frontend/src/components/TransactionRows/DurationRow.vue b/frontend/src/components/TransactionRows/DurationRow.vue index 6f62d9dc5..f9b7873d6 100644 --- a/frontend/src/components/TransactionRows/DurationRow.vue +++ b/frontend/src/components/TransactionRows/DurationRow.vue @@ -12,7 +12,7 @@ + diff --git a/frontend/src/components/UserSettings/UserNewsletter.spec.js b/frontend/src/components/UserSettings/UserNewsletter.spec.js index b211ec169..7ae3ddd7c 100644 --- a/frontend/src/components/UserSettings/UserNewsletter.spec.js +++ b/frontend/src/components/UserSettings/UserNewsletter.spec.js @@ -18,7 +18,6 @@ describe('UserCard_Newsletter', () => { $store: { state: { language: 'de', - email: 'peter@lustig.de', newsletterState: true, }, commit: storeCommitMock, diff --git a/frontend/src/graphql/mutations.js b/frontend/src/graphql/mutations.js index 65bdd7497..8a281aad9 100644 --- a/frontend/src/graphql/mutations.js +++ b/frontend/src/graphql/mutations.js @@ -26,6 +26,7 @@ export const forgotPassword = gql` export const updateUserInfos = gql` mutation( + $alias: String $firstName: String $lastName: String $password: String @@ -35,6 +36,7 @@ export const updateUserInfos = gql` $hideAmountGDT: Boolean ) { updateUserInfos( + alias: $alias firstName: $firstName lastName: $lastName password: $password @@ -145,7 +147,7 @@ export const login = gql` mutation($email: String!, $password: String!, $publisherId: Int) { login(email: $email, password: $password, publisherId: $publisherId) { gradidoID - email + alias firstName lastName language diff --git a/frontend/src/graphql/queries.js b/frontend/src/graphql/queries.js index d0cbc145d..f254b93cc 100644 --- a/frontend/src/graphql/queries.js +++ b/frontend/src/graphql/queries.js @@ -3,7 +3,7 @@ import gql from 'graphql-tag' export const verifyLogin = gql` query { verifyLogin { - email + gradidoID firstName lastName language @@ -40,7 +40,6 @@ export const transactionsQuery = gql` firstName lastName gradidoID - email } decay { decay @@ -90,6 +89,12 @@ export const queryOptIn = gql` } ` +export const checkUsername = gql` + query($username: String!) { + checkUsername(username: $username) + } +` + export const queryTransactionLink = gql` query($code: String!) { queryTransactionLink(code: $code) { @@ -102,9 +107,9 @@ export const queryTransactionLink = gql` redeemedAt deletedAt user { + gradidoID firstName publisherId - email } } ... on ContributionLink { diff --git a/frontend/src/layouts/DashboardLayout.spec.js b/frontend/src/layouts/DashboardLayout.spec.js index 9f68199da..a2a666591 100644 --- a/frontend/src/layouts/DashboardLayout.spec.js +++ b/frontend/src/layouts/DashboardLayout.spec.js @@ -43,7 +43,6 @@ const mocks = { $store: { dispatch: storeDispatchMock, state: { - email: 'user@example.org', publisherId: 123, firstName: 'User', lastName: 'Example', @@ -260,34 +259,6 @@ describe('DashboardLayout', () => { }) }) - describe.skip('elopage URI', () => { - describe('user has no publisher ID and no elopage', () => { - beforeEach(() => { - mocks.$store.state.publisherId = null - mocks.$store.state.hasElopage = false - wrapper = Wrapper() - }) - - it('links to basic-de', () => { - expect(wrapper.vm.elopageUri).toBe( - 'https://elopage.com/s/gradido/basic-de/payment?locale=en&prid=111&pid=2896&firstName=User&lastName=Example&email=user@example.org', - ) - }) - }) - - describe('user has elopage', () => { - beforeEach(() => { - mocks.$store.state.publisherId = '123' - mocks.$store.state.hasElopage = true - wrapper = Wrapper() - }) - - it('links to sign in for elopage', () => { - expect(wrapper.vm.elopageUri).toBe('https://elopage.com/s/gradido/sign_in?locale=en') - }) - }) - }) - describe.skip('admin method', () => { const windowLocationMock = jest.fn() beforeEach(() => { diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index a5357e6d9..a29069104 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -153,6 +153,7 @@ "password_new_repeat": "Neues Passwort wiederholen", "password_old": "Altes Passwort", "recipient": "Empfänger", + "recipientCommunity": "Gemeinschaft des Empfängers", "reply": "Antworten", "reset": "Zurücksetzen", "save": "Speichern", @@ -166,12 +167,15 @@ "thx": "Danke", "to": "bis", "to1": "an", + "username": "Nutzername", + "username-placeholder": "Gebe einen eindeutigen Nutzernamen ein", "validation": { "gddCreationTime": "Das Feld {_field_} muss eine Zahl zwischen {min} und {max} mit höchstens einer Nachkommastelle sein", "gddSendAmount": "Das Feld {_field_} muss eine Zahl zwischen {min} und {max} mit höchstens zwei Nachkommastellen sein", "is-not": "Du kannst dir selbst keine Gradidos überweisen", - "usernmae-regex": "Der Username muss mit einem Buchstaben beginnen, auf den mindestens zwei alpha-numerische Zeichen folgen müssen.", - "usernmae-unique": "Der Username ist bereits vergeben." + "username-allowed-chars": "Der Nutzername darf nur aus Buchstaben (ohne Umlaute), Zahlen, Binde- oder Unterstrichen bestehen.", + "username-hyphens": "Binde- oder Unterstriche müssen zwischen Buchstaben oder Zahlen stehen.", + "username-unique": "Der Nutzername ist bereits vergeben." }, "your_amount": "Dein Betrag" }, @@ -319,7 +323,12 @@ "subtitle": "Wenn du dein Passwort vergessen hast, kannst du es hier zurücksetzen." }, "showAmountGDD": "Dein GDD Betrag ist sichtbar.", - "showAmountGDT": "Dein GDT Betrag ist sichtbar." + "showAmountGDT": "Dein GDT Betrag ist sichtbar.", + "username": { + "change-success": "Dein Nutzername wurde erfolgreich geändert.", + "change-username": "Nutzername ändern", + "no-username": "Bitte gebe einen Nutzernamen ein. Damit hilfst du anderen Benutzern dich zu finden, ohne deine Email preisgeben zu müssen." + } }, "signin": "Anmelden", "signup": "Registrieren", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 42f22f709..ad7077e69 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -153,6 +153,7 @@ "password_new_repeat": "Repeat new password", "password_old": "Old password", "recipient": "Recipient", + "recipientCommunity": "Community of the recipient", "reply": "Reply", "reset": "Reset", "save": "Save", @@ -166,12 +167,15 @@ "thx": "Thank you", "to": "to", "to1": "to", + "username": "Username", + "username-placeholder": "Enter a unique username", "validation": { "gddCreationTime": "The field {_field_} must be a number between {min} and {max} with at most one decimal place.", "gddSendAmount": "The {_field_} field must be a number between {min} and {max} with at most two digits after the decimal point", "is-not": "You cannot send Gradidos to yourself", - "usernmae-regex": "The username must start with a letter, followed by at least two alphanumeric characters.", - "usernmae-unique": "This username is already taken." + "username-allowed-chars": "The username may only contain letters, numbers, hyphens or underscores.", + "username-hyphens": "Hyphens or underscores must be in between letters or numbers.", + "username-unique": "This username is already taken." }, "your_amount": "Your amount" }, @@ -319,7 +323,12 @@ "subtitle": "If you have forgotten your password, you can reset it here." }, "showAmountGDD": "Your GDD amount is visible.", - "showAmountGDT": "Your GDT amount is visible." + "showAmountGDT": "Your GDT amount is visible.", + "username": { + "change-success": "Your username has been changed successfully.", + "change-username": "Change username", + "no-username": "Please enter a username. This helps other users to find you without exposing your email." + } }, "signin": "Sign in", "signup": "Sign up", diff --git a/frontend/src/main.js b/frontend/src/main.js index 4809e490c..f31311ab2 100755 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -27,7 +27,7 @@ const filters = loadFilters(i18n) Vue.filter('amount', filters.amount) Vue.filter('GDD', filters.GDD) -loadAllRules(i18n) +loadAllRules(i18n, apolloProvider.defaultClient) addNavigationGuards(router, store, apolloProvider.defaultClient) diff --git a/frontend/src/pages/Settings.vue b/frontend/src/pages/Settings.vue index 530484d9a..c5ca00f08 100644 --- a/frontend/src/pages/Settings.vue +++ b/frontend/src/pages/Settings.vue @@ -3,6 +3,8 @@
+ +

@@ -13,6 +15,7 @@