2024-06-26 15:57:15 +00:00
|
|
|
const collapsibleButton = document.querySelector("#hamburger-menu");
|
|
|
|
const menuContent = document.querySelector(".menu-content");
|
|
|
|
collapsibleButton.addEventListener("click", function () {
|
|
|
|
menuContent.classList.toggle("active");
|
|
|
|
if (menuContent.style.display === "block") {
|
|
|
|
menuContent.style.display = "none";
|
|
|
|
} else {
|
|
|
|
menuContent.style.display = "block";
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2024-10-12 18:38:31 +00:00
|
|
|
// Toggle theme
|
|
|
|
const toggleButton = document.getElementById('theme-toggle');
|
|
|
|
const htmlElement = document.documentElement;
|
|
|
|
|
|
|
|
function applyTheme() {
|
|
|
|
const savedTheme = localStorage.getItem('theme');
|
|
|
|
if (savedTheme === 'dark') {
|
|
|
|
toggleButton.checked = true;
|
|
|
|
htmlElement.classList.add('dark-theme');
|
|
|
|
} else {
|
|
|
|
htmlElement.classList.remove('dark-theme');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-12 19:37:08 +00:00
|
|
|
// toggleButton.addEventListener('click', () => {
|
|
|
|
// if (htmlElement.classList.contains('dark-theme')) {
|
|
|
|
// htmlElement.classList.remove('dark-theme');
|
|
|
|
// localStorage.setItem('theme', 'light');
|
|
|
|
// } else {
|
|
|
|
// htmlElement.classList.add('dark-theme');
|
|
|
|
// localStorage.setItem('theme', 'dark');
|
|
|
|
// }
|
|
|
|
// });
|
2024-06-26 15:57:15 +00:00
|
|
|
|
2024-10-12 18:38:31 +00:00
|
|
|
// Load the saved theme on page load
|
|
|
|
window.onload = () => {
|
|
|
|
// applyTheme();
|
|
|
|
resetFormFields()
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
function resetFormFields() {
|
|
|
|
const form = document.getElementById('wizard-container');
|
|
|
|
form.reset();
|
|
|
|
|
|
|
|
const policy_field = document.getElementById('policy');
|
|
|
|
policy_field.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
function readFileAsText(file) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
const reader = new FileReader();
|
|
|
|
|
|
|
|
reader.onload = function (e) {
|
|
|
|
resolve(e.target.result);
|
|
|
|
};
|
|
|
|
|
|
|
|
reader.onerror = function (e) {
|
|
|
|
reject(new Error(`Error reading file ${file.name}: ${e.target.error.message}`));
|
|
|
|
};
|
|
|
|
|
|
|
|
return reader.readAsText(file);
|
2024-06-26 15:57:15 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-10-12 18:38:31 +00:00
|
|
|
async function extractValues() {
|
|
|
|
const policy = {}
|
|
|
|
|
|
|
|
const policyValidToDateEl = document.getElementById('policy_valid_to_date');
|
|
|
|
const policyValidToDate = policyValidToDateEl.value.replace(/-/g, "/");
|
|
|
|
if (policyValidToDate) {
|
|
|
|
policy.policy_valid_to_date = policyValidToDate;
|
|
|
|
console.log(policyValidToDate);
|
|
|
|
}
|
|
|
|
|
|
|
|
const policyValidAfterDateEl = document.getElementById('policy_valid_after_date');
|
|
|
|
const policyValidAfterDate = policyValidAfterDateEl.value.replace(/-/g, "/");
|
|
|
|
if (policyValidAfterDate) {
|
|
|
|
policy.policy_valid_after_date = policyValidAfterDate;
|
|
|
|
console.log(policyValidAfterDate);
|
|
|
|
}
|
|
|
|
|
|
|
|
const policyMutableLl = document.getElementById('policy_mutable');
|
|
|
|
const policyMutable = policyMutableLl.value;
|
|
|
|
if (policyMutable) {
|
|
|
|
policy.policy_mutable = policyMutable;
|
|
|
|
console.log(policyMutable);
|
|
|
|
}
|
|
|
|
|
|
|
|
const remoteAvailableEl = document.getElementById('remote_available');
|
|
|
|
const remoteAvailable = remoteAvailableEl.value;
|
|
|
|
if (remoteAvailable) {
|
|
|
|
policy.remote_available = remoteAvailable;
|
|
|
|
console.log(remoteAvailable);
|
|
|
|
}
|
|
|
|
|
|
|
|
const remoteThresholdEl = document.getElementById('remote_threshold');
|
|
|
|
const remoteThreshold = remoteThresholdEl.value;
|
|
|
|
if (remoteThreshold) {
|
|
|
|
policy.remote_threshold = remoteThreshold;
|
|
|
|
console.log(remoteThreshold);
|
|
|
|
}
|
|
|
|
|
|
|
|
const pubKeysEl = document.getElementById('pub_keys');
|
|
|
|
const pubKeys = pubKeysEl.files;
|
|
|
|
let pubKeyData = [];
|
|
|
|
for (let i = 0; i < pubKeys.length; i++) {
|
|
|
|
const pubKeyFile = pubKeys[i];
|
|
|
|
const fileText = await readFileAsText(pubKeyFile);
|
|
|
|
pubKeyData.push(fileText);
|
|
|
|
}
|
|
|
|
if (pubKeyData.length) {
|
|
|
|
policy.pub_keys = pubKeyData;
|
|
|
|
console.log(pubKeys);
|
|
|
|
}
|
|
|
|
|
|
|
|
const kycAvailableEl = document.getElementById('kyc_available');
|
|
|
|
const kycAvailable = kycAvailableEl.value;
|
|
|
|
if (kycAvailable) {
|
|
|
|
policy.kyc_available = kycAvailable;
|
|
|
|
console.log(kycAvailable);
|
|
|
|
}
|
|
|
|
|
|
|
|
const kycThresholdEl = document.getElementById('kyc_threshold');
|
|
|
|
const kycThreshold = kycThresholdEl.value;
|
|
|
|
if (kycThreshold) {
|
|
|
|
policy.kyc_threshold = kycThreshold;
|
|
|
|
console.log(kycThreshold);
|
|
|
|
}
|
|
|
|
|
|
|
|
const kycDataEl = document.getElementById('kyc_data');
|
2024-10-12 19:37:08 +00:00
|
|
|
const kycDataFiles = kycDataEl.files;
|
|
|
|
let kycData = [];
|
|
|
|
for (let i = 0; i < kycDataFiles.length; i++) {
|
|
|
|
const kycDataFile = kycDataFiles[i];
|
|
|
|
const fileText = await readFileAsText(kycDataFile);
|
|
|
|
kycData.push(fileText);
|
|
|
|
}
|
|
|
|
if (kycData.length) {
|
2024-10-12 18:38:31 +00:00
|
|
|
policy.kyc_data = kycData;
|
|
|
|
console.log(kycData);
|
|
|
|
}
|
|
|
|
|
|
|
|
const dataStorageEl = document.getElementById('data_storage');
|
|
|
|
const dataStorage = dataStorageEl.value;
|
|
|
|
if (dataStorage) {
|
|
|
|
policy.data_storage = dataStorage;
|
|
|
|
console.log(dataStorage)
|
|
|
|
}
|
|
|
|
|
|
|
|
const multiRuleRequirementEl = document.getElementById('multi_rule_requirement');
|
|
|
|
const multiRuleRequirement = multiRuleRequirementEl.value;
|
|
|
|
if (multiRuleRequirement) {
|
|
|
|
policy.multi_rule_requirement = multiRuleRequirement;
|
|
|
|
console.log(multiRuleRequirement);
|
|
|
|
}
|
|
|
|
|
|
|
|
return policy;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function generatePolicy(event) {
|
|
|
|
event.preventDefault()
|
|
|
|
const policyValues = extractValues();
|
|
|
|
|
|
|
|
const tomlPolicy = objectToTOML(policyValues);
|
|
|
|
console.log(tomlPolicy);
|
|
|
|
|
|
|
|
const policyTextEl = document.getElementById('policy');
|
|
|
|
policyTextEl.value = toml_policy;
|
|
|
|
}
|
|
|
|
|
|
|
|
function validateThreshold(threshold) {
|
|
|
|
const regex = /^\d+\/\d+$/;
|
|
|
|
const valid = regex.test(threshold);
|
|
|
|
let res = {
|
|
|
|
threshold,
|
|
|
|
};
|
2024-06-26 15:57:15 +00:00
|
|
|
|
2024-10-12 18:38:31 +00:00
|
|
|
if (valid) {
|
|
|
|
const numbers = threshold.split('/');
|
|
|
|
if (Number(numbers[0]) > Number(numbers[1])) {
|
|
|
|
res.error = "Error: first number has to be lesser than second.";
|
|
|
|
} else {
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
res.error = "Error: invalid threshold value. Use n/m format where n < m"
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
function objectToTOML(obj, indent = '') {
|
|
|
|
let toml = '';
|
|
|
|
|
|
|
|
for (const key in obj) {
|
|
|
|
if (obj.hasOwnProperty(key)) {
|
|
|
|
const value = obj[key];
|
|
|
|
|
|
|
|
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
|
|
toml += `${indent}[${key}]\n`;
|
|
|
|
toml += objectToTOML(value, `${indent} `);
|
|
|
|
} else if (Array.isArray(value)) {
|
|
|
|
toml += `${indent}${key} = [${value.map(v => JSON.stringify(v)).join(', ')}]\n`;
|
|
|
|
} else {
|
|
|
|
toml += `${indent}${key} = ${JSON.stringify(value)}\n`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return toml;
|
|
|
|
}
|
|
|
|
|
|
|
|
function clearSegments() {
|
|
|
|
const segmentLeft = document.getElementById('segment-left');
|
|
|
|
const segmentMiddle = document.getElementById('segment-middle');
|
|
|
|
const segmentRight = document.getElementById('segment-right');
|
|
|
|
|
|
|
|
segmentLeft.classList.remove('active-segment');
|
|
|
|
segmentMiddle.classList.remove('active-segment');
|
|
|
|
segmentRight.classList.remove('active-segment');
|
|
|
|
|
|
|
|
const fromDateArrow = document.getElementById('from-date-arrow');
|
|
|
|
const toDateArrow = document.getElementById('to-date-arrow');
|
|
|
|
|
|
|
|
fromDateArrow.innerText = "";
|
|
|
|
toDateArrow.innerText = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
function colorSegment(from_date, to_date) {
|
|
|
|
clearSegments();
|
|
|
|
|
|
|
|
const segmentLeft = document.getElementById('segment-left');
|
|
|
|
const segmentMiddle = document.getElementById('segment-middle');
|
|
|
|
const segmentRight = document.getElementById('segment-right');
|
|
|
|
|
|
|
|
const fromDateArrow = document.getElementById('from-date-arrow');
|
|
|
|
const toDateArrow = document.getElementById('to-date-arrow');
|
|
|
|
|
|
|
|
if (from_date && !to_date) {
|
|
|
|
segmentMiddle.classList.add('active-segment');
|
|
|
|
segmentRight.classList.add('active-segment');
|
|
|
|
|
|
|
|
fromDateArrow.innerText = '→';
|
|
|
|
} else if (!from_date && to_date) {
|
|
|
|
segmentLeft.classList.add('active-segment');
|
|
|
|
segmentMiddle.classList.add('active-segment');
|
|
|
|
|
|
|
|
toDateArrow.innerText = '←';
|
|
|
|
} else if (from_date && to_date) {
|
|
|
|
const fromDateTyped = new Date(from_date);
|
|
|
|
const toDateTyped = new Date(to_date);
|
|
|
|
if (fromDateTyped < toDateTyped) {
|
|
|
|
segmentMiddle.classList.add('active-segment');
|
|
|
|
|
|
|
|
fromDateArrow.innerText = '→';
|
|
|
|
toDateArrow.innerText = '←';
|
|
|
|
} else if (fromDateTyped > toDateTyped) {
|
|
|
|
segmentLeft.classList.add('active-segment');
|
|
|
|
segmentRight.classList.add('active-segment');
|
|
|
|
|
|
|
|
fromDateArrow.innerText = '←';
|
|
|
|
toDateArrow.innerText = '→';
|
|
|
|
} else {
|
|
|
|
clearSegments();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
clearSegments();
|
2024-06-26 15:57:15 +00:00
|
|
|
}
|
2024-10-12 18:38:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: fix listeners to only activate if on the correct
|
|
|
|
|
|
|
|
const toDatePicker = document.getElementById('policy_valid_to_date');
|
|
|
|
const fromDatePicker = document.getElementById('policy_valid_after_date');
|
|
|
|
const fromDateMarker = document.getElementById('from_date');
|
|
|
|
const toDateMarker = document.getElementById('to_date');
|
|
|
|
|
|
|
|
fromDatePicker.addEventListener('change', function () {
|
|
|
|
fromDateMarker.innerText = fromDatePicker.value;
|
|
|
|
toDateMarker.innerText = toDatePicker.value;
|
|
|
|
|
|
|
|
let from_value = fromDatePicker.value;
|
|
|
|
let to_value = toDatePicker.value;
|
|
|
|
|
|
|
|
colorSegment(from_value, to_value);
|
|
|
|
});
|
|
|
|
|
|
|
|
toDatePicker.addEventListener('change', function () {
|
|
|
|
fromDateMarker.innerText = fromDatePicker.value;
|
|
|
|
toDateMarker.innerText = toDatePicker.value;
|
|
|
|
|
|
|
|
let fromValue = fromDatePicker.value;
|
|
|
|
let toValue = toDatePicker.value;
|
|
|
|
|
|
|
|
colorSegment(fromValue, toValue);
|
|
|
|
});
|
2024-06-26 15:57:15 +00:00
|
|
|
|
2024-10-12 18:38:31 +00:00
|
|
|
let remoteAvailableEl = document.getElementById('remote_available');
|
|
|
|
remoteAvailableEl.addEventListener('input', function () {
|
|
|
|
let currentValue = remoteAvailableEl.value;
|
|
|
|
let remoteAvailableContainer = document.getElementById('remote_available_container');
|
|
|
|
if (currentValue == 'true') {
|
|
|
|
remoteAvailableContainer.classList.remove('hidden');
|
|
|
|
} else {
|
|
|
|
remoteAvailableContainer.classList.add('hidden');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
const remoteThresholdEl = document.getElementById('remote_threshold');
|
|
|
|
remoteThresholdEl.addEventListener('input', function () {
|
|
|
|
const remoteThresholdErrorEl = document.getElementById('remote_threshold_error');
|
|
|
|
remoteThresholdErrorEl.innerText = "";
|
|
|
|
const currentValue = remoteThresholdEl.value;
|
|
|
|
|
|
|
|
const thresholdRes = validateThreshold(currentValue)
|
|
|
|
if (thresholdRes.error) {
|
|
|
|
remoteThresholdErrorEl.innerText = thresholdRes.error;
|
2024-06-26 15:57:15 +00:00
|
|
|
}
|
2024-10-12 18:38:31 +00:00
|
|
|
});
|
2024-06-26 15:57:15 +00:00
|
|
|
|
2024-10-12 19:37:08 +00:00
|
|
|
const kycThresholdEl = document.getElementById('kyc_threshold');
|
|
|
|
kycThresholdEl.addEventListener('input', function () {
|
|
|
|
const kycThresholdErrorEl = document.getElementById('kyc_threshold_error');
|
|
|
|
kycThresholdErrorEl.innerText = "";
|
|
|
|
const currentValue = kycThresholdEl.value;
|
|
|
|
const thresholdRes = validateThreshold(currentValue)
|
|
|
|
if (thresholdRes.error) {
|
|
|
|
kycThresholdErrorEl.innerText = thresholdRes.error;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2024-10-12 18:38:31 +00:00
|
|
|
const pubKeysErrorEl = document.getElementById('pub_keys_error');
|
|
|
|
const pubKeys = document.getElementById('pub_keys')
|
|
|
|
pubKeys.addEventListener('change', function () {
|
|
|
|
pubKeysErrorEl.innerText = "";
|
|
|
|
const res = validateThreshold(remoteThresholdEl.value);
|
|
|
|
if (pubKeys.files.length < res.threshold.split('/')[1] || !res || !res.threshold) {
|
2024-10-12 19:37:08 +00:00
|
|
|
pubKeysErrorEl.innerText = "Please select a valid threshold or upload the correct number of public key files.";
|
2024-10-12 18:38:31 +00:00
|
|
|
pubKeys.value = "";
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2024-10-12 19:37:08 +00:00
|
|
|
const kycDataErrorEl = document.getElementById('kyc_data_error');
|
|
|
|
const kycData = document.getElementById('kyc_data')
|
|
|
|
kycData.addEventListener('change', function () {
|
|
|
|
kycDataErrorEl.innerText = "";
|
|
|
|
const res = validateThreshold(kycThresholdEl.value);
|
|
|
|
if (kycData.files.length < res.threshold.split('/')[1] || !res || !res.threshold) {
|
|
|
|
kycDataErrorEl.innerText = "Please select a valid threshold or upload the correct number of public key files.";
|
|
|
|
kycData.value = "";
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2024-10-12 18:38:31 +00:00
|
|
|
let kycAvailableEl = document.getElementById('kyc_available');
|
|
|
|
kycAvailableEl.addEventListener('input', function () {
|
|
|
|
let currentValue = kycAvailableEl.value;
|
|
|
|
let remoteAvailableContainer = document.getElementById('kyc_available_container');
|
|
|
|
if (currentValue == 'true') {
|
|
|
|
remoteAvailableContainer.classList.remove('hidden');
|
|
|
|
} else {
|
|
|
|
remoteAvailableContainer.classList.add('hidden');
|
|
|
|
}
|
|
|
|
});
|