Initial commit

This commit is contained in:
k_lar 2026-02-12 00:11:37 +01:00
commit 8421c6999a
10 changed files with 1794 additions and 0 deletions

27
Caddyfile Normal file
View file

@ -0,0 +1,27 @@
# Caddyfile za MiTM demo aplikacijo
# Za HTTPS demo z avtomatskimi SSL certifikati
# HTTP verzija - za MiTM demo (paketi vidni v Wireshark)
:8080 {
reverse_proxy localhost:8081
log {
output file /var/log/caddy/mitm-demo-http.log
format console
}
}
# HTTPS verzija - za primerjavo (paketi šifrirani)
# OPOMBA: Za lokalno testiranje uporabite localhost namesto domene
localhost:8443 {
reverse_proxy localhost:8081
tls internal # Uporabi Caddy-jeve self-signed certs za localhost
log {
output file /var/log/caddy/mitm-demo-https.log
format console
}
}
# Za resnično domeno z Let's Encrypt certifikati:
# vasa-domena.com {
# reverse_proxy localhost:8081
# }

154
README.md Normal file
View file

@ -0,0 +1,154 @@
# 🏦 SecureBank Demo - MiTM Napadalna Aplikacija
Preprosta Go spletna aplikacija za demonstracijo razlike med HTTP in HTTPS pri prenosu občutljivih podatkov (MiTM napadi).
## 🎯 Namen aplikacije
Ta aplikacija je namenjena **izobraževalnim** namenom za prikaz:
- Kako so podatki vidni v HTTP prometu
- Kako HTTPS ščiti podatke pred prisluškovalci
- Praktična uporaba Wireshark-a za analizo mrežnega prometa
## 🚀 Hitri zagon
### 1. Zaženite Go aplikacijo
```bash
go run main.go -port 8081
```
### 2. Testiraj HTTP (nezaščiten)
Odprite brskalnik: `http://localhost:8081`
### 3. Zagon s Caddy za HTTPS
```bash
# Namestite Caddy (če še ni nameščen)
# Na Ubuntu/Debian:
sudo apt install caddy
# Na macOS:
brew install caddy
# Zaženite Caddy z našo konfiguracijo
caddy run --config Caddyfile
# Aplikacija bo dostopna na:
# HTTP: http://localhost:8080 (preko Caddy proxy)
# HTTPS: https://localhost:8443 (z avtomatskimi SSL certifikati)
```
## 🔍 MiTM Demo navodila
### Korak 1: HTTP analiza
1. **Zaženite Wireshark**
```bash
sudo wireshark
```
2. **Nastavite filtre:**
- Vmesnik: `Loopback: lo`
- Filter: `http and tcp.port == 8080`
3. **Testirajte prenose:**
- Prijavite se z: `admin` / `admin123`
- Opazujte pakete v Wireshark-u
4. **Poiščite POST request:**
- Desni klik na paket → Follow → HTTP Stream
- Videli boste geslo v običajnem besedilu!
### Korak 2: HTTPS primerjava
1. **Nastavite Wireshark filter:**
```
tcp.port == 8443
```
2. **Dostopajte do HTTPS verzije:**
```
https://localhost:8443
```
3. **Primerjajte pakete:**
- Videli boste samo TLS handshake
- Aplikacijski podatki so šifrirani
- Gesla niso več vidna!
## 👤 Demo uporabniki
| Uporabniško ime | Geslo | Opis |
|-----------------|----------|------|
| `admin` | `admin123` | Administrator |
| `janez` | `geslo123` | Običajen uporabnik |
## 📂 Struktura projekta
```
server/
├── main.go # Glavna Go aplikacija
├── Caddyfile # Caddy konfiguracija
├── templates/ # HTML predloge
│ ├── home.html
│ ├── login.html
│ ├── register.html
│ └── dashboard.html
└── static/
└── style.css # CSS styling
```
## 🛠️ Comandni argumenti
```bash
go run main.go -port 8081 # Nastavi drug port
```
## ⚠️ Varnostna opozorila
**Ta aplikacija je namenoma NEZAŠČITENA in vsebuje varnostne luknje:**
- ❌ Gesla se shranjujejo v običajnem besedilu
- ❌ Ni session managementa
- ❌ Ni CSRF zaščite
- ❌ Ni proper input validacije
- ❌ Ni rate limiting-a
**NE UPORABLJAJTE V PRODUKCIJI!** To je samo demonstracijska aplikacija.
## 🎓 Za prezetnje
### Ključne točke za predstavo:
1. **HTTP telovi** - pokažite kako so gesla vidna
2. **TLS Encryption** - razložite razliko v Wireshark-u
3. **Headers analiza** - pokažite HTTP vs HTTPS headers
4. **Certificate validation** - pokažite browser warnings za self-signed certs
### Dodatni filtri za Wireshark:
```
# Samo POST requesti
http.request.method == POST
# Form data
urlencoded-form
# TLS paketi
tls
```
## 🔧 Troubleshooting
**Problem:** Caddy se ne zažene
**Rešitev:** Preverite če port 8080/8443 ni že zaseden:
```bash
lsof -i :8080
lsof -i :8443
```
**Problem:** Browser SSL warning
**Rešitev:** To je normalno za self-signed certifikate. Kliknite "Advanced" → "Proceed to localhost"
**Problem:** Wireshark ne vidi paketov
**Rešitev:** Poskusite filter `tcp.port == 8081` (direct Go app port)
## 📚 Dodatni viri
- [Caddy dokumentacija](https://caddyserver.com/docs/)
- [Wireshark User Guide](https://www.wireshark.org/docs/wsug_html_chunked/)
- [OWASP TLS Guidelines](https://owasp.org/www-project-cheat-sheets/cheatsheets/Transport_Layer_Protection_Cheat_Sheet.html)

3
go.mod Normal file
View file

@ -0,0 +1,3 @@
module secure-bank-demo
go 1.25.5

29
launch_browsers.sh Normal file
View file

@ -0,0 +1,29 @@
#!/bin/bash
echo "🌐 Starting browsers with HTTPS certificate bypass..."
echo ""
# Chrome with certificate bypass
if command -v google-chrome &> /dev/null; then
echo "🔧 Starting Chrome with certificate bypass..."
google-chrome --ignore-certificate-errors-on-localhost https://localhost:8443 &
echo "✅ Chrome started"
elif command -v chromium &> /dev/null; then
echo "🔧 Starting Chromium with certificate bypass..."
chromium --ignore-certificate-errors-on-localhost https://localhost:8443 &
echo "✅ Chromium started"
fi
# Firefox (will need manual exception)
if command -v firefox &> /dev/null; then
echo "🔧 Starting Firefox..."
firefox https://localhost:8443 &
echo "ℹ️ Firefox started - you'll need to accept the security exception manually"
fi
echo ""
echo "📋 URLs for testing:"
echo " HTTP: http://localhost:8080"
echo " HTTPS: https://localhost:8443"
echo ""
echo "💡 For permanent setup, add security exceptions in browser settings"

198
main.go Normal file
View file

@ -0,0 +1,198 @@
package main
import (
"flag"
"fmt"
"html/template"
"log"
"net/http"
"sync"
)
// User struktura za uporabniške podatke
type User struct {
ID int
Username string
Password string
Email string
FullName string
}
// In-memory shranjevanje uporabnikov
var (
users = make(map[string]*User)
usersMux = &sync.RWMutex{}
lastID = 0
)
// Template cache
var templates *template.Template
func init() {
// Privzeti uporabniki
addUser("jnovak", "secure123", "janez.novak@securebank.si", "Janez Novak")
addUser("mpetric", "banking456", "maja.petric@securebank.si", "Maja Petrič")
}
func addUser(username, password, email, fullName string) {
usersMux.Lock()
defer usersMux.Unlock()
lastID++
users[username] = &User{
ID: lastID,
Username: username,
Password: password,
Email: email,
FullName: fullName,
}
}
func main() {
// Nastavimo port preko command line argumenta
var port = flag.String("port", "8080", "Port na katerem se bo zagnal server")
flag.Parse()
// Naložimo HTML predloge
var err error
templates, err = template.ParseGlob("templates/*.html")
if err != nil {
log.Fatal("Napaka pri nalaganju predlog:", err)
}
// Statične datoteke (CSS)
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static/"))))
// Routes
http.HandleFunc("/", homeHandler)
http.HandleFunc("/register", registerHandler)
http.HandleFunc("/login", loginHandler)
http.HandleFunc("/dashboard", dashboardHandler)
http.HandleFunc("/logout", logoutHandler)
// Zagon strežnika
fmt.Printf("SecureBank aplikacija se zaganja na portu %s\n", *port)
fmt.Printf("Dostop: http://localhost:%s\n", *port)
serverAddr := ":" + *port
log.Fatal(http.ListenAndServe(serverAddr, nil))
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
templates.ExecuteTemplate(w, "home.html", nil)
}
func registerHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
templates.ExecuteTemplate(w, "register.html", nil)
return
}
if r.Method == "POST" {
username := r.FormValue("username")
password := r.FormValue("password")
email := r.FormValue("email")
fullName := r.FormValue("fullName")
//Validacija
if username == "" || password == "" || email == "" || fullName == "" {
templates.ExecuteTemplate(w, "register.html", map[string]string{
"Error": "Vsa polja so obvezna!",
})
return
}
// Preverimo če uporabnik že obstaja
usersMux.RLock()
_, exists := users[username]
usersMux.RUnlock()
if exists {
templates.ExecuteTemplate(w, "register.html", map[string]string{
"Error": "Uporabniško ime že obstaja!",
})
return
}
// Dodamo novega uporabnika
addUser(username, password, email, fullName)
// Preusmeri na prijavo
http.Redirect(w, r, "/login?registered=1", http.StatusSeeOther)
return
}
}
func loginHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
data := map[string]string{}
if r.URL.Query().Get("registered") == "1" {
data["Success"] = "Registracija je bila uspešna! Sedaj se lahko prijavite."
}
templates.ExecuteTemplate(w, "login.html", data)
return
}
if r.Method == "POST" {
username := r.FormValue("username")
password := r.FormValue("password")
// Preverimo podatke
usersMux.RLock()
user, exists := users[username]
usersMux.RUnlock()
if !exists || user.Password != password {
templates.ExecuteTemplate(w, "login.html", map[string]string{
"Error": "Napačno uporabniško ime ali geslo!",
})
return
}
// Uspešna prijava - preusmeri na dashboard
// POZOR: Brez session management za demo!
http.Redirect(w, r, "/dashboard?user="+username, http.StatusSeeOther)
return
}
}
func dashboardHandler(w http.ResponseWriter, r *http.Request) {
username := r.URL.Query().Get("user")
if username == "" {
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
usersMux.RLock()
user, exists := users[username]
usersMux.RUnlock()
if !exists {
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
// Simuliramo "bančne" podatke
accounts := []map[string]interface{}{
{
"Name": "Glavni račun",
"Number": "SI56 1234 5678 9012 345",
"Balance": "€2,456.78",
},
{
"Name": "Varčevalni račun",
"Number": "SI56 1234 5678 9012 999",
"Balance": "€15,230.45",
},
}
data := map[string]interface{}{
"User": user,
"Accounts": accounts,
}
templates.ExecuteTemplate(w, "dashboard.html", data)
}
func logoutHandler(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/", http.StatusSeeOther)
}

984
static/style.css Normal file
View file

@ -0,0 +1,984 @@
/* SecureBank - Professional CSS */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
color: #333;
}
.container {
max-width: 1200px;
margin: 0 auto;
min-height: 100vh;
background: white;
box-shadow: 0 0 20px rgba(0,0,0,0.1);
}
/* Header */
.header {
background: linear-gradient(135deg, #2c3e50 0%, #3498db 100%);
color: white;
padding: 25px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
display: flex;
justify-content: space-between;
align-items: center;
}
.bank-logo h1 {
font-size: 2.5em;
margin-bottom: 5px;
}
.tagline {
font-size: 1em;
opacity: 0.9;
font-style: italic;
}
.user-info {
margin-top: 15px;
font-size: 1.1em;
}
.logout-btn {
background: #e74c3c;
color: white;
padding: 5px 10px;
border-radius: 5px;
text-decoration: none;
margin-left: 10px;
font-size: 0.9em;
}
.logout-btn:hover {
background: #c0392b;
}
/* Main content */
.main {
padding: 30px;
}
/* Welcome page */
.welcome-section {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 40px;
margin: 40px 0;
}
.welcome-content h2 {
color: #2c3e50;
margin-bottom: 20px;
font-size: 2.2em;
}
.welcome-text {
font-size: 1.1em;
line-height: 1.6;
margin-bottom: 30px;
color: #555;
}
.features {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
margin: 30px 0;
}
.feature {
background: #f8f9fa;
padding: 20px;
border-radius: 10px;
text-align: center;
border-left: 4px solid #3498db;
}
.feature h3 {
color: #2c3e50;
margin-bottom: 10px;
}
/* Info sidebar */
.info-sidebar {
background: #f8f9fa;
padding: 20px;
border-radius: 10px;
}
.contact-info,
.security-notice {
background: white;
padding: 20px;
margin-bottom: 20px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.contact-info h4,
.security-notice h4 {
color: #2c3e50;
margin-bottom: 15px;
}
/* Action section */
.action-section {
text-align: center;
margin: 40px 0;
}
.action-section h3 {
color: #2c3e50;
margin-bottom: 20px;
}
.action-buttons {
display: flex;
gap: 20px;
justify-content: center;
flex-wrap: wrap;
}
/* Buttons */
.btn {
padding: 12px 25px;
border: none;
border-radius: 8px;
text-decoration: none;
display: inline-block;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
font-size: 1.1em;
}
.btn-primary {
background: #3498db;
color: white;
}
.btn-primary:hover {
background: #2980b9;
transform: translateY(-2px);
}
.btn-secondary {
background: #95a5a6;
color: white;
}
.btn-secondary:hover {
background: #7f8c8d;
transform: translateY(-2px);
}
.btn-outline {
background: transparent;
border: 2px solid #3498db;
color: #3498db;
}
.btn-outline:hover {
background: #3498db;
color: white;
}
/* Demo users */
.demo-users {
background: #f8f9fa;
padding: 20px;
border-radius: 10px;
margin: 30px 0;
}
.demo-users h3 {
margin-bottom: 15px;
color: #2c3e50;
}
.user-list {
display: flex;
gap: 15px;
flex-wrap: wrap;
}
.demo-user {
background: white;
padding: 10px 15px;
border-radius: 5px;
border: 1px solid #ddd;
}
.demo-user code {
background: #e8f4f8;
color: #2980b9;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
}
/* Wireshark info */
.wireshark-info {
background: #e8f5e8;
border: 2px solid #27ae60;
padding: 20px;
border-radius: 10px;
margin: 30px 0;
}
.wireshark-info h3 {
color: #27ae60;
margin-bottom: 15px;
}
.wireshark-info ol {
margin-left: 20px;
}
.wireshark-info li {
margin: 8px 0;
}
.wireshark-info code {
background: #2c3e50;
color: #ecf0f1;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
}
/* Form styling */
.form-container {
max-width: 600px;
margin: 0 auto;
}
.form-container h2 {
color: #2c3e50;
margin-bottom: 15px;
text-align: center;
font-size: 2em;
}
.form-subtitle {
text-align: center;
color: #7f8c8d;
margin-bottom: 30px;
font-size: 1.1em;
}
/* Dashboard specific styles */
.quick-actions {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
margin: 30px 0;
}
.action-card {
background: #f8f9fa;
padding: 25px;
border-radius: 10px;
text-align: center;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
transition: transform 0.3s ease;
}
.action-card:hover {
transform: translateY(-5px);
}
.action-card h3 {
color: #2c3e50;
margin-bottom: 10px;
font-size: 1.3em;
}
.action-card p {
color: #7f8c8d;
margin-bottom: 20px;
}
/* User info grid */
.user-info-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px;
}
.info-item {
display: flex;
justify-content: space-between;
padding: 10px 0;
border-bottom: 1px solid #ecf0f1;
}
.info-item strong {
color: #2c3e50;
}
/* Accounts grid */
.accounts-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 20px;
margin-top: 20px;
}
.account-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.account-status {
background: #27ae60;
color: white;
padding: 4px 12px;
border-radius: 20px;
font-size: 0.8em;
font-weight: bold;
}
.account-balance {
display: flex;
justify-content: space-between;
align-items: center;
margin: 15px 0;
padding: 15px;
background: #f8f9fa;
border-radius: 8px;
}
.balance-amount {
font-size: 1.5em;
font-weight: bold;
color: #27ae60;
}
.account-actions {
display: flex;
gap: 10px;
}
/* Transactions */
.transaction-list {
background: #f8f9fa;
border-radius: 10px;
padding: 20px;
margin: 20px 0;
}
.transaction-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 0;
border-bottom: 1px solid #e9ecef;
}
.transaction-item:last-child {
border-bottom: none;
}
.transaction-desc {
font-weight: bold;
color: #2c3e50;
}
.transaction-date {
font-size: 0.9em;
color: #7f8c8d;
}
.transaction-amount.positive {
color: #27ae60;
font-weight: bold;
}
.transaction-amount.negative {
color: #e74c3c;
font-weight: bold;
}
/* Notifications */
.notification-item {
display: flex;
gap: 15px;
padding: 20px;
background: #e8f4f8;
border-radius: 10px;
border-left: 4px solid #3498db;
margin: 20px 0;
}
.notification-icon {
font-size: 1.5em;
}
.notification-content strong {
color: #2c3e50;
margin-bottom: 8px;
display: block;
}
/* Demo accounts */
.demo-accounts {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15px;
margin: 20px 0;
}
.demo-account {
background: #e8f4f8;
padding: 15px;
border-radius: 8px;
border-left: 4px solid #3498db;
}
.demo-credential {
background: #2c3e50;
color: #ecf0f1;
padding: 2px 6px;
border-radius: 4px;
font-family: 'Courier New', monospace;
font-weight: bold;
}
/* Security tips and info */
.security-tips {
background: #fff3cd;
border: 1px solid #ffc107;
padding: 20px;
border-radius: 10px;
margin: 20px 0;
}
.security-tips h3 {
color: #856404;
margin-bottom: 15px;
}
.security-tips ul {
margin-left: 20px;
}
.security-tips li {
margin: 8px 0;
color: #856404;
}
.security-info {
background: #e8f5e8;
border: 2px solid #27ae60;
padding: 20px;
border-radius: 10px;
margin: 20px 0;
}
.security-info h3 {
color: #27ae60;
margin-bottom: 15px;
}
.security-info ul {
margin-left: 20px;
}
.security-info li {
margin: 8px 0;
}
/* Checkbox styling */
.checkbox-container {
display: flex;
align-items: center;
cursor: pointer;
padding: 10px 0;
}
.checkbox-container input[type="checkbox"] {
margin-right: 10px;
}
.terms-section {
margin: 20px 0;
}
.form-options {
display: flex;
justify-content: space-between;
align-items: center;
margin: 20px 0;
}
.forgot-password {
color: #3498db;
text-decoration: none;
font-size: 0.9em;
}
.forgot-password:hover {
text-decoration: underline;
}
/* Alerts */
.alert {
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
font-weight: bold;
}
.alert-success {
background: #d4edda;
border: 1px solid #c3e6cb;
color: #155724;
}
.alert-error {
background: #f8d7da;
border: 1px solid #f5c6cb;
color: #721c24;
}
/* Security warnings */
.security-warning {
background: #fff3cd;
border: 2px solid #ffc107;
padding: 20px;
border-radius: 10px;
margin: 20px 0;
}
.security-warning.critical {
background: #f8d7da;
border-color: #e74c3c;
color: #721c24;
}
.security-warning h3 {
margin-bottom: 10px;
color: inherit;
}
.packet-info {
background: #2c3e50;
color: #ecf0f1;
padding: 15px;
border-radius: 5px;
margin-top: 15px;
font-family: 'Courier New', monospace;
font-size: 0.9em;
}
.packet-info code {
display: block;
white-space: pre-line;
}
/* Auth form */
.auth-form {
background: #f8f9fa;
padding: 30px;
border-radius: 10px;
margin: 20px 0;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: #2c3e50;
}
.form-group input {
width: 100%;
padding: 12px;
border: 2px solid #ddd;
border-radius: 5px;
font-size: 1em;
}
.form-group input:focus {
border-color: #3498db;
outline: none;
box-shadow: 0 0 5px rgba(52, 152, 219, 0.3);
}
.form-help {
display: block;
margin-top: 5px;
color: #e74c3c;
font-size: 0.9em;
}
.form-footer {
text-align: center;
margin-top: 20px;
}
.form-footer p {
margin: 10px 0;
}
.form-footer a {
color: #3498db;
text-decoration: none;
}
.form-footer a:hover {
text-decoration: underline;
}
/* Demo credentials */
.demo-credentials {
background: #e8f4f8;
padding: 20px;
border-radius: 10px;
margin: 20px 0;
}
.demo-credentials h3 {
margin-bottom: 15px;
color: #2980b9;
}
.cred-box {
background: white;
padding: 15px;
border-radius: 5px;
margin: 10px 0;
border-left: 4px solid #3498db;
}
.cred-box code {
background: #e8f4f8;
color: #2980b9;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
}
/* Wireshark instructions */
.wireshark-instructions {
background: #f0f8ff;
border: 2px solid #5dade2;
padding: 20px;
border-radius: 10px;
margin: 20px 0;
}
.wireshark-instructions h3 {
color: #2980b9;
margin-bottom: 15px;
}
.wireshark-instructions ol {
margin-left: 20px;
}
.wireshark-instructions code {
background: #2c3e50;
color: #ecf0f1;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
}
.wireshark-tip {
background: #fff9c4;
border: 2px solid #f39c12;
padding: 20px;
border-radius: 10px;
margin: 20px 0;
}
.wireshark-tip h3 {
color: #f39c12;
margin-bottom: 10px;
}
/* Dashboard */
.dashboard-container h2 {
color: #2c3e50;
margin-bottom: 25px;
text-align: center;
}
.success-message {
background: #d4edda;
border: 2px solid #27ae60;
padding: 20px;
border-radius: 10px;
margin-bottom: 25px;
}
.success-message h3 {
color: #27ae60;
margin-bottom: 10px;
}
/* User details */
.user-details {
margin: 30px 0;
}
.user-details h3 {
color: #2c3e50;
margin-bottom: 15px;
}
.user-card {
background: #f8f9fa;
padding: 20px;
border-radius: 10px;
border-left: 4px solid #3498db;
}
.user-card p {
margin: 8px 0;
}
.password-display {
background: #ffebee;
color: #e74c3c;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
font-weight: bold;
}
/* Accounts */
.accounts {
margin: 30px 0;
}
.accounts h3 {
color: #2c3e50;
margin-bottom: 20px;
}
.account-card {
background: white;
border: 1px solid #ddd;
border-radius: 10px;
padding: 20px;
margin: 15px 0;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.account-card h4 {
color: #2c3e50;
margin-bottom: 10px;
}
.account-number {
color: #7f8c8d;
font-family: 'Courier New', monospace;
}
.account-balance {
font-size: 1.2em;
margin-top: 10px;
}
.account-balance strong {
color: #27ae60;
}
/* Security analysis */
.security-analysis {
margin: 30px 0;
}
.security-analysis h3 {
color: #2c3e50;
margin-bottom: 20px;
}
.analysis-points {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.point {
padding: 20px;
border-radius: 10px;
}
.point:first-child {
background: #ffebee;
border: 2px solid #e74c3c;
}
.point:last-child {
background: #e8f5e8;
border: 2px solid #27ae60;
}
.point h4 {
margin-bottom: 15px;
}
.point ul {
margin-left: 20px;
}
.point li {
margin: 8px 0;
}
/* Demo actions */
.demo-actions {
margin: 30px 0;
text-align: center;
}
.demo-actions h3 {
color: #2c3e50;
margin-bottom: 20px;
}
.action-list {
display: flex;
gap: 15px;
justify-content: center;
flex-wrap: wrap;
}
/* HTTPS info */
.https-info {
background: #e8f5e8;
border: 2px solid #27ae60;
padding: 20px;
border-radius: 10px;
margin: 30px 0;
}
.https-info h3 {
color: #27ae60;
margin-bottom: 15px;
}
.https-info code {
background: #2c3e50;
color: #ecf0f1;
padding: 4px 8px;
border-radius: 3px;
font-family: 'Courier New', monospace;
display: inline-block;
margin: 5px 0;
}
.btn-outline:hover {
background: #3498db;
color: white;
}
.btn-sm {
padding: 8px 16px;
font-size: 0.9em;
}
/* Footer */
.footer {
background: #2c3e50;
color: white;
text-align: center;
padding: 25px;
margin-top: auto;
}
.footer-content p {
margin: 8px 0;
}
.footer-content a {
color: #3498db;
text-decoration: none;
}
.footer-content a:hover {
text-decoration: underline;
}
.license {
font-size: 0.9em;
opacity: 0.8;
}
/* Responsive design */
@media (max-width: 768px) {
.header {
flex-direction: column;
text-align: center;
gap: 15px;
}
.welcome-section {
grid-template-columns: 1fr;
}
.features,
.quick-actions {
grid-template-columns: 1fr;
}
.action-buttons,
.action-list {
flex-direction: column;
align-items: center;
}
.user-list,
.demo-accounts {
grid-template-columns: 1fr;
}
.analysis-points,
.protocol-info {
grid-template-columns: 1fr;
}
.main {
padding: 20px;
}
.accounts-grid {
grid-template-columns: 1fr;
}
.form-options {
flex-direction: column;
gap: 15px;
align-items: flex-start;
}
}
@media (max-width: 480px) {
.header h1 {
font-size: 2em;
}
.demo-notice {
display: block;
margin-top: 10px;
}
}

140
templates/dashboard.html Normal file
View file

@ -0,0 +1,140 @@
<!DOCTYPE html>
<html lang="sl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🏦 SecureBank - Dashboard</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div class="container">
<header class="header">
<div class="bank-logo">
<h1>🏦 SecureBank</h1>
<p class="tagline">Vaša varnost, naša prioriteta</p>
</div>
<div class="user-info">
Dobro došli, <strong>{{.User.FullName}}</strong>!
<a href="/logout" class="logout-btn">Odjava</a>
</div>
</header>
<main class="main">
<div class="dashboard-container">
<h2>Pregled vaših računov</h2>
<div class="quick-actions">
<div class="action-card">
<h3>Nakazilo</h3>
<p>Pošljite denar na drug račun</p>
<button class="btn btn-primary">Novo nakazilo</button>
</div>
<div class="action-card">
<h3>Izpisek</h3>
<p>Prenesite mesečnji izpisek</p>
<button class="btn btn-secondary">Prenesi PDF</button>
</div>
<div class="action-card">
<h3>Mobilno</h3>
<p>Povežite z mobilno aplikacijo</p>
<button class="btn btn-outline">Povežite</button>
</div>
</div>
<div class="user-details">
<h3>Podatki o uporabniku</h3>
<div class="user-card">
<div class="user-info-grid">
<div class="info-item">
<strong>Polno ime:</strong>
<span>{{.User.FullName}}</span>
</div>
<div class="info-item">
<strong>Uporabniško ime:</strong>
<span>{{.User.Username}}</span>
</div>
<div class="info-item">
<strong>E-mail:</strong>
<span>{{.User.Email}}</span>
</div>
<div class="info-item">
<strong>Strankarski ID:</strong>
<span>SEC-{{.User.ID}}</span>
</div>
</div>
</div>
</div>
<div class="accounts">
<h3>Vaši bančni računi</h3>
<div class="accounts-grid">
{{range .Accounts}}
<div class="account-card">
<div class="account-header">
<h4>{{.Name}}</h4>
<span class="account-status">Aktiven</span>
</div>
<p class="account-number">{{.Number}}</p>
<div class="account-balance">
<span class="balance-label">Razpoložljivo stanje:</span>
<span class="balance-amount">{{.Balance}}</span>
</div>
<div class="account-actions">
<button class="btn btn-sm btn-primary">Upravljaj</button>
<button class="btn btn-sm btn-outline">Zgodovina</button>
</div>
</div>
{{end}}
</div>
</div>
<div class="recent-transactions">
<h3>Zadnje transakcije</h3>
<div class="transaction-list">
<div class="transaction-item">
<div class="transaction-info">
<span class="transaction-desc">Nakup - Mercator d.d.</span>
<span class="transaction-date">10.02.2026</span>
</div>
<span class="transaction-amount negative">-€24.50</span>
</div>
<div class="transaction-item">
<div class="transaction-info">
<span class="transaction-desc">Plača - Delodajalec d.o.o.</span>
<span class="transaction-date">01.02.2026</span>
</div>
<span class="transaction-amount positive">+€2,100.00</span>
</div>
<div class="transaction-item">
<div class="transaction-info">
<span class="transaction-desc">Prevzem gotovine - Bankomat</span>
<span class="transaction-date">28.01.2026</span>
</div>
<span class="transaction-amount negative">-€100.00</span>
</div>
</div>
<button class="btn btn-outline">Prikaži vse transakcije</button>
</div>
<div class="notifications">
<h3>🔔 Obvestila</h3>
<div class="notification-item">
<span class="notification-icon">ℹ️</span>
<div class="notification-content">
<strong>Varnostno posodobljeno</strong>
<p>Vaši podatki so zaščiteni z najnovejšimi varnostnimi protokoli.</p>
</div>
</div>
</div>
</div>
</main>
<footer class="footer">
<div class="footer-content">
<p>&copy; 2026 SecureBank d.d. Vse pravice pridržane.</p>
<p class="license">Licencirana banka pod nadzorom Banke Slovenije | Uporabnik: {{.User.Username}}</p>
</div>
</footer>
</div>
</body>
</html>

72
templates/home.html Normal file
View file

@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="sl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SecureBank - Varno spletno bančništvo</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div class="container">
<header class="header">
<div class="bank-logo">
<h1>🏦 SecureBank</h1>
<p class="tagline">Vaša varnost, naša prioriteta</p>
</div>
</header>
<main class="main">
<div class="welcome-section">
<div class="welcome-content">
<h2>Dobrodošli v SecureBank</h2>
<p class="welcome-text">Vaš zaupanja vreden partner za varno spletno bančništvo. Z najsodobnejšimi varnostnimi tehnologijami ščitimo vaše finance 24/7.</p>
<div class="features">
<div class="feature">
<h3>Najvišja varnost</h3>
<p>SSL šifriranje in večstopenjski sistem preverjanja</p>
</div>
<div class="feature">
<h3>Enostavno upravljanje</h3>
<p>Intuitivni vmesnik za upravljanje vseh vaših računov</p>
</div>
<div class="feature">
<h3>Dostopnost 24/7</h3>
<p>Bančništvo brez omejitev, kadarkoli in kjerkoli</p>
</div>
</div>
<div class="action-section">
<h3>Dostop do vašega računa</h3>
<div class="action-buttons">
<a href="/login" class="btn btn-primary">Prijava</a>
<a href="/register" class="btn btn-secondary">Registracija</a>
</div>
</div>
</div>
<div class="info-sidebar">
<div class="contact-info">
<h4>📞 Stik z nami</h4>
<p><strong>Brezplačna telefonska številka:</strong><br>080 12 34</p>
<p><strong>E-mail podpora:</strong><br>podpora@securebank.si</p>
<p><strong>Delovni čas:</strong><br>Pon-Pet: 8:00-20:00<br>Sob: 9:00-13:00</p>
</div>
<div class="security-notice">
<h4>Varnostno obvestilo</h4>
<p>Nikoli ne delite svojih prijavnih podatkov z drugimi. SecureBank nikoli ne bo zahteval vaših podatkov preko e-maila ali telefona.</p>
</div>
</div>
</div>
</main>
<footer class="footer">
<div class="footer-content">
<p>&copy; 2026 SecureBank d.d. Vse pravice pridržane. | <a href="#">Pogoji uporabe</a> | <a href="#">Varstvo podatkov</a></p>
<p class="license">Licencirana banka pod nadzorom Banke Slovenije</p>
</div>
</footer>
</div>
</body>
</html>

99
templates/login.html Normal file
View file

@ -0,0 +1,99 @@
<!DOCTYPE html>
<html lang="sl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SecureBank - Prijava</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div class="container">
<header class="header">
<div class="bank-logo">
<h1>🏦 SecureBank</h1>
<p class="tagline">Vaša varnost, naša prioriteta</p>
</div>
</header>
<main class="main">
<div class="form-container">
<h2>Prijava v vaš račun</h2>
<p class="form-subtitle">Dobrodošli nazaj! Prijavite se za dostop do svojih financ.</p>
{{if .Success}}
<div class="alert alert-success">
{{.Success}}
</div>
{{end}}
{{if .Error}}
<div class="alert alert-error">
{{.Error}}
</div>
{{end}}
<form method="POST" action="/login" class="auth-form">
<div class="form-group">
<label for="username">Uporabniško ime:</label>
<input type="text" id="username" name="username" required placeholder="Vnesite uporabniško ime">
</div>
<div class="form-group">
<label for="password">Geslo:</label>
<input type="password" id="password" name="password" required placeholder="Vnesite geslo">
</div>
<div class="form-options">
<label class="checkbox-container">
<input type="checkbox" name="remember">
<span class="checkmark"></span>
Zapomni si me
</label>
<a href="#" class="forgot-password">Pozabljeno geslo?</a>
</div>
<button type="submit" class="btn btn-primary">Prijavite se</button>
</form>
<div class="form-footer">
<p>Nimate še računa? <a href="/register">Registrirajte se</a></p>
<p><a href="/">← Nazaj na domačo stran</a></p>
</div>
<div class="quick-access">
<h3>Hiter dostop za demo</h3>
<div class="demo-accounts">
<div class="demo-account">
<strong>Demo račun 1:</strong><br>
Uporabnik: <span class="demo-credential">jnovak</span><br>
Geslo: <span class="demo-credential">secure123</span>
</div>
<div class="demo-account">
<strong>Demo račun 2:</strong><br>
Uporabnik: <span class="demo-credential">mpetric</span><br>
Geslo: <span class="demo-credential">banking456</span>
</div>
</div>
</div>
<div class="security-tips">
<h3>Varnostni nasveti</h3>
<ul>
<li>Nikoli ne delite svojih prijavnih podatkov</li>
<li>Vedno se odjavite po končani uporabi</li>
<li>Uporabljajte močna, unikatna gesla</li>
<li>Preverite varno povezavo (HTTPS)</li>
</ul>
</div>
</div>
</main>
<footer class="footer">
<div class="footer-content">
<p>&copy; 2026 SecureBank d.d. Vse pravice pridržane.</p>
<p class="license">Licencirana banka pod nadzorom Banke Slovenije</p>
</div>
</footer>
</div>
</body>
</html>

88
templates/register.html Normal file
View file

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html lang="sl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SecureBank - Registracija</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div class="container">
<header class="header">
<div class="bank-logo">
<h1>🏦 SecureBank</h1>
<p class="tagline">Vaša varnost, naša prioriteta</p>
</div>
</header>
<main class="main">
<div class="form-container">
<h2>Registracija novega uporabnika</h2>
<p class="form-subtitle">Ustvarite vaš SecureBank račun v nekaj korakih</p>
{{if .Error}}
<div class="alert alert-error">
{{.Error}}
</div>
{{end}}
<form method="POST" action="/register" class="auth-form">
<div class="form-group">
<label for="fullName">Polno ime in priimek:</label>
<input type="text" id="fullName" name="fullName" required placeholder="Janez Novak">
</div>
<div class="form-group">
<label for="username">Uporabniško ime:</label>
<input type="text" id="username" name="username" required placeholder="jnovak">
<small class="form-help">Izbrite unikatno uporabniško ime za prijavo</small>
</div>
<div class="form-group">
<label for="email">E-mail naslov:</label>
<input type="email" id="email" name="email" required placeholder="janez.novak@email.si">
</div>
<div class="form-group">
<label for="password">Geslo:</label>
<input type="password" id="password" name="password" required>
<small class="form-help">Uporabite močno geslo z vsaj 8 znaki</small>
</div>
<div class="terms-section">
<label class="checkbox-container">
<input type="checkbox" required>
<span class="checkmark"></span>
Strinjam se s <a href="#">pogoji uporabe</a> in <a href="#">politiko zasebnosti</a>
</label>
</div>
<button type="submit" class="btn btn-primary">Ustvari račun</button>
</form>
<div class="form-footer">
<p>Že imate račun? <a href="/login">Prijavite se</a></p>
<p><a href="/">← Nazaj na domačo stran</a></p>
</div>
<div class="security-info">
<h3>Varnost vaših podatkov</h3>
<ul>
<li>SSL šifriranje za varno komunikacijo</li>
<li>Večstopenjski sistem preverjanja</li>
<li>Redna varnostna posodobitev</li>
<li>24/7 nadzor nad sumljivimi aktivnostmi</li>
</ul>
</div>
</div>
</main>
<footer class="footer">
<div class="footer-content">
<p>&copy; 2026 SecureBank d.d. Vse pravice pridržane.</p>
<p class="license">Licencirana banka pod nadzorom Banke Slovenije</p>
</div>
</footer>
</div>
</body>
</html>