diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml
index cbee3af..d606205 100644
--- a/.gitea/workflows/deploy.yml
+++ b/.gitea/workflows/deploy.yml
@@ -63,10 +63,10 @@ jobs:
- name: Health check
run: |
sleep 20
- curl -f https://punktfri.i80.dk/health || echo "Service not yet available"
+ curl -f https://punktfri.dk/health || echo "Service not yet available"
- name: Notify deployment status
run: |
echo "Deployment completed!"
- echo "Service: https://punktfri.i80.dk"
- echo "Health: https://punktfri.i80.dk/health"
+ echo "Service: https://punktfri.dk"
+ echo "Health: https://punktfri.dk/health"
diff --git a/README.md b/README.md
index 94c8c65..3e515e0 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,11 @@ Visit `http://localhost:5000`
| `LOG_FILE` | `signups.log` | Signup log file path |
| `ADMIN_USER` | `admin` | Admin username |
| `ADMIN_PASS` | `punktfri2024` | Admin password |
+| `NOTIFY_EMAIL` | `henrik@i80.dk` | Receives a mail on every signup |
+| `SMTP_HOST` | *(empty)* | SMTP server; notifications are skipped when unset |
+| `SMTP_PORT` | `587` | SMTP port (STARTTLS) |
+| `SMTP_USER` / `SMTP_PASS` | *(empty)* | SMTP login (Consul KV `punktfri/smtp_user`, `punktfri/smtp_pass` in Nomad) |
+| `SMTP_FROM` | `SMTP_USER` | Sender address (Consul KV `punktfri/smtp_from`) |
Change `ADMIN_USER` and `ADMIN_PASS` before deploying publicly.
diff --git a/app.py b/app.py
index 5b756a9..9511356 100644
--- a/app.py
+++ b/app.py
@@ -1,6 +1,9 @@
import os
import logging
+import smtplib
import sqlite3
+import threading
+from email.message import EmailMessage
from functools import wraps
from flask import Flask, render_template, request, redirect, url_for, g, Response, send_from_directory
@@ -10,6 +13,12 @@ LOG_FILE = os.environ.get("LOG_FILE", "signups.log")
ADMIN_USER = os.environ.get("ADMIN_USER", "admin")
ADMIN_PASS = os.environ.get("ADMIN_PASS", "punktfri2024")
PORT = int(os.environ.get("PORT", 5000))
+NOTIFY_EMAIL = os.environ.get("NOTIFY_EMAIL", "henrik@i80.dk")
+SMTP_HOST = os.environ.get("SMTP_HOST", "")
+SMTP_PORT = int(os.environ.get("SMTP_PORT", 587))
+SMTP_USER = os.environ.get("SMTP_USER", "")
+SMTP_PASS = os.environ.get("SMTP_PASS", "")
+SMTP_FROM = os.environ.get("SMTP_FROM", "") or SMTP_USER
app = Flask(__name__)
@@ -20,6 +29,41 @@ _fh.setFormatter(logging.Formatter("%(asctime)s %(message)s"))
signup_logger.addHandler(_fh)
+def build_notification(navn, email, domaener, egne_ns, kommentar):
+ msg = EmailMessage()
+ msg["Subject"] = f"PunktFri: ny tilmelding fra {navn}"
+ msg["From"] = SMTP_FROM
+ msg["To"] = NOTIFY_EMAIL
+ msg["Reply-To"] = email
+ msg.set_content(
+ f"Ny interessetilkendegivelse på punktfri.dk\n\n"
+ f"Navn: {navn}\n"
+ f"E-mail: {email}\n"
+ f"Antal domæner: {domaener}\n"
+ f"Egne navneservere: {egne_ns}\n"
+ f"Kommentar:\n{kommentar or '(ingen)'}\n"
+ )
+ return msg
+
+
+def _send(msg):
+ try:
+ with smtplib.SMTP(SMTP_HOST, SMTP_PORT, timeout=15) as s:
+ s.starttls()
+ if SMTP_USER:
+ s.login(SMTP_USER, SMTP_PASS)
+ s.send_message(msg)
+ except Exception:
+ app.logger.exception("Kunne ikke sende tilmeldingsnotifikation til %s", NOTIFY_EMAIL)
+
+
+def notify_signup(**fields):
+ if not SMTP_HOST:
+ app.logger.warning("SMTP_HOST ikke sat — springer notifikation over")
+ return
+ threading.Thread(target=_send, args=(build_notification(**fields),), daemon=True).start()
+
+
def get_db():
db = getattr(g, "_database", None)
if db is None:
@@ -105,6 +149,10 @@ def index():
f"SIGNUP navn={navn!r} email={email!r} domaener={domaener} "
f"egne_ns={egne_ns} kommentar={kommentar!r}"
)
+ notify_signup(
+ navn=navn, email=email, domaener=domaener,
+ egne_ns=egne_ns, kommentar=kommentar,
+ )
return redirect(url_for("tak"))
return render_template("index.html", error=error)
diff --git a/punktfri.nomad b/punktfri.nomad
index 7aaedee..0b7f0f4 100644
--- a/punktfri.nomad
+++ b/punktfri.nomad
@@ -104,6 +104,19 @@ job "punktfri" {
DATABASE = "/app/instance/punktfri.db"
LOG_FILE = "/app/instance/signups.log"
TZ = "Europe/Copenhagen"
+ NOTIFY_EMAIL = "henrik@i80.dk"
+ SMTP_HOST = "smtp.i80.dk"
+ SMTP_PORT = "587"
+ }
+
+ template {
+ data = < Dit .dk-domæne. Din infrastruktur. Ingen forhandler.
- Punktum dk kræver fra 2026 en akkrediteret registrator for alle .dk-domæner — også dem du har
- administreret selv i årtier uden at bede nogen om hjælp. 90-150 kr/domæne/år for noget du ikke har brug for.
+ Det er sket. Den 1. juli 2026 lukkede Punktum dk for direkte registrering af nye .dk-domæner,
+ og nedtællingen er i gang for dem, du har administreret selv i årtier uden at bede nogen om hjælp:
+ senest 30. juni 2028 skal de også have en registrator. 90–150 kr/domæne/år for noget du ikke har brug for.
Du har ikke bedt om et mellemled. Din infrastruktur virker. PunktFri er et initiativ fra selvhostere,
der heller ikke vil betale kommerciel pris for noget, de aldrig har haft brug for.
PunktFri — Non-profit registrator for .dk-domæner
Punktum dk A/S er den danske registry — det centrale register for alle .dk-domæner. Lidt ligesom Tinglysningsretten er for ejendomme: de er registret, ikke en udbyder. - Indtil nu har tekniske brugere kunnet administrere domæner direkte hos Punktum dk uden mellemmand. - Det slutter nu. + Tekniske brugere har i årevis kunnet administrere deres domæner direkte hos Punktum dk uden mellemmand. + Det er slut: modellen er lukket for nye domæner, og for de eksisterende løber tiden ud.
Som registrant kunne du oprette, betale og administrere dine .dk-domæner direkte hos Punktum dk — uden mellemmand.
+Har du administreret dine domæner direkte hos Punktum dk, kører det fortsat. Men det ændrer sig meget snart.
+ 1. juli 2026 Gældende nu +Punktum dk har lukket for oprettelse af nye domæner uden mellemled. Nye .dk-domæner oprettes nu kun via en registrator — uanset om du bruger deres services eller ej — og registrering og fornyelse sker ét år ad gangen. Dine eksisterende, direkte registrerede domæner kører videre, men kun indtil overgangsperioden udløber.
Direkte registrering af nye domæner hos Punktum dk udgår. Du skal have en akkrediteret registrator — uanset om du bruger deres services eller ej.
-Også domæner registreret direkte hos Punktum dk skal nu have en registrator som formelt mellemled. Intet ændrer sig teknisk — men det administrative led er obligatorisk.
+ 30. juni 2028 Næste frist +Herefter skal alle .dk-domæner ligge hos en registrator — også dem, du i dag har direkte hos Punktum dk. Teknisk ændres intet, men mellemleddet er obligatorisk.
Vi arbejder på det. Målet er at have forening stiftet og akkreditering ansøgt inden 1. juli 2026-deadlinen for nye domæner. Tilmeldingerne her er afgørende for, om vi har den kritiske masse til at gå videre — juridisk, teknisk og organisatorisk.
+Vi arbejder på det. Den frist, der betyder mest for selvhostere med eksisterende domæner, er 30. juni 2028 — og målet er at være klar i god tid før. Tilmeldingerne her er afgørende for, om vi har den kritiske masse til at gå videre — juridisk, teknisk og organisatorisk.
+Siden 1. juli 2026 skal nye domæner oprettes via en registrator. Indtil PunktFri er akkrediteret, må du bruge en eksisterende registrator. Når PunktFri er klar, kan du flytte domænet til os — dine navneservere og zoner er upåvirkede af en registratorflytning.
Punktum dk har endnu ikke offentliggjort præcis, hvad der sker — men de vil sandsynligvis tvinge en overflytning til en registrator, du ikke selv har valgt. Det er bedre at vælge sin registrator på egne præmisser og i god tid.
+Punktum dk har meldt ud, at de selv vil afgøre, hvad der sker med domæner, som ikke er flyttet til en registrator inden 30. juni 2028. I værste fald risikerer du at miste kontrollen over domænet. Mange har desuden forældede kontaktoplysninger hos Punktum dk, hvilket kan trække en overførsel i langdrag — så vent ikke til sidste øjeblik, og vælg din registrator på egne præmisser.