Fixed auth and cleaned up docker

This commit is contained in:
Atridad Lahiji 2024-06-27 21:51:00 -06:00
parent 96671ff7a6
commit 9a579912cd
No known key found for this signature in database
12 changed files with 103 additions and 36 deletions

View file

@ -2,9 +2,13 @@
# This file should not be committed to the repository
# The actual .env file should contain the following variables
# The database URL should be in the format postgres://username:password@host:port/database
DATABASE_URL=
# The database credentials
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_PASSWORD=postgres
POSTGRES_USER=postgres
POSTGRES_DB=db
# The secret key used to sign the JWT tokens
AUTH_SECRET=
AUTH_SECRET=super-duper-secret
# If you want to run the app in development mode, set this to true
DEVMODE=true

17
api/signout.go Normal file
View file

@ -0,0 +1,17 @@
package api
import (
"net/http"
"pollo/lib"
"github.com/labstack/echo/v4"
)
func SignOutUserHandler(c echo.Context) error {
// Clear the session cookie
lib.ClearSessionCookie(c.Response().Writer, "session_id")
// Proceed with login success logic
c.Response().Header().Set("HX-Redirect", "/")
return c.NoContent(http.StatusOK)
}

View file

@ -13,15 +13,28 @@ services:
networks:
- proxy_default
environment:
- AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
- AWS_ENDPOINT_URL_S3=$AWS_ENDPOINT_URL_S3
- AWS_REGION=$AWS_REGION
- AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
- BUCKET_NAME=$BUCKET_NAME
- CLERK_SECRET_KEY=$CLERK_SECRET_KEY
- CLERK_WEBHOOK_SECRET=$CLERK_WEBHOOK_SECRET
- RESEND_API_KEY=$RESEND_API_KEY
- STRIPE_SECRET_KEY=$STRIPE_SECRET_KEY
- POSTGRES_HOST=$POSTGRES_HOST
- POSTGRES_PORT=$POSTGRES_PORT
- POSTGRES_DB=$POSTGRES_DB
- POSTGRES_USER=$POSTGRES_USER
- POSTGRES_PASSWORD=$POSTGRES_PASSWORD
- AUTH_SECRET=$AUTH_SECRET
- DEVMODE=$DEVMODE
db:
image: 'postgres:latest'
pull_policy: build
environment:
- POSTGRES_DB=$POSTGRES_DB
- POSTGRES_PASSWORD=$POSTGRES_PASSWORD
- POSTGRES_USER=$POSTGRES_USER
ports:
- 5432:5432
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- proxy_default
restart: on-failure:3
networks:
proxy_default:

View file

