hmn/src/website/api.go

106 lines
2.3 KiB
Go
Raw Permalink Normal View History

2021-11-25 03:59:51 +00:00
package website
import (
2024-05-07 17:12:52 +00:00
"encoding/json"
2021-11-25 03:59:51 +00:00
"errors"
2024-05-07 17:12:52 +00:00
"io"
2021-11-25 03:59:51 +00:00
"net/http"
2024-05-07 17:12:52 +00:00
"strings"
2021-11-25 03:59:51 +00:00
"git.handmade.network/hmn/hmn/src/db"
"git.handmade.network/hmn/hmn/src/models"
"git.handmade.network/hmn/hmn/src/oops"
2024-05-07 17:12:52 +00:00
"git.handmade.network/hmn/hmn/src/utils"
2021-11-25 03:59:51 +00:00
)
func APICheckUsername(c *RequestContext) ResponseData {
c.Req.ParseForm()
usernameArgs, hasUsername := c.Req.Form["username"]
found := false
canonicalUsername := ""
if hasUsername {
requestedUsername := usernameArgs[0]
found = true
c.Perf.StartBlock("SQL", "Fetch user")
user, err := db.QueryOne[models.User](c, c.Conn,
2021-11-25 03:59:51 +00:00
`
SELECT $columns
2021-11-25 03:59:51 +00:00
FROM
2022-05-07 13:11:05 +00:00
hmn_user
2021-11-25 03:59:51 +00:00
WHERE
2022-05-07 13:11:05 +00:00
LOWER(hmn_user.username) = LOWER($1)
2021-11-25 03:59:51 +00:00
AND status = ANY ($2)
`,
requestedUsername,
[]models.UserStatus{models.UserStatusConfirmed, models.UserStatusApproved},
)
c.Perf.EndBlock()
if err != nil {
if errors.Is(err, db.NotFound) {
found = false
} else {
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user: %s", requestedUsername))
}
} else {
canonicalUsername = user.Username
2021-11-25 03:59:51 +00:00
}
}
var res ResponseData
addCORSHeaders(c, &res)
2021-11-25 03:59:51 +00:00
if found {
2024-05-07 17:12:52 +00:00
res.WriteJson(map[string]any{
"found": true,
"canonical": canonicalUsername,
}, nil)
2021-11-25 03:59:51 +00:00
} else {
2024-05-07 17:12:52 +00:00
res.WriteJson(map[string]any{
"found": false,
}, nil)
2021-11-25 03:59:51 +00:00
}
return res
}
2024-05-07 17:12:52 +00:00
func APINewsletterSignup(c *RequestContext) ResponseData {
bodyBytes := utils.Must1(io.ReadAll(c.Req.Body))
type Input struct {
Email string `json:"email"`
}
var input Input
err := json.Unmarshal(bodyBytes, &input)
if err != nil {
return c.ErrorResponse(http.StatusBadRequest, err)
}
var res ResponseData
sanitized := input.Email
sanitized = strings.TrimSpace(sanitized)
sanitized = strings.ToLower(sanitized)
if len(sanitized) > 200 {
res.StatusCode = http.StatusBadRequest
return res
}
if !strings.Contains(sanitized, "@") {
res.StatusCode = http.StatusBadRequest
res.WriteJson(map[string]any{
"error": "bad email",
}, nil)
return res
}
_, err = c.Conn.Exec(c,
`
INSERT INTO newsletter_emails (email) VALUES ($1)
ON CONFLICT DO NOTHING
`,
sanitized,
)
if err != nil {
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to save email into database"))
}
res.WriteHeader(http.StatusNoContent)
return res
}