mirror of
https://github.com/go-i2p/go-jump-addr.git
synced 2025-06-09 09:33:01 -04:00
start thinking templates
This commit is contained in:
95
handlers.go
95
handlers.go
@ -1,7 +1,98 @@
|
||||
package jumpserver
|
||||
|
||||
import "net/http"
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
var templates *template.Template
|
||||
|
||||
func init() {
|
||||
templates = template.Must(template.ParseFiles(
|
||||
filepath.Join("tpl", "index.html"),
|
||||
filepath.Join("tpl", "add.html"),
|
||||
))
|
||||
}
|
||||
|
||||
func (j *JumpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Serve the jump server
|
||||
switch r.URL.Path {
|
||||
case "/", "/index.html":
|
||||
err := templates.ExecuteTemplate(w, "index.html", j)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
case "/add", "/add.html":
|
||||
j.handleAdd(w, r)
|
||||
case "/static/style.css":
|
||||
http.ServeFile(w, r, filepath.Join("static", "style.css"))
|
||||
case "/static/script.js":
|
||||
http.ServeFile(w, r, filepath.Join("static", "script.js"))
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func (j *JumpServer) handleAdd(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == "GET" {
|
||||
err := templates.ExecuteTemplate(w, "add.html", nil)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if r.Method == "POST" {
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to parse form", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Extract form data
|
||||
hostname := r.Form.Get("hostname")
|
||||
destination := r.Form.Get("destination")
|
||||
regType := r.Form.Get("type")
|
||||
name := r.Form.Get("name")
|
||||
description := r.Form.Get("description")
|
||||
tags := r.Form.Get("tags")
|
||||
|
||||
// Validate hostname
|
||||
if hostname == "" {
|
||||
http.Error(w, "Hostname is required", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Parse I2P address
|
||||
addr, err := i2pkeys.DecodeFromString(destination)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid I2P destination", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Create new hostname entry
|
||||
host := &Hostname{
|
||||
I2PAddr: addr,
|
||||
Time: time.Now(),
|
||||
Registrant: Registrant{
|
||||
Type: regType,
|
||||
Name: name,
|
||||
Description: description,
|
||||
Tags: splitTags(tags),
|
||||
},
|
||||
Hostname: hostname,
|
||||
}
|
||||
|
||||
// Add to jump server
|
||||
j.AddHostname(host)
|
||||
|
||||
// Redirect to index page
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
|
||||
type JumpServer struct {
|
||||
*gohtmlmetadata.Extractor
|
||||
Index string `json:"index"` // The intro page/index page content of the jump server
|
||||
Hostnames []*Hostname `json:"hostnames"` // The hostnames of the jump server
|
||||
Garlic *onramp.Garlic
|
||||
}
|
||||
|
73
tpl/add.html
73
tpl/add.html
@ -0,0 +1,73 @@
|
||||
pl/add.html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Add Host - I2P Jump Server</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>Add Host to Jump Server</h1>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section id="rules">
|
||||
<h2>Rules for Adding Hosts</h2>
|
||||
<ul>
|
||||
<li>The hostname must be unique and not already registered</li>
|
||||
<li>The I2P destination must be valid and reachable</li>
|
||||
<li>The service must be actively running and maintained</li>
|
||||
<li>No illegal or harmful content is allowed</li>
|
||||
<li>Hostnames must be appropriate and not misleading</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="add-form">
|
||||
<h2>Add New Host</h2>
|
||||
<form method="POST" action="/add">
|
||||
<div class="form-group">
|
||||
<label for="hostname">Hostname:</label>
|
||||
<input type="text" id="hostname" name="hostname" required
|
||||
pattern="[a-zA-Z0-9.-]+"
|
||||
title="Only letters, numbers, dots and hyphens allowed">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="destination">I2P Destination (Base32 or Base64):</label>
|
||||
<textarea id="destination" name="destination" required></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="type">Type:</label>
|
||||
<select id="type" name="type" required>
|
||||
<option value="service">Service</option>
|
||||
<option value="user">User</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name">Registrant Name:</label>
|
||||
<input type="text" id="name" name="name" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="description">Description:</label>
|
||||
<textarea id="description" name="description"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="tags">Tags (comma separated):</label>
|
||||
<input type="text" id="tags" name="tags"
|
||||
placeholder="e.g. blog, forum, social">
|
||||
</div>
|
||||
|
||||
<button type="submit">Add Host</button>
|
||||
</form>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<script src="/static/script.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,64 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>I2P Jump Server</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>I2P Jump Server</h1>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section id="index-content">
|
||||
{{if .Index}}
|
||||
{{.Index}}
|
||||
{{else}}
|
||||
<p>Welcome to the I2P Jump Server. This service helps you discover and navigate I2P services.</p>
|
||||
{{end}}
|
||||
</section>
|
||||
|
||||
<section id="hostname-list">
|
||||
<h2>Registered Hostnames</h2>
|
||||
{{if .Hostnames}}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Hostname</th>
|
||||
<th>Base32 Address</th>
|
||||
<th>Type</th>
|
||||
<th>Registrant</th>
|
||||
<th>Description</th>
|
||||
<th>Tags</th>
|
||||
<th>Added</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .Hostnames}}
|
||||
<tr>
|
||||
<td>{{.Hostname}}</td>
|
||||
<td>{{.I2PAddr.Base32}}</td>
|
||||
<td>{{.Registrant.Type}}</td>
|
||||
<td>{{.Registrant.Name}}</td>
|
||||
<td>{{.Registrant.Description}}</td>
|
||||
<td>
|
||||
{{range .Registrant.Tags}}
|
||||
<span class="tag">{{.}}</span>
|
||||
{{end}}
|
||||
</td>
|
||||
<td>{{.Time.Format "2006-01-02"}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{else}}
|
||||
<p>No hostnames registered yet.</p>
|
||||
{{end}}
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<script src="/static/script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
Reference in New Issue
Block a user