diff options
Diffstat (limited to 'index.html')
| -rw-r--r-- | index.html | 194 | 
1 files changed, 194 insertions, 0 deletions
| diff --git a/index.html b/index.html new file mode 100644 index 0000000..f4fe7a3 --- /dev/null +++ b/index.html @@ -0,0 +1,194 @@ +<!DOCTYPE html> +<html lang="en" data-theme="dark"> + +<head> +  <meta charset="UTF-8"> +  <meta name="description" content="AES-256 Encryption Example"> +  <title>Secure Paste</title> +  <link rel="icon" href="./favicon.svg" type="image/svg+xml"> +  <link rel="stylesheet" href="./pico.min.css"> +</head> + +<body> +  <main class="container"> +    <h1>paste-cgi</h1> + +    <form id="cryptoForm"> +      <label for="title">Title</label> +      <input type="text" id="title" placeholder="Enter a title" required /> + +      <label for="plaintext">Paste</label> +      <textarea id="plaintext" rows="5" placeholder="Enter your paste" required></textarea> + +      <label for="pasteType">Type</label> +      <select id="pasteType" onchange="togglePasteType()"> +        <option value="plain">Plain</option> +        <option value="password">Password</option> +      </select> + +      <div id="passwordField" style="display: none;"> +        <label for="password">Password</label> +        <input type="password" id="password" placeholder="Enter your password" /> +      </div> + +      <label for="expiration">Expiration</label> +      <select id="expiration"> +        <option value="never">Never</option> +        <option value="burn_after_read">Burn after read</option> +        <option value="10_minutes">10 minutes</option> +        <option value="1_hour">1 hour</option> +        <option value="1_day">1 Day</option> +        <option value="1_week">1 Week</option> +        <option value="2_weeks">2 Weeks</option> +        <option value="1_month">1 Month</option> +        <option value="6_months">6 Months</option> +        <option value="1_year">1 Year</option> +      </select> + +      <button type="button" id="encryptBtn" onclick="handlePaste()">Paste</button> +    </form> + +    <div id="pasteUrlSection" style="display: none;"> +      <h3>Paste Url:</h3> +      <input id="pasteUrl" readonly></textarea> +      <button type="button" onclick="copyPaste()">Copy</button> +    </div> +  </main> + +  <script> +    const pasteTypeConstant = "pasteType"; +    const passwordFieldConstant = "passwordField"; +    const passwordTypeConstant = "password"; +    const plainTypeConstant = "plain"; +    const titleConstant = "title"; +    const expirationConstant = "expiration"; +    const plaintextConstant = "plaintext"; +    const pasteUrlConstant = "pasteUrl" +    const pasteUrlSectionConstant = "pasteUrlSection" + +    function copyPaste(){ +      var copyText = document.getElementById(pasteUrlConstant); + +      copyText.select(); +      copyText.setSelectionRange(0, 99999); + +      navigator.clipboard.writeText(copyText.value); +    } + +    function togglePasteType() { +      const passwordType = document.getElementById(pasteTypeConstant).value; +      const passwordField = document.getElementById(passwordFieldConstant); +      if (passwordType === passwordTypeConstant) { +        passwordField.style.display = 'block'; +      } else { +        passwordField.style.display = 'none'; +      } +    } + +    async function deriveKey(password, salt) { +      let encodedPassword = new TextEncoder().encode(password); +      let baseKey = await window.crypto.subtle.importKey( +        "raw", +        encodedPassword, +        { name: "PBKDF2" }, +        false, +        ["deriveKey"], +      ); + +      let derivedKey = await window.crypto.subtle.deriveKey( +        { +          name: "PBKDF2", +          salt: salt, +          iterations: 600000, +          hash: "SHA-256", +        }, +        baseKey, +        { name: "AES-GCM", length: 256 }, +        true, +        ["encrypt", "decrypt"], +      ); + +      return derivedKey; +    } + +    async function encryptData(data, password) { +      let salt = window.crypto.getRandomValues(new Uint8Array(16)); +      let iv = window.crypto.getRandomValues(new Uint8Array(12)); +      let key = await deriveKey(password, salt); +      let encodedData = new TextEncoder().encode(data); + +      let encryptedContent = await window.crypto.subtle.encrypt( +        { +          name: "AES-GCM", +          iv: iv, +          tagLength: 128, +        }, +        key, +        encodedData, +      ); + +      let ciphertext = encryptedContent.slice( +        0, +        encryptedContent.byteLength - 16, +      ); +      let authTag = encryptedContent.slice(encryptedContent.byteLength - 16); + +      return { +        ciphertext: new Uint8Array(ciphertext), +        iv: iv, +        authTag: new Uint8Array(authTag), +        salt: salt, +      }; +    } +     +    async function handlePaste() { +      let type = document.getElementById(pasteTypeConstant).value; +      let title = document.getElementById(titleConstant).value; +      let expiration = document.getElementById(expirationConstant).value; +      let plaintext = document.getElementById(plaintextConstant).value; +      let password = document.getElementById(passwordTypeConstant).value; + +      let pasted_text = "" +      if (type == plainTypeConstant) { +        if (!plaintext || !title) return alert("Enter title and paste."); + +        pasted_text = plaintext +      } +      else { +        if (!plaintext || !password || !title) return alert("Enter title, paste and password."); + +        let encrypted = await encryptData(plaintext, password); +        pasted_text = btoa(JSON.stringify(encrypted)) +      } + +      let currentPath = window.location.origin; + +      try { +        let response = await fetch(currentPath + "/submit", { +          method: "POST", +          headers: { +            "Content-Type": "application/json", +          }, +          body: JSON.stringify({ +            type: type, +            title: title, +            expiration: expiration, +            pasted_text: pasted_text +          }), +        }); + +        if (response.ok) { +          let jsonResponse = await response.json(); +          document.getElementById(pasteUrlConstant).value = currentPath + "/get?id=" + jsonResponse.id; +          document.getElementById(pasteUrlSectionConstant).style.display = 'block'; +        } else { +          console.error("Failed to submit data. Status:", response.status); +        } +      } catch (error) { +        console.error("Error making the POST request:", error); +      } +    } +  </script> +</body> + +</html>
\ No newline at end of file | 
