Compare commits

...

65 Commits

Author SHA1 Message Date
David D'ALMEIDA 2c497ae48d Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL cd511d9113 Merge pull request 'Clean_Project' (#19) from Clean_Project into master
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL 0ce24fb8f9 Change Overview
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL 6558df0558 Small improvements 🔨
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL b746fbf7d2 Update chat screen and add a StubMessageService
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL d2421812e2 Merge branch 'Clean_Project' of https://codefirst.iut.uca.fr/git/FLAD_Dev/FLAD into Clean_Project
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL a0f7cbf89c Update API and can change spotify account
1 year ago
Emre KARTAL 3faac72493 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL 85b47bf961 correct small errors
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL 10bd4b892a upgrade navbar
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL ae0ff4e455 Upgrade spot screen and navbar 🎨
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL e86a35118d Add swagger 📚
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL d389b58930 Clean spot screen and CardComponent 🎨
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL bc612f98dd add a new API route and getSpots
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL f761028031 New API route for changing password and functionality completion of Settings, Profile, Favorite and Detail pages
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL 1a0e02bdef Add a new ServiceSpotify, improved the structure and added new routes to modify user information and favorite music
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL 0ce68c7c26 Improved authentication on the API and CLIENT side with error management
continuous-integration/drone/push Build is passing Details
1 year ago
Emre KARTAL 9dc8a5be16 Re add model
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 01de765939 Delete Model
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 559f299aeb Clean redux
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL b94cc83dbb Delete config
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 3efff8a9de Mise à jour de 'src/Api/src/app.ts'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 0833a8539e Mise à jour de 'src/Api/src/app.ts'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 507b63a8f5 Mise à jour de 'src/Api/src/app.ts'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 614b9103e2 Mise à jour de 'src/Api/src/app.ts'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL c8d74edfa2 Mise à jour de 'src/Api/Dockerfile'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL fceb0358e7 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL eebd3c8b8c Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 09fa5f39a2 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL e60545d009 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 43f61d0796 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 90274de4ce Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 3a36f9b41b Mise à jour de 'src/Api/Dockerfile'
continuous-integration/drone/push Build is failing Details
2 years ago
Emre KARTAL c6c99246cf Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 years ago
Emre KARTAL 51073ee256 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
2 years ago
Emre KARTAL 54f0928856 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 years ago
Emre KARTAL 7e957c8cbf Ajouter 'src/Api/Dockerfile'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL b3455962b0 Merge branch 'Clean_Project' of https://codefirst.iut.uca.fr/git/FLAD_Dev/FLAD into Clean_Project
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 64d84ca415 Clean spotify Controller
2 years ago
Emre KARTAL 6e42a3f39a Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 232feb72c6 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
2 years ago
Emre KARTAL 20c5957094 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
2 years ago
Emre KARTAL 42ca152553 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL d41ba6d96b Correct error 🐛
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 7970e4bdc2 delete useless files
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 959030c8c7 Delete android files
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL e9d8b26c4d Use .env
continuous-integration/drone/push Build is failing Details
2 years ago
Emre KARTAL ef4500d4af Update gitignore
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL bd6d47987c Delete dist
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL b1f1269f97 Delete .env and update SpotifyController
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 0ab6b83b8d Delete .env and update SpotifyController
2 years ago
Emre KARTAL 97987ec443 Merge branch 'Clean_Project' of https://codefirst.iut.uca.fr/git/FLAD_Dev/FLAD into Clean_Project
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL ca8d8a2bd0 Clean UserController and Database 🎨
2 years ago
Emre KARTAL ca8b7aff44 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL ee937b8c3e delete useless files and update struct 🎨
continuous-integration/drone/push Build is failing Details
2 years ago
Emre KARTAL bbc1af9ccd update struct 🎨
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 31fcc3f526 change images
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL c3306c4518 change name images 🎨
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL c0fe4ee3f7 change name images 🎨
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL 77e35143d2 Merge branch 'Clean_Project' of https://codefirst.iut.uca.fr/git/FLAD_Dev/FLAD into Clean_Project
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL ee7cf440f7 update struct 🎨
2 years ago
Emre KARTAL 08f55cd103 Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL a7900aae79 Change name folder 🎨
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL b3fb1a593d Change name folder 🎨
continuous-integration/drone/push Build is passing Details
2 years ago
Emre KARTAL aa87bf066e Improvement of the project structure 🎨
continuous-integration/drone/push Build is passing Details
2 years ago

@ -1,6 +1,6 @@
kind: pipeline kind: pipeline
type: docker type: docker
name: FLAD name: FLAD-CLI
trigger: trigger:
event: event:
@ -14,6 +14,34 @@ steps:
- npm install - npm install
- npm run - npm run
- name: code-analysis
image: node:latest
environment:
SONAR_TOKEN:
from_secret: SONAR_TOKEN
settings:
sources: ./src/FLAD/
commands:
- export SONAR_SCANNER_VERSION=4.7.0.2747
- export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux
- curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-linux.zip
- unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
- export PATH=$SONAR_SCANNER_HOME/bin:$PATH
- export SONAR_SCANNER_OPTS="-server"
- sonar-scanner -D sonar.projectKey=FLAD -D sonar.sources=./src/FLAD -D sonar.host.url=https://codefirst.iut.uca.fr/sonar
depends_on: [ app-build ]
---
kind: pipeline
type: docker
name: FLAD-API-MQTT
trigger:
event:
- push
steps:
- name: docker-build-and-push - name: docker-build-and-push
image: plugins/docker image: plugins/docker
settings: settings:
@ -25,25 +53,54 @@ steps:
from_secret: SECRET_REGISTRY_USERNAME from_secret: SECRET_REGISTRY_USERNAME
password: password:
from_secret: SECRET_REGISTRY_PASSWORD from_secret: SECRET_REGISTRY_PASSWORD
depends_on: [ app-build ]
#container deployment
- name: deploy-container - name: deploy-container
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment: environment:
IMAGENAME: hub.codefirst.iut.uca.fr/emre.kartal/flad:latest IMAGENAME: hub.codefirst.iut.uca.fr/emre.kartal/flad:latest
CONTAINERNAME: flady-container CONTAINERNAME: flad
CODEFIRST_CLIENTDRONE_ENV_PORT: 80
CODEFIRST_CLIENTDRONE_ENV_MONGO_PASSWORD:
from_secret: MONGO_PASSWORD
CODEFIRST_CLIENTDRONE_ENV_CLIENT_ID_SPOTIFY:
from_secret: CLIENT_ID_SPOTIFY
CODEFIRST_CLIENTDRONE_ENV_CLIENT_SECRET_SPOTIFY:
from_secret: CLIENT_SECRET_SPOTIFY
COMMAND: create COMMAND: create
OVERWRITE: true OVERWRITE: true
ADMINS: emrekartal,davidd_almeida, ADMINS: emrekartal,davidd_almeida,
depends_on: [ docker-build-and-push ] depends_on: [ docker-build-and-push ]
- name: docker-build-and-push-mqtt
image: plugins/docker
settings:
dockerfile: src/Mqtt/Dockerfile
context: src/Mqtt
registry: hub.codefirst.iut.uca.fr
repo: hub.codefirst.iut.uca.fr/david.d_almeida/flad
username:
from_secret: SECRET_REGISTRY_USERNAME_MQTT
password:
from_secret: SECRET_REGISTRY_PASSWORD_MQTT
- name: deploy-container-mqtt
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment:
IMAGENAME: hub.codefirst.iut.uca.fr/david.d_almeida/flad:latest
CONTAINERNAME: mqtt
COMMAND: create
OVERWRITE: true
ADMINS: emrekartal,davidd_almeida
depends_on: [ docker-build-and-push-mqtt ]
- name: code-analysis - name: code-analysis
image: node:latest image: node:latest
environment: environment:
SONAR_TOKEN: SONAR_TOKEN:
from_secret: SONAR_TOKEN from_secret: SONAR_TOKEN_API
settings: settings:
sources: ./src/FLAD/ sources: ./src/Api/
commands: commands:
- export SONAR_SCANNER_VERSION=4.7.0.2747 - export SONAR_SCANNER_VERSION=4.7.0.2747
- export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux - export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux
@ -51,5 +108,4 @@ steps:
- unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/ - unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
- export PATH=$SONAR_SCANNER_HOME/bin:$PATH - export PATH=$SONAR_SCANNER_HOME/bin:$PATH
- export SONAR_SCANNER_OPTS="-server" - export SONAR_SCANNER_OPTS="-server"
- sonar-scanner -D sonar.projectKey=FLAD -D sonar.sources=. -D sonar.host.url=https://codefirst.iut.uca.fr/sonar - sonar-scanner -D sonar.projectKey=FLAD-API -D sonar.sources=./src/Api -D sonar.host.url=https://codefirst.iut.uca.fr/sonar
depends_on: [ app-build ]

