diff --git a/app/controllers/sac_cas/groups/self_registration_controller.rb b/app/controllers/sac_cas/groups/self_registration_controller.rb
index 39df3f85c..dc2ade7b3 100644
--- a/app/controllers/sac_cas/groups/self_registration_controller.rb
+++ b/app/controllers/sac_cas/groups/self_registration_controller.rb
@@ -18,7 +18,7 @@ module SacCas::Groups::SelfRegistrationController
 
   def restrict_access
     return redirect_to_login if !signed_in? && email_exists?
-    return redirect_to_memberships_tab if member_or_applied?
+    return redirect_to_memberships_tab if wizard.member_or_applied?
     redirect_to_person_show if family?
   end
 
@@ -26,11 +26,6 @@ def email_exists? = email.present? && Person.exists?(email: email)
 
   def family? = current_user&.household&.present?
 
-  def member_or_applied?
-    current_user&.sac_membership&.stammsektion_role ||
-      current_user&.sac_membership&.neuanmeldung_stammsektion_role
-  end
-
   def model_class
     case group
     when Group::AboBasicLogin
diff --git a/app/models/wizards/signup/abo_basic_login_wizard.rb b/app/models/wizards/signup/abo_basic_login_wizard.rb
index 9b19088c8..c23b2d042 100644
--- a/app/models/wizards/signup/abo_basic_login_wizard.rb
+++ b/app/models/wizards/signup/abo_basic_login_wizard.rb
@@ -14,13 +14,20 @@ class AboBasicLoginWizard < Wizards::RegisterNewUserWizard
 
     public :group
 
-    delegate :email, to: :main_email_field
     delegate :newsletter, to: :person_fields
 
     self.asides = ["aside_abo_basic_login"]
 
+    def member_or_applied?
+      current_user&.login? # do not allow if person already has a login
+    end
+
     def save!
-      super
+      if current_user
+        person.save!
+      else
+        super
+      end
 
       mailing_list&.subscribe_if(person, newsletter)
     end
@@ -34,9 +41,15 @@ def build_person
     end
 
     def person_attributes
-      person_fields
-        .person_attributes
-        .merge(main_email_field.attributes)
+      person_fields.person_attributes.merge(email:)
+    end
+
+    def step_after(step_class_or_name)
+      if step_class_or_name == :_start && current_user
+        Wizards::Steps::Signup::AboBasicLogin::PersonFields.step_name
+      else
+        super
+      end
     end
 
     def mailing_list = MailingList.find_by(id: Group.root.sac_newsletter_mailing_list_id)
diff --git a/app/models/wizards/signup/abo_magazin_wizard.rb b/app/models/wizards/signup/abo_magazin_wizard.rb
index 40624ea86..d1626c59f 100644
--- a/app/models/wizards/signup/abo_magazin_wizard.rb
+++ b/app/models/wizards/signup/abo_magazin_wizard.rb
@@ -15,8 +15,18 @@ class AboMagazinWizard < AboBasicLoginWizard
 
     self.asides = ["aside_abo"]
 
+    RESTRICTED_ROLES = [
+      Group::AboMagazin::Abonnent.sti_name,
+      Group::AboMagazin::Neuanmeldung.sti_name,
+      Group::AboMagazin::Gratisabonnent.sti_name
+    ].freeze
+
     delegate :newsletter, to: :summary
 
+    def member_or_applied?
+      current_user&.roles&.map(&:type)&.any? { |type| RESTRICTED_ROLES.include?(type) }
+    end
+
     def costs = SacCas::ABO_COSTS[:magazin]
 
     def requires_policy_acceptance? = false
diff --git a/app/models/wizards/signup/abo_touren_portal_wizard.rb b/app/models/wizards/signup/abo_touren_portal_wizard.rb
index f5ab7ca67..80302151f 100644
--- a/app/models/wizards/signup/abo_touren_portal_wizard.rb
+++ b/app/models/wizards/signup/abo_touren_portal_wizard.rb
@@ -14,6 +14,15 @@ class AboTourenPortalWizard < AboBasicLoginWizard
 
     self.asides = ["aside_abo"]
 
+    RESTRICTED_ROLES = [
+      Group::AboTourenPortal::Abonnent.sti_name,
+      Group::AboTourenPortal::Neuanmeldung.sti_name
+    ].freeze
+
+    def member_or_applied?
+      current_user&.roles&.map(&:type)&.any? { |type| RESTRICTED_ROLES.include?(type) }
+    end
+
     def costs = SacCas::ABO_COSTS[:tourenportal]
   end
 end
diff --git a/app/models/wizards/signup/sektion_wizard.rb b/app/models/wizards/signup/sektion_wizard.rb
index 2614d593d..acf772379 100644
--- a/app/models/wizards/signup/sektion_wizard.rb
+++ b/app/models/wizards/signup/sektion_wizard.rb
@@ -28,8 +28,9 @@ class SektionWizard < Wizards::RegisterNewUserWizard
 
     public :group
 
