diff --git a/backend/app/routes/user.route.js b/backend/app/routes/user.route.js index 75928f9..c3a5652 100644 --- a/backend/app/routes/user.route.js +++ b/backend/app/routes/user.route.js @@ -38,7 +38,7 @@ router.get("/:id", [addLogger, isTokenValid, User.id, validator], getById) router.get("/username/:username", [addLogger, isTokenValid, UserRequest.username, validator], getByUsername); // UPDATE USER -router.put("/:id", [addLogger, isTokenValid, User.id, UserRegister.email, UserRegister.username, UserRegister.password, validator, doUserExists, isOwner], update); +router.put("/:id", [addLogger, isTokenValid, User.id, UserRegister.email, UserRegister.username, validator, doUserExists, isOwner], update); // DELETE USER router.delete("/:id", [addLogger, isTokenValid, User.id, validator, doUserExists, isOwner], deleteUser); diff --git a/backend/app/uploads/profiles/astria.png b/backend/app/uploads/profiles/astria.png new file mode 100644 index 0000000..388cdbe Binary files /dev/null and b/backend/app/uploads/profiles/astria.png differ diff --git a/backend/app/uploads/profiles/sacha.jpg b/backend/app/uploads/profiles/sacha.jpg new file mode 100644 index 0000000..0028516 Binary files /dev/null and b/backend/app/uploads/profiles/sacha.jpg differ diff --git a/backend/logs/access.log b/backend/logs/access.log index 9feeea6..5591400 100644 --- a/backend/logs/access.log +++ b/backend/logs/access.log @@ -1218,3 +1218,80 @@ [2025-07-20 20:51:37.656] [undefined] GET(/:id/channel): failed due to invalid values with status 400 [2025-07-20 20:51:37.660] [undefined] GET(/:id/history): failed due to invalid values with status 400 [2025-07-20 20:51:37.662] [undefined] GET(/user/:id): failed due to invalid values with status 400 +[2025-07-21 08:25:33.854] [undefined] POST(/): try to register a user with username: sacha and email: test@test.test +[2025-07-21 08:25:33.934] [undefined] POST(/): successfully registered with status 200 +[2025-07-21 08:25:33.956] [undefined] POST(/login): try to login with username 'sacha' +[2025-07-21 08:25:34.017] [undefined] POST(/login): Successfully logged in with status 200 +[2025-07-21 08:25:43.729] [undefined] GET(/:id/history): try to retrieve history of user 1 +[2025-07-21 08:25:43.731] [undefined] GET(/:id/channel): try to retrieve channel of user 1 +[2025-07-21 08:25:43.733] [undefined] GET(/:id/history): failed to retrieve history of user 1 because it doesn't exist with status 404 +[2025-07-21 08:25:43.735] [undefined] GET(/:id/channel): failed to retrieve channel of user 1 because it doesn't exist with status 404 +[2025-07-21 08:25:43.748] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200 +[2025-07-21 08:27:05.391] [undefined] GET(/:id/channel): try to retrieve channel of user 1 +[2025-07-21 08:27:05.396] [undefined] GET(/:id/history): try to retrieve history of user 1 +[2025-07-21 08:27:05.400] [undefined] GET(/:id/channel): failed to retrieve channel of user 1 because it doesn't exist with status 404 +[2025-07-21 08:27:05.406] [undefined] GET(/:id/history): failed to retrieve history of user 1 because it doesn't exist with status 404 +[2025-07-21 08:27:05.424] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200 +[2025-07-21 13:26:38.560] [undefined] GET(/:id/channel): Invalid token with status 401 +[2025-07-21 13:26:38.574] [undefined] GET(/user/:id): Invalid token with status 401 +[2025-07-21 13:26:38.578] [undefined] GET(/:id/history): Invalid token with status 401 +[2025-07-21 13:26:47.958] [undefined] PUT(/:id): Invalid token with status 401 +[2025-07-21 13:27:15.056] [undefined] POST(/): try to register a user with username: astria and email: sachaguerin.sg@gmail.com +[2025-07-21 13:27:15.159] [undefined] POST(/): successfully registered with status 200 +[2025-07-21 13:27:15.182] [undefined] POST(/login): try to login with username 'astria' +[2025-07-21 13:27:15.275] [undefined] POST(/login): Successfully logged in with status 200 +[2025-07-21 13:27:21.989] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-07-21 13:27:21.997] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-07-21 13:27:22.001] [undefined] GET(/:id/channel): failed to retrieve channel of user 2 because it doesn't exist with status 404 +[2025-07-21 13:27:22.004] [undefined] GET(/:id/history): failed to retrieve history of user 2 because it doesn't exist with status 404 +[2025-07-21 13:27:22.023] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-07-21 13:31:48.331] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-07-21 13:31:48.335] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-07-21 13:31:48.347] [undefined] GET(/:id/channel): failed to retrieve channel of user 2 because it doesn't exist with status 404 +[2025-07-21 13:31:48.351] [undefined] GET(/:id/history): failed to retrieve history of user 2 because it doesn't exist with status 404 +[2025-07-21 13:31:48.367] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-07-21 13:43:14.509] [undefined] POST(/login): try to login with username 'astria' +[2025-07-21 13:43:14.642] [undefined] POST(/login): Successfully logged in with status 200 +[2025-07-21 13:44:06.419] [undefined] POST(/login): try to login with username 'astria' +[2025-07-21 13:44:06.535] [undefined] POST(/login): Successfully logged in with status 200 +[2025-07-21 13:46:40.594] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-07-21 13:46:40.596] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-07-21 13:46:40.603] [undefined] GET(/:id/channel): failed to retrieve channel of user 2 because it doesn't exist with status 404 +[2025-07-21 13:46:40.607] [undefined] GET(/:id/history): failed to retrieve history of user 2 because it doesn't exist with status 404 +[2025-07-21 13:46:40.628] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-07-21 13:49:14.141] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-07-21 13:49:14.147] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-07-21 13:49:14.158] [undefined] GET(/:id/channel): failed to retrieve channel of user 2 because it doesn't exist with status 404 +[2025-07-21 13:49:14.164] [undefined] GET(/:id/history): failed to retrieve history of user 2 because it doesn't exist with status 404 +[2025-07-21 13:49:14.176] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-07-21 13:49:27.835] [undefined] PUT(/:id): failed due to invalid values with status 400 +[2025-07-21 13:53:11.927] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-07-21 13:53:11.928] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-07-21 13:53:11.934] [undefined] GET(/:id/channel): failed to retrieve channel of user 2 because it doesn't exist with status 404 +[2025-07-21 13:53:11.939] [undefined] GET(/:id/history): failed to retrieve history of user 2 because it doesn't exist with status 404 +[2025-07-21 13:53:11.961] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-07-21 13:53:26.486] [undefined] PUT(/:id): failed due to invalid values with status 400 +[2025-07-21 13:55:33.519] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-07-21 13:55:33.528] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-07-21 13:55:33.532] [undefined] GET(/:id/channel): failed to retrieve channel of user 2 because it doesn't exist with status 404 +[2025-07-21 13:55:33.542] [undefined] GET(/:id/history): failed to retrieve history of user 2 because it doesn't exist with status 404 +[2025-07-21 13:55:33.562] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-07-21 13:55:44.670] [undefined] PUT(/:id): try to update user 2 +[2025-07-21 13:55:44.684] [undefined] PUT(/:id): successfully updated user 2 with status 200 +[2025-07-21 13:55:48.794] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-07-21 13:55:48.797] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-07-21 13:55:48.799] [undefined] GET(/:id/history): failed to retrieve history of user 2 because it doesn't exist with status 404 +[2025-07-21 13:55:48.803] [undefined] GET(/:id/channel): failed to retrieve channel of user 2 because it doesn't exist with status 404 +[2025-07-21 13:55:48.822] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-07-21 13:56:33.755] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-07-21 13:56:33.763] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-07-21 13:56:33.771] [undefined] GET(/:id/history): failed to retrieve history of user 2 because it doesn't exist with status 404 +[2025-07-21 13:56:33.782] [undefined] GET(/:id/channel): failed to retrieve channel of user 2 because it doesn't exist with status 404 +[2025-07-21 13:56:33.804] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-07-21 13:56:43.181] [undefined] POST(/login): try to login with username 'astria' +[2025-07-21 13:56:43.306] [undefined] POST(/login): Successfully logged in with status 200 +[2025-07-21 13:56:56.291] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-07-21 13:56:56.313] [undefined] GET(/:id/channel): failed to retrieve channel of user 2 because it doesn't exist with status 404 +[2025-07-21 13:56:56.344] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-07-21 13:56:56.354] [undefined] GET(/:id/history): failed to retrieve history of user 2 because it doesn't exist with status 404 +[2025-07-21 13:56:56.363] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 diff --git a/docker-compose.yaml b/docker-compose.yaml index f2c6e24..9efeef2 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -4,14 +4,13 @@ services: build: context: ./backend dockerfile: Dockerfile - network: host container_name: resit_backend ports: - "8000:8000" environment: DB_USER: ${POSTGRES_USER} DB_NAME: ${POSTGRES_DB} - DB_HOST: ${POSTGRES_HOST} + DB_HOST: db DB_PASSWORD: ${POSTGRES_PASSWORD} JWT_SECRET: ${JWT_SECRET} LOG_FILE: ${LOG_FILE} @@ -35,12 +34,16 @@ services: frontend: image: nginx:latest - network_mode: host ports: - "80:80" + - "443:443" volumes: - ./frontend/dist:/usr/share/nginx/html - ./nginx/default.conf:/etc/nginx/conf.d/default.conf + - ./nginx/nginx-selfsigned.crt:/etc/nginx/ssl/nginx-selfsigned.crt + - ./nginx/nginx-selfsigned.key:/etc/nginx/ssl/nginx-selfsigned.key + depends_on: + - resit_backend volumes: db_data: diff --git a/nginx/default.conf b/nginx/default.conf index d08da12..20e8df5 100644 --- a/nginx/default.conf +++ b/nginx/default.conf @@ -2,12 +2,25 @@ server { server_name localhost; listen 80; + return 301 https://$host$request_uri; +} + +server { + server_name localhost; + listen 443 ssl; + root /usr/share/nginx/html; index index.html index.htm; + ssl_certificate /etc/nginx/ssl/nginx-selfsigned.crt; + ssl_certificate_key /etc/nginx/ssl/nginx-selfsigned.key; + + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + # API routes - proxy to backend (MUST come before static file rules) location /api/ { - proxy_pass http://127.0.0.1:8000; + proxy_pass http://resit_backend:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/nginx/nginx-selfsigned.crt b/nginx/nginx-selfsigned.crt new file mode 100644 index 0000000..29fac8a --- /dev/null +++ b/nginx/nginx-selfsigned.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID5zCCAs+gAwIBAgIUXzNzqa/12lyIcoxXf+v371J3fWkwDQYJKoZIhvcNAQEL +BQAwgYIxCzAJBgNVBAYTAkZSMREwDwYDVQQIDAhOb3JtYW5keTENMAsGA1UEBwwE +Q2FlbjERMA8GA1UECgwIRnJhbWluZm8xFTATBgNVBAMMDFNhY2hhIEdVRVJJTjEn +MCUGCSqGSIb3DQEJARYYc2FjaGEuZ3VlcmluQHN1cGluZm8uY29tMB4XDTI1MDcy +MTEzMzgwMVoXDTI2MDcyMTEzMzgwMVowgYIxCzAJBgNVBAYTAkZSMREwDwYDVQQI +DAhOb3JtYW5keTENMAsGA1UEBwwEQ2FlbjERMA8GA1UECgwIRnJhbWluZm8xFTAT +BgNVBAMMDFNhY2hhIEdVRVJJTjEnMCUGCSqGSIb3DQEJARYYc2FjaGEuZ3Vlcmlu +QHN1cGluZm8uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvLg7 +nR0UqRZ7UadhI8jrUjRMV1SZj+ljxEnV6tDOVMsvafsym1MhDZHb+cyv8769yqPv +CKtIOQKhMH0PkSqau8szNlF1Tg/1UzT+Mkd4zvLvGE5+aW/oDMg7E2LMJZuCyO4X +9SzWDVA5+b1QFIw6vvb3mCkUOtVDkOFreBBwryZKcWJ0b8o1hT60oB2wr18P14j0 +0C2/TmHMtim0o4r3gKGvpatqt1fXJo0UlYOwTvfMrYhu2VHqsQ2qP7ocazXEWt5u +Alf1vNPkAenF0ZV/2UiaL41Q8GMoV1enDP7k7/qfgXvta/hOeYnLtmv5Qpi4XiWz +xKjSukTUD2sRtSX+YQIDAQABo1MwUTAdBgNVHQ4EFgQUVj9KtmjLFy4xWzkNI9Kq +NAxNsfUwHwYDVR0jBBgwFoAUVj9KtmjLFy4xWzkNI9KqNAxNsfUwDwYDVR0TAQH/ +BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAGpUPMoF/ASIqOOfX5anDtaPvnslj +DuEVbU7Uoyc4EuSD343DPV7iMUKoFvVLPxJJqMLhSo3aEGJyqOF6q3fvq/vX2VE7 +9MhwS1t2DBGb5foWRosnT1EuqFU1/S0RJ/Y+GNcoY1PrUES4+r7zqqJJjwKOzneV +ktUVCdKl0C1gtw6W4Ajxse3fm9DNLxnZZXbyNqn+KbI8QdO0xSEl+gyiycvPu/NT ++EesdlFoYjO7gdA8dXkmu+Z7R61MYhE9Zvyop5KVMqgU8/Ym04UUWjWQYWWLMyuu +bxngE4XNEI5fhg+0e/I25xJJ9wVV/ZNAF4+XOylHz/CmU8V/SPKuGXBGHg== +-----END CERTIFICATE----- diff --git a/nginx/nginx-selfsigned.key b/nginx/nginx-selfsigned.key new file mode 100644 index 0000000..0ac5345 --- /dev/null +++ b/nginx/nginx-selfsigned.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC8uDudHRSpFntR +p2EjyOtSNExXVJmP6WPESdXq0M5Uyy9p+zKbUyENkdv5zK/zvr3Ko+8Iq0g5AqEw +fQ+RKpq7yzM2UXVOD/VTNP4yR3jO8u8YTn5pb+gMyDsTYswlm4LI7hf1LNYNUDn5 +vVAUjDq+9veYKRQ61UOQ4Wt4EHCvJkpxYnRvyjWFPrSgHbCvXw/XiPTQLb9OYcy2 +KbSjiveAoa+lq2q3V9cmjRSVg7BO98ytiG7ZUeqxDao/uhxrNcRa3m4CV/W80+QB +6cXRlX/ZSJovjVDwYyhXV6cM/uTv+p+Be+1r+E55icu2a/lCmLheJbPEqNK6RNQP +axG1Jf5hAgMBAAECggEAAj+hmDRx6jafAAf67sqi3ZgEGEmBkXNeeLGBTPc/qhxd +ip6krTELnz8TE26RG5LYXzslasUNrn42nIImvBT5ZkcjcosKpWfEqQEAjc1PQovC +9eyKnKfw4TpUvvmiveT4T98vCYEOOqHE0/WTdlOoaBY/f+sZKQYu+1NMtAjFcg2r +vVqwsZb5vGyh7CKmIHZnz3UP8P+7G5digiNRne18pGnE2oTnSoQ3/QIqUWBs69DS +k5ew+CSyTLiUFFnMnE4adwyg6wAud5fBlzowF6UF2agToX7pxEaGxGvpBGG034kk +1UXaB/d5YwcsBeH+x5cNMLKZy4zqjoxEEW31Q466NQKBgQDtKk1R/slpTpRqvtBT +NC7InvjcCBXkXttylQHJRN9glqhmflEOe8iMW1/qRwBPlQgK1wq/sXySanVv2+gO +JGq8XNRLbHyG3YRyshdnJHP1HoWQE0uedD/rfqgkNaW5S1IvHrD7Q7tOvCrF+KbS +612pmIgNVzn+inafDXPhMZc4pQKBgQDLtQGAu2eK58ewndyL8+7+VHZSTEtKpt+h +G/U/ccv+6NGqdxI5YUkrJ7k6vV81VeRMvmN9uUS/i8znORFQmm6noRVkhXytwW5B +HXq2co4WRvv9b/XqcqS0GSYVPJ1u4YNH6lvtDZ4UWPyBzYl700GdHrGa+erT44yL +tnibHx9GDQKBgFW1J+Qt85O+9hvtgVPQU+fkq4K42VCCh0PNXavi2+cICyufEqPt +T/iJPQxpRE9+SD3CoPvNpHs1ReN60U3rEzenRIFNX2NNwoPAoHyBy/YVZac/keBd +mov8Zb9QM+fWtIiaytLDE3nMvph017T5ogucN+66SxcV6vBn6CzFwySRAoGAcUf2 +Tv1ohkGAtgIDrLx5cmvL5NZSpHAKOpDOoHqLA/W66v4OX2RviRUtF7JJ6OIb9GWH +9Fl8Fr0KtKbyrw1CbevRdrYY8JN52bIoFJ+9zjupVHXXnookd5boq7SqpAe6ttpo +RnplJ1GZEiIXy4lemp6AC/vhD/YhqWxOw4zaGl0CgYBslhqVt5F0EHf94p7NrCuY +hNHKHaNaULYP0VXKefQamt/ssDuktqb6DNSIvx2rbbB5+33nTlLTya67gimY1lKt +WeNB33/yBkCjfSP/J5UDD9mE/oPLt3vAOkOUgMCfp2IpC2Wez1QGqLHS260zpotP +VpgalHuSWtn8D4nO2pk1hg== +-----END PRIVATE KEY-----