2021-08-13 16:21:00 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2021-08-25 10:00:16 +00:00
|
|
|
"embed"
|
2021-08-13 16:21:00 +00:00
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
2021-08-14 23:52:16 +00:00
|
|
|
"strings"
|
2021-08-13 16:21:00 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/cockroachdb/pebble"
|
2021-09-28 15:10:13 +00:00
|
|
|
"github.com/fiatjaf/makeinvoice"
|
2021-08-13 16:21:00 +00:00
|
|
|
"github.com/gorilla/mux"
|
|
|
|
"github.com/kelseyhightower/envconfig"
|
|
|
|
_ "github.com/lib/pq"
|
|
|
|
"github.com/rs/zerolog"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Settings struct {
|
2021-08-14 23:52:16 +00:00
|
|
|
Host string `envconfig:"HOST" default:"0.0.0.0"`
|
|
|
|
Port string `envconfig:"PORT" required:"true"`
|
|
|
|
Domain string `envconfig:"DOMAIN" required:"true"`
|
|
|
|
Secret string `envconfig:"SECRET" required:"true"`
|
|
|
|
SiteOwnerName string `envconfig:"SITE_OWNER_NAME" required:"true"`
|
|
|
|
SiteOwnerURL string `envconfig:"SITE_OWNER_URL" required:"true"`
|
|
|
|
SiteName string `envconfig:"SITE_NAME" required:"true"`
|
2021-09-26 18:29:30 +00:00
|
|
|
|
|
|
|
TorProxyURL string `envconfig:"TOR_PROXY_URL"`
|
2021-08-13 16:21:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var s Settings
|
|
|
|
var db *pebble.DB
|
|
|
|
var router = mux.NewRouter()
|
|
|
|
var log = zerolog.New(os.Stderr).Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
|
|
|
|
|
|
|
//go:embed index.html
|
2021-08-25 10:00:16 +00:00
|
|
|
var indexHTML string
|
|
|
|
|
|
|
|
//go:embed grab.html
|
|
|
|
var grabHTML string
|
|
|
|
|
|
|
|
//go:embed static
|
|
|
|
var static embed.FS
|
2021-08-13 16:21:00 +00:00
|
|
|
|
|
|
|
func main() {
|
|
|
|
err := envconfig.Process("", &s)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal().Err(err).Msg("couldn't process envconfig.")
|
|
|
|
}
|
|
|
|
|
2021-12-08 19:40:45 +00:00
|
|
|
// increase default makeinvoice client timeout because people are using tor
|
|
|
|
makeinvoice.Client = &http.Client{Timeout: 25 * time.Second}
|
|
|
|
|
2021-08-24 23:56:58 +00:00
|
|
|
s.Domain = strings.ToLower(s.Domain)
|
|
|
|
|
2021-09-26 18:29:30 +00:00
|
|
|
if s.TorProxyURL != "" {
|
|
|
|
makeinvoice.TorProxyURL = s.TorProxyURL
|
|
|
|
}
|
|
|
|
|
2021-08-13 16:21:00 +00:00
|
|
|
db, err = pebble.Open(s.Domain, nil)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal().Err(err).Str("path", s.Domain).Msg("failed to open db.")
|
|
|
|
}
|
|
|
|
|
|
|
|
router.Path("/.well-known/lnurlp/{username}").Methods("GET").
|
|
|
|
HandlerFunc(handleLNURL)
|
|
|
|
|
|
|
|
router.Path("/").HandlerFunc(
|
|
|
|
func(w http.ResponseWriter, r *http.Request) {
|
2021-08-25 10:00:16 +00:00
|
|
|
renderHTML(w, indexHTML, map[string]interface{}{})
|
2021-08-13 16:21:00 +00:00
|
|
|
},
|
|
|
|
)
|
|
|
|
|
2021-08-25 10:00:16 +00:00
|
|
|
router.PathPrefix("/static/").Handler(http.FileServer(http.FS(static)))
|
|
|
|
|
2021-08-13 16:21:00 +00:00
|
|
|
router.Path("/grab").HandlerFunc(
|
|
|
|
func(w http.ResponseWriter, r *http.Request) {
|
2021-08-30 19:10:26 +00:00
|
|
|
name := r.FormValue("name")
|
|
|
|
|
|
|
|
pin, inv, err := SaveName(name, &Params{
|
2021-08-13 16:21:00 +00:00
|
|
|
Kind: r.FormValue("kind"),
|
|
|
|
Host: r.FormValue("host"),
|
|
|
|
Key: r.FormValue("key"),
|
2021-08-14 21:55:05 +00:00
|
|
|
Pak: r.FormValue("pak"),
|
|
|
|
Waki: r.FormValue("waki"),
|
2021-08-20 12:32:45 +00:00
|
|
|
}, r.FormValue("pin"))
|
|
|
|
if err != nil {
|
2021-08-13 16:21:00 +00:00
|
|
|
w.WriteHeader(500)
|
2021-08-20 12:32:45 +00:00
|
|
|
fmt.Fprint(w, err.Error())
|
2021-08-13 16:21:00 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-08-25 10:00:16 +00:00
|
|
|
renderHTML(w, grabHTML, struct {
|
|
|
|
PIN string `json:"pin"`
|
|
|
|
Invoice string `json:"invoice"`
|
2021-08-30 19:10:26 +00:00
|
|
|
Name string `json:"name"`
|
|
|
|
}{pin, inv, name})
|
2021-08-13 16:21:00 +00:00
|
|
|
},
|
|
|
|
)
|
|
|
|
|
2021-10-27 09:48:21 +00:00
|
|
|
api := router.PathPrefix("/api/v1").Subrouter()
|
|
|
|
api.Use(authenticate)
|
|
|
|
|
|
|
|
// unauthenticated
|
|
|
|
api.HandleFunc("/claim", ClaimAddress).Methods("POST")
|
|
|
|
|
|
|
|
// authenticated routes; X-Pin in header or in json request body
|
|
|
|
api.HandleFunc("/users/{name}", GetUser).Methods("GET")
|
|
|
|
api.HandleFunc("/users/{name}", UpdateUser).Methods("PUT")
|
|
|
|
api.HandleFunc("/users/{name}", DeleteUser).Methods("DELETE")
|
|
|
|
|
2021-08-13 16:21:00 +00:00
|
|
|
srv := &http.Server{
|
|
|
|
Handler: router,
|
|
|
|
Addr: s.Host + ":" + s.Port,
|
|
|
|
WriteTimeout: 15 * time.Second,
|
|
|
|
ReadTimeout: 15 * time.Second,
|
|
|
|
}
|
|
|
|
log.Debug().Str("addr", srv.Addr).Msg("listening")
|
|
|
|
srv.ListenAndServe()
|
|
|
|
}
|