Add upload support to transit encrypt/decrypt. Closes #4.
This commit is contained in:
parent
7bbd1e26ba
commit
d7d86b6bc8
|
@ -29,7 +29,7 @@ export function CopyableInputBox(text: string, copyable = true): CopyableInputBo
|
||||||
|
|
||||||
const inputBoxInput = makeElement({
|
const inputBoxInput = makeElement({
|
||||||
tag: "input",
|
tag: "input",
|
||||||
class: ["uk-input"],
|
class: ["uk-input-copyable"],
|
||||||
attributes: { "readonly": true, "type": "text" },
|
attributes: { "readonly": true, "type": "text" },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
42
src/elements/FileUploadInput.ts
Normal file
42
src/elements/FileUploadInput.ts
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import { makeElement } from "../htmlUtils";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export function FileUploadInput(name: string): Element {
|
||||||
|
const fileInput = makeElement({
|
||||||
|
tag: "input",
|
||||||
|
attributes: {
|
||||||
|
name: name,
|
||||||
|
type: "file"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const selectInput = makeElement({
|
||||||
|
tag: "input",
|
||||||
|
class: ["uk-input", "uk-form-width-medium"],
|
||||||
|
attributes: {
|
||||||
|
type: "text",
|
||||||
|
placeholder: i18next.t("file_upload_input_btn")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const fileIcon = makeElement({
|
||||||
|
tag: "a",
|
||||||
|
class: "uk-form-icon",
|
||||||
|
attributes: {
|
||||||
|
"uk-icon": "icon: upload",
|
||||||
|
"role": "img"
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return makeElement({
|
||||||
|
tag: "div",
|
||||||
|
attributes: {
|
||||||
|
"uk-form-custom": "target: true"
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
fileIcon,
|
||||||
|
fileInput,
|
||||||
|
selectInput
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
|
@ -61,4 +61,11 @@ export function setElementAttributes(element: Element, attributes: {[propName: s
|
||||||
for (const key of Object.getOwnPropertyNames(attributes)) {
|
for (const key of Object.getOwnPropertyNames(attributes)) {
|
||||||
element.setAttribute(key, attributes[key]);
|
element.setAttribute(key, attributes[key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const fileToBase64 = (file: File): Promise<string> => new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
reader.onload = () => resolve(reader.result as string);
|
||||||
|
reader.onerror = error => reject(error);
|
||||||
|
});
|
|
@ -1,8 +1,9 @@
|
||||||
import { CopyableModal } from "../../elements/CopyableModal";
|
import { CopyableModal } from "../../elements/CopyableModal";
|
||||||
|
import { FileUploadInput } from "../../elements/FileUploadInput";
|
||||||
import { Margin } from "../../elements/Margin";
|
import { Margin } from "../../elements/Margin";
|
||||||
import { Page } from "../../types/Page";
|
import { Page } from "../../types/Page";
|
||||||
import { changePage, setErrorText, setPageContent, setTitleElement } from "../../pageUtils";
|
import { changePage, setErrorText, setPageContent, setTitleElement } from "../../pageUtils";
|
||||||
import { makeElement } from "../../htmlUtils";
|
import { fileToBase64, makeElement } from "../../htmlUtils";
|
||||||
import { pageState } from "../../globalPageState";
|
import { pageState } from "../../globalPageState";
|
||||||
import { transitDecrypt } from "../../api/transitDecrypt";
|
import { transitDecrypt } from "../../api/transitDecrypt";
|
||||||
import UIkit from 'uikit/dist/js/uikit.min.js';
|
import UIkit from 'uikit/dist/js/uikit.min.js';
|
||||||
|
@ -35,6 +36,7 @@ export class TransitDecryptPage extends Page {
|
||||||
name: "ciphertext",
|
name: "ciphertext",
|
||||||
}
|
}
|
||||||
})),
|
})),
|
||||||
|
Margin(FileUploadInput("ciphertext_file")),
|
||||||
Margin([
|
Margin([
|
||||||
makeElement({
|
makeElement({
|
||||||
tag: "div",
|
tag: "div",
|
||||||
|
@ -70,18 +72,27 @@ export class TransitDecryptPage extends Page {
|
||||||
]
|
]
|
||||||
}) as HTMLFormElement;
|
}) as HTMLFormElement;
|
||||||
setPageContent(this.transitDecryptForm);
|
setPageContent(this.transitDecryptForm);
|
||||||
this.transitDecryptForm.addEventListener("submit", function (e: Event) {
|
this.transitDecryptForm.addEventListener("submit", async function (e: Event) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.transitEncryptFormHandler();
|
await this.transitDecryptFormHandler();
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
transitEncryptFormHandler(): void {
|
async transitDecryptFormHandler(): Promise<void> {
|
||||||
const formData = new FormData(this.transitDecryptForm);
|
const formData = new FormData(this.transitDecryptForm);
|
||||||
|
|
||||||
|
const decodeBase64 = formData.get("decodeBase64Checkbox") as string;
|
||||||
|
|
||||||
transitDecrypt(pageState.currentBaseMount, pageState.currentSecret, formData.get("ciphertext") as string).then(res => {
|
let ciphertext = formData.get("ciphertext") as string;
|
||||||
|
|
||||||
|
const ciphertext_file = formData.get("ciphertext_file") as File;
|
||||||
|
if (ciphertext_file.size > 0) {
|
||||||
|
ciphertext = atob((await fileToBase64(ciphertext_file) as string).replace("data:text/plain;base64,", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
transitDecrypt(pageState.currentBaseMount, pageState.currentSecret, ciphertext).then(res => {
|
||||||
let plaintext = res.plaintext;
|
let plaintext = res.plaintext;
|
||||||
if (formData.get("decodeBase64Checkbox") as string == "on") {
|
if (decodeBase64 == "on") {
|
||||||
plaintext = atob(plaintext);
|
plaintext = atob(plaintext);
|
||||||
}
|
}
|
||||||
const modal = CopyableModal(i18next.t("transit_decrypt_decryption_result_modal_title"), plaintext);
|
const modal = CopyableModal(i18next.t("transit_decrypt_decryption_result_modal_title"), plaintext);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { CopyableModal } from "../../elements/CopyableModal";
|
import { CopyableModal } from "../../elements/CopyableModal";
|
||||||
|
import { FileUploadInput } from "../../elements/FileUploadInput";
|
||||||
import { Margin } from "../../elements/Margin";
|
import { Margin } from "../../elements/Margin";
|
||||||
import { Page } from "../../types/Page";
|
import { Page } from "../../types/Page";
|
||||||
import { changePage, setErrorText, setPageContent, setTitleElement } from "../../pageUtils";
|
import { changePage, setErrorText, setPageContent, setTitleElement } from "../../pageUtils";
|
||||||
import { makeElement } from "../../htmlUtils";
|
import { fileToBase64, makeElement } from "../../htmlUtils";
|
||||||
import { pageState } from "../../globalPageState";
|
import { pageState } from "../../globalPageState";
|
||||||
import { transitEncrypt } from "../../api/transitEncrypt";
|
import { transitEncrypt } from "../../api/transitEncrypt";
|
||||||
import UIkit from 'uikit/dist/js/uikit.min.js';
|
import UIkit from 'uikit/dist/js/uikit.min.js';
|
||||||
|
@ -37,6 +38,7 @@ export class TransitEncryptPage extends Page {
|
||||||
name: "plaintext",
|
name: "plaintext",
|
||||||
}
|
}
|
||||||
})),
|
})),
|
||||||
|
Margin(FileUploadInput("plaintext_file")),
|
||||||
Margin([
|
Margin([
|
||||||
makeElement({
|
makeElement({
|
||||||
tag: "div",
|
tag: "div",
|
||||||
|
@ -73,17 +75,29 @@ export class TransitEncryptPage extends Page {
|
||||||
}) as HTMLFormElement;
|
}) as HTMLFormElement;
|
||||||
setPageContent(this.transitEncryptForm);
|
setPageContent(this.transitEncryptForm);
|
||||||
|
|
||||||
this.transitEncryptForm.addEventListener("submit", function (e) {
|
this.transitEncryptForm.addEventListener("submit", async function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.transitEncryptFormHandler();
|
await this.transitEncryptFormHandler();
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
transitEncryptFormHandler(): void {
|
async transitEncryptFormHandler(): Promise<void> {
|
||||||
const formData = new FormData(this.transitEncryptForm);
|
const formData = new FormData(this.transitEncryptForm);
|
||||||
const encodedData =
|
|
||||||
formData.get("base64Checkbox") as string == "on" ? formData.get("plaintext") as string : btoa(formData.get("plaintext") as string);
|
const base64Checkbox = formData.get("base64Checkbox") as string;
|
||||||
transitEncrypt(pageState.currentBaseMount, pageState.currentSecret, encodedData).then(res => {
|
|
||||||
|
let plaintext = formData.get("plaintext") as string;
|
||||||
|
|
||||||
|
const plaintext_file = formData.get("plaintext_file") as File;
|
||||||
|
if (plaintext_file.size > 0) {
|
||||||
|
plaintext = (await fileToBase64(plaintext_file) as string).replace("data:text/plain;base64,", "");
|
||||||
|
plaintext = base64Checkbox == "on" ? atob(plaintext) : plaintext;
|
||||||
|
} else {
|
||||||
|
plaintext = base64Checkbox == "on" ? plaintext : btoa(plaintext);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
transitEncrypt(pageState.currentBaseMount, pageState.currentSecret, plaintext).then(res => {
|
||||||
const modal = CopyableModal(i18next.t("transit_encrypt_encryption_result_modal_title"), res.ciphertext);
|
const modal = CopyableModal(i18next.t("transit_encrypt_encryption_result_modal_title"), res.ciphertext);
|
||||||
document.body.querySelector("#pageContent").appendChild(modal);
|
document.body.querySelector("#pageContent").appendChild(modal);
|
||||||
UIkit.modal(modal).show();
|
UIkit.modal(modal).show();
|
||||||
|
|
|
@ -76,4 +76,4 @@ $form-radio-background: $global-secondary-background;
|
||||||
@import "uikit/src/scss/components/inverse.scss";
|
@import "uikit/src/scss/components/inverse.scss";
|
||||||
|
|
||||||
// TODO: replace this with a better solution to https://github.com/uikit/uikit/discussions/4458
|
// TODO: replace this with a better solution to https://github.com/uikit/uikit/discussions/4458
|
||||||
.uk-input { padding-left: $form-icon-width !important; }
|
.uk-input-copyable { padding-left: $form-icon-width !important; }
|
3
src/translations/en.js
vendored
3
src/translations/en.js
vendored
|
@ -21,6 +21,9 @@ module.exports = {
|
||||||
// Copyable Input Box
|
// Copyable Input Box
|
||||||
"copy_input_box_copy_icon_text": "Copy Button",
|
"copy_input_box_copy_icon_text": "Copy Button",
|
||||||
|
|
||||||
|
// File Upload Input
|
||||||
|
"file_upload_input_btn": "Upload File",
|
||||||
|
|
||||||
// Me Page
|
// Me Page
|
||||||
"me_page_title": "Me/Settings",
|
"me_page_title": "Me/Settings",
|
||||||
"log_out_btn": "Log Out",
|
"log_out_btn": "Log Out",
|
||||||
|
|
Loading…
Reference in a new issue