diff --git a/backend/.env.template b/backend/.env.template index 6697f09c4..5ecc5a5c4 100644 --- a/backend/.env.template +++ b/backend/.env.template @@ -17,3 +17,4 @@ PRIVATE_KEY_PASSPHRASE="a7dsf78sadg87ad87sfagsadg78" SENTRY_DSN_BACKEND= COMMIT= +PUBLIC_REGISTRATION=false diff --git a/backend/src/config/index.js b/backend/src/config/index.js index 3709b5cc3..00361ba63 100644 --- a/backend/src/config/index.js +++ b/backend/src/config/index.js @@ -21,7 +21,12 @@ const { GRAPHQL_URI = 'http://localhost:4000', } = process.env -export const requiredConfigs = { MAPBOX_TOKEN, JWT_SECRET, PRIVATE_KEY_PASSPHRASE } +export const requiredConfigs = { + MAPBOX_TOKEN, + JWT_SECRET, + PRIVATE_KEY_PASSPHRASE, +} + export const smtpConfigs = { SMTP_HOST, SMTP_PORT, @@ -30,7 +35,12 @@ export const smtpConfigs = { SMTP_PASSWORD, } export const neo4jConfigs = { NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD } -export const serverConfigs = { GRAPHQL_PORT, CLIENT_URI, GRAPHQL_URI } +export const serverConfigs = { + GRAPHQL_PORT, + CLIENT_URI, + GRAPHQL_URI, + PUBLIC_REGISTRATION: process.env.PUBLIC_REGISTRATION === 'true', +} export const developmentConfigs = { DEBUG: process.env.NODE_ENV !== 'production' && process.env.DEBUG, diff --git a/backend/src/middleware/email/templateBuilder.js b/backend/src/middleware/email/templateBuilder.js index 4b7bcc7cd..b4b7b78ca 100644 --- a/backend/src/middleware/email/templateBuilder.js +++ b/backend/src/middleware/email/templateBuilder.js @@ -18,7 +18,7 @@ export const signupTemplate = ({ email, nonce }) => { subject, html: mustache.render( templates.layout, - { actionUrl, supportUrl, subject }, + { actionUrl, nonce, supportUrl, subject }, { content: templates.signup }, ), } diff --git a/backend/src/middleware/email/templates/signup.html b/backend/src/middleware/email/templates/signup.html index 79894b584..ad60d9323 100644 --- a/backend/src/middleware/email/templates/signup.html +++ b/backend/src/middleware/email/templates/signup.html @@ -60,7 +60,9 @@
-

Falls Du Dich nicht selbst bei Sollte der Button für Dich nicht funktionieren, kannst Du auch folgenden Code in Dein Browserfenster kopieren: {{{ nonce }}}

+

Das funktioniert allerdings nur, wenn du Dich über unsere Website registriert hast.

+

Falls Du Dich nicht selbst bei Human Connection angemeldet hast, schau doch mal vorbei! Wir sind ein gemeinnütziges Aktionsnetzwerk – von Menschen für Menschen.

PS: Wenn Du keinen Account bei uns möchtest, kannst Du diese @@ -169,7 +171,9 @@
-

If you didn't sign up for If the above button doesn't work, you can also copy the following code into your browser window: {{{ nonce }}}

+

However, this only works if you have registered through our website.

+

If you didn't sign up for Human Connection we recommend you to check it out! It's a social network from people for people who want to connect and change the world together.

PS: If you ignore this e-mail we will not create an account diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.js index 8343443c9..df87f743e 100644 --- a/backend/src/middleware/permissionsMiddleware.js +++ b/backend/src/middleware/permissionsMiddleware.js @@ -111,6 +111,8 @@ const noEmailFilter = rule({ return !('email' in args) }) +const publicRegistration = rule()(() => !!CONFIG.PUBLIC_REGISTRATION) + // Permissions const permissions = shield( { @@ -137,7 +139,7 @@ const permissions = shield( '*': deny, login: allow, SignupByInvitation: allow, - Signup: isAdmin, + Signup: or(publicRegistration, isAdmin), SignupVerification: allow, CreateInvitationCode: and(isAuthenticated, or(not(invitationLimitReached), isAdmin)), UpdateUser: onlyYourself, diff --git a/docker-compose.override.yml b/docker-compose.override.yml index ba9b32c18..df7d6ac92 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -15,6 +15,7 @@ services: - ./webapp:/nitro-web environment: - NUXT_BUILD=/tmp/nuxt # avoid file permission issues when `rm -rf .nuxt/` + - PUBLIC_REGISTRATION=true command: yarn run dev backend: build: @@ -28,6 +29,7 @@ services: - SMTP_PORT=25 - SMTP_IGNORE_TLS=true - "DEBUG=${DEBUG}" + - PUBLIC_REGISTRATION=true maintenance: image: humanconnection/maintenance:latest build: diff --git a/webapp/.env.template b/webapp/.env.template index bebdeaaaf..fdabcf003 100644 --- a/webapp/.env.template +++ b/webapp/.env.template @@ -1,3 +1,4 @@ MAPBOX_TOKEN="pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ" SENTRY_DSN_WEBAPP= COMMIT= +PUBLIC_REGISTRATION=false diff --git a/webapp/components/PasswordReset/VerifyNonce.spec.js b/webapp/components/EnterNonce/EnterNonce.spec.js similarity index 67% rename from webapp/components/PasswordReset/VerifyNonce.spec.js rename to webapp/components/EnterNonce/EnterNonce.spec.js index ebe552f0d..67f1f9073 100644 --- a/webapp/components/PasswordReset/VerifyNonce.spec.js +++ b/webapp/components/EnterNonce/EnterNonce.spec.js @@ -1,12 +1,12 @@ import { mount, createLocalVue } from '@vue/test-utils' -import VerifyNonce from './VerifyNonce.vue' +import EnterNonce from './EnterNonce.vue' import Styleguide from '@human-connection/styleguide' const localVue = createLocalVue() localVue.use(Styleguide) -describe('VerifyNonce ', () => { +describe('EnterNonce ', () => { let wrapper let Wrapper let mocks @@ -25,28 +25,28 @@ describe('VerifyNonce ', () => { beforeEach(jest.useFakeTimers) Wrapper = () => { - return mount(VerifyNonce, { + return mount(EnterNonce, { mocks, localVue, propsData, }) } - it('renders a verify nonce form', () => { + it('renders an enter nonce form', () => { wrapper = Wrapper() - expect(wrapper.find('.verify-nonce').exists()).toBe(true) + expect(wrapper.find('form').exists()).toBe(true) }) - describe('after verification nonce given', () => { + describe('after nonce entered', () => { beforeEach(() => { wrapper = Wrapper() wrapper.find('input#nonce').setValue('123456') wrapper.find('form').trigger('submit') }) - it('emits `verification`', () => { + it('emits `nonceEntered`', () => { const expected = [[{ nonce: '123456', email: 'mail@example.org' }]] - expect(wrapper.emitted('verification')).toEqual(expected) + expect(wrapper.emitted('nonceEntered')).toEqual(expected) }) }) }) diff --git a/webapp/components/EnterNonce/EnterNonce.vue b/webapp/components/EnterNonce/EnterNonce.vue new file mode 100644 index 000000000..d936544ad --- /dev/null +++ b/webapp/components/EnterNonce/EnterNonce.vue @@ -0,0 +1,66 @@ + + + diff --git a/webapp/components/PasswordReset/ChangePassword.spec.js b/webapp/components/PasswordReset/ChangePassword.spec.js index e93d5d00d..b5d85dea7 100644 --- a/webapp/components/PasswordReset/ChangePassword.spec.js +++ b/webapp/components/PasswordReset/ChangePassword.spec.js @@ -39,7 +39,7 @@ describe('ChangePassword ', () => { }) } - describe('given email and verification nonce', () => { + describe('given email and nonce', () => { beforeEach(() => { propsData.email = 'mail@example.org' propsData.nonce = '123456' @@ -66,7 +66,7 @@ describe('ChangePassword ', () => { describe('password reset successful', () => { it('displays success message', () => { - const expected = 'verify-nonce.form.change-password.success' + const expected = 'components.password-reset.change-password.success' expect(mocks.$t).toHaveBeenCalledWith(expected) }) diff --git a/webapp/components/PasswordReset/ChangePassword.vue b/webapp/components/PasswordReset/ChangePassword.vue index 3de4f048a..e45612171 100644 --- a/webapp/components/PasswordReset/ChangePassword.vue +++ b/webapp/components/PasswordReset/ChangePassword.vue @@ -1,54 +1,62 @@ - diff --git a/webapp/components/PasswordReset/VerifyNonce.vue b/webapp/components/PasswordReset/VerifyNonce.vue deleted file mode 100644 index 94ae13564..000000000 --- a/webapp/components/PasswordReset/VerifyNonce.vue +++ /dev/null @@ -1,67 +0,0 @@ - - - diff --git a/webapp/components/Registration/CreateUserAccount.spec.js b/webapp/components/Registration/CreateUserAccount.spec.js index 6551211c0..67a14b3c5 100644 --- a/webapp/components/Registration/CreateUserAccount.spec.js +++ b/webapp/components/Registration/CreateUserAccount.spec.js @@ -8,6 +8,7 @@ const localVue = createLocalVue() localVue.use(Styleguide) config.stubs['sweetalert-icon'] = '' config.stubs['client-only'] = '' +config.stubs['nuxt-link'] = '' describe('CreateUserAccount', () => { let wrapper, Wrapper, mocks, propsData, stubs @@ -102,7 +103,9 @@ describe('CreateUserAccount', () => { it('displays success', async () => { await action() - expect(mocks.$t).toHaveBeenCalledWith('registration.create-user-account.success') + expect(mocks.$t).toHaveBeenCalledWith( + 'components.registration.create-user-account.success', + ) }) describe('after timeout', () => { @@ -130,7 +133,9 @@ describe('CreateUserAccount', () => { it('displays form errors', async () => { await action() - expect(wrapper.find('.backendErrors').text()).toContain('Invalid nonce') + expect(mocks.$t).toHaveBeenCalledWith( + 'components.registration.create-user-account.error', + ) }) }) }) diff --git a/webapp/components/Registration/CreateUserAccount.vue b/webapp/components/Registration/CreateUserAccount.vue index b5711873c..be01e0bb0 100644 --- a/webapp/components/Registration/CreateUserAccount.vue +++ b/webapp/components/Registration/CreateUserAccount.vue @@ -1,117 +1,111 @@ + diff --git a/webapp/pages/password-reset/change-password.vue b/webapp/pages/password-reset/change-password.vue index 7ab124782..3efdd001b 100644 --- a/webapp/pages/password-reset/change-password.vue +++ b/webapp/pages/password-reset/change-password.vue @@ -3,7 +3,11 @@ :email="email" :nonce="nonce" @passwordResetResponse="handlePasswordResetResponse" - /> + > + + {{ $t('site.back-to-login') }} + + diff --git a/webapp/pages/password-reset/request.vue b/webapp/pages/password-reset/request.vue index aa1b1ef05..29f8fde9d 100644 --- a/webapp/pages/password-reset/request.vue +++ b/webapp/pages/password-reset/request.vue @@ -1,5 +1,9 @@ diff --git a/webapp/pages/registration.vue b/webapp/pages/registration.vue index 7c7f03975..695570d26 100644 --- a/webapp/pages/registration.vue +++ b/webapp/pages/registration.vue @@ -1,9 +1,29 @@ diff --git a/webapp/pages/registration/signup.vue b/webapp/pages/registration/signup.vue new file mode 100644 index 000000000..721cb6268 --- /dev/null +++ b/webapp/pages/registration/signup.vue @@ -0,0 +1,34 @@ + + +