feat(frontend): scaffolding to build frontend

- Added `make fnginx` to have better dev experience
- Added app.conf to nginx configuration to handle frontend
This commit is contained in:
Maieul BOYER 2025-11-10 16:58:42 +01:00 committed by Maix0
parent 5dd6067c95
commit 0db41a440d
11 changed files with 186 additions and 10 deletions

3
.gitignore vendored
View file

@ -4,10 +4,11 @@
node_modules/
*.pdf
**/dist/
*.crt
*.key
# sqlite stuff
*.db
*.db-shm
*.db-wal
/db/
package-lock.json

View file

@ -6,7 +6,7 @@
# By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2023/11/12 11:05:05 by rparodi #+# #+# #
# Updated: 2025/11/09 01:22:55 by maiboyer ### ########.fr #
# Updated: 2025/11/10 01:05:11 by maiboyer ### ########.fr #
# #
# **************************************************************************** #
@ -144,8 +144,12 @@ tmux:
@tmux select-window -t $(PROJECT):0
@tmux attach-session -t $(PROJECT)
fnginx:
fnginx &
nginx-dev/nginx-selfsigned.crt nginx-dev/nginx-selfsigned.key &:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./nginx-dev/nginx-selfsigned.key -out ./nginx-dev/nginx-selfsigned.crt -subj "/C=FR/OU=student/CN=local.maix.me";
fnginx: nginx-dev/nginx-selfsigned.crt nginx-dev/nginx-selfsigned.key
nginx -p ./nginx-dev -c nginx.conf -e /dev/stderr &
-(cd ./frontend && pnpm exec tsc --noEmit --watch --preserveWatchOutput) &
-(cd ./frontend && pnpm exec vite --clearScreen false)
wait

View file

@ -2,6 +2,19 @@ networks:
transcendance-network:
driver: bridge
services:
###############
# USER #
###############
frontend:
build: ./frontend
container_name: frontend
restart: on-failure:3
networks:
- transcendance-network
volumes:
- static-volume:/volumes/static
#
# The "entry point" as in it does all of this:
# - serve files (images, static files, video)
@ -88,6 +101,7 @@ services:
- DATABASE_DIR=/volumes/database
volumes:
images-volume:
sqlite-volume:

View file

@ -54,6 +54,11 @@
sqlite-interactive
tmux-setup
typescript
act
openssl
nginx
openjdk # for openapi-generator... its a jar file
];
shellHook = ''
export PODMAN_COMPOSE_WARNING_LOGS="false";

99
nginx-dev/mime.types Normal file
View file

@ -0,0 +1,99 @@
types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/javascript js;
application/atom+xml atom;
application/rss+xml rss;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;
image/avif avif;
image/png png;
image/svg+xml svg svgz;
image/tiff tif tiff;
image/vnd.wap.wbmp wbmp;
image/webp webp;
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
font/woff woff;
font/woff2 woff2;
application/java-archive jar war ear;
application/json json;
application/mac-binhex40 hqx;
application/msword doc;
application/pdf pdf;
application/postscript ps eps ai;
application/rtf rtf;
application/vnd.apple.mpegurl m3u8;
application/vnd.google-earth.kml+xml kml;
application/vnd.google-earth.kmz kmz;
application/vnd.ms-excel xls;
application/vnd.ms-fontobject eot;
application/vnd.ms-powerpoint ppt;
application/vnd.oasis.opendocument.graphics odg;
application/vnd.oasis.opendocument.presentation odp;
application/vnd.oasis.opendocument.spreadsheet ods;
application/vnd.oasis.opendocument.text odt;
application/vnd.openxmlformats-officedocument.presentationml.presentation
pptx;
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
xlsx;
application/vnd.openxmlformats-officedocument.wordprocessingml.document
docx;
application/vnd.wap.wmlc wmlc;
application/wasm wasm;
application/x-7z-compressed 7z;
application/x-cocoa cco;
application/x-java-archive-diff jardiff;
application/x-java-jnlp-file jnlp;
application/x-makeself run;
application/x-perl pl pm;
application/x-pilot prc pdb;
application/x-rar-compressed rar;
application/x-redhat-package-manager rpm;
application/x-sea sea;
application/x-shockwave-flash swf;
application/x-stuffit sit;
application/x-tcl tcl tk;
application/x-x509-ca-cert der pem crt;
application/x-xpinstall xpi;
application/xhtml+xml xhtml;
application/xspf+xml xspf;
application/zip zip;
application/octet-stream bin exe dll;
application/octet-stream deb;
application/octet-stream dmg;
application/octet-stream iso img;
application/octet-stream msi msp msm;
audio/midi mid midi kar;
audio/mpeg mp3;
audio/ogg ogg;
audio/x-m4a m4a;
audio/x-realaudio ra;
video/3gpp 3gpp 3gp;
video/mp2t ts;
video/mp4 mp4;
video/mpeg mpeg mpg;
video/quicktime mov;
video/webm webm;
video/x-flv flv;
video/x-m4v m4v;
video/x-mng mng;
video/x-ms-asf asx asf;
video/x-ms-wmv wmv;
video/x-msvideo avi;
}

47
nginx-dev/nginx.conf Normal file
View file

@ -0,0 +1,47 @@
worker_processes 1;
pid /dev/null;
daemon off;
error_log stderr debug;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
access_log /dev/stderr;
listen 8000 ssl;
server_name localhost;
ssl_certificate nginx-selfsigned.crt;
ssl_certificate_key nginx-selfsigned.key;
ssl_protocols TLSv1.3;
error_page 497 https://$http_host$request_uri;
location /api {
proxy_ssl_verify off;
proxy_pass https://localhost:8888;
}
location /assets {
proxy_pass http://localhost:5173;
proxy_ssl_verify off;
}
location /app {
proxy_pass http://localhost:5173/;
proxy_ssl_verify off;
}
location / {
proxy_ssl_verify off;
return 301 'https://$http_host/app/$request_uri';
}
}
}

View file

@ -26,5 +26,6 @@ server {
ssl_protocols TLSv1.3;
proxy_set_header X-Forwarded true;
error_page 497 https://$http_host$request_uri;
include conf.d/locations/*.conf;
}

View file

@ -0,0 +1,8 @@
location /app {
root /volumes/static/app/;
try_files /index.html =404;
}
location /assets {
root /volumes/static/app/;
}

View file

@ -2,7 +2,3 @@
location /api/auth/ {
proxy_pass http://auth;
}
location / {
root /volumes/static/auth/;
}

View file

@ -1,5 +1,6 @@
packages:
- ./src/*
- \!frontend
nodeLinker: hoisted

View file

@ -33,10 +33,10 @@ const route: FastifyPluginAsync = async (fastify, _opts): Promise<void> => {
// does the user exist
// does it have a password setup ?
if (isNullish(user?.password)) { return res.makeResponse(403, 'failed', 'login.failed.invalid'); }
if (isNullish(user?.password)) { return res.makeResponse(400, 'failed', 'login.failed.invalid'); }
// does the password he provided match the one we have
if (!(await verifyUserPassword(user, password))) { return res.makeResponse(403, 'failed', 'login.failed.invalid'); }
if (!(await verifyUserPassword(user, password))) { return res.makeResponse(400, 'failed', 'login.failed.invalid'); }
// does the user has 2FA up ?
if (!isNullish(user.otp)) {