function fillTemplate(templateId, values) {
var tpl = document.getElementById(templateId).text;
Object.keys(values).forEach(key => {
tpl = tpl.replace(new RegExp("\\[\\[ \\." + key + " \\]\\]", "g"), values[key]);
});
var out = [];
tpl.split("\n").forEach(line => {
line = line.replace(/^\s+/, "").replace(/\s+$/, "");
if (line !== "") {
out.push(line);
}
});
return out.join("\n");
}
function getJSON(response) {
if (!response.ok) {
document.getElementById("api-error").style.display = "block";
throw new Error("Error loading api");
}
return response.json();
}
function accountTableLinkClick(event) {
event.preventDefault();
var thisRow = event.target.parentElement.parentElement;
var account = thisRow.dataset["accountName"];
var oldText = event.target.text;
var existingTr = document.getElementById("credentials-for-" + account);
if (existingTr) {
existingTr.remove();
}
event.target.text = "Loading...";
fetch(thisRow.dataset["globalCredentialEndpoint"], {
"headers": {
"Accept": event.target.dataset["contentType"]
}
}).then(r => r.text()).then(text => {
var newTr = fillTemplate("credential_row_template", {
"Account": account,
"Content": text,
});
event.target.text = oldText;
thisRow.insertAdjacentHTML("afterend", newTr);
thisRow.nextElementSibling.getElementsByTagName("button")[0].addEventListener("click", e => {
e.target.parentNode.parentNode.remove();
});
});
return false;
}
function populateUserRow(row) {
var [key, value] = row;
var tokens = "";
if (value.is_admin) {
tokens += 'Admin';
}
if (value.is_service) {
tokens += 'Service';
}
var out = fillTemplate("user_row_template", {
"username": key,
"tokens": tokens,
});
document.querySelector("#user-table tr").insertAdjacentHTML("afterend", out);
}
function populateAccountRow(row) {
document.querySelector("#account-table tr").insertAdjacentHTML("afterend",
fillTemplate(row["vendor"] + "_account_row_template", row));
document.querySelectorAll(".account-row a[data-content-type]").forEach(e => {
e.addEventListener("click", accountTableLinkClick);
});
}
function getCookie(name) {
return document.cookie.match(new RegExp(name + "=\"?([^;\"]*)\"?;?"))[1];
}
function parseJWT() {
return JSON.parse(atob(getCookie("github-token").split(".")[1]));
}
function parseJWTExpires() {
return new Date(parseJWT()["exp"] * 1000);
}
function isAdmin() {
return parseJWT()["admin"];
}
function getApiUrl(formId) {
var urlParts = window.location.pathname.split("/");
if (urlParts.length != 3) {
return null;
}
var shortName = urlParts[urlParts.length-1];
return document.getElementById(formId).action + "/" + shortName;
}
function submitForm(target, url, method) {
var result = {};
target.querySelectorAll("form input, form select").forEach(e => {
if (e.selectedOptions !== undefined) {
var items = [];
Array.from(e.selectedOptions).forEach(i => items.push(i.value));
result[e.id] = items;
} else if (e.type == "number") {
result[e.id] = parseInt(e.value);
} else {
result[e.id] = e.value;
}
});
fetch(url, {
"method": method,
"headers": { "Content-Type": "application/vnd.broker.v2+json" },
"body": JSON.stringify(result)
})
.then(r => {
if (r.status < 299) {
return { "request": r };
} else {
return r.json().then(j => ({ "json": j, "request": r }))
}
})
.then(r => {
if (r.request.status > 299) {
document.getElementById("api-error").style.display = "block";
document.querySelector("#api-error .sub-message").innerText = r.json.message;
} else {
document.getElementById("api-success").style.display = "block";
}
})
.catch(_ => document.getElementById("api-error").style.display = "block");
}
function populateUsers(selected) {
fetch("/api/user")
.then(r => {
if (r.status == 404) {
return {};
}
// If they can't load the user endpoint they will not be able to submt updates
document.getElementById("submit-form").disabled = false;
return r.json()
})
.then(r => {
var e = document.getElementById("users");
Object.entries(r).forEach(([key, value]) => {
if (!selected[key]) {
var opt = document.createElement("option");
opt.value = key;
opt.innerText = key;
e.appendChild(opt);
}
});
})
.catch(_ => document.getElementById("api-error").style.display = "block");
}
function setupUserPage() {
document.getElementById("back").addEventListener('click', _ => window.location.pathname = "/");
document.getElementById("user-form").addEventListener('submit', e => e.preventDefault());
var apiUrl = getApiUrl("user-form");
if (apiUrl == null) {
document.getElementById("submit-form").addEventListener('click', e => {
var target = document.getElementById("user-form");
submitForm(target, target.action, "POST");
e.preventDefault();
return false;
});
} else {
document.getElementById("submit-form").addEventListener('click', e => {
var target = document.getElementById("user-form");
submitForm(target, getApiUrl(target.id), "PUT");
e.preventDefault();
return false;
});
fetch(apiUrl)
.then(r => r.json())
.then(r => {
Object.entries(r).forEach(([key, value]) => {
var e = document.getElementById(key);
if (e === null) {
return;
} else if (e.type == "text") {
e.value = value;
} else if (e.type == "checkbox") {
e.checked = value;
}
});
})
.catch(_ => document.getElementById("api-error").style.display = "block");
}
}
function setupManageAccount() {
document.getElementById("submit-form").disabled = true;
document.getElementById("back").addEventListener('click', _ => window.location.pathname = "/");
document.getElementById("account-form").addEventListener('submit', e => e.preventDefault());
var apiUrl = getApiUrl("account-form");
if (apiUrl == null) {
populateUsers({});
document.getElementById("submit-form").addEventListener('click', e => {
var target = document.getElementById("account-form");
submitForm(target, target.action, "POST");
e.preventDefault();
return false;
});
} else {
document.getElementById("submit-form").addEventListener('click', e => {
var target = document.getElementById("account-form");
submitForm(target, getApiUrl(target.id), "PUT");
e.preventDefault();
return false;
});
fetch(apiUrl)
.then(r => r.json())
.then(r => {
var selectedUsers = {};
Object.entries(r).forEach(([key, value]) => {
var e = document.getElementById(key);
if (e.type !== "select") {
e.value = value;
}
if (key == "users") {
value.forEach(v => {
var opt = document.createElement("option");
opt.value = v;
opt.selected = true;
opt.innerText = v;
e.appendChild(opt);
selectedUsers[v] = true;
});
}
});
return selectedUsers;
})
.then(populateUsers)
.catch(_ => document.getElementById("api-error").style.display = "block");
}
}
function setupHomePage() {
document.getElementById("add-account").addEventListener('click', _ => window.location.pathname = "/account");
document.getElementById("add-user").addEventListener('click', _ => window.location.pathname = "/user");
fetch("/api/account").then(getJSON).then(r => r.forEach(populateAccountRow));
document.getElementById("username").innerText = parseJWT()["sub"];
if (isAdmin()) {
document.body.classList.add("isAdmin");
fetch("/api/user").then(getJSON).then(r => Object.entries(r).forEach(populateUserRow));
}
document.getElementById("show-api-key").addEventListener("click", _ => {
document.querySelector("#api-key textarea").innerText = getCookie("github-token");
document.querySelector("#session-expires").innerText = parseJWTExpires();
document.getElementById("api-key-block").style.display = "block";
});
}