Remove OTP code

This commit is contained in:
Melon 2023-12-17 15:28:00 +00:00
parent fe29128ad2
commit f00d1c4a51
Signed by: melon
GPG Key ID: 6C9D970C50D26A25
4 changed files with 98 additions and 0 deletions

View File

@ -167,6 +167,10 @@ WHERE subject = ?`,
} }
func (t *Tx) SetTwoFactor(sub uuid.UUID, secret string, digits int) error { func (t *Tx) SetTwoFactor(sub uuid.UUID, secret string, digits int) error {
if secret == "" && digits == 0 {
_, err := t.tx.Exec(`DELETE FROM otp WHERE otp.subject = ?`, sub.String())
return err
}
_, err := t.tx.Exec(`INSERT INTO otp(subject, secret, digits) VALUES (?, ?, ?) ON CONFLICT(subject) DO UPDATE SET secret = excluded.secret, digits = excluded.digits`, sub.String(), secret, digits) _, err := t.tx.Exec(`INSERT INTO otp(subject, secret, digits) VALUES (?, ?, ?) ON CONFLICT(subject) DO UPDATE SET secret = excluded.secret, digits = excluded.digits`, sub.String(), secret, digits)
return err return err
} }

21
pages/remove-otp.go.html Normal file
View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{.ServiceName}}</title>
</head>
<body>
<header>
<h1>{{.ServiceName}}</h1>
</header>
<main>
<form method="POST" action="/edit/otp">
<input type="hidden" name="remove" value="1"/>
<div>
<label for="field_code">OTP Code:</label>
<input type="text" name="code" id="field_code" required autofocus pattern="[0-9]{6,8}" title="6/7/8 digit one time passcode"/>
</div>
<button type="submit">Remove OTP</button>
</form>
</main>
</body>
</html>

View File

@ -0,0 +1,49 @@
package server
import (
"context"
"errors"
"fmt"
"github.com/go-oauth2/oauth2/v4"
)
var _ oauth2.TokenStore = &TestingStruct{}
type TestingStruct struct {
}
func (t TestingStruct) Create(ctx context.Context, info oauth2.TokenInfo) error {
fmt.Println(info.GetAccessExpiresIn())
fmt.Println(info.GetRefreshExpiresIn())
return errors.New("error")
}
func (t TestingStruct) RemoveByCode(ctx context.Context, code string) error {
//TODO implement me
panic("implement me")
}
func (t TestingStruct) RemoveByAccess(ctx context.Context, access string) error {
//TODO implement me
panic("implement me")
}
func (t TestingStruct) RemoveByRefresh(ctx context.Context, refresh string) error {
//TODO implement me
panic("implement me")
}
func (t TestingStruct) GetByCode(ctx context.Context, code string) (oauth2.TokenInfo, error) {
//TODO implement me
panic("implement me")
}
func (t TestingStruct) GetByAccess(ctx context.Context, access string) (oauth2.TokenInfo, error) {
//TODO implement me
panic("implement me")
}
func (t TestingStruct) GetByRefresh(ctx context.Context, refresh string) (oauth2.TokenInfo, error) {
//TODO implement me
panic("implement me")
}

View File

@ -76,6 +76,30 @@ func (h *HttpServer) fetchAndValidateOtp(rw http.ResponseWriter, sub uuid.UUID,
} }
func (h *HttpServer) EditOtpPost(rw http.ResponseWriter, req *http.Request, _ httprouter.Params, auth UserAuth) { func (h *HttpServer) EditOtpPost(rw http.ResponseWriter, req *http.Request, _ httprouter.Params, auth UserAuth) {
if req.Method == http.MethodPost && req.FormValue("remove") == "1" {
if !req.Form.Has("code") {
// render page
pages.RenderPageTemplate(rw, "remove-otp", map[string]any{
"ServiceName": h.conf.ServiceName,
})
return
}
otpInput := req.Form.Get("code")
if h.fetchAndValidateOtp(rw, auth.Data.ID, otpInput) {
return
}
if h.DbTx(rw, func(tx *database.Tx) error {
return tx.SetTwoFactor(auth.Data.ID, "", 0)
}) {
return
}
http.Redirect(rw, req, "/", http.StatusFound)
return
}
var digits int var digits int
switch req.FormValue("digits") { switch req.FormValue("digits") {
case "6": case "6":