@ -8,7 +8,6 @@
--- ---
  ![Redux](https://img.shields.io/badge/Redux-593D88?style=for-the-badge&logo=redux&logoColor=white)
  ![Docker](https://img.shields.io/badge/Docker-2496ED.svg?style=for-the-badge&logo=Docker&logoColor=white)   ![Docker](https://img.shields.io/badge/Docker-2496ED.svg?style=for-the-badge&logo=Docker&logoColor=white)
  ![React Native](https://img.shields.io/badge/React_Native-20232A?style=for-the-badge&logo=react&logoColor=61DAFB)   ![React Native](https://img.shields.io/badge/React_Native-20232A?style=for-the-badge&logo=react&logoColor=61DAFB)
  ![Spotify Api](https://img.shields.io/badge/Spotify-1ED760?&style=for-the-badge&logo=spotify&logoColor=white)   ![Spotify Api](https://img.shields.io/badge/Spotify-1ED760?&style=for-the-badge&logo=spotify&logoColor=white)
@ -34,9 +33,9 @@
La racine de notre gitlab est composée de deux dossiers essentiels au projet: La racine de notre gitlab est composée de deux dossiers essentiels au projet:
[**src**](src) : **Toute la partie codage de l'application mobile** (contient un dossier API pour l'API FLAD qui effectue les requêtes vers l'API SPOTIFY et la base de données, ainsi qu'un dossier FLAD qui contient toute la partie côté client de l'application) [**src**](src) : **Ensemble du code pour l'application mobile et les services web** (Application React Native, API Express en TypeScript, et messagerie MQTT)
[**doc**](doc) : **Documentation de l'application** (contient les maquettes) [**doc**](doc) : **Documentation de l'application** (Inclut des diagrammes, des maquettes et des images)
## Fonctionnement ## Fonctionnement
@ -62,11 +61,11 @@ Pour la suite, il suffit seulement de vérifier que node.js est à jour et insta
Maintenant vous pouvez à tout moment lancer l'application grâce à la commande : **npx expo start :sunglasses:** Maintenant vous pouvez à tout moment lancer l'application grâce à la commande : **npx expo start :sunglasses:**
<br> <br>
:information_source: *Cliquer sur la touche 'w' si vous voulez le visualiser sur un navigateur (ce que je ne conseille pas) ou installer l'application 'Expo go' de votre téléphone et scanner le QR code proposer pour le visualiser (à noter que l'ordinateur dans lequel il se voit lancer doit être dans le même réseau local que votre téléphone)* :information_source: *N'oubliez pas d'installer 'Expo Go' depuis le store de votre téléphone.*
- ### Comment le lancer à partir de l'iut d'Aubière ? - ### Comment le lancer à partir de l'IUT d'Aubière ?
Cela est un peu plus difficile mais faisable !!! Cela est un peu plus difficile mais faisable !
<br> <br>
Tout d'abord aller dans votre compte scratch : **cd home/scratch/compte** Tout d'abord aller dans votre compte scratch : **cd home/scratch/compte**
@ -89,36 +88,37 @@ Et entrer la commande : **export NODE_OPTIONS=--openssl-legacy-provider**
Maintenant vous pouvez à tout moment lancer l'application grâce à la commande : **npx expo start :sunglasses:** Maintenant vous pouvez à tout moment lancer l'application grâce à la commande : **npx expo start :sunglasses:**
<br> <br>
:information_source: *Cliquer sur la touche 'w' si vous voulez le visualiser sur un navigateur (ce que je ne conseille pas) ou installer l'application 'Expo go' de votre téléphone et scanner le QR code proposer pour le visualiser (à noter que l'ordinateur dans lequel il se voit lancer doit être dans le même réseau local que votre téléphone)*
- ### Comment s'inscrire sur l'application ? - ### Comment s'inscrire sur l'application ?
Tout d'abord, il faut fournir votre *adresse e-mail* et votre *nom Spotify* aux **techniciens de l'application** (voir plus bas). Ils s'occuperont de vous ajouter définitivement à l'application. Une fois que cela est fait, inscrivez-vous via la **page d'inscription** de l'application en cliquant d'abord sur le bouton 'lier mon compte': Tout d'abord, il faut fournir votre *adresse e-mail* et votre *nom Spotify* aux **techniciens de l'application** (voir plus bas). Ils s'occuperont de vous ajouter définitivement à l'application. Une fois que cela est fait, inscrivez-vous via la **page d'inscription** de l'application :
<div align = center> <div align = center>
<img src="doc/Images/Real_RegisterPage.png" width="250" > <img src="doc/Maquettes/RegisterPage.png" width="200" >
</div> </div>
Vous serez normalement redirigé sur la page Spotify où vous devrez vous connecter. Une fois connecté, entrez votre nom, votre adresse e-mail et votre mot de passe en tant qu'utilisateur FLAD (n'oubliez pas ces informations car vous en aurez besoin pour vous connecter). Ensuite, cliquez sur le bouton ```suivant``` et bienvenue sur l'application ! Une fois sur la page, saisissez votre nom, votre adresse e-mail, et votre mot de passe en tant qu'utilisateur FLAD (n'oubliez pas ces informations, vous en aurez besoin pour vous connecter). Pour lier votre compte à Spotify, vous serez automatiquement redirigé vers la page de connexion Spotify. Entrez vos identifiants Spotify, puis cliquez sur le bouton ```Suivant``` et bienvenue sur l'application !"
## Visuel de l'Application ## Visuel de l'Application
<div align = center> <div align = center>
<img src="doc/Images/Real_HomePage.png" width="250" > <img src="doc/Images/Overview.png">
<img src="doc/Images/Real_FavoritePage.png" width="250" >
<img src="doc/Images/Real_ConversationPage.png" width="250" >
<img src="doc/Images/Real_SettingPage.png" width="250" >
</div> </div>
:information_source: Lorsque vous entrez dans notre application, la page d'accueil (**home**) vous permet de découvrir les musiques :notes: des utilisateurs autour de vous. Vous pouvez valider une musique soit en cliquant sur le bouton, soit en la glissant vers la droite :point_up_2:. Cette musique sera alors ajoutée à la page **favoris** :heart: et vous pourrez entamer une discussion avec l'utilisateur dans la page **chat** :speech_balloon:. :information_source: Lorsque vous entrez dans notre application, la page d'accueil (**home**) vous permet de découvrir les musiques :notes: des utilisateurs autour de vous. Vous pouvez valider une musique soit en cliquant sur le bouton, soit en la glissant vers la droite :point_up_2:. Cette musique sera alors ajoutée à la page **favoris** :heart: et vous pourrez entamer une discussion avec l'utilisateur dans la page **chat** :speech_balloon:.
<br/>
Pour accéder aux détails d'une musique, maintenez votre doigt appuyé sur un Spot ou rendez-vous sur la page des favoris. Vous pourrez écouter la musique :arrow_forward:, obtenir des informations sur l'artiste et la chanson, découvrir des musiques similaires, et même l'ajouter à votre playlist Spotify ou la partager.
<br/> <br/>
Dans la page **settings** ⚙️, vous avez accès à toutes vos informations ```Spotify```, que vous pouvez modifier à votre guise. Toutefois, ces modifications ne seront prises en compte que dans notre application. Vous pouvez également choisir le mode sombre (dark mode) dans les paramètres pour une expérience de navigation plus confortable. Dans la page **settings** ⚙️, vous avez accès à toutes vos informations ```Spotify```, que vous pouvez modifier à votre guise. Toutefois, ces modifications ne seront prises en compte que dans notre application. Vous pouvez également choisir le mode sombre (dark mode) dans les paramètres pour une expérience de navigation plus confortable.
<br/> <br/>
### Voici un petit récapitulatif ### Voici un petit récapitulatif
<div align="center"> <div align="center">
<table> <table>
@ -128,9 +128,9 @@ Dans la page **settings** ⚙️, vous avez accès à toutes vos informations ``
<td align="center"><img src="doc/Images/Like_Img.png" alt="Button 3" width="100" height="100"></td> <td align="center"><img src="doc/Images/Like_Img.png" alt="Button 3" width="100" height="100"></td>
</tr> </tr>
<tr> <tr>
<td align="center">Suprimer de la pile un spot</td> <td align="center">Supprimer de la pile un spot</td>
<td align="center">Ajout Discover (pour l'instant il permet d'ajouter des spot suplémentaires dans la pile pour que vous puissiez vous amusez si il n'y aucun utilisateur à coté de vous)</td> <td align="center">Ajout dans une playlist de votre compte Spotify (créée spécialement par l'application)</td>
<td align="center">Like pour ajouter au favorie</td> <td align="center">Ajouter à vos favoris</td>
</tr> </tr>
</table> </table>
</div> </div>
@ -151,17 +151,19 @@ La composition pour le projet se voit réaliser par deux élèves de l'IUT d'Aub
<div align="center"> <div align="center">
<a href = "https://codefirst.iut.uca.fr/git/emre.kartal"> <a href = "https://codefirst.iut.uca.fr/git/emre.kartal">
<img src="https://codefirst.iut.uca.fr/git/avatars/402cf312e853192f42c0135a888725c2?size=870" width="50" > <img src="https://codefirst.iut.uca.fr/git/avatars/1ff65c9c5ab0e8c8883fb48adbcf972f?size=72" width="50" >
</a> </a>
<a href = "https://codefirst.iut.uca.fr/git/david.d_almeida"> <a href = "https://codefirst.iut.uca.fr/git/david.d_almeida">
<img src="https://codefirst.iut.uca.fr/git/avatars/0f8eaaad1e26d3de644ca522eccaea7c?size=870" width="50" > <img src="https://codefirst.iut.uca.fr/git/avatars/a16fa2dc52ceae18d8923c91121caa66?size=870" width="50" >
</a> </a>
</div> </div>
<div align = center> <div align = center>
© PM2 (Projet inspiré par nos très chers développeurs de la Dafl Team (S.O les Dafl dev)) © FladDev
</div> </div>
<hr> <div align = right>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a><br />Ce(tte) œuvre est mise à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/">Licence Creative Commons Attribution - Pas d&#39;Utilisation Commerciale - Pas de Modification 4.0 International</a>. </div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 366 KiB

After

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 867 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 729 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 892 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

@ -1,15 +0,0 @@
> Why do I have a folder named ".expo" in my project?
The ".expo" folder is created when an Expo project is started using "expo start" command.
> What do the files contain?
- "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds.
- "packager-info.json": contains port numbers and process PIDs that are used to serve the application to the mobile device/simulator.
- "settings.json": contains the server configuration that is used to serve the application manifest.
> Should I commit the ".expo" folder?
No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
Upon project creation, the ".expo" folder is already added to your ".gitignore" file.

@ -1,8 +0,0 @@
{
"hostType": "lan",
"lanType": "ip",
"dev": true,
"minify": false,
"urlRandomness": null,
"https": false
}

@ -1 +0,0 @@
PORT=8080

@ -21,6 +21,7 @@ DerivedData
*.xcuserstate *.xcuserstate
project.xcworkspace project.xcworkspace
**/.xcode.env.local **/.xcode.env.local
**/src/config.ts
# Gradle # Gradle
/build/ /build/
@ -72,6 +73,8 @@ node_modules
*.log *.log
.nvm .nvm
package-lock.json package-lock.json
dist
**/.env
# OS X # OS X
.DS_Store .DS_Store

@ -1,10 +1,8 @@
FROM node:latest FROM node:latest
WORKDIR /Api WORKDIR /Api
ADD package.json /Api COPY package.json /Api
ADD tsconfig.json /Api COPY tsconfig.json /Api
ADD . /Api COPY . /Api
RUN npm install RUN npm install && npm run build
RUN npm run build EXPOSE 80
EXPOSE 8080
CMD ["node", "."] CMD ["node", "."]

@ -1,62 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
// import compression from 'compression';
const cors_1 = __importDefault(require("cors"));
// import ErrorMiddleware from './middleware/error.middleware';
const body_parser_1 = __importDefault(require("body-parser"));
const mongoose_1 = __importDefault(require("mongoose"));
const cookie_parser_1 = __importDefault(require("cookie-parser"));
class App {
constructor(controllers, port) {
this.express = (0, express_1.default)();
this.port = port;
this.dataBase = null;
this.initialiseDatabase();
this.initialiseMiddleware();
this.initialiseControllers(controllers);
// this.initialiseErrorHandling();
}
initialiseMiddleware() {
// this.express.use(helmet());
this.express.use((0, cors_1.default)());
this.express.use((0, cookie_parser_1.default)());
// this.express.use(morgan('dev'));
this.express.use(express_1.default.json());
this.express.use(express_1.default.urlencoded({ extended: false }));
// this.express.use(compression());
// mine
this.express.use(body_parser_1.default.json());
this.express.use(body_parser_1.default.urlencoded({
extended: true
}));
}
initialiseControllers(controllers) {
controllers.forEach((controller) => {
this.express.use('/api', controller.router);
this.express.get('/toto', (req, res) => {
res.send('Hello World!');
});
});
}
// private initialiseErrorHandling(): void {
// this.express.use(ErrorMiddleware);
// }
listen() {
const server = this.express.listen(this.port, () => {
console.log(`⚡️[server] : App listening on the port ${this.port}`);
});
}
initialiseDatabase() {
const { MONGO_USER, MONGO_PASSWORD, MONGO_PATH } = process.env;
const uri = "mongodb+srv://fladDevDb:ZslYlNRWIOUU7i6o@fladcluster.b29tytu.mongodb.net/?retryWrites=true&w=majority";
mongoose_1.default.connect(uri)
.then(() => console.log("Connect to MongoDB database successfully"))
.catch(err => console.log("Error connecting : " + err));
}
}
exports.default = App;
//# sourceMappingURL=app.js.map

@ -1 +0,0 @@
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";;;;;AAAA,sDAA+C;AAC/C,yCAAyC;AACzC,gDAAwB;AAIxB,+DAA+D;AAC/D,8DAAqC;AACrC,wDAAgC;AAMhC,kEAAyC;AAEzC,MAAM,GAAG;IAOL,YAAY,WAAyB,EAAE,IAAY;QAC/C,IAAI,CAAC,OAAO,GAAG,IAAA,iBAAO,GAAE,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAErB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC;QAExC,kCAAkC;IACtC,CAAC;IAEO,oBAAoB;QACxB,8BAA8B;QAC9B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAA,cAAI,GAAE,CAAC,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAA,uBAAY,GAAE,CAAC,CAAC;QAGjC,mCAAmC;QACnC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QAC1D,mCAAmC;QACnC,OAAO;QACP,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAU,CAAC,IAAI,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAU,CAAC,UAAU,CAAC;YACnC,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC,CAAC;IAEV,CAAC;IAEO,qBAAqB,CAAC,WAAyB;QACnD,WAAW,CAAC,OAAO,CAAC,CAAC,UAAsB,EAAE,EAAE;YAC3C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;YAC5C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;gBACnC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAA;QACR,CAAC,CAAC,CAAC;IACP,CAAC;IAED,4CAA4C;IAC5C,yCAAyC;IACzC,IAAI;IAEG,MAAM;QACT,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE;YAC/C,OAAO,CAAC,GAAG,CAAC,0CAA0C,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,kBAAkB;QACtB,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;QAC/D,MAAM,GAAG,GAAG,uGAAuG,CAAA;QACnH,kBAAQ,CAAC,OAAO,CAAC,GAAG,CAAC;aACpB,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;aACnE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,GAAE,GAAG,CAAE,CAAC,CAAC;IAC5D,CAAC;CAEJ;AAED,kBAAe,GAAG,CAAC"}

@ -1,3 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=Icontroller.js.map

@ -1 +0,0 @@
{"version":3,"file":"Icontroller.js","sourceRoot":"","sources":["../../src/controller/Icontroller.ts"],"names":[],"mappings":""}

@ -1,34 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
class PingController {
constructor() {
this.path = '/ping';
this.router = (0, express_1.Router)();
this.initialiseRoutes();
}
initialiseRoutes() {
this.router.get("/ping", (_req, res) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.getMessage();
return res.send(response);
}));
}
getMessage() {
return __awaiter(this, void 0, void 0, function* () {
return {
message: "pong",
};
});
}
}
exports.default = PingController;
//# sourceMappingURL=TestCtrl.js.map