-    def email
-      current_user&.email || step(:main_email_field)&.email
+    def member_or_applied?
+      current_user&.sac_membership&.stammsektion_role ||
+        current_user&.sac_membership&.neuanmeldung_stammsektion_role
     end
 
     def save!
diff --git a/app/views/groups/self_registration/_aside_abo.html.haml b/app/views/groups/self_registration/_aside_abo.html.haml
index 6a4c4d639..ee3d912c2 100644
--- a/app/views/groups/self_registration/_aside_abo.html.haml
+++ b/app/views/groups/self_registration/_aside_abo.html.haml
@@ -4,4 +4,5 @@
 
 = turbo_frame_tag(partial_name, class: 'col-md') do
   = render "abo_infos", costs: wizard.costs
-  = render(SelfRegistration::InfosComponent.new)
+  - unless current_user
+    = render(SelfRegistration::InfosComponent.new)
diff --git a/app/views/wizards/steps/signup/abo_magazin/_person_info_table.html.haml b/app/views/wizards/steps/signup/abo_magazin/_person_info_table.html.haml
index e3e70d5d5..8547a0d8a 100644
--- a/app/views/wizards/steps/signup/abo_magazin/_person_info_table.html.haml
+++ b/app/views/wizards/steps/signup/abo_magazin/_person_info_table.html.haml
@@ -20,7 +20,7 @@
       %td=person.last_name
     %tr
       %td=t("activemodel.attributes.wizards/steps/signup/main_email_field.email")
-      %td=wizard.main_email_field.email
+      %td=wizard.email
     %tr
       %td=person.class.human_attribute_name(:birthday)
       %td=person.birthday.strftime("%d.%m.%Y")
diff --git a/lib/hitobito_sac_cas/wagon.rb b/lib/hitobito_sac_cas/wagon.rb
index cab3b5e96..c9e7cd843 100644
--- a/lib/hitobito_sac_cas/wagon.rb
+++ b/lib/hitobito_sac_cas/wagon.rb
@@ -71,7 +71,6 @@ class Wagon < Rails::Engine
       QualificationKind.include SacCas::QualificationKind
       Contactable.prepend SacCas::Contactable
       Wizards::Steps::NewUserForm.support_company = false
-      Wizards::RegisterNewUserWizard.delegate :email, to: :new_user_form
 
       HouseholdAsideComponent.prepend SacCas::HouseholdAsideComponent
       HouseholdAsideMemberComponent.prepend SacCas::HouseholdAsideMemberComponent
diff --git a/spec/features/signup/abo_basic_login_spec.rb b/spec/features/signup/abo_basic_login_spec.rb
index 6ef7441af..cb32335f0 100644
--- a/spec/features/signup/abo_basic_login_spec.rb
+++ b/spec/features/signup/abo_basic_login_spec.rb
@@ -102,4 +102,10 @@ def expect_validation_error(message)
       expect(page).to have_link("Anmelden")
     end
   end
+
+  it "redirects if logged in" do
+    sign_in(people(:admin))
+    visit group_self_registration_path(group_id: group)
+    expect(page).to have_content("Du besitzt bereits eine SAC-Mitgliedschaft. Wenn du diese anpassen möchtest, kontaktiere bitte die SAC-Geschäftsstelle.")
+  end
 end
diff --git a/spec/features/signup/abo_magazin_spec.rb b/spec/features/signup/abo_magazin_spec.rb
index e7b9c1eca..f72f3abba 100644
--- a/spec/features/signup/abo_magazin_spec.rb
+++ b/spec/features/signup/abo_magazin_spec.rb
@@ -155,4 +155,26 @@ def complete_last_page(date: Date.tomorrow, submit: true)
       expect(page).to have_field("Geburtsdatum", with: "03.01.1924")
     end
   end
+
+  it "has prefilled form when logged in" do
+    people(:admin).update!(country: "CH")
+    sign_in(people(:admin))
+    visit group_self_registration_path(group_id: group)
+    expect_active_step "Personendaten"
+    click_button "Weiter"
+    expect(page).to have_text "support@hitobito.example.com"
+    check "Ich habe die AGB gelesen und stimme diesen zu"
+    check "Ich habe die Datenschutzerklärung gelesen und stimme dieser zu"
+    expect do
+      click_button "ABO KOSTENPFLICHTIG BESTELLEN"
+      expect(page).to have_css "#error_explanation, #flash > .alert"
+    end.to change { Role.count }.by(1)
+  end
+
+  it "redirects if already abonnent of magazin" do
+    sign_in(people(:mitglied))
+    Group::AboMagazin::Abonnent.create!(person: people(:mitglied), group: group)
+    visit group_self_registration_path(group_id: group)
+    expect(page).to have_content("Du besitzt bereits eine SAC-Mitgliedschaft. Wenn du diese anpassen möchtest, kontaktiere bitte die SAC-Geschäftsstelle.")
+  end
 end
