diff --git a/.env.example b/.env.example
index eee7df6..f3e89b1 100644
--- a/.env.example
+++ b/.env.example
@@ -1,3 +1,2 @@
URL="http://localhost"
-SERVER_PORT="3030"
-MONGO="mongodb://127.0.0.1:27017/urlshortener"
\ No newline at end of file
+PORT="3030"
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index c5ff331..fbeb7d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,10 @@
-node_modules/
-package-lock.json
.env
-yarn.lock
\ No newline at end of file
+
+
+# Added by cargo
+
+/target
+Cargo.lock
+db.json
+.vscode
+.idea
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..bb3a387
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "text-display"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+dotenv = "0.15.0"
+rocket = { version = "0.5.0-rc.2", features = ["json", "secrets"] }
+rocket_cors = "0.5.2"
+rpassword = "7.2.0"
+serde = "1.0.152"
+serde_json = "1.0.93"
+text_io = "0.1.12"
+tokio = { version = "1.25.0", features = ["full"] }
+xxhash-rust = { version = "0.8.6", features = ["xxh64"] }
diff --git a/Rocket.toml b/Rocket.toml
new file mode 100644
index 0000000..13dffcb
--- /dev/null
+++ b/Rocket.toml
@@ -0,0 +1,20 @@
+## defaults for _all_ profiles
+[default]
+address = "0.0.0.0"
+limits = { form = "64 kB", json = "1 MiB" }
+
+## set only when compiled in debug mode, i.e, `cargo build`
+[debug]
+port = 8000
+## only the `json` key from `default` will be overridden; `form` will remain
+limits = { json = "10MiB" }
+
+## set only when the `nyc` profile is selected
+[nyc]
+port = 9001
+
+## set only when compiled in release mode, i.e, `cargo build --release`
+## don't use this secret_key! generate your own and keep it private!
+[release]
+port = 8000
+secret_key = "edit me"
\ No newline at end of file
diff --git a/dist/output.css b/dist/output.css
deleted file mode 100644
index a4109fe..0000000
--- a/dist/output.css
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
-! tailwindcss v3.0.16 | MIT License | https://tailwindcss.com
-*/
-
-/*
-1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
-2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
-*/
-
-*,
-::before,
-::after {
- box-sizing: border-box;
- /* 1 */
- border-width: 0;
- /* 2 */
- border-style: solid;
- /* 2 */
- border-color: #e5e7eb;
- /* 2 */
-}
-
-::before,
-::after {
- --tw-content: '';
-}
-
-/*
-1. Use a consistent sensible line-height in all browsers.
-2. Prevent adjustments of font size after orientation changes in iOS.
-3. Use a more readable tab size.
-4. Use the user's configured `sans` font-family by default.
-*/
-
-html {
- line-height: 1.5;
- /* 1 */
- -webkit-text-size-adjust: 100%;
- /* 2 */
- -moz-tab-size: 4;
- /* 3 */
- -o-tab-size: 4;
- tab-size: 4;
- /* 3 */
- font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
- /* 4 */
-}
-
-/*
-1. Remove the margin in all browsers.
-2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
-*/
-
-body {
- margin: 0;
- /* 1 */
- line-height: inherit;
- /* 2 */
-}
-
-/*
-1. Add the correct height in Firefox.
-2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
-3. Ensure horizontal rules are visible by default.
-*/
-
-hr {
- height: 0;
- /* 1 */
- color: inherit;
- /* 2 */
- border-top-width: 1px;
- /* 3 */
-}
-
-/*
-Add the correct text decoration in Chrome, Edge, and Safari.
-*/
-
-abbr:where([title]) {
- -webkit-text-decoration: underline dotted;
- text-decoration: underline dotted;
-}
-
-/*
-Remove the default font size and weight for headings.
-*/
-
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- font-size: inherit;
- font-weight: inherit;
-}
-
-/*
-Reset links to optimize for opt-in styling instead of opt-out.
-*/
-
-a {
- color: inherit;
- text-decoration: inherit;
-}
-
-/*
-Add the correct font weight in Edge and Safari.
-*/
-
-b,
-strong {
- font-weight: bolder;
-}
-
-/*
-1. Use the user's configured `mono` font family by default.
-2. Correct the odd `em` font sizing in all browsers.
-*/
-
-code,
-kbd,
-samp,
-pre {
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
- /* 1 */
- font-size: 1em;
- /* 2 */
-}
-
-/*
-Add the correct font size in all browsers.
-*/
-
-small {
- font-size: 80%;
-}
-
-/*
-Prevent `sub` and `sup` elements from affecting the line height in all browsers.
-*/
-
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-
-sub {
- bottom: -0.25em;
-}
-
-sup {
- top: -0.5em;
-}
-
-/*
-1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
-2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
-3. Remove gaps between table borders by default.
-*/
-
-table {
- text-indent: 0;
- /* 1 */
- border-color: inherit;
- /* 2 */
- border-collapse: collapse;
- /* 3 */
-}
-
-/*
-1. Change the font styles in all browsers.
-2. Remove the margin in Firefox and Safari.
-3. Remove default padding in all browsers.
-*/
-
-button,
-input,
-optgroup,
-select,
-textarea {
- font-family: inherit;
- /* 1 */
- font-size: 100%;
- /* 1 */
- line-height: inherit;
- /* 1 */
- color: inherit;
- /* 1 */
- margin: 0;
- /* 2 */
- padding: 0;
- /* 3 */
-}
-
-/*
-Remove the inheritance of text transform in Edge and Firefox.
-*/
-
-button,
-select {
- text-transform: none;
-}
-
-/*
-1. Correct the inability to style clickable types in iOS and Safari.
-2. Remove default button styles.
-*/
-
-button,
-[type='button'],
-[type='reset'],
-[type='submit'] {
- -webkit-appearance: button;
- /* 1 */
- background-color: transparent;
- /* 2 */
- background-image: none;
- /* 2 */
-}
-
-/*
-Use the modern Firefox focus style for all focusable elements.
-*/
-
-:-moz-focusring {
- outline: auto;
-}
-
-/*
-Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
-*/
-
-:-moz-ui-invalid {
- box-shadow: none;
-}
-
-/*
-Add the correct vertical alignment in Chrome and Firefox.
-*/
-
-progress {
- vertical-align: baseline;
-}
-
-/*
-Correct the cursor style of increment and decrement buttons in Safari.
-*/
-
-::-webkit-inner-spin-button,
-::-webkit-outer-spin-button {
- height: auto;
-}
-
-/*
-1. Correct the odd appearance in Chrome and Safari.
-2. Correct the outline style in Safari.
-*/
-
-[type='search'] {
- -webkit-appearance: textfield;
- /* 1 */
- outline-offset: -2px;
- /* 2 */
-}
-
-/*
-Remove the inner padding in Chrome and Safari on macOS.
-*/
-
-::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-
-/*
-1. Correct the inability to style clickable types in iOS and Safari.
-2. Change font properties to `inherit` in Safari.
-*/
-
-::-webkit-file-upload-button {
- -webkit-appearance: button;
- /* 1 */
- font: inherit;
- /* 2 */
-}
-
-/*
-Add the correct display in Chrome and Safari.
-*/
-
-summary {
- display: list-item;
-}
-
-/*
-Removes the default spacing and border for appropriate elements.
-*/
-
-blockquote,
-dl,
-dd,
-h1,
-h2,
-h3,
-h4,
-h5,
-h6,
-hr,
-figure,
-p,
-pre {
- margin: 0;
-}
-
-fieldset {
- margin: 0;
- padding: 0;
-}
-
-legend {
- padding: 0;
-}
-
-ol,
-ul,
-menu {
- list-style: none;
- margin: 0;
- padding: 0;
-}
-
-/*
-Prevent resizing textareas horizontally by default.
-*/
-
-textarea {
- resize: vertical;
-}
-
-/*
-1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
-2. Set the default placeholder color to the user's configured gray 400 color.
-*/
-
-input::-moz-placeholder, textarea::-moz-placeholder {
- opacity: 1;
- /* 1 */
- color: #9ca3af;
- /* 2 */
-}
-
-input:-ms-input-placeholder, textarea:-ms-input-placeholder {
- opacity: 1;
- /* 1 */
- color: #9ca3af;
- /* 2 */
-}
-
-input::placeholder,
-textarea::placeholder {
- opacity: 1;
- /* 1 */
- color: #9ca3af;
- /* 2 */
-}
-
-/*
-Set the default cursor for buttons.
-*/
-
-button,
-[role="button"] {
- cursor: pointer;
-}
-
-/*
-Make sure disabled buttons don't get the pointer cursor.
-*/
-
-:disabled {
- cursor: default;
-}
-
-/*
-1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
-2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
- This can trigger a poorly considered lint error in some tools but is included by design.
-*/
-
-img,
-svg,
-video,
-canvas,
-audio,
-iframe,
-embed,
-object {
- display: block;
- /* 1 */
- vertical-align: middle;
- /* 2 */
-}
-
-/*
-Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
-*/
-
-img,
-video {
- max-width: 100%;
- height: auto;
-}
-
-/*
-Ensure the default browser behavior of the `hidden` attribute.
-*/
-
-[hidden] {
- display: none;
-}
-
-*, ::before, ::after {
- --tw-translate-x: 0;
- --tw-translate-y: 0;
- --tw-rotate: 0;
- --tw-skew-x: 0;
- --tw-skew-y: 0;
- --tw-scale-x: 1;
- --tw-scale-y: 1;
- --tw-pan-x: ;
- --tw-pan-y: ;
- --tw-pinch-zoom: ;
- --tw-scroll-snap-strictness: proximity;
- --tw-ordinal: ;
- --tw-slashed-zero: ;
- --tw-numeric-figure: ;
- --tw-numeric-spacing: ;
- --tw-numeric-fraction: ;
- --tw-ring-inset: ;
- --tw-ring-offset-width: 0px;
- --tw-ring-offset-color: #fff;
- --tw-ring-color: rgb(59 130 246 / 0.5);
- --tw-ring-offset-shadow: 0 0 #0000;
- --tw-ring-shadow: 0 0 #0000;
- --tw-shadow: 0 0 #0000;
- --tw-shadow-colored: 0 0 #0000;
- --tw-blur: ;
- --tw-brightness: ;
- --tw-contrast: ;
- --tw-grayscale: ;
- --tw-hue-rotate: ;
- --tw-invert: ;
- --tw-saturate: ;
- --tw-sepia: ;
- --tw-drop-shadow: ;
- --tw-backdrop-blur: ;
- --tw-backdrop-brightness: ;
- --tw-backdrop-contrast: ;
- --tw-backdrop-grayscale: ;
- --tw-backdrop-hue-rotate: ;
- --tw-backdrop-invert: ;
- --tw-backdrop-opacity: ;
- --tw-backdrop-saturate: ;
- --tw-backdrop-sepia: ;
-}
-
-.static {
- position: static;
-}
-
-.absolute {
- position: absolute;
-}
-
-.bottom-0 {
- bottom: 0px;
-}
-
-.left-10 {
- left: 2.5rem;
-}
-
-.left-52 {
- left: 13rem;
-}
-
-.top-52 {
- top: 13rem;
-}
-
-.left-0 {
- left: 0px;
-}
-
-.right-0 {
- right: 0px;
-}
-
-.grid {
- display: grid;
-}
-
-.h-24 {
- height: 6rem;
-}
-
-.h-screen {
- height: 100vh;
-}
-
-.grid-cols-1 {
- grid-template-columns: repeat(1, minmax(0, 1fr));
-}
-
-.grid-cols-2 {
- grid-template-columns: repeat(2, minmax(0, 1fr));
-}
-
-.place-content-center {
- place-content: center;
-}
-
-.place-items-center {
- place-items: center;
-}
-
-.content-center {
- align-content: center;
-}
-
-.items-center {
- align-items: center;
-}
-
-.gap-4 {
- gap: 1rem;
-}
-
-.gap-40 {
- gap: 10rem;
-}
-
-.gap-10 {
- gap: 2.5rem;
-}
-
-.self-center {
- align-self: center;
-}
-
-.rounded-full {
- border-radius: 9999px;
-}
-
-.rounded-sm {
- border-radius: 0.125rem;
-}
-
-.rounded-lg {
- border-radius: 0.5rem;
-}
-
-.border {
- border-width: 1px;
-}
-
-.border-2 {
- border-width: 2px;
-}
-
-.border-4 {
- border-width: 4px;
-}
-
-.border-stone-700 {
- --tw-border-opacity: 1;
- border-color: rgb(68 64 60 / var(--tw-border-opacity));
-}
-
-.border-slate-900 {
- --tw-border-opacity: 1;
- border-color: rgb(15 23 42 / var(--tw-border-opacity));
-}
-
-.border-slate-50 {
- --tw-border-opacity: 1;
- border-color: rgb(248 250 252 / var(--tw-border-opacity));
-}
-
-.bg-slate-600 {
- --tw-bg-opacity: 1;
- background-color: rgb(71 85 105 / var(--tw-bg-opacity));
-}
-
-.px-4 {
- padding-left: 1rem;
- padding-right: 1rem;
-}
-
-.py-1 {
- padding-top: 0.25rem;
- padding-bottom: 0.25rem;
-}
-
-.py-4 {
- padding-top: 1rem;
- padding-bottom: 1rem;
-}
-
-.px-10 {
- padding-left: 2.5rem;
- padding-right: 2.5rem;
-}
-
-.py-3 {
- padding-top: 0.75rem;
- padding-bottom: 0.75rem;
-}
-
-.px-2 {
- padding-left: 0.5rem;
- padding-right: 0.5rem;
-}
-
-.py-2 {
- padding-top: 0.5rem;
- padding-bottom: 0.5rem;
-}
-
-.font-mono {
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
-}
-
-.font-sans {
- font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
-}
-
-.text-sm {
- font-size: 0.875rem;
- line-height: 1.25rem;
-}
-
-.text-lg {
- font-size: 1.125rem;
- line-height: 1.75rem;
-}
-
-.text-9xl {
- font-size: 8rem;
- line-height: 1;
-}
-
-.text-7xl {
- font-size: 4.5rem;
- line-height: 1;
-}
-
-.text-6xl {
- font-size: 3.75rem;
- line-height: 1;
-}
-
-.text-5xl {
- font-size: 3rem;
- line-height: 1;
-}
-
-.text-2xl {
- font-size: 1.5rem;
- line-height: 2rem;
-}
-
-.text-4xl {
- font-size: 2.25rem;
- line-height: 2.5rem;
-}
-
-.font-bold {
- font-weight: 700;
-}
-
-.font-medium {
- font-weight: 500;
-}
-
-.text-gray-300 {
- --tw-text-opacity: 1;
- color: rgb(209 213 219 / var(--tw-text-opacity));
-}
-
-.text-slate-100 {
- --tw-text-opacity: 1;
- color: rgb(241 245 249 / var(--tw-text-opacity));
-}
-
-.text-slate-50 {
- --tw-text-opacity: 1;
- color: rgb(248 250 252 / var(--tw-text-opacity));
-}
-
-.shadow-sm {
- --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
- --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
- box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
-}
-
-.shadow {
- --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
- --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
- box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
-}
-
-.hover\:border-none:hover {
- border-style: none;
-}
-
-.hover\:border-transparent:hover {
- border-color: transparent;
-}
-
-.hover\:border-slate-900:hover {
- --tw-border-opacity: 1;
- border-color: rgb(15 23 42 / var(--tw-border-opacity));
-}
-
-.hover\:bg-black:hover {
- --tw-bg-opacity: 1;
- background-color: rgb(0 0 0 / var(--tw-bg-opacity));
-}
-
-.hover\:bg-slate-900:hover {
- --tw-bg-opacity: 1;
- background-color: rgb(15 23 42 / var(--tw-bg-opacity));
-}
-
-.hover\:font-bold:hover {
- font-weight: 700;
-}
-
-.hover\:text-gray-400:hover {
- --tw-text-opacity: 1;
- color: rgb(156 163 175 / var(--tw-text-opacity));
-}
-
-.focus\:border-slate-900:focus {
- --tw-border-opacity: 1;
- border-color: rgb(15 23 42 / var(--tw-border-opacity));
-}
-
-.focus\:bg-slate-900:focus {
- --tw-bg-opacity: 1;
- background-color: rgb(15 23 42 / var(--tw-bg-opacity));
-}
-
-.focus\:hover\:border-slate-900:hover:focus {
- --tw-border-opacity: 1;
- border-color: rgb(15 23 42 / var(--tw-border-opacity));
-}
-
-.focus\:hover\:bg-slate-900:hover:focus {
- --tw-bg-opacity: 1;
- background-color: rgb(15 23 42 / var(--tw-bg-opacity));
-}
\ No newline at end of file
diff --git a/package.json b/package.json
deleted file mode 100644
index 48a2299..0000000
--- a/package.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "name": "text",
- "version": "1.0.0",
- "description": "",
- "main": "src/index.js",
- "scripts": {
- "start": "node src/index.js",
- "adduser": "python script/adduser.py",
- "build": "babel src -d lib"
- },
- "author": "unurled",
- "license": "ISC",
- "dependencies": {
- "dotenv": "^14.3.2",
- "express": "^4.17.2",
- "express-session": "^1.17.2",
- "jsonwebtoken": "^8.5.1",
- "mongoose": "^6.1.8",
- "passport": "^0.5.2",
- "passport-gitlab2": "^5.0.0",
- "passport-local": "^1.0.0",
- "xxhashjs": "^0.2.2"
- },
- "devDependencies": {
- "tailwindcss": "^3.0.16"
- }
-}
diff --git a/public/css/main.css b/public/css/main.css
new file mode 100644
index 0000000..bd02494
--- /dev/null
+++ b/public/css/main.css
@@ -0,0 +1,17 @@
+#content {
+ position: absolute;
+ top: 40vh;
+}
+
+#login-content {
+ position: absolute;
+ top: 20vh;
+}
+
+#login {
+ bottom: 5vh;
+}
+
+#text {
+ font-size: large;
+}
\ No newline at end of file
diff --git a/public/edit.html b/public/edit.html
new file mode 100644
index 0000000..629cd80
--- /dev/null
+++ b/public/edit.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+ Text Display
+
+
+
+
+
+
+
+
+
Login
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..c07d99d
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+ Text Display
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/js/edit.js b/public/js/edit.js
new file mode 100644
index 0000000..5e40c64
--- /dev/null
+++ b/public/js/edit.js
@@ -0,0 +1,17 @@
+function saveText() {
+ let x = document.getElementById("text").value;
+
+ const options = {method: 'POST', body: JSON.stringify({text: x}), headers: { 'Content-Type': 'application/json' }};
+
+ fetch('http://127.0.0.1:8000/api/edit', options)
+ .then((response) => response.text())
+ .then(data => {
+ redirectOrNot(data);
+ })
+ .catch(err => console.error(err));
+}
+
+async function redirectOrNot(res) {
+ let url = "http://" + location.hostname + ":" + location.port
+ location.href = url+res
+}
\ No newline at end of file
diff --git a/public/js/login.js b/public/js/login.js
new file mode 100644
index 0000000..7bb649e
--- /dev/null
+++ b/public/js/login.js
@@ -0,0 +1,17 @@
+function formLink() {
+ let x = document.getElementById("Token").value;
+ const options = {method: 'POST', headers: {Token: x}};
+
+ fetch('http://127.0.0.1:8000/login', options)
+ .then((response) => response.text())
+ .then(data => {
+ redirectOrNot(data);
+ })
+ .catch(err => console.log(err));
+
+}
+
+async function redirectOrNot(res) {
+ let url = "http://" + location.hostname + ":" + location.port
+ location.href = url+res
+}
\ No newline at end of file
diff --git a/public/js/main.js b/public/js/main.js
new file mode 100644
index 0000000..1a4ef9f
--- /dev/null
+++ b/public/js/main.js
@@ -0,0 +1,18 @@
+!async function(){
+ let data = await fetch("http://localhost:8000/api")
+ .then((response) => response.text())
+ .then(data => {
+ return data;
+ })
+ .catch(error => {
+ console.error(error);
+ });
+
+ console.log(data);
+ print(data);
+ }();
+
+function print(data) {
+ document.getElementById("text").innerText = data
+ document.getElementById("text").value = data
+}
diff --git a/public/login.html b/public/login.html
new file mode 100644
index 0000000..2a30329
--- /dev/null
+++ b/public/login.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+ Text Display
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/script/adduser.py b/script/adduser.py
deleted file mode 100644
index f29c1f2..0000000
--- a/script/adduser.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import collections
-from pymongo import MongoClient
-from dotenv import load_dotenv
-from os import getenv
-import xxhash
-import getpass
-
-load_dotenv()
-client=MongoClient(getenv("MONGO"))
-db = client.get_database(getenv("DB"))
-
-def add_user():
- username = input('username ? ')
- password = getpass.getpass('password ? ')
- pass_retry = getpass.getpass('Re-type your password ? ')
- if password != pass_retry:
- print("not correct password.")
- add_user()
- hashed_pass = xxhash.xxh64(password, 5).hexdigest()
- collection = db["users"]
- print(f"username: {username}, password: {hashed_pass}")
- collection.update_one({ "name": username}, { "$set": {"pass": hashed_pass}})
-
-add_user()
\ No newline at end of file
diff --git a/src/config/db.config.js b/src/config/db.config.js
deleted file mode 100644
index 3b8f31c..0000000
--- a/src/config/db.config.js
+++ /dev/null
@@ -1,14 +0,0 @@
-require('dotenv').config()
-// import mongoose package
-const mongoose = require('mongoose')
-
-// declare a Database string URI
-const DB_URI = process.env.MONGO
-
-// establishing a database connection
-mongoose.connect(DB_URI)
-
-const connection = mongoose.connection
-
-// export the connection object
-module.exports = connection
diff --git a/src/data.rs b/src/data.rs
new file mode 100644
index 0000000..43743e2
--- /dev/null
+++ b/src/data.rs
@@ -0,0 +1,11 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Serialize, Deserialize)]
+pub struct Text {
+ pub(crate) password: u64,
+ pub(crate) text: String,
+}
+
+pub(crate) fn deserialize(data: String) -> Result {
+ serde_json::from_str(Box::leak(data.into_boxed_str()))
+}
\ No newline at end of file
diff --git a/src/file.rs b/src/file.rs
new file mode 100644
index 0000000..dc18547
--- /dev/null
+++ b/src/file.rs
@@ -0,0 +1,45 @@
+use std::{fs::File, path::Path, io::Write, fs::write};
+use std::string::ToString;
+use text_io::read;
+use rpassword::prompt_password;
+use crate::data::Text;
+
+use crate::hash;
+
+pub static PATH: &str = "db.json";
+
+pub fn new_file() -> File {
+ let pass: String = prompt_password("Input the token: ").unwrap();
+ print!("Input the text you want to display: ");
+ let text_str: String = read!("{}\n");
+
+ let path_obj = Path::new(&PATH);
+ let text_obj = Text {
+ password: hash::hash(pass),
+ text: text_str,
+ };
+ let j = serde_json::to_string(&text_obj).unwrap();
+ let mut file = match File::create(&path_obj) {
+ Err(why) => panic!("couldn't create {}: {}", path_obj.display(), why),
+ Ok(file) => file,
+ };
+ match file.write_all(j.to_string().as_bytes()) {
+ Err(why) => panic!("couldn't write to {}: {}", path_obj.display(), why),
+ Ok(file) => file,
+ };
+ return file;
+}
+
+pub fn write_file(data: Text) {
+ let j = serde_json::to_string(&data).unwrap();
+ write(&PATH, j).expect("Unable to write data;");
+}
+
+pub fn get_file() -> File {
+ let path_obj = Path::new("db.json");
+ let file: File = match File::open(&path_obj) {
+ Err(_why) => new_file(),
+ Ok(file) => file,
+ };
+ return file;
+}
\ No newline at end of file
diff --git a/src/hash.rs b/src/hash.rs
new file mode 100644
index 0000000..0d0976d
--- /dev/null
+++ b/src/hash.rs
@@ -0,0 +1,5 @@
+use xxhash_rust::xxh64::xxh64;
+
+pub fn hash(string: String) -> u64 {
+ xxh64(string.as_bytes(), 12)
+}
\ No newline at end of file
diff --git a/src/http_server.rs b/src/http_server.rs
new file mode 100644
index 0000000..fe91f24
--- /dev/null
+++ b/src/http_server.rs
@@ -0,0 +1,127 @@
+use std::fs;
+use std::path::Path;
+use rocket;
+use rocket::fs::{FileServer, NamedFile, relative};
+use rocket::http::{CookieJar, Cookie, Status};
+use rocket::request::{FromRequest, Outcome};
+use rocket::{Request, routes, uri};
+use rocket_cors::{AllowedHeaders, AllowedOrigins, Cors};
+use rocket::serde::json::Json;
+
+use crate::{data, file};
+use crate::data::deserialize;
+use crate::file::PATH;
+
+struct Token(String);
+
+#[derive(Debug)]
+enum ApiTokenError {
+ Missing,
+}
+
+#[derive(serde::Deserialize)]
+#[serde(crate = "rocket::serde")]
+struct Text<'r> {
+ text: &'r str,
+}
+
+#[rocket::async_trait]
+impl<'r> FromRequest<'r> for Token {
+ type Error = ApiTokenError;
+
+ async fn from_request(request: &'r Request<'_>) -> rocket::request::Outcome {
+ let token = request.headers().get_one("token");
+ match token {
+ Some(token) => {
+ // check validity
+ Outcome::Success(Token(token.to_string()))
+ }
+ None => Outcome::Failure((Status::Unauthorized, ApiTokenError::Missing)),
+ }
+ }
+}
+
+fn make_cors() -> Cors {
+ rocket_cors::CorsOptions {
+ allowed_origins: AllowedOrigins::all(),
+ allowed_headers: AllowedHeaders::some(&["Authorization", "Accept"]),
+ allow_credentials: true,
+ ..Default::default()
+ }
+ .to_cors()
+ .expect("error while building CORS")
+}
+
+#[rocket::get("/")]
+fn get_text() -> String {
+ let content = data::deserialize(fs::read_to_string(&file::PATH).expect(""));
+ if content.is_err() {
+ return "".to_string();
+ }
+ return content.unwrap().text;
+}
+
+#[rocket::get("/edit")]
+async fn edit_get() -> Option {
+ let path = Path::new(relative!("public")).join("edit.html");
+
+ NamedFile::open(path).await.ok()
+}
+
+#[rocket::post("/login")]
+fn login(token: Token, cookies: &CookieJar<'_>) -> String {
+ let temp = fs::read_to_string(PATH);
+ if temp.is_err() {
+ return "/".to_string();
+ }
+ let content = deserialize(temp.unwrap());
+ let token_int = token.0.parse::();
+ if token_int.is_err() {
+ return "/".to_string();
+ }
+ if content.is_ok() {
+ if content.unwrap().password == token.0.parse::().unwrap() {
+ cookies.add_private(Cookie::new("Token", token.0));
+ return uri!(edit_get).to_string();
+ }
+ }
+ return "/".to_string();
+}
+
+#[rocket::post("/edit", format = "json", data = "")]
+fn edit(text: Json>, cookies: &CookieJar<'_>) -> String {
+ let temp = fs::read_to_string(PATH);
+ if temp.is_err() {
+ return "/".to_string();
+ }
+ let content = deserialize(temp.unwrap());
+ let token = cookies.get_private("Token");
+ if token.is_none() {
+ return "/".to_string();
+ }
+ let token_int = token.unwrap().value().parse::();
+ if token_int.is_err() {
+ return "/".to_string();
+ }
+ if content.is_ok() {
+ let mut data = content.unwrap();
+ if data.password == token_int.unwrap() {
+ data.text = text.text.to_string();
+ file::write_file(data);
+ return "/".to_string();
+ }
+ }
+ return "/".to_string();
+}
+
+#[rocket::main]
+pub async fn main() -> Result<(), rocket::Error> {
+ let _rocket = rocket::build()
+ .mount("/", FileServer::from("public/"))
+ .mount("/", routes![login, edit_get])
+ .mount("/api", routes![get_text, edit])
+ .manage(make_cors())
+ .launch()
+ .await?;
+ Ok(())
+}
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
deleted file mode 100644
index 4687f1d..0000000
--- a/src/index.js
+++ /dev/null
@@ -1,50 +0,0 @@
-require('dotenv').config()
-var express = require('express');
-var session = require('express-session');
-var bodyParser = require('body-parser');
-var path = require('path');
-
-const connection = require('./config/db.config');
-connection.once('open', () => console.log('DB Connected'));
-connection.on('error', () => console.log('Error'));
-
-var app = express();
-
-app.use(session({
- secret: 'haklo secret very secret',
- resave: true,
- saveUninitialized: true
-}));
-app.use(bodyParser.urlencoded({extended : false}));
-app.use(bodyParser.json());
-
-app.use('/api/post', require('./post'));
-app.use('/text', require('./text'))
-app.use('/', require('./login'));
-app.get('/', function (req, res) {
- res.sendFile(path.join(__dirname + `/public/index.html`));
-})
-app.get('/main.js', function(req, res) {
- res.sendFile(path.join(__dirname + '/public/main.js'))
-})
-app.get('/FetchService.js', function(req, res) {
- res.sendFile(path.join(__dirname + '/public/FetchService.js'))
-})
-app.get('/getText.js', function(req, res) {
- res.sendFile(path.join(__dirname + '/public/getText.js'))
- })
-app.get('/login.html', function (req, res) {
- res.sendFile(path.join(__dirname + `/public/login.html`));
-})
-app.get('/dist/output.css', function (req, res) {
- res.sendFile(path.join(__dirname + `/../dist/output.css`));
-})
-app.get('/edit', function(request, res) {
- if (request.session.loggedin) {
- res.sendFile(path.join(__dirname + `/public/edit.html`));
- } else {
- res.send("You need to login at /login.html");
- }
-});
-
-app.listen(process.env.SERVER_PORT, console.log(process.env.URL + '/' + process.env.SERVER_PORT))
\ No newline at end of file
diff --git a/src/login.js b/src/login.js
deleted file mode 100644
index 362f308..0000000
--- a/src/login.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const User = require('./model/user');
-const express = require('express')
-
-const router = express.Router()
-const XXH = require('xxhashjs');
-
-router.post('/auth', function(request, response) {
- var username = request.body.username;
- var password = XXH.h64(request.body.password, 5).toString(16);
- if (username && password) {
- let user = User.findOne({
- name: username, pass: password
- }, function(err, results) {
- if (results !=null) {
- console.log(results.name);
- if (results.name.length > 0) {
- request.session.loggedin = true;
- request.session.username = username;
- request.session.password = password
- response.redirect('/edit');
- } else {
- response.send('Incorrect Username and/or Password!');
- }
- response.end();
- } else {
- response.send('Use a registered username Please.')
- }
- });
- } else {
- response.send('Please enter Username and Password!');
- response.end();
- }
-});
-
-module.exports = router
\ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..8bd3f99
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,22 @@
+use dotenv::dotenv;
+use std::env;
+
+mod file;
+pub mod hash;
+mod http_server;
+mod data;
+
+use file::get_file;
+
+fn main() {
+ dotenv().ok();
+ if env::var("URL").is_err() || env::var("PORT").is_err() {
+ println!("Please set .env file, you can see an example in the file .env.example");
+ return;
+ }
+ let _file = get_file();
+ let res = http_server::main();
+ if res.is_err() {
+ println!("Error in server: {}", res.unwrap_err())
+ }
+}
\ No newline at end of file
diff --git a/src/model/user.js b/src/model/user.js
deleted file mode 100644
index 923f982..0000000
--- a/src/model/user.js
+++ /dev/null
@@ -1,12 +0,0 @@
-const mongoose = require('mongoose')
-
-// instantiate a mongoose schema
-const UserSchema = new mongoose.Schema({
- name: String,
- pass: String,
- text: String
-})
-
-// create a model from schema and export it
-// user here is the collection name modify it if you want
-module.exports = mongoose.model('user', UserSchema)
\ No newline at end of file
diff --git a/src/post.js b/src/post.js
deleted file mode 100644
index 03014d8..0000000
--- a/src/post.js
+++ /dev/null
@@ -1,26 +0,0 @@
-const express = require('express')
-const router = express.Router()
-
-const User = require('./model/user');
-
-router.post('/', function(request, response) {
- console.log("Connection")
- var username = request.session.username;
- var password = request.session.password;
- console.log(username + password)
- let user = User.findOneAndUpdate(
- {user: username},
- {text: request.body.text}, function(err, results) {
- console.log("updated, ")
- console.log(request.body)
- console.log(results.text)
- if (results.text.length > 0) {
- response.redirect("/");
- //response.sendFile(path.join(__dirname + `/public/index.html`))
- } else {
- response.send('Incorrect Username and/or Password!');
- }
- });
-});
-
-module.exports = router
diff --git a/src/public/FetchService.js b/src/public/FetchService.js
deleted file mode 100644
index 2a69e39..0000000
--- a/src/public/FetchService.js
+++ /dev/null
@@ -1,62 +0,0 @@
-export default class FetchService {
- constructor() {
-
- }
-
- async performGetHttpRequest(fetchLink, headers, query=null) {
- if(!fetchLink || !headers) {
- throw new Error("One or more GET request parameters was not passed.");
- }
- try {
- const rawResponse = await fetch(fetchLink, {
- method: "GET",
- headers: headers,
- query: (query != null) ? query : ""
- });
- const content = await rawResponse.json();
- return content;
- }
- catch(err) {
- console.error(`Error at fetch GET: ${err}`);
- throw err;
- }
- }
-
- async performPostHttpRequest(fetchLink, headers, body) {
- if(!fetchLink || !headers || !body) {
- throw new Error("One or more POST request parameters was not passed.");
- }
- try {
- const rawResponse = await fetch(fetchLink, {
- method: "POST",
- headers: headers,
- body: JSON.stringify(body)
- });
- const content = await rawResponse.json();
- return content;
- }
- catch(err) {
- console.error(`Error at fetch POST: ${err}`);
- throw err;
- }
- }
-
- async performPutHttpRequest(fetchLink, headers, body) {
- if(!fetchLink || !headers || !body) {
- throw new Error("One or more POST request parameters was not passed.");
- }
- try {
- const rawResponse = await fetch(fetchLink, {
- method: "PUT",
- headers: headers,
- body: JSON.stringify(body)
- });
- const content = await rawResponse.json();
- return content;
- }
- catch(err) {
- console.error(`Error at fetch PUT: ${err}`);
- throw err;
- }
- }
-}
\ No newline at end of file
diff --git a/src/public/edit.html b/src/public/edit.html
deleted file mode 100644
index 0e8e50d..0000000
--- a/src/public/edit.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
Edit text
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/public/getText.js b/src/public/getText.js
deleted file mode 100644
index 35cad5b..0000000
--- a/src/public/getText.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import FetchService from './FetchService.js';
-
-const fetchService = new FetchService();
-
-function buildHeaders(authorization = null) {
- const headers = {
- "Content-Type": "application/json",
- "Authorization": (authorization) ? authorization : "Bearer TOKEN_MISSING"
- };
- return headers;
-}
-
-const response = await fetchService.performGetHttpRequest(window.location.href + 'text', buildHeaders());
-
-document.getElementById("text").innerHTML = response.text;
diff --git a/src/public/index.html b/src/public/index.html
deleted file mode 100644
index b70e24d..0000000
--- a/src/public/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
- Login
-
-
-
-
\ No newline at end of file
diff --git a/src/public/login.html b/src/public/login.html
deleted file mode 100644
index 82e994f..0000000
--- a/src/public/login.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
- Login
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/public/main.js b/src/public/main.js
deleted file mode 100644
index bdf8af8..0000000
--- a/src/public/main.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import FetchService from './FetchService.js';
-
-/*-- Objects --*/
-const fetchService = new FetchService();
-
-async function save(e, btn) {
-
- const textarea = document.getElementById('textarea1').value;
-
- const headers = buildHeaders();
- const jsonFileData = buildJsonFormData(textarea);
-
- const response = await fetchService.performPostHttpRequest(window.location.href + 'api/post', headers, jsonFileData);
-}
-
-function buildHeaders(authorization = null) {
- const headers = {
- "Content-Type": "application/json",
- "Authorization": (authorization) ? authorization : "Bearer TOKEN_MISSING"
- };
- return headers;
-}
-
-function buildJsonFormData(text) {
- return JSON.parse('{"text": "'+ text+'"}');
-}
-
-const button = document.querySelector(".btn");
- button.addEventListener('click', function(e) {
- save(e, this);
-});
\ No newline at end of file
diff --git a/src/public/style.css b/src/public/style.css
deleted file mode 100644
index bd6213e..0000000
--- a/src/public/style.css
+++ /dev/null
@@ -1,3 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
\ No newline at end of file
diff --git a/src/text.js b/src/text.js
deleted file mode 100644
index ff9d9f0..0000000
--- a/src/text.js
+++ /dev/null
@@ -1,22 +0,0 @@
-require('dotenv').config()
-const express = require('express')
-const router = express.Router()
-
-const User = require('./model/user');
-
-router.get('/', function(request, response) {
- let username = "";
- console.log(username);
- User.find({}, function(err, res) {
- console.log("updated, ")
- console.log(res[0].text)
- if (res[0].text.length > 0) {
- response.send('{"text": "' + res[0].text + '"}')
- //response.sendFile(path.join(__dirname + `/public/index.html`))
- } else {
- response.send('Incorrect Username and/or Password!');
- }
- });
-});
-
-module.exports = router
diff --git a/tailwind.config.js b/tailwind.config.js
deleted file mode 100644
index 68d980b..0000000
--- a/tailwind.config.js
+++ /dev/null
@@ -1,10 +0,0 @@
-module.exports = {
- content: [
- "./src/public/*.{html,js}",
- "./src/*.{js}"
- ],
- theme: {
- extend: {},
- },
- plugins: [],
-}