challenge/resource-load: use proper redirect URL to current issued challenge, add static/dynamic cache bust
This commit is contained in:
@@ -8,7 +8,9 @@ import (
|
|||||||
"git.gammaspectra.live/git/go-away/utils"
|
"git.gammaspectra.live/git/go-away/utils"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrInvalidToken = errors.New("invalid token")
|
var ErrInvalidToken = errors.New("invalid token")
|
||||||
@@ -47,6 +49,7 @@ const (
|
|||||||
QueryArgRequestId = QueryArgPrefix + "_id"
|
QueryArgRequestId = QueryArgPrefix + "_id"
|
||||||
QueryArgChallenge = QueryArgPrefix + "_challenge"
|
QueryArgChallenge = QueryArgPrefix + "_challenge"
|
||||||
QueryArgToken = QueryArgPrefix + "_token"
|
QueryArgToken = QueryArgPrefix + "_token"
|
||||||
|
QueryArgBust = QueryArgPrefix + "_bust"
|
||||||
)
|
)
|
||||||
|
|
||||||
const MakeChallengeUrlSuffix = "/make-challenge"
|
const MakeChallengeUrlSuffix = "/make-challenge"
|
||||||
@@ -96,6 +99,7 @@ func VerifyUrl(r *http.Request, reg *Registration, token string) (*url.URL, erro
|
|||||||
values.Set(QueryArgRedirect, redirectUrl.String())
|
values.Set(QueryArgRedirect, redirectUrl.String())
|
||||||
values.Set(QueryArgToken, token)
|
values.Set(QueryArgToken, token)
|
||||||
values.Set(QueryArgChallenge, reg.Name)
|
values.Set(QueryArgChallenge, reg.Name)
|
||||||
|
values.Set(QueryArgBust, strconv.FormatInt(time.Now().UTC().UnixMilli(), 10))
|
||||||
uri.RawQuery = values.Encode()
|
uri.RawQuery = values.Encode()
|
||||||
|
|
||||||
return uri, nil
|
return uri, nil
|
||||||
|
|||||||
@@ -23,9 +23,13 @@ func FillRegistrationHeader(state challenge.StateInterface, reg *challenge.Regis
|
|||||||
return challenge.VerifyResultFail
|
return challenge.VerifyResultFail
|
||||||
}
|
}
|
||||||
|
|
||||||
|
redirectUri, err := challenge.RedirectUrl(r, reg)
|
||||||
|
if err != nil {
|
||||||
|
return challenge.VerifyResultFail
|
||||||
|
}
|
||||||
// self redirect!
|
// self redirect!
|
||||||
//TODO: adjust deadline
|
//TODO: adjust deadline
|
||||||
w.Header().Set("Refresh", "2; url="+r.URL.String())
|
w.Header().Set("Refresh", "2; url="+redirectUri.String())
|
||||||
|
|
||||||
state.ChallengePage(w, r, state.Settings().ChallengeResponseCode, reg, map[string]any{
|
state.ChallengePage(w, r, state.Settings().ChallengeResponseCode, reg, map[string]any{
|
||||||
"LinkTags": []map[string]string{
|
"LinkTags": []map[string]string{
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ func ServeChallengeScript(w http.ResponseWriter, r *http.Request, reg *Registrat
|
|||||||
//TODO: log
|
//TODO: log
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data.ResponseHeaders(w)
|
data.ResponseHeaders(w)
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ func ServeChallengeScript(w http.ResponseWriter, r *http.Request, reg *Registrat
|
|||||||
"Id": data.Id.String(),
|
"Id": data.Id.String(),
|
||||||
"Path": reg.Path,
|
"Path": reg.Path,
|
||||||
"Parameters": paramData,
|
"Parameters": paramData,
|
||||||
"Random": utils.CacheBust(),
|
"Random": utils.StaticCacheBust(),
|
||||||
"Challenge": reg.Name,
|
"Challenge": reg.Name,
|
||||||
"ChallengeScript": script,
|
"ChallengeScript": script,
|
||||||
"Strings": data.State.Strings(),
|
"Strings": data.State.Strings(),
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ func FillJavaScriptRegistration(state challenge.StateInterface, reg *challenge.R
|
|||||||
reg.IssueChallenge = func(w http.ResponseWriter, r *http.Request, key challenge.Key, expiry time.Time) challenge.VerifyResult {
|
reg.IssueChallenge = func(w http.ResponseWriter, r *http.Request, key challenge.Key, expiry time.Time) challenge.VerifyResult {
|
||||||
state.ChallengePage(w, r, state.Settings().ChallengeResponseCode, reg, map[string]any{
|
state.ChallengePage(w, r, state.Settings().ChallengeResponseCode, reg, map[string]any{
|
||||||
"EndTags": []template.HTML{
|
"EndTags": []template.HTML{
|
||||||
template.HTML(fmt.Sprintf("<script async type=\"module\" src=\"%s?cacheBust=%s\"></script>", reg.Path+"/script.mjs", utils.CacheBust())),
|
template.HTML(fmt.Sprintf("<script async type=\"module\" src=\"%s?cacheBust=%s\"></script>", reg.Path+"/script.mjs", utils.StaticCacheBust())),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return challenge.VerifyResultNone
|
return challenge.VerifyResultNone
|
||||||
@@ -164,6 +164,8 @@ func FillJavaScriptRegistration(state challenge.StateInterface, reg *challenge.R
|
|||||||
w.Header()[k] = v
|
w.Header()[k] = v
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(out.Data)))
|
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(out.Data)))
|
||||||
|
|
||||||
|
data.ResponseHeaders(w)
|
||||||
w.WriteHeader(out.Code)
|
w.WriteHeader(out.Code)
|
||||||
_, _ = w.Write(out.Data)
|
_, _ = w.Write(out.Data)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ func (state *State) ChallengePage(w http.ResponseWriter, r *http.Request, status
|
|||||||
data := challenge.RequestDataFromContext(r.Context())
|
data := challenge.RequestDataFromContext(r.Context())
|
||||||
input := make(map[string]any)
|
input := make(map[string]any)
|
||||||
input["Id"] = data.Id.String()
|
input["Id"] = data.Id.String()
|
||||||
input["Random"] = utils.CacheBust()
|
input["Random"] = utils.StaticCacheBust()
|
||||||
|
|
||||||
input["Path"] = state.UrlPath()
|
input["Path"] = state.UrlPath()
|
||||||
input["Links"] = state.opt.Links
|
input["Links"] = state.opt.Links
|
||||||
@@ -121,7 +121,7 @@ func (state *State) ErrorPage(w http.ResponseWriter, r *http.Request, status int
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"Id": data.Id.String(),
|
"Id": data.Id.String(),
|
||||||
"Random": utils.CacheBust(),
|
"Random": utils.StaticCacheBust(),
|
||||||
"Error": err.Error(),
|
"Error": err.Error(),
|
||||||
"Path": state.UrlPath(),
|
"Path": state.UrlPath(),
|
||||||
"Theme": "",
|
"Theme": "",
|
||||||
|
|||||||
@@ -167,15 +167,14 @@ func GetRemoteAddress(ctx context.Context) *netip.AddrPort {
|
|||||||
return &ip
|
return &ip
|
||||||
}
|
}
|
||||||
|
|
||||||
func CacheBust() string {
|
func RandomCacheBust(n int) string {
|
||||||
return cacheBust
|
buf := make([]byte, n)
|
||||||
}
|
|
||||||
|
|
||||||
var cacheBust string
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
|
|
||||||
buf := make([]byte, 16)
|
|
||||||
_, _ = rand.Read(buf)
|
_, _ = rand.Read(buf)
|
||||||
cacheBust = base64.RawURLEncoding.EncodeToString(buf)
|
return base64.RawURLEncoding.EncodeToString(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
var staticCacheBust = RandomCacheBust(16)
|
||||||
|
|
||||||
|
func StaticCacheBust() string {
|
||||||
|
return staticCacheBust
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user