diff --git a/internal/cli/apps_test.go b/internal/cli/apps_test.go index d15b4542b..85088a9ec 100644 --- a/internal/cli/apps_test.go +++ b/internal/cli/apps_test.go @@ -117,5 +117,6 @@ func TestTypeFor(t *testing.T) { } func TestCommaSeparatedStringToSlice(t *testing.T) { - assert.Equal(t, []string{"foo"}, commaSeparatedStringToSlice("foo")) + assert.Equal(t, []string{}, commaSeparatedStringToSlice("")) + assert.Equal(t, []string{"foo", "bar", "baz"}, commaSeparatedStringToSlice(" foo , bar , baz ")) } diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 2e4a0375f..ca8698c2c 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -256,10 +256,7 @@ func (c *cli) prepareTenant(ctx context.Context) (Tenant, error) { if err := t.regenerateAccessToken(ctx); err != nil { if t.authenticatedWithClientCredentials() { errorMessage := fmt.Errorf( - "failed to fetch access token using client credentials: %w\n\n"+ - "This may occur if the designated Auth0 application has been deleted, "+ - "the client secret has been rotated or previous failure to store client secret in the keyring.\n\n"+ - "Please re-authenticate by running: %s", + "failed to fetch access token using client credentials: %w\n\nThis may occur if the designated Auth0 application has been deleted, the client secret has been rotated or previous failure to store client secret in the keyring.\n\nPlease re-authenticate by running: %s", err, ansi.Bold("auth0 login --domain --client-secret "), ) diff --git a/internal/cli/cli_test.go b/internal/cli/cli_test.go index 6575f0a28..699d80cc8 100644 --- a/internal/cli/cli_test.go +++ b/internal/cli/cli_test.go @@ -174,3 +174,24 @@ func TestGetAccessToken(t *testing.T) { assert.Equal(t, strings.Join(accessTokenChunks, ""), getAccessToken(Tenant{Domain: mockTenantDomain, AccessToken: "even if this is set for some reason"})) }) } + +func TestAuthenticatedWithClientCredentials(t *testing.T) { + mockTenantClientCredentials := Tenant{ClientID: "some-valid-client-id"} + assert.True(t, mockTenantClientCredentials.authenticatedWithClientCredentials()) + + mockTenantDeviceFlow := Tenant{ClientID: ""} + assert.False(t, mockTenantDeviceFlow.authenticatedWithClientCredentials()) +} + +func TestHasAllRequiredScopes(t *testing.T) { + mockTenantWithNoScopes := Tenant{Scopes: []string{}} + assert.False(t, hasAllRequiredScopes(mockTenantWithNoScopes)) + + mockTenantWithAllRequiredScopes := Tenant{Scopes: auth.RequiredScopes} + assert.True(t, hasAllRequiredScopes(mockTenantWithAllRequiredScopes)) + + requiredScopesAndMore := auth.RequiredScopes + requiredScopesAndMore = append(requiredScopesAndMore, "read:foo", "update:foo", "delete:foo") + mockTenantWithAllRequiredScopesAndMore := Tenant{Scopes: requiredScopesAndMore} + assert.True(t, hasAllRequiredScopes(mockTenantWithAllRequiredScopesAndMore)) +} diff --git a/internal/cli/login.go b/internal/cli/login.go index 64ba273f4..b2e723893 100644 --- a/internal/cli/login.go +++ b/internal/cli/login.go @@ -267,9 +267,7 @@ func RunLoginAsMachine(ctx context.Context, inputs LoginInputs, cli *cli, cmd *c }, ) if err != nil { - return fmt.Errorf( - "failed to fetch access token using client credentials. \n\n"+ - "Ensure that the provided client-id, client-secret and domain are correct. \n\nerror: %w\n", err) + return fmt.Errorf("failed to fetch access token using client credentials. \n\nEnsure that the provided client-id, client-secret and domain are correct. \n\nerror: %w\n", err) } t := Tenant{ diff --git a/internal/cli/logs.go b/internal/cli/logs.go index 704765b5f..f7d3d82bd 100644 --- a/internal/cli/logs.go +++ b/internal/cli/logs.go @@ -110,7 +110,7 @@ func tailLogsCmd(cli *cli) *cobra.Command { // // Create a `set` to detect duplicates clientside. set := make(map[string]struct{}) - list = dedupLogs(list, set) + list = dedupeLogs(list, set) if len(list) > 0 { lastLogID = list[len(list)-1].GetLogID() @@ -142,7 +142,7 @@ func tailLogsCmd(cli *cli) *cobra.Command { } if len(list) > 0 { - logsCh <- dedupLogs(list, set) + logsCh <- dedupeLogs(list, set) lastLogID = list[len(list)-1].GetLogID() } @@ -186,7 +186,7 @@ func getLatestLogs(cli *cli, n int, filter string) ([]*management.Log, error) { return cli.api.Log.List(queryParams...) } -func dedupLogs(list []*management.Log, set map[string]struct{}) []*management.Log { +func dedupeLogs(list []*management.Log, set map[string]struct{}) []*management.Log { res := make([]*management.Log, 0, len(list)) for _, l := range list { diff --git a/internal/cli/logs_test.go b/internal/cli/logs_test.go index b036af452..50b62f886 100644 --- a/internal/cli/logs_test.go +++ b/internal/cli/logs_test.go @@ -11,7 +11,7 @@ import ( "github.com/auth0/auth0-cli/internal/auth0" ) -func TestDedupLogs(t *testing.T) { +func TestDedupeLogs(t *testing.T) { t.Run("removes duplicate logs and sorts by date asc", func(t *testing.T) { logs := []*management.Log{ { @@ -28,7 +28,7 @@ func TestDedupLogs(t *testing.T) { }, } set := map[string]struct{}{"some-id-3": {}} - result := dedupLogs(logs, set) + result := dedupeLogs(logs, set) assert.Len(t, result, 2) assert.Equal(t, "some-id-2", result[0].GetID()) @@ -51,7 +51,7 @@ func TestDedupLogs(t *testing.T) { }, } set := map[string]struct{}{} - result := dedupLogs(logs, set) + result := dedupeLogs(logs, set) assert.Len(t, logs, 3) assert.Equal(t, "some-id-2", result[0].GetID()) @@ -79,7 +79,7 @@ func TestDedupLogs(t *testing.T) { "some-id-2": {}, "some-id-3": {}, } - result := dedupLogs(logs, set) + result := dedupeLogs(logs, set) assert.Len(t, result, 0) }) diff --git a/internal/cli/templates.go b/internal/cli/templates.go index 3dc167b08..877cb849a 100644 --- a/internal/cli/templates.go +++ b/internal/cli/templates.go @@ -5,7 +5,6 @@ import ( "strings" "github.com/spf13/cobra" - "github.com/spf13/pflag" "golang.org/x/term" "github.com/auth0/auth0-cli/internal/ansi" @@ -14,8 +13,6 @@ import ( func init() { cobra.AddTemplateFunc("WrappedInheritedFlagUsages", WrappedInheritedFlagUsages) cobra.AddTemplateFunc("WrappedLocalFlagUsages", WrappedLocalFlagUsages) - cobra.AddTemplateFunc("WrappedRequestParamsFlagUsages", WrappedRequestParamsFlagUsages) - cobra.AddTemplateFunc("WrappedNonRequestParamsFlagUsages", WrappedNonRequestParamsFlagUsages) cobra.AddTemplateFunc("WrappedAliases", WrappedAliases) } @@ -33,46 +30,6 @@ func WrappedLocalFlagUsages(cmd *cobra.Command) string { return cmd.LocalFlags().FlagUsagesWrapped(getTerminalWidth()) } -// WrappedRequestParamsFlagUsages returns a string containing the usage -// information for all request parameters flags, i.e. flags used in operation -// commands to set values for request parameters. The string is wrapped to the -// terminal's width. -func WrappedRequestParamsFlagUsages(cmd *cobra.Command) string { - var sb strings.Builder - - // We're cheating a little bit in thie method: we're not actually wrapping - // anything, just printing out the flag names and assuming that no name - // will be long enough to go over the terminal's width. - // We do this instead of using pflag's `FlagUsagesWrapped` function because - // we don't want to print the types (all request parameters flags are - // defined as strings in the CLI, but it would be confusing to print that - // out as a lot of them are not strings in the API). - // If/when we do add help strings for request parameters flags, we'll have - // to do actual wrapping. - cmd.LocalFlags().VisitAll(func(flag *pflag.Flag) { - if _, ok := flag.Annotations["request"]; ok { - sb.WriteString(fmt.Sprintf(" --%s\n", flag.Name)) - } - }) - - return sb.String() -} - -// WrappedNonRequestParamsFlagUsages returns a string containing the usage -// information for all non-request parameters flags. The string is wrapped to -// the terminal's width. -func WrappedNonRequestParamsFlagUsages(cmd *cobra.Command) string { - nonRequestParamsFlags := pflag.NewFlagSet("request", pflag.ExitOnError) - - cmd.LocalFlags().VisitAll(func(flag *pflag.Flag) { - if _, ok := flag.Annotations["request"]; !ok { - nonRequestParamsFlags.AddFlag(flag) - } - }) - - return nonRequestParamsFlags.FlagUsagesWrapped(getTerminalWidth()) -} - // WrappedAliases returns a formatted string containing the command aliases if defined, otherwise an empty string. func WrappedAliases(cmd *cobra.Command) string { if len(cmd.Aliases) > 0 { diff --git a/internal/cli/tenants.go b/internal/cli/tenants.go index 1862188a9..847cc4913 100644 --- a/internal/cli/tenants.go +++ b/internal/cli/tenants.go @@ -133,7 +133,6 @@ func (c *cli) tenantPickerOptions() (pickerOptions, error) { for _, tenant := range tenants { opt := pickerOption{value: tenant.Domain, label: tenant.Domain} - // Check if this is currently the default tenant. if tenant.Domain == c.config.DefaultTenant { priorityOpts = append(priorityOpts, opt) } else { diff --git a/internal/cli/universal_login_templates.go b/internal/cli/universal_login_templates.go index 8ced5c5f5..ae0b5842b 100644 --- a/internal/cli/universal_login_templates.go +++ b/internal/cli/universal_login_templates.go @@ -149,11 +149,7 @@ func updateBrandingTemplateCmd(cli *cli) *cobra.Command { } if templateData.Experience == "classic" { - cli.renderer.Warnf( - "The tenant is configured to use the classic Universal Login Experience instead of the new. " + - "The template changes won't apply until you select the new Universal Login Experience. " + - "You can do so by running: \"auth0 api patch prompts --data '{\"universal_login_experience\":\"new\"}'\"", - ) + cli.renderer.Warnf("The tenant is configured to use the classic Universal Login Experience instead of the new. The template changes won't apply until you select the new Universal Login Experience. You can do so by running: \"auth0 api patch prompts --data '{\"universal_login_experience\":\"new\"}'\"") } if templateData.Body == "" { @@ -200,7 +196,6 @@ func updateBrandingTemplateCmd(cli *cli) *cobra.Command { func (cli *cli) fetchTemplateData(ctx context.Context) (*TemplateData, error) { group, ctx := errgroup.WithContext(ctx) - group.Go(func() (err error) { return ensureCustomDomainIsEnabled(ctx, cli.api) }) @@ -213,8 +208,7 @@ func (cli *cli) fetchTemplateData(ctx context.Context) (*TemplateData, error) { var clientList *management.ClientList group.Go(func() (err error) { - // Capping the clients retrieved to 100 for now. - clientList, err = cli.api.Client.List(management.Context(ctx), management.PerPage(100)) + clientList, err = cli.api.Client.List(management.Context(ctx), management.PerPage(100)) // Capping the clients retrieved to 100 for now. return err }) @@ -263,9 +257,8 @@ func (cli *cli) fetchTemplateData(ctx context.Context) (*TemplateData, error) { func ensureCustomDomainIsEnabled(ctx context.Context, api *auth0.API) error { domains, err := api.CustomDomain.List(management.Context(ctx)) 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 errNotAllowed // 403 is a valid response for free tenants that don't have custom domains enabled } return err @@ -284,8 +277,7 @@ func ensureCustomDomainIsEnabled(ctx context.Context, api *auth0.API) error { func fetchBrandingSettingsOrUseDefaults(ctx context.Context, api *auth0.API) *management.Branding { brandingSettings, err := api.Branding.Read(management.Context(ctx)) if err != nil { - // If we error we'll provide defaults. - brandingSettings = &management.Branding{} + brandingSettings = &management.Branding{} // If we error we'll provide defaults. } if brandingSettings.GetColors() == nil { @@ -312,10 +304,7 @@ func fetchBrandingTemplateOrUseEmpty(ctx context.Context, api *auth0.API) *manag func (cli *cli) editTemplateAndPreviewChanges(ctx context.Context, cmd *cobra.Command, templateData *TemplateData) error { 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:"), - ) + 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:")) } onFileCreated := func(filename string) { @@ -423,7 +412,6 @@ func buildRoutes( }) router.Handle("/", http.FileServer(http.FS(templatePreviewAssets))) - return router } diff --git a/internal/display/apis_test.go b/internal/display/apis_test.go new file mode 100644 index 000000000..6bed86fb2 --- /dev/null +++ b/internal/display/apis_test.go @@ -0,0 +1,65 @@ +package display + +import ( + "fmt" + "testing" + + "github.com/auth0/go-auth0/management" + "github.com/stretchr/testify/assert" +) + +func TestGetScopes(t *testing.T) { + t.Run("no scopes should not truncate", func(t *testing.T) { + mockScopes := []management.ResourceServerScope{} + + scopes, didTruncate := getScopes(mockScopes) + assert.Equal(t, "", scopes) + assert.False(t, didTruncate) + }) + + t.Run("few scopes should not truncate", func(t *testing.T) { + mockScopes := []management.ResourceServerScope{} + + for i := 0; i < 3; i++ { + v := fmt.Sprintf("scope%d", i) + d := fmt.Sprintf("Description for scope%d", i) + + mockScopes = append(mockScopes, management.ResourceServerScope{ + Value: &v, + Description: &d, + }) + } + + scopes, didTruncate := getScopes(mockScopes) + assert.Equal(t, "scope0 scope1 scope2", scopes) + assert.False(t, didTruncate) + }) + + t.Run("should truncate", func(t *testing.T) { + mockScopes := []management.ResourceServerScope{} + + for i := 0; i < 100; i++ { + v := fmt.Sprintf("scope%d", i) + d := fmt.Sprintf("Description for scope%d", i) + + mockScopes = append(mockScopes, management.ResourceServerScope{ + Value: &v, + Description: &d, + }) + } + + scopes, didTruncate := getScopes(mockScopes) + assert.Equal(t, "scope0 scope1 scope2 scope3 scope4 scope5 scope6...", scopes) + assert.True(t, didTruncate) + }) +} + +func TestApiView_AsTableHeader(t *testing.T) { + mockAPIView := apiView{} + assert.Equal(t, []string{}, mockAPIView.AsTableHeader()) +} + +func TestApiView_AsTableRow(t *testing.T) { + mockAPIView := apiView{} + assert.Equal(t, []string{}, mockAPIView.AsTableRow()) +} diff --git a/internal/display/custom_domain_test.go b/internal/display/custom_domain_test.go new file mode 100644 index 000000000..02a9b081b --- /dev/null +++ b/internal/display/custom_domain_test.go @@ -0,0 +1,23 @@ +package display + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCustomDomainView_AsTableHeader(t *testing.T) { + mockCustomDomainView := customDomainView{} + + assert.Equal(t, []string{"ID", "Domain", "Status"}, mockCustomDomainView.AsTableHeader()) +} + +func TestCustomDomainView_AsTableRow(t *testing.T) { + mockCustomDomainView := customDomainView{ + ID: "custom-domain-id", + Domain: "example.com", + Status: "verified", + } + + assert.Equal(t, []string{"custom-domain-id", "example.com", "verified"}, mockCustomDomainView.AsTableRow()) +} diff --git a/internal/display/display_test.go b/internal/display/display_test.go index 8fc70df39..55d3eba68 100644 --- a/internal/display/display_test.go +++ b/internal/display/display_test.go @@ -1,8 +1,16 @@ package display import ( + "bytes" + "io" + "sync" "testing" "time" + + "github.com/auth0/go-auth0/management" + "github.com/stretchr/testify/assert" + + "github.com/auth0/auth0-cli/internal/auth0" ) func TestTimeAgo(t *testing.T) { @@ -14,6 +22,7 @@ func TestTimeAgo(t *testing.T) { want string }{ {t0, "0 seconds ago"}, + {t0.Add(-61 * time.Second), "a minute ago"}, {t0.Add(-2 * time.Minute), "2 minutes ago"}, {t0.Add(-119 * time.Minute), "an hour ago"}, {t0.Add(-3 * time.Hour), "3 hours ago"}, @@ -34,3 +43,66 @@ func TestTimeAgo(t *testing.T) { }) } } + +func TestStream(t *testing.T) { + var stdout bytes.Buffer + mockRender := &Renderer{ + MessageWriter: io.Discard, + ResultWriter: &stdout, + } + + results := []View{ + &logView{ + Log: &management.Log{ + LogID: auth0.String("354234"), + Type: auth0.String("sapi"), + Description: auth0.String("Update branding settings"), + }, + }, + } + + t.Run("Stream correctly handles nil channel", func(t *testing.T) { + mockRender.Stream(results, nil) + expectedResult := "API Operation Update branding settings Jan 01 00:00:00.000 N/A N/A \n" + assert.Equal(t, expectedResult, stdout.String()) + stdout.Reset() + }) + + t.Run("Stream successfully", func(t *testing.T) { + viewChan := make(chan View) + + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + mockRender.Stream(results, viewChan) + }() + + wg.Add(1) + go func() { + defer wg.Done() + viewChan <- &logView{ + Log: &management.Log{ + LogID: auth0.String("354236"), + Type: auth0.String("sapi"), + Description: auth0.String("Update tenant settings"), + }, + } + close(viewChan) + }() + + wg.Wait() + + expectedResult := `API Operation Update branding settings Jan 01 00:00:00.000 N/A N/A +API Operation Update tenant settings Jan 01 00:00:00.000 N/A N/A +` + assert.Equal(t, expectedResult, stdout.String()) + stdout.Reset() + }) +} + +func TestIndent(t *testing.T) { + assert.Equal(t, "foo", indent("foo", "")) + assert.Equal(t, " foo", indent("foo", " ")) + assert.Equal(t, " line1\n line2\n line3", indent("line1\nline2\nline3", " ")) +} diff --git a/test/integration/test-cases.yaml b/test/integration/test-cases.yaml index 82dfc2bc2..e1e06ae7c 100644 --- a/test/integration/test-cases.yaml +++ b/test/integration/test-cases.yaml @@ -108,7 +108,7 @@ tests: - ORDER 2 - SCRIPT function(user, context, cb) { exit-code: 0 - + rules list all with data: command: auth0 rules list exit-code: 0 @@ -244,24 +244,16 @@ tests: - STAGE_PRE_USER_REGISTRATION_RATE exit-code: 0 - update universal login branding prompts (login): - command: cat ./test/integration/fixtures/update-ul-prompts-login.json | auth0 ul prompts update login - exit-code: 0 - - update universal login branding prompts (mfa-push): - command: cat ./test/integration/fixtures/update-ul-prompts-mfa-push.json | auth0 ul prompts update mfa-push - exit-code: 0 - tenants use: command: auth0 tenants use $AUTH0_CLI_CLIENT_DOMAIN exit-code: 0 stderr: - contains: + contains: - "Default tenant switched to:" tenants open: command: auth0 tenants open $AUTH0_CLI_CLIENT_DOMAIN --no-input exit-code: 0 stderr: - contains: + contains: - "Open the following URL in a browser: https://manage.auth0.com/dashboard/" diff --git a/test/integration/universal-login-test-cases.yaml b/test/integration/universal-login-test-cases.yaml index 4dcf24da5..8b06d72d3 100644 --- a/test/integration/universal-login-test-cases.yaml +++ b/test/integration/universal-login-test-cases.yaml @@ -22,52 +22,83 @@ tests: exit-code: 0 stdout: json: - colors.primary: "#2A2E35" - colors.page_background: "#FF4F40" - favicon_url: "https://example.com/favicon.png" - logo_url: "https://example.com/logo.png" - font.url: "https://example.com/font.woff" + colors.primary: "#2A2E35" + colors.page_background: "#FF4F40" + favicon_url: "https://example.com/favicon.png" + logo_url: "https://example.com/logo.png" + font.url: "https://example.com/font.woff" 004 - it successfully updates universal login branding: command: auth0 ul update --accent "#2A2E35" --background "#FF4F40" --logo "https://example.com/logo-updated.png" --favicon "https://example.com/favicon-updated.png" --font https://example.com/font-updated.woff exit-code: 0 stdout: contains: - - "ACCENT COLOR #2A2E35" - - "BACKGROUND COLOR #FF4F40" - - LOGO URL https://example.com/logo-updated.png - - FAVICON URL https://example.com/favicon-updated.png - - CUSTOM FONT URL https://example.com/font-updated.woff + - "ACCENT COLOR #2A2E35" + - "BACKGROUND COLOR #FF4F40" + - LOGO URL https://example.com/logo-updated.png + - FAVICON URL https://example.com/favicon-updated.png + - CUSTOM FONT URL https://example.com/font-updated.woff 005 - it successfully updates universal login branding and outputs as json: command: auth0 ul update --accent "#FF4F40" --background "#2A2E35" --logo "https://example.com/logo-updated-json.png" --favicon "https://example.com/favicon-updated-json.png" --font https://example.com/font-updated-json.woff --json exit-code: 0 stdout: json: - colors.primary: "#FF4F40" - colors.page_background: "#2A2E35" - favicon_url: "https://example.com/favicon-updated-json.png" - logo_url: "https://example.com/logo-updated-json.png" - font.url: "https://example.com/font-updated-json.woff" + colors.primary: "#FF4F40" + colors.page_background: "#2A2E35" + favicon_url: "https://example.com/favicon-updated-json.png" + logo_url: "https://example.com/logo-updated-json.png" + font.url: "https://example.com/font-updated-json.woff" 006 - it successfully updates universal login branding and persists previous colors: command: auth0 ul update --logo "https://example.com/logo-updated-2.png" --favicon "https://example.com/favicon-updated-2.png" --font https://example.com/font-updated-2.woff --json exit-code: 0 stdout: json: - colors.primary: "#FF4F40" - colors.page_background: "#2A2E35" - favicon_url: "https://example.com/favicon-updated-2.png" - logo_url: "https://example.com/logo-updated-2.png" - font.url: "https://example.com/font-updated-2.woff" + colors.primary: "#FF4F40" + colors.page_background: "#2A2E35" + favicon_url: "https://example.com/favicon-updated-2.png" + logo_url: "https://example.com/logo-updated-2.png" + font.url: "https://example.com/font-updated-2.woff" 007 - it successfully updates universal login branding and persists previous URLs: command: auth0 ul update --accent "#2A2E35" --background "#FF4F40" --json exit-code: 0 stdout: json: - colors.primary: "#2A2E35" - colors.page_background: "#FF4F40" - favicon_url: "https://example.com/favicon-updated-2.png" - logo_url: "https://example.com/logo-updated-2.png" - font.url: "https://example.com/font-updated-2.woff" + colors.primary: "#2A2E35" + colors.page_background: "#FF4F40" + favicon_url: "https://example.com/favicon-updated-2.png" + logo_url: "https://example.com/logo-updated-2.png" + font.url: "https://example.com/font-updated-2.woff" + + 008 - it returns no universal login templates: + command: auth0 ul templates show + exit-code: 0 + stderr: + contains: + - "No custom template found. To set one, run: `auth0 universal-login templates update`" + + 009 - it cannot successfully update universal login templates because no verified custom domain: + command: auth0 ul templates update + exit-code: 1 + stderr: + contains: + - "failed to fetch the Universal Login template data: this feature requires at least one custom domain to be set and verified for the tenant, use 'auth0 domains create' to create one and 'auth0 domains verify' to have it verified" + + 010 - update universal login branding prompts (login): + command: cat ./test/integration/fixtures/update-ul-prompts-login.json | auth0 ul prompts update login + exit-code: 0 + + 011 - update universal login branding prompts (mfa-push): + command: cat ./test/integration/fixtures/update-ul-prompts-mfa-push.json | auth0 ul prompts update mfa-push + exit-code: 0 + + 012 - show universal login branding prompts (mfa-push): + command: auth0 ul prompts show mfa-push + exit-code: 0 + stdout: + json: + mfa-push-challenge-push.rememberMeText: "Remember this device for 30 days" + mfa-push-success.title: "You're All Set!" + mfa-push-enrollment-qr.logoAltText: "${companyName}"