From 9930db748488aa8a47d31dad5d26819a1f8e7d31 Mon Sep 17 00:00:00 2001 From: Ian Littman Date: Tue, 10 Dec 2024 18:58:40 -0600 Subject: [PATCH] Include expiration info, drop "personalized", in MFA email (#24630) For #22078. # Checklist for submitter - [x] Manual QA for all new/changed functionality --- server/datastore/mysql/sessions.go | 5 +---- server/datastore/mysql/sessions_test.go | 2 +- server/fleet/service.go | 2 ++ server/mail/mfa.go | 13 ++++++++----- server/mail/templates/mfa.html | 4 ++-- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/server/datastore/mysql/sessions.go b/server/datastore/mysql/sessions.go index d402f10fb7df..1e4f27d4b4e2 100644 --- a/server/datastore/mysql/sessions.go +++ b/server/datastore/mysql/sessions.go @@ -4,15 +4,12 @@ import ( "context" "database/sql" "errors" - "time" - "github.com/fleetdm/fleet/v4/server" "github.com/fleetdm/fleet/v4/server/contexts/ctxerr" "github.com/fleetdm/fleet/v4/server/fleet" "github.com/jmoiron/sqlx" ) -const mfaLinkTTL = time.Minute * 15 const mfaTokenEntropyInBytes = 32 func (ds *Datastore) SessionByMFAToken(ctx context.Context, token string, sessionKeySize int) (*fleet.Session, *fleet.User, error) { @@ -23,7 +20,7 @@ func (ds *Datastore) SessionByMFAToken(ctx context.Context, token string, sessio &userID, "SELECT user_id FROM verification_tokens WHERE token = ? AND created_at >= NOW() - INTERVAL ? SECOND", token, - mfaLinkTTL.Seconds(), + fleet.MFALinkTTL.Seconds(), ) if err != nil { if errors.Is(err, sql.ErrNoRows) { diff --git a/server/datastore/mysql/sessions_test.go b/server/datastore/mysql/sessions_test.go index e714f92a2de5..db835b591978 100644 --- a/server/datastore/mysql/sessions_test.go +++ b/server/datastore/mysql/sessions_test.go @@ -70,7 +70,7 @@ func testMFA(t *testing.T, ds *Datastore) { _, err := q.ExecContext( context.Background(), "UPDATE verification_tokens SET created_at = NOW() - INTERVAL ? SECOND - INTERVAL 0.5 SECOND", - mfaLinkTTL.Seconds(), + fleet.MFALinkTTL.Seconds(), ) return err }) diff --git a/server/fleet/service.go b/server/fleet/service.go index d8f9db8e9881..52e877481f75 100644 --- a/server/fleet/service.go +++ b/server/fleet/service.go @@ -1190,4 +1190,6 @@ const ( BatchSetSoftwareInstallersStatusFailed = "failed" // MinOrbitLUKSVersion is the earliest version of Orbit that can escrow LUKS passphrases MinOrbitLUKSVersion = "1.36.0" + // MFALinkTTL is how long MFA verification links stay active + MFALinkTTL = time.Minute * 15 ) diff --git a/server/mail/mfa.go b/server/mail/mfa.go index 5d822ce80d0f..c2759e02a467 100644 --- a/server/mail/mfa.go +++ b/server/mail/mfa.go @@ -2,6 +2,7 @@ package mail import ( "bytes" + "github.com/fleetdm/fleet/v4/server/fleet" "html/template" "time" @@ -10,15 +11,17 @@ import ( // MFAMailer is used to build an email template for the MFA email. type MFAMailer struct { - FullName string - Token string - BaseURL template.URL - AssetURL template.URL - CurrentYear int + FullName string + Token string + BaseURL template.URL + AssetURL template.URL + CurrentYear int + TTLInMinutes float64 // due to rounding below, will always be a whole number } func (i *MFAMailer) Message() ([]byte, error) { i.CurrentYear = time.Now().Year() + i.TTLInMinutes = fleet.MFALinkTTL.Truncate(time.Minute).Minutes() // better to show a whole, rounded-down number t, err := server.GetTemplate("server/mail/templates/mfa.html", "email_template") if err != nil { return nil, err diff --git a/server/mail/templates/mfa.html b/server/mail/templates/mfa.html index 7a508ea1a4ae..a0441d856c51 100644 --- a/server/mail/templates/mfa.html +++ b/server/mail/templates/mfa.html @@ -110,8 +110,8 @@

Log in to Fleet

Hello {{.FullName}},

- Please click the personalized link below to log into your - account. + Please click the link below to log into your account. This link will stay + active for {{.TTLInMinutes}} minutes.