diff --git a/app/models/user.rb b/app/models/user.rb index f475e72..bb0ed0a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -2,7 +2,7 @@ class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, - :recoverable, :rememberable, :validatable + :recoverable, :rememberable, :validatable, :confirmable has_many :entries, dependent: :destroy diff --git a/app/views/devise/confirmations/new.html.erb b/app/views/devise/confirmations/new.html.erb new file mode 100644 index 0000000..15f85bd --- /dev/null +++ b/app/views/devise/confirmations/new.html.erb @@ -0,0 +1,20 @@ +
+

Bestätigungs‑Link erneut senden

+ + <%= form_with(scope: resource_name, url: password_path(resource_name), local: true) do |f| %> + + +
+ <%= f.label :email, 'E‑Mail Adresse', class: 'form-label' %> + <%= f.email_field :email, autofocus: true, class: 'form-control', placeholder: 'Ihre E‑Mail' %> +
+ +
+ <%= f.submit 'Link senden', class: 'btn btn-primary w-100' %> +
+ <% end %> + +
+ <%= link_to 'Zurück zur Anmeldung', new_session_path(resource_name), class: 'btn btn-link' %> +
+
diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb new file mode 100644 index 0000000..14bd32f --- /dev/null +++ b/app/views/devise/passwords/edit.html.erb @@ -0,0 +1,32 @@ +
+

🔐 Passwort zurücksetzen

+ + <%= devise_error_messages! %> + + <%= form_with(scope: resource_name, url: password_path(resource_name), method: :put, local: true) do |f| %> + <%= f.hidden_field :reset_password_token, value: params[:reset_password_token] %> + +
+ <%= f.label :email, 'E‑Mail Adresse', class: 'form-label' %> + <%= f.email_field :email, autofocus: true, class: 'form-control', placeholder: 'Ihre E‑Mail' %> +
+ +
+ <%= f.label :password, 'Neues Passwort', class: 'form-label' %> + <%= f.password_field :password, autocomplete: "new-password", class: 'form-control' %> +
+ +
+ <%= f.label :password_confirmation, 'Passwort bestätigen', class: 'form-label' %> + <%= f.password_field :password_confirmation, autocomplete: "new-password", class: 'form-control' %> +
+ +
+ <%= f.submit 'Passwort aktualisieren', class: 'btn btn-primary w-100' %> +
+ <% end %> + +
+ <%= link_to 'Zurück zur Anmeldung', new_session_path(resource_name), class: 'btn btn-link' %> +
+
diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb new file mode 100644 index 0000000..c85c7a8 --- /dev/null +++ b/app/views/devise/passwords/new.html.erb @@ -0,0 +1,20 @@ +
+

Passwort vergessen?

+ + <%= form_with(scope: resource_name, url: password_path(resource_name), local: true) do |f| %> + + +
+ <%= f.label :email, 'E‑Mail Adresse', class: 'form-label' %> + <%= f.email_field :email, autofocus: true, class: 'form-control', placeholder: 'Ihre E‑Mail' %> +
+ +
+ <%= f.submit 'Zugangsdaten senden', class: 'btn btn-primary w-100' %> +
+ <% end %> + +
+ <%= link_to 'Zurück zur Anmeldung', new_session_path(resource_name), class: 'btn btn-link' %> +
+
diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb index 8ece3e0..76dc956 100644 --- a/app/views/devise/registrations/edit.html.erb +++ b/app/views/devise/registrations/edit.html.erb @@ -1,5 +1,7 @@

Profil bearbeiten

+ <%= devise_error_messages! %> + <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= f.label :email, "E-Mail", class: "form-label" %> diff --git a/app/views/entries/index.html.erb b/app/views/entries/index.html.erb index 7877cbb..0ea95b3 100644 --- a/app/views/entries/index.html.erb +++ b/app/views/entries/index.html.erb @@ -1,5 +1,7 @@
+ +

Meine Einträge

diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index ab26abf..90a58e3 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -1,53 +1,63 @@ + + - - Praktikumsuhr + - - + <%= csrf_meta_tags %> + <%= csp_meta_tag %> - + - - <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> - - - - - - - - - - <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %> - - - -<% if notice %>
<%= notice %>
<% end %> -<% if alert %>
<%= alert %>
<% end %> - -<% if user_signed_in? %> -

- Eingeloggt als <%= current_user.email %> | - <%= link_to "Profil", edit_user_registration_path %> | - <%= link_to "Admin", admin_root_path %> | - <%= link_to "Logout", destroy_user_session_path, method: :delete, data: { turbo: false } %> -

