Skip to content

Commit

Permalink
feat(docs): add more informations in README.md, and update some thing…
Browse files Browse the repository at this point in the history
…s to a better configuration
  • Loading branch information
EliotAmn committed Jan 21, 2025
1 parent 048562d commit 4dd9497
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 32 deletions.
104 changes: 103 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
# TekBetter - A better intranet for Epitech

# Table of contents

#### Setup guide:

- [Environement variables](#environment-variables)
- [Run in development mode](#run-in-development-mode)

## Description

TekBetter is a project that aims to create a better interface who rassemble all the tools that Epitech students use in
their daily life.

## Environment variables

### Backend (`/.env`)

| Variable | Description | Default value |
|----------------------|----------------------------------------------------------------------------|---------------|
| PORT | Port where the server will listen | 3000 |
| PORT | Port where the server will listen | 8080 |
| MONGO_HOST | The mongodb database hostname. | mongo |
| MONGO_PORT | The mongodb database port. | 27017 |
| MONGO_DB | The mongodb database name. | tekbetter |
Expand All @@ -21,3 +30,96 @@ their daily life.
| AES_KEY | The key used to encrypt sensible data in database. 64 bytes long required. | |
| SCRAPERS_CONFIG_FILE | The path to the scrapers configuration file. Optional | scrapers.json |
| APP_URL | The app url used to send register links by email. | |
| ENABLE_MAILER | Enable the mailer service. | true |

### Frontend (`/web/.env`)

| Variable | Description | Default value |
|-------------------|-------------------------|-----------------------------|
| REACT_APP_API_URL | The backend server url. | Auto detect the current url |

## Run in development mode

### Setup environment variables

You can find the front-end react app in the `web/` directory.
You need to define an environment variable `REACT_APP_API_URL` to point to the backend server.

```dotenv
# web/.env
REACT_APP_API_URL=http://localhost:8080
```

For the backend, you can create a `.env` file in the root directory of the project.
You can find a `/docker-compose.yml` file that will start a mongodb and a redis server.
Create a `scrapers.json` file in the root directory of the project to configure the scrapers, and add the following
content :

```json
[]
```

This is an example `.env` file for the backend with docker-compose usage :

```dotenv
APP_URL=http://localhost:8080
JWT_SECRET=my_jwt_secret
AES_KEY=a9421fce83c42eeab1a958c24b516943ccda3e2c4cf6ee3ada4cc78315d228d2
MONGO_HOST=localhost
REDIS_HOST=localhost
REDIS_PASSWORD=123456
SCRAPERS_CONFIG_FILE=scrapers.json
ENABLE_MAILER=false
```

### Run the frontend

Please check that you have `npm` and a recent version of `node` installed on your machine.
Navigate to the `web/` directory and run the following commands :

```bash
npm install
npm start
```

### Run the backend

Please check that you have `python3` and `pip` installed on your machine.
Go back to the root directory of the project and run the following commands :

```bash
pip install -r requirements.txt
PYTHONPATH=$(pwd) python3 app/main.py
```

#### Happy coding !

## How to configure internal scrapers

An internal scraper is a scraper that will be controlled by the backend.
To configure a scraper, you need to create a `scrapers.json` file in the root directory of the project.

Here is an example of a scraper configuration :

```json
[
{
"id": "paris-01",
"label": "PARIS-01",
"access_token": "choose_a_random_string"
},
{
"id": "paris-02",
"label": "PARIS-02",
"access_token": "choose_a_random_string"
}
]
```

`id` is the unique identifier of the scraper.

`label` is the name of the scraper.

`access_token` is a random string that will be used to authenticate the scraper. This access token will be set in the
scraper environment variable `SCRAPER_ACCESS_TOKEN`.
2 changes: 1 addition & 1 deletion app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def init_services():
load_env()
except Exception as e:
log_error(str(e))
raise
exit(1)

# Connect to MongoDB
mongo_url = f"mongodb://{os.getenv('MONGO_HOST')}:{os.getenv('MONGO_PORT')}?directConnection=true"
Expand Down
4 changes: 1 addition & 3 deletions app/models/PublicScraper.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ class PublicScraper:
id: str
label: str
access_token: str
enabled: bool

def to_dict(self):
return {
"id": self.id,
"label": self.label,
"access_token": self.access_token,
"enabled": self.enabled
"access_token": self.access_token
}

def get_students(self):
Expand Down
3 changes: 1 addition & 2 deletions app/services/publicscraper_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def load_scrapers_from_config():
scrapers = Globals.public_scrapers
config = get_config()
for scraper in config:
for key in ["id", "label", "enabled", "access_token"]:
for key in ["id", "label", "access_token"]:
if not scraper.get(key):
raise Exception(
f"Missing key {key} in scraper configuration")
Expand All @@ -37,7 +37,6 @@ def load_scrapers_from_config():
scraper["id"])
ns.id = scraper["id"]
ns.name = scraper["label"]
ns.enabled = scraper["enabled"]
ns.access_token = scraper["access_token"]

if is_new:
Expand Down
38 changes: 21 additions & 17 deletions app/services/student_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from app.services.redis_service import RedisService
from app.tools.jwt_engine import generate_jwt
from app.tools.password_tools import hash_password
from app.tools.teklogger import log_debug
from app.tools.teklogger import log_debug, log_warning


class StudentService:
Expand Down Expand Up @@ -85,23 +85,27 @@ def create_register_ticket(email: str):
ticket_url = f"{os.getenv("APP_URL")}/auth?ticket={ticket}"
RedisService.set(f"register_ticket_{ticket}", email,
60 * 60) # Expires in 1 hour
subject: str = "Confirm Your TekBetter Account"
body: str = f"""\
Hello,
Thank you for creating a TekBetter account! To complete your registration, please confirm your email address by clicking the link below:
{ticket_url}
Please note that this link will expire in 1 hour. If you did not request this account, you can safely ignore this email.
Thank you for choosing TekBetter. We’re excited to have you on board!
Best regards,
The TekBetter Team
"""
MailService.send_mail(email, subject, body)
log_debug(f"Register ticket created for {email}: {ticket}")
if os.getenv("ENABLE_MAILER") == "true":
subject: str = "Confirm Your TekBetter Account"
body: str = f"""\
Hello,
Thank you for creating a TekBetter account! To complete your registration, please confirm your email address by clicking the link below:
{ticket_url}
Please note that this link will expire in 1 hour. If you did not request this account, you can safely ignore this email.
Thank you for choosing TekBetter. We’re excited to have you on board!
Best regards,
The TekBetter Team
"""
MailService.send_mail(email, subject, body)
else:
log_warning(
"Mailer is disabled, not sending email. You can use the following link to confirm your account:" + ticket_url)
return ticket

@staticmethod
Expand Down
13 changes: 11 additions & 2 deletions app/tools/envloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from app.tools.teklogger import log_debug, log_warning

default_values = {
"PORT": "3000",
"PORT": "8080",
"MONGO_HOST": "mongo",
"MONGO_PORT": "27017",
"MONGO_DB": "tekbetter",
Expand All @@ -20,7 +20,8 @@
"SMTP_HOST": None,
"SMTP_PORT": 587,
"SMTP_USER": None,
"SMTP_PASSWORD": None
"SMTP_PASSWORD": None,
"ENABLE_MAILER": "false",
}


Expand All @@ -32,6 +33,13 @@ def load_env():

log_debug("Loading environment variables")
load_dotenv()

smtp_vars = ["SMTP_HOST", "SMTP_USER", "SMTP_PASSWORD"]
if os.getenv("ENABLE_MAILER") == "true":
for var in smtp_vars:
if os.getenv(var) is None:
raise Exception(f"ENABLE_MAILER is true, so {var} must be set")

for key, value in default_values.items():
if os.getenv(key, None) is None:
if value is not None:
Expand All @@ -40,5 +48,6 @@ def load_env():
os.environ[key] = value
else:
raise Exception(f"Missing environment variable {key}")

if len(os.getenv("AES_KEY")) != 64:
raise Exception("AES_KEY must be 64 characters long")
2 changes: 1 addition & 1 deletion web/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/node_modules
/.pnp
.pnp.js

/.env
# testing
/coverage

Expand Down
6 changes: 1 addition & 5 deletions web/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@ export class StaticVars {
this.setErrorPopup = (title: string | null, message: string | null) => {
}
}

}


//const backend_url = process.env.REACT_APP_BACKEND_URL || "http://localhost:8080"
const current_domain = window.location.hostname;
const backend_url = process.env.NODE_ENV === 'development' ? "https://tekbetter.ovh" : `https://${current_domain}`
const backend_url = process.env.REACT_APP_API_URL || window.location.origin

const api = axios.create({
baseURL: `${backend_url}/api/`,
Expand Down

0 comments on commit 4dd9497

Please sign in to comment.