mirror of
https://github.com/1f349/lavender.git
synced 2024-12-22 07:34:06 +00:00
Return to logged out with fetchUserInfo fails, updates to test client
This commit is contained in:
parent
b47d4c8ad3
commit
e1825ce1e8
3
go.mod
3
go.mod
@ -14,6 +14,7 @@ require (
|
|||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/julienschmidt/httprouter v1.3.0
|
github.com/julienschmidt/httprouter v1.3.0
|
||||||
github.com/mattn/go-sqlite3 v1.14.22
|
github.com/mattn/go-sqlite3 v1.14.22
|
||||||
|
github.com/rs/cors v1.10.1
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
golang.org/x/oauth2 v0.16.0
|
golang.org/x/oauth2 v0.16.0
|
||||||
)
|
)
|
||||||
@ -35,7 +36,7 @@ require (
|
|||||||
github.com/tidwall/pretty v1.2.1 // indirect
|
github.com/tidwall/pretty v1.2.1 // indirect
|
||||||
github.com/tidwall/rtred v0.1.2 // indirect
|
github.com/tidwall/rtred v0.1.2 // indirect
|
||||||
github.com/tidwall/tinyqueue v0.1.1 // indirect
|
github.com/tidwall/tinyqueue v0.1.1 // indirect
|
||||||
golang.org/x/net v0.20.0 // indirect
|
golang.org/x/net v0.21.0 // indirect
|
||||||
google.golang.org/appengine v1.6.8 // indirect
|
google.golang.org/appengine v1.6.8 // indirect
|
||||||
google.golang.org/protobuf v1.32.0 // indirect
|
google.golang.org/protobuf v1.32.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
6
go.sum
6
go.sum
@ -100,6 +100,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
|||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||||
|
github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo=
|
||||||
|
github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||||
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
|
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
|
||||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||||
@ -177,8 +179,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
|||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
|
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
|
||||||
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
|
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
|
||||||
|
@ -12,13 +12,11 @@
|
|||||||
<div>Log in as: <span>{{.LoginName}}</span></div>
|
<div>Log in as: <span>{{.LoginName}}</span></div>
|
||||||
<div>
|
<div>
|
||||||
<form method="POST" action="/login">
|
<form method="POST" action="/login">
|
||||||
<input type="hidden" name="origin" value="{{.Origin}}"/>
|
|
||||||
<button type="submit" name="not-you" value="1">Not You?</button>
|
<button type="submit" name="not-you" value="1">Not You?</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<form method="POST" action="/login">
|
<form method="POST" action="/login">
|
||||||
<input type="hidden" name="origin" value="{{.Origin}}"/>
|
|
||||||
<input type="hidden" name="loginname" value="{{.LoginName}}"/>
|
<input type="hidden" name="loginname" value="{{.LoginName}}"/>
|
||||||
<button type="submit">Continue</button>
|
<button type="submit">Continue</button>
|
||||||
</form>
|
</form>
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<form method="POST" action="/login">
|
<form method="POST" action="/login">
|
||||||
<input type="hidden" name="origin" value="{{.Origin}}"/>
|
|
||||||
<div>
|
<div>
|
||||||
<label for="field_loginname">Login Name:</label>
|
<label for="field_loginname">Login Name:</label>
|
||||||
<input type="text" name="loginname" id="field_loginname" required/>
|
<input type="text" name="loginname" id="field_loginname" required/>
|
||||||
|
@ -67,8 +67,9 @@ func (h *HttpServer) OptionalAuthentication(next UserHandler) httprouter.Handle
|
|||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if auth.IsGuest() && h.readLoginDataCookie(rw, req, &auth) {
|
if auth.IsGuest() {
|
||||||
return
|
// if this fails internally it just sees the user as logged out
|
||||||
|
h.readLoginDataCookie(rw, req, &auth)
|
||||||
}
|
}
|
||||||
next(rw, req, params, auth)
|
next(rw, req, params, auth)
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,12 @@ func (h *HttpServer) loginGet(rw http.ResponseWriter, req *http.Request, _ httpr
|
|||||||
if err == nil && cookie.Valid() == nil {
|
if err == nil && cookie.Valid() == nil {
|
||||||
pages.RenderPageTemplate(rw, "login-memory", map[string]any{
|
pages.RenderPageTemplate(rw, "login-memory", map[string]any{
|
||||||
"ServiceName": h.conf.ServiceName,
|
"ServiceName": h.conf.ServiceName,
|
||||||
"Origin": req.URL.Query().Get("origin"),
|
|
||||||
"LoginName": cookie.Value,
|
"LoginName": cookie.Value,
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pages.RenderPageTemplate(rw, "login", map[string]any{
|
pages.RenderPageTemplate(rw, "login", map[string]any{
|
||||||
"ServiceName": h.conf.ServiceName,
|
"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{
|
http.Redirect(rw, req, (&url.URL{
|
||||||
Path: "/login",
|
Path: "/login",
|
||||||
RawQuery: url.Values{
|
|
||||||
"origin": []string{req.PostFormValue("origin")},
|
|
||||||
}.Encode(),
|
|
||||||
}).String(), http.StatusFound)
|
}).String(), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -111,8 +106,9 @@ func (h *HttpServer) loginCallback(rw http.ResponseWriter, req *http.Request, _
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionData, done := h.fetchUserInfo(rw, err, flowState.sso, token)
|
sessionData := h.fetchUserInfo(rw, err, flowState.sso, token)
|
||||||
if !done {
|
if sessionData.ID == "" {
|
||||||
|
http.Error(rw, "Failed to fetch user info", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,63 +162,57 @@ func (h *HttpServer) setLoginDataCookie(rw http.ResponseWriter, userId string, t
|
|||||||
return false
|
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")
|
loginCookie, err := req.Cookie("lavender-login-data")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
decryptedBytes, err := base64.RawStdEncoding.DecodeString(loginCookie.Value)
|
decryptedBytes, err := base64.RawStdEncoding.DecodeString(loginCookie.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
decryptedData, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, h.signingKey.PrivateKey(), decryptedBytes, []byte("lavender-login-data"))
|
decryptedData, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, h.signingKey.PrivateKey(), decryptedBytes, []byte("lavender-login-data"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := bytes.NewBuffer(decryptedData)
|
buf := bytes.NewBuffer(decryptedData)
|
||||||
userId, err := buf.ReadString(0)
|
userId, err := buf.ReadString(0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
userId = strings.TrimSuffix(userId, "\x00")
|
userId = strings.TrimSuffix(userId, "\x00")
|
||||||
|
|
||||||
var token *oauth2.Token
|
var token *oauth2.Token
|
||||||
err = json.NewDecoder(buf).Decode(&token)
|
err = json.NewDecoder(buf).Decode(&token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sso := h.manager.FindServiceFromLogin(userId)
|
sso := h.manager.FindServiceFromLogin(userId)
|
||||||
if sso == nil {
|
if sso == nil {
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionData, done := h.fetchUserInfo(rw, err, sso, token)
|
u.Data = h.fetchUserInfo(rw, err, sso, token)
|
||||||
if !done {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
u.Data = sessionData
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
res, err := sso.OAuth2Config.Client(context.Background(), token).Get(sso.UserInfoEndpoint)
|
||||||
if err != nil || res.StatusCode != http.StatusOK {
|
if err != nil || res.StatusCode != http.StatusOK {
|
||||||
return SessionData{}, false
|
return SessionData{}
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
var userInfoJson UserInfoFields
|
var userInfoJson UserInfoFields
|
||||||
if err := json.NewDecoder(res.Body).Decode(&userInfoJson); err != nil {
|
if err := json.NewDecoder(res.Body).Decode(&userInfoJson); err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
return SessionData{}, false
|
return SessionData{}
|
||||||
}
|
}
|
||||||
subject, ok := userInfoJson.GetString("sub")
|
subject, ok := userInfoJson.GetString("sub")
|
||||||
if !ok {
|
if !ok {
|
||||||
http.Error(rw, "Invalid subject", http.StatusInternalServerError)
|
http.Error(rw, "Invalid subject", http.StatusInternalServerError)
|
||||||
return SessionData{}, false
|
return SessionData{}
|
||||||
}
|
}
|
||||||
subject += "@" + sso.Config.Namespace
|
subject += "@" + sso.Config.Namespace
|
||||||
|
|
||||||
@ -231,5 +221,5 @@ func (h *HttpServer) fetchUserInfo(rw http.ResponseWriter, err error, sso *issue
|
|||||||
ID: subject,
|
ID: subject,
|
||||||
DisplayName: displayName,
|
DisplayName: displayName,
|
||||||
UserInfo: userInfoJson,
|
UserInfo: userInfoJson,
|
||||||
}, true
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,15 @@ func NewHttpServer(conf Conf, db *database.DB, signingKey mjwt.Signer) *http.Ser
|
|||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
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)
|
token, err := oauthSrv.ValidationBearerToken(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(rw, "403 Forbidden", http.StatusForbidden)
|
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()
|
m["updated_at"] = time.Now().Unix()
|
||||||
|
|
||||||
_ = json.NewEncoder(rw).Encode(m)
|
_ = json.NewEncoder(rw).Encode(m)
|
||||||
})
|
}
|
||||||
|
r.GET("/userinfo", userInfoRequest)
|
||||||
|
r.OPTIONS("/userinfo", userInfoRequest)
|
||||||
|
|
||||||
return &http.Server{
|
return &http.Server{
|
||||||
Addr: conf.Listen,
|
Addr: conf.Listen,
|
||||||
|
@ -1,92 +1,72 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>Test Client</title>
|
<title>Test Client</title>
|
||||||
<script src="popup.js"></script>
|
<script src="pop2.js"></script>
|
||||||
<script>
|
<script>
|
||||||
let currentTokens = null;
|
const ssoService = "http://localhost:9090";
|
||||||
const ssoService = "http://localhost:9090";
|
|
||||||
|
|
||||||
POP2.init(ssoService + "/authorize", "f4cdb93d-fe28-427b-b037-f03f44c86a16", "openid profile", 500, 600);
|
POP2.init(ssoService + "/authorize", "f4cdb93d-fe28-427b-b037-f03f44c86a16", "openid profile", 500, 600);
|
||||||
|
|
||||||
function updateTokenInfo(data) {
|
function updateTokenInfo(data) {
|
||||||
currentTokens = data.tokens;
|
document.getElementById("someTextArea").textContent = JSON.stringify(data, null, 2);
|
||||||
data.tokens = {
|
}
|
||||||
access: "*****",
|
|
||||||
refresh: "*****",
|
|
||||||
}
|
|
||||||
document.getElementById("someTextArea").textContent = JSON.stringify(data, null, 2);
|
|
||||||
let perms = document.getElementById("somePerms");
|
|
||||||
while (perms.childNodes.length > 0) {
|
|
||||||
perms.childNodes.item(0).remove();
|
|
||||||
}
|
|
||||||
document.getElementById("tokenValues").textContent = JSON.stringify(currentTokens, null, 2);
|
|
||||||
|
|
||||||
let jwt = parseJwt(currentTokens.access);
|
function parseJwt(token) {
|
||||||
if (jwt.per != null) {
|
const base64Url = token.split('.')[1];
|
||||||
jwt.per.forEach(function (x) {
|
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
||||||
let a = document.createElement("li");
|
const jsonPayload = decodeURIComponent(window.atob(base64).split('').map(function (c) {
|
||||||
a.textContent = x;
|
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||||
perms.appendChild(a);
|
}).join(''));
|
||||||
});
|
return JSON.parse(jsonPayload);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function parseJwt(token) {
|
function doThisThing() {
|
||||||
const base64Url = token.split('.')[1];
|
POP2.clientRequest(ssoService + "/userinfo", {}, true).then(function (x) {
|
||||||
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
console.log(x);
|
||||||
const jsonPayload = decodeURIComponent(window.atob(base64).split('').map(function (c) {
|
}).catch(function (x) {
|
||||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
console.error(x);
|
||||||
}).join(''));
|
});
|
||||||
return JSON.parse(jsonPayload);
|
}
|
||||||
}
|
</script>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
color-scheme: light dark;
|
||||||
|
}
|
||||||
|
|
||||||
function doThisThing() {
|
#someTextArea {
|
||||||
POP2.getToken(function (token) {
|
width: 400px;
|
||||||
console.log(token);
|
height: 400px;
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
#tokenValues {
|
||||||
</script>
|
width: 400px;
|
||||||
<style>
|
height: 400px;
|
||||||
:root {
|
}
|
||||||
color-scheme: light dark;
|
</style>
|
||||||
}
|
|
||||||
|
|
||||||
#someTextArea {
|
|
||||||
width: 400px;
|
|
||||||
height: 400px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#tokenValues {
|
|
||||||
width: 400px;
|
|
||||||
height: 400px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<h1>Test Client</h1>
|
<h1>Test Client</h1>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
|
<div>
|
||||||
|
<button onclick="doThisThing();">Login</button>
|
||||||
|
</div>
|
||||||
|
<div style="display:flex; gap: 2em;">
|
||||||
<div>
|
<div>
|
||||||
<button onclick="doThisThing();">Login</button>
|
<div>
|
||||||
|
<label for="someTextArea"></label><textarea id="someTextArea"></textarea>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="tokenValues"></label><textarea id="tokenValues"></textarea>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex; gap: 2em;">
|
<div>
|
||||||
<div>
|
<p>Permissions:</p>
|
||||||
<div>
|
<ul id="somePerms"></ul>
|
||||||
<label for="someTextArea"></label><textarea id="someTextArea"></textarea>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="tokenValues"></label><textarea id="tokenValues"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>Permissions:</p>
|
|
||||||
<ul id="somePerms"></ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -71,7 +71,7 @@
|
|||||||
client_id,
|
client_id,
|
||||||
scope = '',
|
scope = '',
|
||||||
redirect_uri = window.location.href.substr(0, window.location.href.length - window.location.hash.length).replace(/#$/, ''),
|
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,
|
callbackWaitForToken,
|
||||||
w_width = 400,
|
w_width = 400,
|
||||||
w_height = 360;
|
w_height = 360;
|
||||||
@ -91,10 +91,12 @@
|
|||||||
receiveToken: function (token, expires_in) {
|
receiveToken: function (token, expires_in) {
|
||||||
if (token !== 'ERROR') {
|
if (token !== 'ERROR') {
|
||||||
access_token = token;
|
access_token = token;
|
||||||
|
localStorage.setItem("pop2_access_token", access_token);
|
||||||
if (callbackWaitForToken) callbackWaitForToken(access_token);
|
if (callbackWaitForToken) callbackWaitForToken(access_token);
|
||||||
setTimeout(
|
setTimeout(
|
||||||
function () {
|
function () {
|
||||||
access_token = undefined;
|
access_token = undefined;
|
||||||
|
localStorage.removeItem("pop2_access_token");
|
||||||
},
|
},
|
||||||
expires_in * 1000
|
expires_in * 1000
|
||||||
);
|
);
|
||||||
@ -129,6 +131,31 @@
|
|||||||
} else {
|
} else {
|
||||||
return callback(access_token);
|
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);
|
Loading…
Reference in New Issue
Block a user