Finalize join request feature #472

Merged
simon merged 18 commits from feature/308-web-form into main 2026-03-13 20:51:11 +01:00
Owner

Description of the implemented changes

The changes were:

  • Bugfixing
  • New Feature
  • Breaking Change
  • Refactoring

Goal: Extend the join (web form) flow with configurable registration, duplicate-email handling, reviewer display, and email-failure behaviour; improve unauthenticated UX (theme/locale, translations); refactor global settings and SMTP layout.


What has been changed?

  • Registration toggle

    • New setting registration_enabled (DB: migration, Setting attribute). When false, GET /register is redirected to /sign-in with a flash message; the “Register” link on the sign-in page is hidden.
    • MvWeb.Plugs.RegistrationEnabled: redirects /register when disabled and puts registration_enabled in session for sign-in/register.
    • Mv.Accounts.User.Validations.RegistrationEnabled: blocks direct registration (e.g. register_with_password) when registration is disabled.
    • Router: plug applied to auth routes; global settings UI: new checkbox and toggle_registration_enabled handler.
  • Join flow: duplicate email handling

    • Submissions with an email that is already a member or already has a submitted join request are detected; no second JoinRequest is created.
    • JoinAlreadyMemberEmail and JoinAlreadyPendingEmail send notices; UI still shows the same success message (anti-enumeration).
  • Join flow: email delivery failure

    • Domain returns {:error, :email_delivery_failed} when confirmation email delivery fails; JoinLive shows an error and no success message; behaviour covered by domain and LiveView tests using FailingMailAdapter.
  • Join requests: reviewer display

    • New column reviewed_by_display on join_requests, backfilled from users.email; approval UI can show “Geprüft von” without loading User.
  • Global settings

    • SMTP section reordered; authentication subsection added (registration toggle); global_settings_live.ex refactored (structure and assign handling).
  • Unauthenticated pages

    • Theme/locale selector on sign-in and join; layout/sidebar and AuthOverrides updated so unauthenticated pages use a consistent header (e.g. logo) and locale/theme controls.
    • Login page translation fix (locale/Gettext).
  • Docs and config

    • CODE_GUIDELINES.md, DESIGN_GUIDELINES.md, docs/feature-roadmap.md, docs/onboarding-join-concept.md, docs/smtp-configuration-concept.md, docs/development-progress-log.md updated; new docs/settings-authentication-mockup.txt.
    • Seeds and Justfile adjusted where needed.
  • Tests

    • test/mv_web/live/join_live_email_failure_test.exs: Join form shows error when confirmation email fails.
    • test/membership/join_request_submit_email_failure_test.exs: submit_join_request returns {:error, :email_delivery_failed} when mail fails.
    • test/mv_web/controllers/auth_controller_test.exs: GET /sign-in as unauthenticated; registration-disabled redirect from /register (with on_exit restore of registration_enabled).
    • test/support/failing_mail_adapter.ex: test mail adapter for failure scenarios.
    • Join request and approval-related tests extended/updated as needed.

Definition of Done

Code Quality

  • No new technical depths
  • Linting passed
  • Documentation is added where needed

Accessibility

  • New elements are properly defined with html-tags
  • Colour contrast follows WCAG criteria
  • Aria labels are added when needed
  • Everything is accessible by keyboard
  • Tab-Order is comprehensible
  • All interactive elements have a visible focus

Testing

  • Tests for new code are written
  • All tests pass
  • axe-core dev tools show no critical or major issues