-<% end %> - -<%= yield %> + + + +
+ <% if notice %> +
<%= notice %>
+ <% end %> + <% if alert %> +
<%= alert %>
+ <% end %> + + <%= yield %> +
+ diff --git a/config/application.rb b/config/application.rb index 271e0f5..4dd23e9 100644 --- a/config/application.rb +++ b/config/application.rb @@ -35,7 +35,7 @@ module Praktikum # # config.time_zone = "Central Time (US & Canada)" # config.eager_load_paths << Rails.root.join("extras") - + # Don't generate system test files. config.generators.system_tests = nil end diff --git a/config/environments/development.rb b/config/environments/development.rb index 2e7fb48..031b231 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -37,9 +37,24 @@ Rails.application.configure do config.active_storage.service = :local # Don't care if the mailer can't send. - config.action_mailer.raise_delivery_errors = false - config.action_mailer.perform_caching = false + + config.action_mailer.default_url_options = { :host => "localhost:3000", :protocol => 'http', from: 'praktikum@marzell.net' } + + config.action_mailer.delivery_method = :smtp + # SMTP settings for gmail + + config.action_mailer.perform_deliveries = true + config.action_mailer.smtp_settings = { + :address => 'smtp.ionos.de', + :port => 587, + domain: "marzell.net", + :user_name => 'praktikum@marzell.net', + :password => 'CSSABXGRhSzUFK9', + authentication: 'plain', + enable_starttls_auto: true + + } # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log diff --git a/config/environments/production.rb b/config/environments/production.rb index 1204906..85de75a 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -95,19 +95,21 @@ Rails.application.configure do # Skip DNS rebinding protection for the default health check endpoint. # config.host_authorization = { exclude: ->(request) { request.path == "/up" } } - config.action_mailer.default_url_options = { - host: "praktikum.marzell.net", - protocol: "https" - } + config.action_mailer.perform_caching = false + + config.action_mailer.default_url_options = { :host => "praktikum.marzell.net", :protocol => 'https', from: 'praktikum@marzell.net' } config.action_mailer.delivery_method = :smtp - config.action_mailer.smtp_settings = { - address: "smtp.mailgun.org", - port: 587, - domain: "mg.marzell.net", - user_name: "postmaster@mg.marzell.net", # ⬅️ das bekommst du bei Mailgun - password: ENV["MAILGUN_SMTP_PASSWORD"], # ⬅️ sicher via ENV setzen - authentication: "plain", + # SMTP settings for gmail + + config.action_mailer.perform_deliveries = true + config.action_mailer.smtp_settings = { + :address => 'smtp.ionos.de', + :port => 587, + :user_name => 'praktikum@marzell.net', + :password => 'CSSABXGRhSzUFK9', + domain: "marzell.net", + authentication: 'plain', enable_starttls_auto: true } diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 7ede34c..1e88826 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -24,7 +24,7 @@ Devise.setup do |config| # Configure the e-mail address which will be shown in Devise::Mailer, # note that it will be overwritten if you use your own mailer class # with default "from" parameter. - config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com' + config.mailer_sender = 'praktikum@marzell.net' # Configure the class responsible to send e-mails. # config.mailer = 'Devise::Mailer' diff --git a/db/migrate/20251108073226_add_confirmable_to_users.rb b/db/migrate/20251108073226_add_confirmable_to_users.rb new file mode 100644 index 0000000..0353a3c --- /dev/null +++ b/db/migrate/20251108073226_add_confirmable_to_users.rb @@ -0,0 +1,9 @@ +class AddConfirmableToUsers < ActiveRecord::Migration[7.1] + def change + add_column :users, :confirmation_token, :string + add_index :users, :confirmation_token + add_column :users, :confirmed_at, :datetime + add_column :users, :confirmation_sent_at, :datetime + add_column :users, :unconfirmed_email, :string + end +end diff --git a/db/migrate/20251108073233_confirm_all_existing_users.rb b/db/migrate/20251108073233_confirm_all_existing_users.rb new file mode 100644 index 0000000..e422126 --- /dev/null +++ b/db/migrate/20251108073233_confirm_all_existing_users.rb @@ -0,0 +1,9 @@ +class ConfirmAllExistingUsers < ActiveRecord::Migration[7.1] + def up + User.update_all(confirmed_at: Time.current) + end + + def down + User.update_all(confirmed_at: nil) + end +end diff --git a/db/schema.rb b/db/schema.rb index 16d6e49..803f749 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2025_11_07_054255) do +ActiveRecord::Schema[7.1].define(version: 2025_11_08_073233) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -39,6 +39,11 @@ ActiveRecord::Schema[7.1].define(version: 2025_11_07_054255) do t.integer "weekly_target_hours", default: 12, null: false t.jsonb "required_hours_matrix", default: {}, null: false t.jsonb "weekly_target_matrix", default: {}, null: false + t.string "confirmation_token" + t.datetime "confirmed_at" + t.datetime "confirmation_sent_at" + t.string "unconfirmed_email" + t.index ["confirmation_token"], name: "index_users_on_confirmation_token" t.index ["email"], name: "index_users_on_email", unique: true t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true end