186 lines
4.3 KiB
Go
186 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"html/template"
|
|
"log"
|
|
"net/mail"
|
|
"os"
|
|
"strings"
|
|
|
|
_ "leadsform/migrations"
|
|
|
|
altcha "github.com/altcha-org/altcha-lib-go"
|
|
"github.com/pocketbase/pocketbase"
|
|
"github.com/pocketbase/pocketbase/core"
|
|
"github.com/pocketbase/pocketbase/plugins/migratecmd"
|
|
"github.com/pocketbase/pocketbase/tools/mailer"
|
|
)
|
|
|
|
var altchaHMACKey = os.Getenv("ALTCHA_HMAC_KEY")
|
|
|
|
func mapToString(m map[string]string) string {
|
|
t, _ := template.New("body").Parse("Details \n\n{{.}}")
|
|
|
|
tr, _ := template.New("tr").Parse("{{.Key}} : {{.Value}} \n")
|
|
|
|
trString := ""
|
|
|
|
type TR struct {
|
|
Key string
|
|
Value string
|
|
}
|
|
for k, v := range m {
|
|
data := TR{
|
|
Key: k,
|
|
Value: v,
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
_ = tr.Execute(&buf, data)
|
|
|
|
trString = trString + buf.String()
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
_ = t.Execute(&buf, trString)
|
|
|
|
return buf.String()
|
|
}
|
|
|
|
func main() {
|
|
app := pocketbase.New()
|
|
|
|
app.OnServe().BindFunc(func(se *core.ServeEvent) error {
|
|
se.Router.GET("/altcha", func(e *core.RequestEvent) error {
|
|
orginH := e.Request.Header["Origin"]
|
|
if len(orginH) != 1 {
|
|
return e.Error(400, "Origin header is required", nil)
|
|
}
|
|
|
|
origin := orginH[0]
|
|
|
|
website, err := app.FindFirstRecordByData("websites", "url", origin)
|
|
if err != nil || website == nil {
|
|
return e.Error(400, "Invalid origin", nil)
|
|
}
|
|
|
|
challenge, err := altcha.CreateChallenge(altcha.ChallengeOptions{
|
|
HMACKey: altchaHMACKey,
|
|
MaxNumber: 50000,
|
|
})
|
|
if err != nil {
|
|
return e.Error(400, "Unable to create challenge", nil)
|
|
}
|
|
|
|
return e.JSON(200, challenge)
|
|
})
|
|
|
|
se.Router.POST("/lead", func(e *core.RequestEvent) error {
|
|
orginH := e.Request.Header["Origin"]
|
|
|
|
if len(orginH) != 1 {
|
|
return e.Error(400, "Origin header is required", nil)
|
|
}
|
|
|
|
origin := orginH[0]
|
|
|
|
website, err := app.FindFirstRecordByData("websites", "url", origin)
|
|
if err != nil {
|
|
return e.Error(400, "Invalid origin", nil)
|
|
}
|
|
info, err := e.RequestInfo()
|
|
|
|
if err != nil || info.Body == nil {
|
|
return e.Error(400, "Unable to parse request", err)
|
|
}
|
|
|
|
payload := info.Body["altcha"].(string)
|
|
|
|
if payload == "" {
|
|
return e.Error(400, "Altcha payload is required", nil)
|
|
}
|
|
|
|
formData := map[string][]string{}
|
|
|
|
for k, v := range info.Body {
|
|
formData[k] = []string{v.(string)}
|
|
}
|
|
|
|
fmt.Println(payload)
|
|
fmt.Println(altchaHMACKey)
|
|
|
|
verified, err := altcha.VerifySolution(payload, altchaHMACKey, true)
|
|
if err != nil || !verified {
|
|
return e.Error(400, "Invalid Altcha payload", nil)
|
|
}
|
|
|
|
collection, err := app.FindCollectionByNameOrId("leads")
|
|
if err != nil {
|
|
app.Logger().Error("Unable to find collection ~ leads", nil)
|
|
}
|
|
|
|
record := core.NewRecord(collection)
|
|
|
|
delete(info.Body, "altcha")
|
|
data, err := json.Marshal(info.Body)
|
|
if err != nil {
|
|
app.Logger().Warn("Unable to marshal data", nil)
|
|
return e.Error(400, "Unable to marshal data", nil)
|
|
}
|
|
record.Set("data", data)
|
|
record.Set("website", website.Id)
|
|
|
|
if err := app.Save(record); err != nil {
|
|
return e.Error(500, "Unable to save record", err)
|
|
}
|
|
|
|
return e.String(201, "Submitted")
|
|
})
|
|
|
|
return se.Next()
|
|
})
|
|
|
|
app.OnRecordAfterCreateSuccess("leads").BindFunc(func(e *core.RecordEvent) error {
|
|
go func() {
|
|
e.App.ExpandRecord(e.Record, []string{"website"}, nil)
|
|
|
|
website := e.Record.ExpandedOne("website")
|
|
|
|
subject := fmt.Sprintf("New lead from %s", website.GetString("url"))
|
|
|
|
data := make(map[string]string)
|
|
|
|
_ = json.Unmarshal([]byte(e.Record.GetString("data")), &data)
|
|
|
|
message := &mailer.Message{
|
|
From: mail.Address{
|
|
Address: e.App.Settings().Meta.SenderAddress,
|
|
Name: e.App.Settings().Meta.SenderName,
|
|
},
|
|
To: []mail.Address{{Address: website.GetString("notification_email")}},
|
|
Subject: subject,
|
|
Text: mapToString(data),
|
|
}
|
|
|
|
_ = e.App.NewMailClient().Send(message)
|
|
}()
|
|
|
|
return e.Next()
|
|
})
|
|
|
|
// loosely check if it was executed using "go run"
|
|
isGoRun := strings.HasPrefix(os.Args[0], os.TempDir())
|
|
|
|
migratecmd.MustRegister(app, app.RootCmd, migratecmd.Config{
|
|
// enable auto creation of migration files when making collection changes in the Dashboard
|
|
// (the isGoRun check is to enable it only during development)
|
|
Automigrate: isGoRun,
|
|
})
|
|
|
|
if err := app.Start(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|