@ -1 +0,0 @@
{"version":3,"file":"TestCtrl.js","sourceRoot":"","sources":["../../src/controller/TestCtrl.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,qCAAiC;AAOjC,MAAqB,cAAc;IAI/B;QAHO,SAAI,GAAG,OAAO,CAAC;QACf,WAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;QAGrB,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IAEO,gBAAgB;QACpB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAO,IAAI,EAAE,GAAG,EAAE,EAAE;YACzC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YACzC,OAAO,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC,CAAA,CAAC,CAAC;IACT,CAAC;IACK,UAAU;;YACZ,OAAO;gBACP,OAAO,EAAE,MAAM;aACd,CAAC;QACN,CAAC;KAAA;CACJ;AAnBD,iCAmBC"}

@ -1,17 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class CryptString {
constructor(length) {
this.stringCrypt = this.generateRandomString(length);
}
generateRandomString(length) {
var text = '';
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
}
exports.default = CryptString;
//# sourceMappingURL=crypt.js.map

@ -1 +0,0 @@
{"version":3,"file":"crypt.js","sourceRoot":"","sources":["../../../src/controller/spotify-controller/crypt.ts"],"names":[],"mappings":";;AAAA,MAAqB,WAAW;IAI5B,YAAY,MAAe;QACvB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACzD,CAAC;IACD,oBAAoB,CAAE,MAAe;QACjC,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,QAAQ,GAAG,gEAAgE,CAAC;QAEhF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;YAC/B,IAAI,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;SACtE;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ;AAhBD,8BAgBC"}

@ -1,3 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=authReqBody.js.map

@ -1 +0,0 @@
{"version":3,"file":"authReqBody.js","sourceRoot":"","sources":["../../../../src/controller/spotify-controller/request/authReqBody.ts"],"names":[],"mappings":""}

@ -1,218 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const httpExeption_1 = __importDefault(require("../../middleware/exeption/httpExeption"));
const axios_1 = __importDefault(require("axios"));
const crypt_1 = __importDefault(require("./crypt"));
const qs_1 = __importDefault(require("qs"));
class SpotifyController {
constructor() {
this.path = '/spotify';
this.router = (0, express_1.Router)();
// need to put in ENvironement file
// private readonly CLIENT_CALLBACK_URL = "http://localhost:8080/callback";
this.API_URL = "https://accounts.spotify.com/api/token";
this.CLIENT_ID = "1f1e34e4b6ba48b388469dba80202b10";
this.CLIENT_SECRET = "779371c6d4994a68b8dd6e84b0873c82";
// private readonly CLIENT_CALLBACK_URL = "https://auth.expo.io/@thed47/FLAD//callback";
this.CALLBACK_2 = 'https://flad-api-production.up.railway.app/api/spotify/callback';
this.SCOPES = 'user-read-private user-read-email user-read-playback-state user-read-currently-playing user-read-recently-played playlist-modify-public ugc-image-upload user-modify-playback-state';
this.ENCRYPTION_SECRET = new crypt_1.default(16);
this.clientRedirect = 'spotify_final_redirect-uri-key';
this.login = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
console.log("useeeee== login");
try {
// const params = req.body;
// if (!params.refresh_token) {
// return res.json({
// "error": "Parameter missing"
// });
// }
// this.spotifyRequest({
// grant_type: "authorization_code",
// redirect_uri: this.CLIENT_CALLBACK_2,
// // code: params.code
// })
const redirectResponse = req.query.redirectUrl ? req.query.redirectUrl : req.headers.referer;
res.cookie(this.clientRedirect, redirectResponse);
console.log("aloorrr si c'est niquuuuuuuuuuuueeee" + this.CALLBACK_2 + "gennnnnnnnnrree vraiiiiiiiment ");
res.redirect('https://accounts.spotify.com/authorize?' +
qs_1.default.stringify({
response_type: 'code',
client_id: this.CLIENT_ID,
scope: this.SCOPES,
redirect_uri: this.CALLBACK_2,
// state: this.ENCRYPTION_SECRET.stringCrypt
}));
// '?response_type=code' +
// '&client_id=' +
// "1f1e34e4b6ba48b388469dba80202b10" +
// (this.SCOPES ? '&scope=' + encodeURIComponent(this.SCOPES) : '') +
// '&redirect_uri=' +
// encodeURIComponent(this.CALLBACK_2)
// );
// .then(session => {
// let result = {
// "access_token": session.access_token,
// "expires_in": session.expires_in,
// "refresh_token": this.encrypt(session.refresh_token)
// };
// return res.send(result);
// })
// .catch(response => {
// return res.json(response);
// });
}
catch (error) {
next(new httpExeption_1.default(400, 'Cannot create spot'));
}
});
this.getRefreshToken = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
console.log('UUse2');
try {
const params = req.query.refresh_token;
if (!req.query.refresh_token) {
return res.json({
"error": "Parameter refresh_token missing"
});
}
var authOptions = {
method: 'POST',
url: 'https://accounts.spotify.com/api/token',
data: qs_1.default.stringify({
grant_type: 'refresh_token',
refresh_token: params
}),
headers: {
'Authorization': 'Basic ' + (Buffer.from(this.CLIENT_ID + ':' + this.CLIENT_SECRET).toString('base64')),
'Content-Type': 'application/x-www-form-urlencoded'
},
json: true
};
// request.post(authOptions, function(error, response, body) {
// if (!error && response.statusCode === 200) {
// var access_token = body.access_token;
// res.send({
// 'access_token': access_token
// });
// }
// });
(0, axios_1.default)(authOptions)
.then(session => {
if (session.status === 200) {
console.log('### Information : responce ###' + JSON.stringify(session.data));
console.log('### Information : refresh_token ###' + session.data.refresh_token);
res.send({
"access_token": session.data.access_token,
"refresh_token": session.data.refresh_token,
"expires_in": session.data.expires_in
});
}
});
console.log("goood");
}
catch (error) {
console.log("errur");
next(new httpExeption_1.default(400, 'Cannot create post'));
}
});
this.getSpot = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
const spots = [
{
name: "blue",
sourceUrl: "https://cdns-images.dzcdn.net/images/artist/399e7e760d8fedf3cc2891e9c0c41658/200x200-000000-80-0-0.jpg",
index: 3
},
{
name: "strange history",
sourceUrl: "https://images.genius.com/339dfe2a7c0adf9a5d08febf29a845f4.1000x1000x1.jpg",
index: 7
},
{
name: "oboy album",
sourceUrl: "https://i.pinimg.com/originals/ad/cc/d5/adccd58a0d0ff516a6114703cd05810e.jpg",
index: 1
}
];
try {
res.send(spots);
}
catch (error) {
console.log('heuuuuuuuuuuuuuuuuuuuuubizzzaaarrreeee');
console.log(error);
next(new httpExeption_1.default(400, 'On peut pas avoir darray mec'));
}
});
this.getAccessToken = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
console.log("useeeee== accesToken");
var code = req.query.code;
var state = req.query.state || null;
var storedredirectUri = req.cookies ? req.cookies[this.clientRedirect] : null;
// var storedState = req.cookies ? req.cookies[stateKey] : null;
var authOptions = {
method: 'POST',
url: 'https://accounts.spotify.com/api/token',
data: qs_1.default.stringify({
code: code,
redirect_uri: this.CALLBACK_2,
grant_type: 'authorization_code'
}),
headers: {
'Authorization': 'Basic ' + (Buffer.from(this.CLIENT_ID + ':' + this.CLIENT_SECRET).toString('base64')),
'Content-Type': 'application/x-www-form-urlencoded'
},
json: true
};
try {
var resp = yield (0, axios_1.default)(authOptions);
if (resp.status === 200) {
console.log('oon esttt laaa');
var access_token = resp.data.access_token;
var expiration = resp.data.expires_in;
var refresh = resp.data.refresh_token;
console.log(access_token);
// res.send({
// "access_token": access_token,
// "expires_in": expiration,
// "refresh" : refresh
// });
res.clearCookie(this.clientRedirect);
res.redirect(`${storedredirectUri}?` +
qs_1.default.stringify({
"access_token": access_token,
"expires_in": expiration,
"refresh_token": refresh
}));
}
}
catch (error) {
console.log('heuuuuuuuuuuuuuuuuuuuuubizzzaaarrreeee');
console.log(error);
next(new httpExeption_1.default(400, 'On peut pas te connecter mec' + error.message));
}
});
console.log("useeeee");
this.initialiseRoutes();
}
initialiseRoutes() {
// this.router.post(`${this.path}`,this.createTask);
this.router.get(`${this.path}/exchange`, this.login);
this.router.get(`${this.path}/callback`, this.getAccessToken);
this.router.get(`${this.path}/refresh`, this.getRefreshToken);
this.router.get(`${this.path}/spot`, this.getSpot);
}
}
exports.default = SpotifyController;
//# sourceMappingURL=spotifyCtrl.js.map

File diff suppressed because one or more lines are too long

@ -1,193 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const httpExeption_1 = __importDefault(require("../../middleware/exeption/httpExeption"));
const UserService_1 = __importDefault(require("../../service/UserService"));
const UserValidation_1 = __importDefault(require("../../database/schema/User/UserValidation"));
const ValidatorMiddleware_1 = __importDefault(require("../../middleware/validation/ValidatorMiddleware"));
const authMiddleware_1 = __importDefault(require("../../middleware/authMiddleware"));
const LocationService_1 = __importDefault(require("../../service/LocationService"));
class UserController {
constructor() {
this.path = '/users';
this.router = (0, express_1.Router)();
this.userService = new UserService_1.default();
this.locationService = new LocationService_1.default();
// private createUser = async (
// req: Request,
// res: Response,
// next: NextFunction
// ): Promise<Response | void> => {
// try {
// console.log(req.body);
// const reqBody:CreateTaskReqBody = Object.assign({}, req.body);
// checkIfIsValidCreateTaskReqBody(reqBody);
// await this.userService.createUserById(reqBody.fin
// );
// res.status(200).send({ status: "Success", msg: "Success add" });
// } catch (error) {
// next(new HttpException(400, 'Cannot create post'));
// }
// };
// private readonly getUserById: RequestHandler = async (
// req: Request,
// res: Response,
// next: NextFunction
// ): Promise<Response | void> => {
// try {
// const id = req.params.taskId;
// const userId = req.params.userId;
// const data = await this.userService.getUserById(id, userId);
// res.status(201).send(data);
// }
// catch(error){
// next(new HttpException(400, 'Cannot create post'));
// }
// }
// private readonly getAllUsers: RequestHandler = async (
// req: Request,
// res: Response,
// next: NextFunction
// ): Promise<Response | void> => {
// try {
// const userId = req.params.userId;
// const tasks = await this.userService.getUsers(userId);
// const responseList = tasks.map(task => new TaskResumedRes(task));
// res.status(201).send(responseList);
// }
// catch(error){
// next(new HttpException(400, 'Cannot get user task'));
// }
// }
// private deleteUser = async (
// req: Request,
// res: Response,
// next: NextFunction
// ): Promise<Response | void> => {
// try {
// const id = req.params.taskId;
// const userId = req.params.userId;
// await this.userService.DeleteUser(id, userId);
// return res.status(200).send({ status: "Success", msg: "Data Removed" });
// } catch (error) {
// next(new HttpException(400, 'Cannot create post'));
// }
// };
// private updateUser = async (
// req: Request,
// res: Response,
// next: NextFunction
// ): Promise<Response | void> => {
// try {
// const taskId = req.params.taskId;
// const userId = req.params.userId;
// const reqBody:CreateTaskReqBody = Object.assign({}, req.body);
// const updatedTask = await this.userService.UpdateTask(
// // req.auth!.uid,
// taskId,
// userId,
// // firebase.auth().currentUser.getIdToken()
// reqBody.nom,
// reqBody.description,
// reqBody.logo,
// reqBody.duration,
// reqBody.done,
// // reqBody.tags,
// reqBody.repepat,
// reqBody.deb,
// reqBody.fin
// );
// // res.send('Success add');
// // res.status(201).json({ task });
// res.status(204).send(`Update a new contact: ${updatedTask}`);
// } catch (error) {
// console.log(error);
// next(new HttpException(403, 'Cannot create post'));
// }
// };
this.register = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
try {
// the FladId should be created by the Userservice
const { name, email, password, idFlad, idSpotify } = req.body;
console.log(name, email, password, idFlad, idSpotify);
const token = yield this.userService.register(name, email, password, idFlad, idSpotify);
res.status(201).json({ token });
}
catch (error) {
next(new httpExeption_1.default(400, error.message));
}
});
this.login = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
try {
const { email, password } = req.body;
const token = yield this.userService.login(email, password);
res.status(200).json({ token });
}
catch (error) {
next(new httpExeption_1.default(400, error.message));
}
});
this.getUser = (req, res, next) => {
if (!req.user) {
return next(new httpExeption_1.default(404, 'No logged in user'));
}
res.status(200).send({ data: req.user });
};
this.getUserNext = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
try {
const longitude = Number(req.query.longitude);
const latitude = Number(req.query.latitude);
//verify::val_int(){
console.log('woooooooooooooo' + req);
if (isNaN(longitude) || isNaN(latitude)) {
console.log('============' + longitude);
console.log('============' + latitude);
console.log('Impossible de convertir la chaîne en nombre');
}
//}
const userId = req.user.idFlad;
const musicId = String(req.query.currentMusic);
console.log('============' + longitude);
console.log('============' + latitude);
console.log('daaaaaaaaaaaaaaaaaaaaaa' + musicId);
const data = yield this.locationService.getNearUser(userId, musicId, latitude, longitude);
console.log(data);
res.status(201).send(data);
}
catch (error) {
next(new httpExeption_1.default(400, 'Cannot create get netUser'));
}
});
this.initialiseRoutes();
}
initialiseRoutes() {
this.router.post(`${this.path}/register`, (0, ValidatorMiddleware_1.default)(UserValidation_1.default.register), this.register);
this.router.post(`${this.path}/login`, (0, ValidatorMiddleware_1.default)(UserValidation_1.default.login), this.login);
this.router.get(`${this.path}`, authMiddleware_1.default, this.getUser);
this.router.get(`${this.path}/nextTo`, authMiddleware_1.default, this.getUserNext);
// //create
// this.router.post(`${this.path}`,this.createUser);
// // // get One
// this.router.get (`${this.path}/:userId`, this.getUserById);
// // // get All
// this.router.get (`${this.path}`, this.getAllUsers);
// //update One
// this.router.put (`${this.path}/:userId`, this.updateUser);
// //Delete One
// this.router.delete (`${this.path}/:userId`, this.deleteUser);
}
}
exports.default = UserController;
//# sourceMappingURL=userCtrl.js.map

@ -1 +0,0 @@
{"version":3,"file":"userCtrl.js","sourceRoot":"","sources":["../../../src/controller/user-controller/userCtrl.ts"],"names":[],"mappings":"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"}

@ -1,2 +0,0 @@
// export default db = new MongoClient(uri);
//# sourceMappingURL=MongoDataBase.js.map

@ -1 +0,0 @@
{"version":3,"file":"MongoDataBase.js","sourceRoot":"","sources":["../../src/database/MongoDataBase.ts"],"names":[],"mappings":"AACA,4CAA4C"}

@ -1 +0,0 @@
//# sourceMappingURL=StrategyDatabase.js.map

@ -1 +0,0 @@
{"version":3,"file":"StrategyDatabase.js","sourceRoot":"","sources":["../../src/database/StrategyDatabase.ts"],"names":[],"mappings":""}

@ -1,26 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const mongoose_1 = require("mongoose");
const locationSchema = new mongoose_1.Schema({
idFlad: {
type: String,
required: true,
unique: true,
},
musicId: {
type: String,
required: true,
},
latitude: {
type: Number,
required: true,
},
longitude: {
type: Number,
required: true,
},
}, { timestamps: true });
// fladDevDb
// ZslYlNRWIOUU7i6o
exports.default = (0, mongoose_1.model)('Location', locationSchema);
//# sourceMappingURL=LocationSchema.js.map

@ -1 +0,0 @@
{"version":3,"file":"LocationSchema.js","sourceRoot":"","sources":["../../../src/database/schema/LocationSchema.ts"],"names":[],"mappings":";;AAAA,uCAAkD;AAGlD,MAAM,cAAc,GAAG,IAAI,iBAAM,CAC7B;IAEI,MAAM,EAAE;QACJ,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,IAAI;KACf;IACD,OAAO,EAAE;QACL,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACjB;IACD,QAAQ,EAAE;QACN,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACjB;IACD,SAAS,EAAE;QACP,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACjB;CAGJ,EACD,EAAE,UAAU,EAAE,IAAI,EAAE,CACvB,CAAC;AAEF,YAAY;AACZ,mBAAmB;AACnB,kBAAe,IAAA,gBAAK,EAAY,UAAU,EAAE,cAAc,CAAC,CAAC"}

@ -1,9 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const mongoose_1 = require("mongoose");
const notificationSchema = new mongoose_1.Schema({
type: { type: String, required: true },
content: { type: String, required: true }
});
exports.default = { Notification: (0, mongoose_1.model)("nofitication", notificationSchema) };
//# sourceMappingURL=NotificationSchema.js.map