diff --git a/spec/features/signup/abo_touren_portal_spec.rb b/spec/features/signup/abo_touren_portal_spec.rb
index 65f5b86c0..1f7e3fda8 100644
--- a/spec/features/signup/abo_touren_portal_spec.rb
+++ b/spec/features/signup/abo_touren_portal_spec.rb
@@ -114,4 +114,25 @@ def expect_validation_error(message)
       expect(page).to have_text "Person muss 18 Jahre oder älter sein"
     end.not_to change { Person.count }
   end
+
+  it "has prefilled form when logged in" do
+    people(:admin).update!(country: "CH")
+    sign_in(people(:admin))
+    visit group_self_registration_path(group_id: group)
+    expect(page).to have_text "Registrieren"
+    expect(page).not_to have_text "Weiter"
+    check "Ich habe die Statuten gelesen und stimme diesen zu"
+    check "Ich habe die Datenschutzerklärung gelesen und stimme dieser zu"
+    expect do
+      click_button "Registrieren"
+      expect(page).to have_css "#error_explanation, #flash > .alert"
+    end.to change { Role.count }.by(1)
+  end
+
+  it "redirects if already abonnent of touren portal" do
+    sign_in(people(:mitglied))
+    Group::AboTourenPortal::Abonnent.create!(person: people(:mitglied), group: group)
+    visit group_self_registration_path(group_id: group)
+    expect(page).to have_content("Du besitzt bereits eine SAC-Mitgliedschaft. Wenn du diese anpassen möchtest, kontaktiere bitte die SAC-Geschäftsstelle.")
+  end
 end
diff --git a/spec/models/wizards/signup/abo_basic_login_wizard_spec.rb b/spec/models/wizards/signup/abo_basic_login_wizard_spec.rb
index 15b2cb800..dad51be30 100644
--- a/spec/models/wizards/signup/abo_basic_login_wizard_spec.rb
+++ b/spec/models/wizards/signup/abo_basic_login_wizard_spec.rb
@@ -104,5 +104,39 @@ def build(params = required_attrs)
       expect(max.subscriptions).to be_empty
       expect(newsletter.people).to be_empty
     end
+
+    it "saves role for current_user when logged in" do
+      allow_any_instance_of(Wizards::Signup::AboBasicLoginWizard).to receive(:current_user).and_return(people(:admin))
+      expect(wizard).to be_valid
+      expect { wizard.save! }.not_to change { Person.count }
+      expect(people(:admin).roles.last.type).to eq Group::AboBasicLogin::BasicLogin.sti_name
+    end
+  end
+
+  describe "steps" do
+    it "starts at main email field step when not logged in" do
+      expect(wizard.step_at(0)).to be_instance_of(Wizards::Steps::Signup::MainEmailField)
+      expect(wizard.step_at(1)).to be_instance_of(Wizards::Steps::Signup::AboBasicLogin::PersonFields)
+    end
+
+    it "starts at person fields step when logged in" do
+      allow_any_instance_of(Wizards::Signup::AboBasicLoginWizard).to receive(:current_user).and_return(people(:admin))
+      expect(wizard.step_at(0)).to be_instance_of(Wizards::Steps::Signup::AboBasicLogin::PersonFields)
+    end
+  end
+
+  describe "#member_or_applied?" do
+    before do
+      allow_any_instance_of(Wizards::Signup::AboBasicLoginWizard).to receive(:current_user).and_return(people(:mitglied))
+    end
+
+    it "returns true when user has login" do
+      expect(wizard.member_or_applied?).to be_truthy
+    end
+
+    it "returns true if user does not have login" do
+      allow(people(:mitglied)).to receive(:login?).and_return(false)
+      expect(wizard.member_or_applied?).to be_falsy
+    end
   end
 end
diff --git a/spec/models/wizards/signup/abo_magazin_wizard_spec.rb b/spec/models/wizards/signup/abo_magazin_wizard_spec.rb
index aa216ad28..70ffc6f85 100644
--- a/spec/models/wizards/signup/abo_magazin_wizard_spec.rb
+++ b/spec/models/wizards/signup/abo_magazin_wizard_spec.rb
@@ -129,6 +129,13 @@ def build(params = required_attrs)
           .with(kind_of(Person), group, true)
       end
     end
