Initial commit
This commit is contained in:
commit
49cbb85e7b
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
node_modules/
|
||||
yarn-error.log
|
||||
package.json.lock
|
||||
dist/
|
5
.idea/.gitignore
generated
vendored
Normal file
5
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
6
.idea/jsLibraryMappings.xml
generated
Normal file
6
.idea/jsLibraryMappings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptLibraryMappings">
|
||||
<includedPredefinedLibrary name="Node.js Core" />
|
||||
</component>
|
||||
</project>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/ourcrypt.iml" filepath="$PROJECT_DIR$/.idea/ourcrypt.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
12
.idea/ourcrypt.iml
generated
Normal file
12
.idea/ourcrypt.iml
generated
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
2
electron-builder.env
Normal file
2
electron-builder.env
Normal file
@ -0,0 +1,2 @@
|
||||
ELECTRON_ENABLE_LOGGING=1
|
||||
NODE_ENV=production
|
77
package.json
Normal file
77
package.json
Normal file
@ -0,0 +1,77 @@
|
||||
{
|
||||
"name": "ourcrypt",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"compile": "tsc && webpack",
|
||||
"watchTs": "tsc -w",
|
||||
"watchWp": "webpack --watch",
|
||||
"start": "yarn run compile && electron ./dist/main.js --trace-warnings",
|
||||
"dist": "electron-builder",
|
||||
"distMult": "electron-builder --linux --win",
|
||||
"build": "yarn run compile && yarn run dist",
|
||||
"fullBuild": "yarn run compile && yarn run distMult",
|
||||
"pack": "electron-builder --dir"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": {
|
||||
"email": "tobi@gaminggeneration.de",
|
||||
"name": "Tobias Hopp",
|
||||
"url": "https://git.gaminggeneration.de/tobiash/"
|
||||
},
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "^6.0.5",
|
||||
"@types/electron": "^1.6.10",
|
||||
"@types/typescript": "^2.0.0",
|
||||
"electron": "^23.1.1",
|
||||
"electron-builder": "^23.6.0",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^4.9.5",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-cli": "^5.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.3.4",
|
||||
"crypto": "^1.0.1",
|
||||
"electron-pug": "^2.0.0",
|
||||
"electron-store": "^8.1.0",
|
||||
"electron-updater": "^5.3.0",
|
||||
"openpgp": "^5.7.0"
|
||||
},
|
||||
"build": {
|
||||
"appId": "net.hopp.tobias.ourcrypt",
|
||||
"productName": "TryCrypt",
|
||||
"forceCodeSigning": false,
|
||||
"artifactName": "TryCrypt_${version}_${os}_${arch}.${ext}",
|
||||
"files": [
|
||||
"dist/**/*",
|
||||
"static/**/*",
|
||||
"node_modules/**/*",
|
||||
"package.json"
|
||||
],
|
||||
"win": {
|
||||
"target": "nsis"
|
||||
},
|
||||
"nsis": {
|
||||
"oneClick": true,
|
||||
"perMachine": false,
|
||||
"allowToChangeInstallationDirectory": false
|
||||
},
|
||||
"linux": {
|
||||
"target": "AppImage",
|
||||
"icon": "staticWeb/Infoscreen-Logo_256x256.png",
|
||||
"category": "System",
|
||||
"description": "The official infoscreen app compiled for debian"
|
||||
},
|
||||
"deb": {},
|
||||
"directories": {
|
||||
"output": "releases"
|
||||
},
|
||||
"publish": {
|
||||
"provider": "generic",
|
||||
"url": "https://infoscreen.iif.li/releases/"
|
||||
}
|
||||
}
|
||||
}
|
160
src/main.ts
Normal file
160
src/main.ts
Normal file
@ -0,0 +1,160 @@
|
||||
import {app, BrowserWindow, dialog, ipcMain, powerSaveBlocker, screen} from "electron";
|
||||
import * as path from "path";
|
||||
import AppUpdater from "./updater";
|
||||
const crypto = require('crypto');
|
||||
|
||||
const setupPug = require('electron-pug');
|
||||
const packageJson = require("../package.json");
|
||||
const Store = require('electron-store');
|
||||
|
||||
|
||||
const store = new Store();
|
||||
|
||||
|
||||
process.on("uncaughtException", (err) => {
|
||||
console.log("Uncaught Exception")
|
||||
console.error(err);
|
||||
const messageBoxOptions = {
|
||||
type: "error",
|
||||
title: "Shit - There was an error!",
|
||||
message: err.message
|
||||
};
|
||||
dialog.showMessageBoxSync(messageBoxOptions);
|
||||
});
|
||||
|
||||
const updater = new AppUpdater();
|
||||
let pug;
|
||||
|
||||
|
||||
const operatingSystem = process.platform;
|
||||
console.log("Starting TryCrypt v" + packageJson.version);
|
||||
console.log("Detected operating system is " + operatingSystem);
|
||||
|
||||
let mainWindow: BrowserWindow;
|
||||
|
||||
|
||||
function sleep(ms: number) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => resolve(null), ms);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main window
|
||||
*/
|
||||
function createWindow() {
|
||||
return new Promise((resolve) => {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, "preload.js"),
|
||||
contextIsolation: true,
|
||||
nodeIntegration: true,
|
||||
},
|
||||
width: 1000,
|
||||
height: 600,
|
||||
alwaysOnTop: false,
|
||||
autoHideMenuBar: false,
|
||||
title: "TryCrypt",
|
||||
show: true,
|
||||
});
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile(path.join(__dirname, "../static/index.pug"));
|
||||
|
||||
mainWindow.on("ready-to-show", (e: Event) => {
|
||||
resolve(true);
|
||||
});
|
||||
|
||||
mainWindow.on("closed", () => {
|
||||
console.log("Closing app...");
|
||||
app.exit(0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* App is ready (Electron has booted up!)
|
||||
*/
|
||||
app.on("ready", async () => {
|
||||
try {
|
||||
pug = await setupPug({pretty: true});
|
||||
pug.on('error', (err: string) => console.error('render error', err));
|
||||
|
||||
let updateAvailable = await updater.checkForUpdates();
|
||||
if (updateAvailable) {
|
||||
await updater.downloadAndInstallUpdate();
|
||||
const messageBoxOptions = {
|
||||
type: "info",
|
||||
title: "Update!",
|
||||
message: "An update of this application will be installed now..."
|
||||
};
|
||||
dialog.showMessageBoxSync(messageBoxOptions);
|
||||
return;
|
||||
}
|
||||
|
||||
await createWindow();
|
||||
|
||||
} catch (e) {
|
||||
app.relaunch();
|
||||
app.exit();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
////// IPC HANDLES \\\\\\\
|
||||
|
||||
function generateRandom(length: number) {
|
||||
let result = '';
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
const charactersLength = characters.length;
|
||||
let counter = 0;
|
||||
while (counter < length) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
counter += 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Relaunch handler
|
||||
ipcMain.on("relaunch", () => {
|
||||
app.relaunch();
|
||||
app.exit();
|
||||
return;
|
||||
});
|
||||
|
||||
|
||||
ipcMain.handle("getKey", (e) => {
|
||||
console.log("Key requested!");
|
||||
return [store.get('key'), store.get('iv')];
|
||||
});
|
||||
|
||||
ipcMain.handle("generateKey", (e) => {
|
||||
console.log("Key generating...");
|
||||
const key = generateRandom(32);
|
||||
const iv = generateRandom(16);
|
||||
return [key, iv];
|
||||
});
|
||||
|
||||
ipcMain.on("setKey", (e, key: string, iv: string) => {
|
||||
console.log("Got new key!");
|
||||
store.set('key', key);
|
||||
store.set('iv', iv);
|
||||
});
|
||||
|
||||
ipcMain.handle("encrypt", (e, text) => {
|
||||
console.log("Encrypting...");
|
||||
const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(store.get('key')), Buffer.from(store.get('iv')));
|
||||
const encryptedData = cipher.update(text, 'utf8', 'base64') + cipher.final('base64');
|
||||
return encryptedData;
|
||||
});
|
||||
|
||||
ipcMain.handle("decrypt", (e, text) => {
|
||||
console.log("Decrypting...");
|
||||
const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(store.get('key')), Buffer.from(store.get('iv')));
|
||||
let decrypted = decipher.update(text, 'base64', 'utf8');
|
||||
decrypted += decipher.final('utf8');
|
||||
return decrypted.toString();
|
||||
});
|
30
src/preload.ts
Normal file
30
src/preload.ts
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) Tobias Hopp, 2022.
|
||||
* This program is copyright protected.
|
||||
* Copying, distributing or using source code is prohibited.
|
||||
* Any distribution or illegal copying will be prosecuted.
|
||||
*
|
||||
* You may not use this sourcecode.
|
||||
*
|
||||
*/
|
||||
|
||||
import {contextBridge, ipcRenderer} from "electron";
|
||||
|
||||
|
||||
contextBridge.exposeInMainWorld('trycrypt', {
|
||||
getKey: () : Promise<string[]> => {
|
||||
return ipcRenderer.invoke("getKey");
|
||||
},
|
||||
setKey: (key: string, iv: string) => {
|
||||
ipcRenderer.send("setKey", key, iv);
|
||||
},
|
||||
generateKey: () : Promise<string[]> => {
|
||||
return ipcRenderer.invoke("generateKey");
|
||||
},
|
||||
encrypt: (text: string) : Promise<string> => {
|
||||
return ipcRenderer.invoke("encrypt", text);
|
||||
},
|
||||
decrypt: (text: string) : Promise<string> => {
|
||||
return ipcRenderer.invoke("decrypt", text);
|
||||
}
|
||||
})
|
14
src/tsconfig.json
Normal file
14
src/tsconfig.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"*": [
|
||||
"/src/*"
|
||||
]
|
||||
},
|
||||
"module": "Node16",
|
||||
"target": "ES6"
|
||||
},
|
||||
"include": [
|
||||
]
|
||||
}
|
59
src/updater.ts
Normal file
59
src/updater.ts
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) Tobias Hopp, 2022.
|
||||
* This program is copyright protected.
|
||||
* Copying, distributing or using source code is prohibited.
|
||||
* Any distribution or illegal copying will be prosecuted.
|
||||
*
|
||||
* You may not use this sourcecode.
|
||||
*
|
||||
*/
|
||||
|
||||
import {autoUpdater} from "electron-updater";
|
||||
|
||||
export default class AppUpdater {
|
||||
constructor() {
|
||||
|
||||
//log.transports.file.level = "debug"
|
||||
autoUpdater.autoDownload = false;
|
||||
autoUpdater.allowDowngrade = false;
|
||||
autoUpdater.setFeedURL("https://infoscreen.iif.li/releases/");
|
||||
}
|
||||
|
||||
public checkForUpdates(): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
autoUpdater.on('update-available', (ev) => {
|
||||
resolve(true);
|
||||
})
|
||||
autoUpdater.on('update-not-available', (ev) => {
|
||||
resolve(false);
|
||||
})
|
||||
|
||||
autoUpdater.on("update-cancelled", () => {
|
||||
resolve(false);
|
||||
})
|
||||
|
||||
autoUpdater.checkForUpdates().then(result => {
|
||||
if (result == null)
|
||||
resolve(false);
|
||||
}).catch(() => reject());
|
||||
setTimeout( () => reject(false), 1000 * 30 );
|
||||
});
|
||||
}
|
||||
|
||||
public downloadAndInstallUpdate() {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
autoUpdater.on('update-downloaded', (ev) => {
|
||||
// Wait 5 seconds, then quit and install
|
||||
// In your application, you don't need to wait 5 seconds.
|
||||
// You could call autoUpdater.quitAndInstall(); immediately
|
||||
resolve(true);
|
||||
setTimeout(() => autoUpdater.quitAndInstall(true, true), 5000);
|
||||
});
|
||||
autoUpdater.downloadUpdate().catch(() => reject());
|
||||
} catch (e) {
|
||||
reject();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
97
src/web/page.ts
Normal file
97
src/web/page.ts
Normal file
@ -0,0 +1,97 @@
|
||||
let key: string, iv: string;
|
||||
let keyField: HTMLInputElement;
|
||||
let ivField: HTMLInputElement;
|
||||
let keySave: HTMLButtonElement;
|
||||
let keyShow: HTMLButtonElement;
|
||||
let keyGenerate: HTMLButtonElement;
|
||||
let decryptBtn: HTMLButtonElement;
|
||||
let encryptBtn: HTMLButtonElement;
|
||||
let userTB: HTMLTextAreaElement;
|
||||
let systemTB: HTMLTextAreaElement;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
// Loaded
|
||||
keyField = document.getElementById("keyField") as HTMLInputElement;
|
||||
ivField = document.getElementById("ivField") as HTMLInputElement;
|
||||
keySave = document.getElementById("keySave") as HTMLButtonElement;
|
||||
keyShow = document.getElementById("keyRefresh") as HTMLButtonElement;
|
||||
keyGenerate = document.getElementById("generateRandom") as HTMLButtonElement;
|
||||
userTB = document.getElementById("userTB") as HTMLTextAreaElement;
|
||||
systemTB = document.getElementById("systemTB") as HTMLTextAreaElement;
|
||||
encryptBtn = document.getElementById("btnEncrypt") as HTMLButtonElement;
|
||||
decryptBtn = document.getElementById("btnDecrypt") as HTMLButtonElement;
|
||||
|
||||
systemTB.onclick = () => {
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(systemTB);
|
||||
const selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
navigator.clipboard.writeText(systemTB.value);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// @ts-ignore
|
||||
[key, iv] = await window.trycrypt.getKey();
|
||||
|
||||
if (key)
|
||||
keyField.value = key;
|
||||
if (iv)
|
||||
ivField.value = iv;
|
||||
|
||||
keySave.onclick = () => onKeySave();
|
||||
keyShow.onmousedown = () => {
|
||||
keyField.type = "text";
|
||||
ivField.type = "text";
|
||||
}
|
||||
keyShow.onmouseup = () => {
|
||||
keyField.type = "password";
|
||||
ivField.type = "password";
|
||||
}
|
||||
|
||||
encryptBtn.onclick = () => encrypt();
|
||||
decryptBtn.onclick = () => decrypt();
|
||||
keyGenerate.onclick = () => generateRandom();
|
||||
});
|
||||
|
||||
function onKeySave() {
|
||||
key = keyField.value;
|
||||
iv = ivField.value;
|
||||
// @ts-ignore
|
||||
window.trycrypt.setKey(key, iv);
|
||||
keySave.style.backgroundColor = "green";
|
||||
setTimeout(() => keySave.style.backgroundColor = "", 1000);
|
||||
}
|
||||
|
||||
async function generateRandom() {
|
||||
//@ts-ignore
|
||||
let [gen_key, gen_iv] = await window.trycrypt.generateKey();
|
||||
key = gen_key;
|
||||
iv = gen_iv;
|
||||
|
||||
keyField.value = key;
|
||||
ivField.value = iv;
|
||||
|
||||
keyField.type = "text";
|
||||
ivField.type = "text";
|
||||
setTimeout( () => {
|
||||
keyField.type = "password";
|
||||
ivField.type = "password";
|
||||
}, 3000 );
|
||||
}
|
||||
|
||||
async function encrypt() {
|
||||
let text = userTB.value;
|
||||
|
||||
// @ts-ignore
|
||||
systemTB.value = await window.trycrypt.encrypt(text);
|
||||
}
|
||||
|
||||
async function decrypt() {
|
||||
let text = userTB.value;
|
||||
|
||||
// @ts-ignore
|
||||
systemTB.value = await window.trycrypt.decrypt(text);
|
||||
}
|
||||
|
23
src/web/tsconfig.json
Normal file
23
src/web/tsconfig.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"target": "ES6",
|
||||
"module": "CommonJS",
|
||||
"lib": [
|
||||
"es5",
|
||||
"es6",
|
||||
"dom",
|
||||
"dom.iterable"
|
||||
],
|
||||
"allowJs": true,
|
||||
"sourceMap": true,
|
||||
"downlevelIteration": true,
|
||||
"baseUrl": "src/web/",
|
||||
"paths": {
|
||||
"*": [
|
||||
"src/web/*",
|
||||
"src/preload.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
19
static/index.pug
Normal file
19
static/index.pug
Normal file
@ -0,0 +1,19 @@
|
||||
extends layout.pug
|
||||
|
||||
block body
|
||||
h1 TryCrypt
|
||||
br
|
||||
div#general
|
||||
p Please enter your KEY and IV
|
||||
input#keyField(type="password" placeholder="Passkey" style="width:30%;")
|
||||
input#ivField(type="password" placeholder="IV" style="width:16%;")
|
||||
button#keyRefresh 👁
|
||||
button#keySave Save
|
||||
button#generateRandom Generate
|
||||
br
|
||||
br
|
||||
div#boxes
|
||||
textarea#userTB(placeholder="Your encrypted or plain text" style="width: 48.5%; margin-left: 1%; height: 50%; float:left;")
|
||||
textarea#systemTB(placeholder="The decrypted/encrypted text" readonly="readonly" style="width: 48.5%; margin-left: 1%; height: 50%; float:left")
|
||||
button#btnEncrypt Encrypt
|
||||
button#btnDecrypt Decrypt
|
23
static/layout.pug
Normal file
23
static/layout.pug
Normal file
@ -0,0 +1,23 @@
|
||||
doctype "html"
|
||||
html(lang="en")
|
||||
head
|
||||
meta(charset="UTF-16")
|
||||
title TryCrypt
|
||||
|
||||
link(rel="stylesheet" href="reset.css")
|
||||
link(rel="stylesheet" href="style.css")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1")
|
||||
|
||||
script const exports = { "__esModule": true };
|
||||
|
||||
|
||||
body
|
||||
block body
|
||||
|
||||
script(src="../dist/trycrypt.bundle.js")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
60
static/reset.css
Normal file
60
static/reset.css
Normal file
@ -0,0 +1,60 @@
|
||||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
border: 0;
|
||||
font: inherit;
|
||||
font-size: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
|
||||
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: "";
|
||||
content: none;
|
||||
}
|
||||
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
60
static/style.css
Normal file
60
static/style.css
Normal file
@ -0,0 +1,60 @@
|
||||
body {
|
||||
font-size: 14pt;
|
||||
font-family: SansSerif, serif;
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 4.5em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 3.7em;
|
||||
}
|
||||
h3 {
|
||||
font-size: 3em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 2em;
|
||||
}
|
||||
h5 {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#general {
|
||||
margin-left: 3%;
|
||||
margin-top: 2%;
|
||||
}
|
||||
|
||||
button {
|
||||
border: 0;
|
||||
background-color: darkslategrey;
|
||||
color: white;
|
||||
height: 1.5em;
|
||||
border-radius: 3px;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #65A4A4;
|
||||
}
|
||||
button:active {
|
||||
background-color: #146B4D;
|
||||
}
|
||||
|
||||
#btnEncrypt, #btnDecrypt
|
||||
{
|
||||
float:left;
|
||||
margin-top: 1%;
|
||||
height: 6%;
|
||||
width: 48.5%;
|
||||
margin-left: 1%;
|
||||
}
|
||||
|
||||
|
||||
#systemTB:active {
|
||||
background-color: #91DE93;
|
||||
transition: background-color 0.1s;
|
||||
}
|
20
tsconfig.json
Normal file
20
tsconfig.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"noImplicitAny": true,
|
||||
"sourceMap": true,
|
||||
"outDir": "dist",
|
||||
"target": "ES5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"removeComments": true,
|
||||
"suppressImplicitAnyIndexErrors": true
|
||||
},
|
||||
"include": [
|
||||
"./src/"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
26
webpack.config.js
Normal file
26
webpack.config.js
Normal file
@ -0,0 +1,26 @@
|
||||
const path = require( "path" );
|
||||
|
||||
module.exports = {
|
||||
mode: "development",
|
||||
devtool: "inline-source-map",
|
||||
entry: {
|
||||
trycrypt: "./src/web/page.ts",
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: "ts-loader",
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
extensions: [".tsx", ".ts", ".js"],
|
||||
},
|
||||
output: {
|
||||
filename: "[name].bundle.js",
|
||||
path: path.resolve( __dirname, "dist" ),
|
||||
},
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user