package email import ( "context" "fmt" "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/models" proLogic "github.com/gravitl/netmaker/pro/logic" "github.com/gravitl/netmaker/schema" "github.com/gravitl/netmaker/servercfg" ) // JITRequestMail - mail for notifying admins of JIT access requests type JITRequestMail struct { BodyBuilder EmailBodyBuilder Request *schema.JITRequest Network models.Network } // SendJITRequestEmails - sends email notifications to network admins about JIT requests func SendJITRequestEmails(request *schema.JITRequest, network models.Network) error { admins, err := proLogic.GetNetworkAdmins(request.NetworkID) if err != nil { return err } for _, admin := range admins { if admin.UserName == "" { continue } // Skip sending email if username is not a valid email address if !IsValid(admin.UserName) { logger.Log(2, "skipping JIT request email for admin with non-email username", "admin", admin.UserName) continue } // Create a fresh mail struct per admin to avoid BodyBuilder state accumulation // (EmailBodyBuilderWithH1HeadlineAndImage mutates internal state on each GetBody call) mail := JITRequestMail{ BodyBuilder: &EmailBodyBuilderWithH1HeadlineAndImage{}, Request: request, Network: network, } notification := Notification{ RecipientMail: admin.UserName, // Assuming username is email RecipientName: admin.UserName, } if err := GetClient().SendEmail(context.Background(), notification, mail); err != nil { logger.Log(0, "failed to send JIT request email", "admin", admin.UserName, "error", err.Error()) continue } } return nil } // GetSubject - gets the subject of the email func (mail JITRequestMail) GetSubject(info Notification) string { return fmt.Sprintf("JIT Access Request: %s requests access to %s", mail.Request.UserName, mail.Network.NetID) } // GetBody - gets the body of the email func (mail JITRequestMail) GetBody(info Notification) string { dashboardURL := fmt.Sprintf("https://dashboard.%s/networks/%s/jit-requests?jit_req_id=%s", servercfg.GetNmBaseDomain(), mail.Network.NetID, mail.Request.ID) if servercfg.DeployedByOperator() { dashboardURL = fmt.Sprintf("%s/dashboard?tenant_id=%s&network=%s&jit_req_id=%s", proLogic.GetAccountsUIHost(), servercfg.GetNetmakerTenantID(), mail.Network.NetID, mail.Request.ID) } reasonText := mail.Request.Reason if reasonText == "" { reasonText = "No reason provided" } content := mail.BodyBuilder. WithHeadline("New JIT Access Request"). WithParagraph(fmt.Sprintf("User %s has requested Just-In-Time access to network %s.", mail.Request.UserName, mail.Network.NetID)). WithParagraph("Request Details:"). WithHtml("