@ -2,6 +2,7 @@ package lib
import (
"context"
"fmt"
"github.com/jackc/pgx/v4/pgxpool"
)
@ -9,7 +10,10 @@ import (
var dbPool *pgxpool.Pool
// Initializes the global database connection pool.
func InitializeDBPool(connString string) error {
func InitializeDBPool(host, user, password, dbname string, port int) error {
// Construct the connection string using the provided parameters
connString := fmt.Sprintf("postgres://%s:%s@%s:%d/%s", user, password, host, port, dbname)
var err error
dbPool, err = pgxpool.Connect(context.Background(), connString)
if err != nil {

View file

@ -48,6 +48,19 @@ func GetSessionCookie(r *http.Request, name string) (string, error) {
return cookie.Value, nil
}
// ClearSessionCookie clears the session cookie from the client's browser
func ClearSessionCookie(w http.ResponseWriter, name string) {
http.SetCookie(w, &http.Cookie{
Name: name,
Value: "",
Path: "/",
HttpOnly: true,
Secure: os.Getenv("DEVMODE") != "true",
SameSite: http.SameSiteStrictMode,
MaxAge: -1, // Set MaxAge to -1 to delete the cookie immediately.
})
}
// Checks if the user is signed in by checking the session cookie
func IsSignedIn(c echo.Context) bool {
_, err := GetSessionCookie(c.Request(), "session_id")

19
main.go
View file

@ -7,6 +7,7 @@ import (
"log"
"net/http"
"os"
"strconv"
"pollo/api"
"pollo/api/webhooks"
@ -28,12 +29,21 @@ func main() {
}
// Initialize the database connection pool
connString := os.Getenv("DATABASE_URL")
if connString == "" {
log.Fatal("DATABASE_URL environment variable is not set.")
postgresHost := os.Getenv("POSTGRES_HOST")
postgresPort := os.Getenv("POSTGRES_PORT")
postgresUser := os.Getenv("POSTGRES_USER")
postgresPassword := os.Getenv("POSTGRES_PASSWORD")
postgresDB := os.Getenv("POSTGRES_DB")
if postgresHost == "" || postgresPort == "" || postgresUser == "" || postgresPassword == "" || postgresDB == "" {
log.Fatal("Darta environment variable is not set.")
}
if err := lib.InitializeDBPool(connString); err != nil {
portNumber, err := strconv.Atoi(postgresPort)
if err != nil {
log.Fatalf("Invalid database port: %v", err)
}
if err := lib.InitializeDBPool(postgresHost, postgresUser, postgresPassword, postgresDB, portNumber); err != nil {
log.Fatalf("Failed to initialize DB pool: %v", err)
}
@ -80,6 +90,7 @@ func main() {
// Public routes
apiGroup.POST("/register", api.RegisterUserHandler)
apiGroup.POST("/signin", api.SignInUserHandler)
apiGroup.POST("/signout", api.SignOutUserHandler)
// Webhook Routes:
webhookGroup := e.Group("/webhook")

View file

@ -7,10 +7,13 @@ import (
)
type DashboardProps struct {
IsLoggedIn bool
}
func Dashboard(c echo.Context) error {
props := HomeProps{}
props := DashboardProps{
IsLoggedIn: lib.IsSignedIn(c),
}
// Specify the partials used by this page
partials := []string{"header"}

View file

@ -1,9 +1,9 @@
{{define "title"}}
Pollo // Root
Pollo // Dashboard
{{end}}
{{define "headercontent"}}
Pollo // Root
Pollo // Dashboard
{{end}}
{{define "head"}}

View file

@ -9,7 +9,7 @@
<a class="btn btn-primary btn-outline mx-2" href="/dashboard">
Dashboard
</a>
<a class="btn btn-primary" href="/signout">
<a class="btn btn-primary" hx-post="/api/signout" hx-redirect="/">
Sign Out
</a>
{{else}}

View file

@ -1,9 +1,9 @@
{{define "title"}}
Pollo // Root
Pollo // Register
{{end}}
{{define "headercontent"}}
Pollo // Root
Pollo // Register
{{end}}
{{define "head"}}
@ -12,11 +12,12 @@ Pollo // Root
{{define "main"}}
<div id="auth-form">
<h2>Register</h2>
<form hx-post="/api/register" hx-swap="none">
<input type="email" name="email" placeholder="Email" required>
<input type="password" name="password" placeholder="Password" required>
<button type="submit">Register</button>
<h2 class="text-4xl">Register</h2>
<br>
<form class="flex flex-col gap-2" hx-post="/api/register" hx-swap="none">
<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>
</form>
<p>Already have an account? <a href="/signin">Sign In</a></p>
</div>

View file

@ -1,9 +1,9 @@
{{define "title"}}
Pollo // Root
Pollo // Sign In
{{end}}
{{define "headercontent"}}
Pollo // Root
Pollo // Sign In
{{end}}
{{define "head"}}
@ -12,11 +12,12 @@ Pollo // Root
{{define "main"}}
<div id="auth-form" hx-ext="response-targets">
<h2>Sign In</h2>
<form hx-post="/api/signin" hx-target-4*="#error-message">
<input type="email" name="email" placeholder="Email" required>
<input type="password" name="password" placeholder="Password" required>
<button type="submit">Sign In</button>
<h2 class="text-4xl">Sign In</h2>
<br>
<form class="flex flex-col gap-2" hx-post="/api/signin" hx-target-4*="#error-message">
<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">Sign In</button>
</form>
<div id="error-message"style="color: red;"></div>
<p>Don't have an account? <a href="/register">Register</a></p>

File diff suppressed because one or more lines are too long