diff --git a/cms/core/src/systems/bread/alpha/cms/main.cljc b/cms/core/src/systems/bread/alpha/cms/main.cljc index bfb205b4..b13b9c3c 100644 --- a/cms/core/src/systems/bread/alpha/cms/main.cljc +++ b/cms/core/src/systems/bread/alpha/cms/main.cljc @@ -118,7 +118,8 @@ ["/confirm-email" {:name :confirm-email :dispatcher/type ::email/confirm=> - :dispatcher/component #'rise/ConfirmPage}] + :dispatcher/component #'rise/ConfirmPage + :dispatcher/not-found-component #'rise/ConfirmPage}] ["/patterns" ["/rise" {:name :patterns.rise @@ -364,7 +365,7 @@ {:session-store (auth/session-store config conn) :connection conn}))) -(defmethod ig/resolve-key :ring/session-store [_ {:as x :keys [session-store]}] +(defmethod ig/resolve-key :ring/session-store [_ {:keys [session-store]}] session-store) (defmethod ig/halt-key! :ring/session-store [_ {:keys [connection]}] diff --git a/cms/themes/rise/src/systems/bread/alpha/cms/theme/rise.cljc b/cms/themes/rise/src/systems/bread/alpha/cms/theme/rise.cljc index 4277e06f..d0d00f24 100644 --- a/cms/themes/rise/src/systems/bread/alpha/cms/theme/rise.cljc +++ b/cms/themes/rise/src/systems/bread/alpha/cms/theme/rise.cljc @@ -795,12 +795,15 @@ :content [:main.gap-large [:h2 (:email/please-confirm i18n)] - [:p address] - [:form {:method :post :action uri} - [:input {:type :hidden :name :email :value address}] - [:input {:type :hidden :name :code :value code}] - [:button {:type :submit} - (:email/confirm-email i18n)]]]})) + (if (empty? address) + [:.error (:email/invalid-reset-link i18n)] + [:<> + [:p address] + [:form {:method :post :action uri} + [:input {:type :hidden :name :email :value address}] + [:input {:type :hidden :name :code :value code}] + [:button {:type :submit} + (:email/confirm-email i18n)]]])]})) (defc SignupPage [{:as data diff --git a/plugins/auth/systems/bread/alpha/plugin/auth.cljc b/plugins/auth/systems/bread/alpha/plugin/auth.cljc index bd0cd190..42dffd8c 100644 --- a/plugins/auth/systems/bread/alpha/plugin/auth.cljc +++ b/plugins/auth/systems/bread/alpha/plugin/auth.cljc @@ -181,7 +181,7 @@ (assoc result :user user))))) (defmethod bread/expand ::authenticate-two-factor - [{:keys [generous? lock-seconds two-factor-code]} {user :auth/result}] + [{:keys [lock-seconds two-factor-code]} {user :auth/result}] (let [;; Don't store password data in session user (dissoc user :user/password) locked? (and (:user/locked-at user) @@ -197,6 +197,7 @@ {:valid valid :user user})))) (defmethod bread/action ::logout [res _ _] + ;; TODO delete session (let [login-uri (bread/config res :auth/login-uri)] (-> res (assoc :session nil :status 302 :body login-uri) @@ -311,8 +312,7 @@ {:expansion/name ::authenticate-two-factor :expansion/key :auth/result :two-factor-code (:two-factor-code params) - :lock-seconds lock-seconds - :generous? (bread/config req :auth/generous-totp-window?)}] + :lock-seconds lock-seconds}] :effects [{:effect/name ::log-attempt :effect/description @@ -698,7 +698,6 @@ ([] (plugin {})) ([{:keys [forgot-password-uri - generous-totp-window? hash-algorithm lock-seconds login-uri @@ -724,7 +723,6 @@ forgot-password-uri "/forgot" reset-password-uri "/reset" reset-expiration-seconds (* 10 60) - generous-totp-window? true ;; Don't track Personally Identfiable Information (PII) by default. store-session-ip? false store-session-user-agent? false}}] @@ -758,7 +756,6 @@ #:auth{:secret-key secret-key :require-mfa? require-mfa? :mfa-issuer mfa-issuer - :generous-totp-window? generous-totp-window? :hash-algorithm hash-algorithm :max-failed-login-count max-failed-login-count :min-password-length min-password-length diff --git a/plugins/email/email.i18n.edn b/plugins/email/email.i18n.edn index f250d62d..280bf9df 100644 --- a/plugins/email/email.i18n.edn +++ b/plugins/email/email.i18n.edn @@ -20,9 +20,10 @@ :email-in-use "That email is already in use." :email-settings "Email settings" :invalid-email "Invalid email" + :invalid-reset-link "This email is invalid or has already been confirmed." :no-emails "No emails yet." :make-primary "Make primary" - :please-confirm "Please confirm your email:" + :please-confirm "Please confirm your email" :primary "Primary email" :resend-confirmation "Resend confirmation" :to-add-email-confirm-pending "To add another email, first confirm any pending email addresses." diff --git a/plugins/email/systems/bread/alpha/plugin/email.cljc b/plugins/email/systems/bread/alpha/plugin/email.cljc index 71fe2701..88bd0d88 100644 --- a/plugins/email/systems/bread/alpha/plugin/email.cljc +++ b/plugins/email/systems/bread/alpha/plugin/email.cljc @@ -8,6 +8,7 @@ [systems.bread.alpha.core :as bread] [systems.bread.alpha.database :as db] [systems.bread.alpha.i18n :as i18n] + [systems.bread.alpha.internal.interop :refer [sha-512]] [systems.bread.alpha.internal.time :as t] [systems.bread.alpha.ring :as ring]) (:import @@ -88,7 +89,7 @@ :body body})})) (defmethod bread/effect [::update :resend-confirmation] resend-confirmation - [{:keys [conn params]} {:as data :keys [config user]}] + [{:keys [params]} {:as data :keys [config user]}] (let [emails (:user/emails user) ;; Check that the email belongs to the user and that it's still ;; actually pending confirmation. @@ -99,16 +100,16 @@ first) effect (confirmation-effect {:from (:email/smtp-from-email config) :to (:email/address email) + ;; TODO hash code :code (:email/code email)} data)] (when email {:effects [effect] :flash {:success-key :email/confirmation-resent}}))) -(defmethod bread/effect [::update :delete] +(defmethod bread/effect [::update :delete] delete-email [{:keys [conn params]} {:keys [user]}] - (let [emails (:user/emails user) - id (Integer. (:id params))] + (let [id (Integer. (:id params))] (ensure-own-email-id user id) (try (db/transact conn [[:db/retractEntity id]]) @@ -133,6 +134,7 @@ (log/info "adding email" {:email email :user-id user-id}) (db/transact conn [{:db/id (:db/id user) :user/emails [{:email/address email + ;; TODO hash code :email/code code :thing/updated-at now :thing/created-at now}]}]) @@ -235,6 +237,7 @@ (defmethod bread/dispatch ::confirm=> [{:as req :keys [request-method] {:keys [code email]} :params}] (let [post? (= :post request-method) + hashed (sha-512 (str (bread/config req :auth/secret-key) ":" code)) expansions [{:expansion/name ::db/query :expansion/key :pending-email @@ -250,7 +253,7 @@ [?e :email/address ?email] ;; Only query for unconfirmed emails. (not-join [?e] [?e :email/confirmed-at])]} - code email]} + hashed email]} {:expansion/name ::validate-recency :expansion/key :pending-email :expansion/description "Validate the confirmation link's age."