2024-09-13 20:06:00 +00:00
|
|
|
package cognito_auth
|
2024-09-13 19:39:02 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"html/template"
|
|
|
|
"net/http"
|
|
|
|
"path/filepath"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Handlers struct {
|
|
|
|
Client *Client
|
|
|
|
Templates *template.Template
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewHandlers(client *Client, templateDir string) (*Handlers, error) {
|
|
|
|
templates, err := template.ParseGlob(filepath.Join(templateDir, "*.html"))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &Handlers{
|
|
|
|
Client: client,
|
|
|
|
Templates: templates,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handlers) RenderTemplate(w http.ResponseWriter, tmpl string, data interface{}) {
|
|
|
|
err := h.Templates.ExecuteTemplate(w, tmpl+".html", data)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type JSONResponse struct {
|
|
|
|
Message string `json:"message,omitempty"`
|
|
|
|
Data interface{} `json:"data,omitempty"`
|
|
|
|
Error string `json:"error,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handlers) SignUpHTMLHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if r.Method == http.MethodGet {
|
|
|
|
// Render the sign-up form
|
|
|
|
h.RenderTemplate(w, "signup", nil)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if r.Method == http.MethodPost {
|
|
|
|
// Parse form data
|
|
|
|
if err := r.ParseForm(); err != nil {
|
|
|
|
h.RenderTemplate(w, "signup", map[string]string{"Error": "Invalid form data"})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
username := r.FormValue("username")
|
|
|
|
email := r.FormValue("email")
|
|
|
|
password := r.FormValue("password")
|
|
|
|
|
|
|
|
// Sign up the user
|
|
|
|
err := h.Client.SignUp(SignUpRequest{
|
|
|
|
Context: r.Context(),
|
|
|
|
Username: username,
|
|
|
|
Password: password,
|
|
|
|
Email: email,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
h.RenderTemplate(w, "signup", map[string]string{"Error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Redirect to confirmation page or show success message
|
|
|
|
http.Redirect(w, r, "/confirm_signup", http.StatusSeeOther)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handlers) SignUpJSONHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if r.Method != http.MethodPost {
|
|
|
|
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var req struct {
|
|
|
|
Username string `json:"username"`
|
|
|
|
Email string `json:"email"`
|
|
|
|
Password string `json:"password"`
|
|
|
|
}
|
|
|
|
|
|
|
|
decoder := json.NewDecoder(r.Body)
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
http.Error(w, "Bad Request: "+err.Error(), http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
err := h.Client.SignUp(SignUpRequest{
|
|
|
|
Username: req.Username,
|
|
|
|
Password: req.Password,
|
|
|
|
Email: req.Email,
|
|
|
|
Context: r.Context(),
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
response := JSONResponse{Error: err.Error()}
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
json.NewEncoder(w).Encode(response)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
response := JSONResponse{Message: "User signed up successfully. Please confirm your email."}
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
json.NewEncoder(w).Encode(response)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handlers) ConfirmSignUpHTMLHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if r.Method == http.MethodGet {
|
|
|
|
// Render the confirm sign-up form
|
|
|
|
h.RenderTemplate(w, "confirm_signup", nil)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if r.Method == http.MethodPost {
|
|
|
|
// Parse form data
|
|
|
|
if err := r.ParseForm(); err != nil {
|
|
|
|
h.RenderTemplate(w, "confirm_signup", map[string]string{"Error": "Invalid form data"})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
username := r.FormValue("username")
|
|
|
|
confirmationCode := r.FormValue("confirmation_code")
|
|
|
|
|
|
|
|
// Confirm sign-up
|
|
|
|
err := h.Client.ConfirmSignUp(ConfirmSignUpRequest{
|
|
|
|
Context: r.Context(),
|
|
|
|
Username: username,
|
|
|
|
ConfirmationCode: confirmationCode,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
h.RenderTemplate(w, "confirm_signup", map[string]string{"Error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Redirect to sign-in page or show success message
|
|
|
|
http.Redirect(w, r, "/signin", http.StatusSeeOther)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handlers) ConfirmSignUpJSONHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if r.Method != http.MethodPost {
|
|
|
|
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var req struct {
|
|
|
|
Username string `json:"username"`
|
|
|
|
ConfirmationCode string `json:"confirmation_code"`
|
|
|
|
}
|
|
|
|
|
|
|
|
decoder := json.NewDecoder(r.Body)
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
http.Error(w, "Bad Request: "+err.Error(), http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
err := h.Client.ConfirmSignUp(ConfirmSignUpRequest{
|
|
|
|
Context: r.Context(),
|
|
|
|
Username: req.Username,
|
|
|
|
ConfirmationCode: req.ConfirmationCode,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
response := JSONResponse{Error: err.Error()}
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
json.NewEncoder(w).Encode(response)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
response := JSONResponse{Message: "User confirmed successfully."}
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
json.NewEncoder(w).Encode(response)
|
|
|
|
}
|
|
|
|
|
|
|
|
// SignInHTMLHandler handles HTML sign-in requests
|
|
|
|
func (h *Handlers) SignInHTMLHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if r.Method == http.MethodGet {
|
|
|
|
// Render the sign-in form
|
|
|
|
h.RenderTemplate(w, "signin", nil)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if r.Method == http.MethodPost {
|
|
|
|
// Parse form data
|
|
|
|
if err := r.ParseForm(); err != nil {
|
|
|
|
h.RenderTemplate(w, "signin", map[string]string{"Error": "Invalid form data"})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
username := r.FormValue("username")
|
|
|
|
password := r.FormValue("password")
|
|
|
|
|
|
|
|
// Sign in the user
|
|
|
|
authResult, err := h.Client.SignIn(r.Context(), username, password)
|
|
|
|
if err != nil {
|
|
|
|
h.RenderTemplate(w, "signin", map[string]string{"Error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Render a success page or display tokens
|
|
|
|
h.RenderTemplate(w, "signin_success", authResult)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handlers) SignInJSONHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if r.Method != http.MethodPost {
|
|
|
|
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var req struct {
|
|
|
|
Username string `json:"username"`
|
|
|
|
Password string `json:"password"`
|
|
|
|
}
|
|
|
|
|
|
|
|
decoder := json.NewDecoder(r.Body)
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
http.Error(w, "Bad Request: "+err.Error(), http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
authResult, err := h.Client.SignIn(r.Context(), req.Username, req.Password)
|
|
|
|
if err != nil {
|
|
|
|
response := JSONResponse{Error: err.Error()}
|
|
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
|
|
json.NewEncoder(w).Encode(response)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
response := JSONResponse{Data: authResult}
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
json.NewEncoder(w).Encode(response)
|
|
|
|
}
|