diff --git a/docker-compose.yaml b/docker-compose.yaml
index a4b92e3..1662c82 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -1,22 +1,18 @@
services:
front:
build: ./traque-front
+ restart: always
+
+ reverse_proxy:
+ build: ./proxy
ports:
- - "3000:3000"
- environment:
- - NEXT_PUBLIC_SOCKET_HOST = 'quentinrsl.com'
- - NEXT_PUBLIC_SOCKET_PORT = 3001
+ - "3000:443"
+ volumes:
+ - ./traque-back/ssl:/etc/nginx/ssl:ro
+ restart: always
back:
build: ./traque-back
ports:
- "3001:3001"
- environment:
- - HOST = 'quentinrsl.com'
- - PORT = 3001
- - SSL_KEY = "/etc/letsencrypt/live/quentinrsl.com/privkey.pem"
- - SSL_CERT = "/etc/letsencrypt/live/quentinrsl.com/cert.pem"
- - ADMIN_PASSWORD = 'admin'
- - MAX_PENALTIES = 3
- - ALLOWED_TIME_OUT_OF_ZONE_IN_MINUTES = 10
- - ALLOWED_TIME_BETWEEN_POSITION_UPDATE_IN_MINUTES = 10
\ No newline at end of file
+ restart: always
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..3877974
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,6 @@
+{
+ "name": "traque",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {}
+}
diff --git a/proxy/Dockerfile b/proxy/Dockerfile
new file mode 100644
index 0000000..3772885
--- /dev/null
+++ b/proxy/Dockerfile
@@ -0,0 +1,8 @@
+# nginx/Dockerfile
+
+FROM nginx:1.23.3-alpine
+
+COPY nginx.conf /etc/nginx/nginx.conf
+
+EXPOSE 80
+EXPOSE 443
diff --git a/proxy/nginx.conf b/proxy/nginx.conf
new file mode 100644
index 0000000..eb5699f
--- /dev/null
+++ b/proxy/nginx.conf
@@ -0,0 +1,42 @@
+# nginx/nginx.conf
+
+events {
+}
+
+http {
+ upstream front {
+ server front:3000;
+ }
+ server {
+ # Redirect HTTP requests to HTTPS.
+ listen 80;
+ server_name localhost;
+ root /srv/public;
+ return 301 https://$host$request_uri;
+ }
+
+ server {
+ listen 443 ssl;
+
+ server_name localhost;
+ root /srv/public;
+ server_tokens off;
+
+ ssl_certificate /etc/nginx/ssl/cert.pem;
+ ssl_certificate_key /etc/nginx/ssl/privkey.pem;
+
+ location / {
+ try_files $uri $uri/ @front;
+ }
+
+ location @front {
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto https;
+ proxy_set_header X-Forwarded-Ssl on;
+ proxy_set_header Host $http_host;
+ proxy_redirect off;
+ proxy_pass http://front;
+ proxy_cookie_path / "/; HTTPOnly; Secure";
+ }
+ }
+}
\ No newline at end of file
diff --git a/readme.md b/readme.md
index 62e3fff..49525f3 100644
--- a/readme.md
+++ b/readme.md
@@ -4,7 +4,7 @@
Edit the .env file in traque-front and add specify the following values:
```
NEXT_PUBLIC_SOCKET_HOST = 'example.com'
-NEXT_PUBLIC_SOCKET_PORT = 3000
+NEXT_PUBLIC_SOCKET_PORT = 3001
```
Where NEXT_PUBLIC_SOCKET_HOST is the host of the socket server and NEXT_PUBLIC_SOCKET_PORT is the port of the socket server.
### Back end configuration
@@ -25,6 +25,8 @@ MAX_PENALTIES is the maximum number of penalties a user can have before loosing
ALLOWED_TIME_OUT_OF_ZONE_IN_MINUTES is the time a user can be out of the zone before being penalized.
ALLOWED_TIME_BETWEEN_POSITION_UPDATE_IN_MINUTES is the maximum amount of time a user can wait before updating their position, after this period they will recieve a pennalty.
+Note : make sure PORT and NEXT_PUBLIC_SOCKET_PORT are the same
+
### Running the project
#### Front end
To run the front end, navigate to the traque-front directory and run the following commands:
@@ -43,5 +45,9 @@ Then navigate to the host and port specified in the .env file to access the appl
https://example.com:3000
```
-## Depployment
+## Deployment
+
+### SSL certificates
+Put your certificate and private key in the traque-back/ssl folder. They need to be named `cert.pem` and `privkey.pem`.
+You can then depploy the docker application with `docker compose up`
diff --git a/traque-back/.gitignore b/traque-back/.gitignore
index 410b041..800f3e6 100644
--- a/traque-back/.gitignore
+++ b/traque-back/.gitignore
@@ -1,8 +1,6 @@
uploads/*
#https dev certificates
-csr.pem
-key.pem
-server.crt
+*.pem
# Logs
logs
*.log
diff --git a/traque-back/admin_socket.js b/traque-back/admin_socket.js
index 3be25d6..93c7b2d 100644
--- a/traque-back/admin_socket.js
+++ b/traque-back/admin_socket.js
@@ -122,6 +122,7 @@ export function initAdminSocketHandler() {
}
if (game.reorderTeams(newOrder)) {
secureAdminBroadcast("teams", game.teams);
+ game.teams.forEach(t => sendUpdatedTeamInformations(t.id))
} else {
socket.emit("error", "Error reordering teams");
}
diff --git a/traque-back/game.js b/traque-back/game.js
index 7c381cf..411f3da 100644
--- a/traque-back/game.js
+++ b/traque-back/game.js
@@ -24,6 +24,7 @@ export default class Game {
}
//The game has started
if (newState == GameState.PLAYING) {
+ penaltyController.start();
if (!this.zone.ready()) {
return false;
}
diff --git a/traque-back/index.js b/traque-back/index.js
index 2607865..88b2a4d 100644
--- a/traque-back/index.js
+++ b/traque-back/index.js
@@ -49,7 +49,6 @@ function onUpdateZone(zone) {
export const game = new Game(onUpdateZone, onUpdateNewZone);
export const penaltyController = new PenaltyController();
-penaltyController.init()
initAdminSocketHandler();
diff --git a/traque-back/penalty_controller.js b/traque-back/penalty_controller.js
index 843e1c5..926d3c2 100644
--- a/traque-back/penalty_controller.js
+++ b/traque-back/penalty_controller.js
@@ -14,7 +14,7 @@ export class PenaltyController {
this.checkIntervalId = null;
}
- init() {
+ start() {
this.outOfBoundsSince = {};
if(this.checkIntervalId) {
clearInterval(this.checkIntervalId)
@@ -62,6 +62,7 @@ export class PenaltyController {
}
watchZone() {
+ console.log("watching zone")
this.game.teams.forEach((team) => {
if (team.captured) { return }
//All the informations are not ready yet
@@ -69,9 +70,11 @@ export class PenaltyController {
return;
}
if (!isInCircle({lat: team.currentLocation[0], lng: team.currentLocation[1]}, this.game.zone.currentZone.center, this.game.zone.currentZone.radius)) {
+ console.log("tema " + team.name + " out of zone")
//The team was not previously out of the zone
if (!this.outOfBoundsSince[team.id]) {
this.outOfBoundsSince[team.id] = new Date();
+ console.log("tema " + team.name + " warned")
teamBroadcast(team.id, "warning", `You left the zone, you have ${process.env.ALLOWED_TIME_OUT_OF_ZONE_IN_MINUTES} minutes to get back in the marked area.`)
} else {
if (new Date() - this.outOfBoundsSince[team.id] > process.env.ALLOWED_TIME_OUT_OF_ZONE_IN_MINUTES * 60 * 1000) {
diff --git a/traque-front/Dockerfile b/traque-front/Dockerfile
new file mode 100644
index 0000000..3d1b852
--- /dev/null
+++ b/traque-front/Dockerfile
@@ -0,0 +1,67 @@
+FROM node:18-alpine AS base
+
+# Install dependencies only when needed
+FROM base AS deps
+# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
+RUN apk add --no-cache libc6-compat
+WORKDIR /app
+
+# Install dependencies based on the preferred package manager
+COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
+RUN \
+ if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
+ elif [ -f package-lock.json ]; then npm ci; \
+ elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
+ else echo "Lockfile not found." && exit 1; \
+ fi
+
+
+# Rebuild the source code only when needed
+FROM base AS builder
+WORKDIR /app
+COPY --from=deps /app/node_modules ./node_modules
+COPY . .
+
+# Next.js collects completely anonymous telemetry data about general usage.
+# Learn more here: https://nextjs.org/telemetry
+# Uncomment the following line in case you want to disable telemetry during the build.
+# ENV NEXT_TELEMETRY_DISABLED 1
+
+RUN \
+ if [ -f yarn.lock ]; then yarn run build; \
+ elif [ -f package-lock.json ]; then npm run build; \
+ elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
+ else echo "Lockfile not found." && exit 1; \
+ fi
+
+# Production image, copy all the files and run next
+FROM base AS runner
+WORKDIR /app
+
+ENV NODE_ENV production
+# Uncomment the following line in case you want to disable telemetry during runtime.
+# ENV NEXT_TELEMETRY_DISABLED 1
+
+RUN addgroup --system --gid 1001 nodejs
+RUN adduser --system --uid 1001 nextjs
+
+COPY --from=builder /app/public ./public
+
+# Set the correct permission for prerender cache
+RUN mkdir .next
+RUN chown nextjs:nodejs .next
+
+# Automatically leverage output traces to reduce image size
+# https://nextjs.org/docs/advanced-features/output-file-tracing
+COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
+COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
+
+USER nextjs
+
+EXPOSE 3000
+
+ENV PORT 3000
+
+# server.js is created by next build from the standalone output
+# https://nextjs.org/docs/pages/api-reference/next-config-js/output
+CMD HOSTNAME="0.0.0.0" node server.js
diff --git a/traque-front/components/team/actionDrawer.jsx b/traque-front/components/team/actionDrawer.jsx
index 13c00a3..ef96c2b 100644
--- a/traque-front/components/team/actionDrawer.jsx
+++ b/traque-front/components/team/actionDrawer.jsx
@@ -4,6 +4,7 @@ import BlueButton, { GreenButton, RedButton } from "../util/button";
import TextInput from "../util/textInput";
import { useTeamConnexion } from "@/context/teamConnexionContext";
import { EnemyTeamModal } from "./enemyTeamModal";
+import Image from "next/image";
export default function ActionDrawer() {
const [visible, setVisible] = useState(false);
@@ -29,10 +30,10 @@ export default function ActionDrawer() {
return (