diff --git a/.gitignore b/.gitignore index bce9d97..8162224 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target -xssbook.db \ No newline at end of file +xssbook.db +/public/avatar/custom/* \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 9a47937..7b16e84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "ahash" version = "0.7.6" @@ -97,6 +103,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + [[package]] name = "bitflags" version = "1.3.2" @@ -118,6 +130,18 @@ version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +[[package]] +name = "bytemuck" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c041d3eab048880cb0b86b256447da3f18859a163c3b8d8893f4e6368abe6393" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "bytes" version = "1.3.0" @@ -136,6 +160,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "cookie" version = "0.16.2" @@ -156,6 +186,49 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + [[package]] name = "crossbeam-utils" version = "0.8.14" @@ -165,6 +238,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -198,6 +277,27 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[package]] +name = "exr" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eb5f255b5980bb0c8cf676b675d1a99be40f316881444f44e0462eaf5df5ded" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "smallvec", + "threadpool", +] + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -210,6 +310,29 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" +[[package]] +name = "flate2" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -347,8 +470,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "gif" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06" +dependencies = [ + "color_quant", + "weezl", ] [[package]] @@ -369,6 +504,15 @@ dependencies = [ "smallvec", ] +[[package]] +name = "half" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" +dependencies = [ + "crunchy", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -484,12 +628,40 @@ dependencies = [ "want", ] +[[package]] +name = "image" +version = "0.24.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-rational", + "num-traits", + "png", + "scoped_threadpool", + "tiff", +] + [[package]] name = "itoa" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" +[[package]] +name = "jpeg-decoder" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" +dependencies = [ + "rayon", +] + [[package]] name = "js-sys" version = "0.3.60" @@ -505,6 +677,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "libc" version = "0.2.139" @@ -562,6 +740,15 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "mime" version = "0.3.16" @@ -578,6 +765,15 @@ dependencies = [ "unicase", ] +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.5" @@ -590,6 +786,15 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + [[package]] name = "no-std-compat" version = "0.4.1" @@ -618,6 +823,36 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.15.0" @@ -707,6 +942,18 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +[[package]] +name = "png" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" +dependencies = [ + "bitflags", + "crc32fast", + "flate2", + "miniz_oxide", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -786,6 +1033,28 @@ dependencies = [ "bitflags", ] +[[package]] +name = "rayon" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -821,6 +1090,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + [[package]] name = "scopeguard" version = "1.1.0" @@ -933,6 +1208,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "spin" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +dependencies = [ + "lock_api", +] + [[package]] name = "syn" version = "1.0.107" @@ -979,6 +1263,26 @@ dependencies = [ "once_cell", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "tiff" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "time" version = "0.3.17" @@ -1330,6 +1634,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "weezl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" + [[package]] name = "winapi" version = "0.3.9" @@ -1416,6 +1726,7 @@ dependencies = [ "axum", "axum-client-ip", "bytes", + "image", "lazy_static", "rand", "rusqlite", diff --git a/Cargo.toml b/Cargo.toml index 9fdbd0c..272112f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] tokio = { version = "1.23.0", features = ["full"] } -axum = { version = "0.6.4", features = ["headers"] } +axum = { version = "0.6.4", features = ["headers", "query"] } axum-client-ip = "0.3.1" tower-http = { version = "0.3.5", features = ["fs"] } tower_governor = "0.0.4" @@ -19,4 +19,5 @@ serde_json = { version = "1.0", features = ["std"] } rusqlite = { version = "0.28.0", features = ["bundled"] } rand = "0.8.5" time = "0.3.17" -lazy_static = "1.4.0" \ No newline at end of file +lazy_static = "1.4.0" +image = "0.24.3" \ No newline at end of file diff --git a/README.md b/README.md index 720f5c9..0dfb9d2 100644 --- a/README.md +++ b/README.md @@ -30,15 +30,17 @@ If you want to run it in a docker container a premade dockerfile is here for you There is also a docker-compose.yml file for your reference in the /deployments/docker folder. -The one thing about the docker container is you have to mount the volume +There are two volumes you have to make for the container. First one for the database otherwise all data will be wiped upon container restart. You only should volume the database file so create the vollume with the directory below. + +`touch [your directory]/xssbook.db` `-v [your directory]/xssbook.db:/data/xssbook.db` -to make the database persistant. Finally, before running the container run +You have to create the database file beforehand because otherwise docker will create a folder there instead, and then the program will crash when it tries to load a folder as a database. -`touch [your directory]/xssbook.db` +Finally, you have to make a volume to store custom user avatars and banners. Without this, this data too will be lost upon contaienr restart. To make the volume simply run this with your container. -since docker will create a folder there otherwise and it won't work. +`-v [another directory]:/data/public/image/custom` **reverse proxy** diff --git a/deployments/docker/Dockerfile b/deployments/docker/Dockerfile index f14b0a6..9764939 100644 --- a/deployments/docker/Dockerfile +++ b/deployments/docker/Dockerfile @@ -13,6 +13,8 @@ COPY --from=builder /usr/local/cargo/bin/xssbook /usr/local/bin/xssbook RUN mkdir /data WORKDIR /data COPY ./public ./public +RUN mkdir ./public/image/custom +VOLUME ./public/image/custom EXPOSE 8080 CMD ["/usr/local/bin/xssbook"] \ No newline at end of file diff --git a/deployments/docker/docker-compose.yml b/deployments/docker/docker-compose.yml index 09415e4..1b0b269 100644 --- a/deployments/docker/docker-compose.yml +++ b/deployments/docker/docker-compose.yml @@ -10,3 +10,4 @@ services: - 8080:8080 volumes: - ${PWD}/xssbook.db:/data/xssbook.db + - ${PWD}/custom:/data/public/image/custom diff --git a/public/css/main.css b/public/css/main.css index e15ffa6..1926ed9 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -368,4 +368,14 @@ form { input:focus { outline: none; } + + .changeavatar { + filter: invert(100%) !important; + background-color: #bbbbbb !important; + } + + .changebanner { + filter: invert(100%) !important; + background-color: #bbbbbb !important; + } } \ No newline at end of file diff --git a/public/css/profile.css b/public/css/profile.css index 62ce1d2..1077919 100644 --- a/public/css/profile.css +++ b/public/css/profile.css @@ -24,7 +24,7 @@ body { justify-content: center; } -#banner div, #banner img { +#banner .bg, #banner img { width: 80em; max-width: 100%; height: inherit; @@ -56,6 +56,27 @@ body { border-radius: 7em; } +.changeavatar, .changebanner { + all: unset; + position: absolute; + width: 3em; + height: 3em; + margin-left: -3em; + margin-top: 9em; + border-radius: 3em; + background-color: var(--secondary); + z-index: 10000 !important; + text-align: center; + background-image: url('data:image/png;base64,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/TwzbKRT88RhYqHQxnIbs6KhEk8TRxRVo3x/xmWF8xZntVxlzXvyF4Zy2soy12kNIYFFLEGEABlVlFCGhSjtGikmUnQe9/APOn6RXDK5SmDkWEAFKiTHD/4Hv2dr5qcm3aRQHOh8se2PESC4CzRqtv19bNuNEyDwDFxpLX+lDsx+kl5raZEjoHcbuLhuafIecLkDDDzpkiE5UoCWP58H3s/om7JA3y3QvebOrXmO0wcgTbNK3gAHh8BogbLXPd7d1T63f3ua8/sBAv9y4GhT1LwAAA14aVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpHSU1QPSJodHRwOi8vd3d3LmdpbXAub3JnL3htcC8iCiAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgeG1wTU06RG9jdW1lbnRJRD0iZ2ltcDpkb2NpZDpnaW1wOjNlYWM4M2MyLTUzMjctNDE5ZS1iMjJlLWU2YjE5M2M2ZTc2NiIKICAgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0MTNkODIxZC1jMDE1LTQ1ZGQtYTAwNS04MTA2OGY3ZTg1YjEiCiAgIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo4ZGRkOGY2My1iODAwLTQ1MDQtYWE3Yi1iNzAwOTRiOTg5YTgiCiAgIEdJTVA6QVBJPSIyLjAiCiAgIEdJTVA6UGxhdGZvcm09IkxpbnV4IgogICBHSU1QOlRpbWVTdGFtcD0iMTY3NTIwNTQzNTkyMzY1NCIKICAgR0lNUDpWZXJzaW9uPSIyLjEwLjMyIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjM6MDE6MzFUMTc6NTA6MzUtMDU6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIzOjAxOjMxVDE3OjUwOjM1LTA1OjAwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6ZGJjMjRlYWMtODdmMC00YjJjLWI2MzAtYTBhOTIxY2I1MmJmIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKExpbnV4KSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMy0wMS0zMVQxNzo1MDozNS0wNTowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz7KJrUFAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH5wEfFjIjpTMVIgAAAlFJREFUaN7t2E2ITXEYx/HPHTNehmlMGSXyMiILJBsbid2QHZZsZj8bL2WtMKLYiJWXkhVJsZLUkJeUl0JCTZJB42UwZphmxsIzdZtmxr3m3OPeOt86nc69z/n/n985z/P8n/MnIyMjIyMjI6OimYcL+IWhEh+fcAwzCnUuV6DdTDzAQjxFV4kf2mLMxV2sR19SA++LJ9WW0tufjHMx554kB76FAdSmGMr1GER7IcZVBQ46JXLjR0JOVmMp6sax6cZPTEtSSJJswzs8x0ccKiJXJ8x99CYwzkr04xvO4GXkQesY9r0xd9kJORCOb4nrxhB2Z6JC0g6tmjh/z3N0IHJmQqQt5GKcT2E/rkchuVRpOSLyoS9vFT8f60ZF5cgws7AWi/5iV7CQ6hK/yfpYD0bShZtJTlSqHJmKI+iIkls2FBNaq/Ak4n8AnWgax34JmsspR6qwN9qKbuzApmhtXmHOKPdswOcQvKschDRFYzmEG1iQ99/2aP4eRc4M0xIiO3Ev7j0bYflfhLREy9GH3WP0Ta3haDum43BcP8b8cP50/HY77+2lIqQRl/McWl7gN82HOF8dpfvdGWH2GqvTELIZ72PStnEWtJGcCBFHMWkMm2Z8QU+MXxIhtTgZznRg3T+U++YC7JbhRcyTuJB+PMtLyroSl/yGKAaJr+zVmI2tsZtSaobLsqSF9GMF3pbjXlUxLcpguYooRsib+G7YmKJvDbG+fE0ytA5GtbmCh1EeS0nOn81AMWeirMG1yJWhFI4eHM/lcjUyMjIyMjIyMiqT3wkE0qfVNfiiAAAAAElFTkSuQmCC'); + cursor: pointer; +} + +.changebanner { + position: relative; + margin-left: -4em; + margin-top: 26em; +} + .infodata { margin-top: 2em; display: flex; @@ -138,5 +159,4 @@ body { .logout { flex: 1; - /* align-self: flex-end !important; */ } \ No newline at end of file diff --git a/public/img/0.png b/public/image/default/0.png similarity index 100% rename from public/img/0.png rename to public/image/default/0.png diff --git a/public/img/1.png b/public/image/default/1.png similarity index 100% rename from public/img/1.png rename to public/image/default/1.png diff --git a/public/img/10.png b/public/image/default/10.png similarity index 100% rename from public/img/10.png rename to public/image/default/10.png diff --git a/public/img/11.png b/public/image/default/11.png similarity index 100% rename from public/img/11.png rename to public/image/default/11.png diff --git a/public/img/12.png b/public/image/default/12.png similarity index 100% rename from public/img/12.png rename to public/image/default/12.png diff --git a/public/img/13.png b/public/image/default/13.png similarity index 100% rename from public/img/13.png rename to public/image/default/13.png diff --git a/public/img/14.png b/public/image/default/14.png similarity index 100% rename from public/img/14.png rename to public/image/default/14.png diff --git a/public/img/15.png b/public/image/default/15.png similarity index 100% rename from public/img/15.png rename to public/image/default/15.png diff --git a/public/img/16.png b/public/image/default/16.png similarity index 100% rename from public/img/16.png rename to public/image/default/16.png diff --git a/public/img/17.png b/public/image/default/17.png similarity index 100% rename from public/img/17.png rename to public/image/default/17.png diff --git a/public/img/18.png b/public/image/default/18.png similarity index 100% rename from public/img/18.png rename to public/image/default/18.png diff --git a/public/img/19.png b/public/image/default/19.png similarity index 100% rename from public/img/19.png rename to public/image/default/19.png diff --git a/public/img/2.png b/public/image/default/2.png similarity index 100% rename from public/img/2.png rename to public/image/default/2.png diff --git a/public/img/20.png b/public/image/default/20.png similarity index 100% rename from public/img/20.png rename to public/image/default/20.png diff --git a/public/img/21.png b/public/image/default/21.png similarity index 100% rename from public/img/21.png rename to public/image/default/21.png diff --git a/public/img/22.png b/public/image/default/22.png similarity index 100% rename from public/img/22.png rename to public/image/default/22.png diff --git a/public/img/23.png b/public/image/default/23.png similarity index 100% rename from public/img/23.png rename to public/image/default/23.png diff --git a/public/img/24.png b/public/image/default/24.png similarity index 100% rename from public/img/24.png rename to public/image/default/24.png diff --git a/public/img/3.png b/public/image/default/3.png similarity index 100% rename from public/img/3.png rename to public/image/default/3.png diff --git a/public/img/4.png b/public/image/default/4.png similarity index 100% rename from public/img/4.png rename to public/image/default/4.png diff --git a/public/img/5.png b/public/image/default/5.png similarity index 100% rename from public/img/5.png rename to public/image/default/5.png diff --git a/public/img/6.png b/public/image/default/6.png similarity index 100% rename from public/img/6.png rename to public/image/default/6.png diff --git a/public/img/7.png b/public/image/default/7.png similarity index 100% rename from public/img/7.png rename to public/image/default/7.png diff --git a/public/img/8.png b/public/image/default/8.png similarity index 100% rename from public/img/8.png rename to public/image/default/8.png diff --git a/public/img/9.png b/public/image/default/9.png similarity index 100% rename from public/img/9.png rename to public/image/default/9.png diff --git a/public/js/api.js b/public/js/api.js index 9845be5..b2ea597 100644 --- a/public/js/api.js +++ b/public/js/api.js @@ -1,6 +1,27 @@ const endpoint = '/api' +const fileRequest = async (url, file, method) => { + if (method === undefined) method = 'POST' + const response = await fetch(endpoint + url, { + method, + body: file, + headers: {} + }); + if (response.status == 401) { + location.href = 'login' + } + const contentType = response.headers.get("content-type"); + if (contentType && contentType.indexOf("application/json") !== -1) { + const json = await response.json() + return { status: response.status, msg: json.msg, json } + } else { + const msg = await response.text(); + return { status: response.status, msg } + } +} + const request = async (url, body, method) => { + if (method === undefined) method = 'POST' const response = await fetch(endpoint + url, { method, @@ -88,4 +109,12 @@ const adminusers = async () => { const adminsessions = async () => { return await request('/admin/sessions', {}) +} + +const updateavatar = async (file) => { + return await fileRequest('/users/avatar', file, 'PUT') +} + +const updatebanner = async (file) => { + return await fileRequest('/users/banner', file, 'PUT') } \ No newline at end of file diff --git a/public/js/main.js b/public/js/main.js index 87dd8e0..ffbc1f3 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -33,7 +33,11 @@ function remove(id) { } function pfp(id) { - return `` + return `` +} + +function banner(id) { + return `` } const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', diff --git a/public/js/profile.js b/public/js/profile.js index 10eb873..90787f0 100644 --- a/public/js/profile.js +++ b/public/js/profile.js @@ -16,24 +16,44 @@ function swap(value) { } } +function changeimage(fn) { + + var input = document.createElement('input') + input.type = 'file' + input.accept= 'image/png' + + input.onchange = async (e) => { + var file = e.target.files[0]; + if (file.type !== 'image/png') { + return + } + let response = await fn(file); + alert(response.msg) + } + + input.click(); +} + function render() { const html = `