Auth fixes

This commit is contained in:
Atridad Lahiji 2024-06-28 09:11:03 -06:00
parent de07026042
commit 7978dd131a
No known key found for this signature in database
8 changed files with 52 additions and 13 deletions

View file

@ -8,15 +8,25 @@ import (
)
func RegisterUserHandler(c echo.Context) error {
name := c.FormValue("name")
email := c.FormValue("email")
password := c.FormValue("password")
// Check if the email already exists
existingUser, err := lib.GetUserByEmail(lib.GetDBPool(), email)
if err == nil && existingUser != nil {
// User with the given email already exists
errorMessage := `<div id="error-message" style="color: red;">An account with this email already exists!</div>`
return c.HTML(http.StatusBadRequest, errorMessage)
}
// Proceed with the existing registration logic
hashedPassword, err := lib.HashPassword(password)
if err != nil {
return c.JSON(http.StatusInternalServerError, "Failed to hash password")
}
user := lib.User{Email: email, Password: hashedPassword}
user := lib.User{Name: name, Email: email, Password: hashedPassword}
if err := lib.SaveUser(lib.GetDBPool(), &user); err != nil {
return c.JSON(http.StatusInternalServerError, "Failed to save user")
}
@ -30,6 +40,7 @@ func RegisterUserHandler(c echo.Context) error {
lib.SetSessionCookie(c.Response().Writer, "session", lib.SessionData{
SessionID: sessionID,
UserID: user.ID,
Name: user.Name,
Email: user.Email,
Roles: []string{"user"},
})

View file

@ -12,6 +12,7 @@ import (
type User struct {
ID string
Name string
Email string
Password string
}
@ -43,6 +44,21 @@ func GetUserByEmail(dbPool *pgxpool.Pool, email string) (*User, error) {
return &user, nil
}
// GetUserByID fetches a user by ID from the database.
func GetUserByID(dbPool *pgxpool.Pool, id string) (*User, error) {
if dbPool == nil {
return nil, errors.New("database connection pool is not initialized")
}
var user User
// Ensure the ID is being scanned as a string.
err := dbPool.QueryRow(context.Background(), "SELECT id::text, email, password FROM users WHERE id = $1", id).Scan(&user.ID, &user.Email, &user.Password)
if err != nil {
return nil, err
}
return &user, nil
}
// SaveUser saves a new user to the database.
func SaveUser(dbPool *pgxpool.Pool, user *User) error {
if dbPool == nil {

View file

@ -26,6 +26,7 @@ func InitializeSchema(dbPool *pgxpool.Pool) error {
const schemaSQL = `
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL
);`

View file

@ -21,6 +21,7 @@ import (
type SessionData struct {
SessionID string `json:"sessionID"`
UserID string `json:"userId"`
Name string `json:"name"`
Email string `json:"email"`
Roles []string `json:"roles"`
}
@ -154,12 +155,21 @@ func ClearSessionCookie(w http.ResponseWriter, name string) {
// Checks if the user is signed in by checking the session cookie
func IsSignedIn(c echo.Context) bool {
_, err := GetSessionCookie(c.Request(), "session")
sessionData, err := GetSessionCookie(c.Request(), "session")
if err != nil {
// Log the error for debugging purposes
log.Printf("Error retrieving session cookie: %v", err)
return false
}
return err == nil
// Validate the session data by checking if the user exists in the database
user, err := GetUserByID(GetDBPool(), sessionData.UserID)
if err != nil || user == nil {
log.Printf("Session refers to a non-existent user: %v", err)
ClearSessionCookie(c.Response().Writer, "session")
return false
}
return true
}
// GenerateRandomBytes returns securely generated random bytes.

View file

@ -8,7 +8,7 @@ import (
type DashboardProps struct {
IsLoggedIn bool
Email string
Name string
}
func Dashboard(c echo.Context) error {
@ -19,7 +19,7 @@ func Dashboard(c echo.Context) error {
props := DashboardProps{
IsLoggedIn: lib.IsSignedIn(c),
Email: currentSession.Email,
Name: currentSession.Name,
}
// Specify the partials used by this page

View file

@ -13,7 +13,7 @@ Pollo // Dashboard
{{define "main"}}
<div class="flex flex-col items-center justify-center gap-8">
<h1 class="flex flex-row flex-wrap text-center justify-center items-center gap-1 text-4xl font-bold">
Hi, {{.Email}}!
Hi, {{.Name}}!
</h1>
<label htmlFor="new-room-modal" class="btn btn-primary">

View file

@ -11,19 +11,21 @@ Pollo // Register
{{end}}
{{define "main"}}
<div id="auth-form">
<div id="auth-form" hx-ext="response-targets">
<h2 class="text-4xl">Register</h2>
<br>
<form class="flex flex-col gap-2" hx-post="/api/register" hx-swap="none">
<form class="flex flex-col gap-2" hx-post="/api/register" hx-target-4*="#error-message">
<input class="input input-bordered input-primary w-full max-w-xs" type="text" name="name" placeholder="Name" required>
<input class="input input-bordered input-primary w-full max-w-xs" type="email" name="email" placeholder="Email" required>
<input class="input input-bordered input-primary w-full max-w-xs" type="password" name="password" placeholder="Password" required>
<button class="btn btn-primary" type="submit">Register</button>
<button class="btn btn-primary" type="submit">Sign In</button>
</form>
<p>Already have an account? <a href="/signin">Sign In</a></p>
<div id="error-message"style="color: red;"></div>
<p>Already have an account? <a href="/signin">Register</a></p>
</div>
{{end}}
{{define "foot"}}
<script src="/public/js/htmx.base.js"></script>
<script src="/public/js/htmx.sse.js"></script>
<script src="/public/js/htmx.targets.js"></script>
{{end}}

View file

@ -26,6 +26,5 @@ Pollo // Sign In
{{define "foot"}}
<script src="/public/js/htmx.base.js"></script>
<script src="/public/js/htmx.sse.js"></script>
<script src="/public/js/htmx.targets.js"></script>
{{end}}