disaster-recovery-website/_layouts/wizard.html

390 lines
16 KiB
HTML
Raw Normal View History

2024-10-08 15:01:31 +00:00
<!DOCTYPE html>
<html lang="{{ page.lang | default: site.lang | default: en }}">
{%- include head.html -%}
2024-10-07 23:10:24 +00:00
<body>
2024-10-08 15:01:31 +00:00
<div class="container">
{%- include header.html -%}
<h1>Recovery Policy Wizard</h1>
<p>
This wizard will assist you in constructing the set of rules, also
known as the Recovery Policy, which specifies under which conditions
your data can be recovered. The policy has been designed with flexibility
in mind in order to accommodate different use-cases and threat models.
</p>
2024-10-08 16:40:31 +00:00
<form id="wizard-container" onsubmit="generatePolicy(event)">
2024-10-08 15:01:31 +00:00
<section>
<h2>Time Based Rules</h2>
<p>
Time based rules allow specifying during which time period the policy is <b>active</b>.
In order to request data recovery, a policy has to be in an active state at the time the
request is made to recover data. If a policy is <b>mutable</b> (allowed to be updated),
it can also only happen while the policy is in an active state, and is done by creating
a new policy which will take place of the old one.
The dates are always interpreted in UTC (Coordinated Universal Time), at 12:00AM of the
selected date.
The two dates which are configurable, <b>from_date</b> and <b>upto_date</b> allow for
the following configurations:
<ul>
<li>
<b>from_date < upto_date</b>: makes the policy active during a time window. (e.g from_date:
2024/08/01, upto_date: 2024/09/01 would make the policy active only between those dates)
</li>
<li>
<b>upto_date < from_date</b>: makes the policy in-active during a time window (e.g upto_date:
2024/08/01, from_date: 2024/09/01 would make the policy in-active only between those
dates)
</li>
<li>
<b>upto_date only</b>: makes the policy expire after the <b>upto_date</b> (e.g upto_date:
2027/01/01 means the policy is never active again after this date.)
</li>
<li>
<b>from_date only</b>: makes the policy active after the <b>from_date</b> (e.g from_date:
2025/01/01 means the policy is active only starting after that date)
</li>
</ul>
</p>
2024-10-08 16:40:31 +00:00
<label for="policy_valid_upto_date"><b>upto_date</b> *</label>
<input required type="date" id="policy_valid_upto_date" name="policy_valid_upto_date">
2024-10-08 15:01:31 +00:00
<br>
<br>
2024-10-08 16:40:31 +00:00
<label for="policy_valid_after_date"><b>from_date</b> *</label>
<input required type="date" id="policy_valid_after_date" name="policy_valid_after_date">
2024-10-08 15:01:31 +00:00
<br>
<br>
<label for="policy_mutable">Is the policy editable (mutable) while it's active?</label>
<br>
2024-10-08 16:40:31 +00:00
<select required name="policy_mutable" id="policy_mutable">
2024-10-08 15:01:31 +00:00
<option disabled selected value> -- select an option -- </option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
</section>
<hr class="divider">
<section>
<h2>Remote Recovery via Cryptographic Signatures</h2>
2024-10-08 16:40:31 +00:00
<p>
This type of recovery makes it possible to recover data remotely
by providing cryptographic signatures to show intent of recovery.
We support all widely used types of signatures such as `OpenPGP`,
ETH, BTC, etc.
</p>
2024-10-08 15:01:31 +00:00
<label for="remote_available">Can recovery be authorized using threshold based cryptographic
2024-10-08 16:40:31 +00:00
signing? *</label>
2024-10-08 15:01:31 +00:00
<br>
2024-10-08 16:40:31 +00:00
<select required name="remote_available" id="remote_available">
2024-10-08 15:01:31 +00:00
<option disabled selected value> -- select an option -- </option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
<br>
<br>
<div id="remote_available_container" class="hidden">
<label>What threshold would you like to use for the cryptographic signing recovery method? (2/3,
3/5,
4/7
etc)</label>
<br>
<input type="text" id="remote_threshold" name="remote_threshold">
<!-- if is_remote_available is true -->
2024-10-08 16:40:31 +00:00
<p>Please select public keys which can be used for recovery. These keys should be valid public keys
for whichever protocols you would like to use. You may use a mix of protocols. Ensure each file
only has 1 key:</p>
2024-10-08 15:01:31 +00:00
<input type="file" id="pub_keys" name="files[]" multiple>
</div>
</section>
<hr class="divider">
<section>
<h2>Recovery via KYC Validation and Statement of Intent</h2>
2024-10-08 16:40:31 +00:00
<p>
Recovery via KYC requires that a threshold of authorized
persons be KYCd in person by legal representatives of Distrust
and confirm their intent to recover data. This process varies
based on the jurisdiction it's being conducted in and adds
time to the recovery process.
</p>
2024-10-08 15:01:31 +00:00
2024-10-08 16:40:31 +00:00
<label>Can recovery be authorized by persons using KYC? *</label>
2024-10-08 15:01:31 +00:00
<br>
2024-10-08 16:40:31 +00:00
<select required name="kyc_available" id="kyc_available">
2024-10-08 15:01:31 +00:00
<option disabled selected value> -- select an option -- </option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
<br>
<br>
<div id="kyc_available_container" class="hidden">
<label>What threshold would you like to use for the KYC recovery method? (2/3, 3/5, 4/7 etc)</label>
<br>
<input type="text" id="kyc_threshold" name="kyc_threshold">
2024-10-08 16:40:31 +00:00
<p>
Please select KYC data for individuals who can participate in recovery.
Each person's data should be a `.toml` file. Pictures of front and back
of IDs should be base64 encoded and listed in the <b>id_images</b> array.
The supported ID types are Driver's License, Passport, National Identity Card:
</p>
<pre>
<code>
first_name = "John"
last_name = "Doe"
date_of_birth = "1990-01-01"
id_images = ["<base_64_encoded_image>", "<base_64_encoded_image>", ...]
country_of_birth = "US"
</code>
</pre>
2024-10-08 15:01:31 +00:00
<input type="file" id="kyc_data" name="files[]" multiple>
</div>
</section>
<hr class="divider">
<section>
<h2>Data Storage</h2>
<p>
This part of the policy allows you to select wether you would like
Distrust to fully back up all your data, or to only hold an encryption
key in escrow, in which case you are responsible for redundantly backing up
the encrypted data (learn more <a href="/data-storage.html">here</a>)
</p>
2024-10-08 16:40:31 +00:00
<label>Type of data storage *</label>
2024-10-08 15:01:31 +00:00
<br>
2024-10-08 16:40:31 +00:00
<select required name="data_stroage" id="data_storage">
<option required disabled selected value> -- select an option -- </option>
2024-10-08 15:01:31 +00:00
<option value="managed">Fully managed</option>
<option value="key_escrow">Key escrow only</option>
</select>
</section>
<hr class="divider">
<section>
<h2>Additional Configurations</h2>
<label>Are both remote and KYC based recovery required? (If "No", either one can be used for
2024-10-08 16:40:31 +00:00
recovery) *</label>
2024-10-08 15:01:31 +00:00
<br>
2024-10-08 16:40:31 +00:00
<select required name="multi_rule_requirement" id="multi_rule_requirement">
2024-10-08 15:01:31 +00:00
<option disabled selected value> -- select an option -- </option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
</section>
2024-10-08 16:40:31 +00:00
<input type="submit" value="Generate Policy">
2024-10-08 15:04:24 +00:00
</form>
2024-10-08 15:07:42 +00:00
2024-10-08 15:01:31 +00:00
2024-10-08 16:40:31 +00:00
<form id="policy">
<textarea id="generated-policy-form" disabled placeholder="Click 'Generate Policy'"></textarea>
</form>
2024-10-08 15:01:31 +00:00
<script>
2024-10-08 15:04:24 +00:00
function resetFormFields() {
const form = document.getElementById('wizard-container');
form.reset();
2024-10-08 16:40:31 +00:00
const policy_field = document.getElementById('policy');
form.reset();
2024-10-08 15:04:24 +00:00
}
window.onload = resetFormFields;
2024-10-08 15:01:31 +00:00
function extractValues() {
const policy = {}
const policy_valid_upto_date_el = document.getElementById('policy_valid_upto_date');
const policy_valid_upto_date = policy_valid_upto_date_el.value.replace(/-/g, "/");
2024-10-08 16:40:31 +00:00
if (policy_valid_upto_date) {
policy.policy_valid_upto_date = policy_valid_upto_date;
console.log(policy_valid_upto_date);
}
2024-10-08 15:01:31 +00:00
const policy_valid_after_date_el = document.getElementById('policy_valid_after_date');
const policy_valid_after_date = policy_valid_after_date_el.value.replace(/-/g, "/");
2024-10-08 16:40:31 +00:00
if (policy_valid_after_date) {
policy.policy_valid_after_date = policy_valid_after_date;
console.log(policy_valid_after_date);
}
2024-10-08 15:01:31 +00:00
const policy_mutable_el = document.getElementById('policy_mutable');
const policy_mutable = policy_mutable_el.value;
2024-10-08 16:40:31 +00:00
if (policy_mutable) {
policy.policy_mutable = policy_mutable;
console.log(policy_mutable);
}
2024-10-08 15:01:31 +00:00
const remote_available_el = document.getElementById('remote_available');
const remote_available = remote_available_el.value;
2024-10-08 16:40:31 +00:00
if (remote_available) {
policy.remote_available = remote_available;
console.log(remote_available);
}
2024-10-08 15:01:31 +00:00
const remote_threshold_el = document.getElementById('remote_threshold');
const remote_threshold = remote_threshold_el.value;
2024-10-08 16:40:31 +00:00
if (remote_threshold) {
policy.remote_threshold = remote_threshold;
console.log(remote_threshold);
}
2024-10-08 15:01:31 +00:00
const pub_keys_el = document.getElementById('pub_keys');
const pub_keys = pub_keys_el.files;
2024-10-08 16:40:31 +00:00
if (pub_keys) {
policy.pub_keys = pub_keys;
console.log(pub_keys);
}
2024-10-08 15:01:31 +00:00
const kyc_available_el = document.getElementById('kyc_available');
const kyc_available = kyc_available_el.value;
2024-10-08 16:40:31 +00:00
if (kyc_available) {
policy.kyc_available = kyc_available;
console.log(kyc_available);
}
2024-10-08 15:01:31 +00:00
const kyc_threshold_el = document.getElementById('kyc_threshold');
const kyc_threshold = kyc_threshold_el.value;
2024-10-08 16:40:31 +00:00
if (kyc_threshold) {
policy.kyc_threshold = kyc_threshold;
console.log(kyc_threshold);
}
2024-10-08 15:01:31 +00:00
const kyc_data_el = document.getElementById('kyc_data');
const kyc_data = kyc_data_el.files;
2024-10-08 16:40:31 +00:00
if (kyc_data) {
policy.kyc_data = kyc_data;
console.log(kyc_data);
}
const data_storage_el = document.getElementById('data_storage');
const data_storage = data_storage_el.value;
if (data_storage) {
policy.data_storage = data_storage;
console.log(data_storage)
}
2024-10-08 15:01:31 +00:00
const multi_rule_requirement_el = document.getElementById('multi_rule_requirement');
const multi_rule_requirement = multi_rule_requirement_el.value;
2024-10-08 16:40:31 +00:00
if (multi_rule_requirement) {
policy.multi_rule_requirement = multi_rule_requirement;
console.log(multi_rule_requirement);
}
2024-10-08 15:01:31 +00:00
return policy;
}
2024-10-07 23:10:24 +00:00
2024-10-08 16:40:31 +00:00
function generatePolicy(event) {
event.preventDefault()
2024-10-08 15:01:31 +00:00
const policy_values = extractValues();
2024-10-07 23:10:24 +00:00
2024-10-08 15:01:31 +00:00
const toml_policy = objectToTOML(policy_values);
console.log(toml_policy);
2024-10-07 23:10:24 +00:00
2024-10-08 15:01:31 +00:00
const policy_text_el = document.getElementById('policy');
policy_text_el.value = toml_policy;
}
2024-10-07 23:10:24 +00:00
2024-10-08 15:01:31 +00:00
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`;
}
}
}
2024-10-07 23:10:24 +00:00
2024-10-08 15:01:31 +00:00
return toml;
}
2024-10-07 23:10:24 +00:00
2024-10-08 15:01:31 +00:00
let remote_available_el = document.getElementById('remote_available');
remote_available_el.addEventListener('input', function () {
let currentValue = remote_available_el.value;
let remote_available_container = document.getElementById('remote_available_container');
if (currentValue == 'true') {
remote_available_container.classList.remove('hidden');
} else {
remote_available_container.classList.add('hidden');
2024-10-07 23:10:24 +00:00
}
2024-10-08 15:01:31 +00:00
});
let kyc_available_el = document.getElementById('kyc_available');
kyc_available_el.addEventListener('input', function () {
let currentValue = kyc_available_el.value;
let remote_available_container = document.getElementById('kyc_available_container');
if (currentValue == 'true') {
remote_available_container.classList.remove('hidden');
} else {
remote_available_container.classList.add('hidden');
}
});
</script>
<style>
.hidden {
display: none;
2024-10-07 23:10:24 +00:00
}
2024-10-08 15:01:31 +00:00
input,
select,
textarea,
textarea::-webkit-input-placeholder {
border: 1px solid white;
2024-10-07 23:28:37 +00:00
}
2024-10-08 15:01:31 +00:00
#wizard-container {
border: 1px solid white;
border-radius: 20px;
padding: 30px;
}
.divider {
color: white;
margin: 50px 0px;
2024-10-07 23:28:37 +00:00
}
2024-10-08 15:01:31 +00:00
2024-10-08 16:40:31 +00:00
#generated-policy-form {
2024-10-08 15:01:31 +00:00
height: 400px;
padding: 30px;
margin-top: 30px;
border-radius: 20px;
}
</style>
</main>
{%- include footer.html -%}
</div>
</body>
</html>