Additional Notes

  • Review focus

    • MvWeb.Plugs.RegistrationEnabled: only GET /register is redirected; session key registration_enabled is used on sign-in/register.
    • User validation RegistrationEnabled runs in the registration path; when registration is disabled, both the plug (UI) and the validation (API/direct calls) enforce it.
    • Email failure: domain and LiveView tests use async: false and swap the Mailer adapter to avoid config races; on_exit restores the previous config.
    • Migrations: reviewed_by_display is backfilled from users.email; registration_enabled defaults to true for existing settings.
  • Related

    • Issue #308 (web form / join); concept in docs/onboarding-join-concept.md. SMTP behaviour and join confirmation mail are documented in docs/smtp-configuration-concept.md.
  • Suggested checks before merge

    • Run full test suite (including join_live_email_failure_test.exs and join_request_submit_email_failure_test.exs).
    • Manually: enable/disable “Registration” in global settings, then open /register and sign-in and confirm redirect/link visibility; submit join with duplicate email and with failing mail (if easily reproducible).
## Description of the implemented changes The changes were: - [ ] Bugfixing - [x] New Feature - [ ] Breaking Change - [x] Refactoring **Goal:** Extend the join (web form) flow with configurable registration, duplicate-email handling, reviewer display, and email-failure behaviour; improve unauthenticated UX (theme/locale, translations); refactor global settings and SMTP layout. --- ## What has been changed? - **Registration toggle** - New setting `registration_enabled` (DB: migration, `Setting` attribute). When `false`, GET `/register` is redirected to `/sign-in` with a flash message; the “Register” link on the sign-in page is hidden. - `MvWeb.Plugs.RegistrationEnabled`: redirects `/register` when disabled and puts `registration_enabled` in session for sign-in/register. - `Mv.Accounts.User.Validations.RegistrationEnabled`: blocks direct registration (e.g. `register_with_password`) when registration is disabled. - Router: plug applied to auth routes; global settings UI: new checkbox and `toggle_registration_enabled` handler. - **Join flow: duplicate email handling** - Submissions with an email that is already a member or already has a submitted join request are detected; no second JoinRequest is created. - `JoinAlreadyMemberEmail` and `JoinAlreadyPendingEmail` send notices; UI still shows the same success message (anti-enumeration). - **Join flow: email delivery failure** - Domain returns `{:error, :email_delivery_failed}` when confirmation email delivery fails; JoinLive shows an error and no success message; behaviour covered by domain and LiveView tests using `FailingMailAdapter`. - **Join requests: reviewer display** - New column `reviewed_by_display` on `join_requests`, backfilled from `users.email`; approval UI can show “Geprüft von” without loading User. - **Global settings** - SMTP section reordered; authentication subsection added (registration toggle); `global_settings_live.ex` refactored (structure and assign handling). - **Unauthenticated pages** - Theme/locale selector on sign-in and join; layout/sidebar and `AuthOverrides` updated so unauthenticated pages use a consistent header (e.g. logo) and locale/theme controls. - Login page translation fix (locale/Gettext). - **Docs and config** - `CODE_GUIDELINES.md`, `DESIGN_GUIDELINES.md`, `docs/feature-roadmap.md`, `docs/onboarding-join-concept.md`, `docs/smtp-configuration-concept.md`, `docs/development-progress-log.md` updated; new `docs/settings-authentication-mockup.txt`. - Seeds and Justfile adjusted where needed. - **Tests** - `test/mv_web/live/join_live_email_failure_test.exs`: Join form shows error when confirmation email fails. - `test/membership/join_request_submit_email_failure_test.exs`: `submit_join_request` returns `{:error, :email_delivery_failed}` when mail fails. - `test/mv_web/controllers/auth_controller_test.exs`: GET `/sign-in` as unauthenticated; registration-disabled redirect from `/register` (with `on_exit` restore of `registration_enabled`). - `test/support/failing_mail_adapter.ex`: test mail adapter for failure scenarios. - Join request and approval-related tests extended/updated as needed. --- ## Definition of Done ### Code Quality - [ ] No new technical depths - [ ] Linting passed - [ ] Documentation is added where needed ### Accessibility - [ ] New elements are properly defined with html-tags - [ ] Colour contrast follows WCAG criteria - [ ] Aria labels are added when needed - [ ] Everything is accessible by keyboard - [ ] Tab-Order is comprehensible - [ ] All interactive elements have a visible focus ### Testing - [ ] Tests for new code are written - [ ] All tests pass - [ ] axe-core dev tools show no critical or major issues --- ## Additional Notes - **Review focus** - `MvWeb.Plugs.RegistrationEnabled`: only GET `/register` is redirected; session key `registration_enabled` is used on sign-in/register. - User validation `RegistrationEnabled` runs in the registration path; when registration is disabled, both the plug (UI) and the validation (API/direct calls) enforce it. - Email failure: domain and LiveView tests use `async: false` and swap the Mailer adapter to avoid config races; `on_exit` restores the previous config. - Migrations: `reviewed_by_display` is backfilled from `users.email`; `registration_enabled` defaults to `true` for existing settings. - **Related** - Issue #308 (web form / join); concept in `docs/onboarding-join-concept.md`. SMTP behaviour and join confirmation mail are documented in `docs/smtp-configuration-concept.md`. - **Suggested checks before merge** - Run full test suite (including `join_live_email_failure_test.exs` and `join_request_submit_email_failure_test.exs`). - Manually: enable/disable “Registration” in global settings, then open `/register` and sign-in and confirm redirect/link visibility; submit join with duplicate email and with failing mail (if easily reproducible).
simon added 7 commits 2026-03-13 16:45:02 +01:00
feat: improve field order for approvals and add seeds
Some checks failed
continuous-integration/drone/push Build is failing
a7481f6ab1
fix: join confirmation mail configuration
Some checks failed
continuous-integration/drone/push Build is failing
40a4461d23
feat: prevent join requests with equal mail
All checks were successful
continuous-integration/drone/push Build is passing
086ecdcb1b
fix: translation of login page
All checks were successful
continuous-integration/drone/push Build is passing
99a8d64344
feat: add theme selector to unauthenticated pages
Some checks failed
continuous-integration/drone/push Build is failing
104faf7006
feat: rearrange smtp settings
All checks were successful
continuous-integration/drone/push Build is passing
eb18209669
feat: allow disabling registration
Some checks failed
continuous-integration/drone/push Build is failing
09e4b64663
simon added 1 commit 2026-03-13 16:45:49 +01:00
Merge remote-tracking branch 'origin/main' into feature/308-web-form
Some checks failed
continuous-integration/drone/push Build is failing
9a3cf74871
simon added 1 commit 2026-03-13 16:47:29 +01:00
i18n: update gettext
Some checks failed
continuous-integration/drone/push Build is failing
5e39fffce2
simon added 1 commit 2026-03-13 16:54:10 +01:00
docs: update changelog
Some checks failed
continuous-integration/drone/push Build is failing
d54393d80b
simon added 1 commit 2026-03-13 17:07:33 +01:00
test: fix tests
All checks were successful
continuous-integration/drone/push Build is passing
f12da8a359
simon added 1 commit 2026-03-13 17:55:31 +01:00
refactor: review remarks
Some checks failed
continuous-integration/drone/push Build is failing
349cee0ce6
simon added 1 commit 2026-03-13 18:22:25 +01:00
feat: add timezone handling
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is failing
e8ec620d57
simon added 1 commit 2026-03-13 19:02:08 +01:00
feat: unify page titles
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is failing
c933144920
simon added 1 commit 2026-03-13 19:25:30 +01:00
fix: failing tests
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is failing
a4239ce09b
simon added 1 commit 2026-03-13 19:44:02 +01:00
fix: failing tests
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is failing
86c032004e
simon added 1 commit 2026-03-13 20:00:11 +01:00
fix: failing tests
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is failing
171a699326
simon added 1 commit 2026-03-13 20:36:27 +01:00
fix: failing tests
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is passing
1866c79461
simon merged commit 837f5fd5bf into main 2026-03-13 20:51:11 +01:00
Sign in to join this conversation.
No description provided.