WebPass / webpass /templates /share.html
ag235772's picture
Initial Release: WebPass V2 with Steganography, Crypto Vault, and Cloud Toggle
136c0f7
{% extends "base.html" %}
{% block title %}Dead Drop{% endblock %}
{% block page_title %}Secure Dead Drop{% endblock %}
{% block content %}
<div class="row justify-content-center mt-4">
<div class="col-lg-8 fade-in-up">
<div class="cyber-card p-5">
<div class="text-center mb-4">
<i class="bi bi-incognito fs-1 text-danger"></i>
<h3 class="mt-2">Self-Destructing Messages</h3>
<p class="text-muted">
Create a one-time link. The message is encrypted in your browser, stored encrypted, and deleted immediately after viewing.
</p>
</div>
<form id="create-share-form">
<div class="mb-3">
<label class="form-label text-accent">Secret Message</label>
<textarea id="secret-text" class="form-control" rows="5" placeholder="Paste your password or secret key here..." required></textarea>
</div>
<div class="mb-4">
<label class="form-label text-accent">Self-Destruct View Time (Seconds)</label>
<div class="input-group">
<span class="input-group-text bg-dark border-secondary text-warning"><i class="bi bi-stopwatch"></i></span>
<input type="number" id="view-time" class="form-control bg-dark text-white border-secondary" placeholder="e.g. 15" min="1" max="3600" required>
</div>
<small class="text-muted mt-1 d-block">Number of seconds the receiver has to read it before it wipes from their screen.</small>
</div>
<button type="submit" class="btn btn-cyber w-100 py-3">
<i class="bi bi-link-45deg me-2"></i>Generate Secure Link
</button>
</form>
<div id="result-area" class="d-none mt-4 p-3 border border-success rounded bg-dark">
<label class="fw-bold text-success mb-2">Your One-Time Link:</label>
<div class="input-group">
<input type="text" id="share-link" class="form-control text-success font-monospace" readonly>
<button class="btn btn-outline-success" onclick="copyLink()">Copy</button>
</div>
<div class="mt-2 text-danger small">
<i class="bi bi-exclamation-triangle-fill"></i> Warning: If you close this tab, the link is lost forever.
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='js/zk_crypto.js') }}"></script>
<script>
document.getElementById("create-share-form").addEventListener("submit", async (e) => {
e.preventDefault();
const password = Math.random().toString(36).slice(-10) + Math.random().toString(36).slice(-10);
const text = document.getElementById("secret-text").value;
const viewTime = document.getElementById("view-time").value;
const enc = new TextEncoder();
const salt = ZKCrypto.randomBytes(16);
const iv = ZKCrypto.randomBytes(12);
const key = await ZKCrypto.deriveKey(password, salt);
const encryptedContent = await window.crypto.subtle.encrypt(
{ name: "AES-GCM", iv: iv },
key,
enc.encode(text)
);
const b64Data = btoa(String.fromCharCode(...new Uint8Array(encryptedContent)));
const b64Salt = btoa(String.fromCharCode(...salt));
const b64Iv = btoa(String.fromCharCode(...iv));
const res = await fetch("/share/create", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
ciphertext: b64Data,
iv: b64Iv,
salt: b64Salt,
ttl: 60, // Link valid for 1 hour by default before it expires
view_time: viewTime
})
});
const data = await res.json();
let finalUrl = "";
if (data.link) {
finalUrl = `${data.link}#${password}`;
} else {
finalUrl = `${window.location.origin}/share/v/${data.id}#${password}`;
}
document.getElementById("share-link").value = finalUrl;
document.getElementById("result-area").classList.remove("d-none");
});
function copyLink() {
const copyText = document.getElementById("share-link");
copyText.select();
document.execCommand("copy");
alert("Link copied!");
}
</script>
{% endblock %}