From e00ab6183ca9053f8a3224d05fe966b9aa70fafb Mon Sep 17 00:00:00 2001 From: unurled Date: Thu, 16 Feb 2023 13:30:06 +0100 Subject: [PATCH] rust server working :) !!! --- .env.example | 3 +- .gitignore | 12 +- Cargo.toml | 17 + Rocket.toml | 20 + dist/output.css | 767 ------------------------------------- package.json | 27 -- public/css/main.css | 17 + public/edit.html | 31 ++ public/index.html | 23 ++ public/js/edit.js | 17 + public/js/login.js | 17 + public/js/main.js | 18 + public/login.html | 30 ++ script/adduser.py | 24 -- src/config/db.config.js | 14 - src/data.rs | 11 + src/file.rs | 45 +++ src/hash.rs | 5 + src/http_server.rs | 127 ++++++ src/index.js | 50 --- src/login.js | 35 -- src/main.rs | 22 ++ src/model/user.js | 12 - src/post.js | 26 -- src/public/FetchService.js | 62 --- src/public/edit.html | 17 - src/public/getText.js | 15 - src/public/index.html | 12 - src/public/login.html | 27 -- src/public/main.js | 31 -- src/public/style.css | 3 - src/text.js | 22 -- tailwind.config.js | 10 - 33 files changed, 410 insertions(+), 1159 deletions(-) create mode 100644 Cargo.toml create mode 100644 Rocket.toml delete mode 100644 dist/output.css delete mode 100644 package.json create mode 100644 public/css/main.css create mode 100644 public/edit.html create mode 100644 public/index.html create mode 100644 public/js/edit.js create mode 100644 public/js/login.js create mode 100644 public/js/main.js create mode 100644 public/login.html delete mode 100644 script/adduser.py delete mode 100644 src/config/db.config.js create mode 100644 src/data.rs create mode 100644 src/file.rs create mode 100644 src/hash.rs create mode 100644 src/http_server.rs delete mode 100644 src/index.js delete mode 100644 src/login.js create mode 100644 src/main.rs delete mode 100644 src/model/user.js delete mode 100644 src/post.js delete mode 100644 src/public/FetchService.js delete mode 100644 src/public/edit.html delete mode 100644 src/public/getText.js delete mode 100644 src/public/index.html delete mode 100644 src/public/login.html delete mode 100644 src/public/main.js delete mode 100644 src/public/style.css delete mode 100644 src/text.js delete mode 100644 tailwind.config.js 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 + + + + + + +
+
+

Login

+
+
+ + +
+ +
+ + +
+
+
+ + + \ 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 - - - -
-
-

Login Form

-
-
-
- -
-
- -
-
- - -
- -
- - \ 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: [], -}