static.js.palantir.js Maven / Gradle / Ivy
const DEFAULT_INTERVAL = 15000;
/**
* Internal Functions
*/
const Tabs = {
APPLICATIONS: 0,
SYSTEM: 1,
TICKETS: 2,
TASKS: 3,
ACCESS_STRATEGY: 4,
LOGGING: 5,
SSO_SESSIONS: 6,
CONFIGURATION: 7,
PERSON_DIRECTORY: 8,
AUTHENTICATION: 9,
CONSENT: 10,
PROTOCOLS: 11,
THROTTLES: 12,
MFA: 13
};
/**
* Charts objects.
*/
let servicesChart = null;
let memoryChart = null;
let statisticsChart = null;
let systemHealthChart = null;
let jvmThreadsChart = null;
let httpRequestResponsesChart = null;
let httpRequestsByUrlChart = null;
let auditEventsChart = null;
let threadDumpChart = null;
let currentActiveTab = Tabs.APPLICATIONS;
const CAS_FEATURES = [];
let notyf = null;
function fetchServices(callback) {
if (actuatorEndpoints.registeredservices) {
$.get(actuatorEndpoints.registeredservices, response => {
let serviceCountByType = [0, 0, 0, 0, 0];
let applicationsTable = $("#applicationsTable").DataTable();
applicationsTable.clear();
for (const service of response[1]) {
let icon = "mdi-web-box";
const serviceClass = service["@class"];
if (serviceClass.includes("CasRegisteredService")) {
icon = "mdi-alpha-c-box-outline";
serviceCountByType[0]++;
} else if (serviceClass.includes("SamlRegisteredService")) {
icon = "mdi-alpha-s-box-outline";
serviceCountByType[1]++;
} else if (serviceClass.includes("OAuthRegisteredService")) {
icon = "mdi-alpha-o-circle-outline";
serviceCountByType[2]++;
} else if (serviceClass.includes("OidcRegisteredService")) {
icon = "mdi-alpha-o-box-outline";
serviceCountByType[3]++;
} else if (serviceClass.includes("WSFederationRegisteredService")) {
icon = "mdi-alpha-w-box-outline";
serviceCountByType[4]++;
}
let serviceDetails = `${service.name}`;
serviceDetails += "";
if (service.informationUrl) {
serviceDetails += `Information URL`;
}
if (service.privacyUrl) {
serviceDetails += ` Privacy URL`;
}
let serviceIdDetails = `${service.serviceId}`;
if (serviceClass.includes("SamlRegisteredService")) {
serviceIdDetails += `
Metadata Location`;
}
let serviceButtons = `
`;
if (actuatorEndpoints.entityhistory) {
serviceButtons += `
`;
}
applicationsTable.row.add({
0: ``,
1: `${serviceDetails}`,
2: `${serviceIdDetails}`,
3: `${service.description ?? ""}`,
4: `${serviceButtons.trim()}`,
5: `${service.id}`
});
}
applicationsTable.search("").draw();
servicesChart.data.datasets[0].data = serviceCountByType;
servicesChart.update();
if (callback !== undefined) {
callback(applicationsTable);
}
initializeServiceButtons();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
}
function selectSidebarMenuTab(tab) {
const applicationMenuItem = $(`nav.sidebar-navigation ul li[data-tab-index=${tab}]`);
selectSidebarMenuButton(applicationMenuItem);
}
function navigateToApplication(serviceIdToFind) {
let applicationsTable = $("#applicationsTable").DataTable();
applicationsTable.search(String(serviceIdToFind));
const foundRows = applicationsTable.rows({search: "applied"}).count();
if (foundRows > 0) {
const matchingRows = applicationsTable.rows({search: "applied"});
matchingRows.nodes().to$().addClass("selected");
applicationsTable.draw();
activateDashboardTab(Tabs.APPLICATIONS);
selectSidebarMenuTab(Tabs.APPLICATIONS);
} else {
displayBanner(`Could not find a registered service with id ${serviceIdToFind}`);
applicationsTable.search("").draw();
}
}
function initializeFooterButtons() {
$("button[name=newService]").off().on("click", () => {
if (actuatorEndpoints.registeredservices) {
const editServiceDialogElement = document.getElementById("editServiceDialog");
let editServiceDialog = window.mdc.dialog.MDCDialog.attachTo(editServiceDialogElement);
const editor = initializeAceEditor("serviceEditor");
editor.setValue("");
editor.gotoLine(1);
$(editServiceDialogElement).attr("newService", true);
editServiceDialog["open"]();
}
});
$("button[name=importService]").off().on("click", () => {
if (actuatorEndpoints.registeredservices) {
$("#serviceFileInput").click();
$("#serviceFileInput").change(event =>
Swal.fire({
title: "Are you sure you want to import this entry?",
text: "Once imported, the entry should take immediate effect.",
icon: "warning",
showConfirmButton: true,
showDenyButton: true
})
.then((result) => {
if (result.isConfirmed) {
const file = event.target.files[0];
const reader = new FileReader();
reader.readAsText(file);
reader.onload = e => {
const fileContent = e.target.result;
$.ajax({
url: `${actuatorEndpoints.registeredservices}`,
type: "PUT",
contentType: "application/json",
data: fileContent,
success: response => {
$("#reloadAll").click();
},
error: (xhr, status, error) => {
console.error("File upload failed:", error);
displayBanner(xhr);
}
});
};
}
}));
}
});
$("button[name=exportService]").off().on("click", () => {
if (actuatorEndpoints.registeredservices) {
let serviceId = $(exportServiceButton).attr("serviceId");
fetch(`${actuatorEndpoints.registeredservices}/export/${serviceId}`)
.then(response => {
const filename = response.headers.get("filename");
response.blob().then(blob => {
const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
})
.catch(error => console.error("Error fetching file:", error));
}
});
$("button[name=exportAll]").off().on("click", () => {
if (actuatorEndpoints.registeredservices) {
fetch(`${actuatorEndpoints.registeredservices}/export`)
.then(response => {
const filename = response.headers.get("filename");
response.blob().then(blob => {
const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
})
.catch(error => console.error("Error fetching file:", error));
}
});
}
/**
* Initialization Functions
*/
async function initializeHeimdallOperations() {
if (!CAS_FEATURES.includes("Authorization")) {
$("#heimdall").addClass("d-none");
return;
}
const heimdallResourcesTable = $("#heimdallResourcesTable").DataTable({
pageLength: 10,
columnDefs: [
{visible: false, targets: 0},
{visible: false, targets: 1},
{width: "50%", targets: 2},
{width: "20%", targets: 3},
{width: "9%", targets: 4},
{width: "10%", targets: 5},
],
autoWidth: false,
drawCallback: settings => {
$("#heimdallResourcesTable tr").addClass("mdc-data-table__row");
$("#heimdallResourcesTable td").addClass("mdc-data-table__cell");
const api = settings.api;
const rows = api.rows({page: "current"}).nodes();
let last = null;
api.column(0, {page: "current"})
.data()
.each((group, i) => {
if (last !== group) {
$(rows).eq(i).before(
`
Namespace: ${group}
`.trim());
last = group;
}
});
}
});
if (actuatorEndpoints.heimdall) {
const heimdallViewResourceEditor = initializeAceEditor("heimdallViewResourceEditor", "json");
heimdallViewResourceEditor.setReadOnly(true);
function fetchHeimdallResources(heimdallViewResourceEditor) {
$.get(`${actuatorEndpoints.heimdall}/resources`, response => {
heimdallResourcesTable.clear();
for (const [key, value] of Object.entries(response)) {
for (const resource of Object.values(value)) {
let buttons = `
`;
heimdallResourcesTable.row.add({
0: `${key}
`,
1: `${resource.id}`,
2: `${resource.pattern}
`,
3: `${resource.method}
`,
4: `${resource.enforceAllPolicies ?? "false"}
`,
5: buttons
});
}
}
heimdallResourcesTable.draw();
$("button[name=viewHeimdallResource]").off().on("click", function () {
const namespace = $(this).data("namespace");
const resourceId = $(this).data("id");
$.get(`${actuatorEndpoints.heimdall}/resources/${namespace}/${resourceId}`, response => {
heimdallViewResourceEditor.setValue(JSON.stringify(response, null, 2));
heimdallViewResourceEditor.gotoLine(1);
const beautify = ace.require("ace/ext/beautify");
beautify.beautify(heimdallViewResourceEditor.session);
const dialog = window.mdc.dialog.MDCDialog.attachTo(document.getElementById("heimdallViewResourceDialog"));
dialog["open"]();
})
.fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
});
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
fetchHeimdallResources(heimdallViewResourceEditor);
setInterval(() => {
if (currentActiveTab === Tabs.ACCESS_STRATEGY) {
fetchHeimdallResources();
}
}, DEFAULT_INTERVAL);
}
}
async function initializeAccessStrategyOperations() {
if (!CAS_FEATURES.includes("SAMLIdentityProvider")) {
$("#accessEntityIdLabel").addClass("d-none");
}
if (!CAS_FEATURES.includes("OpenIDConnect") && !CAS_FEATURES.includes("OAuth")) {
$("#accessClientIdLabel").addClass("d-none");
}
const accessStrategyEditor = initializeAceEditor("accessStrategyEditor");
accessStrategyEditor.setReadOnly(true);
const accessStrategyAttributesTable = $("#accessStrategyAttributesTable").DataTable({
pageLength: 10,
drawCallback: settings => {
$("#accessStrategyAttributesTable tr").addClass("mdc-data-table__row");
$("#accessStrategyAttributesTable td").addClass("mdc-data-table__cell");
}
});
$("button[name=accessStrategyButton]").off().on("click", () => {
if (actuatorEndpoints.serviceaccess) {
hideBanner();
accessStrategyAttributesTable.clear();
const form = document.getElementById("fmAccessStrategy");
if (!form.reportValidity()) {
return false;
}
accessStrategyEditor.setValue("");
const formData = $(form).serializeArray();
const renamedData = formData.filter(item => item.value !== "").map(item => {
const newName = $(`[name="${item.name}"]`).data("param-name") || item.name;
return {name: newName, value: item.value};
});
$.ajax({
url: actuatorEndpoints.serviceaccess,
type: "POST",
contentType: "application/x-www-form-urlencoded",
data: $.param(renamedData),
success: (response, status, xhr) => {
$("#accessStrategyEditorContainer").removeClass("d-none");
$("#accessStrategyAttributesContainer").removeClass("d-none");
accessStrategyEditor.setValue(JSON.stringify(response.registeredService, null, 2));
accessStrategyEditor.gotoLine(1);
for (const [key, value] of Object.entries(response.authentication.principal.attributes)) {
accessStrategyAttributesTable.row.add({
0: `${key}
`,
1: `${value}
`
});
}
accessStrategyAttributesTable.draw();
updateNavigationSidebar();
$("#authorizedServiceNavigation").off().on("click", () => {
navigateToApplication(response.registeredService.id);
});
},
error: (xhr, status, error) => {
$("#accessStrategyEditorContainer").addClass("d-none");
$("#accessStrategyAttributesContainer").addClass("d-none");
displayBanner(`Status ${xhr.status}: Service is unauthorized.`);
}
});
}
});
}
function hideBanner() {
notyf.dismissAll();
}
function displayBanner(error) {
let message = "";
if (error.hasOwnProperty("status")) {
switch (error.status) {
case 401:
message = "You are not authorized to access this resource. Are you sure you are authenticated?";
break;
case 403:
message = "You are forbidden from accessing this resource. Are you sure you have the necessary permissions and the entry is correctly regstered with CAS?";
break;
case 400:
case 500:
message = "Unable to process or accept the request. Check CAS server logs for details.";
break;
case 0:
message = "Unable to contact the CAS server. Are you sure the server is reachable?";
break;
default:
message = `HTTP error: ${error.status}. `;
break;
}
}
if (error.hasOwnProperty("path")) {
message += `Unable to make an API call to ${error.path}. Is the endpoint enabled and available?`;
}
if (typeof error === "string") {
message = error;
}
notyf.dismissAll();
notyf.error(message);
}
function initializeJvmMetrics() {
function fetchJvmThreadMetric(metricName) {
return new Promise((resolve, reject) =>
$.get(`${actuatorEndpoints.metrics}/${metricName}`, response => resolve(response.measurements[0].value)).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
reject(error);
})
);
}
async function fetchJvmThreadsMetrics() {
const promises = [
"jvm.threads.daemon",
"jvm.threads.live",
"jvm.threads.peak",
"jvm.threads.started",
"jvm.threads.states"
].map(metric => fetchJvmThreadMetric(metric));
const results = await Promise.all(promises);
const numbersArray = results.map(result => Number(result));
return numbersArray;
}
async function fetchThreadDump() {
return new Promise((resolve, reject) =>
$.get(actuatorEndpoints.threaddump, response => {
let threadData = {};
for (const thread of response.threads) {
if (!threadData[thread.threadState]) {
threadData[thread.threadState] = 0;
}
threadData[thread.threadState] += 1;
}
resolve(threadData);
}).fail((xhr, status, error) => {
console.error("Error thread dump:", error);
displayBanner(xhr);
reject(error);
}));
}
if (actuatorEndpoints.metrics) {
fetchJvmThreadsMetrics()
.then(payload => {
jvmThreadsChart.data.datasets[0].data = payload;
jvmThreadsChart.update();
});
}
if (actuatorEndpoints.threaddump) {
fetchThreadDump().then(payload => {
threadDumpChart.data.labels = Object.keys(payload);
const values = Object.values(payload);
threadDumpChart.data.datasets[0] = {
label: `${values.reduce((sum, value) => sum + value, 0)} Threads`,
data: values
};
threadDumpChart.update();
});
}
}
async function initializeScheduledTasksOperations() {
const threadDumpTable = $("#threadDumpTable").DataTable({
pageLength: 10,
autoWidth: false,
columnDefs: [
{width: "5%", targets: 0},
{width: "35%", targets: 1},
{width: "30%", targets: 2},
{width: "10%", targets: 3},
{width: "10%", targets: 4},
{width: "10%", targets: 5}
],
drawCallback: settings => {
$("#threadDumpTable tr").addClass("mdc-data-table__row");
$("#threadDumpTable td").addClass("mdc-data-table__cell");
}
});
const groupColumn = 0;
const scheduledtasks = $("#scheduledTasksTable").DataTable({
pageLength: 25,
columnDefs: [{visible: false, targets: groupColumn}],
order: [groupColumn, "asc"],
drawCallback: settings => {
$("#scheduledTasksTable tr").addClass("mdc-data-table__row");
$("#scheduledTasksTable td").addClass("mdc-data-table__cell");
const api = settings.api;
const rows = api.rows({page: "current"}).nodes();
let last = null;
api.column(groupColumn, {page: "current"})
.data()
.each((group, i) => {
if (last !== group) {
$(rows).eq(i).before(
`
${group}
`.trim());
last = group;
}
});
}
});
function addScheduledTaskCategory(groupName, items) {
if (items !== undefined && Array.isArray(items)) {
for (const group of items) {
const flattened = flattenJSON(group);
for (const [key, value] of Object.entries(flattened)) {
const target = flattened["runnable.target"];
if (target !== value) {
scheduledtasks.row.add({
0: `${camelcaseToTitleCase(groupName)} / ${getLastTwoWords(target)}
`,
1: `${key}
`,
2: `${value}
`
});
}
}
}
}
}
if (actuatorEndpoints.scheduledtasks) {
$.get(actuatorEndpoints.scheduledtasks, response => {
scheduledtasks.clear();
for (const group of Object.keys(response)) {
addScheduledTaskCategory(group, response[group]);
}
scheduledtasks.draw();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
if (actuatorEndpoints.metrics) {
initializeJvmMetrics();
setInterval(() => {
if (currentActiveTab === Tabs.TASKS) {
initializeJvmMetrics();
}
}, DEFAULT_INTERVAL);
}
function fetchThreadDump() {
$.get(actuatorEndpoints.threaddump, response => {
threadDumpTable.clear();
for (const thread of response.threads) {
threadDumpTable.row.add({
0: `${thread.threadId}
`,
1: `${thread.threadName}
`,
2: `${thread.threadState}
`,
3: `${thread.priority}
`,
4: `${thread.daemon}
`,
5: `${thread.suspended}
`
});
}
threadDumpTable.draw();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
if (actuatorEndpoints.threaddump) {
fetchThreadDump();
setInterval(() => {
if (currentActiveTab === Tabs.TASKS) {
fetchThreadDump();
}
}, DEFAULT_INTERVAL);
}
}
async function initializeTicketsOperations() {
const ticketEditor = initializeAceEditor("ticketEditor");
ticketEditor.setReadOnly(true);
$("button#searchTicketButton").off().on("click", () => {
const ticket = document.getElementById("ticket");
if (!ticket.checkValidity()) {
ticket.reportValidity();
return false;
}
const ticketId = $(ticket).val();
const type = $("#ticketDefinitions .mdc-list-item--selected").attr("data-value").trim();
if (ticket && type) {
const decode = new mdc.switchControl.MDCSwitch(document.getElementById("decodeTicketButton")).selected;
ticketEditor.setValue("");
if (actuatorEndpoints.ticketregistry) {
$.get(`${actuatorEndpoints.ticketregistry}/query?type=${type}&id=${ticketId}&decode=${decode}`,
response => {
ticketEditor.setValue(JSON.stringify(response, null, 2));
ticketEditor.gotoLine(1);
})
.fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
}
});
$("button#cleanTicketsButton").off().on("click", () => {
hideBanner();
if (actuatorEndpoints.ticketregistry) {
$.ajax({
url: `${actuatorEndpoints.ticketregistry}/clean`,
type: "DELETE",
success: response => {
ticketEditor.setValue(JSON.stringify(response, null, 2));
ticketEditor.gotoLine(1);
},
error: (xhr, status, error) => {
console.error(`Error: ${status} / ${error} / ${xhr.responseText}`);
displayBanner(xhr);
}
});
}
});
const ticketCatalogTable = $("#ticketCatalogTable").DataTable({
pageLength: 10,
columnDefs: [
{visible: false, targets: 0}
],
order: [0, "desc"],
drawCallback: settings => {
$("#ticketCatalogTable tr").addClass("mdc-data-table__row");
$("#ticketCatalogTable td").addClass("mdc-data-table__cell");
const api = settings.api;
const rows = api.rows({page: "current"}).nodes();
let last = null;
api.column(0, {page: "current"})
.data()
.each((group, i) => {
if (last !== group) {
$(rows).eq(i).before(
`
${group} `.trim());
last = group;
}
});
}
});
if (actuatorEndpoints.ticketregistry) {
$.get(`${actuatorEndpoints.ticketregistry}/ticketCatalog`, response => {
response.forEach(entry => {
let item = `
${entry.apiClass}
`;
$("#ticketDefinitions").append($(item.trim()));
const flattened = flattenJSON(entry);
for (const [key, value] of Object.entries(flattened)) {
ticketCatalogTable.row.add({
0: `${entry.prefix}
`,
1: `${key}
`,
2: `${value}
`
});
}
ticketCatalogTable.draw();
});
const ticketDefinitions = new mdc.select.MDCSelect(document.getElementById("ticketDefinitionsSelect"));
ticketDefinitions.selectedIndex = 0;
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
const ticketExpirationPoliciesTable = $("#ticketExpirationPoliciesTable").DataTable({
pageLength: 10,
columnDefs: [
{visible: false, targets: 0}
],
order: [0, "desc"],
drawCallback: settings => {
$("#ticketExpirationPoliciesTable tr").addClass("mdc-data-table__row");
$("#ticketExpirationPoliciesTable td").addClass("mdc-data-table__cell");
const api = settings.api;
const rows = api.rows({page: "current"}).nodes();
let last = null;
api.column(0, {page: "current"})
.data()
.each((group, i) => {
if (last !== group) {
$(rows).eq(i).before(
`
${group} `.trim());
last = group;
}
});
}
});
if (actuatorEndpoints.ticketExpirationPolicies) {
$.get(actuatorEndpoints.ticketExpirationPolicies, response => {
ticketExpirationPoliciesTable.clear();
for (const key of Object.keys(response)) {
const policy = response[key];
delete policy.name;
const flattened = flattenJSON(policy);
for (const [k, v] of Object.entries(flattened)) {
ticketExpirationPoliciesTable.row.add({
0: `${key}
`,
1: `${k}
`,
2: `${v}
`
});
}
}
ticketExpirationPoliciesTable.draw();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
}
async function initializeSsoSessionOperations() {
const ssoSessionDetailsTable = $("#ssoSessionDetailsTable").DataTable({
pageLength: 10,
autoWidth: false,
columnDefs: [
{width: "10%", targets: 0},
{width: "20%", targets: 1},
{width: "70%", targets: 2}
],
drawCallback: settings => {
$("#ssoSessionDetailsTable tr").addClass("mdc-data-table__row");
$("#ssoSessionDetailsTable td").addClass("mdc-data-table__cell");
}
});
const ssoSessionsTable = $("#ssoSessionsTable").DataTable({
pageLength: 10,
autoWidth: false,
columnDefs: [
{width: "13%", targets: 0},
{width: "37%", targets: 1},
{width: "10%", targets: 2},
{width: "15%", targets: 3},
{width: "5%", targets: 4},
{width: "8%", targets: 5},
{width: "12%", targets: 6},
{visible: false, target: 7}
],
drawCallback: settings => {
$("#ssoSessionsTable tr").addClass("mdc-data-table__row");
$("#ssoSessionsTable td").addClass("mdc-data-table__cell");
}
});
$("#ssoSessionUsername").on("keypress", e => {
if (e.which === 13) {
$("#ssoSessionButton").click();
}
});
$("#removeSsoSessionButton").off().on("click", () => {
if (actuatorEndpoints.ssosessions) {
const form = document.getElementById("fmSsoSessions");
if (!form.reportValidity()) {
return false;
}
Swal.fire({
title: "Are you sure you want to delete all sessions for the user?",
text: "Once deleted, you may not be able to recover this entry.",
icon: "warning",
showConfirmButton: true,
showDenyButton: true
})
.then((result) => {
if (result.isConfirmed) {
const username = $("#ssoSessionUsername").val();
$.ajax({
url: `${actuatorEndpoints.ssosessions}/users/${username}`,
type: "DELETE",
contentType: "application/x-www-form-urlencoded",
success: (response, status, xhr) => {
ssoSessionsTable.clear().draw();
},
error: (xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
}
});
}
});
}
});
$("button[name=ssoSessionButton]").off().on("click", () => {
if (actuatorEndpoints.ssosessions) {
const form = document.getElementById("fmSsoSessions");
if (!form.reportValidity()) {
return false;
}
const username = $("#ssoSessionUsername").val();
Swal.fire({
icon: "info",
title: `Fetching SSO Sessions for ${username}`,
text: "Please wait while single sign-on sessions are retrieved...",
allowOutsideClick: false,
showConfirmButton: false,
didOpen: () => {
Swal.showLoading();
}
});
ssoSessionsTable.clear();
$.ajax({
url: `${actuatorEndpoints.ssosessions}/users/${username}`,
type: "GET",
contentType: "application/x-www-form-urlencoded",
success: (response, status, xhr) => {
for (const session of response.activeSsoSessions) {
const attributes = {
principal: session["principal_attributes"],
authentication: session["authentication_attributes"]
};
let serviceButtons = `
`;
ssoSessionsTable.row.add({
0: `${session["authentication_date"]}
`,
1: `${session["ticket_granting_ticket"]}
`,
2: `${session["authentication_attributes"]?.clientIpAddress?.[0]}
`,
3: `${session["authentication_attributes"]?.userAgent?.[0]}
`,
4: `${session["number_of_uses"]}
`,
5: `${session["remember_me"]}
`,
6: `${serviceButtons}`,
7: `${JSON.stringify(attributes)}`
});
}
ssoSessionsTable.draw();
Swal.close();
$("button[name=viewSsoSession]").off().on("click", function () {
const attributes = JSON.parse($(this).children("span").first().text());
for (const [key, value] of Object.entries(attributes.principal)) {
ssoSessionDetailsTable.row.add({
0: `Principal
`,
1: `${key}
`,
2: `${value}
`
});
}
for (const [key, value] of Object.entries(attributes.authentication)) {
ssoSessionDetailsTable.row.add({
0: `Authentication
`,
1: `${key}
`,
2: `${value}
`
});
}
ssoSessionDetailsTable.draw();
let dialog = mdc.dialog.MDCDialog.attachTo(document.getElementById("ssoSession-dialog"));
dialog["open"]();
});
$("button[name=removeSsoSession]").off().on("click", function () {
const ticket = $(this).data("ticketgrantingticket");
Swal.fire({
title: "Are you sure you want to delete this session?",
text: "Once deleted, you may not be able to recover this entry.",
icon: "warning",
showConfirmButton: true,
showDenyButton: true
})
.then((result) => {
if (result.isConfirmed) {
$.ajax({
url: `${actuatorEndpoints.ssosessions}/${ticket}`,
type: "DELETE",
contentType: "application/x-www-form-urlencoded",
success: (response, status, xhr) => {
let nearestTr = $(this).closest("tr");
ssoSessionsTable.row(nearestTr).remove().draw();
},
error: (xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
}
});
}
});
});
},
error: (xhr, status, error) => {
console.error("Error fetching data:", error);
Swal.close();
displayBanner(xhr);
}
});
}
});
}
async function initializeLoggingOperations() {
const toolbar = document.createElement("div");
toolbar.innerHTML = `
`;
const loggersTable = $("#loggersTable").DataTable({
layout: {
topStart: toolbar
},
pageLength: 25,
autoWidth: false,
columnDefs: [
{width: "90%", targets: 0},
{width: "10%", targets: 1}
],
drawCallback: settings => {
$("#loggersTable tr").addClass("mdc-data-table__row");
$("#loggersTable td").addClass("mdc-data-table__cell");
}
});
function determineLoggerColor(level) {
let background = "darkgray";
switch (level) {
case "DEBUG":
background = "cornflowerblue";
break;
case "INFO":
background = "mediumseagreen";
break;
case "WARN":
background = "darkorange";
break;
case "OFF":
background = "black";
break;
case "ERROR":
background = "red";
break;
}
return background;
}
function handleLoggerLevelSelectionChange() {
$("select[name=loggerLevelSelect]").off().on("change", function () {
if (actuatorEndpoints.loggers) {
const logger = $(this).data("logger");
const level = $(this).val();
const loggerData = {
"configuredLevel": level
};
$.ajax({
url: `${actuatorEndpoints.loggers}/${logger}`,
type: "POST",
contentType: "application/json",
data: JSON.stringify(loggerData),
success: response => {
$(this).css("background-color", determineLoggerColor(level));
},
error: (xhr, status, error) => {
console.error("Failed", error);
displayBanner(xhr);
}
});
}
});
}
function fetchLoggerData(callback) {
if (actuatorEndpoints.loggingconfig) {
$.get(actuatorEndpoints.loggingconfig, response => callback(response)).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
}
function updateLoggersTable() {
fetchLoggerData(response => {
function addLoggerToTable(logger) {
const background = determineLoggerColor(logger.level);
const loggerLevel = `
`;
loggersTable.row.add({
0: `${logger.name}
`,
1: `${loggerLevel.trim()}`
});
}
loggersTable.clear();
for (const logger of response.loggers) {
addLoggerToTable(logger);
}
loggersTable.draw();
$("#newLoggerButton").off().on("click", () =>
Swal.fire({
input: "text",
inputAttributes: {
autocapitalize: "off"
},
showConfirmButton: true,
showDenyButton: true,
icon: "success",
title: "What's the name of the new logger?",
text: "The new logger will only be effective at runtime and will not be persisted."
})
.then((result) => {
if (result.isConfirmed) {
addLoggerToTable({name: result.value, level: "INFO"});
loggersTable.draw();
handleLoggerLevelSelectionChange();
loggersTable.search(result.value).draw();
}
}));
handleLoggerLevelSelectionChange();
});
}
let tabs = new mdc.tabBar.MDCTabBar(document.querySelector("#dashboardTabBar"));
tabs.listen("MDCTabBar:activated", ev => {
let index = ev.detail.index;
if (index === Tabs.LOGGING) {
updateLoggersTable();
}
});
if (currentActiveTab === Tabs.LOGGING) {
updateLoggersTable();
}
const logEndpoints = [actuatorEndpoints.cloudwatchlogs, actuatorEndpoints.gcplogs, actuatorEndpoints.loggingconfig, actuatorEndpoints.logfile];
const hasLogEndpoint = logEndpoints.some(element => element !== undefined);
if (hasLogEndpoint) {
const scrollSwitch = new mdc.switchControl.MDCSwitch(document.getElementById("scrollLogsButton"));
scrollSwitch.selected = true;
if (actuatorEndpoints.logfile) {
$("#logFileStream").parent().addClass("w-50");
$("#logDataStream").parent().addClass("w-50");
} else {
$("#logFileStream").parent().addClass("d-none");
$("#logDataStream").parent().addClass("w-100");
}
async function fetchLogsFrom(endpoint) {
if (endpoint) {
const logDataStream = $("#logDataStream");
const level = $("#logLevelFilter").val();
const count = $("#logCountFilter").val();
$.ajax({
url: `${endpoint}/stream?level=${level}&count=${count}`,
type: "GET",
dataType: "json",
success: logEvents => {
logDataStream.empty();
logEvents.forEach(log => {
let className = `log-${log.level.toLowerCase()}`;
const logEntry = `${new Date(log.timestamp).toLocaleString()} - [${log.level}] - ${log.message}`;
logDataStream.append($(logEntry));
});
if (scrollSwitch.selected) {
logDataStream.scrollTop(logDataStream.prop("scrollHeight"));
}
},
error: (xhr, status, error) => {
console.error("Streaming logs failed:", error);
}
});
}
}
function startStreamingLogFile() {
return setInterval(() => {
if (currentActiveTab === Tabs.LOGGING) {
const logFileStream = $("#logFileStream");
$.ajax({
url: actuatorEndpoints.logfile,
type: "GET",
success: response => {
logFileStream.empty();
logFileStream.text(response);
if (scrollSwitch.selected) {
logFileStream.scrollTop(logFileStream.prop("scrollHeight"));
}
},
error: (xhr, status, error) => {
console.error("Streaming logs failed:", error);
}
});
}
}, $("#logRefreshFilter").val())
}
function startStreamingLogData() {
return setInterval(() => {
if (currentActiveTab === Tabs.LOGGING) {
fetchLogsFrom(actuatorEndpoints.cloudwatchlogs);
fetchLogsFrom(actuatorEndpoints.gcplogs);
fetchLogsFrom(actuatorEndpoints.loggingconfig);
}
}, $("#logRefreshFilter").val())
}
let refreshStreamInterval = startStreamingLogData();
let refreshLogFileInterval = undefined;
if (actuatorEndpoints.logfile) {
refreshLogFileInterval = startStreamingLogFile();
}
$("#logRefreshFilter").selectmenu({
change: (event, data) => {
clearInterval(refreshStreamInterval);
refreshStreamInterval = startStreamingLogData();
if (refreshLogFileInterval) {
clearInterval(refreshLogFileInterval);
refreshLogFileInterval = startStreamingLogFile()
}
}
});
} else {
$("#loggingDataStreamOps").parent().addClass("d-none");
}
}
async function initializeAuditEventsOperations() {
if (actuatorEndpoints.auditlog) {
const auditEventsTable = $("#auditEventsTable").DataTable({
pageLength: 10,
drawCallback: settings => {
$("#auditEventsTable tr").addClass("mdc-data-table__row");
$("#auditEventsTable td").addClass("mdc-data-table__cell");
}
});
function fetchAuditLog() {
return setInterval(() => {
if (currentActiveTab === Tabs.LOGGING) {
const interval = $("#auditEventsIntervalFilter").val();
const count = $("#auditEventsCountFilter").val();
$.ajax({
url: `${actuatorEndpoints.auditlog}?interval=${interval}&count=${count}`,
type: "GET",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
success: (response, textStatus, xhr) => {
auditEventsTable.clear();
for (const entry of response) {
auditEventsTable.row.add({
0: `${entry?.principal ?? "N/A"}
`,
1: `${entry?.auditableResource ?? "N/A"}
`,
2: `${entry?.actionPerformed ?? "N/A"}
`,
3: `${entry?.whenActionWasPerformed ?? "N/A"}
`,
4: `${entry?.clientInfo?.clientIpAddress ?? "N/A"}
`,
5: `${entry?.clientInfo?.userAgent ?? "N/A"}`,
});
}
auditEventsTable.draw();
},
error: (xhr, textStatus, errorThrown) => {
console.error("Error fetching data:", errorThrown);
}
});
}
}, $("#auditEventsRefreshFilter").val())
}
let refreshInterval = undefined;
if (actuatorEndpoints.auditlog) {
refreshInterval = fetchAuditLog();
}
$("#auditEventsRefreshFilter").selectmenu({
change: (event, data) => {
if (refreshInterval) {
clearInterval(refreshInterval);
refreshInterval = fetchAuditLog()
}
}
});
}
}
async function initializeSystemOperations() {
function configureAuditEventsChart() {
if (actuatorEndpoints.auditevents) {
$.get(actuatorEndpoints.auditevents, response => {
let auditData = [];
const results = response.events.reduce((accumulator, event) => {
let timestamp = formatDateYearMonthDay(event.timestamp);
const type = event.type;
if (!accumulator[timestamp]) {
accumulator[timestamp] = {};
}
if (!accumulator[timestamp][type]) {
accumulator[timestamp][type] = 0;
}
accumulator[timestamp][type]++;
return accumulator;
}, {});
for (const [key, value] of Object.entries(results)) {
let auditEntry = Object.assign({timestamp: key}, value);
auditData.push(auditEntry);
}
auditEventsChart.data.labels = auditData.map(d => d.timestamp);
let datasets = [];
for (const entry of auditData) {
for (const type of Object.keys(auditData[0])) {
if (type !== "timestamp" && type !== "AUTHORIZATION_FAILURE") {
datasets.push({
borderWidth: 2,
data: auditData,
parsing: {
xAxisKey: "timestamp",
yAxisKey: type
},
label: type
});
}
}
}
auditEventsChart.data.datasets = datasets;
auditEventsChart.update();
});
}
}
async function configureHttpRequestResponses() {
if (actuatorEndpoints.httpexchanges) {
$.get(actuatorEndpoints.httpexchanges, response => {
function urlIsAcceptable(url) {
return !url.startsWith("/actuator")
&& !url.startsWith("/webjars")
&& !url.endsWith(".js")
&& !url.endsWith(".ico")
&& !url.endsWith(".png")
&& !url.endsWith(".jpg")
&& !url.endsWith(".jpeg")
&& !url.endsWith(".gif")
&& !url.endsWith(".svg")
&& !url.endsWith(".css");
}
let httpSuccesses = [];
let httpFailures = [];
let httpSuccessesPerUrl = [];
let httpFailuresPerUrl = [];
let totalHttpSuccessPerUrl = 0;
let totalHttpSuccess = 0;
let totalHttpFailurePerUrl = 0;
let totalHttpFailure = 0;
for (const exchange of response.exchanges) {
let timestamp = formatDateYearMonthDayHourMinute(exchange.timestamp);
let url = exchange.request.uri
.replace(casServerPrefix, "")
.replaceAll(/\?.+/gi, "");
if (urlIsAcceptable(url)) {
if (exchange.response.status >= 100 && exchange.response.status <= 400) {
totalHttpSuccess++;
httpSuccesses.push({x: timestamp, y: totalHttpSuccess});
totalHttpSuccessPerUrl++;
httpSuccessesPerUrl.push({x: url, y: totalHttpSuccessPerUrl});
} else {
totalHttpFailure++;
httpFailures.push({x: timestamp, y: totalHttpFailure});
totalHttpFailurePerUrl++;
httpFailuresPerUrl.push({x: url, y: totalHttpFailurePerUrl});
}
}
}
httpRequestResponsesChart.data.datasets[0].data = httpSuccesses;
httpRequestResponsesChart.data.datasets[0].label = "Success";
httpRequestResponsesChart.data.datasets[1].data = httpFailures;
httpRequestResponsesChart.data.datasets[1].label = "Failure";
httpRequestResponsesChart.update();
httpRequestsByUrlChart.data.datasets[0].data = httpSuccessesPerUrl;
httpRequestsByUrlChart.data.datasets[0].label = "Success";
httpRequestsByUrlChart.data.datasets[1].data = httpFailuresPerUrl;
httpRequestsByUrlChart.data.datasets[1].label = "Failure";
httpRequestsByUrlChart.update();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
$("#downloadHeapDumpButton").off().on("click", () => {
$("#downloadHeapDumpButton").prop("disabled", true);
fetch(actuatorEndpoints.heapdump)
.then(response =>
response.blob().then(blob => {
const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = "heapdump";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
$("#downloadHeapDumpButton").prop("disabled", false);
}))
.catch(error => {
console.error("Error fetching file:", error);
$("#downloadHeapDumpButton").prop("disabled", false);
});
});
}
}
async function configureHealthChart() {
if (actuatorEndpoints.health) {
$.get(actuatorEndpoints.health, response => {
const payload = {
labels: [],
data: [],
colors: []
};
Object.keys(response.components).forEach(key => {
payload.labels.push(key.charAt(0).toUpperCase() + key.slice(1).toLowerCase());
payload.data.push(response.components[key].status === "UP" ? 1 : 0);
payload.colors.push(response.components[key].status === "UP" ? "rgb(5, 166, 31)" : "rgba(166, 45, 15)");
});
systemHealthChart.data.labels = payload.labels;
systemHealthChart.data.datasets[0].data = payload.data;
systemHealthChart.data.datasets[0].backgroundColor = payload.colors;
systemHealthChart.data.datasets[0].borderColor = payload.colors;
systemHealthChart.options.plugins.legend.labels.generateLabels = (chart => {
const originalLabels = Chart.defaults.plugins.legend.labels.generateLabels(chart);
originalLabels.forEach(label => {
label.fillStyle = response.status === "UP" ? "rgb(5, 166, 31)" : "rgba(166, 45, 15)";
label.lineWidth = 0;
});
return originalLabels;
});
systemHealthChart.update();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
}
async function configureStatistics() {
if (actuatorEndpoints.statistics) {
$.get(actuatorEndpoints.statistics, response => {
const expired = response.expiredTickets;
const valid = response.validTickets;
statisticsChart.data.datasets[0].data = [valid, expired];
statisticsChart.update();
}).fail((xhr, status, error) => console.error("Error fetching data:", error));
}
}
async function fetchSystemData(callback) {
if (actuatorEndpoints.info) {
$.get(actuatorEndpoints.info, response => callback(response)).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
}
async function configureSystemData() {
await fetchSystemData(response => {
const maximum = convertMemoryToGB(response.systemInfo["JVM Maximum Memory"]);
const free = convertMemoryToGB(response.systemInfo["JVM Free Memory"]);
const total = convertMemoryToGB(response.systemInfo["JVM Total Memory"]);
memoryChart.data.datasets[0].data = [maximum, total, free];
memoryChart.update();
});
if (actuatorEndpoints.metrics) {
$.get(`${actuatorEndpoints.metrics}/http.server.requests`, response => {
let count = response.measurements[0].value;
let totalTime = response.measurements[1].value.toFixed(2);
let maxTime = response.measurements[2].value.toFixed(2);
$("#httpRequestsCount").text(count);
$("#httpRequestsTotalTime").text(`${totalTime}s`);
$("#httpRequestsMaxTime").text(`${maxTime}s`);
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
$.get(`${actuatorEndpoints.metrics}/http.server.requests.active`, response => {
let active = response.measurements[0].value;
let duration = response.measurements[1].value.toFixed(2);
$("#httpRequestsActive").text(active);
$("#httpRequestsDuration").text(`${duration}s`);
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
configureHttpRequestResponses().then(configureAuditEventsChart());
}
const systemTable = $("#systemTable").DataTable({
pageLength: 10,
drawCallback: settings => {
$("#systemTable tr").addClass("mdc-data-table__row");
$("#systemTable td").addClass("mdc-data-table__cell");
}
});
let tabs = new mdc.tabBar.MDCTabBar(document.querySelector("#dashboardTabBar"));
async function configureSystemInfo() {
await fetchSystemData(response => {
const flattened = flattenJSON(response);
systemTable.clear();
for (const [key, value] of Object.entries(flattened)) {
systemTable.row.add({
0: `${key}
`,
1: `${value}
`
});
}
systemTable.draw();
hljs.highlightAll();
$("#casServerPrefix").text(casServerPrefix);
$("#casServerHost").text(response.server["host"]);
});
}
tabs.listen("MDCTabBar:activated", ev => {
let index = ev.detail.index;
if (index === Tabs.SYSTEM) {
configureSystemInfo();
}
});
setInterval(() => {
if (currentActiveTab === Tabs.SYSTEM) {
configureSystemData();
configureHealthChart();
configureStatistics();
}
}, DEFAULT_INTERVAL);
await configureSystemData()
.then(configureStatistics())
.then(configureHealthChart())
.then(configureSystemInfo);
}
async function initializeCasFeatures() {
return new Promise((resolve, reject) => {
if (actuatorEndpoints.casFeatures) {
$.get(actuatorEndpoints.casFeatures, response => {
$("#casFeaturesChipset").empty();
for (const element of response) {
const featureName = element.trim().replace("CasFeatureModule.", "");
CAS_FEATURES.push(featureName);
let feature = `
${featureName}
`.trim();
$("#casFeaturesChipset").append($(feature));
}
resolve();
});
}
});
}
function initializeServiceButtons() {
const editor = initializeAceEditor("serviceEditor");
let editServiceDialog = window.mdc.dialog.MDCDialog.attachTo(document.getElementById("editServiceDialog"));
if (actuatorEndpoints.registeredservices) {
const entityHistoryTable = $("#entityHistoryTable").DataTable();
$("button[name=viewEntityHistory]").off().on("click", function () {
let serviceId = $(this).parent().attr("serviceId");
$.get(`${actuatorEndpoints.entityhistory}/registeredServices/${serviceId}`, response => {
entityHistoryTable.clear();
const editor = initializeAceEditor("entityHistoryEditor", "json");
editor.setValue("");
editor.setReadOnly(true);
for (const item of response) {
entityHistoryTable.row.add({
0: `${item.id}
`,
1: `${item.date}
`,
2: `${JSON.stringify(item.entity, null, 4)}`
});
}
entityHistoryTable.draw();
entityHistoryTable.on("click", "tbody tr", function () {
let data = entityHistoryTable.row(this).data();
editor.setValue(data[2]);
editor.gotoLine(1);
editor.setReadOnly(true);
});
if (response.length > 0) {
const dialog = window.mdc.dialog.MDCDialog.attachTo(document.getElementById("viewEntityHistoryDialog"));
dialog["open"]();
} else {
Swal.fire("No History!", "There are no changes recorded for this application definition.", "info");
}
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
});
}
$("button[name=viewEntityChangelog]").off().on("click", function () {
let serviceId = $(this).parent().attr("serviceId");
$.get(`${actuatorEndpoints.entityhistory}/registeredServices/${serviceId}/changelog`, response => {
const editor = initializeAceEditor("entityChangelogEditor", "text");
editor.setValue(response);
editor.setReadOnly(true);
editor.gotoLine(1);
const dialog = window.mdc.dialog.MDCDialog.attachTo(document.getElementById("viewEntityChangelogDialog"));
dialog["open"]();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
});
$("button[name=deleteService]").off().on("click", function () {
let serviceId = $(this).parent().attr("serviceId");
if (actuatorEndpoints.registeredservices) {
Swal.fire({
title: "Are you sure you want to delete this entry?",
text: "Once deleted, you may not be able to recover this entry.",
icon: "warning",
showConfirmButton: true,
showDenyButton: true
})
.then((result) => {
if (result.isConfirmed) {
$.ajax({
url: `${actuatorEndpoints.registeredservices}/${serviceId}`,
type: "DELETE",
success: response => {
let nearestTr = $(this).closest("tr");
let applicationsTable = $("#applicationsTable").DataTable();
applicationsTable.row(nearestTr).remove().draw();
},
error: (xhr, status, error) => {
console.error("Error deleting resource:", error);
displayBanner(xhr);
}
});
}
});
}
});
$("button[name=editService]").off().on("click", function () {
let serviceId = $(this).parent().attr("serviceId");
if (actuatorEndpoints.registeredservices) {
$.get(`${actuatorEndpoints.registeredservices}/${serviceId}`, response => {
const value = JSON.stringify(response, null, 4);
editor.setValue(value, -1);
editor.gotoLine(1);
const editServiceDialogElement = document.getElementById("editServiceDialog");
$(editServiceDialogElement).attr("newService", false);
editServiceDialog["open"]();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
});
$("button[name=saveService]").off().on("click", () => {
if (actuatorEndpoints.registeredservices) {
const editServiceDialogElement = document.getElementById("editServiceDialog");
const isNewService = $(editServiceDialogElement).attr("newService") === "true";
Swal.fire({
title: `Are you sure you want to ${isNewService ? "create" : "update"} this entry?`,
text: "Once updated, you may not be able to revert this entry.",
icon: "warning",
showConfirmButton: true,
showDenyButton: true
})
.then((result) => {
if (result.isConfirmed) {
const value = editor.getValue();
$.ajax({
url: `${actuatorEndpoints.registeredservices}`,
type: isNewService ? "POST" : "PUT",
contentType: "application/json",
data: value,
success: response => {
editServiceDialog["close"]();
fetchServices(() => {
let newServiceId = response.id;
$("#applicationsTable tr").removeClass("selected");
$(`#applicationsTable tr td span[serviceId=${newServiceId}]`).each(function () {
$(this).closest("tr").addClass("selected");
});
updateNavigationSidebar();
});
},
error: (xhr, status, error) => {
console.error("Update failed:", error);
displayBanner(xhr);
}
});
}
});
}
});
$("button[name=copyService]").off().on("click", function () {
if (actuatorEndpoints.registeredservices) {
let serviceId = $(this).parent().attr("serviceId");
$.get(`${actuatorEndpoints.registeredservices}/${serviceId}`, response => {
let clone = {...response};
clone.serviceId = "...";
clone.name = `...`;
delete clone.id;
["clientId", "clientSecret", "metadataLocation"].forEach(entry => {
if (Object.hasOwn(clone, entry)) {
clone[entry] = `...`;
}
});
const value = JSON.stringify(clone, null, 4);
editor.setValue(value, -1);
editor.gotoLine(1);
editor.findAll("...", {regExp: false});
const editServiceDialogElement = document.getElementById("editServiceDialog");
$(editServiceDialogElement).attr("newService", true);
editServiceDialog["open"]();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
});
}
async function initializeServicesOperations() {
const applicationsTable = $("#applicationsTable").DataTable({
pageLength: 25,
autoWidth: false,
columnDefs: [
{width: "5%", targets: 0},
{width: "10%", targets: 1},
{width: "17%", targets: 2},
{width: "56%", targets: 3},
{width: "12%", targets: 4},
{visible: false, targets: 5}
],
drawCallback: settings => {
$("#applicationsTable tr").addClass("mdc-data-table__row");
$("#applicationsTable td").addClass("mdc-data-table__cell");
}
});
applicationsTable.on("click", "tbody tr", e => e.currentTarget.classList.remove("selected"));
$("#entityHistoryTable").DataTable({
pageLength: 10,
autoWidth: false,
columnDefs: [
{width: "5%", targets: 0},
{width: "25%", targets: 1},
{visible: false, targets: 2}
],
drawCallback: settings => {
$("#entityHistoryTable tr").addClass("mdc-data-table__row");
$("#entityHistoryTable td").addClass("mdc-data-table__cell");
}
});
fetchServices();
initializeFooterButtons();
let serviceDefinitionsEntries = "";
for (let type in serviceDefinitions) {
serviceDefinitionsEntries += `${type}
`;
const entries = serviceDefinitions[type];
serviceDefinitionsEntries += "";
for (const entry of entries) {
const definition = JSON.parse(entry);
serviceDefinitionsEntries += `${definition.name}-${definition.id}`;
}
serviceDefinitionsEntries += "";
}
$("#serviceTemplatesContainer")
.html(serviceDefinitionsEntries)
.accordion({
collapsible: true,
heightStyle: "content"
})
.tooltip();
$("a[name=serviceDefinitionEntry]").off().on("click", function () {
let type = $(this).data("type");
let id = $(this).data("id");
const entries = serviceDefinitions[type];
for (const entry of entries) {
const definition = JSON.parse(entry);
if (definition.id === id) {
const serviceEditor = initializeAceEditor("serviceEditor", "json");
serviceEditor.setReadOnly(false);
serviceEditor.setValue(JSON.stringify(definition, null, 2));
serviceEditor.gotoLine(1);
}
}
});
}
async function initializeAllCharts() {
threadDumpChart = new Chart(document.getElementById("threadDumpChart").getContext("2d"), {
type: "bar",
options: {
responsive: true,
fill: true,
borderWidth: 2,
plugins: {
legend: {
position: "top"
},
title: {
display: true
}
}
}
});
threadDumpChart.update();
servicesChart = new Chart(document.getElementById("servicesChart").getContext("2d"), {
type: "pie",
data: {
labels: [
"CAS",
"SAML2",
"OAuth",
"OpenID Connect",
"Ws-Federation"
],
datasets: [{
label: "Registered Services",
data: [0, 0, 0, 0, 0],
backgroundColor: [
"deepskyblue",
"indianred",
"mediumpurple",
"limegreen",
"slategrey"
],
hoverOffset: 4
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: "top"
},
title: {
display: true
}
}
}
});
servicesChart.update();
memoryChart = new Chart(document.getElementById("memoryChart").getContext("2d"), {
type: "bar",
data: {
labels: ["Total Memory", "Free Memory", "Used Memory"],
datasets: [{
label: "Memory (GB)",
data: [0, 0, 0],
fill: true,
backgroundColor: ["rgba(54, 162, 235, 0.2)", "rgba(75, 192, 192, 0.2)", "rgba(255, 99, 132, 0.2)"],
borderColor: ["rgba(54, 162, 235, 1)", "rgba(75, 192, 192, 1)", "rgba(255, 99, 132, 1)"],
borderWidth: 2
}]
},
options: {
scales: {
y: {
beginAtZero: true,
stacked: true
},
x: {
stacked: true,
grid: {
offset: true
}
}
}
}
});
statisticsChart = new Chart(document.getElementById("statisticsChart").getContext("2d"), {
type: "bar",
data: {
labels: ["Current Tickets", "Expired (Removed) Tickets"],
datasets: [{
label: "Ticket Registry",
data: [0, 0],
fill: true,
backgroundColor: ["rgba(75, 192, 192, 0.2)", "rgba(255, 99, 132, 0.2)"],
borderColor: ["rgba(75, 192, 192, 1)", "rgba(255, 99, 132, 1)"],
borderWidth: 2
}]
},
options: {
scales: {
y: {
beginAtZero: true,
stacked: true,
ticks: {
stepSize: 1
}
},
x: {
stacked: true,
grid: {
offset: true
}
}
}
}
});
auditEventsChart = new Chart(document.getElementById("auditEventsChart").getContext("2d"), {
type: "bar",
options: {
plugins: {
title: {
display: true,
text: "Audit Events"
}
}
}
});
auditEventsChart.update();
httpRequestResponsesChart = new Chart(document.getElementById("httpRequestResponsesChart").getContext("2d"), {
type: "bar",
data: {
datasets: [
{
data: [{x: "N/A", y: 0}, {x: "N/A", y: 0}],
label: "Success",
borderWidth: 2
},
{
data: [{x: "N/A", y: 0}, {x: "N/A", y: 0}],
label: "Failure",
borderWidth: 2
}
]
},
options: {
plugins: {
title: {
display: true,
text: "HTTP Requests/Responses (Date)"
}
}
}
});
httpRequestResponsesChart.update();
httpRequestsByUrlChart = new Chart(document.getElementById("httpRequestsByUrlChart").getContext("2d"), {
type: "bar",
data: {
datasets: [
{
data: [{x: "N/A", y: 0}, {x: "N/A", y: 0}],
label: "Success",
borderWidth: 2
},
{
data: [{x: "N/A", y: 0}, {x: "N/A", y: 0}],
label: "Failure",
borderWidth: 2
}
]
},
options: {
plugins: {
title: {
display: true,
text: "HTTP Requests/Responses (URL)"
}
}
}
});
httpRequestsByUrlChart.update();
systemHealthChart = new Chart(document.getElementById("systemHealthChart").getContext("2d"), {
type: "bar",
data: {
datasets: [{
label: "System Health",
fill: true,
borderWidth: 2
}]
},
options: {
indexAxis: "y",
scales: {
x: {
ticks: {
display: false
}
}
}
}
});
jvmThreadsChart = new Chart(document.getElementById("jvmThreadsChart").getContext("2d"), {
type: "bar",
data: {
labels: ["Daemon", "Live", "Peak", "Started", "States"],
datasets: [{
label: "JVM Thread Types",
data: [0, 0, 0, 0, 0],
fill: true,
borderWidth: 2
}]
},
options: {
scales: {
y: {
beginAtZero: true,
stacked: true,
ticks: {
stepSize: 1
}
},
x: {
stacked: true,
grid: {
offset: true
}
}
}
}
});
}
function updateNavigationSidebar() {
setTimeout(() => $("nav.sidebar-navigation").css("height", $("#dashboard .mdc-card").css("height")), 100);
}
async function initializePersonDirectoryOperations() {
const personDirectoryTable = $("#personDirectoryTable").DataTable({
pageLength: 10,
drawCallback: settings => {
$("#personDirectoryTable tr").addClass("mdc-data-table__row");
$("#personDirectoryTable td").addClass("mdc-data-table__cell");
}
});
$("button[name=personDirectoryClearButton]").off().on("click", () => {
if (actuatorEndpoints.persondirectory) {
const form = document.getElementById("fmPersonDirectory");
if (!form.reportValidity()) {
return false;
}
const username = $("#personUsername").val();
Swal.fire({
title: `Are you sure you want to delete the cache for ${username}?`,
text: `Once the cached entry is removed, attribute repositories would be forced to fetch attributes for ${username} again`,
icon: "warning",
showConfirmButton: true,
showDenyButton: true
})
.then((result) => {
if (result.isConfirmed) {
personDirectoryTable.clear();
$.ajax({
url: `${actuatorEndpoints.persondirectory}/cache/${username}`,
type: "DELETE",
contentType: "application/json",
success: (response, status, xhr) => {
},
error: (xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
}
});
}
});
}
});
$("button[name=personDirectoryButton]").off().on("click", () => {
if (actuatorEndpoints.persondirectory) {
const form = document.getElementById("fmPersonDirectory");
if (!form.reportValidity()) {
return false;
}
const username = $("#personUsername").val();
personDirectoryTable.clear();
$.ajax({
url: `${actuatorEndpoints.persondirectory}/cache/${username}`,
type: "GET",
contentType: "application/json",
success: (response, status, xhr) => {
for (const [key, values] of Object.entries(response.attributes)) {
personDirectoryTable.row.add({
0: `${key}
`,
1: `${values}
`
});
}
personDirectoryTable.draw();
},
error: (xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
}
});
}
});
}
async function initializeAuthenticationOperations() {
const authenticationHandlersTable = $("#authenticationHandlersTable").DataTable({
pageLength: 10,
autoWidth: false,
columnDefs: [
{visible: false, targets: 0},
{width: "80%", targets: 1},
{width: "10%", targets: 2},
{width: "10%", targets: 3}
],
order: [0, "asc"],
drawCallback: settings => {
$("#authenticationHandlersTable tr").addClass("mdc-data-table__row");
$("#authenticationHandlersTable td").addClass("mdc-data-table__cell");
const api = settings.api;
const rows = api.rows({page: "current"}).nodes();
let last = null;
api.column(0, {page: "current"})
.data()
.each((group, i) => {
if (last !== group) {
$(rows).eq(i).before(
`
${group} `.trim());
last = group;
}
});
}
});
function configureSaml2ClientMetadataButtons() {
function showSamlMetadata(payload) {
const saml2Editor = initializeAceEditor("delegatedClientsSaml2Editor", "xml");
saml2Editor.setReadOnly(true);
saml2Editor.setValue(new XMLSerializer().serializeToString(payload));
saml2Editor.gotoLine(1);
const beautify = ace.require("ace/ext/beautify");
beautify.beautify(saml2Editor.session);
const dialog = window.mdc.dialog.MDCDialog.attachTo(document.getElementById("delegatedClientsSaml2Dialog"));
dialog["open"]();
}
$("button[name=saml2ClientSpMetadata]").off().on("click", function () {
$(this).prop("disabled", true);
const url = `${casServerPrefix}/sp/${$(this).attr("clientName")}/metadata`;
$.get(url, payload => showSamlMetadata(payload))
.always(() => $(this).prop("disabled", false));
});
$("button[name=saml2ClientIdpMetadata]").off().on("click", function () {
$(this).prop("disabled", true);
const clientName = `${$(this).attr("clientName")}`;
const url = `${casServerPrefix}/sp/${clientName}/idp/metadata`;
Swal.fire({
icon: "info",
title: `Fetching SAML2 Identity Provider Metadata for ${clientName}`,
text: "Please wait while data is being retrieved...",
allowOutsideClick: false,
showConfirmButton: false,
didOpen: () => {
Swal.showLoading();
}
});
$.get(url, payload => {
showSamlMetadata(payload);
updateNavigationSidebar();
Swal.close();
})
.always(() => $(this).prop("disabled", false));
});
}
authenticationHandlersTable.clear();
if (actuatorEndpoints.authenticationHandlers) {
$.get(actuatorEndpoints.authenticationHandlers, response => {
for (const handler of response) {
authenticationHandlersTable.row.add({
0: `${handler.name}`,
1: `${handler.type}
`,
2: `${handler.state}
`,
3: `${handler.order}
`
});
}
authenticationHandlersTable.draw();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
const authenticationPoliciesTable = $("#authenticationPoliciesTable").DataTable({
pageLength: 10,
order: [0, "asc"],
autoWidth: false,
columnDefs: [
{width: "80%", targets: 0},
{width: "20%", targets: 1}
],
drawCallback: settings => {
$("#authenticationPoliciesTable tr").addClass("mdc-data-table__row");
$("#authenticationPoliciesTable td").addClass("mdc-data-table__cell");
}
});
authenticationPoliciesTable.clear();
if (actuatorEndpoints.authenticationPolicies) {
$.get(actuatorEndpoints.authenticationPolicies, response => {
for (const handler of response) {
authenticationPoliciesTable.row.add({
0: `${handler.name}`,
1: `${handler.order}
`
});
}
authenticationPoliciesTable.draw();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
const delegatedClientsTable = $("#delegatedClientsTable").DataTable({
pageLength: 10,
order: [0, "asc"],
autoWidth: false,
columnDefs: [
{visible: false, targets: 0},
{width: "40%", targets: 1},
{width: "60%", targets: 2},
{visible: false, targets: 3}
],
drawCallback: settings => {
$("#delegatedClientsTable tr").addClass("mdc-data-table__row");
$("#delegatedClientsTable td").addClass("mdc-data-table__cell");
const api = settings.api;
const rows = api.rows({page: "current"}).nodes();
let last = null;
api.column(0, {page: "current"})
.data()
.each((group, i) => {
if (last !== group) {
let samlButtons = "";
rows.data().each(entry => {
if (entry[0] === group && entry[3] === "saml2") {
samlButtons = `
`.trim();
}
});
$(rows).eq(i).before(
`
${group} ${samlButtons.trim()}
`.trim()
);
configureSaml2ClientMetadataButtons();
last = group;
}
});
}
});
delegatedClientsTable.clear();
if (actuatorEndpoints.delegatedClients) {
$.get(actuatorEndpoints.delegatedClients, response => {
for (const [key, idp] of Object.entries(response)) {
const details = flattenJSON(idp);
for (const [k, v] of Object.entries(details)) {
if (Object.keys(v).length > 0 && k !== "type") {
delegatedClientsTable.row.add({
0: `${key}`,
1: `${toKebabCase(k)}
`,
2: `${v}
`,
3: `${idp.type}`
});
}
}
}
delegatedClientsTable.draw();
$("#delegatedClientsContainer").removeClass("d-none");
$("#delegatedclients").removeClass("d-none");
updateNavigationSidebar();
configureSaml2ClientMetadataButtons();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
$("#delegatedClientsContainer").addClass("d-none");
$("#delegatedclients").addClass("d-none");
});
} else {
$("#delegatedClientsContainer").addClass("d-none");
$("#delegatedclients").addClass("d-none");
}
}
async function initializeConsentOperations() {
if (actuatorEndpoints.attributeconsent) {
const consentAttributesTable = $("#consentAttributesTable").DataTable({
pageLength: 10,
autoWidth: false,
columnDefs: [
{width: "40%", targets: 0},
{width: "60%", targets: 1}
],
drawCallback: settings => {
$("#consentAttributesTable tr").addClass("mdc-data-table__row");
$("#consentAttributesTable td").addClass("mdc-data-table__cell");
}
});
const consentTable = $("#consentTable").DataTable({
pageLength: 10,
autoWidth: false,
columnDefs: [
{visible: false, targets: 0},
{width: "12%", targets: 1},
{width: "20%", targets: 2},
{visible: false, targets: 3},
{width: "15%", targets: 4},
{width: "8%", targets: 5},
{width: "8%", targets: 6},
{width: "12%", targets: 7}
],
drawCallback: settings => {
$("#consentTable tr").addClass("mdc-data-table__row");
$("#consentTable td").addClass("mdc-data-table__cell");
}
});
consentTable.clear();
$.get(actuatorEndpoints.attributeconsent, response => {
for (const source of response) {
let consentButtons = `
`;
consentTable.row.add({
0: `${source.decision.id}
`,
1: `${source.decision.principal}
`,
2: `${source.decision.service}
`,
3: `
`,
4: `${source.decision.createdDate}
`,
5: `${source.decision.options}
`,
6: `${source.decision.reminder} ${source.decision.reminderTimeUnit}
`,
7: `${consentButtons}`
});
}
consentTable.draw();
$("button[name=viewConsentAttributes]").off().on("click", function () {
const attributes = JSON.parse($(this).children("span").first().text());
for (const [key, value] of Object.entries(attributes)) {
consentAttributesTable.row.add({
0: `${key}
`,
1: `${value}
`
});
}
consentAttributesTable.draw();
let dialog = mdc.dialog.MDCDialog.attachTo(document.getElementById("consentAttributes-dialog"));
dialog["open"]();
});
$("button[name=deleteConsent]").off().on("click", function () {
const id = $(this).attr("consentId");
const principal = $(this).attr("principal");
Swal.fire({
title: `Are you sure you want to delete this entry for ${principal}?`,
text: "Once deleted, you may not be able to recover this entry.",
icon: "warning",
showConfirmButton: true,
showDenyButton: true
})
.then((result) => {
if (result.isConfirmed) {
$.ajax({
url: `${actuatorEndpoints.attributeconsent}/${principal}/${id}`,
type: "DELETE",
contentType: "application/x-www-form-urlencoded",
success: (response, status, xhr) => {
let nearestTr = $(this).closest("tr");
consentTable.row(nearestTr).remove().draw();
},
error: (xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
}
});
}
});
});
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
$("button[name=exportAllConsent]").off().on("click", () => {
if (actuatorEndpoints.attributeconsent) {
fetch(`${actuatorEndpoints.attributeconsent}/export`)
.then(response => {
const filename = response.headers.get("filename");
response.blob().then(blob => {
const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
})
.catch(error => console.error("Error fetching file:", error));
}
});
}
}
async function initializeConfigurationOperations() {
const configurationTable = $("#configurationTable").DataTable({
pageLength: 10,
autoWidth: false,
columnDefs: [
{visible: false, targets: 0}
],
order: [0, "asc"],
drawCallback: settings => {
$("#configurationTable tr").addClass("mdc-data-table__row");
$("#configurationTable td").addClass("mdc-data-table__cell");
const api = settings.api;
const rows = api.rows({page: "current"}).nodes();
let last = null;
api.column(0, {page: "current"})
.data()
.each((group, i) => {
if (last !== group) {
$(rows).eq(i).before(
`
${group} `.trim());
last = group;
}
});
}
});
function encryptOrDecryptConfig(op) {
hideBanner();
$("#configEncryptionResult").addClass("d-none");
const form = document.getElementById("fmConfigEncryption");
if (!form.reportValidity()) {
return false;
}
const configValue = $("#configValue").val();
if (actuatorEndpoints.casconfig) {
$.post({
url: `${actuatorEndpoints.casconfig}/${op}`,
data: configValue,
contentType: "text/plain"
}, data => {
$("#configEncryptionResult pre code").text(data);
hljs.highlightAll();
$("#configEncryptionResult").removeClass("d-none");
}).fail((xhr, status, error) => {
displayBanner(xhr);
$("#configEncryptionResult").addClass("d-none");
});
}
}
configurationTable.clear();
if (actuatorEndpoints.env) {
$.get(actuatorEndpoints.env, response => {
for (const source of response.propertySources) {
const properties = flattenJSON(source.properties);
for (const [key, value] of Object.entries(properties)) {
if (!key.endsWith(".origin")) {
configurationTable.row.add({
0: `${camelcaseToTitleCase(source.name)}`,
1: `${key.replace(".value", "")}
`,
2: `${value}
`
});
}
}
}
configurationTable.draw();
$("#casActiveProfiles").empty();
for (const element of response.activeProfiles) {
let feature = `
${element.trim()}
`.trim();
$("#casActiveProfiles").append($(feature));
}
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
const configPropsTable = $("#configPropsTable").DataTable({
pageLength: 10,
autoWidth: false,
columnDefs: [
{visible: false, targets: 0}
],
order: [0, "asc"],
drawCallback: settings => {
$("#configPropsTable tr").addClass("mdc-data-table__row");
$("#configPropsTable td").addClass("mdc-data-table__cell");
const api = settings.api;
const rows = api.rows({page: "current"}).nodes();
let last = null;
api.column(0, {page: "current"})
.data()
.each((group, i) => {
if (last !== group) {
$(rows).eq(i).before(
`
${group} `.trim());
last = group;
}
});
}
});
configPropsTable.clear();
if (actuatorEndpoints.configprops) {
$.get(actuatorEndpoints.configprops, response => {
const casBeans = response.contexts["cas-1"].beans;
const bootstrapBeans = response.contexts["bootstrap"].beans;
for (const [sourceBean, bean] of Object.entries(casBeans)) {
let flattened = flattenJSON(bean.properties);
for (const [prop, propValue] of Object.entries(flattened)) {
const property = `${bean.prefix}.${prop}`;
if (Object.keys(propValue).length > 0) {
configPropsTable.row.add({
0: `${sourceBean}`,
1: `${property}
`,
2: `${propValue}
`
});
}
}
}
for (const [sourceBean, bean] of Object.entries(bootstrapBeans)) {
let flattened = flattenJSON(bean.properties);
for (const [prop, propValue] of Object.entries(flattened)) {
const property = `${bean.prefix}.${prop}`;
if (Object.keys(propValue).length > 0) {
configPropsTable.row.add({
0: `${sourceBean}`,
1: `${toKebabCase(property)}
`,
2: `${propValue}
`
});
}
}
}
configPropsTable.draw();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
$("#encryptConfigButton").off().on("click", () => encryptOrDecryptConfig("encrypt"));
$("#decryptConfigButton").off().on("click", () => encryptOrDecryptConfig("decrypt"));
}
async function initializeCasProtocolOperations() {
function buildCasProtocolPayload(endpoint, format) {
const form = document.getElementById("fmCasProtocol");
if (!form.reportValidity()) {
return false;
}
const username = $("#casProtocolUsername").val();
const password = $("#casProtocolPassword").val();
const service = $("#casProtocolService").val();
$.post(`${actuatorEndpoints.casvalidate}/${endpoint}`, {
username: username,
password: password,
service: service
}, data => {
const casProtocolEditor = initializeAceEditor("casProtocolEditor", format);
casProtocolEditor.setReadOnly(true);
casProtocolEditor.setValue(data.response);
casProtocolEditor.gotoLine(1);
const casProtocolServiceEditor = initializeAceEditor("casProtocolServiceEditor", "json");
casProtocolServiceEditor.setReadOnly(true);
casProtocolServiceEditor.setValue(JSON.stringify(data.registeredService, null, 2));
casProtocolServiceEditor.gotoLine(1);
$("#casProtocolEditorContainer").removeClass("d-none");
$("#casProtocolServiceEditorContainer").removeClass("d-none");
updateNavigationSidebar();
$("#casProtocolServiceNavigation").off().on("click", () => {
navigateToApplication(data.registeredService.id);
});
}).fail((xhr, status, error) => {
displayBanner(xhr);
$("#casProtocolEditorContainer").addClass("d-none");
$("#casProtocolServiceEditorContainer").addClass("d-none");
});
}
$("button[name=casProtocolV1Button]").off().on("click", () => buildCasProtocolPayload("validate", "text"));
$("button[name=casProtocolV2Button]").off().on("click", () => buildCasProtocolPayload("serviceValidate", "xml"));
$("button[name=casProtocolV3Button]").off().on("click", () => buildCasProtocolPayload("p3/serviceValidate", "xml"));
}
async function initializeTrustedMultifactorOperations() {
const mfaTrustedDevicesTable = $("#mfaTrustedDevicesTable").DataTable({
pageLength: 10,
autoWidth: true,
columnDefs: [
{visible: false, targets: 7}
],
drawCallback: settings => {
$("#mfaTrustedDevicesTable tr").addClass("mdc-data-table__row");
$("#mfaTrustedDevicesTable td").addClass("mdc-data-table__cell");
}
});
$("#mfaTrustedDevicesButton").off().on("click", () => {
if (actuatorEndpoints.multifactortrusteddevices) {
mfaTrustedDevicesTable.clear();
const username = $("#mfaTrustedUsername").val();
$("#mfaTrustedDevicesButton").prop("disabled", true);
Swal.fire({
icon: "info",
title: `Fetching Multifactor Trusted Devices for ${username}`,
text: "Please wait while registered multifactor trusted devices are retrieved...",
allowOutsideClick: false,
showConfirmButton: false,
didOpen: () => {
Swal.showLoading();
}
});
$.get(`${actuatorEndpoints.multifactortrusteddevices}/${username}`, response => {
for (const device of Object.values(response)) {
let buttons = `
`;
mfaTrustedDevicesTable.row.add({
0: `${device.id ?? "N/A"}
`,
1: `${device.principal ?? "N/A"}
`,
2: `${device.deviceFingerprint ?? "N/A"}
`,
3: `${device.recordDate ?? "N/A"}
`,
4: `${device.name ?? "N/A"}
`,
5: `${device.expirationDate ?? "N/A"}
`,
6: `${device.multifactorAuthenticationProvider ?? "N/A"}
`,
7: `${device.recordKey ?? "N/A"}
`,
8: `${buttons}`,
});
}
mfaTrustedDevicesTable.draw();
$("#mfaTrustedDevicesButton").prop("disabled", false);
Swal.close();
$("button[name=removeMfaTrustedDevice]").off().on("click", function () {
const key = $(this).data("key");
Swal.fire({
title: "Are you sure you want to delete this entry?",
text: "Once deleted, you may not be able to recover this entry.",
icon: "warning",
showConfirmButton: true,
showDenyButton: true
})
.then((result) => {
if (result.isConfirmed) {
$.ajax({
url: `${actuatorEndpoints.multifactortrusteddevices}/${key}`,
type: "DELETE",
contentType: "application/x-www-form-urlencoded",
success: (response, status, xhr) => {
let nearestTr = $(this).closest("tr");
mfaTrustedDevicesTable.row(nearestTr).remove().draw();
},
error: (xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
}
});
}
});
});
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
$("#mfaTrustedDevicesButton").prop("disabled", false);
Swal.close();
});
}
});
}
async function initializeMultifactorOperations() {
const mfaDevicesTable = $("#mfaDevicesTable").DataTable({
pageLength: 10,
autoWidth: true,
columnDefs: [
{visible: false, targets: 8}
],
drawCallback: settings => {
$("#mfaDevicesTable tr").addClass("mdc-data-table__row");
$("#mfaDevicesTable td").addClass("mdc-data-table__cell");
}
});
$("#mfaDevicesButton").off().on("click", () => {
function fetchMfaDevices() {
const username = $("#mfaUsername").val();
$("#mfaDevicesButton").prop("disabled", true);
Swal.fire({
icon: "info",
title: `Fetching Devices for ${username}`,
text: "Please wait while registered multifactor devices are retrieved...",
allowOutsideClick: false,
showConfirmButton: false,
didOpen: () => {
Swal.showLoading();
}
});
mfaDevicesTable.clear();
$.get(`${actuatorEndpoints.mfadevices}/${username}`, response => {
for (const device of Object.values(response)) {
let buttons = `
`;
mfaDevicesTable.row.add({
0: `${device.name ?? "N/A"}
`,
1: `${device.type ?? "N/A"}
`,
2: `${device.id ?? "N/A"}
`,
3: `${device.number ?? "N/A"}
`,
4: `${device.model ?? "N/A"}
`,
5: `${device.lastUsedDateTime ?? "N/A"}
`,
6: `${device.expirationDateTime ?? "N/A"}
`,
7: `${device.source ?? "N/A"}
`,
8: `${device.payload}`,
9: `${buttons}`,
});
}
mfaDevicesTable.draw();
$("#mfaDevicesButton").prop("disabled", false);
Swal.close();
$("button[name=removeMfaDevice]").off().on("click", function () {
const key = $(this).data("key");
const providerId = $(this).data("provider");
Swal.fire({
title: "Are you sure you want to delete this entry?",
text: "Once deleted, you may not be able to recover this entry.",
icon: "warning",
showConfirmButton: true,
showDenyButton: true
})
.then((result) => {
if (result.isConfirmed) {
$.ajax({
url: `${actuatorEndpoints.mfadevices}/${username}/${providerId}/${key}`,
type: "DELETE",
contentType: "application/x-www-form-urlencoded",
success: (response, status, xhr) => {
let nearestTr = $(this).closest("tr");
mfaDevicesTable.row(nearestTr).remove().draw();
},
error: (xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
}
});
}
});
});
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
$("#mfaDevicesButton").prop("disabled", false);
Swal.close();
});
}
const fmMfaDevices = document.getElementById("fmMfaDevices");
if (!fmMfaDevices.checkValidity()) {
fmMfaDevices.reportValidity();
return false;
}
fetchMfaDevices();
});
}
async function initializeThrottlesOperations() {
const throttlesTable = $("#throttlesTable").DataTable({
pageLength: 10,
autoWidth: false,
columnDefs: [
{width: "15%", targets: 1},
{width: "10%", targets: 2},
{width: "15%", targets: 3},
{width: "10%", targets: 4},
{width: "20%", targets: 5},
{width: "10%", targets: 6}
],
drawCallback: settings => {
$("#throttlesTable tr").addClass("mdc-data-table__row");
$("#throttlesTable td").addClass("mdc-data-table__cell");
}
});
function fetchThrottledAttempts() {
throttlesTable.clear();
$.get(actuatorEndpoints.throttles, response => {
for (const record of response) {
let buttons = `
`;
throttlesTable.row.add({
0: `${record.key}
`,
1: `${record.id}
`,
2: `${record.value}
`,
3: `${record.username}
`,
4: `${record.clientIpAddress}
`,
5: `${record.expiration}
`,
6: `${buttons}`
});
}
throttlesTable.draw();
$("button[name=removeThrottledAttempt]").off().on("click", function () {
const key = $(this).data("key");
Swal.fire({
title: "Are you sure you want to delete this entry?",
text: "Once deleted, you may not be able to recover this entry.",
icon: "warning",
showConfirmButton: true,
showDenyButton: true
})
.then((result) => {
if (result.isConfirmed) {
$.ajax({
url: `${actuatorEndpoints.throttles}/${key}`,
type: "DELETE",
contentType: "application/x-www-form-urlencoded",
success: (response, status, xhr) => {
let nearestTr = $(this).closest("tr");
throttlesTable.row(nearestTr).remove().draw();
},
error: (xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
}
});
}
});
});
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
if (actuatorEndpoints.throttles) {
fetchThrottledAttempts();
$("button[name=releaseThrottlesButton]").off().on("click", () => {
Swal.fire({
title: "Are you sure you want to release throttled entries?",
text: "Released entries, when eligible, will be removed from the authentication throttling store.",
icon: "warning",
showConfirmButton: true,
showDenyButton: true
})
.then((result) => {
if (result.isConfirmed) {
$.ajax({
url: `${actuatorEndpoints.throttles}`,
type: "DELETE",
data: {
clear: false
},
success: (response, textStatus, jqXHR) => {
fetchThrottledAttempts();
},
error: (jqXHR, textStatus, errorThrown) => {
displayBanner(jqXHR);
}
});
}
});
});
$("button[name=clearThrottlesButton]").off().on("click", () => {
Swal.fire({
title: "Are you sure you want to clear throttled entries?",
text: "All entries will be removed from the authentication throttling store.",
icon: "warning",
showConfirmButton: true,
showDenyButton: true
})
.then((result) => {
if (result.isConfirmed) {
$.ajax({
url: `${actuatorEndpoints.throttles}`,
type: "DELETE",
data: {
clear: true
},
success: (response, textStatus, jqXHR) => {
fetchThrottledAttempts();
},
error: (jqXHR, textStatus, errorThrown) => {
displayBanner(jqXHR);
}
});
}
});
});
}
}
async function initializeSAML1ProtocolOperations() {
$("button[name=saml1ProtocolButton]").off().on("click", () => {
const form = document.getElementById("fmSaml1Protocol");
if (!form.reportValidity()) {
return false;
}
const username = $("#saml1ProtocolUsername").val();
const password = $("#saml1ProtocolPassword").val();
const service = $("#saml1ProtocolService").val();
$.post(`${actuatorEndpoints.samlvalidate}`, {
username: username,
password: password,
service: service
}, data => {
$("#saml1ProtocolEditorContainer").removeClass("d-none");
const editor = initializeAceEditor("saml1ProtocolEditor", "xml");
editor.setReadOnly(true);
editor.setValue(data.assertion);
editor.gotoLine(1);
const serviceEditor = initializeAceEditor("saml1ProtocolServiceEditor", "json");
serviceEditor.setReadOnly(true);
serviceEditor.setValue(JSON.stringify(data.registeredService, null, 2));
serviceEditor.gotoLine(1);
}).fail((xhr, status, error) => {
displayBanner(xhr);
$("#saml2ProtocolEditorContainer").addClass("d-none");
});
});
}
function showSaml2IdPMetadata() {
$.get(`${casServerPrefix}/idp/metadata`, response => {
let oidcOpConfigurationDialog = window.mdc.dialog.MDCDialog.attachTo(document.getElementById("saml2MetadataDialog"));
const editor = initializeAceEditor("saml2MetadataDialogEditor", "xml");
editor.setValue(new XMLSerializer().serializeToString(response));
editor.gotoLine(1);
editor.setReadOnly(true);
oidcOpConfigurationDialog["open"]();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
function showOidcJwks() {
$.get(`${casServerPrefix}/oidc/jwks`, response => {
let oidcOpConfigurationDialog = window.mdc.dialog.MDCDialog.attachTo(document.getElementById("oidcOpConfigurationDialog"));
const editor = initializeAceEditor("oidcOpConfigurationDialogEditor", "json");
editor.setValue(JSON.stringify(response, null, 2));
editor.gotoLine(1);
editor.setReadOnly(true);
oidcOpConfigurationDialog["open"]();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
async function initializeOidcProtocolOperations() {
if (CAS_FEATURES.includes("OpenIDConnect")) {
$.get(`${casServerPrefix}/oidc/.well-known/openid-configuration`, response => {
hljs.highlightAll();
$("#oidcIssuer").text(response.issuer);
});
$("button[name=oidcOpConfigurationButton]").off().on("click", () => {
hideBanner();
$.get(`${casServerPrefix}/oidc/.well-known/openid-configuration`, response => {
let oidcOpConfigurationDialog = window.mdc.dialog.MDCDialog.attachTo(document.getElementById("oidcOpConfigurationDialog"));
const editor = initializeAceEditor("oidcOpConfigurationDialogEditor", "json");
editor.setValue(JSON.stringify(response, null, 2));
editor.gotoLine(1);
editor.setReadOnly(true);
oidcOpConfigurationDialog["open"]();
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
});
$("button[name=oidcKeyRotationButton]").off().on("click", () => {
hideBanner();
Swal.fire({
title: "Are you sure you want to rotate keys?",
text: "Once rotated, the change will take effect immediately.",
icon: "warning",
showConfirmButton: true,
showDenyButton: true
})
.then((result) => {
if (result.isConfirmed) {
$("#oidcKeyRotationButton").prop("disabled", true);
$.get(`${actuatorEndpoints.oidcjwks}/rotate`, response => {
Swal.fire({
title: "Done!",
text: "Keys in the OpenID Connect keystore are successfully rotated.",
icon: "success",
timer: 1000
});
$("#oidcKeyRotationButton").prop("disabled", false);
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
$("#oidcKeyRotationButton").prop("disabled", false);
});
}
});
});
$("button[name=oidcKeyRevocationButton]").off().on("click", () => {
hideBanner();
Swal.fire({
title: "Are you sure you want to revoke keys?",
text: "Once revoked, the change will take effect immediately.",
icon: "warning",
showConfirmButton: true,
showDenyButton: true
})
.then((willDo) => {
if (willDo) {
$("#oidcKeyRevocationButton").prop("disabled", true);
$.get(`${actuatorEndpoints.oidcjwks}/revoke`, response => {
Swal.fire({
title: "Done!",
text: "Keys in the OpenID Connect keystore are successfully revoked.",
showConfirmButton: false,
icon: "success",
timer: 1000
});
$("#oidcKeyRevocationButton").prop("disabled", false);
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
$("#oidcKeyRevocationButton").prop("disabled", false);
});
}
});
});
$("button[name=oidcProtocolButton]").off().on("click", () => {
hideBanner();
const oidcForm = document.getElementById("fmOidcProtocol");
if (!oidcForm.checkValidity()) {
oidcForm.reportValidity();
return false;
}
function decodeJWT(token) {
const parts = token.split(".");
if (parts.length === 3) {
const header = JSON.parse(atob(parts[0]));
const payload = JSON.parse(atob(parts[1]));
const signature = parts[2];
return {
header: header,
payload: payload,
signature: signature
};
}
return {};
}
$.get(`${casServerPrefix}/oidc/.well-known/openid-configuration`, oidcConfiguration => {
const clientId = $("#oidcProtocolClientId").val();
const clientSecret = $("#oidcProtocolClientSecret").val();
const scopes = encodeURIComponent($("#oidcProtocolScopes").val());
$.ajax({
url: `${oidcConfiguration.token_endpoint}?grant_type=client_credentials&scope=${scopes}`,
type: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${btoa(`${clientId}:${clientSecret}`)}`
},
success: (response, textStatus, xhr) => {
const oidcProtocolEditorTokens = initializeAceEditor("oidcProtocolEditorTokens", "json");
oidcProtocolEditorTokens.setReadOnly(true);
oidcProtocolEditorTokens.setValue(JSON.stringify(response, null, 2));
oidcProtocolEditorTokens.gotoLine(1);
const oidcProtocolEditorIdTokenClaims = initializeAceEditor("oidcProtocolEditorIdTokenClaims", "json");
oidcProtocolEditorIdTokenClaims.setReadOnly(true);
const idToken = response.id_token;
const decodedIdToken = decodeJWT(idToken);
oidcProtocolEditorIdTokenClaims.setValue(JSON.stringify(decodedIdToken.payload, null, 2));
oidcProtocolEditorIdTokenClaims.gotoLine(1);
const oidcProtocolEditorProfile = initializeAceEditor("oidcProtocolEditorProfile", "json");
oidcProtocolEditorProfile.setReadOnly(true);
const accessToken = response.access_token;
$.post(`${oidcConfiguration.userinfo_endpoint}`, {
access_token: accessToken
}, data => {
oidcProtocolEditorProfile.setValue(JSON.stringify(data, null, 2));
oidcProtocolEditorProfile.gotoLine(1);
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
$("#oidcProtocolEditorContainer").removeClass("d-none");
},
error: (xhr, textStatus, errorThrown) => {
$("#oidcProtocolEditorContainer").addClass("d-none");
console.error("Error fetching data:", errorThrown);
displayBanner(xhr);
}
});
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
$("#oidcProtocolEditorContainer").addClass("d-none");
});
});
}
}
async function initializeSAML2ProtocolOperations() {
if (CAS_FEATURES.includes("SAMLIdentityProvider")) {
if (actuatorEndpoints.info) {
$.get(actuatorEndpoints.info, response => {
hljs.highlightAll();
$("#saml2EntityId").text(response.saml2.entityId);
}).fail((xhr, status, error) => {
console.error("Error fetching data:", error);
displayBanner(xhr);
});
}
$("button[name=saml2ProtocolPostButton]").off().on("click", () => {
const form = document.getElementById("fmSaml2Protocol");
if (!form.reportValidity()) {
return false;
}
const username = $("#saml2ProtocolUsername").val();
const password = $("#saml2ProtocolPassword").val();
const entityId = $("#saml2ProtocolEntityId").val();
$.post(`${actuatorEndpoints.samlpostprofileresponse}`, {
username: username,
password: password,
entityId: entityId
}, data => {
const editor = initializeAceEditor("saml2ProtocolEditor", "xml");
editor.setReadOnly(true);
editor.setValue(new XMLSerializer().serializeToString(data));
editor.gotoLine(1);
$("#saml2ProtocolEditorContainer").removeClass("d-none");
$("#saml2ProtocolLogoutEditor").addClass("d-none");
}).fail((xhr, status, error) => {
displayBanner(xhr);
$("#saml2ProtocolEditorContainer").addClass("d-none");
});
});
$("button[name=saml2ProtocolLogoutButton]").off().on("click", () => {
const entityId = document.getElementById("saml2ProtocolEntityId");
if (!entityId.checkValidity()) {
entityId.reportValidity();
return false;
}
$.ajax({
url: `${actuatorEndpoints.samlpostprofileresponse}/logout/post`,
type: "POST",
data: {
entityId: $("#saml2ProtocolEntityId").val()
},
success: (response, textStatus, jqXHR) => {
const saml2ProtocolEditor = initializeAceEditor("saml2ProtocolEditor", "html");
saml2ProtocolEditor.setReadOnly(true);
saml2ProtocolEditor.setValue(response);
saml2ProtocolEditor.gotoLine(1);
const logoutRequest = atob(jqXHR.getResponseHeader("LogoutRequest"));
const saml2ProtocolLogoutEditor = initializeAceEditor("saml2ProtocolLogoutEditor", "xml");
saml2ProtocolLogoutEditor.setReadOnly(true);
saml2ProtocolLogoutEditor.setValue(logoutRequest);
saml2ProtocolLogoutEditor.gotoLine(1);
$("#saml2ProtocolEditorContainer").removeClass("d-none");
$("#saml2ProtocolLogoutEditor").removeClass("d-none");
},
error: (jqXHR, textStatus, errorThrown) => {
displayBanner(xhr);
$("#saml2ProtocolEditorContainer").addClass("d-none");
$("#saml2ProtocolLogoutEditor").addClass("d-none");
}
});
});
$("button[name=saml2MetadataCacheInvalidateButton]").off().on("click", () => {
hideBanner();
$("#saml2MetadataCacheEditorContainer").addClass("d-none");
Swal.fire({
title: "Are you sure you want to invalidate the cache entry?",
text: "Once deleted, the change will take effect immediately.",
icon: "warning",
showConfirmButton: true,
showDenyButton: true
})
.then((result) => {
if (result.isConfirmed) {
$.ajax({
url: `${actuatorEndpoints.samlidpregisteredservicemetadatacache}`,
type: "DELETE",
data: {
entityId: $("#saml2MetadataCacheEntityId").val(),
serviceId: $("#saml2MetadataCacheService").val()
},
success: (response, textStatus, jqXHR) => {
Swal.fire({
title: "Cached metadata record(s) removed.",
text: "Cached metadata entry has been removed successfully.",
showConfirmButton: false,
icon: "success",
timer: 1000
});
},
error: (jqXHR, textStatus, errorThrown) => {
displayBanner(jqXHR);
}
});
}
});
});
$("button[name=saml2MetadataCacheFetchButton]").off().on("click", function () {
hideBanner();
$(this).prop("disabled", true);
$.ajax({
url: `${actuatorEndpoints.samlidpregisteredservicemetadatacache}`,
type: "GET",
data: {
entityId: $("#saml2MetadataCacheEntityId").val(),
serviceId: $("#saml2MetadataCacheService").val()
},
success: (response, textStatus, jqXHR) => {
const editor = initializeAceEditor("saml2MetadataCacheEditor", "xml");
editor.setReadOnly(true);
for (const [entityId, entry] of Object.entries(response)) {
editor.setValue(entry.metadata);
$("#saml2MetadataCacheDetails").html(` Cache Instant: ${entry.cachedInstant}
`);
}
editor.gotoLine(1);
$("#saml2MetadataCacheEditorContainer").removeClass("d-none");
$("#saml2MetadataCacheDetails").removeClass("d-none");
$(this).prop("disabled", false);
},
error: (jqXHR, textStatus, errorThrown) => {
displayBanner(jqXHR);
$("#saml2MetadataCacheEditorContainer").addClass("d-none");
$("#saml2MetadataCacheDetails").addClass("d-none");
$(this).prop("disabled", false);
}
});
});
}
}
async function initializePalantir() {
try {
setTimeout(() => {
if (!actuatorEndpoints.registeredservices) {
$("#applicationsTabButton").addClass("d-none");
$(`#attribute-tab-${Tabs.APPLICATIONS}`).addClass("d-none");
}
if (!actuatorEndpoints.metrics || !actuatorEndpoints.httpexchanges || !actuatorEndpoints.auditevents
|| !actuatorEndpoints.heapdump || !actuatorEndpoints.health || !actuatorEndpoints.statistics) {
$("#systemTabButton").addClass("d-none");
$(`#attribute-tab-${Tabs.SYSTEM}`).addClass("d-none");
}
if (!actuatorEndpoints.ticketregistry) {
$("#ticketsTabButton").addClass("d-none");
$(`#attribute-tab-${Tabs.TICKETS}`).addClass("d-none");
}
if (!actuatorEndpoints.ticketregistry) {
$("#tasksTabButton").addClass("d-none");
$(`#attribute-tab-${Tabs.TASKS}`).addClass("d-none");
}
if (!actuatorEndpoints.persondirectory) {
$("#personDirectoryTabButton").addClass("d-none");
$(`#attribute-tab-${Tabs.PERSON_DIRECTORY}`).addClass("d-none");
}
if (!actuatorEndpoints.authenticationHandlers || !actuatorEndpoints.authenticationPolicies) {
$("#authenticationTabButton").addClass("d-none");
$(`#attribute-tab-${Tabs.AUTHENTICATION}`).addClass("d-none");
}
if (!actuatorEndpoints.serviceaccess) {
$("#accessStrategyTabButton").addClass("d-none");
$(`#attribute-tab-${Tabs.ACCESS_STRATEGY}`).addClass("d-none");
}
if (!actuatorEndpoints.ssosessions) {
$("#ssoSessionsTabButton").addClass("d-none");
$(`#attribute-tab-${Tabs.SSO_SESSIONS}`).addClass("d-none");
}
if (!actuatorEndpoints.auditlog) {
$("#auditEvents").parent().addClass("d-none");
}
if ((!actuatorEndpoints.loggingconfig || !actuatorEndpoints.loggers) && !actuatorEndpoints.auditlog) {
$("#loggingTabButton").addClass("d-none");
$(`#attribute-tab-${Tabs.LOGGING}`).addClass("d-none");
}
if (!actuatorEndpoints.env || !actuatorEndpoints.configprops) {
$("#configurationTabButton").addClass("d-none");
$(`#attribute-tab-${Tabs.CONFIGURATION}`).addClass("d-none");
}
if (!actuatorEndpoints.attributeconsent) {
$("#consentTabButton").addClass("d-none");
$(`#attribute-tab-${Tabs.CONSENT}`).addClass("d-none");
}
if (!actuatorEndpoints.casvalidate) {
$("#casprotocol").parent().remove();
$("#casProtocolContainer").addClass("d-none");
}
if (!actuatorEndpoints.samlpostprofileresponse) {
$("#saml2protocol").parent().remove();
$("#saml2ProtocolContainer").addClass("d-none");
}
if (!actuatorEndpoints.samlvalidate) {
$("#saml1ProtocolContainer").addClass("d-none");
$("#saml1protocol").parent().remove();
}
if (!actuatorEndpoints.casconfig) {
$("#config-encryption-tab").addClass("d-none");
$("#casConfigSecurity").parent().remove();
}
if (!actuatorEndpoints.oidcjwks) {
$("#oidcprotocol").parent().remove();
$("#oidcProtocolContainer").addClass("d-none");
}
if (!actuatorEndpoints.samlvalidate && !actuatorEndpoints.casvalidate
&& !actuatorEndpoints.samlpostprofileresponse && !actuatorEndpoints.oidcjwks) {
$("#protocolsTabButton").addClass("d-none");
$(`#attribute-tab-${Tabs.PROTOCOLS}`).addClass("d-none");
}
if (!actuatorEndpoints.throttles) {
$("#throttlesTabButton").addClass("d-none");
$(`#attribute-tab-${Tabs.THROTTLES}`).addClass("d-none");
}
if (!actuatorEndpoints.mfadevices) {
$("#mfaTabButton").addClass("d-none");
$("#mfaDevicesTab").parent().addClass("d-none");
$(`#attribute-tab-${Tabs.MFA}`).addClass("d-none");
}
if (!actuatorEndpoints.multifactortrusteddevices) {
$("#trustedMfaDevicesTab").parent().addClass("d-none");
}
let visibleCount = $("nav.sidebar-navigation ul li:visible").length;
if (visibleCount === 0) {
$("#dashboard").hide();
Swal.fire({
title: "Palantir is unavailable!",
text: `Palantir requires a number of actuator endpoints to be enabled and exposed, and your CAS deployment fails to do so.`,
icon: "warning",
showConfirmButton: false
});
} else {
let selectedTab = window.localStorage.getItem("PalantirSelectedTab");
if (!$(`nav.sidebar-navigation ul li[data-tab-index=${selectedTab}]`).is(":visible")) {
selectedTab = Tabs.APPLICATIONS;
}
$(`nav.sidebar-navigation ul li[data-tab-index=${selectedTab}]`).click();
activateDashboardTab(selectedTab);
initializeCasFeatures().then(() => {
Promise.all([
initializeAllCharts(),
initializeScheduledTasksOperations(),
initializeServicesOperations(),
initializeAccessStrategyOperations(),
initializeHeimdallOperations(),
initializeTicketsOperations(),
initializeSystemOperations(),
initializeLoggingOperations(),
initializeSsoSessionOperations(),
initializeConfigurationOperations(),
initializePersonDirectoryOperations(),
initializeAuthenticationOperations(),
initializeConsentOperations(),
initializeCasProtocolOperations(),
initializeSAML2ProtocolOperations(),
initializeSAML1ProtocolOperations(),
initializeOidcProtocolOperations(),
initializeThrottlesOperations(),
initializeMultifactorOperations(),
initializeTrustedMultifactorOperations(),
initializeAuditEventsOperations()
]);
});
}
}, 2);
$("#dashboard").removeClass("d-none");
} catch (error) {
console.error("An error occurred:", error);
}
}
function activateDashboardTab(idx) {
try {
let tabs = new mdc.tabBar.MDCTabBar(document.querySelector("#dashboardTabBar"));
tabs.activateTab(Number(idx));
currentActiveTab = Number(idx);
updateNavigationSidebar();
} catch (e) {
console.error("An error occurred while activating tab:", e);
}
}
function selectSidebarMenuButton(selectedItem) {
$("nav.sidebar-navigation ul li").removeClass("active");
$(selectedItem).addClass("active");
const index = $(selectedItem).data("tab-index");
window.localStorage.setItem("PalantirSelectedTab", index);
return index;
}
document.addEventListener("DOMContentLoaded", () => {
$(".jqueryui-tabs").tabs();
$(".jqueryui-menu").menu();
$(".jqueryui-selectmenu").selectmenu();
$("nav.sidebar-navigation ul li").off().on("click", function () {
hideBanner();
const index = selectSidebarMenuButton(this);
activateDashboardTab(index);
});
Swal.fire({
icon: "info",
title: "Initializing Palantir",
text: "Please wait while Palantir is initializing...",
allowOutsideClick: false,
showConfirmButton: false
});
notyf = new Notyf({
duration: 3000,
ripple: true,
dismissable: true,
position: {
x: "center",
y: "bottom"
}
});
initializePalantir().then(r => {
Swal.fire({
title: "Palantir is ready!",
text: "Palantir is successfully initialized and is ready for use.",
showConfirmButton: false,
icon: "success",
timer: 800
});
});
});