diff --git a/miniRT/Dockerfile b/miniRT/Dockerfile index da0ef7c..300bc1f 100644 --- a/miniRT/Dockerfile +++ b/miniRT/Dockerfile @@ -36,7 +36,7 @@ RUN git clone https://github.com/novnc/noVNC.git /opt/noVNC # Create VNC directory and set password RUN mkdir -p /root/.vnc && \ - echo "password" | vncpasswd -f > /root/.vnc/passwd && \ + echo "1312" | vncpasswd -f > /root/.vnc/passwd && \ chmod 600 /root/.vnc/passwd RUN rm /opt/noVNC/*.html diff --git a/minishell/Dockerfile b/minishell/Dockerfile index b631492..ab69794 100644 --- a/minishell/Dockerfile +++ b/minishell/Dockerfile @@ -13,7 +13,7 @@ RUN apk update && \ chmod 700 /entrypoint.sh && \ touch /etc/.firstrun && \ ln -s "/usr/share/zoneinfo/$TZ" /etc/localtime && \ - echo $TZ > /etc/timezone + echo $TZ > /etc/timezone RUN rm -f /bin/ping /bin/ping6 /usr/bin/wget /usr/bin/curl \ /usr/bin/nc /usr/bin/telnet /sbin/ip /bin/netstat diff --git a/minishell/bin/minishell b/minishell/bin/minishell new file mode 100755 index 0000000..aec2af1 Binary files /dev/null and b/minishell/bin/minishell differ diff --git a/minishell/libft/libft.a b/minishell/libft/libft.a new file mode 100644 index 0000000..e5985a1 Binary files /dev/null and b/minishell/libft/libft.a differ diff --git a/misc/deploy.sh b/misc/deploy.sh deleted file mode 100755 index 002982d..0000000 --- a/misc/deploy.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -# reset server_website directory -rm -rf server_website -ssh server rm -rf /home/victor/website -mkdir -p server_website/{minishell,vvsite} - -# Build server binary -cd vvsite && cargo leptos build --release -cp -r target/release/vvsite Dockerfile Cargo.toml target/site ../server_website/vvsite - - -# Build minishell files -cd ../minishell -make -C minishell_src -cp -r ./minishell_src/bin ./Dockerfile ./entrypoint.sh ../server_website/minishell - -# Copy to server -cd .. -cp -r ./nginx ./compose.yaml server_website -scp -r server_website server:/home/victor/website - diff --git a/misc/run.sh b/misc/run.sh index 521cc3c..40bae58 100755 --- a/misc/run.sh +++ b/misc/run.sh @@ -3,20 +3,8 @@ set -e # Compile the minishell project -make -C minishell/minishell_src - -# rebuild website -cd vvsite && cargo leptos build -cd .. - -# stop containers if running -docker compose down -v - -# remove volumes -docker volume prune -f - -docker rmi website-website website-minishell website-nginx -f - +make -C minishell +make -C miniRT # start the containers -docker compose up +docker compose up --build diff --git a/nginx/nginx.conf b/nginx/nginx.conf index 75d883f..082a1dc 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -36,11 +36,23 @@ http { listen 443 ssl; server_name localhost; + root /var/www/html; + ssl_certificate /certs/localhost.pem; ssl_certificate_key /certs/localhost-key.pem; # Apply connection limits - limit_conn conn_limit_per_ip 20; + limit_conn conn_limit_per_ip 2; + + location / { + root /var/www/html; + index index.html index.htm; + } + + location /minirt/password { + add_header Content-Type application/json; + try_files /json/password.json =404; + } location /minishell/vnc { proxy_pass http://minishell:8006/; @@ -53,6 +65,25 @@ http { } location /minirt/vnc { + index vnc.html; + try_files $uri $uri/ /vnc.html; + + # Ensure proper MIME types for JavaScript modules + location ~* \.js$ { + add_header Content-Type "application/javascript" always; + expires 1h; + } + location ~* \.css$ { + add_header Content-Type "text/css" always; + expires 1h; + } + location ~* \.(png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1d; + add_header Cache-Control "public, immutable"; + } + } + + location /vnc { alias /opt/noVNC/; index vnc.html; try_files $uri $uri/ /vnc.html; @@ -87,9 +118,5 @@ http { proxy_buffering off; } - location / { - root /var/www/html; - index index.html index.htm; - } } } diff --git a/nginx/site/config.js b/nginx/site/config.js new file mode 100644 index 0000000..2d54ba2 --- /dev/null +++ b/nginx/site/config.js @@ -0,0 +1,3 @@ +export const config = { + BASE_URL: 'https://localhost:5443/' +}; diff --git a/nginx/site/css/minirt.css b/nginx/site/css/minirt.css new file mode 100644 index 0000000..4c7598a --- /dev/null +++ b/nginx/site/css/minirt.css @@ -0,0 +1,39 @@ +.minirt-canvas-background { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 9999; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + background-color: rgba(32, 32, 32, 0.5); +} + +#top_bar { + background-color: #6e84a3; + color: white; + font: bold 12px Helvetica; + padding: 6px 5px 4px 5px; + border-bottom: 1px outset; +} + +#status { + text-align: center; +} + +#sendCtrlAltDelButton { + position: fixed; + top: 0px; + right: 0px; + border: 1px outset; + padding: 5px 5px 4px 5px; + cursor: pointer; +} + +#screen { + flex: 1; /* fill remaining space */ + overflow: hidden; +} diff --git a/nginx/site/css/tailwind.css b/nginx/site/css/tailwind.css index ec8f035..47123b9 100644 --- a/nginx/site/css/tailwind.css +++ b/nginx/site/css/tailwind.css @@ -1,113 +1,5 @@ -*, ::before, ::after { - --tw-border-spacing-x: 0; - --tw-border-spacing-y: 0; - --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-gradient-from-position: ; - --tw-gradient-via-position: ; - --tw-gradient-to-position: ; - --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: ; - --tw-contain-size: ; - --tw-contain-layout: ; - --tw-contain-paint: ; - --tw-contain-style: ; -} - -::backdrop { - --tw-border-spacing-x: 0; - --tw-border-spacing-y: 0; - --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-gradient-from-position: ; - --tw-gradient-via-position: ; - --tw-gradient-to-position: ; - --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: ; - --tw-contain-size: ; - --tw-contain-layout: ; - --tw-contain-paint: ; - --tw-contain-style: ; -} - /* -! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com +! tailwindcss v3.4.0 | MIT License | https://tailwindcss.com */ /* @@ -319,8 +211,6 @@ textarea { /* 1 */ line-height: inherit; /* 1 */ - letter-spacing: inherit; - /* 1 */ color: inherit; /* 1 */ margin: 0; @@ -344,9 +234,9 @@ select { */ button, -input:where([type='button']), -input:where([type='reset']), -input:where([type='submit']) { +[type='button'], +[type='reset'], +[type='submit'] { -webkit-appearance: button; /* 1 */ background-color: transparent; @@ -550,10 +440,110 @@ video { /* Make elements with the HTML hidden attribute stay hidden by default */ -[hidden]:where(:not([hidden="until-found"])) { +[hidden] { display: none; } +*, ::before, ::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --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-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --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: ; +} + +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --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-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --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: ; +} + .fixed { position: fixed; } @@ -566,53 +556,12 @@ video { position: relative; } -.inset-0 { - inset: 0px; +.right-\[16px\] { + right: 16px; } -.z-10 { - z-index: 10; -} - -.z-20 { - z-index: 20; -} - -.m-24 { - margin: 6rem; -} - -.m-auto { - margin: auto; -} - -.m-60 { - margin: 15rem; -} - -.mx-24 { - margin-left: 6rem; - margin-right: 6rem; -} - -.mx-60 { - margin-left: 15rem; - margin-right: 15rem; -} - -.mx-\[40\%\] { - margin-left: 40%; - margin-right: 40%; -} - -.mx-\[20\%\] { - margin-left: 20%; - margin-right: 20%; -} - -.mx-auto { - margin-left: auto; - margin-right: auto; +.top-\[16px\] { + top: 16px; } .mb-4 { @@ -623,22 +572,6 @@ video { margin-left: 1rem; } -.ml-2 { - margin-left: 0.5rem; -} - -.mb-2 { - margin-bottom: 0.5rem; -} - -.-mt-4 { - margin-top: -1rem; -} - -.mr-2 { - margin-right: 0.5rem; -} - .ml-\[10\%\] { margin-left: 10%; } @@ -647,58 +580,34 @@ video { margin-right: auto; } -.box-border { - box-sizing: border-box; -} - .flex { display: flex; } -.h-32 { - height: 8rem; +.hidden { + display: none; } .h-48 { height: 12rem; } -.h-\[8vh\] { - height: 8vh; +.h-\[20dvh\] { + height: 20dvh; } -.h-full { - height: 100%; -} - -.h-\[600px\] { - height: 600px; -} - -.h-\[20\%\] { - height: 20%; -} - -.h-\[10\%\] { - height: 10%; -} - -.h-\[8\%\] { - height: 8%; -} - -.h-5 { - height: 1.25rem; -} - -.min-h-\[8vh\] { - min-height: 8vh; +.h-\[5dvh\] { + height: 5dvh; } .min-h-\[600px\] { min-height: 600px; } +.w-\[60\%\] { + width: 60%; +} + .w-full { width: 100%; } @@ -707,58 +616,23 @@ video { width: 100vw; } -.w-\[20\%\] { - width: 20%; -} - -.w-\[10\%\] { - width: 10%; -} - -.w-\[800px\] { - width: 800px; -} - -.w-\[50\%\] { - width: 50%; -} - -.w-\[60\%\] { - width: 60%; -} - -.w-5 { - width: 1.25rem; -} - -.min-w-\[800px\] { - min-width: 800px; -} - -.max-w-prose { - max-width: 65ch; +.w-fit { + width: -moz-fit-content; + width: fit-content; } .max-w-\[800px\] { max-width: 800px; } -.max-w-4xl { - max-width: 56rem; -} - -.max-w-6xl { - max-width: 72rem; +.max-w-prose { + max-width: 65ch; } .grow { flex-grow: 1; } -.transform { - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - .list-inside { list-style-position: inside; } @@ -791,14 +665,6 @@ video { gap: 1rem; } -.gap-6 { - gap: 1.5rem; -} - -.gap-2 { - gap: 0.5rem; -} - .gap-y-6 { row-gap: 1.5rem; } @@ -809,138 +675,35 @@ video { margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); } -.space-y-4 > :not([hidden]) ~ :not([hidden]) { - --tw-space-y-reverse: 0; - margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(1rem * var(--tw-space-y-reverse)); +.place-self-start { + place-self: start; } -.overflow-hidden { - overflow: hidden; +.place-self-end { + place-self: end; } .rounded-md { border-radius: 0.375rem; } -.rounded { - border-radius: 0.25rem; -} - -.rounded-lg { - border-radius: 0.5rem; -} - -.rounded-t-xl { - border-top-left-radius: 0.75rem; - border-top-right-radius: 0.75rem; -} - .border { border-width: 1px; } -.border-b-2 { - border-bottom-width: 2px; -} - -.border-l-4 { - border-left-width: 4px; -} - -.border-blue-400 { - --tw-border-opacity: 1; - border-color: rgb(96 165 250 / var(--tw-border-opacity, 1)); -} - -.border-gray-300 { - --tw-border-opacity: 1; - border-color: rgb(209 213 219 / var(--tw-border-opacity, 1)); -} - -.border-gray-600 { - --tw-border-opacity: 1; - border-color: rgb(75 85 99 / var(--tw-border-opacity, 1)); -} - .bg-gray-800 { --tw-bg-opacity: 1; - background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1)); + background-color: rgb(31 41 55 / var(--tw-bg-opacity)); } .bg-neutral-100\/50 { background-color: rgb(245 245 245 / 0.5); } -.bg-neutral-100 { - --tw-bg-opacity: 1; - background-color: rgb(245 245 245 / var(--tw-bg-opacity, 1)); -} - -.bg-neutral-300 { - --tw-bg-opacity: 1; - background-color: rgb(212 212 212 / var(--tw-bg-opacity, 1)); -} - -.bg-neutral-100\/80 { - background-color: rgb(245 245 245 / 0.8); -} - -.bg-neutral-100\/70 { - background-color: rgb(245 245 245 / 0.7); -} - .bg-neutral-200\/70 { background-color: rgb(229 229 229 / 0.7); } -.bg-black\/10 { - background-color: rgb(0 0 0 / 0.1); -} - -.bg-gray-50 { - --tw-bg-opacity: 1; - background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1)); -} - -.bg-gradient-to-br { - background-image: linear-gradient(to bottom right, var(--tw-gradient-stops)); -} - -.bg-gradient-to-r { - background-image: linear-gradient(to right, var(--tw-gradient-stops)); -} - -.from-gray-800 { - --tw-gradient-from: #1f2937 var(--tw-gradient-from-position); - --tw-gradient-to: rgb(31 41 55 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); -} - -.from-green-400 { - --tw-gradient-from: #4ade80 var(--tw-gradient-from-position); - --tw-gradient-to: rgb(74 222 128 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); -} - -.from-neutral-100 { - --tw-gradient-from: #f5f5f5 var(--tw-gradient-from-position); - --tw-gradient-to: rgb(245 245 245 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); -} - -.to-gray-900 { - --tw-gradient-to: #111827 var(--tw-gradient-to-position); -} - -.to-green-500 { - --tw-gradient-to: #22c55e var(--tw-gradient-to-position); -} - -.to-neutral-200\/70 { - --tw-gradient-to: rgb(229 229 229 / 0.7) var(--tw-gradient-to-position); -} - .p-1 { padding: 0.25rem; } @@ -953,13 +716,8 @@ video { padding: 2rem; } -.p-6 { - padding: 1.5rem; -} - -.py-8 { - padding-top: 2rem; - padding-bottom: 2rem; +.p-2 { + padding: 0.5rem; } .px-16 { @@ -967,13 +725,9 @@ video { padding-right: 4rem; } -.px-1 { - padding-left: 0.25rem; - padding-right: 0.25rem; -} - -.pb-2 { - padding-bottom: 0.5rem; +.py-8 { + padding-top: 2rem; + padding-bottom: 2rem; } .text-center { @@ -990,171 +744,48 @@ video { line-height: 1; } -.text-lg { - font-size: 1.125rem; - line-height: 1.75rem; -} - .font-bold { font-weight: 700; } -.font-semibold { - font-weight: 600; -} - .leading-relaxed { line-height: 1.625; } -.text-red-400 { - --tw-text-opacity: 1; - color: rgb(248 113 113 / var(--tw-text-opacity, 1)); -} - .text-\[\#FFF6DA\] { --tw-text-opacity: 1; - color: rgb(255 246 218 / var(--tw-text-opacity, 1)); -} - -.text-gray-700 { - --tw-text-opacity: 1; - color: rgb(55 65 81 / var(--tw-text-opacity, 1)); -} - -.text-gray-800 { - --tw-text-opacity: 1; - color: rgb(31 41 55 / var(--tw-text-opacity, 1)); -} - -.text-purple-400 { - --tw-text-opacity: 1; - color: rgb(192 132 252 / var(--tw-text-opacity, 1)); -} - -.text-purple-200 { - --tw-text-opacity: 1; - color: rgb(233 213 255 / var(--tw-text-opacity, 1)); -} - -.text-blue-600 { - --tw-text-opacity: 1; - color: rgb(37 99 235 / var(--tw-text-opacity, 1)); -} - -.text-white { - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity, 1)); + color: rgb(255 246 218 / var(--tw-text-opacity)); } .text-blue-700 { --tw-text-opacity: 1; - color: rgb(29 78 216 / var(--tw-text-opacity, 1)); + color: rgb(29 78 216 / var(--tw-text-opacity)); +} + +.text-gray-700 { + --tw-text-opacity: 1; + color: rgb(55 65 81 / var(--tw-text-opacity)); +} + +.text-gray-800 { + --tw-text-opacity: 1; + color: rgb(31 41 55 / var(--tw-text-opacity)); +} + +.text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); } .underline { text-decoration-line: underline; } -.shadow-2xl { - --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); - --tw-shadow-colored: 0 25px 50px -12px 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-lg { - --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px 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-xl { - --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.drop-shadow-lg { - --tw-drop-shadow: drop-shadow(0 10px 8px rgb(0 0 0 / 0.04)) drop-shadow(0 4px 3px rgb(0 0 0 / 0.1)); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); -} - -.transition-all { - transition-property: all; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; -} - -.transition-colors { - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; -} - -.duration-150 { - transition-duration: 150ms; -} - -.duration-200 { - transition-duration: 200ms; -} - -.duration-300 { - transition-duration: 300ms; -} - -.hover\:scale-105:hover { - --tw-scale-x: 1.05; - --tw-scale-y: 1.05; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.hover\:transform:hover { - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - .hover\:bg-\[\#aa9E73ff\]:hover { background-color: #aa9E73ff; } -.hover\:bg-blue-50:hover { - --tw-bg-opacity: 1; - background-color: rgb(239 246 255 / var(--tw-bg-opacity, 1)); -} - -.hover\:from-green-500:hover { - --tw-gradient-from: #22c55e var(--tw-gradient-from-position); - --tw-gradient-to: rgb(34 197 94 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); -} - -.hover\:to-green-600:hover { - --tw-gradient-to: #16a34a var(--tw-gradient-to-position); -} - -.hover\:text-blue-800:hover { - --tw-text-opacity: 1; - color: rgb(30 64 175 / var(--tw-text-opacity, 1)); -} - -.hover\:text-gray-900:hover { - --tw-text-opacity: 1; - color: rgb(17 24 39 / var(--tw-text-opacity, 1)); -} - .hover\:text-blue-900:hover { --tw-text-opacity: 1; - color: rgb(30 58 138 / var(--tw-text-opacity, 1)); -} - -.hover\:shadow-lg:hover { - --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px 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\:shadow-xl:hover { - --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + color: rgb(30 58 138 / var(--tw-text-opacity)); } diff --git a/nginx/site/html/minirt.html b/nginx/site/html/minirt.html index 9f51179..fef7438 100644 --- a/nginx/site/html/minirt.html +++ b/nginx/site/html/minirt.html @@ -5,34 +5,9 @@ MiniRT Preview + -
@@ -45,15 +20,87 @@
-