@ -1 +0,0 @@
{"version":3,"file":"NotificationSchema.js","sourceRoot":"","sources":["../../../src/database/schema/NotificationSchema.ts"],"names":[],"mappings":";;AAAA,uCAAyC;AAEzC,MAAM,kBAAkB,GAAG,IAAI,iBAAM,CAAC;IAClC,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAC;IACpC,OAAO,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAC;CAC1C,CAAC,CAAC;AAEH,kBAAe,EAAC,YAAY,EAAE,IAAA,gBAAK,EAAC,cAAc,EAAE,kBAAkB,CAAC,EAAC,CAAA"}

@ -1,3 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=IToken.js.map

@ -1 +0,0 @@
{"version":3,"file":"IToken.js","sourceRoot":"","sources":["../../../../src/database/schema/Token/IToken.ts"],"names":[],"mappings":""}

@ -1,3 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=UserInterface.js.map

@ -1 +0,0 @@
{"version":3,"file":"UserInterface.js","sourceRoot":"","sources":["../../../../src/database/schema/User/UserInterface.ts"],"names":[],"mappings":""}

@ -1,82 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const mongoose_1 = require("mongoose");
const bcrypt_1 = __importDefault(require("bcrypt"));
// const userSchema: Schema = new Schema<IUser>({
// pseudo: {type: String, index: { unique: true }},
// email: {type: String},
// idDafl: {type: String, index: { unique: true }},
// idSpotify: {type: String},
// password: {type: String},
// prenom: {type: String, default: ""},
// description: {type: String, default: ""},
// nom: {type: String, default: ""},
// ville: {type: String, default: ""},
// profilPic: {type: String},
// noteList: [],
// notifications: [],
// friends: {type: [String] },
// favoris: [],
// conversations: {type: [String] }
// });
const userSchema = new mongoose_1.Schema({
idFlad: {
type: String,
required: true,
unique: true,
},
idSpotify: {
type: String,
required: true,
unique: true,
},
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
// this mean that we identify user by email
unique: true,
// delete the whitespace
trim: true,
},
password: {
type: String,
},
}, { timestamps: true });
// this means that we hash the user password before saving it to the database
userSchema.pre('save', function (next) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.isModified('password')) {
//just had that to be sure that the api still going
return next();
}
const hash = yield bcrypt_1.default.hash(this.password, 8);
this.password = hash;
next();
});
});
userSchema.methods.isValidPassword = function (password) {
return __awaiter(this, void 0, void 0, function* () {
return yield bcrypt_1.default.compare(password, this.password);
});
};
// fladDevDb
// ZslYlNRWIOUU7i6o
exports.default = (0, mongoose_1.model)('User', userSchema);
// export const User: Model<IUser> = model('User', userSchema);
//# sourceMappingURL=UserSchema.js.map

