diff --git a/api/dns.go b/api/dns.go new file mode 100644 index 0000000..3105f91 --- /dev/null +++ b/api/dns.go @@ -0,0 +1,23 @@ +package api + +import ( + "log" + "net/http" + + "git.hatecomputers.club/hatecomputers/hatecomputers.club/database" +) + +func ListDNSRecordsContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain { + return func(success Continuation, failure Continuation) ContinuationChain { + dnsRecords, err := database.GetUserDNSRecords(context.DBConn, context.User.ID) + if err != nil { + log.Println(err) + resp.WriteHeader(http.StatusInternalServerError) + return failure(context, req, resp) + } + + (*context.TemplateData)["DNSRecords"] = dnsRecords + + return success(context, req, resp) + } +} diff --git a/api/serve.go b/api/serve.go index 758a8d9..38b65b2 100644 --- a/api/serve.go +++ b/api/serve.go @@ -19,7 +19,8 @@ type RequestContext struct { Id string Start time.Time - User *database.User + TemplateData *map[string]interface{} + User *database.User } type Continuation func(*RequestContext, *http.Request, http.ResponseWriter) ContinuationChain @@ -75,12 +76,14 @@ func MakeServer(argv *args.Arguments, dbConn *sql.DB) *http.Server { return &RequestContext{ DBConn: dbConn, Args: argv, + + TemplateData: &map[string]interface{}{}, } } mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { requestContext := makeRequestContext() - LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(IdContinuation, IdContinuation)(TemplateContinuation("home.html", nil, true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation) + LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(IdContinuation, IdContinuation)(TemplateContinuation("home.html", true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation) }) mux.HandleFunc("GET /api/health", func(w http.ResponseWriter, r *http.Request) { @@ -108,10 +111,15 @@ func MakeServer(argv *args.Arguments, dbConn *sql.DB) *http.Server { LogRequestContinuation(requestContext, r, w)(LogoutContinuation, FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation) }) + mux.HandleFunc("GET /dns", func(w http.ResponseWriter, r *http.Request) { + requestContext := makeRequestContext() + LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(ListDNSRecordsContinuation, GoLoginContinuation)(TemplateContinuation("dns.html", true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation) + }) + mux.HandleFunc("GET /{name}", func(w http.ResponseWriter, r *http.Request) { requestContext := makeRequestContext() name := r.PathValue("name") - LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(IdContinuation, IdContinuation)(TemplateContinuation(name+".html", nil, true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation) + LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(IdContinuation, IdContinuation)(TemplateContinuation(name+".html", true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation) }) return &http.Server{ diff --git a/api/template.go b/api/template.go index a4ccfa8..eeaeb51 100644 --- a/api/template.go +++ b/api/template.go @@ -9,7 +9,7 @@ import ( "os" ) -func renderTemplate(context *RequestContext, templateName string, showBaseHtml bool, data interface{}) (bytes.Buffer, error) { +func renderTemplate(context *RequestContext, templateName string, showBaseHtml bool) (bytes.Buffer, error) { templatePath := context.Args.TemplatePath basePath := templatePath + "/base_empty.html" if showBaseHtml { @@ -22,11 +22,14 @@ func renderTemplate(context *RequestContext, templateName string, showBaseHtml b return bytes.Buffer{}, err } - if data == nil { - data = map[string]interface{}{} + dataPtr := context.TemplateData + if dataPtr == nil { + dataPtr = &map[string]interface{}{} } - if context.User != nil { - data.(map[string]interface{})["User"] = context.User + + data := *dataPtr + if data["User"] == nil { + data["User"] = context.User } var buffer bytes.Buffer @@ -38,13 +41,13 @@ func renderTemplate(context *RequestContext, templateName string, showBaseHtml b return buffer, nil } -func TemplateContinuation(path string, data interface{}, showBase bool) Continuation { +func TemplateContinuation(path string, showBase bool) Continuation { return func(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain { return func(success Continuation, failure Continuation) ContinuationChain { - html, err := renderTemplate(context, path, true, data) + html, err := renderTemplate(context, path, true) if errors.Is(err, os.ErrNotExist) { resp.WriteHeader(404) - html, err = renderTemplate(context, "404.html", true, nil) + html, err = renderTemplate(context, "404.html", true) if err != nil { log.Println("error rendering 404 template", err) resp.WriteHeader(500) diff --git a/database/dns.go b/database/dns.go new file mode 100644 index 0000000..17487b7 --- /dev/null +++ b/database/dns.go @@ -0,0 +1,40 @@ +package database + +import ( + "database/sql" + _ "github.com/mattn/go-sqlite3" + "log" + "time" +) + +type DNSRecord struct { + ID string + UserID string + Name string + Type string + Content string + TTL int + CreatedAt time.Time +} + +func GetUserDNSRecords(db *sql.DB, userID string) ([]DNSRecord, error) { + log.Println("getting dns records for user", userID) + + rows, err := db.Query("SELECT * FROM dns_records WHERE user_id = ?", userID) + if err != nil { + return nil, err + } + defer rows.Close() + + var records []DNSRecord + for rows.Next() { + var record DNSRecord + err := rows.Scan(&record.ID, &record.UserID, &record.Name, &record.Type, &record.Content, &record.TTL, &record.CreatedAt) + if err != nil { + return nil, err + } + records = append(records, record) + } + + return records, nil +} diff --git a/static/css/colors.css b/static/css/colors.css index 2535049..69e3e4b 100644 --- a/static/css/colors.css +++ b/static/css/colors.css @@ -1,25 +1,33 @@ :root { --background-color-light: #f4e8e9; + --background-color-light-2: #f7f7f7; --text-color-light: #333; --link-color-light: #d291bc; - --container-bg-light: #fff7f8; + --container-bg-light: #fff7f87a; + --border-color-light: #692fcc; --background-color-dark: #333; + --background-color-dark-2: #2c2c2c; --text-color-dark: #f4e8e9; --link-color-dark: #b86b77; - --container-bg-dark: #424242; + --container-bg-dark: #424242ea; + --border-color-dark: #956ade; } [data-theme="DARK"] { --background-color: var(--background-color-dark); + --background-color-2: var(--background-color-dark-2); --text-color: var(--text-color-dark); --link-color: var(--link-color-dark); --container-bg: var(--container-bg-dark); + --border-color: var(--border-color-dark); } [data-theme="LIGHT"] { --background-color: var(--background-color-light); + --background-color-2: var(--background-color-light-2); --text-color: var(--text-color-light); --link-color: var(--link-color-light); --container-bg: var(--container-bg-light); + --border-color: var(--border-color-light); } diff --git a/static/css/form.css b/static/css/form.css new file mode 100644 index 0000000..4e14b68 --- /dev/null +++ b/static/css/form.css @@ -0,0 +1,30 @@ +form { + max-width: 600px; + padding: 1em; + background: var(--background-color-2); + border: 1px solid #ccc; +} + +label { + display: block; + margin: 0 0 1em; + font-weight: bold; +} + +input { + display: block; + width: 100%; + padding: 0.5em; + margin: 0 0 1em; + border: 1px solid var(--border-color); + background: var(--container-bg); +} + +button, +input[type="submit"] { + padding: 0.5em 1em; + background: var(--link-color); + color: var(--text-color); + border: 0; + cursor: pointer; +} diff --git a/static/css/styles.css b/static/css/styles.css index ffc3114..b3babe7 100644 --- a/static/css/styles.css +++ b/static/css/styles.css @@ -1,5 +1,7 @@ @import "/static/css/colors.css"; @import "/static/css/blinky.css"; +@import "/static/css/table.css"; +@import "/static/css/form.css"; @font-face { font-family: "ComicSans"; @@ -11,10 +13,10 @@ margin: 0; padding: 0; color: var(--text-color); + font-family: "ComicSans", sans-serif; } body { - font-family: "ComicSans", sans-serif; background-color: var(--background-color); background-image: url("/static/img/stars.gif"); min-height: 100vh; @@ -35,7 +37,6 @@ a:hover { margin: auto; background-color: var(--container-bg); padding: 1rem; - opacity: 0.95; } hr { @@ -44,3 +45,11 @@ hr { margin: 20px 0; } + +.blinkies { + display: flex; + justify-content: left; + flex-wrap: wrap; + max-width: 900px; + gap: 10px 10px; +} diff --git a/static/css/table.css b/static/css/table.css new file mode 100644 index 0000000..640ad83 --- /dev/null +++ b/static/css/table.css @@ -0,0 +1,26 @@ +table { + width: auto; + border-collapse: collapse; + border: 1px solid var(--border-color); +} + +th, +td { + padding: 12px 20px; + text-align: left; + border-bottom: 1px solid var(--border-color); +} + +tbody tr:nth-child(odd) { + background-color: var(--link-color); + color: var(--text-color); +} + +tbody tr { + transition: background-color 0.3s ease; +} + +tbody tr:hover { + background-color: #ff47daa0; + color: #2a2a2a; +} diff --git a/templates/base.html b/templates/base.html index a60ac55..79e0d12 100644 --- a/templates/base.html +++ b/templates/base.html @@ -50,6 +50,21 @@ diff --git a/templates/dns.html b/templates/dns.html new file mode 100644 index 0000000..0a40cab --- /dev/null +++ b/templates/dns.html @@ -0,0 +1,37 @@ +{{ define "content" }} + + + + + + + + {{ if (eq (len .DNSRecords) 0) }} + + + + {{ end }} + {{ range $record := .DNSRecords }} + + + + + + + {{ end }} +
TypeNameContentTTL
No DNS records found
{{ $record.Type }}{{ $record.Name }}{{ $record.Content }}{{ $record.TTL }}
+
+
+

Add DNS Records

+
+ + + + + + + + + +
+{{ end }}