diff --git a/internal/auth/auth.go b/internal/auth/auth.go index 112959da5..5edfec358 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -33,6 +33,7 @@ var requiredScopes = []string{ "create:rules", "delete:rules", "read:rules", "update:rules", "create:users", "delete:users", "read:users", "update:users", "read:branding", "update:branding", + "read:email_templates", "update:email_templates", "read:connections", "update:connections", "read:client_keys", "read:logs", "read:tenant_settings", "read:custom_domains", "create:custom_domains", "update:custom_domains", "delete:custom_domains", diff --git a/internal/auth0/auth0.go b/internal/auth0/auth0.go index dd5e0d248..3b56c5571 100644 --- a/internal/auth0/auth0.go +++ b/internal/auth0/auth0.go @@ -14,6 +14,7 @@ type API struct { Client ClientAPI Connection ConnectionAPI CustomDomain CustomDomainAPI + EmailTemplate EmailTemplateAPI Log LogAPI LogStream LogStreamAPI ResourceServer ResourceServerAPI @@ -30,6 +31,7 @@ func NewAPI(m *management.Management) *API { Branding: m.Branding, Client: m.Client, CustomDomain: m.CustomDomain, + EmailTemplate: m.EmailTemplate, Log: m.Log, LogStream: m.LogStream, ResourceServer: m.ResourceServer, diff --git a/internal/auth0/email_template.go b/internal/auth0/email_template.go new file mode 100644 index 000000000..c406921ef --- /dev/null +++ b/internal/auth0/email_template.go @@ -0,0 +1,24 @@ +//go:generate mockgen -source=email_template.go -destination=email_template_mock.go -package=auth0 + +package auth0 + +import "gopkg.in/auth0.v5/management" + +type EmailTemplateAPI interface { + // Retrieve an email template by pre-defined name. + // + // These names are `verify_email`, `reset_email`, `welcome_email`, + // `blocked_account`, `stolen_credentials`, `enrollment_email`, and + // `mfa_oob_code`. + // + // The names `change_password`, and `password_reset` are also supported for + // legacy scenarios. + // + // See: https://auth0.com/docs/api/management/v2#!/Email_Templates/get_email_templates_by_templateName + Read(template string, opts ...management.RequestOption) (e *management.EmailTemplate, err error) + + // Modify an email template. + // + // See: https://auth0.com/docs/api/management/v2#!/Email_Templates/patch_email_templates_by_templateName + Update(template string, e *management.EmailTemplate, opts ...management.RequestOption) (err error) +} diff --git a/internal/cli/actions.go b/internal/cli/actions.go index 4eecda677..a53437d5d 100644 --- a/internal/cli/actions.go +++ b/internal/cli/actions.go @@ -295,7 +295,7 @@ auth0 actions update --n myaction -t post-login -d "lodash=4.0.0" -s "API_K if err := actionCode.EditorPromptU( cmd, &inputs.Code, - actionTemplate(inputs.Trigger), + current.GetCode(), inputs.Name+".*.js", cli.actionEditorHint, ); err != nil { diff --git a/internal/cli/branding.go b/internal/cli/branding.go index 168c79839..9c0e22670 100644 --- a/internal/cli/branding.go +++ b/internal/cli/branding.go @@ -84,6 +84,7 @@ func brandingCmd(cli *cli) *cobra.Command { cmd.AddCommand(updateBrandingCmd(cli)) cmd.AddCommand(templateCmd(cli)) cmd.AddCommand(customDomainsCmd(cli)) + cmd.AddCommand(emailTemplateCmd(cli)) return cmd } @@ -100,6 +101,20 @@ func templateCmd(cli *cli) *cobra.Command { return cmd } +func emailTemplateCmd(cli *cli) *cobra.Command { + cmd := &cobra.Command{ + Use: "emails", + Short: "Manage custom email templates", + Long: "Manage custom email templates. This requires a custom email provider to be configured for the tenant.", + } + + cmd.SetUsageTemplate(resourceUsageTemplate()) + cmd.AddCommand(showEmailTemplateCmd(cli)) + cmd.AddCommand(updateEmailTemplateCmd(cli)) + return cmd +} + + func showBrandingCmd(cli *cli) *cobra.Command { cmd := &cobra.Command{ Use: "show", @@ -137,10 +152,10 @@ func updateBrandingCmd(cli *cli) *cobra.Command { } cmd := &cobra.Command{ - Use: "update", - Args: cobra.NoArgs, - Short: "Update the custom branding settings for Universal Login", - Long: "Update the custom branding settings for Universal Login.", + Use: "update", + Args: cobra.NoArgs, + Short: "Update the custom branding settings for Universal Login", + Long: "Update the custom branding settings for Universal Login.", Example: `auth0 branding update auth0 branding update --accent '#B24592' --background '#F2DDEC' auth0 branding update -a '#B24592' -b '#F2DDEC --logo 'https://example.com/logo.png`, diff --git a/internal/cli/email_templates.go b/internal/cli/email_templates.go new file mode 100644 index 000000000..896e027fb --- /dev/null +++ b/internal/cli/email_templates.go @@ -0,0 +1,292 @@ +package cli + +import ( + "fmt" + + "github.com/auth0/auth0-cli/internal/ansi" + "github.com/spf13/cobra" + "gopkg.in/auth0.v5" + "gopkg.in/auth0.v5/management" +) + +const ( + emailTemplateVerifyLink = "verify-link" + emailTemplateVerifyCode = "verify-code" + emailTemplateChangePassword = "change-password" + emailTemplateWelcome = "welcome" + emailTemplateBlockedAccount = "blocked-account" + emailTemplatePasswordBreach = "password-breach" + emailTemplateMFAEnrollment = "mfa-enrollment" + emailTemplateMFACode = "mfa-code" + emailTemplateUserInvitation = "user-invitation" +) + +var ( + emailTemplateTemplate = Argument{ + Name: "Template", + Help: fmt.Sprintf("Template name. Can be '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' or '%s'", + emailTemplateVerifyLink, + emailTemplateVerifyCode, + emailTemplateChangePassword, + emailTemplateWelcome, + emailTemplateBlockedAccount, + emailTemplatePasswordBreach, + emailTemplateMFAEnrollment, + emailTemplateMFACode, + emailTemplateUserInvitation), + } + + emailTemplateBody = Flag{ + Name: "Body", + LongForm: "body", + ShortForm: "b", + Help: "Body of the email template.", + IsRequired: true, + } + + emailTemplateFrom = Flag{ + Name: "From", + LongForm: "from", + ShortForm: "f", + Help: "Sender's 'from' email address.", + AlwaysPrompt: true, + } + + emailTemplateSubject = Flag{ + Name: "Subject", + LongForm: "subject", + ShortForm: "s", + Help: "Subject line of the email.", + AlwaysPrompt: true, + } + + emailTemplateEnabled = Flag{ + Name: "Enabled", + LongForm: "enabled", + ShortForm: "e", + Help: "Whether the template is enabled (true) or disabled (false).", + AlwaysPrompt: true, + } + + emailTemplateURL = Flag{ + Name: "Result URL", + LongForm: "url", + ShortForm: "u", + Help: "URL to redirect the user to after a successful action.", + } + + emailTemplateLifetime = Flag{ + Name: "Result URL Lifetime", + LongForm: "lifetime", + ShortForm: "l", + Help: "Lifetime in seconds that the link within the email will be valid for.", + } + + emailTemplateOptions = pickerOptions{ + {"Verification Email (using Link)", emailTemplateVerifyLink}, + {"Verification Email (using Code)", emailTemplateVerifyCode}, + {"Change Password", emailTemplateChangePassword}, + {"Welcome Email", emailTemplateWelcome, }, + {"Blocked Account Email", emailTemplateBlockedAccount}, + {"Password Breach Alert", emailTemplatePasswordBreach}, + {"Enroll in Multifactor Authentication", emailTemplateMFAEnrollment}, + {"Verification Code for Email MFA", emailTemplateMFACode}, + {"User Invitation", emailTemplateUserInvitation}, + } +) + +func showEmailTemplateCmd(cli *cli) *cobra.Command { + var inputs struct { + Template string + } + + cmd := &cobra.Command{ + Use: "show", + Args: cobra.MaximumNArgs(1), + Short: "Show an email template", + Long: "Show an email template.", + Example: `auth0 branding emails show