@ -1 +0,0 @@
{"version":3,"file":"UserSchema.js","sourceRoot":"","sources":["../../../../src/database/schema/User/UserSchema.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAEA,uCAAyC;AACzC,oDAA4B;AAC5B,iDAAiD;AACjD,uDAAuD;AACvD,6BAA6B;AAC7B,uDAAuD;AACvD,iCAAiC;AACjC,gCAAgC;AAChC,2CAA2C;AAC3C,gDAAgD;AAChD,wCAAwC;AACxC,0CAA0C;AAC1C,iCAAiC;AACjC,oBAAoB;AACpB,yBAAyB;AACzB,kCAAkC;AAClC,mBAAmB;AACnB,uCAAuC;AACvC,MAAM;AAEN,MAAM,UAAU,GAAG,IAAI,iBAAM,CACzB;IAEI,MAAM,EAAE;QACJ,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,IAAI;KACf;IACD,SAAS,EAAE;QACP,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,IAAI;KACf;IACD,IAAI,EAAE;QACF,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACjB;IACD,KAAK,EAAE;QACH,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;QACd,2CAA2C;QAC3C,MAAM,EAAE,IAAI;QACZ,wBAAwB;QACxB,IAAI,EAAE,IAAI;KACb;IACD,QAAQ,EAAE;QACN,IAAI,EAAE,MAAM;KACf;CAEJ,EACD,EAAE,UAAU,EAAE,IAAI,EAAE,CACvB,CAAC;AAEF,6EAA6E;AAC7E,UAAU,CAAC,GAAG,CAAQ,MAAM,EAAE,UAAgB,IAAI;;QAC9C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;YAC9B,mDAAmD;YACnD,OAAO,IAAI,EAAE,CAAC;SACjB;QAED,MAAM,IAAI,GAAG,MAAM,gBAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAEjD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAErB,IAAI,EAAE,CAAC;IACX,CAAC;CAAA,CAAC,CAAC;AAEH,UAAU,CAAC,OAAO,CAAC,eAAe,GAAG,UACjC,QAAgB;;QAEhB,OAAO,MAAM,gBAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzD,CAAC;CAAA,CAAC;AAEF,YAAY;AACZ,mBAAmB;AACnB,kBAAe,IAAA,gBAAK,EAAQ,MAAM,EAAE,UAAU,CAAC,CAAC;AAChD,+DAA+D"}

@ -1,20 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const joi_1 = __importDefault(require("joi"));
const register = joi_1.default.object({
name: joi_1.default.string().max(30).required(),
email: joi_1.default.string().email().required(),
password: joi_1.default.string().min(6).required(),
// can add an field like confimPassword and cheked that the password is equal to the confirmPassword
idSpotify: joi_1.default.string(),
idFlad: joi_1.default.string(),
});
const login = joi_1.default.object({
email: joi_1.default.string().email().required(),
password: joi_1.default.string().required(),
});
exports.default = { register, login };
//# sourceMappingURL=UserValidation.js.map

@ -1 +0,0 @@
{"version":3,"file":"UserValidation.js","sourceRoot":"","sources":["../../../../src/database/schema/User/UserValidation.ts"],"names":[],"mappings":";;;;;AAAA,8CAAsB;AAEtB,MAAM,QAAQ,GAAG,aAAG,CAAC,MAAM,CAAC;IACxB,IAAI,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;IAErC,KAAK,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE;IAEtC,QAAQ,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACxC,oGAAoG;IACpG,SAAS,EAAE,aAAG,CAAC,MAAM,EAAE;IACvB,MAAM,EAAG,aAAG,CAAC,MAAM,EAAE;CACxB,CAAC,CAAC;AAEH,MAAM,KAAK,GAAG,aAAG,CAAC,MAAM,CAAC;IACrB,KAAK,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE;IACtC,QAAQ,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACpC,CAAC,CAAC;AAEH,kBAAe,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC"}

@ -1,14 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const app_1 = __importDefault(require("./app"));
const spotifyCtrl_1 = __importDefault(require("./controller/spotify-controller/spotifyCtrl"));
const TestCtrl_1 = __importDefault(require("./controller/TestCtrl"));
const userCtrl_1 = __importDefault(require("./controller/user-controller/userCtrl"));
const dotenv_1 = __importDefault(require("dotenv"));
dotenv_1.default.config();
const app = new app_1.default([new TestCtrl_1.default(), new spotifyCtrl_1.default(), new userCtrl_1.default()], Number(process.env.PORT));
app.listen();
//# sourceMappingURL=index.js.map

@ -1 +0,0 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,gDAAwB;AACxB,8FAA4E;AAC5E,qEAAmD;AACnD,qFAAmE;AACnE,oDAA2B;AAC3B,gBAAM,CAAC,MAAM,EAAE,CAAC;AAChB,MAAM,GAAG,GAAG,IAAI,aAAG,CACf,CAAC,IAAI,kBAAc,EAAE,EAAE,IAAI,qBAAiB,EAAE,EAAE,IAAI,kBAAc,EAAE,CAAC,EACrE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAE3B,CAAC;AAEF,GAAG,CAAC,MAAM,EAAE,CAAC"}

@ -1,46 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
const UserSchema_1 = __importDefault(require("../database/schema/User/UserSchema"));
const token_1 = __importDefault(require("../model/token"));
const httpExeption_1 = __importDefault(require("./exeption/httpExeption"));
function authenticatedMiddleware(req, res, next) {
return __awaiter(this, void 0, void 0, function* () {
const bearer = req.headers.authorization;
if (!bearer || !bearer.startsWith('Bearer ')) {
return next(new httpExeption_1.default(401, 'Unauthorised'));
}
const accessToken = bearer.split('Bearer ')[1].trim();
try {
const payload = yield token_1.default.verifyToken(accessToken);
if (payload instanceof jsonwebtoken_1.default.JsonWebTokenError) {
return next(new httpExeption_1.default(401, 'Unauthorised'));
}
const user = yield UserSchema_1.default.findById(payload.id)
.select('-password')
.exec();
if (!user) {
return next(new httpExeption_1.default(401, 'Unauthorised'));
}
req.user = user;
return next();
}
catch (error) {
return next(new httpExeption_1.default(401, 'Unauthorised'));
}
});
}
exports.default = authenticatedMiddleware;
//# sourceMappingURL=authMiddleware.js.map

@ -1 +0,0 @@
{"version":3,"file":"authMiddleware.js","sourceRoot":"","sources":["../../src/middleware/authMiddleware.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AACA,gEAA+B;AAE/B,oFAA4D;AAC5D,2DAAmC;AACnC,2EAAoD;AAEpD,SAAe,uBAAuB,CAClC,GAAY,EACZ,GAAa,EACb,IAAkB;;QAElB,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC;QAEzC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE;YAC1C,OAAO,IAAI,CAAC,IAAI,sBAAa,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;SACvD;QAED,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtD,IAAI;YACA,MAAM,OAAO,GAAmC,MAAM,eAAK,CAAC,WAAW,CACnE,WAAW,CACd,CAAC;YAEF,IAAI,OAAO,YAAY,sBAAG,CAAC,iBAAiB,EAAE;gBAC1C,OAAO,IAAI,CAAC,IAAI,sBAAa,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;aACvD;YAED,MAAM,IAAI,GAAG,MAAM,oBAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;iBAC7C,MAAM,CAAC,WAAW,CAAC;iBACnB,IAAI,EAAE,CAAC;YAEZ,IAAI,CAAC,IAAI,EAAE;gBACP,OAAO,IAAI,CAAC,IAAI,sBAAa,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;aACvD;YAED,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;YAEhB,OAAO,IAAI,EAAE,CAAC;SACjB;QAAC,OAAO,KAAK,EAAE;YACZ,OAAO,IAAI,CAAC,IAAI,sBAAa,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;SACvD;IACL,CAAC;CAAA;AAED,kBAAe,uBAAuB,CAAC"}

@ -1,12 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class HttpException extends Error {
constructor(status, message) {
super(message);
this.status = status;
this.message = message;
}
}
// en fontion de l'exeption firebas,etc une bonne exeption
exports.default = HttpException;
//# sourceMappingURL=httpExeption.js.map

@ -1 +0,0 @@
{"version":3,"file":"httpExeption.js","sourceRoot":"","sources":["../../../src/middleware/exeption/httpExeption.ts"],"names":[],"mappings":";;AAAA,MAAM,aAAc,SAAQ,KAAK;IAI7B,YAAY,MAAc,EAAE,OAAe;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;CACJ;AACD,0DAA0D;AAE1D,kBAAe,aAAa,CAAC"}

@ -1,34 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
function validationMiddleware(schema) {
return (req, res, next) => __awaiter(this, void 0, void 0, function* () {
const validationOptions = {
abortEarly: false,
allowUnknown: true,
stripUnknown: true,
};
try {
const value = yield schema.validateAsync(req.body, validationOptions);
req.body = value;
next();
}
catch (e) {
const errors = [];
e.details.forEach((error) => {
errors.push(error.message);
});
res.status(400).send({ errors: errors });
}
});
}
exports.default = validationMiddleware;
//# sourceMappingURL=ValidatorMiddleware.js.map

@ -1 +0,0 @@
{"version":3,"file":"ValidatorMiddleware.js","sourceRoot":"","sources":["../../../src/middleware/validation/ValidatorMiddleware.ts"],"names":[],"mappings":";;;;;;;;;;;AAGA,SAAS,oBAAoB,CAAC,MAAkB;IAC5C,OAAO,CACH,GAAY,EACZ,GAAa,EACb,IAAkB,EACL,EAAE;QACf,MAAM,iBAAiB,GAAG;YACtB,UAAU,EAAE,KAAK;YACjB,YAAY,EAAE,IAAI;YAClB,YAAY,EAAE,IAAI;SACrB,CAAC;QAEF,IAAI;YACA,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,aAAa,CACpC,GAAG,CAAC,IAAI,EACR,iBAAiB,CACpB,CAAC;YACF,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC;YACjB,IAAI,EAAE,CAAC;SACV;QAAC,OAAO,CAAM,EAAE;YACb,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAA8B,EAAE,EAAE;gBACjD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;SAC5C;IACL,CAAC,CAAA,CAAC;AACN,CAAC;AAED,kBAAe,oBAAoB,CAAC"}

@ -1,9 +0,0 @@
// export const loggerOptions: expressWinston.LoggerOptions = {
// transports: [new winston.transports.Console()],
// format: winston.format.combine(
// winston.format.json(),
// winston.format.prettyPrint(),
// winston.format.colorize({ all: true })
// ),
// };
//# sourceMappingURL=winston.js.map

@ -1 +0,0 @@
{"version":3,"file":"winston.js","sourceRoot":"","sources":["../../src/middleware/winston.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,sDAAsD;AACtD,sCAAsC;AACtC,iCAAiC;AACjC,wCAAwC;AACxC,iDAAiD;AACjD,SAAS;AACT,KAAK"}

@ -1,3 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=IUser.js.map

@ -1 +0,0 @@
{"version":3,"file":"IUser.js","sourceRoot":"","sources":["../../src/model/IUser.ts"],"names":[],"mappings":""}

@ -1,27 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Place = exports.UserLocation = exports.PlacePosition = void 0;
class PlacePosition {
constructor(timestamp, latitude, longitude) {
this.timestamp = timestamp;
this.coords = { latitude, longitude };
}
}
exports.PlacePosition = PlacePosition;
class UserLocation {
constructor(uuid, musicId, latitude, longitude) {
this.uuid = uuid;
this.musicId = musicId;
this.latitude = latitude;
this.longitude = longitude;
}
}
exports.UserLocation = UserLocation;
class Place {
constructor(address, position) {
this.position = position;
this.address = address;
}
}
exports.Place = Place;
//# sourceMappingURL=locationModel.js.map

@ -1 +0,0 @@
{"version":3,"file":"locationModel.js","sourceRoot":"","sources":["../../src/model/locationModel.ts"],"names":[],"mappings":";;;AAmBA,MAAa,aAAa;IAMtB,YAAY,SAAiB,EAAC,QAAiB,EAAE,SAAiB;QAC9D,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,EAAC,QAAQ,EAAE,SAAS,EAAC,CAAC;IACxC,CAAC;CACJ;AAVD,sCAUC;AACD,MAAa,YAAY;IAKrB,YAAY,IAAY,EAAE,OAAgB,EAAC,QAAgB,EAAE,SAAiB;QAC1E,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC/B,CAAC;CACJ;AAXD,oCAWC;AAED,MAAa,KAAK;IAGlB,YAAY,OAAgB,EAAC,QAAkB;QAC3C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;CACA;AAPD,sBAOC"}

@ -1,34 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyToken = exports.createToken = void 0;
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
const createToken = (user) => {
return jsonwebtoken_1.default.sign({ id: user._id }, "foo", {
expiresIn: '100d',
});
};
exports.createToken = createToken;
const verifyToken = (token) => __awaiter(void 0, void 0, void 0, function* () {
return new Promise((resolve, reject) => {
jsonwebtoken_1.default.verify(token, "foo", (err, payload) => {
if (err)
return reject(err);
resolve(payload);
});
});
});
exports.verifyToken = verifyToken;
exports.default = { createToken: exports.createToken, verifyToken: exports.verifyToken };
//# sourceMappingURL=token.js.map

@ -1 +0,0 @@
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/model/token.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,gEAA+B;AAIxB,MAAM,WAAW,GAAG,CAAC,IAAW,EAAU,EAAE;IAC/C,OAAO,sBAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAmB,EAAE;QACnD,SAAS,EAAE,MAAM;KACpB,CAAC,CAAC;AACP,CAAC,CAAC;AAJW,QAAA,WAAW,eAItB;AAEK,MAAM,WAAW,GAAG,CACvB,KAAa,EACqB,EAAE;IACpC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnC,sBAAG,CAAC,MAAM,CACN,KAAK,EACL,KAAmB,EACnB,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE;YACb,IAAI,GAAG;gBAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;YAE5B,OAAO,CAAC,OAAiB,CAAC,CAAC;QAC/B,CAAC,CACJ,CAAC;IACN,CAAC,CAAC,CAAC;AACP,CAAC,CAAA,CAAC;AAdW,QAAA,WAAW,eActB;AAEF,kBAAe,EAAE,WAAW,EAAX,mBAAW,EAAE,WAAW,EAAX,mBAAW,EAAE,CAAC"}

@ -1,116 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// import db from '../database';
const locationModel_1 = require("../model/locationModel");
const LocationSchema_1 = __importDefault(require("../database/schema/LocationSchema"));
class LocationService {
constructor() {
this.locationCollection = LocationSchema_1.default;
this.toRad = (value) => (value * Math.PI) / 180;
this.toDeg = (value) => (value * 180) / Math.PI;
// getCenter(coords)
}
// private API_KEY : string = "AIzaSyBFCEAtmhZ8jvw84UTQvX3Aqpr66GVqB_A";
getNearUser(idFlad, musicId, latitude, longitude) {
return __awaiter(this, void 0, void 0, function* () {
yield this.locationCollection.findOneAndUpdate({ idFlad }, { idFlad, musicId, latitude, longitude }, { upsert: true });
const snapshot = yield this.locationCollection.find({ idFlad: { $ne: idFlad } });
if (snapshot.length === 0) {
console.log('No matching documents.');
return;
}
let dbUsersList = [];
snapshot.forEach(doc => {
dbUsersList.push(new locationModel_1.UserLocation(doc.idFlad, doc.musicId, doc.latitude, doc.longitude));
console.log(doc.idFlad, '=>', doc);
});
// missing the curent music
let listUser = [];
const listUser2 = {};
dbUsersList.forEach(user => {
console.log(user);
const dist = this.distanceBetween(latitude, longitude, user.latitude, user.longitude);
console.log(user.uuid, dist);
if (dist <= 100) {
listUser.push(user.uuid);
listUser2[user.uuid] = user.musicId;
}
});
return { listUser, listUser2 };
// $listUser[] = {userID,idMusic};
});
}
getCenter(points) {
if (Array.isArray(points) === false || points.length === 0) {
return false;
}
const numberOfPoints = points.length;
const sum = points.reduce((acc, point) => {
const pointLat = this.toRad(point.coords.latitude);
const pointLon = this.toRad(point.coords.longitude);
return {
X: acc.X + Math.cos(pointLat) * Math.cos(pointLon),
Y: acc.Y + Math.cos(pointLat) * Math.sin(pointLon),
Z: acc.Z + Math.sin(pointLat),
};
}, { X: 0, Y: 0, Z: 0 });
const X = sum.X / numberOfPoints;
const Y = sum.Y / numberOfPoints;
const Z = sum.Z / numberOfPoints;
return {
longitude: this.toDeg(Math.atan2(Y, X)),
latitude: this.toDeg(Math.atan2(Z, Math.sqrt(X * X + Y * Y))),
};
}
;
// sa c'est un utils du coup mettre dans une calss utils
// resulta en km
distanceBetween(lat1, lon1, lat2, lon2) {
if ((lat1 == lat2) && (lon1 == lon2)) {
return 0;
}
else {
var radlat1 = Math.PI * lat1 / 180;
var radlat2 = Math.PI * lat2 / 180;
var theta = lon1 - lon2;
var radtheta = Math.PI * theta / 180;
var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
if (dist > 1) {
dist = 1;
}
dist = Math.acos(dist);
dist = dist * 180 / Math.PI;
dist = dist * 60 * 1.1515;
dist = dist * 1.609344;
return dist;
}
}
distanceBetweenPosition(first, second) {
return this.distanceBetween(first.coords.latitude, first.coords.longitude, second.coords.latitude, second.coords.longitude);
}
// give a array of position sorted by distance and return the first
findNearest(main, list) {
this.orderByDistance(main, list)[0];
}
//distanceFn: DistanceFn = getDistance est param sa serrait cool de lui passer un fonction
orderByDistance(mainPos, coords) {
return coords
.slice()
.sort((a, b) => this.distanceBetweenPosition(mainPos, a) - this.distanceBetweenPosition(mainPos, b));
}
;
}
exports.default = LocationService;
//# sourceMappingURL=LocationService.js.map

@ -1 +0,0 @@
{"version":3,"file":"LocationService.js","sourceRoot":"","sources":["../../src/service/LocationService.ts"],"names":[],"mappings":"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"}

@ -1,69 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const UserSchema_1 = __importDefault(require("../database/schema/User/UserSchema"));
const token_1 = __importDefault(require("../model/token"));
class UserService {
constructor() {
this.user = UserSchema_1.default;
}
/**
* Register a new user
*/
register(name, email, password, idFlad, idSpotify) {
return __awaiter(this, void 0, void 0, function* () {
try {
const user = yield this.user.create({
name,
email,
password,
idFlad,
idSpotify
});
const accessToken = token_1.default.createToken(user);
return accessToken;
}
catch (error) {
throw new Error(error.message);
}
});
}
/**
* Attempt to login a user
*/
login(email, password) {
return __awaiter(this, void 0, void 0, function* () {
try {
// should maybe creat a method base on id and other information for better security
// need to view with Emre
const user = yield this.user.findOne({ email });
// const user = await this.user.findById(idFlad);
if (!user) {
throw new Error('Unable to find user with that email address');
}
if (yield user.isValidPassword(password)) {
return token_1.default.createToken(user);
}
else {
throw new Error('Wrong credentials given');
}
}
catch (error) {
throw new Error('Unable to create user');
}
});
}
}
exports.default = UserService;
//# sourceMappingURL=UserService.js.map

@ -1 +0,0 @@
{"version":3,"file":"UserService.js","sourceRoot":"","sources":["../../src/service/UserService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,oFAA4D;AAC5D,2DAAmC;AAGnC,MAAM,WAAW;IAAjB;QACY,SAAI,GAAG,oBAAU,CAAC;IAuD9B,CAAC;IArDG;;OAEG;IACU,QAAQ,CACjB,IAAY,EACZ,KAAa,EACb,QAAgB,EAChB,MAAe,EACf,SAAkB;;YAElB,IAAI;gBACA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;oBAChC,IAAI;oBACJ,KAAK;oBACL,QAAQ;oBACR,MAAM;oBACN,SAAS;iBACZ,CAAC,CAAC;gBAEH,MAAM,WAAW,GAAG,eAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;gBAE5C,OAAO,WAAW,CAAC;aACtB;YAAC,OAAO,KAAW,EAAE;gBAClB,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;aAClC;QACL,CAAC;KAAA;IAED;;OAEG;IACU,KAAK,CACd,KAAa,EACb,QAAgB;;YAEhB,IAAI;gBACA,mFAAmF;gBACnF,yBAAyB;gBACzB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;gBAChD,iDAAiD;gBAEjD,IAAI,CAAC,IAAI,EAAE;oBACP,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;iBAClE;gBAED,IAAI,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE;oBACtC,OAAO,eAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;iBAClC;qBAAM;oBACH,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;iBAC9C;aACJ;YAAC,OAAO,KAAK,EAAE;gBACZ,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;aAC5C;QACL,CAAC;KAAA;CACJ;AAED,kBAAe,WAAW,CAAC"}

@ -0,0 +1,5 @@
{
"watch": ["src"],
"ext": ".ts.js",
"exec": "ts-node ./src/index.ts"
}

@ -1,13 +1,11 @@
{ {
"name": "api", "name": "flad_api",
"version": "1.0.0", "version": "1.0.0",
"description": "", "description": "",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"dave": "nodemon ./src/index.ts", "dev": "nodemon",
"dev": "tsc -w & nodemon .",
"start": "tsc & node .",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"keywords": [], "keywords": [],
@ -15,36 +13,30 @@
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {
"@types/bcrypt": "^5.0.0", "@types/bcrypt": "^5.0.0",
"@types/body-parser": "^1.19.2",
"@types/cors": "^2.8.13", "@types/cors": "^2.8.13",
"@types/debug": "^4.1.7",
"@types/express": "^4.17.16", "@types/express": "^4.17.16",
"@types/jsonwebtoken": "^9.0.1", "@types/jsonwebtoken": "^9.0.1",
"@types/morgan": "^1.9.4", "@types/swagger-jsdoc": "^6.0.4",
"@types/node": "^18.14.0", "@types/swagger-ui-express": "^4.1.6",
"nodemon": "^2.0.20", "nodemon": "^2.0.20",
"pre-commit": "^1.2.2",
"ts-node": "^10.9.1", "ts-node": "^10.9.1",
"typescript": "^4.9.5" "typescript": "^4.9.5"
}, },
"dependencies": { "dependencies": {
"@types/cookie-parser": "^1.4.3", "@types/cookie-parser": "^1.4.3",
"@types/crypto-js": "^4.1.1",
"@types/mongoose": "^5.11.97", "@types/mongoose": "^5.11.97",
"@types/request": "^2.48.8",
"axios": "^1.2.6", "axios": "^1.2.6",
"bcrypt": "^5.1.0", "bcrypt": "^5.1.0",
"build": "^0.1.4",
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^16.0.3", "dotenv": "^16.0.3",
"express-winston": "^4.2.0", "express": "^4.18.2",
"joi": "^17.8.1", "joi": "^17.8.1",
"jsonwebtoken": "^9.0.0", "jsonwebtoken": "^9.0.0",
"mongodb": "^5.0.0",
"mongoose": "^6.9.0", "mongoose": "^6.9.0",
"morgan": "^1.10.0", "swagger-jsdoc": "^6.2.8",
"request": "^2.88.2", "swagger-ui-express": "^5.0.0"
"rimraf": "^4.1.2",
"swagger-ui-express": "^4.6.0",
"winston": "^3.8.2"
} }
} }

@ -1,68 +1,60 @@
import express, { Application } from 'express'; import express, { Application } from 'express';
import cors from 'cors'; import cors from 'cors';
import Controller from './controller/Icontroller'; import cookieParser from 'cookie-parser';
import bodyParser from 'body-parser'; import bodyParser from 'body-parser';
import IController from './controllers/interfaces/IController';
import mongoose from 'mongoose'; import mongoose from 'mongoose';
import swaggerUi from "swagger-ui-express";
import cookieParser from 'cookie-parser'; import { specs } from './utils/swagger';
class App { class App {
public express: Application; public express: Application;
public port: number; public port: number;
public dataBase: null;
public server : any; constructor(controllers: IController[], port: number) {
constructor(controllers: Controller[], port: number) {
this.express = express(); this.express = express();
this.port = port; this.port = port;
this.dataBase = null;
this.initialiseDatabase();
this.initialiseMiddleware();
this.initialiseControllers(controllers);
this.initDatabase();
this.initMiddleware();
this.initControllers(controllers);
this.initSwagger();
} }
private initialiseMiddleware(): void { private initMiddleware(): void {
this.express.use(cors()); this.express.use(cors());
this.express.use(cookieParser()); this.express.use(cookieParser());
this.express.use(express.json()); this.express.use(express.json());
this.express.use(express.urlencoded({ extended: false })); this.express.use(express.urlencoded({ extended: false }));
this.express.use(bodyParser.json()); this.express.use(bodyParser.json());
this.express.use(bodyParser.urlencoded({ this.express.use(bodyParser.urlencoded({
extended: true extended: true
})); }));
} }
private initialiseControllers(controllers: Controller[]): void { private initControllers(controllers: IController[]): void {
controllers.forEach((controller: Controller) => { controllers.forEach((controller: IController) => {
this.express.use('/api', controller.router); this.express.use('/api', controller.router);
this.express.get('/toto', (req, res) => {
res.send('Hello World!');
})
}); });
} }
public listen(): void { public listen(): void {
const server = this.express.listen(this.port, () => { this.express.listen(this.port, () => {
console.log(`⚡️[server] : App listening on the port ${this.port}`); console.log(`⚡️[server] : App listening on the port ${this.port}`);
}); });
} }
private initialiseDatabase(): void { private initDatabase(): void {
const uri = "mongodb+srv://fladDevDb:ZslYlNRWIOUU7i6o@fladcluster.b29tytu.mongodb.net/?retryWrites=true&w=majority" const MONGO_URL = `mongodb+srv://FladDev:${process.env.MONGO_PASSWORD}@flad.mliekr2.mongodb.net/?retryWrites=true&w=majority`;
mongoose.connect(uri) mongoose.connect(MONGO_URL)
.then(() => console.log("Connect to MongoDB database successfully")) .then(() => console.log("Connect to MongoDB database successfully"))
.catch(err => console.log("Error connecting : "+ err )); .catch(error => console.log("Error connecting : " + error));
} }
public initSwagger(): void {
this.express.use("/swagger", swaggerUi.serve, swaggerUi.setup(specs),);
console.log(`Docs available at /${this.port}/swagger`);
}
} }
export default App; export default App;

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

@ -1,15 +0,0 @@
import { Router } from 'express';
interface Controller {
path: string;
router: Router;
// constructor() {
// this.initialiseRoutes();
// }
// initialiseRoutes(): void ;
}
// il y a un truc inject
export default Controller;

@ -1,27 +0,0 @@
import { Router } from "express";
import Controller from "./Icontroller";
type PingResponse = {
message: string;
}
export default class PingController implements Controller {
public path = '/ping';
public router = Router();
constructor() {
this.initialiseRoutes();
}
private initialiseRoutes(): void {
this.router.get("/ping", async (_req, res) => {
const response = await this.getMessage();
return res.send(response);
});
}
async getMessage(): Promise<PingResponse> {
return {
message: "pong",
};
}
}

@ -1,6 +0,0 @@
export type AuthReqBody = {
grant_type: string,
redirect_uri?: string,
code?: string,
refresh_token?: string,
}

@ -1,198 +0,0 @@
import Controller from '../Icontroller';
import { Router, Request, Response, NextFunction } from 'express';
import HttpException from '../../middleware/exeption/httpExeption';
import axios from 'axios';
import qs from 'qs';
class SpotifyController implements Controller {
public path = '/spotify';
public router = Router();
constructor() {
console.log("useeeee");
this.initialiseRoutes();
}
initialiseRoutes() {
this.router.get(`${this.path}/exchange`,this.login);
this.router.get(`${this.path}/callback`,this.getAccessToken);
this.router.get(`${this.path}/refresh`,this.getRefreshToken);
this.router.get(`${this.path}/spot`, this.getSpot);
}
private readonly API_URL = "https://accounts.spotify.com/api/token";
private readonly CLIENT_ID = "1f1e34e4b6ba48b388469dba80202b10";
private readonly CLIENT_SECRET = "779371c6d4994a68b8dd6e84b0873c82";
private readonly CALLBACK_2 = 'https://flad-api-production.up.railway.app/api/spotify/callback';
private readonly SCOPES ='user-read-private user-read-email user-read-playback-state user-read-currently-playing user-read-recently-played playlist-modify-public ugc-image-upload user-modify-playback-state';
private readonly clientRedirect= 'spotify_final_redirect-uri-key';
private login = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> => {
console.log("useeeee== login");
try {
const redirectResponse = req.query.redirectUrl ? req.query.redirectUrl : req.headers.referer;
res.cookie(this.clientRedirect, redirectResponse);
console.log("aloorrr si c'est niquuuuuuuuuuuueeee" +this.CALLBACK_2+ "gennnnnnnnnrree vraiiiiiiiment ");
res.redirect('https://accounts.spotify.com/authorize?' +
qs.stringify({
response_type: 'code',
client_id: this.CLIENT_ID,
scope: this.SCOPES,
redirect_uri: this.CALLBACK_2,
}));
} catch (error) {
next(new HttpException(400, 'Cannot create spot'));
}
};
private getRefreshToken = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> => {
console.log('UUse2');
try {
const params = req.query.refresh_token;
if (!req.query.refresh_token) {
return res.json({
"error": "Parameter refresh_token missing"
});
}
let authOptions = {
method: 'POST',
url: 'https://accounts.spotify.com/api/token',
data: qs.stringify({
grant_type: 'refresh_token',
refresh_token: params
}),
headers: {
'Authorization': 'Basic ' + ( Buffer.from(this.CLIENT_ID + ':' + this.CLIENT_SECRET).toString('base64')),
'Content-Type' : 'application/x-www-form-urlencoded'
},
json: true
};
axios(authOptions)
.then(session => {
if(session.status === 200){
console.log('### Information : responce ###' + JSON.stringify( session.data) );
console.log('### Information : refresh_token ###' + session.data.refresh_token);
res.send({
"access_token": session.data.access_token,
"refresh_token": session.data.refresh_token,
"expires_in": session.data.expires_in
});
}});
console.log("goood");
} catch (error) {
console.log("errur");
next(new HttpException(400, 'Cannot create post'));
}
}
public getSpot = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> => {
const spots = [
{
name: "blue",
sourceUrl: "https://cdns-images.dzcdn.net/images/artist/399e7e760d8fedf3cc2891e9c0c41658/200x200-000000-80-0-0.jpg",
index: 3
},
{
name: "strange history",
sourceUrl: "https://images.genius.com/339dfe2a7c0adf9a5d08febf29a845f4.1000x1000x1.jpg",
index: 7
},
{
name: "oboy album",
sourceUrl: "https://i.pinimg.com/originals/ad/cc/d5/adccd58a0d0ff516a6114703cd05810e.jpg",
index: 1
}
];
try {
res.send(spots);
} catch (error) {
console.log('heuuuuuuuuuuuuuuuuuuuuubizzzaaarrreeee');
console.log(error);
next(new HttpException(400, 'On peut pas avoir darray mec'));
} }
private getAccessToken = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> => {
console.log("useeeee== accesToken");
let code = req.query.code;
let state = req.query.state || null;
let storedredirectUri = req.cookies ? req.cookies[this.clientRedirect] : null;
var authOptions = {
method: 'POST',
url: 'https://accounts.spotify.com/api/token',
data: qs.stringify({
code: code,
redirect_uri: this.CALLBACK_2,
grant_type: 'authorization_code'
}),
headers: {
'Authorization': 'Basic ' + ( Buffer.from(this.CLIENT_ID + ':' + this.CLIENT_SECRET).toString('base64')),
'Content-Type' : 'application/x-www-form-urlencoded'
},
json: true
};
try {
var resp = await axios(authOptions);
if (resp.status === 200) {
console.log('oon esttt laaa');
let access_token = resp.data.access_token;
let expiration =resp.data.expires_in;
let refresh = resp.data.refresh_token
console.log(access_token);
res.clearCookie(this.clientRedirect);
res.redirect(`${storedredirectUri}?` +
qs.stringify({
"access_token": access_token,
"expires_in": expiration,
"refresh_token" : refresh
}));
}
} catch (error) {
console.log('heuuuuuuuuuuuuuuuuuuuuubizzzaaarrreeee');
console.log(error);
next(new HttpException(400, 'On peut pas te connecter mec'+ error.message));
}
};
}
export default SpotifyController;

@ -1,254 +0,0 @@
import { Router, Request, Response, NextFunction, RequestHandler } from 'express';
import Controller from '../Icontroller';
import HttpException from '../../middleware/exeption/httpExeption';
// import LocationService from '../../service/LocationService';
import IUser from '../../database/schema/User/UserInterface';
import UserService from '../../service/UserService';
import validator from '../../database/schema/User/UserValidation'
import validationMiddleware from '../../middleware/validation/ValidatorMiddleware';
import authenticator from '../../middleware/authMiddleware'
import LocationService from '../../service/LocationService';
class UserController implements Controller {
public path = '/users';
public router = Router();
private userService = new UserService();
private locationService = new LocationService();
constructor() {
this.initialiseRoutes();
}
private initialiseRoutes(): void {
this.router.post(
`${this.path}/register`,
validationMiddleware(validator.register),
this.register
);
this.router.post(
`${this.path}/login`,
validationMiddleware(validator.login),
this.login
);
this.router.get(`${this.path}`, authenticator, this.getUser);
this.router.get(`${this.path}/nextTo`, authenticator, this.getUserNext);
// //create
// this.router.post(`${this.path}`,this.createUser);
// // // get One
// this.router.get (`${this.path}/:userId`, this.getUserById);
// // // get All
// this.router.get (`${this.path}`, this.getAllUsers);
// //update One
// this.router.put (`${this.path}/:userId`, this.updateUser);
// //Delete One
// this.router.delete (`${this.path}/:userId`, this.deleteUser);
}
// private createUser = async (
// req: Request,
// res: Response,
// next: NextFunction
// ): Promise<Response | void> => {
// try {
// console.log(req.body);
// const reqBody:CreateTaskReqBody = Object.assign({}, req.body);
// checkIfIsValidCreateTaskReqBody(reqBody);
// await this.userService.createUserById(reqBody.fin
// );
// res.status(200).send({ status: "Success", msg: "Success add" });
// } catch (error) {
// next(new HttpException(400, 'Cannot create post'));
// }
// };
// private readonly getUserById: RequestHandler = async (
// req: Request,
// res: Response,
// next: NextFunction
// ): Promise<Response | void> => {
// try {
// const id = req.params.taskId;
// const userId = req.params.userId;
// const data = await this.userService.getUserById(id, userId);
// res.status(201).send(data);
// }
// catch(error){
// next(new HttpException(400, 'Cannot create post'));
// }
// }
// private readonly getAllUsers: RequestHandler = async (
// req: Request,
// res: Response,
// next: NextFunction
// ): Promise<Response | void> => {
// try {
// const userId = req.params.userId;
// const tasks = await this.userService.getUsers(userId);
// const responseList = tasks.map(task => new TaskResumedRes(task));
// res.status(201).send(responseList);
// }
// catch(error){
// next(new HttpException(400, 'Cannot get user task'));
// }
// }
// private deleteUser = async (
// req: Request,
// res: Response,
// next: NextFunction
// ): Promise<Response | void> => {
// try {
// const id = req.params.taskId;
// const userId = req.params.userId;
// await this.userService.DeleteUser(id, userId);
// return res.status(200).send({ status: "Success", msg: "Data Removed" });
// } catch (error) {
// next(new HttpException(400, 'Cannot create post'));
// }
// };
// private updateUser = async (
// req: Request,
// res: Response,
// next: NextFunction
// ): Promise<Response | void> => {
// try {
// const taskId = req.params.taskId;
// const userId = req.params.userId;
// const reqBody:CreateTaskReqBody = Object.assign({}, req.body);
// const updatedTask = await this.userService.UpdateTask(
// // req.auth!.uid,
// taskId,
// userId,
// // firebase.auth().currentUser.getIdToken()
// reqBody.nom,
// reqBody.description,
// reqBody.logo,
// reqBody.duration,
// reqBody.done,
// // reqBody.tags,
// reqBody.repepat,
// reqBody.deb,
// reqBody.fin
// );
// // res.send('Success add');
// // res.status(201).json({ task });
// res.status(204).send(`Update a new contact: ${updatedTask}`);
// } catch (error) {
// console.log(error);
// next(new HttpException(403, 'Cannot create post'));
// }
// };
private register = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> => {
try {
// the FladId should be created by the Userservice
const { name, email, password , idFlad, idSpotify } = req.body;
console.log(name, email, password, idFlad, idSpotify);
const token = await this.userService.register(
name,
email,
password,
idFlad,
idSpotify
);
res.status(201).json({ token });
} catch (error : any) {
next(new HttpException(400, error.message));
}
};
private login = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> => {
try {
const { email, password } = req.body;
const token = await this.userService.login(email, password);
res.status(200).json({ token });
} catch (error : any) {
next(new HttpException(400, error.message));
}
};
private getUser = (
req: Request,
res: Response,
next: NextFunction
): Response | void => {
if (!req.user) {
return next(new HttpException(404, 'No logged in user'));
}
res.status(200).send({ data: req.user });
};
private getUserNext = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> => {
try {
const longitude = Number(req.query.longitude);
const latitude = Number(req.query.latitude);
//verify::val_int(){
console.log('woooooooooooooo' + req);
if (isNaN(longitude) || isNaN(latitude)) {
console.log('============' + longitude)
console.log('============' + latitude)
console.log('Impossible de convertir la chaîne en nombre');
}
//}
const userId = req.user.idFlad;
const musicId = String(req.query.currentMusic);
console.log('============' + longitude)
console.log('============' + latitude)
console.log('daaaaaaaaaaaaaaaaaaaaaa' + musicId);
const data = await this.locationService.getNearUser(userId,musicId,latitude,longitude);
console.log(data);
res.status(201).send(data);
}
catch(error : any){
next(new HttpException(400, 'Cannot create get netUser'));
}
}
}
export default UserController;
declare global {
namespace Express {
export interface Request {
user: IUser;
}
}
}

@ -0,0 +1,8 @@
import { Router } from 'express';
interface IController {
path: string;
router: Router;
}
export default IController;

@ -0,0 +1,196 @@
import IController from './interfaces/IController';
import { Router, Request, Response } from 'express';
import axios from 'axios';
import qs from 'qs';
class SpotifyController implements IController {
public path = '/spotify';
public router = Router();
public readonly CLIENT_ID_SPOTIFY = process.env.CLIENT_ID_SPOTIFY;
public readonly CLIENT_SECRET_SPOTIFY = process.env.CLIENT_SECRET_SPOTIFY;
private readonly API_URL = "https://accounts.spotify.com/api/token";
private readonly CALLBACK = 'http://localhost:8080/api/spotify/callback';
private readonly SCOPES = 'user-read-private user-read-email user-read-playback-state user-read-currently-playing user-read-recently-played playlist-modify-public ugc-image-upload user-modify-playback-state';
constructor() {
this.initRoutes();
}
initRoutes() {
/**
* @swagger
* /api/spotify/exchange:
* get:
* summary: Initiate the Spotify login flow
* description: Redirect the user to the Spotify login page for authorization
* tags:
* - Spotify
* parameters:
* - in: query
* name: redirectUrl
* schema:
* type: string
* description: The URL to redirect the user after Spotify authorization (optional)
* responses:
* 302:
* description: Redirecting to Spotify login page
* 400:
* description: Bad request - Cannot connect to Spotify
*/
this.router.get(`${this.path}/exchange`, this.login);
/**
* @swagger
* /api/spotify/callback:
* get:
* summary: Handle Spotify callback and exchange code for access token
* description: Handle Spotify callback and exchange the received code for an access token
* tags:
* - Spotify
* responses:
* 302:
* description: Redirecting with access token information
* 400:
* description: Bad request - Error connecting to Spotify
*/
this.router.get(`${this.path}/callback`, this.getAccessToken);
/**
* @swagger
* /api/spotify/refresh:
* get:
* summary: Refresh the Spotify access token using a refresh token
* description: Refresh the Spotify access token using a refresh token
* tags:
* - Spotify
* parameters:
* - in: query
* name: refresh_token
* schema:
* type: string
* required: true
* description: The refresh token obtained during the initial authorization
* responses:
* 200:
* description: Successfully refreshed access token
* content:
* application/json:
* schema:
* type: object
* properties:
* access_token:
* type: string
* description: The new access token
* refresh_token:
* type: string
* description: The new refresh token
* expires_in:
* type: number
* description: The time until the access token expires (in seconds)
* 400:
* description: Bad request - Cannot refresh the access token
*/
this.router.get(`${this.path}/refresh`, this.getRefreshToken);
}
private readonly clientRedirect = 'spotify_final_redirect-uri-key';
private login = async (
req: Request,
res: Response
): Promise<Response | void> => {
try {
const redirectResponse = req.query.redirectUrl ? req.query.redirectUrl : req.headers.referer;
res.cookie(this.clientRedirect, redirectResponse);
res.redirect('https://accounts.spotify.com/authorize?' +
qs.stringify({
response_type: 'code',
client_id: this.CLIENT_ID_SPOTIFY,
scope: this.SCOPES,
redirect_uri: this.CALLBACK,
}));
} catch (error) {
res.status(400).send('Cannot connect: ' + error.message);
}
};
private getRefreshToken = async (
req: Request,
res: Response
): Promise<Response | void> => {
const params = req.query.refresh_token;
if (!req.query.refresh_token) {
return res.json({
"error": "Parameter refresh_token missing"
});
}
const authOptions = {
method: 'POST',
url: 'https://accounts.spotify.com/api/token',
data: qs.stringify({
grant_type: 'refresh_token',
refresh_token: params
}),
headers: {
'Authorization': 'Basic ' + (Buffer.from(this.CLIENT_ID_SPOTIFY + ':' + this.CLIENT_SECRET_SPOTIFY).toString('base64')),
'Content-Type': 'application/x-www-form-urlencoded'
},
json: true
};
axios(authOptions)
.then(session => {
if (session.status === 200) {
res.send({
"access_token": session.data.access_token,
"refresh_token": session.data.refresh_token,
"expires_in": session.data.expires_in
});
}
})
.catch(error => {
res.status(400).send("Cannot get a new refresh token");
});
}
private getAccessToken = async (
req: Request,
res: Response
): Promise<Response | void> => {
let code = req.query.code;
let storedRedirectUri = req.cookies ? req.cookies[this.clientRedirect] : null;
let authOptions = {
method: 'POST',
url: this.API_URL,
data: qs.stringify({
code: code,
redirect_uri: this.CALLBACK,
grant_type: 'authorization_code'
}),
headers: {
'Authorization': 'Basic ' + (Buffer.from(this.CLIENT_ID_SPOTIFY + ':' + this.CLIENT_SECRET_SPOTIFY).toString('base64')),
'Content-Type': 'application/x-www-form-urlencoded'
},
json: true
};
try {
const resp = await axios(authOptions);
if (resp.status === 200) {
let access_token = resp.data.access_token;
let expiration = resp.data.expires_in;
let refresh = resp.data.refresh_token
res.clearCookie(this.clientRedirect);
res.redirect(`${storedRedirectUri}?` +
qs.stringify({
"access_token": access_token,
"expires_in": expiration,
"refresh_token": refresh
}));
}
} catch (error) {
res.status(400).send('Error connection: ' + error.message);
}
};
}
export default SpotifyController;

@ -0,0 +1,803 @@
import { Router, Request, Response } from 'express';
import IController from './interfaces/IController';
import User from '../models/User';
import UserService from '../services/UserService';
import validator from '../middlewares/UserValidation'
import validationMiddleware from '../middlewares/validationMiddleware';
import authenticator from '../middlewares/authMiddleware'
import LocationService from '../services/LocationService';
import axios from 'axios';
import { IMusic } from '../models/Music';
import * as fs from 'fs';
import * as base64js from 'base64-js';
class UserController implements IController {
public path = '/user';
public authPath = '/auth';
public router = Router();
private userService = new UserService();
private locationService = new LocationService();
constructor() {
this.initRoutes();
}
private initRoutes(): void {
/**
* @swagger
* /api/auth/register:
* post:
* summary: Register a new user
* description: Register a new user with the provided details
* tags:
* - Authentication
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* email:
* type: string
* default: john.doe@example.com
* password:
* type: string
* default: stringPassword123
* name:
* type: string
* default: john_doe
* tokenSpotify:
* type: string
* responses:
* 201:
* description: User registered successfully
* 400:
* description: Bad request - Invalid input data
* 401:
* description: Unauthorized - Spotify token is invalid
* 409:
* description: Conflict - Email or username is already in use
* 500:
* description: Internal Server Error - Spotify account not authorized or not found
*/
this.router.post(
`${this.authPath}/register`,
validationMiddleware(validator.register),
this.register
);
/**
* @swagger
* /api/auth/login:
* post:
* summary: Login a user
* description: Login with the provided email and password
* tags:
* - Authentication
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* email:
* type: string
* default: john.doe@example.com
* password:
* type: string
* default: stringPassword123
* responses:
* 200:
* description: User logged in successfully
* content:
* application/json:
* schema:
* type: object
* properties:
* token:
* type: string
* 400:
* description: Bad request - Invalid input data
*/
this.router.post(
`${this.authPath}/login`,
validationMiddleware(validator.login),
this.login
);
/**
* @swagger
* /api/user:
* get:
* summary: Get user information
* description: Get information about the authenticated user
* tags:
* - User
* security:
* - bearerAuth: []
* responses:
* 200:
* description: User logged in successfully
* 401:
* description: Unauthorized - Invalid or missing authentication token
*/
this.router.get(`${this.path}`, authenticator, this.getUser);
/**
* @swagger
* /api/users:
* get:
* summary: Get information about multiple users
* description: Get information about multiple users based on provided user ids
* tags:
* - User
* security:
* - bearerAuth: []
* parameters:
* - in: query
* name: ids
* schema:
* type: string
* description: Comma-separated list of user ids
* responses:
* 200:
* description: Users information retrieved successfully
* 401:
* description: Unauthorized - Invalid or missing authentication token
*/
this.router.get(`${this.path}s`, authenticator, this.getUsers);
/**
* @swagger
* /api/user:
* delete:
* summary: Delete the authenticated user
* description: Delete the authenticated user and associated data
* tags:
* - User
* security:
* - bearerAuth: []
* responses:
* 204:
* description: User deleted successfully
* 401:
* description: Unauthorized - Invalid or missing authentication token
* 404:
* description: User not found
*/
this.router.delete(`${this.path}`, authenticator, this.deleteUser);
/**
* @swagger
* /api/user/nextTo:
* get:
* summary: Get users near the authenticated user
* description: Get information about users near the authenticated user based on location
* tags:
* - User
* security:
* - bearerAuth: []
* parameters:
* - in: query
* name: longitude
* schema:
* type: number
* description: Longitude of the user's current location
* - in: query
* name: latitude
* schema:
* type: number
* description: Latitude of the user's current location
* - in: query
* name: currentMusic
* schema:
* type: string
* description: The ID of the currently playing music
* responses:
* 201:
* description: Users near the authenticated user retrieved successfully
* content:
* application/json:
* schema:
* type: object
* properties:
* data:
* type: array
* 401:
* description: Unauthorized - Invalid or missing authentication token
* 400:
* description: Bad request - Invalid input data
*/
this.router.get(`${this.path}/nextTo`, authenticator, this.getUserNext);
/**
* @swagger
* /api/user/musics/{id}:
* delete:
* summary: Delete a music from the authenticated user's liked list
* description: Delete a music from the authenticated user's liked list by music id
* tags:
* - User
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* schema:
* type: string
* description: The ID of the music to delete
* responses:
* 200:
* description: Music deleted successfully
* 401:
* description: Unauthorized - Invalid or missing authentication token
* 404:
* description: Music not found
*/
this.router.delete(`${this.path}/musics/:id`, authenticator, this.deleteMusic);
/**
* @swagger
* /api/user/musics:
* post:
* summary: Add a music to the authenticated user's liked list
* description: Add a music to the authenticated user's liked list
* tags:
* - User
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* musicId:
* type: string
* description: The ID of the music to add
* userId:
* type: string
* description: The ID of the user who liked the music
* responses:
* 201:
* description: Music added to liked list successfully
* 401:
* description: Unauthorized - Invalid or missing authentication token
* 400:
* description: Bad request - Invalid input data
*/
this.router.post(`${this.path}/musics`, authenticator, this.addMusic);
/**
* @swagger
* /api/user/musics:
* get:
* summary: Get the list of musics liked by the authenticated user
* description: Get the list of musics liked by the authenticated user
* tags:
* - User
* security:
* - bearerAuth: []
* responses:
* 200:
* description: List of musics retrieved successfully
* content:
* application/json:
* schema:
* type: object
* properties:
* musics:
* type: array
* 401:
* description: Unauthorized - Invalid or missing authentication token
*/
this.router.get(`${this.path}/musics`, authenticator, this.getMusics);
/**
* @swagger
* /api/user/name:
* put:
* summary: Update the name of the authenticated user
* description: Update the name of the authenticated user
* tags:
* - User
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* description: The new name for the user
* responses:
* 200:
* description: User name updated successfully
* 401:
* description: Unauthorized - Invalid or missing authentication token
* 400:
* description: Bad request - Invalid input data
* 409:
* description: Conflict - The provided name is already in use by another user
*/
this.router.put(`${this.path}/name`, authenticator, this.setName);
/**
* @swagger
* /api/user/email:
* put:
* summary: Update the email of the authenticated user
* description: Update the email of the authenticated user
* tags:
* - User
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* email:
* type: string
* format: email
* description: The new email for the user
* responses:
* 200:
* description: User email updated successfully
* 401:
* description: Unauthorized - Invalid or missing authentication token
* 400:
* description: Bad request - Invalid input data
* 409:
* description: Conflict - The provided email is already in use by another user
*/
this.router.put(`${this.path}/email`, authenticator, this.setEmail);
/**
* @swagger
* /api/user/spotify:
* put:
* summary: Update the spotify account
* description: Update the spotify account of the authenticated user
* tags:
* - User
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* tokenSpotify:
* type: string
* description: Spotify token
* responses:
* 200:
* description: Spotify account updated successfully
* 401:
* description: Unauthorized - Invalid or missing authentication token
* 409:
* description: Conflict - The provided token is already in use by another user
* 500:
* description: Internal Server Error - Spotify account not authorized or not found
*/
this.router.put(`${this.path}/spotify`, authenticator, this.setSpotify);
/**
* @swagger
* /api/user/image:
* put:
* summary: Update the profile image of the authenticated user
* description: Update the profile image of the authenticated user
* tags:
* - User
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* image:
* type: string
* format: base64
* description: The new profile image for the user (base64 encoded)
* responses:
* 200:
* description: User profile image updated successfully
* 401:
* description: Unauthorized - Invalid or missing authentication token
* 500:
* description: Internal Server Error - Unable to update the profile image
*/
this.router.put(`${this.path}/image`, authenticator, this.setImage);
/**
* @swagger
* /api/user/password:
* put:
* summary: Update the password of the authenticated user
* description: Update the password of the authenticated user
* tags:
* - User
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* oldPassword:
* type: string
* description: The current password of the user
* newPassword:
* type: string
* description: The new password for the user
* responses:
* 200:
* description: User password updated successfully
* 401:
* description: Unauthorized - Invalid or missing authentication token
* 500:
* description: Internal Server Error - Unable to update the password
*/
this.router.put(`${this.path}/password`, authenticator, this.setPassword);
}
private register = async (
req: Request,
res: Response
): Promise<Response | void> => {
let access_token;
let idSpotify: string;
let image: string;
const { name, email, password, tokenSpotify } = req.body;
const apiBaseUrl = process.env.API_BASE_URL || 'http://localhost:8080/api';
const refreshUrl = `${apiBaseUrl}/spotify/refresh?refresh_token=${tokenSpotify}`;
try {
const authOptions = {
method: 'GET',
url: refreshUrl,
json: true
};
const authResponse = await axios(authOptions);
if (authResponse.status === 200) {
access_token = authResponse.data.access_token;
const headers = {
Authorization: `Bearer ${access_token}`,
};
const resp = await axios.get('https://api.spotify.com/v1/me', { headers });
if (resp.status == 200) {
const images = resp.data.images;
idSpotify = resp.data.id;
if (images && images.length > 0) {
images.sort((a: any, b: any) => b.height - a.height);
image = images[0].url;
}
else {
const imagePath = './src/assets/images/default_user.png';
const imageBuffer = fs.readFileSync(imagePath);
const base64Image = 'data:image/png;base64,' + base64js.fromByteArray(imageBuffer);
image = base64Image
}
}
}
} catch (error: any) {
console.log(error);
if (error.response.status === 400) {
res.status(401).send("Unauthorized: Spotify token is invalid");
return;
}
res.status(500).send("Internal Server Error: Unable to authenticate with Spotify");
return;
}
try {
const token = await this.userService.register(
name.toLowerCase(),
email.toLowerCase(),
password,
idSpotify,
tokenSpotify,
image
);
res.status(201).json({ token });
} catch (error: any) {
res.status(409).json(error.message);
}
};
private login = async (
req: Request,
res: Response
): Promise<Response | void> => {
try {
const { email, password } = req.body;
const token = await this.userService.login(email, password);
res.status(200).json({ token });
} catch (error: any) {
res.status(400).json(error.message)
}
};
private getUser = (
req: Request,
res: Response
): Response | void => {
res.status(200).send({ data: req.user });
};
private getUsers = async (
req: Request,
res: Response
): Promise<Response | void> => {
const userIds = req.query.ids as string;
if (!userIds) {
return res.status(200).json([]);
}
const userIdArray = userIds.split('&');
try {
const users = await this.userService.getUsers(userIdArray);
res.json(users);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
private deleteUser = async (
req: Request,
res: Response
): Promise<Response | void> => {
try {
const { _id } = req.user;
await this.userService.delete(_id);
await this.locationService.delete(_id);
res.status(204).send();
} catch (error: any) {
res.status(404).json(error.message)
}
};
private getUserNext = async (
req: Request,
res: Response
): Promise<Response | void> => {
try {
const longitude = Number(req.query.longitude);
const latitude = Number(req.query.latitude);
if (isNaN(longitude) || isNaN(latitude)) {
console.log('Unable to convert string to number');
throw new Error('Unable to convert string to number');
}
const userId = req.user.id;
const musicId = String(req.query.currentMusic);
const data = await this.locationService.getNearUser(userId, musicId, latitude, longitude);
res.status(201).send(data);
}
catch (error: any) {
res.status(400).json(error.message)
}
}
private deleteMusic = async (
req: Request,
res: Response
): Promise<Response | void> => {
try {
const { _id } = req.user;
const musicId: string = req.params.id;
if (!musicId) {
return res.status(400).json({ error: 'musicId are required fields.' });
}
const deleted = await this.userService.deleteMusic(_id, musicId);
if (deleted) {
res.status(200).send({ message: 'Music deleted successfully.' });
} else {
res.status(404).json({ error: 'Music not found.' });
}
} catch (error: any) {
res.status(404).json(error.message)
}
}
private addMusic = async (
req: Request,
res: Response
): Promise<Response | void> => {
try {
const { _id } = req.user;
const { musicId, userId } = req.body;
if (!musicId || !userId) {
return res.status(400).json({ error: 'musicId and userId are required fields.' });
}
const music: IMusic = {
musicId,
userId,
date: new Date(),
};
await this.userService.addMusic(_id, music);
res.status(201).send({ music });
} catch (error: any) {
res.status(400).json(error.message)
}
}
private getMusics = async (
req: Request,
res: Response
): Promise<Response | void> => {
try {
const userId: string = req.user.id;
const musics = await this.userService.getMusics(userId);
return res.status(200).json({ musics });
} catch (error: any) {
res.status(400).json(error.message)
}
}
private setName = async (
req: Request,
res: Response
): Promise<Response | void> => {
try {
const { _id } = req.user;
const { name } = req.body;
const regex = /^\w+$/;
if (!regex.test(name) || !name) {
return res.status(400).json({ error: "Name should only contain alphanumeric characters (letters, numbers, and underscores)" });
}
await this.userService.setName(_id, name.toLowerCase());
res.status(200).json({ message: 'Name updated successfully' });
} catch (error: any) {
res.status(409).json(error.message)
}
}
private setEmail = async (
req: Request,
res: Response
): Promise<Response | void> => {
try {
const { _id } = req.user;
const { email } = req.body;
const regex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
if (!regex.test(email) || !email) {
return res.status(400).json({ error: "Invalid email" });
}
await this.userService.setEmail(_id, email.toLowerCase());
res.status(200).json({ message: 'Email updated successfully' });
} catch (error: any) {
res.status(409).json(error.message)
}
}
private setSpotify = async (
req: Request,
res: Response
): Promise<Response | void> => {
let access_token;
let idAccount: string;
let image: string;
const { _id, idSpotify } = req.user;
const { tokenSpotify } = req.body;
if (!tokenSpotify) {
return res.status(400).json({ error: 'TokenSpotify is missing in the request.' });
}
const apiBaseUrl = process.env.API_BASE_URL || 'http://localhost:8080/api';
const refreshUrl = `${apiBaseUrl}/spotify/refresh?refresh_token=${tokenSpotify}`;
try {
const authOptions = {
method: 'GET',
url: refreshUrl,
json: true
};
const authResponse = await axios(authOptions);
if (authResponse.status === 200) {
access_token = authResponse.data.access_token;
const headers = {
Authorization: `Bearer ${access_token}`,
};
const resp = await axios.get('https://api.spotify.com/v1/me', { headers });
if (resp.status == 200) {
const images = resp.data.images;
idAccount = resp.data.id;
if (idSpotify === idAccount) {
return res.status(400).json({ error: 'idSpotify cannot be the same as idAccount.' });
}
if (images && images.length > 0) {
images.sort((a: any, b: any) => b.height - a.height);
image = images[0].url;
}
else {
const imagePath = './src/assets/images/default_user.png';
const imageBuffer = fs.readFileSync(imagePath);
const base64Image = 'data:image/png;base64,' + base64js.fromByteArray(imageBuffer);
image = base64Image
}
}
}
} catch (error: any) {
console.log(error);
res.status(500).send("Internal Server Error: Unable to authenticate with Spotify");
return;
}
try {
await this.userService.setSpotify(_id, tokenSpotify, idAccount, image);
res.status(200).json({ message: 'Spotify token updated successfully' });
} catch (error: any) {
res.status(409).json(error.message)
}
}
private setImage = async (
req: Request,
res: Response
): Promise<Response | void> => {
try {
const { _id } = req.user;
const { image } = req.body;
await this.userService.setImage(_id, image);
res.status(200).json({ message: 'Image updated successfully' });
} catch (error: any) {
res.status(500).json(error.message)
}
}
private setPassword = async (
req: Request,
res: Response
): Promise<Response | void> => {
try {
const { _id } = req.user;
const { oldPassword, newPassword } = req.body;
await this.userService.setPassword(_id, oldPassword, newPassword);
res.status(200).json({ message: 'Password updated successfully' });
} catch (error: any) {
res.status(500).json(error.message)
}
}
}
export default UserController;
declare global {
namespace Express {
export interface Request {
user: User;
}
}
}

@ -0,0 +1,26 @@
import { Schema, model } from 'mongoose';
import { Location } from '../models/Location';
const locationSchema = new Schema({
userId: {
type: String,
required: true,
unique: true,
},
musicId: {
type: String,
required: true,
},
latitude: {
type: Number,
required: true,
},
longitude: {
type: Number,
required: true,
}
},
{ timestamps: true }
);
export default model<Location>('Location', locationSchema);

@ -1,4 +0,0 @@
// export default db = new MongoClient(uri);

@ -0,0 +1,62 @@
import User from "../models/User";
import { Schema, model } from 'mongoose';
import bcrypt from 'bcrypt';
const userSchema = new Schema({
idSpotify: {
type: String,
required: true,
unique: true
},
tokenSpotify: {
type: String,
required: true
},
name: {
type: String,
required: true,
unique: true
},
email: {
type: String,
required: true,
unique: true,
trim: true
},
password: {
type: String,
required: true
}
,
image: {
type: String,
required: true
},
musics_likes: {
type: [{
musicId: String,
userId: String,
date: Date
}],
default: []
}
},
{ timestamps: true }
);
userSchema.pre<User>('save', async function (next) {
if (!this.isModified('password')) {
return next();
}
const hash = await bcrypt.hash(this.password, 8);
this.password = hash;
next();
});
userSchema.methods.isValidPassword = async function (
password: string
): Promise<boolean | Error> {
return await bcrypt.compare(password, this.password);
};
export default model<User>('User', userSchema);

@ -1,39 +0,0 @@
import { Schema, model,Document } from 'mongoose';
const locationSchema = new Schema(
{
idFlad: {
type: String,
required: true,
unique: true,
},
musicId: {
type: String,
required: true,
},
latitude: {
type: Number,
required: true,
},
longitude: {
type: Number,
required: true,
},
},
{ timestamps: true }
);
// fladDevDb
// ZslYlNRWIOUU7i6o
export default model<ILocation>('Location', locationSchema);
export interface ILocation extends Document {
idFlad: string;
musicId : string;
latitude : number;
longitude: number;
}

@ -1,8 +0,0 @@
import { Schema, model } from 'mongoose';
const notificationSchema = new Schema({
type: {type: String, required: true},
content: {type: String, required: true}
});
export default {Notification: model("nofitication", notificationSchema)}

@ -1,11 +0,0 @@
import { Document } from 'mongoose';
export default interface IUser extends Document {
email: string;
name: string;
password: string;
idFlad : string;
idSpotify : string;
isValidPassword(password: string): Promise<Error | boolean>;
}

@ -1,79 +0,0 @@
// maye this file should me the UserModel like we had in php cause it's here we verrify the password
import IUser from "./UserInterface";
import { Schema, model } from 'mongoose';
import bcrypt from 'bcrypt';
// const userSchema: Schema = new Schema<IUser>({
// pseudo: {type: String, index: { unique: true }},
// email: {type: String},
// idDafl: {type: String, index: { unique: true }},
// idSpotify: {type: String},
// password: {type: String},
// prenom: {type: String, default: ""},
// description: {type: String, default: ""},
// nom: {type: String, default: ""},
// ville: {type: String, default: ""},
// profilPic: {type: String},
// noteList: [],
// notifications: [],
// friends: {type: [String] },
// favoris: [],
// conversations: {type: [String] }
// });
const userSchema = new Schema(
{
idFlad: {
type: String,
required: true,
unique: true,
},
idSpotify: {
type: String,
required: true,
unique: true,
},
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
// this mean that we identify user by email
unique: true,
// delete the whitespace
trim: true,
},
password: {
type: String,
},
},
{ timestamps: true }
);
// this means that we hash the user password before saving it to the database
userSchema.pre<IUser>('save', async function (next) {
if (!this.isModified('password')) {
//just had that to be sure that the api still going
return next();
}
const hash = await bcrypt.hash(this.password, 8);
this.password = hash;
next();
});
userSchema.methods.isValidPassword = async function (
password: string
): Promise< boolean | Error> {
return await bcrypt.compare(password, this.password);
};
// fladDevDb
// ZslYlNRWIOUU7i6o
export default model<IUser>('User', userSchema);
// export const User: Model<IUser> = model('User', userSchema);

@ -8,6 +8,5 @@ class HttpException extends Error {
this.message = message; this.message = message;
} }
} }
// en fontion de l'exeption firebas,etc une bonne exeption
export default HttpException; export default HttpException;

@ -1,16 +1,12 @@
import App from "./app"; import App from "./app";
import SpotifyController from "./controller/spotify-controller/spotifyCtrl"; import SpotifyController from "./controllers/spotifyController";
import PingController from "./controller/TestCtrl"; import UserController from "./controllers/userController";
import UserController from "./controller/user-controller/userCtrl";
import dotenv from 'dotenv' import dotenv from 'dotenv'
dotenv.config(); dotenv.config();
const app = new App( const app = new App(
[new PingController(), new SpotifyController(), new UserController()], [new SpotifyController(), new UserController()],
Number(process.env.PORT) Number(process.env.PORT)
); );
app.listen(); app.listen();

@ -1,45 +0,0 @@
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
import IToken from '../database/schema/Token/IToken';
import UserSchema from '../database/schema/User/UserSchema';
import token from '../model/token';
import HttpException from './exeption/httpExeption';
async function authenticatedMiddleware(
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> {
const bearer = req.headers.authorization;
if (!bearer || !bearer.startsWith('Bearer ')) {
return next(new HttpException(401, 'Unauthorised'));
}
const accessToken = bearer.split('Bearer ')[1].trim();
try {
const payload: IToken | jwt.JsonWebTokenError = await token.verifyToken(
accessToken
);
if (payload instanceof jwt.JsonWebTokenError) {
return next(new HttpException(401, 'Unauthorised'));
}
const user = await UserSchema.findById(payload.id)
.select('-password')
.exec();
if (!user) {
return next(new HttpException(401, 'Unauthorised'));
}
req.user = user;
return next();
} catch (error) {
return next(new HttpException(401, 'Unauthorised'));
}
}
export default authenticatedMiddleware;

@ -1,8 +0,0 @@
// export const loggerOptions: expressWinston.LoggerOptions = {
// transports: [new winston.transports.Console()],
// format: winston.format.combine(
// winston.format.json(),
// winston.format.prettyPrint(),
// winston.format.colorize({ all: true })
// ),
// };

@ -1,14 +1,11 @@
import Joi from 'joi'; import Joi from 'joi';
const register = Joi.object({ const register = Joi.object({
name: Joi.string().max(30).required(), name: Joi.string().max(30).required().regex(/^\w+$/)
.message("Name should only contain alphanumeric characters (letters, numbers, and underscores)"),
email: Joi.string().email().required(), email: Joi.string().email().required(),
password: Joi.string().min(6).required(), password: Joi.string().min(6).required(),
// can add an field like confimPassword and cheked that the password is equal to the confirmPassword tokenSpotify: Joi.string().required()
idSpotify: Joi.string(),
idFlad : Joi.string(),
}); });
const login = Joi.object({ const login = Joi.object({

@ -0,0 +1,45 @@
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
import Token from '../models/Token';
import UserSchema from '../database/UserSchema';
import token from '../services/TokenService';
import HttpException from '../exception/HttpException';
async function authMiddleware(
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> {
const bearer = req.headers.authorization;
if (!bearer || !bearer.startsWith('Bearer ')) {
return next(new HttpException(401, 'Unauthorized'));
}
const accessToken = bearer.split('Bearer')[1].trim();
try {
const payload: Token | jwt.JsonWebTokenError = await token.verifyToken(
accessToken
);
if (payload instanceof jwt.JsonWebTokenError) {
return next(new HttpException(401, 'Unauthorized'));
}
const user = await UserSchema.findById(payload.id)
.select('-password')
.exec();
if (!user) {
return next(new HttpException(401, 'Unauthorized'));
}
req.user = user;
return next();
} catch (error) {
return next(new HttpException(401, 'Unauthorized'));
}
}
export default authMiddleware;

@ -1,5 +0,0 @@
export default interface IUser{
name: string;
email: string;
avatar?: string;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save