summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--roseh.moe.go59
-rw-r--r--templates/otp.html.template6
2 files changed, 65 insertions, 0 deletions
diff --git a/roseh.moe.go b/roseh.moe.go
index 53deb02..e8f2d41 100644
--- a/roseh.moe.go
+++ b/roseh.moe.go
@@ -829,6 +829,63 @@ func logout(w http.ResponseWriter, r *http.Request) {
}
var (
+ //go:embed templates/otp.html.template
+ otpString string
+ otpTemplate = template.Must(outlinedTemplate(otpString))
+
+ otpMu sync.Mutex
+ currentOTP string
+)
+
+type otpTemplateArgs struct {
+ URL string
+ QR string
+}
+
+func otp(w http.ResponseWriter, r *http.Request) {
+ buf := make([]byte, 20)
+ rand.Read(buf)
+ newOTP := new(strings.Builder)
+ for i := range 10 {
+ if i > 0 {
+ newOTP.WriteString("-")
+ }
+ newOTP.WriteString(wordlist.Words[binary.NativeEndian.Uint16(buf[2*i:])&0x1fff])
+ }
+ otpMu.Lock()
+ currentOTP = newOTP.String()
+ otpMu.Unlock()
+ downloadURL := selfURL.String() + "/otp/" + newOTP.String()
+ if err := otpTemplate.Execute(w, otpTemplateArgs{
+ URL: downloadURL,
+ QR: "/qr.png?" + url.Values{"t": []string{downloadURL}, "s": []string{base64.RawURLEncoding.EncodeToString(mac([]byte(downloadURL), "qr"))}}.Encode(),
+ }); err != nil {
+ log.Printf("Warning: otp: %s", err)
+ }
+}
+
+func otpCode(w http.ResponseWriter, r *http.Request) {
+ code := r.PathValue("code")
+ if code == "" {
+ notFound(w, r)
+ return
+ }
+ matched := false
+ otpMu.Lock()
+ if code == currentOTP {
+ currentOTP = ""
+ matched = true
+ }
+ otpMu.Unlock()
+ if !matched {
+ notFound(w, r)
+ return
+ }
+ attachCookie(w)
+ io.WriteString(w, "logged in\n")
+}
+
+var (
//go:embed templates/note.html.template
notepadString string
notepadTemplate = template.Must(outlinedTemplate(notepadString))
@@ -1140,6 +1197,8 @@ func main() {
mux.HandleFunc("GET /wormhole/{hole}", wormholeDownload)
mux.HandleFunc("GET /login", serveLogin)
mux.HandleFunc("POST /login", login)
+ mux.Handle("GET /otp", &authHandler{h: http.HandlerFunc(otp)})
+ mux.HandleFunc("GET /otp/{code}", otpCode)
mux.Handle("GET /logout", &authHandler{h: http.HandlerFunc(logout), noRedirect: true})
mux.Handle("GET /notepad", &authHandler{h: http.HandlerFunc(notepad)})
mux.Handle("POST /notepad", &authHandler{h: http.HandlerFunc(autosave), noRedirect: true})
diff --git a/templates/otp.html.template b/templates/otp.html.template
new file mode 100644
index 0000000..3b765f7
--- /dev/null
+++ b/templates/otp.html.template
@@ -0,0 +1,6 @@
+<title>OTP</title>
+
+<div style="display:flex;flex-direction:column;align-items:center;font-size:50px">
+ <p><a href="{{.URL}}">{{.URL}}</a></p>
+ <img src="{{.QR}}" alt="QR code for {{.URL}}" width="500px">
+</div>