|
1 | | -import { useEffect, useState } from 'react'; |
2 | | -import DownloadService from '../../services/download-service'; |
3 | | -import EncryptionService from '../../services/encryption-service'; |
4 | | -import { FileEncryptDecryptType } from '../../types'; |
5 | | -import BarLoader from '../common/loader'; |
6 | | -import '../../css/index.css'; |
7 | | -import '../../css/file-encrypt-decrypt.css'; |
| 1 | +import { useEffect, useState } from "react"; |
| 2 | +import DownloadService from "../../services/download-service"; |
| 3 | +import EncryptionService from "../../services/encryption-service"; |
| 4 | +import { FileEncryptDecryptType } from "../../types"; |
| 5 | +import BarLoader from "../common/loader"; |
| 6 | +import ConfigService from "../../services/config-service"; |
| 7 | +import "../../css/index.css"; |
| 8 | +import "../../css/file-encrypt-decrypt.css"; |
8 | 9 |
|
9 | | -const commonFileOperations = async (file: any) => { |
10 | | - const blobOfFile: Blob = new Blob([file]); |
11 | | - const arrayBuffer: ArrayBuffer = await blobOfFile.arrayBuffer(); |
12 | | - return arrayBuffer; |
| 10 | +declare global { |
| 11 | + interface Window { |
| 12 | + QRCode: any; |
| 13 | + } |
13 | 14 | } |
| 15 | +const { QRCode } = window; |
| 16 | + |
| 17 | +const getNewQRCodeObject = () => { |
| 18 | + const name = "qrcode"; |
| 19 | + return new QRCode(name, { |
| 20 | + ...ConfigService.QR_CODE_CONFIG, |
| 21 | + correctLevel: QRCode.CorrectLevel.H, |
| 22 | + }); |
| 23 | +}; |
| 24 | + |
| 25 | +const commonFileOperations = async (file: any) => { |
| 26 | + const blobOfFile: Blob = new Blob([file]); |
| 27 | + const arrayBuffer: ArrayBuffer = await blobOfFile.arrayBuffer(); |
| 28 | + return arrayBuffer; |
| 29 | +}; |
14 | 30 |
|
15 | 31 | // Drag and Drop Events. MDN Ref: https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/File_drag_and_drop |
16 | | -const dropHandler = async (ev: any, type: string, encrytionParameters: any, setEncryptionParameters: any) => { |
17 | | - ev.preventDefault(); |
18 | | - if (ev.dataTransfer.items) { |
19 | | - // Use DataTransferItemList interface to access the file(s) |
20 | | - switch (type) { |
21 | | - case 'encrypt': |
22 | | - const { algorithm, IV, key } = encrytionParameters; |
23 | | - for (let i = 0; i < ev.dataTransfer.items.length; i++) { |
24 | | - // If dropped items aren't files, reject them |
25 | | - if (ev.dataTransfer.items[i].kind === 'file') { |
26 | | - const file = ev.dataTransfer.items[i].getAsFile(); |
27 | | - const arrayBuffer: ArrayBuffer = await commonFileOperations(file); |
28 | | - setEncryptionParameters({ ...encrytionParameters, fileEncryptionLoader: true }); |
29 | | - const { blob, iv, savableKey } = await EncryptionService.encryptFileUsingAlgorithm(arrayBuffer, algorithm, IV, key); |
30 | | - setEncryptionParameters({ ...encrytionParameters, fileEncryptionLoader: false }); |
31 | | - const JSONBlob: Blob = new Blob([JSON.stringify({ iv, key: savableKey })], { |
32 | | - type: 'application/json' |
33 | | - }); |
34 | | - setEncryptionParameters({ ...encrytionParameters, keyFileUploaded: false }); |
35 | | - DownloadService.downloadBlob(JSONBlob, `key-${file.name}.json`); |
36 | | - DownloadService.downloadBlob(blob, `encrypted-${file.name}`); |
37 | | - } |
38 | | - } |
39 | | - break; |
40 | | - case 'decrypt': |
41 | | - // setEncryptionParameters({ algorithm: null, IV: null, key: null, }); |
42 | | - const iv: any = encrytionParameters.iv || encrytionParameters.IV; |
43 | | - if (encrytionParameters.key && (iv)) { |
44 | | - for (let i = 0; i < ev.dataTransfer.items.length; i++) { |
45 | | - // If dropped items aren't files, reject them |
46 | | - if (ev.dataTransfer.items[i].kind === 'file') { |
47 | | - const file = ev.dataTransfer.items[i].getAsFile(); |
48 | | - const arrayBuffer: ArrayBuffer = await commonFileOperations(file); |
49 | | - setEncryptionParameters({ ...encrytionParameters, fileEncryptionLoader: true }); |
50 | | - const blob = await EncryptionService.decryptUploadedFile(arrayBuffer, iv, encrytionParameters.key); |
51 | | - setEncryptionParameters({ ...encrytionParameters, fileEncryptionLoader: false }); |
52 | | - const fileName = file?.name?.startsWith('encrypted') ? file.name.replace(/encrypted-/i, '') : file.name; |
53 | | - DownloadService.downloadBlob(blob, `${fileName}`); |
54 | | - } |
55 | | - } |
56 | | - } |
57 | | - break; |
58 | | - case 'key-file': |
59 | | - if (ev.dataTransfer.items[0].kind === 'file') { |
60 | | - const file = ev.dataTransfer.items[0].getAsFile(); |
61 | | - if (file.type === "application/json") { |
62 | | - const data: any = await EncryptionService.fileToJSON(file); |
63 | | - const keyFile = JSON.parse(data); |
64 | | - if (keyFile.iv && keyFile.key) |
65 | | - setEncryptionParameters({ ...keyFile, keyFileUploaded: true }); |
66 | | - else |
67 | | - alert("Uploaded JSON is not an valid key file!"); |
68 | | - } |
69 | | - else { |
70 | | - alert("Uploaded file is not a valid key file. Please check file and reupload again. It should be an JSON file"); |
71 | | - } |
72 | | - } |
73 | | - break; |
74 | | - default: |
75 | | - if (ev.dataTransfer.items[0].kind === 'file') { |
76 | | - const file = ev.dataTransfer.items[0].getAsFile(); |
77 | | - console.log('Key: ' + file.name); |
78 | | - } |
79 | | - break; |
| 32 | +const dropHandler = async ( |
| 33 | + ev: any, |
| 34 | + type: string, |
| 35 | + encrytionParameters: any, |
| 36 | + setEncryptionParameters: any |
| 37 | +) => { |
| 38 | + ev.preventDefault(); |
| 39 | + if (ev.dataTransfer.items) { |
| 40 | + // Use DataTransferItemList interface to access the file(s) |
| 41 | + switch (type) { |
| 42 | + case "encrypt": |
| 43 | + const { algorithm, IV, key } = encrytionParameters; |
| 44 | + for (let i = 0; i < ev.dataTransfer.items.length; i++) { |
| 45 | + // If dropped items aren't files, reject them |
| 46 | + if (ev.dataTransfer.items[i].kind === "file") { |
| 47 | + const file = ev.dataTransfer.items[i].getAsFile(); |
| 48 | + const arrayBuffer: ArrayBuffer = await commonFileOperations(file); |
| 49 | + setEncryptionParameters({ |
| 50 | + ...encrytionParameters, |
| 51 | + fileEncryptionLoader: true, |
| 52 | + }); |
| 53 | + const { blob, iv, savableKey } = |
| 54 | + await EncryptionService.encryptFileUsingAlgorithm( |
| 55 | + arrayBuffer, |
| 56 | + algorithm, |
| 57 | + IV, |
| 58 | + key |
| 59 | + ); |
| 60 | + setEncryptionParameters({ |
| 61 | + ...encrytionParameters, |
| 62 | + fileEncryptionLoader: false, |
| 63 | + }); |
| 64 | + const JSONToExport = JSON.stringify({ iv, key: savableKey }); |
| 65 | + |
| 66 | + const QR_CODE = getNewQRCodeObject(); |
| 67 | + QR_CODE.makeCode(JSONToExport); |
| 68 | + const dataUrl = document.getElementById('qrcode')!.querySelector('img')!.src; |
| 69 | + DownloadService.downloadURI(dataUrl, `qrcode-key-${file.name}`); |
| 70 | + |
| 71 | + const JSONBlob: Blob = new Blob([JSONToExport], { |
| 72 | + type: "application/json", |
| 73 | + }); |
| 74 | + setEncryptionParameters({ |
| 75 | + ...encrytionParameters, |
| 76 | + keyFileUploaded: false, |
| 77 | + }); |
| 78 | + DownloadService.downloadBlob(JSONBlob, `key-${file.name}.json`); |
| 79 | + DownloadService.downloadBlob(blob, `encrypted-${file.name}`); |
| 80 | + } |
| 81 | + } |
| 82 | + break; |
| 83 | + case "decrypt": |
| 84 | + // setEncryptionParameters({ algorithm: null, IV: null, key: null, }); |
| 85 | + const iv: any = encrytionParameters.iv || encrytionParameters.IV; |
| 86 | + if (encrytionParameters.key && iv) { |
| 87 | + for (let i = 0; i < ev.dataTransfer.items.length; i++) { |
| 88 | + // If dropped items aren't files, reject them |
| 89 | + if (ev.dataTransfer.items[i].kind === "file") { |
| 90 | + const file = ev.dataTransfer.items[i].getAsFile(); |
| 91 | + const arrayBuffer: ArrayBuffer = await commonFileOperations(file); |
| 92 | + setEncryptionParameters({ |
| 93 | + ...encrytionParameters, |
| 94 | + fileEncryptionLoader: true, |
| 95 | + }); |
| 96 | + const blob = await EncryptionService.decryptUploadedFile( |
| 97 | + arrayBuffer, |
| 98 | + iv, |
| 99 | + encrytionParameters.key |
| 100 | + ); |
| 101 | + setEncryptionParameters({ |
| 102 | + ...encrytionParameters, |
| 103 | + fileEncryptionLoader: false, |
| 104 | + }); |
| 105 | + const fileName = file?.name?.startsWith("encrypted") |
| 106 | + ? file.name.replace(/encrypted-/i, "") |
| 107 | + : file.name; |
| 108 | + DownloadService.downloadBlob(blob, `${fileName}`); |
| 109 | + } |
| 110 | + } |
80 | 111 | } |
81 | | - } else { |
82 | | - // Use DataTransfer interface to access the file(s) |
83 | | - for (let i = 0; i < ev.dataTransfer.files.length; i++) { |
84 | | - console.log('... file[' + i + '].name = ' + ev.dataTransfer.files[i].name); |
| 112 | + break; |
| 113 | + case "key-file": |
| 114 | + if (ev.dataTransfer.items[0].kind === "file") { |
| 115 | + const file = ev.dataTransfer.items[0].getAsFile(); |
| 116 | + if (file.type === "application/json") { |
| 117 | + const data: any = await EncryptionService.fileToJSON(file); |
| 118 | + const keyFile = JSON.parse(data); |
| 119 | + if (keyFile.iv && keyFile.key) |
| 120 | + setEncryptionParameters({ ...keyFile, keyFileUploaded: true }); |
| 121 | + else alert("Uploaded JSON is not an valid key file!"); |
| 122 | + } else { |
| 123 | + alert( |
| 124 | + "Uploaded file is not a valid key file. Please check file and reupload again. It should be an JSON file" |
| 125 | + ); |
| 126 | + } |
85 | 127 | } |
| 128 | + break; |
| 129 | + default: |
| 130 | + if (ev.dataTransfer.items[0].kind === "file") { |
| 131 | + const file = ev.dataTransfer.items[0].getAsFile(); |
| 132 | + console.log("Key: " + file.name); |
| 133 | + } |
| 134 | + break; |
86 | 135 | } |
87 | | -} |
| 136 | + } else { |
| 137 | + // Use DataTransfer interface to access the file(s) |
| 138 | + for (let i = 0; i < ev.dataTransfer.files.length; i++) { |
| 139 | + console.log( |
| 140 | + "... file[" + i + "].name = " + ev.dataTransfer.files[i].name |
| 141 | + ); |
| 142 | + } |
| 143 | + } |
| 144 | +}; |
88 | 145 |
|
89 | 146 | const dragOverHandler = (ev: any) => ev.preventDefault(); |
90 | 147 |
|
91 | 148 | const FileEncryptDecrypt = () => { |
92 | | - const defaultState: FileEncryptDecryptType = { |
93 | | - fileEncryptionLoader: false, |
94 | | - fileDecryptionLoader: false, |
95 | | - }; |
96 | | - const [encrytionParameters, setEncryptionParameters] = useState(defaultState); |
97 | | - useEffect(() => { fetchAndSetParameters() }, []); |
| 149 | + const defaultState: FileEncryptDecryptType = { |
| 150 | + fileEncryptionLoader: false, |
| 151 | + fileDecryptionLoader: false, |
| 152 | + }; |
| 153 | + const [encrytionParameters, setEncryptionParameters] = useState(defaultState); |
| 154 | + useEffect(() => { |
| 155 | + fetchAndSetParameters(); |
| 156 | + }, []); |
98 | 157 |
|
99 | | - const fetchAndSetParameters = async () => { |
100 | | - const { algorithm, IV, key } = await EncryptionService.generateRandomKey(); |
101 | | - setEncryptionParameters({ algorithm, IV, key, keyFile: null, }); |
102 | | - } |
103 | | - |
104 | | - return ( |
105 | | - <> |
106 | | - <div className="file-ed-container dark"> |
107 | | - {!encrytionParameters?.keyFileUploaded ? |
108 | | - (<section className="file-input encrypt"> |
109 | | - <div id="drop_zone" className='encrypt' onDrop={e => { |
110 | | - e.preventDefault(); |
111 | | - dropHandler(e, 'encrypt', encrytionParameters, setEncryptionParameters); |
112 | | - }} onDragOver={dragOverHandler}> |
113 | | - { |
114 | | - !encrytionParameters.fileEncryptionLoader ? |
115 | | - (<p className='file-title'>{'Drag and drop a file here start Encryption ...'}</p>) : <BarLoader /> |
116 | | - } |
117 | | - </div> |
118 | | - </section>) |
119 | | - : '' |
120 | | - } |
121 | | - <section className='file-input'> |
122 | | - { |
123 | | - encrytionParameters?.keyFileUploaded ? |
124 | | - (<div id="drop_zone" className='decrypt' onDrop={e => { |
125 | | - e.preventDefault(); |
126 | | - dropHandler(e, 'decrypt', encrytionParameters, setEncryptionParameters); |
127 | | - }} onDragOver={dragOverHandler}> |
128 | | - <p className='file-title'>{'Drag and drop a file here start Decryption ...'}</p> |
129 | | - </div>) : '' |
130 | | - } |
| 158 | + const fetchAndSetParameters = async () => { |
| 159 | + const { algorithm, IV, key } = await EncryptionService.generateRandomKey(); |
| 160 | + setEncryptionParameters({ algorithm, IV, key, keyFile: null }); |
| 161 | + }; |
131 | 162 |
|
132 | | - <div id="drop_zone" className='key-file' onDrop={e => { |
133 | | - e.preventDefault(); |
134 | | - dropHandler(e, 'key-file', encrytionParameters, setEncryptionParameters); |
135 | | - }} onDragOver={dragOverHandler}> |
136 | | - <p className='file-title'>{encrytionParameters?.keyFileUploaded ? 'Key Uploaded. Upload encrypted file in decryption section.' : 'Drop key file here to initiate Decryption menu..'}</p> |
137 | | - </div> |
138 | | - </section> |
| 163 | + return ( |
| 164 | + <> |
| 165 | + <div className="file-ed-container dark"> |
| 166 | + {!encrytionParameters?.keyFileUploaded ? ( |
| 167 | + <section className="file-input encrypt"> |
| 168 | + <div |
| 169 | + id="drop_zone" |
| 170 | + className="encrypt" |
| 171 | + onDrop={(e) => { |
| 172 | + e.preventDefault(); |
| 173 | + dropHandler( |
| 174 | + e, |
| 175 | + "encrypt", |
| 176 | + encrytionParameters, |
| 177 | + setEncryptionParameters |
| 178 | + ); |
| 179 | + }} |
| 180 | + onDragOver={dragOverHandler} |
| 181 | + > |
| 182 | + {!encrytionParameters.fileEncryptionLoader ? ( |
| 183 | + <p className="file-title"> |
| 184 | + {"Drag and drop a file here start Encryption ..."} |
| 185 | + </p> |
| 186 | + ) : ( |
| 187 | + <BarLoader /> |
| 188 | + )} |
139 | 189 | </div> |
140 | | - </> |
141 | | - ) |
| 190 | + </section> |
| 191 | + ) : ( |
| 192 | + "" |
| 193 | + )} |
| 194 | + <section className="file-input"> |
| 195 | + {encrytionParameters?.keyFileUploaded ? ( |
| 196 | + <div |
| 197 | + id="drop_zone" |
| 198 | + className="decrypt" |
| 199 | + onDrop={(e) => { |
| 200 | + e.preventDefault(); |
| 201 | + dropHandler( |
| 202 | + e, |
| 203 | + "decrypt", |
| 204 | + encrytionParameters, |
| 205 | + setEncryptionParameters |
| 206 | + ); |
| 207 | + }} |
| 208 | + onDragOver={dragOverHandler} |
| 209 | + > |
| 210 | + <p className="file-title"> |
| 211 | + {"Drag and drop a file here start Decryption ..."} |
| 212 | + </p> |
| 213 | + </div> |
| 214 | + ) : ( |
| 215 | + "" |
| 216 | + )} |
| 217 | + |
| 218 | + <div |
| 219 | + id="drop_zone" |
| 220 | + className="key-file" |
| 221 | + onDrop={(e) => { |
| 222 | + e.preventDefault(); |
| 223 | + dropHandler( |
| 224 | + e, |
| 225 | + "key-file", |
| 226 | + encrytionParameters, |
| 227 | + setEncryptionParameters |
| 228 | + ); |
| 229 | + }} |
| 230 | + onDragOver={dragOverHandler} |
| 231 | + > |
| 232 | + <p className="file-title"> |
| 233 | + {encrytionParameters?.keyFileUploaded |
| 234 | + ? "Key Uploaded. Upload encrypted file in decryption section." |
| 235 | + : "Drop key file here to initiate Decryption menu.."} |
| 236 | + </p> |
| 237 | + </div> |
| 238 | + </section> |
| 239 | + <section className="qrcode" id="qrcode"></section> |
| 240 | + </div> |
| 241 | + </> |
| 242 | + ); |
142 | 243 | }; |
143 | 244 |
|
144 | 245 | export default FileEncryptDecrypt; |
0 commit comments