diff --git a/docs/auth0_universal-login_templates_update.md b/docs/auth0_universal-login_templates_update.md index 30257f9f9..adfa2e7b8 100644 --- a/docs/auth0_universal-login_templates_update.md +++ b/docs/auth0_universal-login_templates_update.md @@ -15,9 +15,15 @@ auth0 universal-login templates update [flags] ``` auth0 universal-login templates update auth0 ul templates update + cat path/to/body.html | auth0 ul templates update ``` +## Flags + +``` + --force Skip confirmation. +``` ## InheritedFlags diff --git a/internal/cli/universal_login.go b/internal/cli/universal_login.go index 333987523..dc9f4cb19 100644 --- a/internal/cli/universal_login.go +++ b/internal/cli/universal_login.go @@ -3,12 +3,15 @@ package cli import ( "errors" "fmt" + "net/http" - "github.com/auth0/go-auth0" "github.com/auth0/go-auth0/management" "github.com/spf13/cobra" "github.com/auth0/auth0-cli/internal/ansi" + "github.com/auth0/auth0-cli/internal/auth0" + "github.com/auth0/auth0-cli/internal/iostream" + "github.com/auth0/auth0-cli/internal/prompt" ) var ( @@ -60,7 +63,7 @@ var ( AlwaysPrompt: true, } - errNotAllowed = errors.New("this feature requires at least one custom domain to be configured for the tenant") + errNotAllowed = errors.New("this feature requires at least one custom domain to be set and verified for the tenant") ) func universalLoginCmd(cli *cli) *cobra.Command { @@ -266,15 +269,26 @@ func showBrandingTemplateCmd(cli *cli) *cobra.Command { auth0 ul templates show`, RunE: func(cmd *cobra.Command, args []string) error { var template *management.BrandingUniversalLogin - if err := ansi.Waiting(func() (err error) { template, err = cli.api.Branding.UniversalLogin() - return err + if err != nil { + if mErr, ok := err.(management.Error); ok && mErr.Status() == http.StatusNotFound { + return nil + } + return err + } + + return nil }); err != nil { - return fmt.Errorf("unable to load the Universal Login template due to an unexpected error: %w", err) + return fmt.Errorf("failed to load the Universal Login template: %w", err) } cli.renderer.Heading("universal login template") + + if template == nil { + cli.renderer.Infof("No custom template found. To set one, run: `auth0 universal-login templates update`.") + } + fmt.Println(template.GetBody()) return nil @@ -291,11 +305,86 @@ func updateBrandingTemplateCmd(cli *cli) *cobra.Command { Short: "Update the custom template for Universal Login", Long: "Update the custom template for Universal Login.", Example: ` auth0 universal-login templates update - auth0 ul templates update`, + auth0 ul templates update + cat path/to/body.html | auth0 ul templates update`, RunE: func(cmd *cobra.Command, args []string) error { + if err := isCustomDomainEnabled(cli.api); err != nil { + return err + } + + var currentTemplate *management.BrandingUniversalLogin + if err := ansi.Waiting(func() (err error) { + currentTemplate, err = cli.api.Branding.UniversalLogin() + if err != nil { + if mErr, ok := err.(management.Error); ok && mErr.Status() == http.StatusNotFound { + return nil + } + return err + } + + return nil + }); err != nil { + return fmt.Errorf("failed to load the Universal Login template: %w", err) + } + + onInfo := func() { + cli.renderer.Infof( + "%s Once you close the editor, you'll be prompted to save your changes. To cancel, press CTRL+C.", + ansi.Faint("Hint:"), + ) + } + + body := string(iostream.PipedInput()) + err := textBody.OpenEditor(cmd, &body, currentTemplate.GetBody(), "ul-template.*.html", onInfo) + if err != nil { + return fmt.Errorf("failed to capture input from the editor: %w", err) + } + + if !cli.force && canPrompt(cmd) { + var confirmed bool + if err := prompt.AskBool("Do you want to save the template?", &confirmed, true); err != nil { + return fmt.Errorf("failed to capture prompt input: %w", err) + } + if !confirmed { + return nil + } + } + + if err = ansi.Waiting(func() error { + return cli.api.Branding.SetUniversalLogin( + &management.BrandingUniversalLogin{ + Body: &body, + }, + ) + }); err != nil { + return fmt.Errorf("failed to update the Universal Login template: %w", err) + } + return nil }, } + cmd.Flags().BoolVar(&cli.force, "force", false, "Skip confirmation.") + return cmd } + +func isCustomDomainEnabled(api *auth0.API) error { + domains, err := api.CustomDomain.List() + if err != nil { + // 403 is a valid response for free tenants that don't have custom domains enabled + if mErr, ok := err.(management.Error); ok && mErr.Status() == http.StatusForbidden { + return errNotAllowed + } + + return err + } + + for _, domain := range domains { + if domain.GetStatus() == "ready" { + return nil + } + } + + return errNotAllowed +} diff --git a/test/integration/fixtures/ul-template.html b/test/integration/fixtures/ul-template.html new file mode 100644 index 000000000..f3b97fa9d --- /dev/null +++ b/test/integration/fixtures/ul-template.html @@ -0,0 +1,9 @@ + + +{%- auth0:head -%} + Universal Login Test Template + + +{%- auth0:widget -%} + +