Fix test client not using refresh endpoint properly

This commit is contained in:
Melon 2023-12-13 02:05:18 +00:00
parent 182c424b33
commit b4787f22aa
Signed by: melon
GPG Key ID: 6C9D970C50D26A25
3 changed files with 119 additions and 112 deletions

View File

@ -5,11 +5,11 @@
<script> <script>
let loginData = { let loginData = {
target:{{.TargetOrigin}}, target:{{.TargetOrigin}},
userinfo:{{.TargetMessage}},
tokens: { tokens: {
access:{{.AccessToken}}, access:{{.AccessToken}},
refresh:{{.RefreshToken}}, refresh:{{.RefreshToken}},
}, },
userinfo:{{.TargetMessage}},
}; };
window.addEventListener("load", function () { window.addEventListener("load", function () {
window.opener.postMessage(loginData, loginData.target); window.opener.postMessage(loginData, loginData.target);

View File

@ -18,7 +18,7 @@ import (
"time" "time"
) )
func (h *HttpServer) refreshHandler(rw http.ResponseWriter, req *http.Request, params httprouter.Params) { func (h *HttpServer) refreshHandler(rw http.ResponseWriter, req *http.Request, _ httprouter.Params) {
ref := strings.TrimSuffix(req.Referer(), "/") ref := strings.TrimSuffix(req.Referer(), "/")
allowedClient, ok := (*h.services.Load())[ref] allowedClient, ok := (*h.services.Load())[ref]
if !ok { if !ok {

View File

@ -1,135 +1,142 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<title>Test Client</title> <title>Test Client</title>
<script> <script>
let currentLoginPopup = null; let currentLoginPopup = null;
let currentTokens = null; let currentTokens = null;
const ssoService = "http://localhost:9090"; const ssoService = "http://localhost:9090";
window.addEventListener("message", function (event) { function updateTokenInfo(data) {
if (event.origin !== ssoService) return; currentTokens = data.tokens;
if (isObject(event.data)) { data.tokens = {
document.getElementById("someTextArea").textContent = JSON.stringify(event.data, null, 2); access: "*****",
let perms = document.getElementById("somePerms"); refresh: "*****",
while (perms.childNodes.length > 0) { }
perms.childNodes.item(0).remove(); document.getElementById("someTextArea").textContent = JSON.stringify(data, null, 2);
} let perms = document.getElementById("somePerms");
currentTokens = event.data.tokens; while (perms.childNodes.length > 0) {
document.getElementById("tokenValues").textContent = JSON.stringify(currentTokens, null, 2); perms.childNodes.item(0).remove();
}
document.getElementById("tokenValues").textContent = JSON.stringify(currentTokens, null, 2);
let jwt = parseJwt(event.data.tokens.access); let jwt = parseJwt(currentTokens.access);
if (jwt.per != null) { if (jwt.per != null) {
jwt.per.forEach(function (x) { jwt.per.forEach(function (x) {
let a = document.createElement("li"); let a = document.createElement("li");
a.textContent = x; a.textContent = x;
perms.appendChild(a); perms.appendChild(a);
}); });
} }
}
if (currentLoginPopup) currentLoginPopup.close(); window.addEventListener("message", function (event) {
return; if (event.origin !== ssoService) return;
} if (isObject(event.data)) {
alert("Failed to log user in: the login data was probably corrupted"); updateTokenInfo(event.data);
});
function parseJwt(token) { if (currentLoginPopup) currentLoginPopup.close();
const base64Url = token.split('.')[1]; return;
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); }
const jsonPayload = decodeURIComponent(window.atob(base64).split('').map(function (c) { alert("Failed to log user in: the login data was probably corrupted");
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); });
}).join(''));
return JSON.parse(jsonPayload);
}
function isObject(obj) { function parseJwt(token) {
return obj != null && obj.constructor.name === "Object" const base64Url = token.split('.')[1];
} const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(window.atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
return JSON.parse(jsonPayload);
}
function popupCenterScreen(url, title, w, h, focus) { function isObject(obj) {
const top = (screen.availHeight - h) / 4, left = (screen.availWidth - w) / 2; return obj != null && obj.constructor.name === "Object"
const popup = openWindow(url, title, `scrollbars=yes,width=${w},height=${h},top=${top},left=${left}`); }
if (focus === true && window.focus) popup.focus();
return popup;
}
function openWindow(url, winnm, options) { function popupCenterScreen(url, title, w, h, focus) {
var wTop = firstAvailableValue([window.screen.availTop, window.screenY, window.screenTop, 0]); const top = (screen.availHeight - h) / 4, left = (screen.availWidth - w) / 2;
var wLeft = firstAvailableValue([window.screen.availLeft, window.screenX, window.screenLeft, 0]); const popup = openWindow(url, title, `scrollbars=yes,width=${w},height=${h},top=${top},left=${left}`);
var top = 0, left = 0; if (focus === true && window.focus) popup.focus();
var result; return popup;
if ((result = /top=(\d+)/g.exec(options))) top = parseInt(result[1]); }
if ((result = /left=(\d+)/g.exec(options))) left = parseInt(result[1]);
if (options) {
options = options.replace("top=" + top, "top=" + (parseInt(top) + wTop));
options = options.replace("left=" + left, "left=" + (parseInt(left) + wLeft));
w = window.open(url, winnm, options);
} else w = window.open(url, winnm);
return w;
}
function firstAvailableValue(arr) { function openWindow(url, winnm, options) {
for (var i = 0; i < arr.length; i++) var wTop = firstAvailableValue([window.screen.availTop, window.screenY, window.screenTop, 0]);
if (typeof arr[i] != 'undefined') var wLeft = firstAvailableValue([window.screen.availLeft, window.screenX, window.screenLeft, 0]);
return arr[i]; var top = 0, left = 0;
} var result;
if ((result = /top=(\d+)/g.exec(options))) top = parseInt(result[1]);
if ((result = /left=(\d+)/g.exec(options))) left = parseInt(result[1]);
if (options) {
options = options.replace("top=" + top, "top=" + (parseInt(top) + wTop));
options = options.replace("left=" + left, "left=" + (parseInt(left) + wLeft));
w = window.open(url, winnm, options);
} else w = window.open(url, winnm);
return w;
}
function doThisThing() { function firstAvailableValue(arr) {
if (currentLoginPopup) currentLoginPopup.close(); for (var i = 0; i < arr.length; i++)
currentLoginPopup = popupCenterScreen(ssoService + '/popup?origin=' + encodeURIComponent(location.origin), 'Login with Lavender', 500, 500, false); if (typeof arr[i] != 'undefined')
} return arr[i];
}
async function refreshAllTokens() { function doThisThing() {
let req = await fetch(ssoService + '/refresh', { if (currentLoginPopup) currentLoginPopup.close();
method: 'POST', currentLoginPopup = popupCenterScreen(ssoService + '/popup?origin=' + encodeURIComponent(location.origin), 'Login with Lavender', 500, 500, false);
mode: 'cors', }
cache: 'no-cache',
credentials: 'include',
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({"token": currentTokens.refresh}),
});
let reqJson = await req.json();
currentTokens = reqJson;
document.getElementById("tokenValues").textContent = JSON.stringify(currentTokens, null, 2);
}
</script>
<style>
#someTextArea {
width: 400px;
height: 400px;
}
#tokenValues { async function refreshAllTokens() {
width: 400px; let req = await fetch(ssoService + '/refresh', {
height: 400px; method: 'POST',
} mode: 'cors',
</style> cache: 'no-cache',
credentials: 'include',
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({"token": currentTokens.refresh}),
});
let reqJson = await req.json();
updateTokenInfo(reqJson);
}
</script>
<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>
<button onclick="refreshAllTokens();">Refresh</button>
</div>
<div style="display:flex; gap: 2em;">
<div> <div>
<button onclick="doThisThing();">Login</button> <div>
<button onclick="refreshAllTokens();">Refresh</button> <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>