diff options
| author | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:08:27 +0200 |
|---|---|---|
| committer | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:08:27 +0200 |
| commit | c9b6b9a5ca082fe7c1b6f58d7713f785a9eb6a5c (patch) | |
| tree | 3e4f42f93c7ae89a364e4d51fff6e5cec4e55fa9 /rushs/eplace/server | |
add: graphs et rushs
Diffstat (limited to 'rushs/eplace/server')
| -rw-r--r-- | rushs/eplace/server/.env | 36 | ||||
| -rw-r--r-- | rushs/eplace/server/config/default-canvas-250.txt | 1 | ||||
| -rw-r--r-- | rushs/eplace/server/config/default-canvas-50.txt | bin | 0 -> 1563 bytes | |||
| -rw-r--r-- | rushs/eplace/server/config/rate-limits.config.json | 54 | ||||
| -rw-r--r-- | rushs/eplace/server/config/rooms.config.json | 39 | ||||
| -rw-r--r-- | rushs/eplace/server/docker-compose.yml | 56 | ||||
| -rw-r--r-- | rushs/eplace/server/openapi/openapi.json | 5064 |
7 files changed, 5250 insertions, 0 deletions
diff --git a/rushs/eplace/server/.env b/rushs/eplace/server/.env new file mode 100644 index 0000000..7ff72e7 --- /dev/null +++ b/rushs/eplace/server/.env @@ -0,0 +1,36 @@ +# Environment variables declared in this file are automatically made available to Prisma. +# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema + +# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB. +# See the documentation for all the connection string options: https://pris.ly/d/connection-strings + +SERVER_PORT=3333 +WSS_PORT=3334 + +POSTGRES_USER="postgres" +POSTGRES_PASSWORD="postgres" +POSTGRES_HOST="postgres" +POSTGRES_PORT=5432 +POSTGRES_DB="eplace" +POSTGRES_SCHEMA="public" +DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?schema=${POSTGRES_SCHEMA}" + + +REDIS_HOST="redis" +REDIS_PORT=6379 + +PUBLIC_API_URL="http://localhost:3333/api" +JWKS_URI="https://cri.epita.fr/jwks" +# DO NOT ERASE THIS UID, IT IS USE AS DEFAULT USER TO SETUP ROOMs, PIXELS +# CHECK README FOR MORE DETAILS +# You can add more admin uids by separating them with a comma +# Example: 9361,9362,9363 +ADMIN_UID_LIST="9361" + + +RATE_LIMITS_CONFIG_PATH="./config/rate-limits.config.json" +ROOMS_CONFIG_PATH="./config/rooms.config.json" + +DISABLE_ADMIN_PREVILEGES="true" +DISABLE_AUTH="false" +DISABLE_RATE_LIMITING="false" diff --git a/rushs/eplace/server/config/default-canvas-250.txt b/rushs/eplace/server/config/default-canvas-250.txt new file mode 100644 index 0000000..9e52292 --- /dev/null +++ b/rushs/eplace/server/config/default-canvas-250.txt @@ -0,0 +1 @@ +B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!BcB„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!BˆcÆ0„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„CÆ1ŒaB„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!BcÆ1ŒcÆ!!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!†1ŒcÆ1ŒcÆ1ŒcÆ!!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„"Æ1ŒcÆ1ŒcÆ1ŒcÆ1Œc‚„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„CÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒcÆ1ŒaB„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!BˆcÆ1ŒcÆ1Œb‚„"„1ŒcÆ1ŒcÆ „!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!BˆcÆ1ŒcÆ „!B„!B„!D1ŒcÆ1ŒcB„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!BˆcÆ1Œc‚„!B„C„!B„!Æ1ŒcÆ0„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!BˆcÆ1ŒcB„!B„#Æ1ˆ!B„!BˆcÆ1ŒcB„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„cÆ1ŒbB„!B„!Æ1ŒcB„!B„!F1ŒcÆ „!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„CÆ1ŒaB„!B„!Æ1ŒcÆ„!B„!B„CÆ1ŒaB„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„#Æ1ŒaB„!B„!B1ŒaÆ1ˆ!B„!B„!D1ŒcÄ„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„"Æ1ŒbB„!B„!BŒcBŒcB„!B„!B„cÆ1Œ!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!Æ1ŒbB„!B„!B„!„c„!B„!B„!F1Œc‚„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!Æ1ŒcB„!B„!B„!B„!Æ„!B„!B„!BˆcÆ1„!B„!B„!BˆBB„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!BˆcÆ1ŒcB„!B„!B„!B„!B„!B„!B„!B„!Æ1ŒcÆ0„!B„!BˆcÆ„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„cÆ1ŒcB„!B„!B„!B„!B„!B„!B„!B„!BŒcÆ1ŒbB„!BˆcÆ1Œ!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„"Æ1Œc„!BŒcÄ„!B„!B„!B„!B„!B„!B„"Æ1Œc„!B„cÆ1ŒcB„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!Æ1ŒcÄ„!B„cÆ1Œ!B„!B„!B„!B„!B1„!B„!B1ŒcÆ1!B„#Æ1ŒcÆ„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B1ŒcÆ „!B„"Æ1ŒcB„!B„!B„!B„!F1ŒcB„!B„cÆ1ŒAB„"Æ1ŒaÆ1!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!B„!BŒcÆ1!B„!Æ1ˆCÆ„!B„!B„!B„!B1ŒcÆ0„!B„!Æ1ŒcB„!Æ1Œb diff --git a/rushs/eplace/server/config/default-canvas-50.txt b/rushs/eplace/server/config/default-canvas-50.txt Binary files differnew file mode 100644 index 0000000..ff61da9 --- /dev/null +++ b/rushs/eplace/server/config/default-canvas-50.txt diff --git a/rushs/eplace/server/config/rate-limits.config.json b/rushs/eplace/server/config/rate-limits.config.json new file mode 100644 index 0000000..aeb1cd2 --- /dev/null +++ b/rushs/eplace/server/config/rate-limits.config.json @@ -0,0 +1,54 @@ +{ + "testsLimiter": { + "limit": 10, + "interval": 1 + }, + "getCanvasLimiter": { + "limit": 10, + "interval": 1 + }, + "getPixelLimiter": { + "limit": 10, + "interval": 1 + }, + "placePixelLimiter": { + "limit": 1, + "interval": 30 + }, + "getRoomsLimiter": { + "limit": 10, + "interval": 1 + }, + "getRoomConfigLimiter": { + "limit": 10, + "interval": 1 + }, + "createRoomLimiter": { + "limit": 1, + "interval": 300 + }, + "updateRoomLimiter": { + "limit": 1, + "interval": 1 + }, + "deleteRoomLimiter": { + "limit": 2, + "interval": 1 + }, + "getStudentLimiter": { + "limit": 10, + "interval": 1 + }, + "updateStudentLimiter": { + "limit": 1, + "interval": 1 + }, + "sendMessageLimiter": { + "limit": 1, + "interval": 1 + }, + "reportRoomLimiter": { + "limit": 1, + "interval": 5 + } +} diff --git a/rushs/eplace/server/config/rooms.config.json b/rushs/eplace/server/config/rooms.config.json new file mode 100644 index 0000000..b50080e --- /dev/null +++ b/rushs/eplace/server/config/rooms.config.json @@ -0,0 +1,39 @@ +{ + "maxRoomsCreatedPerUser": 3, + "rooms": { + "default": { + "metadata": { + "canvasDimensions": 50 + }, + "settings": { + "roomColors": "#ffffff,#d4d7d9,#898d90,#515252,#000000,#fe4500,#fea800,#fed634,#01a268,#7eed56,#2350a4,#3690ea,#51e9f4,#811f9f,#b44bc0,#ff99aa,#9c6925", + "defaultCanvas": "config/default-canvas-50.txt" + } + }, + "epi-place": { + "metadata": { + "name": "epi/place", + "slug": "epi-place", + "description": "Le Roi de la malice est passé par là ", + "canvasDimensions": 250, + "iconURL": "https://media.tenor.com/XUHq8pN_maQAAAAi/puffer-fish-fish.gif", + "isPublic": true + }, + "settings": { + "roomColors": "#ffffff,#d4d7d9,#898d90,#515252,#6c001a,#be0039,#fe4500,#fea800,#fed634,#fff8b8,#01a268,#00cc78,#7eed56,#02756f,#019eaa,#00ccbf,#2350a4,#3690ea,#51e9f4,#493ac1,#6a5cff,#94b3ff,#811f9f,#b44bc0,#e4aaff,#de107f,#ff3981,#ff99aa,#6d482f,#9c6925,#ffb470,#000000", + "defaultCanvas": "config/default-canvas-250.txt" + } + }, + "test": { + "metadata": { + "name": "Test Room", + "description": "A room small enough to test things out", + "canvasDimensions": 10, + "isPublic": true + }, + "settings": { + "roomColors": "#ffffff,#d4d7d9,#898d90,#515252,#000000,#fe4500,#fea800,#fed634,#01a268,#7eed56,#2350a4,#3690ea,#51e9f4,#811f9f,#b44bc0,#ff99aa,#9c6925" + } + } + } +}
\ No newline at end of file diff --git a/rushs/eplace/server/docker-compose.yml b/rushs/eplace/server/docker-compose.yml new file mode 100644 index 0000000..f0419b9 --- /dev/null +++ b/rushs/eplace/server/docker-compose.yml @@ -0,0 +1,56 @@ +version: '3.9' +services: + postgres: + image: registry.cri.epita.fr/ing/assistants/public/registry/postgres:15.2-alpine + container_name: postgres + restart: always + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: eplace + expose: + - 5432 + volumes: + - postgres-data:/var/lib/postgresql/data + # Proper docker-compose would use named networks + # networks: + # - postgres-network + redis: + image: registry.cri.epita.fr/ing/assistants/public/registry/redis:7.0.9-alpine + container_name: redis + restart: always + expose: + - 6379 + volumes: + - redis-data:/data + # Proper docker-compose would use named networks + # networks: + # - redis-network + eplace: + image: registry.cri.epita.fr/ing/assistants/public/registry/eplace:latest + container_name: eplace + restart: always + environment: + NODE_ENV: production + volumes: + - ./config:/usr/src/app/config + - type: 'bind' + source: './.env' + target: '/usr/src/app/.env' + ports: + - 3000:3000 + - 3333:3333 + # Proper docker-compose would use named networks + # networks: + # - postgres-network + # - redis-network + depends_on: + - postgres + - redis +volumes: + postgres-data: + redis-data: + # Proper docker-compose would use named networks + # networks: + # postgres-network: + # redis-network: diff --git a/rushs/eplace/server/openapi/openapi.json b/rushs/eplace/server/openapi/openapi.json new file mode 100644 index 0000000..4f0dd77 --- /dev/null +++ b/rushs/eplace/server/openapi/openapi.json @@ -0,0 +1,5064 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "E/PLACE API", + "description": "Publicly available API for E/PLACE", + "version": "1.0.0" + }, + "servers": [ + { + "url": "http://localhost:3333/api" + } + ], + "paths": { + "/status": { + "get": { + "operationId": "status", + "summary": "Get the status of the API", + "description": "Get the status of the API", + "tags": [ + "Misc" + ], + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/reload-config": { + "put": { + "operationId": "reloadConfig", + "summary": "Reload the config", + "description": "Reload the config", + "tags": [ + "Admin" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "reloadLocally": { + "type": "boolean" + } + }, + "required": [ + "reloadLocally" + ], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/update-event/{slug}": { + "post": { + "operationId": "changeEvent", + "summary": "Update the event of a room", + "description": "Update the event of a room", + "tags": [ + "Admin" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "event": { + "type": "string", + "enum": [ + null, + "EVEN_OR_ODD", + "EVEN_OR_ODD_DEFAULT_CANVAS", + "INITIAL_DEFAULT_CANVAS", + "RANDOM", + "GROUPS", + "VOID" + ], + "nullable": true, + "default": null + }, + "radius": { + "type": "number" + } + }, + "additionalProperties": false + } + } + } + }, + "parameters": [ + { + "name": "slug", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "additionalProperties": false + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/update-rate-limits/{slug}": { + "post": { + "operationId": "updateRateLimits", + "summary": "Update the rate limits", + "description": "Update the rate limits for the API", + "tags": [ + "Admin" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "rateLimitName": { + "type": "string", + "enum": [ + "testsLimiter", + "getCanvasLimiter", + "getPixelLimiter", + "placePixelLimiter", + "getRoomsLimiter", + "getRoomConfigLimiter", + "createRoomLimiter", + "updateRoomLimiter", + "deleteRoomLimiter", + "getStudentLimiter", + "updateStudentLimiter", + "sendMessageLimiter", + "reportRoomLimiter" + ] + }, + "limit": { + "type": "number", + "minimum": 1 + }, + "interval": { + "type": "number", + "minimum": 0 + } + }, + "required": [ + "rateLimitName", + "limit", + "interval" + ], + "additionalProperties": false + } + } + } + }, + "parameters": [ + { + "name": "slug", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/tests/error": { + "get": { + "operationId": "tests-error", + "summary": "Return a server error", + "description": "Always return 500 Internal Server Error", + "tags": [ + "Tests" + ], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/tests/invalid-token": { + "post": { + "operationId": "tests-invalid-token", + "summary": "Return an invalid token error", + "description": "Always return 401 Unauthorized \"Invalid token\"", + "tags": [ + "Tests" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": {}, + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/tests/expired-token": { + "post": { + "operationId": "tests-expired-token", + "summary": "Return a token expired error", + "description": "Always return 401 Unauthorized \"Token expired\"", + "tags": [ + "Tests" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": {}, + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/tests/too-many-requests": { + "get": { + "operationId": "tests-too-many-requests", + "summary": "Return a too many requests error", + "description": "Always return 429 Too Many Requests", + "tags": [ + "Tests" + ], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/students": { + "get": { + "operationId": "students-getStudents", + "summary": "Get all students", + "description": "Get all students", + "tags": [ + "Admin" + ], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "uid": { + "type": "number" + }, + "login": { + "type": "string" + } + }, + "required": [ + "uid", + "login" + ], + "additionalProperties": false + }, + "description": "An array of students with their UID and login" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/students/{id}": { + "get": { + "operationId": "students-getStudent", + "summary": "Get a student by UID or login", + "description": "Get a student by UID or login", + "tags": [ + "Students (Mandatory)" + ], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The UID or login of the student" + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "groups": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ADMIN", + "YAKA", + "ING1_LYON", + "ING1_PARIS", + "ING1_RENNES", + "ING1_STRASBOURG", + "ING1_TOULOUSE" + ] + } + }, + "uid": { + "type": "number" + }, + "login": { + "type": "string" + }, + "avatarURL": { + "type": "string", + "nullable": true + }, + "quote": { + "type": "string", + "nullable": true + }, + "currentRoomSlug": { + "type": "string", + "nullable": true + }, + "banUntil": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "groups", + "uid", + "login", + "avatarURL", + "quote", + "currentRoomSlug", + "banUntil" + ], + "additionalProperties": false + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + }, + "put": { + "operationId": "students-updateStudent", + "summary": "Update a student by UID or login", + "description": "Update a student by UID or login", + "tags": [ + "Students (Optional)" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "avatarURL": { + "anyOf": [ + { + "type": "string" + }, + { + "enum": [ + "null" + ], + "nullable": true + } + ], + "description": "The URL of your avatar" + }, + "quote": { + "anyOf": [ + { + "type": "string" + }, + { + "enum": [ + "null" + ], + "nullable": true + } + ], + "description": "Your quote" + } + }, + "additionalProperties": false + } + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Your student UID or login" + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "groups": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ADMIN", + "YAKA", + "ING1_LYON", + "ING1_PARIS", + "ING1_RENNES", + "ING1_STRASBOURG", + "ING1_TOULOUSE" + ] + } + }, + "uid": { + "type": "number" + }, + "login": { + "type": "string" + }, + "avatarURL": { + "type": "string", + "nullable": true + }, + "quote": { + "type": "string", + "nullable": true + }, + "currentRoomSlug": { + "type": "string", + "nullable": true + }, + "banUntil": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "groups", + "uid", + "login", + "avatarURL", + "quote", + "currentRoomSlug", + "banUntil" + ], + "additionalProperties": false + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/students/{id}/ban": { + "post": { + "operationId": "students-banStudent", + "summary": "Ban a student by UID or login", + "description": "Ban a student by UID or by login. If no date is provided, the student will be unbanned.", + "tags": [ + "Admin" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "banUntil": { + "type": "string", + "description": "The date until the student is banned" + }, + "reason": { + "type": "string", + "description": "The reason of the ban" + } + }, + "additionalProperties": false + } + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The UID or login of the student" + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "groups": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ADMIN", + "YAKA", + "ING1_LYON", + "ING1_PARIS", + "ING1_RENNES", + "ING1_STRASBOURG", + "ING1_TOULOUSE" + ] + } + }, + "uid": { + "type": "number" + }, + "login": { + "type": "string" + }, + "avatarURL": { + "type": "string", + "nullable": true + }, + "quote": { + "type": "string", + "nullable": true + }, + "currentRoomSlug": { + "type": "string", + "nullable": true + }, + "banUntil": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "groups", + "uid", + "login", + "avatarURL", + "quote", + "currentRoomSlug", + "banUntil" + ], + "additionalProperties": false + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/rooms": { + "get": { + "operationId": "rooms-getRooms", + "summary": "Get all rooms", + "description": "List all the rooms available to the student", + "tags": [ + "Rooms (Optional)" + ], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "List of available rooms", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Room" + } + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + }, + "post": { + "operationId": "rooms-createRoom", + "summary": "Create a room", + "description": "Create a new room", + "tags": [ + "Rooms (Optional)" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the room" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "enum": [ + "null" + ], + "nullable": true + } + ], + "description": "The description of the room" + }, + "iconURL": { + "anyOf": [ + { + "type": "string" + }, + { + "enum": [ + "null" + ], + "nullable": true + } + ], + "description": "The URL of the room's icon" + }, + "isPublic": { + "type": "boolean", + "description": "Whether the room is public or not. Defaults to false" + }, + "studentsWhitelist": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "description": "The list of students allowed to join the room. Effective only if isPublic is false. Accepts both UIDs and logins. Defaults to an empty array" + }, + "studentsBlacklist": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "description": "The list of students not allowed to join the room. Effective only if isPublic is true. Accepts both UIDs and logins. Defaults to an empty array" + } + }, + "required": [ + "name" + ], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "slug": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "nullable": true + }, + "iconURL": { + "type": "string", + "nullable": true + }, + "canvasDimensions": { + "type": "number" + }, + "isPublic": { + "type": "boolean" + }, + "studentsWhitelist": { + "type": "array", + "items": { + "type": "number" + } + }, + "studentsBlacklist": { + "type": "array", + "items": { + "type": "number" + } + }, + "ownerUid": { + "type": "number" + }, + "password": { + "type": "string", + "nullable": true + }, + "hidden": { + "type": "boolean" + }, + "deleted": { + "type": "boolean" + }, + "createdAt": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "slug", + "name", + "description", + "iconURL", + "canvasDimensions", + "isPublic", + "studentsWhitelist", + "studentsBlacklist", + "ownerUid", + "password", + "hidden", + "deleted", + "createdAt" + ], + "additionalProperties": false + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/rooms/{slug}": { + "put": { + "operationId": "rooms-updateRoom", + "summary": "Update a room", + "description": "Update a room", + "tags": [ + "Rooms (Optional)" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the room" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "enum": [ + "null" + ], + "nullable": true + } + ], + "description": "The description of the room" + }, + "iconURL": { + "anyOf": [ + { + "type": "string" + }, + { + "enum": [ + "null" + ], + "nullable": true + } + ], + "description": "The URL of the room's icon" + }, + "isPublic": { + "type": "boolean", + "description": "Whether the room is public or not. Defaults to false" + }, + "studentsWhitelist": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "description": "The list of students allowed to join the room. Effective only if isPublic is false. Accepts both UIDs and logins. Defaults to an empty array" + }, + "studentsBlacklist": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "description": "The list of students not allowed to join the room. Effective only if isPublic is true. Accepts both UIDs and logins. Defaults to an empty array" + } + }, + "additionalProperties": false + } + } + } + }, + "parameters": [ + { + "name": "slug", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The slug of the room" + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "slug": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "nullable": true + }, + "iconURL": { + "type": "string", + "nullable": true + }, + "canvasDimensions": { + "type": "number" + }, + "isPublic": { + "type": "boolean" + }, + "studentsWhitelist": { + "type": "array", + "items": { + "type": "number" + } + }, + "studentsBlacklist": { + "type": "array", + "items": { + "type": "number" + } + }, + "ownerUid": { + "type": "number" + }, + "password": { + "type": "string", + "nullable": true + }, + "hidden": { + "type": "boolean" + }, + "deleted": { + "type": "boolean" + }, + "createdAt": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "slug", + "name", + "description", + "iconURL", + "canvasDimensions", + "isPublic", + "studentsWhitelist", + "studentsBlacklist", + "ownerUid", + "password", + "hidden", + "deleted", + "createdAt" + ], + "additionalProperties": false + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "rooms-deleteRoom", + "summary": "Delete a room", + "description": "Delete a room", + "tags": [ + "Rooms (Optional)" + ], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [ + { + "name": "slug", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The slug of the room" + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/rooms/{slug}/config": { + "get": { + "operationId": "rooms-getRoomConfig", + "summary": "Get the room config", + "description": "Get the room config", + "tags": [ + "Rooms (Mandatory)" + ], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [ + { + "name": "slug", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The slug of the room" + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "metadata": { + "type": "object", + "properties": { + "slug": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "enum": [ + "null" + ], + "nullable": true + } + ] + }, + "iconURL": { + "anyOf": [ + { + "type": "string" + }, + { + "enum": [ + "null" + ], + "nullable": true + } + ] + }, + "canvasDimensions": { + "type": "number" + }, + "isPublic": { + "type": "boolean" + }, + "studentsWhitelist": { + "type": "array", + "items": { + "type": "number" + } + }, + "studentsBlacklist": { + "type": "array", + "items": { + "type": "number" + } + }, + "ownerUid": { + "type": "number" + }, + "createdAt": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "slug", + "name", + "description", + "iconURL", + "canvasDimensions", + "isPublic", + "ownerUid", + "createdAt" + ], + "additionalProperties": false + }, + "settings": { + "type": "object", + "properties": { + "roomColors": { + "type": "string" + } + }, + "required": [ + "roomColors" + ], + "additionalProperties": false + }, + "rateLimits": { + "type": "object", + "properties": { + "testsLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "getCanvasLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "getPixelLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "placePixelLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "getRoomsLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "getRoomConfigLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "createRoomLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "updateRoomLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "deleteRoomLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "getStudentLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "updateStudentLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "sendMessageLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "reportRoomLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + } + }, + "required": [ + "testsLimiter", + "getCanvasLimiter", + "getPixelLimiter", + "placePixelLimiter", + "getRoomsLimiter", + "getRoomConfigLimiter", + "createRoomLimiter", + "updateRoomLimiter", + "deleteRoomLimiter", + "getStudentLimiter", + "updateStudentLimiter", + "sendMessageLimiter", + "reportRoomLimiter" + ], + "additionalProperties": false + } + }, + "required": [ + "metadata", + "settings", + "rateLimits" + ], + "additionalProperties": false + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + }, + "post": { + "operationId": "rooms-changeRoomConfig", + "summary": "Load another json room config", + "description": "Load another json room config", + "tags": [ + "Admin" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "settings": { + "type": "object", + "properties": { + "roomColors": { + "type": "string", + "description": "The colors of the room" + } + }, + "additionalProperties": false, + "description": "The settings to change" + }, + "events": { + "type": "object", + "properties": { + "colorationEvent": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "The type of the coloration event" + }, + "groups": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The groups of the coloration event" + }, + "colorsSubSet": { + "type": "array", + "items": { + "type": "number" + }, + "description": "The colors subset of the coloration event" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + "radiusEvent": { + "type": "object", + "properties": { + "radius": { + "type": "number", + "description": "The radius of the event" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "rateLimitsOverride": { + "type": "object", + "properties": { + "testsLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "getCanvasLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "getPixelLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "placePixelLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "getRoomsLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "getRoomConfigLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "createRoomLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "updateRoomLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "deleteRoomLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "getStudentLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "updateStudentLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "sendMessageLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + }, + "reportRoomLimiter": { + "type": "object", + "properties": { + "limit": { + "type": "number" + }, + "interval": { + "type": "number" + } + }, + "required": [ + "limit", + "interval" + ], + "additionalProperties": false + } + }, + "required": [ + "testsLimiter", + "getCanvasLimiter", + "getPixelLimiter", + "placePixelLimiter", + "getRoomsLimiter", + "getRoomConfigLimiter", + "createRoomLimiter", + "updateRoomLimiter", + "deleteRoomLimiter", + "getStudentLimiter", + "updateStudentLimiter", + "sendMessageLimiter", + "reportRoomLimiter" + ], + "additionalProperties": false, + "description": "The rate limits to override" + } + }, + "required": [ + "events" + ], + "additionalProperties": false + } + } + } + }, + "parameters": [ + { + "name": "slug", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The slug of the room" + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/rooms/{slug}/report": { + "post": { + "operationId": "rooms-reportRoom", + "summary": "Report a room", + "description": "Report a room", + "tags": [ + "Misc" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "reason": { + "type": "string", + "description": "The reason for the report" + } + }, + "required": [ + "reason" + ], + "additionalProperties": false + } + } + } + }, + "parameters": [ + { + "name": "slug", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The slug of the room" + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/rooms/yeet": { + "post": { + "operationId": "rooms-yeetFromRoom", + "summary": "Yeet a student from a room", + "description": "Yeet a student from a room", + "tags": [ + "Admin" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "slug": { + "type": "string", + "description": "The slug of the room. If empty, all rooms will be yeeted" + }, + "studentsList": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "description": "The list of students to yeet. If empty, all students will be yeeted" + } + }, + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/rooms/{slug}/canvas": { + "get": { + "operationId": "rooms-canvas-getCanvas", + "summary": "Get the canvas of a room", + "description": "Get the canvas of a room", + "tags": [ + "Rooms (Mandatory)" + ], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [ + { + "name": "slug", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The slug of the room" + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "pixels": { + "type": "string", + "description": "The pixels of the room" + } + }, + "required": [ + "pixels" + ], + "additionalProperties": false + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/rooms/{slug}/canvas/pixels": { + "get": { + "operationId": "rooms-canvas-getPixel", + "summary": "Get the pixels of a room", + "description": "Get the pixels of a room", + "tags": [ + "Rooms (Mandatory)" + ], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [ + { + "name": "slug", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The slug of the room" + }, + { + "name": "posX", + "in": "query", + "required": true, + "schema": { + "type": "number" + }, + "description": "The X position of the pixel" + }, + { + "name": "posY", + "in": "query", + "required": true, + "schema": { + "type": "number" + }, + "description": "The Y position of the pixel" + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "roomSlug": { + "type": "string" + }, + "posX": { + "type": "number" + }, + "posY": { + "type": "number" + }, + "color": { + "type": "number" + }, + "timestamp": { + "anyOf": [ + { + "type": "number" + }, + { + "enum": [ + "null" + ], + "nullable": true + } + ] + }, + "placedByUid": { + "anyOf": [ + { + "type": "number" + }, + { + "enum": [ + "null" + ], + "nullable": true + } + ] + } + }, + "required": [ + "roomSlug", + "posX", + "posY", + "color", + "timestamp", + "placedByUid" + ], + "additionalProperties": false + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + }, + "post": { + "operationId": "rooms-canvas-placePixel", + "summary": "Place a pixel in a room", + "description": "Place a pixel in a room", + "tags": [ + "Rooms (Mandatory)" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "posX": { + "type": "number", + "description": "The X position of the pixel" + }, + "posY": { + "type": "number", + "description": "The Y position of the pixel" + }, + "color": { + "type": "number", + "description": "The color index of the pixel" + } + }, + "required": [ + "posX", + "posY", + "color" + ], + "additionalProperties": false + } + } + } + }, + "parameters": [ + { + "name": "slug", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The slug of the room" + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "roomSlug": { + "type": "string" + }, + "posX": { + "type": "number" + }, + "posY": { + "type": "number" + }, + "color": { + "type": "number" + }, + "timestamp": { + "anyOf": [ + { + "type": "number" + }, + { + "enum": [ + "null" + ], + "nullable": true + } + ] + }, + "placedByUid": { + "anyOf": [ + { + "type": "number" + }, + { + "enum": [ + "null" + ], + "nullable": true + } + ] + } + }, + "required": [ + "roomSlug", + "posX", + "posY", + "color", + "timestamp", + "placedByUid" + ], + "additionalProperties": false + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/rooms/{slug}/canvas/resize": { + "put": { + "operationId": "rooms-canvas-resizeCanvas", + "summary": "Resize the canvas of a room", + "description": "Resize the canvas of a room", + "tags": [ + "Admin" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "newCanvasDimensions": { + "type": "number", + "description": "The new size of the room" + } + }, + "required": [ + "newCanvasDimensions" + ], + "additionalProperties": false + } + } + } + }, + "parameters": [ + { + "name": "slug", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The slug of the room" + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "slug": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "nullable": true + }, + "iconURL": { + "type": "string", + "nullable": true + }, + "canvasDimensions": { + "type": "number" + }, + "isPublic": { + "type": "boolean" + }, + "studentsWhitelist": { + "type": "array", + "items": { + "type": "number" + } + }, + "studentsBlacklist": { + "type": "array", + "items": { + "type": "number" + } + }, + "ownerUid": { + "type": "number" + }, + "password": { + "type": "string", + "nullable": true + }, + "hidden": { + "type": "boolean" + }, + "deleted": { + "type": "boolean" + }, + "createdAt": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "slug", + "name", + "description", + "iconURL", + "canvasDimensions", + "isPublic", + "studentsWhitelist", + "studentsBlacklist", + "ownerUid", + "password", + "hidden", + "deleted", + "createdAt" + ], + "additionalProperties": false + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/rooms/{slug}/canvas/reset": { + "put": { + "operationId": "rooms-canvas-resetCanvas", + "summary": "Reset the canvas of a room", + "description": "Reset the canvas of a room", + "tags": [ + "Admin" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "resetOnDefault": { + "type": "boolean", + "description": "Reset the canvas on the default image if exists" + } + }, + "additionalProperties": false + } + } + } + }, + "parameters": [ + { + "name": "slug", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The slug of the room" + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "slug": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "nullable": true + }, + "iconURL": { + "type": "string", + "nullable": true + }, + "canvasDimensions": { + "type": "number" + }, + "isPublic": { + "type": "boolean" + }, + "studentsWhitelist": { + "type": "array", + "items": { + "type": "number" + } + }, + "studentsBlacklist": { + "type": "array", + "items": { + "type": "number" + } + }, + "ownerUid": { + "type": "number" + }, + "password": { + "type": "string", + "nullable": true + }, + "hidden": { + "type": "boolean" + }, + "deleted": { + "type": "boolean" + }, + "createdAt": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "slug", + "name", + "description", + "iconURL", + "canvasDimensions", + "isPublic", + "studentsWhitelist", + "studentsBlacklist", + "ownerUid", + "password", + "hidden", + "deleted", + "createdAt" + ], + "additionalProperties": false + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + }, + "/rooms/{slug}/canvas/load": { + "post": { + "operationId": "rooms-canvas-loadCanvas", + "summary": "Load the canvas of a room", + "description": "Load the canvas of a room", + "tags": [ + "Admin" + ], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "backupId": { + "type": "number", + "description": "The id of the backup" + } + }, + "required": [ + "backupId" + ], + "additionalProperties": false + } + } + } + }, + "parameters": [ + { + "name": "slug", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The slug of the room" + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InvalidToken": { + "value": { + "code": "UNAUTHORIZED", + "message": "Invalid token" + } + }, + "TokenExpired": { + "value": { + "code": "UNAUTHORIZED", + "message": "Token expired" + } + }, + "Unauthenticated": { + "value": { + "code": "UNAUTHORIZED", + "message": "Unauthenticated" + } + }, + "Banned": { + "value": { + "code": "UNAUTHORIZED", + "message": "You are banned" + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "NotAdmin": { + "value": { + "code": "FORBIDDEN", + "message": "You are not an admin" + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "TooManyRequests": { + "value": { + "code": "TOO_MANY_REQUESTS", + "message": "Too many requests" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "InternalServerError": { + "value": { + "code": "INTERNAL_SERVER_ERROR", + "message": "An error occured" + } + } + } + } + } + } + } + } + } + }, + "components": { + "securitySchemes": { + "Authorization": { + "type": "http", + "scheme": "bearer" + } + }, + "responses": { + "error": { + "description": "Error response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "code": { + "type": "string" + }, + "issues": { + "type": "array", + "items": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "additionalProperties": false + } + } + }, + "required": [ + "message", + "code" + ], + "additionalProperties": false + } + } + } + } + }, + "schemas": { + "Room": { + "type": "object", + "properties": { + "slug": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "nullable": true + }, + "iconURL": { + "type": "string", + "nullable": true + }, + "canvasDimensions": { + "type": "number" + }, + "isPublic": { + "type": "boolean" + }, + "studentsWhitelist": { + "type": "array", + "items": { + "type": "number" + } + }, + "studentsBlacklist": { + "type": "array", + "items": { + "type": "number" + } + }, + "ownerUid": { + "type": "number" + }, + "password": { + "type": "string", + "nullable": true + }, + "hidden": { + "type": "boolean" + }, + "deleted": { + "type": "boolean" + }, + "createdAt": { + "type": "string", + "format": "date-time" + } + } + }, + "Student": { + "type": "object", + "properties": { + "groups": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ADMIN", + "YAKA", + "ING1_LYON", + "ING1_PARIS", + "ING1_RENNES", + "ING1_STRASBOURG", + "ING1_TOULOUSE" + ] + } + }, + "uid": { + "type": "number" + }, + "login": { + "type": "string" + }, + "avatarURL": { + "type": "string", + "nullable": true + }, + "quote": { + "type": "string", + "nullable": true + }, + "currentRoomSlug": { + "type": "string", + "nullable": true + }, + "banUntil": { + "type": "string", + "format": "date-time", + "nullable": true + } + } + }, + "Error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + } + } + } + }, + "tags": [ + { + "name": "Misc" + }, + { + "name": "Tests" + }, + { + "name": "Rooms (Mandatory)" + }, + { + "name": "Rooms (Optional)" + }, + { + "name": "Students (Mandatory)" + }, + { + "name": "Students (Optional)" + }, + { + "name": "Admin" + } + ] +}
\ No newline at end of file |
