Skip to content

Commit 7c0839c

Browse files
author
John Rogers
committed
working portal page with name request
1 parent 5feacca commit 7c0839c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1131
-1176
lines changed

.clinerules

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Project Intelligence
2+
3+
## Key Patterns
4+
5+
* Using Go + React (with Typescript) for full-stack development.
6+
* Integrating Ovenplayer and Mirotalk for live streaming.
7+
* Securing the application with Traefik and Let's Encrypt.
8+
9+
## Tool Usage Patterns
10+
11+
* Using `write_to_file` to create and update memory bank files.
12+
* Using `replace_in_file` to modify existing files (but it seems to be failing, so using `write_to_file` instead).
13+
14+
## Challenges
15+
16+
* `replace_in_file` tool is not working as expected.
17+
18+
## Decisions
19+
20+
* Using `write_to_file` as a workaround for `replace_in_file`.

.env

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
PORT=3000

admin_login.html

-27
This file was deleted.

backend/Dockerfile

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
FROM golang:1.24-alpine AS builder
2+
3+
WORKDIR /app
4+
5+
COPY go.mod ./
6+
COPY go.sum ./
7+
RUN go mod download
8+
COPY main.go ./
9+
RUN go mod tidy
10+
RUN apk add --no-cache sqlite gcc musl-dev
11+
RUN sqlite3 colourstream.db ".databases"
12+
13+
ENV CGO_ENABLED=1
14+
RUN go build -o main .
15+
16+
FROM alpine:latest
17+
18+
WORKDIR /app
19+
20+
COPY --from=builder /app/main .
21+
COPY --from=builder /app/colourstream.db .
22+
23+
EXPOSE 8000
24+
25+
CMD ["./main"]

backend/go.mod

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module colourstream/backend
2+
3+
go 1.24.0
4+
5+
require (
6+
github.com/gorilla/mux v1.8.1
7+
github.com/mattn/go-sqlite3 v1.14.24
8+
)

backend/go.sum

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
2+
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
3+
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
4+
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=

backend/main.go

