multipage html + placeholder /grab html.

This commit is contained in:
fiatjaf 2021-08-25 07:00:16 -03:00
parent 8f09556529
commit 4cef3663d3
6 changed files with 285 additions and 223 deletions

16
db.go
View File

@ -21,7 +21,11 @@ type Params struct {
Waki string
}
func SaveName(name string, params *Params, providedPin string) (pin string, err error) {
func SaveName(
name string,
params *Params,
providedPin string,
) (pin string, inv string, err error) {
name = strings.ToLower(name)
key := []byte(name)
@ -32,22 +36,22 @@ func SaveName(name string, params *Params, providedPin string) (pin string, err
if _, closer, err := db.Get(key); err == nil {
defer closer.Close()
if pin != providedPin {
return "", errors.New("name already exists! must provide pin.")
return "", "", errors.New("name already exists! must provide pin.")
}
}
// check if the given data works
if _, err := makeInvoice(params, 1000); err != nil {
return "", fmt.Errorf("couldn't make an invoice with the given data: %w", err)
if inv, err = makeInvoice(params, 1000); err != nil {
return "", "", fmt.Errorf("couldn't make an invoice with the given data: %w", err)
}
// save it
data, _ := json.Marshal(params)
if err := db.Set(key, data, pebble.Sync); err != nil {
return "", err
return "", "", err
}
return pin, nil
return pin, inv, nil
}
func GetName(name string) (*Params, error) {

32
grab.html Normal file
View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Satdress - Name Saved</title>
<meta charset="utf-8" />
<link rel="icon" type="image/png" href="https://i.imgur.com/4yaPtA2.png" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/style.css" />
</head>
<body>
<main id="main">
name saved! this is your secret pin key for this name: {{ pin }}
this is the test invoice we've generated: {{ invoice }}
</main>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.2/vue.global.prod.min.js"
></script>
<script>
const initial = {} // REPLACED WITH SERVER DATA
const Main = {
data() {
return {
...initial,
}
}
};
Vue.createApp(Main).mount('#main');
</script>
</body>
</html>

37
html.go Normal file
View File

@ -0,0 +1,37 @@
package main
import (
"encoding/json"
"fmt"
"net/http"
"strings"
)
type BaseData struct {
Domain string `json:"domain"`
SiteOwnerName string `json:"siteOwnerName"`
SiteOwnerURL string `json:"siteOwnerURL"`
SiteName string `json:"siteName"`
}
func renderHTML(w http.ResponseWriter, html string, extraData interface{}) {
base, _ := json.Marshal(BaseData{
Domain: s.Domain,
SiteOwnerName: s.SiteOwnerName,
SiteOwnerURL: s.SiteOwnerURL,
SiteName: s.SiteName,
})
extra, _ := json.Marshal(extraData)
w.Header().Set("content-type", "text/html")
fmt.Fprint(w,
strings.ReplaceAll(
strings.ReplaceAll(
html,
"{} // REPLACED WITH SERVER DATA",
fmt.Sprintf("{...%s, ...%s}", string(base), string(extra)),
),
"Satdress", s.SiteName,
),
)
}

View File

@ -5,6 +5,7 @@
<meta charset="utf-8" />
<link rel="icon" type="image/png" href="https://i.imgur.com/4yaPtA2.png" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/style.css" />
<meta
property="og:title"
content="Satdress - Federated Lightning Address Server"
@ -33,196 +34,6 @@
<meta name="twitter:description" content="Satdress is a Federated Lightning Address server allowing you to connect Lightning nodes to Lightning Addresses. Satdress follows the Lightning Address protocol and aims to provide an easy-to-deploy Bridge Server." />
<meta name="twitter:image" content="https://i.imgur.com/PsT2uoR.png" />
</head>
<style>
body {
display: flex;
align-items: center;
background: #f3f3f3;
flex-direction: column;
font-family: 'PT Sans';
justify-content: center;
padding: 60px 20px 40px 20px;
}
.title {
font-size: 40px;
font-weight: 700;
text-align: center;
letter-spacing: 1px;
}
.tagline {
opacity: 0.7;
font-size: 18px;
font-weight: 400;
text-align: center;
letter-spacing: 0.5px;
}
.description {
opacity: 0.7;
font-size: 18px;
font-weight: 400;
max-width: 320px;
text-align: center;
margin-bottom: 40px;
letter-spacing: 0.5px;
}
.card {
max-width: 400px;
background: #fff;
border-radius: 8px;
padding: 30px 40px;
margin: 20px 0 20px;
border: 1px solid #999;
}
.submit-wrapper {
display: flex;
align-items: center;
justify-content: center;
}
.submit {
width: 100%;
color: #fff;
outline: none;
font-size: 16px;
cursor: pointer;
font-weight: 600;
margin-top: 20px;
padding: 12px 8px;
border-radius: 8px;
letter-spacing: 0.5px;
border: 1px solid rgba(86, 46, 249, 0.85);
background-color: rgba(86, 46, 249, 0.75);
}
.submit:hover {
background-color: rgba(86, 46, 249, 0.85);
}
.field {
display: flex;
flex-direction: column;
}
.row {
display: flex;
flex-direction: row;
}
label {
margin: 0;
font-size: 16px;
font-weight: 600;
margin-bottom: 5px;
letter-spacing: 0.5px;
}
.input {
height: 35px;
outline: none;
padding: 0 10px;
font-size: 14px;
border-radius: 5px;
margin-bottom: 25px;
letter-spacing: 0.5px;
border: 1px solid #999;
background-color: #f3f3f3;
}
.suffix {
height: 35px;
display: inline-flex;
padding: 0 10px;
font-size: 16px;
font-weight: 600;
align-items: center;
word-break: break-all;
margin-bottom: 25px;
letter-spacing: 0.5px;
}
select {
height: 35px;
outline: none;
padding: 0 5px;
font-size: 14px;
border-radius: 5px;
margin-bottom: 25px;
letter-spacing: 0.5px;
border: 1px solid #999;
background-color: #f3f3f3;
}
.resources {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
}
.resource-button {
padding: 8px;
color: #8062fb;
font-weight: 400;
margin-bottom: 8px;
border-radius: 7px;
text-decoration: none;
}
.resource-button:hover {
color: #8062fb;
background: rgba(42,0,255,0.1);
}
.owner {
display: flex;
padding-top: 5px;
align-items: center;
flex-direction: row;
justify-content: center;
}
.owner-button {
padding: 8px;
color: #8062fb;
font-weight: 400;
margin-bottom: 8px;
border-radius: 7px;
text-decoration: none;
}
.owner-button:hover {
color: #8062fb;
background: rgba(42,0,255,0.1);
}
.owner-name {
font-weight: 600;
}
@media screen and (max-width: 500px) {
body {
padding: 20px 5px 30px 5px;
}
.title {
font-size: 30px;
}
.card {
padding: 25px;
}
.tagline {
font-size: 16px;
padding: 0 10px;
}
}
</style>
<body>
<main id="main">
<div class="title">Satdress</div>
@ -334,7 +145,7 @@
src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.2/vue.global.prod.min.js"
></script>
<script>
const initial = {} // REPLACED WITH SERVER DATA // {siteOwnerName, siteOwnerURL, siteName, domain}
const initial = {} // REPLACED WITH SERVER DATA //
const Main = {
data() {

42
main.go
View File

@ -1,8 +1,8 @@
package main
import (
"embed"
_ "embed"
"encoding/json"
"fmt"
"net/http"
"os"
@ -32,7 +32,13 @@ var router = mux.NewRouter()
var log = zerolog.New(os.Stderr).Output(zerolog.ConsoleWriter{Out: os.Stderr})
//go:embed index.html
var html string
var indexHTML string
//go:embed grab.html
var grabHTML string
//go:embed static
var static embed.FS
func main() {
err := envconfig.Process("", &s)
@ -52,32 +58,15 @@ func main() {
router.Path("/").HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("content-type", "text/html")
serverData, _ := json.Marshal(struct {
Domain string `json:"domain"`
SiteOwnerName string `json:"siteOwnerName"`
SiteOwnerURL string `json:"siteOwnerURL"`
SiteName string `json:"siteName"`
}{
Domain: s.Domain,
SiteOwnerName: s.SiteOwnerName,
SiteOwnerURL: s.SiteOwnerURL,
SiteName: s.SiteName,
})
fmt.Fprint(w,
strings.ReplaceAll(
strings.ReplaceAll(
html, "{} // REPLACED WITH SERVER DATA", string(serverData),
),
"Satdress", s.SiteName,
),
)
renderHTML(w, indexHTML, map[string]interface{}{})
},
)
router.PathPrefix("/static/").Handler(http.FileServer(http.FS(static)))
router.Path("/grab").HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
pin, err := SaveName(r.FormValue("name"), &Params{
pin, inv, err := SaveName(r.FormValue("name"), &Params{
Kind: r.FormValue("kind"),
Host: r.FormValue("host"),
Key: r.FormValue("key"),
@ -90,9 +79,10 @@ func main() {
return
}
fmt.Fprintf(w,
"name saved! this is your secret pin key for this name: %s",
pin)
renderHTML(w, grabHTML, struct {
PIN string `json:"pin"`
Invoice string `json:"invoice"`
}{pin, inv})
},
)

188
static/style.css Normal file
View File

@ -0,0 +1,188 @@
body {
display: flex;
align-items: center;
background: #f3f3f3;
flex-direction: column;
font-family: 'PT Sans';
justify-content: center;
padding: 60px 20px 40px 20px;
}
.title {
font-size: 40px;
font-weight: 700;
text-align: center;
letter-spacing: 1px;
}
.tagline {
opacity: 0.7;
font-size: 18px;
font-weight: 400;
text-align: center;
letter-spacing: 0.5px;
}
.description {
opacity: 0.7;
font-size: 18px;
font-weight: 400;
max-width: 320px;
text-align: center;
margin-bottom: 40px;
letter-spacing: 0.5px;
}
.card {
max-width: 400px;
background: #fff;
border-radius: 8px;
padding: 30px 40px;
margin: 20px 0 20px;
border: 1px solid #999;
}
.submit-wrapper {
display: flex;
align-items: center;
justify-content: center;
}
.submit {
width: 100%;
color: #fff;
outline: none;
font-size: 16px;
cursor: pointer;
font-weight: 600;
margin-top: 20px;
padding: 12px 8px;
border-radius: 8px;
letter-spacing: 0.5px;
border: 1px solid rgba(86, 46, 249, 0.85);
background-color: rgba(86, 46, 249, 0.75);
}
.submit:hover {
background-color: rgba(86, 46, 249, 0.85);
}
.field {
display: flex;
flex-direction: column;
}
.row {
display: flex;
flex-direction: row;
}
label {
margin: 0;
font-size: 16px;
font-weight: 600;
margin-bottom: 5px;
letter-spacing: 0.5px;
}
.input {
height: 35px;
outline: none;
padding: 0 10px;
font-size: 14px;
border-radius: 5px;
margin-bottom: 25px;
letter-spacing: 0.5px;
border: 1px solid #999;
background-color: #f3f3f3;
}
.suffix {
height: 35px;
display: inline-flex;
padding: 0 10px;
font-size: 16px;
font-weight: 600;
align-items: center;
word-break: break-all;
margin-bottom: 25px;
letter-spacing: 0.5px;
}
select {
height: 35px;
outline: none;
padding: 0 5px;
font-size: 14px;
border-radius: 5px;
margin-bottom: 25px;
letter-spacing: 0.5px;
border: 1px solid #999;
background-color: #f3f3f3;
}
.resources {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
}
.resource-button {
padding: 8px;
color: #8062fb;
font-weight: 400;
margin-bottom: 8px;
border-radius: 7px;
text-decoration: none;
}
.resource-button:hover {
color: #8062fb;
background: rgba(42,0,255,0.1);
}
.owner {
display: flex;
padding-top: 5px;
align-items: center;
flex-direction: row;
justify-content: center;
}
.owner-button {
padding: 8px;
color: #8062fb;
font-weight: 400;
margin-bottom: 8px;
border-radius: 7px;
text-decoration: none;
}
.owner-button:hover {
color: #8062fb;
background: rgba(42,0,255,0.1);
}
.owner-name {
font-weight: 600;
}
@media screen and (max-width: 500px) {
body {
padding: 20px 5px 30px 5px;
}
.title {
font-size: 30px;
}
.card {
padding: 25px;
}
.tagline {
font-size: 16px;
padding: 0 10px;
}
}