diff --git a/cmd/alias/create.go b/cmd/alias/create.go index 9c1bf6e..f5a6391 100644 --- a/cmd/alias/create.go +++ b/cmd/alias/create.go @@ -28,6 +28,12 @@ Optionally attach a note, display name, or assign to specific mailboxes.`, Example: ` # Create a random alias sl alias create --random + # Create a word-based random alias + sl alias create --random --mode word + + # Create a UUID-based random alias + sl alias create --random --mode uuid + # Create a random alias with a note sl alias create --random --note "Used for newsletters" @@ -56,6 +62,7 @@ var ( createNote string createName string createHostname string + createMode string createJSON bool createJQ string ) @@ -68,6 +75,7 @@ func init() { createCmd.Flags().StringVar(&createNote, "note", "", "Note for the alias") createCmd.Flags().StringVar(&createName, "name", "", "Display name for the alias") createCmd.Flags().StringVar(&createHostname, "hostname", "", "Associate alias with a hostname/website") + createCmd.Flags().StringVar(&createMode, "mode", "", "Random alias generation mode: uuid or word") createCmd.Flags().BoolVar(&createJSON, "json", false, "Output as JSON") createCmd.Flags().StringVar(&createJQ, "jq", "", "Apply jq expression to JSON output") } @@ -80,8 +88,12 @@ func runCreate(cmd *cobra.Command, args []string) error { client := api.NewClient(key, auth.GetAPIBase()) + if createMode != "" && createMode != "uuid" && createMode != "word" { + return fmt.Errorf("--mode must be 'uuid' or 'word'") + } + if createRandom { - alias, rawJSON, err := client.CreateRandomAlias(createNote, createHostname) + alias, rawJSON, err := client.CreateRandomAlias(createNote, createHostname, createMode) if err != nil { return err } diff --git a/cmd/alias/options.go b/cmd/alias/options.go index 51185d3..fb0fbe3 100644 --- a/cmd/alias/options.go +++ b/cmd/alias/options.go @@ -52,7 +52,7 @@ func runOptions(cmd *cobra.Command, args []string) error { return err } - client := api.NewClient(key) + client := api.NewClient(key, auth.GetAPIBase()) opts, rawJSON, err := client.GetAliasOptions(optionsHostname) if err != nil { diff --git a/cmd/domain/view.go b/cmd/domain/view.go index c477fbb..87ffabb 100644 --- a/cmd/domain/view.go +++ b/cmd/domain/view.go @@ -52,7 +52,7 @@ func runView(cmd *cobra.Command, args []string) error { return err } - client := api.NewClient(key) + client := api.NewClient(key, auth.GetAPIBase()) domain, rawJSON, err := client.GetCustomDomain(id) if err != nil { return err diff --git a/internal/api/client.go b/internal/api/client.go index fb30dda..aedc925 100644 --- a/internal/api/client.go +++ b/internal/api/client.go @@ -452,14 +452,23 @@ type CreateRandomAliasRequest struct { } // CreateRandomAlias creates a random alias. -func (c *Client) CreateRandomAlias(note, hostname string) (*Alias, []byte, error) { +// hostname associates the alias with a specific website. +// mode can be "uuid" or "word" (empty string uses server default). +func (c *Client) CreateRandomAlias(note, hostname, mode string) (*Alias, []byte, error) { var reqBody interface{} if note != "" { reqBody = &CreateRandomAliasRequest{Note: note} } path := "/api/alias/random/new" + params := url.Values{} if hostname != "" { - path += "?hostname=" + url.QueryEscape(hostname) + params.Set("hostname", hostname) + } + if mode != "" { + params.Set("mode", mode) + } + if len(params) > 0 { + path += "?" + params.Encode() } body, status, err := c.do("POST", path, reqBody) if err != nil { diff --git a/internal/api/client_test.go b/internal/api/client_test.go index b8dfe30..545573d 100644 --- a/internal/api/client_test.go +++ b/internal/api/client_test.go @@ -339,7 +339,7 @@ func TestClient_CreateRandomAlias(t *testing.T) { defer srv.Close() c := newTestClient(t, srv) - alias, _, err := c.CreateRandomAlias("test note", "") + alias, _, err := c.CreateRandomAlias("test note", "", "") if err != nil { t.Fatalf("CreateRandomAlias: %v", err) } @@ -351,6 +351,37 @@ func TestClient_CreateRandomAlias(t *testing.T) { } } +func TestClient_CreateRandomAlias_WithMode(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + t.Errorf("expected POST, got %s", r.Method) + } + if r.URL.Path != "/api/alias/random/new" { + t.Errorf("unexpected path: %s", r.URL.Path) + } + mode := r.URL.Query().Get("mode") + if mode != "word" { + t.Errorf("expected mode=word, got %q", mode) + } + w.WriteHeader(201) + alias := Alias{ID: 101, Email: "word-random@sl.local"} + _ = json.NewEncoder(w).Encode(alias) + })) + defer srv.Close() + + c := newTestClient(t, srv) + alias, _, err := c.CreateRandomAlias("", "", "word") + if err != nil { + t.Fatalf("CreateRandomAlias with mode: %v", err) + } + if alias.ID != 101 { + t.Errorf("expected ID 101, got %d", alias.ID) + } + if alias.Email != "word-random@sl.local" { + t.Errorf("expected email word-random@sl.local, got %q", alias.Email) + } +} + func TestClient_GetStats(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/api/stats" {