Skip to content

The great and venerable “Pong“ game, in a modern single-page app!

License

Notifications You must be signed in to change notification settings

jmz-mzr/transcendence

Repository files navigation

Transcendence


Transcendence Logo: 'Pong' written with purple flashing neon letters

Table of Contents

Overview

Transcendence revives the great and venerable “Pong“ game, in a modern single-page application.

Enjoy real-time matches & chat within a stunning user interface, take over the world with your arrow-key-press skills, and achieve the mythical perfect stats! 🏓

Written with love in TypeScript, using NestJS, PostgreSQL, Prisma ORM, Next.JS, React, and Axios with ReactQuery.


Key Features

  • Real-time gameplay with smooth performance via Socket.IO's WebSockets
  • User profiles with customizable usernames and avatars
  • Local and Online modes
  • Matchmaking algorithm for competitive games
  • Match history and player stats tracking
  • Secret achievements for outstanding players
  • Challenge your friends, or watch their game in real-time
  • Real-time chat with public, private, and password-protected channels
  • Advanced user & channel management features
  • Block, kick, ban or mute others
  • Dockerized environment for security and efficiency
  • Two-factor authentication
  • Strict CORS policy and class-validators for secure API communication
  • OAuth sign-in through the 42 network


Transcendence.mp4

Usage

# Development mode
./start-dev.sh

# Production mode
./start-prod.sh

They both call this script to create the .env file if you haven’t, and ensure it is complete. If needed, they create strong passwords using OpenSSL.
They also make sure Husky and Lint-Staged are set to lint the files and enforce code quality before every commit.

The major differences in dev mode are the ReactQueryDevTools, and the continuous incremental compilation when a file change is detected.

To make the development easier and secure, the prima_migrate_dev.sh script records your database migrations in the mounted prisma folder through the Docker container.

Control your paddle in games with the Up / Down arrow keys (or W / S in local two-player mode). Chat, challenge friends, and climb the leaderboard to achieve Pong mastery!


A word on Docker & Security

Both the front and back Docker images leverage multi-stage builds, making them smaller and more secure.

They run as custom unprivileged users, and use Docker Secrets through the docker-compose files to withdraw sensitive informations from the images history, the containers environment, and the docker inspect <...> command.

They use dumb-init to avoid node running as PID 1, and ensure proper signal forwarding & zombie processes reaping.
Also, custom & secure healthchecks report the containers’ status - no need of additional tools!

While we're at it:

  • A strict CORS policy and class-validators with a whitelist-only property secure the RESTful API
  • Channel passwords are stored hashed using the bcrypt library
  • For the DB, Prisma takes care of the requests to properly avoid SQL injections
  • A secure 2FA login can be enabled with your favorite authenticator app!

Login & Configuration

To build and use the app, you need a complete .env file alongside the .env.example. The script called on startup will help you with it (see Usage).

Register a new app on 42’s API, providing this redirect URI: http://<YOUR_SERVER_IP>:3000/auth/42/callback, where YOUR_SERVER_IP is the network address of your machine hosting the app (or localhost for a local version only). Copy the APP_ID and APP_SECRET into the .env file, and give secret values to other empty variables.

Users sign into the app with the OAuth system of the 42 school. There are currently no other connection method. If you’d like to see it coming, as the saying goes: “ask and you shall receive“!

If you are not part of the 42 network, the video will give you a good idea of the project. And for testing purposes, it’s easy to implement another passport method with username / password combination, or using sign-in with Google.


Contributing

Interested in adding features or fixing bugs? Feel free to fork the repository, make changes, and submit a pull request!

And of course the last part of this manual: Have fun! 🥳