+173
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
package main
2+
3+
import (
4+
"database/sql"
5+
"encoding/json"
6+
"fmt"
7+
"log"
8+
"math/rand"
9+
"net/http"
10+
"os"
11+
"strconv"
12+
"time"
13+
14+
_ "github.com/mattn/go-sqlite3"
15+
)
16+
17+
var db *sql.DB
18+
19+
type Credentials struct {
20+
Username string `json:"username"`
21+
Password string `json:"password"`
22+
}
23+
24+
type Room struct {
25+
ID int `json:"id"`
26+
Name string `json:"name"`
27+
}
28+
29+
func main() {
30+
// Initialize SQLite database
31+
db, err := sql.Open("sqlite3", "./colourstream.db")
32+
if err != nil {
33+
log.Fatal(err)
34+
}
35+
defer db.Close()
36+
37+
// Create rooms table if it doesn't exist
38+
_, err = db.Exec(`
39+
CREATE TABLE IF NOT EXISTS rooms (
40+
id INTEGER PRIMARY KEY AUTOINCREMENT,
41+
name TEXT NOT NULL
42+
)
43+
`)
44+
if err != nil {
45+
log.Fatal(err)
46+
}
47+
48+
// Create users table if it doesn't exist
49+
_, err = db.Exec(`
50+
CREATE TABLE IF NOT EXISTS users (
51+
id INTEGER PRIMARY KEY AUTOINCREMENT,
52+
username TEXT NOT NULL,
53+
password TEXT NOT NULL
54+
)
55+
`)
56+
if err != nil {
57+
log.Fatal(err)
58+
}
59+
60+
// Create admin user if it doesn't exist
61+
var count int
62+
err = db.QueryRow("SELECT COUNT(*) FROM users WHERE username = 'admin'").Scan(&count)
63+
if err != nil {
64+
log.Fatal(err)
65+
}
66+
if count == 0 {
67+
_, err = db.Exec(`
68+
INSERT INTO users (username, password) VALUES ('admin', 'password')
69+
`)
70+
if err != nil {
71+
log.Fatal(err)
72+
}
73+
}
74+
75+
// API endpoints
76+
http.HandleFunc("/admin/auth", adminAuthHandler)
77+
http.HandleFunc("/rooms/create", roomCreateHandler)
78+
http.HandleFunc("/rooms/delete", roomDeleteHandler)
79+
http.HandleFunc("/rooms/list", roomListHandler)
80+
81+
// Start server
82+
port := os.Getenv("PORT")
83+
if port == "" {
84+
port = "8080"
85+
}
86+
fmt.Println("Server listening on port " + port)
87+
log.Fatal(http.ListenAndServe(":"+port, nil))
88+
}
89+
90+
func adminAuthHandler(w http.ResponseWriter, r *http.Request) {
91+
var creds Credentials
92+
err := json.NewDecoder(r.Body).Decode(&creds)
93+
if err != nil {
94+
w.WriteHeader(http.StatusBadRequest)
95+
return
96+
}
97+
98+
var storedPassword string
99+
err = db.QueryRow("SELECT password FROM users WHERE username = ?", creds.Username).Scan(&storedPassword)
100+
if err != nil {
101+
w.WriteHeader(http.StatusUnauthorized)
102+
return
103+
}
104+
105+
if creds.Password != storedPassword {
106+
w.WriteHeader(http.StatusUnauthorized)
107+
return
108+
}
109+
110+
w.WriteHeader(http.StatusOK)
111+
json.NewEncoder(w).Encode(map[string]string{"message": "Authentication successful"})
112+
}
113+
114+
func roomCreateHandler(w http.ResponseWriter, r *http.Request) {
115+
rand.Seed(time.Now().UnixNano())
116+
roomName := fmt.Sprintf("room-%d", rand.Intn(1000))
117+
118+
_, err := db.Exec("INSERT INTO rooms (name) VALUES (?)", roomName)
119+
if err != nil {
120+
w.WriteHeader(http.StatusInternalServerError)
121+
return
122+
}
123+
124+
w.WriteHeader(http.StatusCreated)
125+
json.NewEncoder(w).Encode(map[string]string{"message": "Room created successfully", "roomName": roomName})
126+
}
127+
128+
func roomDeleteHandler(w http.ResponseWriter, r *http.Request) {
129+
roomIDStr := r.URL.Query().Get("id")
130+
if roomIDStr == "" {
131+
w.WriteHeader(http.StatusBadRequest)
132+
json.NewEncoder(w).Encode(map[string]string{"message": "Room ID is required"})
133+
return
134+
}
135+
136+
roomID, err := strconv.Atoi(roomIDStr)
137+
if err != nil {
138+
w.WriteHeader(http.StatusBadRequest)
139+
json.NewEncoder(w).Encode(map[string]string{"message": "Invalid room ID"})
140+
return
141+
}
142+
143+
_, err = db.Exec("DELETE FROM rooms WHERE id = ?", roomID)
144+
if err != nil {
145+
w.WriteHeader(http.StatusInternalServerError)
146+
return
147+
}
148+
149+
w.WriteHeader(http.StatusOK)
150+
json.NewEncoder(w).Encode(map[string]string{"message": "Room deleted successfully"})
151+
}
152+
153+
func roomListHandler(w http.ResponseWriter, r *http.Request) {
154+
rows, err := db.Query("SELECT id, name FROM rooms")
155+
if err != nil {
156+
w.WriteHeader(http.StatusInternalServerError)
157+
return
158+
}
159+
defer rows.Close()
160+
161+
var rooms []Room
162+
for rows.Next() {
163+
var room Room
164+
err := rows.Scan(&room.ID, &room.Name)
165+
if err != nil {
166+
w.WriteHeader(http.StatusInternalServerError)
167+
return
168+
}
169+
rooms = append(rooms, room)
170+
}
171+
172+
json.NewEncoder(w).Encode(rooms)
173+
}

colourstream-app/.env

-20
This file was deleted.

colourstream-app/.env.example

-20
This file was deleted.

colourstream-app/Dockerfile

-13
This file was deleted.

0 commit comments

Comments
 (0)