+
+    it "saves role for current_user when logged in" do
+      allow_any_instance_of(Wizards::Signup::AboBasicLoginWizard).to receive(:current_user).and_return(people(:admin))
+      expect(wizard).to be_valid
+      expect { wizard.save! }.not_to change { Person.count }
+      expect(people(:admin).roles.last.type).to eq Group::AboMagazin::Abonnent.sti_name
+    end
   end
 
   describe "#calculate_costs" do
@@ -141,4 +148,46 @@ def build(params = required_attrs)
       expect(wizard.calculated_costs).to eq(76)
     end
   end
+
+  describe "steps" do
+    it "starts at main email field step when not logged in" do
+      expect(wizard.step_at(0)).to be_instance_of(Wizards::Steps::Signup::MainEmailField)
+      expect(wizard.step_at(1)).to be_instance_of(Wizards::Steps::Signup::AboMagazin::PersonFields)
+      expect(wizard.step_at(2)).to be_instance_of(Wizards::Steps::Signup::AboMagazin::Summary)
+    end
+
+    it "starts at person fields step when logged in" do
+      allow_any_instance_of(Wizards::Signup::AboBasicLoginWizard).to receive(:current_user).and_return(people(:admin))
+      expect(wizard.step_at(0)).to be_instance_of(Wizards::Steps::Signup::AboMagazin::PersonFields)
+      expect(wizard.step_at(1)).to be_instance_of(Wizards::Steps::Signup::AboMagazin::Summary)
+    end
+  end
+
+  describe "#member_or_applied?" do
+    let(:person) { people(:mitglied) }
+    let(:group) { groups(:abo_die_alpen) }
+
+    before do
+      allow_any_instance_of(Wizards::Signup::AboBasicLoginWizard).to receive(:current_user).and_return(person)
+    end
+
+    it "returns true when user has abonnent role" do
+      Group::AboMagazin::Abonnent.create!(person:, group:)
+      expect(wizard.member_or_applied?).to be_truthy
+    end
+
+    it "returns true when user has neuanmeldung role" do
+      Group::AboMagazin::Neuanmeldung.create!(person:, group:)
+      expect(wizard.member_or_applied?).to be_truthy
+    end
+
+    it "returns true when user has gratis abonnent role" do
+      Group::AboMagazin::Gratisabonnent.create!(person:, group:)
+      expect(wizard.member_or_applied?).to be_truthy
+    end
+
+    it "returns false if user does not have role" do
+      expect(wizard.member_or_applied?).to be_falsy
+    end
+  end
 end
diff --git a/spec/models/wizards/signup/abo_touren_portal_wizard_spec.rb b/spec/models/wizards/signup/abo_touren_portal_wizard_spec.rb
index 2aad5a471..335f98393 100644
--- a/spec/models/wizards/signup/abo_touren_portal_wizard_spec.rb
+++ b/spec/models/wizards/signup/abo_touren_portal_wizard_spec.rb
@@ -114,5 +114,46 @@ def build(params = required_attrs)
       expect(max.subscriptions).to have(1).item
       expect(newsletter.people).to eq [max]
     end
+
+    it "saves role for current_user when logged in" do
+      allow_any_instance_of(Wizards::Signup::AboBasicLoginWizard).to receive(:current_user).and_return(people(:admin))
+      expect(wizard).to be_valid
+      expect { wizard.save! }.not_to change { Person.count }
+      expect(people(:admin).roles.last.type).to eq Group::AboTourenPortal::Abonnent.sti_name
+    end
+  end
+
+  describe "steps" do
+    it "starts at main email field step when not logged in" do
+      expect(wizard.step_at(0)).to be_instance_of(Wizards::Steps::Signup::MainEmailField)
+      expect(wizard.step_at(1)).to be_instance_of(Wizards::Steps::Signup::AboTourenPortal::PersonFields)
+    end
+
+    it "starts at person fields step when logged in" do
+      allow_any_instance_of(Wizards::Signup::AboBasicLoginWizard).to receive(:current_user).and_return(people(:admin))
+      expect(wizard.step_at(0)).to be_instance_of(Wizards::Steps::Signup::AboTourenPortal::PersonFields)
+    end
+  end
+
+  describe "#member_or_applied?" do
+    let(:person) { people(:mitglied) }
+
+    before do
+      allow_any_instance_of(Wizards::Signup::AboBasicLoginWizard).to receive(:current_user).and_return(person)
+    end
+
+    it "returns true when user has abonnent role" do
+      Group::AboTourenPortal::Abonnent.create!(person:, group:)
+      expect(wizard.member_or_applied?).to be_truthy
+    end
+
+    it "returns true when user has neuanmeldung role" do
+      Group::AboTourenPortal::Neuanmeldung.create!(person:, group:)
+      expect(wizard.member_or_applied?).to be_truthy
+    end
+
+    it "returns false if user does not have role" do
+      expect(wizard.member_or_applied?).to be_falsy
+    end
   end
 end