diff --git a/server/auth.go b/server/auth.go
index 8d0f106..d85ffb5 100644
--- a/server/auth.go
+++ b/server/auth.go
@@ -67,8 +67,9 @@ func (h *HttpServer) OptionalAuthentication(next UserHandler) httprouter.Handle
http.Error(rw, err.Error(), http.StatusInternalServerError)
return
}
- if auth.IsGuest() && h.readLoginDataCookie(rw, req, &auth) {
- return
+ if auth.IsGuest() {
+ // if this fails internally it just sees the user as logged out
+ h.readLoginDataCookie(rw, req, &auth)
}
next(rw, req, params, auth)
}
diff --git a/server/login.go b/server/login.go
index 2d5cca2..653c85d 100644
--- a/server/login.go
+++ b/server/login.go
@@ -32,14 +32,12 @@ func (h *HttpServer) loginGet(rw http.ResponseWriter, req *http.Request, _ httpr
if err == nil && cookie.Valid() == nil {
pages.RenderPageTemplate(rw, "login-memory", map[string]any{
"ServiceName": h.conf.ServiceName,
- "Origin": req.URL.Query().Get("origin"),
"LoginName": cookie.Value,
})
return
}
pages.RenderPageTemplate(rw, "login", map[string]any{
"ServiceName": h.conf.ServiceName,
- "Origin": req.URL.Query().Get("origin"),
})
}
@@ -60,9 +58,6 @@ func (h *HttpServer) loginPost(rw http.ResponseWriter, req *http.Request, _ http
})
http.Redirect(rw, req, (&url.URL{
Path: "/login",
- RawQuery: url.Values{
- "origin": []string{req.PostFormValue("origin")},
- }.Encode(),
}).String(), http.StatusFound)
return
}
@@ -111,8 +106,9 @@ func (h *HttpServer) loginCallback(rw http.ResponseWriter, req *http.Request, _
return
}
- sessionData, done := h.fetchUserInfo(rw, err, flowState.sso, token)
- if !done {
+ sessionData := h.fetchUserInfo(rw, err, flowState.sso, token)
+ if sessionData.ID == "" {
+ http.Error(rw, "Failed to fetch user info", http.StatusInternalServerError)
return
}
@@ -166,63 +162,57 @@ func (h *HttpServer) setLoginDataCookie(rw http.ResponseWriter, userId string, t
return false
}
-func (h *HttpServer) readLoginDataCookie(rw http.ResponseWriter, req *http.Request, u *UserAuth) bool {
+func (h *HttpServer) readLoginDataCookie(rw http.ResponseWriter, req *http.Request, u *UserAuth) {
loginCookie, err := req.Cookie("lavender-login-data")
if err != nil {
- return false
+ return
}
decryptedBytes, err := base64.RawStdEncoding.DecodeString(loginCookie.Value)
if err != nil {
- return false
+ return
}
decryptedData, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, h.signingKey.PrivateKey(), decryptedBytes, []byte("lavender-login-data"))
if err != nil {
- return false
+ return
}
buf := bytes.NewBuffer(decryptedData)
userId, err := buf.ReadString(0)
if err != nil {
- return false
+ return
}
userId = strings.TrimSuffix(userId, "\x00")
var token *oauth2.Token
err = json.NewDecoder(buf).Decode(&token)
if err != nil {
- return false
+ return
}
sso := h.manager.FindServiceFromLogin(userId)
if sso == nil {
- return false
+ return
}
- sessionData, done := h.fetchUserInfo(rw, err, sso, token)
- if !done {
- return true
- }
-
- u.Data = sessionData
- return false
+ u.Data = h.fetchUserInfo(rw, err, sso, token)
}
-func (h *HttpServer) fetchUserInfo(rw http.ResponseWriter, err error, sso *issuer.WellKnownOIDC, token *oauth2.Token) (SessionData, bool) {
+func (h *HttpServer) fetchUserInfo(rw http.ResponseWriter, err error, sso *issuer.WellKnownOIDC, token *oauth2.Token) SessionData {
res, err := sso.OAuth2Config.Client(context.Background(), token).Get(sso.UserInfoEndpoint)
if err != nil || res.StatusCode != http.StatusOK {
- return SessionData{}, false
+ return SessionData{}
}
defer res.Body.Close()
var userInfoJson UserInfoFields
if err := json.NewDecoder(res.Body).Decode(&userInfoJson); err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
- return SessionData{}, false
+ return SessionData{}
}
subject, ok := userInfoJson.GetString("sub")
if !ok {
http.Error(rw, "Invalid subject", http.StatusInternalServerError)
- return SessionData{}, false
+ return SessionData{}
}
subject += "@" + sso.Config.Namespace
@@ -231,5 +221,5 @@ func (h *HttpServer) fetchUserInfo(rw http.ResponseWriter, err error, sso *issue
ID: subject,
DisplayName: displayName,
UserInfo: userInfoJson,
- }, true
+ }
}
diff --git a/server/server.go b/server/server.go
index 7d466db..08f2b8e 100644
--- a/server/server.go
+++ b/server/server.go
@@ -169,7 +169,15 @@ func NewHttpServer(conf Conf, db *database.DB, signingKey mjwt.Signer) *http.Ser
http.Error(rw, err.Error(), http.StatusInternalServerError)
}
})
- r.GET("/userinfo", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params) {
+ userInfoRequest := func(rw http.ResponseWriter, req *http.Request, _ httprouter.Params) {
+ rw.Header().Set("Access-Control-Allow-Credentials", "true")
+ rw.Header().Set("Access-Control-Allow-Headers", "Authorization,Content-Type")
+ rw.Header().Set("Access-Control-Allow-Origin", strings.TrimSuffix(req.Referer(), "/"))
+ rw.Header().Set("Access-Control-Allow-Methods", "GET")
+ if req.Method == http.MethodOptions {
+ return
+ }
+
token, err := oauthSrv.ValidationBearerToken(req)
if err != nil {
http.Error(rw, "403 Forbidden", http.StatusForbidden)
@@ -190,7 +198,9 @@ func NewHttpServer(conf Conf, db *database.DB, signingKey mjwt.Signer) *http.Ser
m["updated_at"] = time.Now().Unix()
_ = json.NewEncoder(rw).Encode(m)
- })
+ }
+ r.GET("/userinfo", userInfoRequest)
+ r.OPTIONS("/userinfo", userInfoRequest)
return &http.Server{
Addr: conf.Listen,
diff --git a/server/userinfo.go b/server/userinfofields.go
similarity index 100%
rename from server/userinfo.go
rename to server/userinfofields.go
diff --git a/test-client/index.html b/test-client/index.html
index 26b9261..adc7413 100644
--- a/test-client/index.html
+++ b/test-client/index.html
@@ -1,92 +1,72 @@
-
Test Client
-
-
+
+
+ #tokenValues {
+ width: 400px;
+ height: 400px;
+ }
+
- Test Client
+ Test Client
+
+
+
+
-
diff --git a/test-client/popup.js b/test-client/pop2.js
similarity index 80%
rename from test-client/popup.js
rename to test-client/pop2.js
index e1d8e0c..f1c30d1 100644
--- a/test-client/popup.js
+++ b/test-client/pop2.js
@@ -71,7 +71,7 @@
client_id,
scope = '',
redirect_uri = window.location.href.substr(0, window.location.href.length - window.location.hash.length).replace(/#$/, ''),
- access_token,
+ access_token = localStorage.getItem("pop2_access_token"),
callbackWaitForToken,
w_width = 400,
w_height = 360;
@@ -91,10 +91,12 @@
receiveToken: function (token, expires_in) {
if (token !== 'ERROR') {
access_token = token;
+ localStorage.setItem("pop2_access_token", access_token);
if (callbackWaitForToken) callbackWaitForToken(access_token);
setTimeout(
function () {
access_token = undefined;
+ localStorage.removeItem("pop2_access_token");
},
expires_in * 1000
);
@@ -129,6 +131,31 @@
} else {
return callback(access_token);
}
+ },
+ clientRequest: function (resource, options, refresh = false) {
+ const sendRequest = function () {
+ options.credentials = 'include';
+ if (options.headers) {
+ options.headers['Authorization'] = 'Bearer ' + access_token;
+ }
+ return fetch(resource, options);
+ };
+ if (!refresh) return sendRequest();
+ else {
+ return new Promise(function (res, rej) {
+ sendRequest().then(function (x) {
+ res(x)
+ }).catch(function () {
+ w.POP2.getToken(function () {
+ sendRequest().then(function (x) {
+ res(x);
+ }).catch(function (x) {
+ rej(x);
+ });
+ })
+ });
+ });
+ }
}
};
-})(this);
+})(window);