mirror of
https://github.com/fiatjaf/nak.git
synced 2025-04-18 15:59:56 -04:00
133 lines
3.0 KiB
Go
133 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"github.com/nbd-wtf/go-nostr"
|
|
"github.com/urfave/cli/v3"
|
|
"golang.org/x/exp/slices"
|
|
)
|
|
|
|
var curlFlags []string
|
|
|
|
var curl = &cli.Command{
|
|
Name: "curl",
|
|
Usage: "calls curl but with a nip98 header",
|
|
Description: "accepts all flags and arguments exactly as they would be passed to curl.",
|
|
Flags: defaultKeyFlags,
|
|
DisableSliceFlagSeparator: true,
|
|
Action: func(ctx context.Context, c *cli.Command) error {
|
|
kr, _, err := gatherKeyerFromArguments(ctx, c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// cowboy parsing of curl flags to get the data we need for nip98
|
|
var url string
|
|
var method string
|
|
var presumedMethod string
|
|
|
|
curlBodyBuildingFlags := []string{
|
|
"-d",
|
|
"--data",
|
|
"--data-binary",
|
|
"--data-ascii",
|
|
"--data-raw",
|
|
"--data-urlencode",
|
|
"-F",
|
|
"--form",
|
|
"--form-string",
|
|
"--form-escape",
|
|
"--upload-file",
|
|
}
|
|
|
|
nextIsMethod := false
|
|
for _, f := range curlFlags {
|
|
if nextIsMethod {
|
|
method = f
|
|
method, _ = strings.CutPrefix(method, `"`)
|
|
method, _ = strings.CutSuffix(method, `"`)
|
|
method = strings.ToUpper(method)
|
|
} else if strings.HasPrefix(f, "https://") || strings.HasPrefix(f, "http://") {
|
|
url = f
|
|
} else if f == "--request" || f == "-X" {
|
|
nextIsMethod = true
|
|
continue
|
|
} else if slices.Contains(curlBodyBuildingFlags, f) ||
|
|
slices.ContainsFunc(curlBodyBuildingFlags, func(s string) bool {
|
|
return strings.HasPrefix(f, s)
|
|
}) {
|
|
presumedMethod = "POST"
|
|
}
|
|
nextIsMethod = false
|
|
}
|
|
|
|
if url == "" {
|
|
return fmt.Errorf("can't create nip98 event: target url is empty")
|
|
}
|
|
|
|
if method == "" {
|
|
if presumedMethod != "" {
|
|
method = presumedMethod
|
|
} else {
|
|
method = "GET"
|
|
}
|
|
}
|
|
|
|
// make and sign event
|
|
evt := nostr.Event{
|
|
Kind: 27235,
|
|
CreatedAt: nostr.Now(),
|
|
Tags: nostr.Tags{
|
|
{"u", url},
|
|
{"method", method},
|
|
},
|
|
}
|
|
if err := kr.SignEvent(ctx, &evt); err != nil {
|
|
return err
|
|
}
|
|
|
|
// the first 2 indexes of curlFlags were reserved for this
|
|
curlFlags[0] = "-H"
|
|
curlFlags[1] = fmt.Sprintf("Authorization: Nostr %s", base64.StdEncoding.EncodeToString([]byte(evt.String())))
|
|
|
|
// call curl
|
|
cmd := exec.Command("curl", curlFlags...)
|
|
cmd.Stderr = os.Stderr
|
|
cmd.Stdin = os.Stdin
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Run()
|
|
return nil
|
|
},
|
|
}
|
|
|
|
func realCurl() error {
|
|
curlFlags = make([]string, 2, max(len(os.Args)-4, 2))
|
|
keyFlags := make([]string, 0, 5)
|
|
|
|
for i := 0; i < len(os.Args[2:]); i++ {
|
|
arg := os.Args[i+2]
|
|
if slices.ContainsFunc(defaultKeyFlags, func(f cli.Flag) bool {
|
|
bareArg, _ := strings.CutPrefix(arg, "-")
|
|
bareArg, _ = strings.CutPrefix(bareArg, "-")
|
|
return slices.Contains(f.Names(), bareArg)
|
|
}) {
|
|
keyFlags = append(keyFlags, arg)
|
|
if arg != "--prompt-sec" {
|
|
i++
|
|
val := os.Args[i+2]
|
|
keyFlags = append(keyFlags, val)
|
|
}
|
|
} else {
|
|
curlFlags = append(curlFlags, arg)
|
|
}
|
|
}
|
|
|
|
return curl.Run(context.Background(), keyFlags)
|
|
}
|