The Shell

+

The Raytracer

+ The next project i want to showcase is the miniRT (mini-raytracer).
+ Like the shell, this was part of the 42 curriculum, and was achieved within the same rules and + constraints as the previous project.

- - + diff --git a/nginx/site/html/minishell.js b/nginx/site/html/minishell.js deleted file mode 100644 index e69de29..0000000 diff --git a/nginx/site/html/tailwind.config.js b/nginx/site/html/tailwind.config.js deleted file mode 100644 index 9ad393b..0000000 --- a/nginx/site/html/tailwind.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - content: ["./*.html"], - theme: { - extend: {}, - }, - plugins: [], -} diff --git a/nginx/site/js/minirt.js b/nginx/site/js/minirt.js new file mode 100644 index 0000000..ec29157 --- /dev/null +++ b/nginx/site/js/minirt.js @@ -0,0 +1,155 @@ +// +// !!! DISCLAIMER !!! +// This is the default template that comes with noVNC, all credit goes to them +// + +import { config } from '/config.js'; +import RFB from '/vnc/core/rfb.js'; + +// RFB holds the API to connect and communicate with a VNC server + +function closeMinirtFrame() { + const screen = document.getElementById('screen'); + if (screen) + screen.remove(); + const canvas_background = document.getElementById('minirt-canvas-background'); + canvas_background.style = 'display: none'; +} + +document.addEventListener('keydown', function(event) { + if (event.key === 'Escape') { + closeMinirtFrame(); + } +}); + +const get_passwd = document.getElementById('minirt-password-btn'); +get_passwd.addEventListener('click', function() { + try { + fetch(config.BASE_URL + 'minirt/password') + .then(resp => { + if (!resp.ok) { + throw new Error("Failed to fetch password"); + } + return resp.json(); + }) + .then(data => { + const passwd_display = document.getElementById('minirt-password-display'); + passwd_display.textContent = `Password: ${data.password}`; + }); + } catch (c) { + console.error(e); + } +}) + +const close_button = document.getElementById('canvas-close-btn'); +close_button.addEventListener('click', closeMinirtFrame); + + +const minirt_button = document.getElementById('minirt-start-button'); +minirt_button.addEventListener('click', function() { + // const url = config.BASE_URL + 'minirt/vnc'; + const canvas_background = document.getElementById('minirt-canvas-background'); + canvas_background.style = ''; + + const screen = document.createElement('div'); + screen.id = 'screen'; + canvas_background.appendChild(screen); + + + let rfb; + let desktopName; + + // When this function is called we have + // successfully connected to a server + function connectedToServer(e) { + status("Connected to " + desktopName); + } + + // This function is called when we are disconnected + function disconnectedFromServer(e) { + if (e.detail.clean) { + status("Disconnected"); + } else { + status("Something went wrong, connection is closed"); + } + } + + // When this function is called, the server requires + // credentials to authenticate + function credentialsAreRequired(e) { + const password = prompt("Password required:"); + if (password) + rfb.sendCredentials({ password: password }); + } + + // When this function is called we have received + // a desktop name from the server + function updateDesktopName(e) { + desktopName = e.detail.name; + } + + // Show a status text in the top bar + function status(text) { + document.getElementById('status').textContent = text; + } + + // This function extracts the value of one variable from the + // query string. If the variable isn't defined in the URL + // it returns the default value instead. + function readQueryVariable(name, defaultValue) { + // A URL with a query parameter can look like this: + // https://www.example.com?myqueryparam=myvalue + // + // Note that we use location.href instead of location.search + // because Firefox < 53 has a bug w.r.t location.search + const re = new RegExp('.*[?&]' + name + '=([^&#]*)'), + match = document.location.href.match(re); + + if (match) { + // We have to decode the URL since want the cleartext value + return decodeURIComponent(match[1]); + } + + return defaultValue; + } + + // Read parameters specified in the URL query string + // By default, use the host and port of server that served this file + const host = readQueryVariable('host', window.location.hostname); + let port = readQueryVariable('port', window.location.port); + const password = readQueryVariable('password'); + const path = readQueryVariable('path', 'websockify'); + + // | | | | | | + // | | | Connect | | | + // v v v v v v + + status("Connecting"); + + // Build the websocket URL used to connect + let url; + if (window.location.protocol === "https:") { + url = 'wss'; + } else { + url = 'ws'; + } + url += '://' + host; + if(port) { + url += ':' + port; + } + url += '/' + path; + + // Creating a new RFB object will start a new connection + rfb = new RFB(screen, url, + { credentials: { password: password } }); + + // Add listeners to important events from the RFB module + rfb.addEventListener("connect", connectedToServer); + rfb.addEventListener("disconnect", disconnectedFromServer); + rfb.addEventListener("credentialsrequired", credentialsAreRequired); + rfb.addEventListener("desktopname", updateDesktopName); + + // Set parameters that can be changed on an active connection + rfb.viewOnly = readQueryVariable('view_only', false); + rfb.scaleViewport = readQueryVariable('scale', false); +}); diff --git a/nginx/site/js/minishell.js b/nginx/site/js/minishell.js new file mode 100644 index 0000000..ca7ee51 --- /dev/null +++ b/nginx/site/js/minishell.js @@ -0,0 +1,19 @@ +import { config } from '/config.js'; + +const shell_button = document.getElementById('shell-start-button'); +shell_button.addEventListener('click', function() { + const shell_container = document.getElementById('shell-container'); + const shell_frame = document.createElement('iframe'); + shell_frame.id = 'minishell-iframe'; + shell_frame.height = '600'; + shell_frame.width = '800'; + shell_frame.src = config.BASE_URL + 'minishell/vnc'; + shell_container.appendChild(shell_frame); + shell_button.style = 'display: none'; +}); + +const next_project_a = document.getElementById('next-project-a'); +next_project_a.addEventListener('click', function() { + const shell_frame = document.getElementById('minishell-iframe'); + shell_frame.remove(); +}); diff --git a/nginx/site/json/password.json b/nginx/site/json/password.json new file mode 100644 index 0000000..a8d3638 --- /dev/null +++ b/nginx/site/json/password.json @@ -0,0 +1 @@ +{ "password": "1312" } diff --git a/nginx/site/tailwind.config.js b/nginx/site/tailwind.config.js new file mode 100644 index 0000000..4aea311 --- /dev/null +++ b/nginx/site/tailwind.config.js @@ -0,0 +1,9 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ["./html/*.html"], + theme: { + extend: {}, + }, + plugins: [], +} +