Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • HEPIA_DevWebAv/2019_tp2
  • ricardo.nunesdeo/2019_tp2
  • nicolas.paschoud/2019_tp2
  • josemanu.netogonc/2019_tp2
  • martin.rickenma/2019_tp2
  • roxanne.grant/2019_tp2
  • alexandr.arondel/2019_tp2
  • justin.foltz/2019_tp2
8 results
Select Git revision
Show changes
Commits on Source (51)
Showing
with 1386 additions and 0 deletions
##
projet/node_modules*
############### MacOS ############### MacOS
# General # General
.DS_Store .DS_Store
......
# Hyperdrive
Fleury Noé et Paschoud Nicolas
## Introduction
Dans le cadre du cours de Développement Web Avancé, nous avons du réaliser un projet web. Durant ce projet, nous avons du créer une API REST afin d'offrir un accès aux données. Ce projet a été réalisé en Javascript en utilisant Node JS.
## L'application
Le projet que nous avons choisi de réaliser est un drive. Pour des besoins personnels, nous avons jugé ce projet pertinent et l'avons donc réalisé. Le but est donc de permettre à un utilisateur de s'enregistrer et de stocker des fichiers sur la plateforme. Il a aussi la possibilité de les organiser en créant des dossiers. Il a aussi la possibilité de les partager avec d'autre utilisateurs du service. Nous avons créer une interface simple découpée en quatre partie :
- Une zone de menu pour se connecter, se déconnecter et créer des dossiers / importer des fichiers.
- La zone de contenu du drive ou sont affichés tous les dossiers et fichiers de l'utilisateur.
- Une zone d'information sur le fichier (nom, son propriétaire, la date d'upload, l'adresse d'upload)
- Une zone de contenu affichants tous les fichiers que les autres utilisateurs partagent avec lui.
L'utilisateur a la possibilité de s'inscrire ainsi que de se connecter au service. Lors de sa connexion, il reçoit un token lui permettant d'accéder à l'API. Lors de sa déconnexion, le token est détruit. Pour créer un dossier, il lui suffit de se mettre à un endroit spécifique et de cliquer sur le bouton "New File" après avoir renseigné le nom du dossier à créer.
Pour permettre la géolocalisation des fichiers, nous avons utilisé 2 API publiques qui sont :
- https://ip-api.com/ Cette API nous permet de récupérer les informations de localisation d'une adresse IP. Nous pouvons grâce à celle-ci, récupérer les latitude et longitude que nous stockons dans la base de données.
- http://bot.whatismyipaddress.com Cette API permet de récupérer l'adresse ip de l'ordinateur courant. Nous l'utilisons exclusivement pour la raisons suivantes. Nous travaillons en local, et n'avons pas déployé de serveur public. Nous ne pouvons donc pas récupérer l'adresse du client qui fait une requête sur l'API car il s'agit d'une adresse privée. Il est cependant facile de modifier cette partie du code pour utiliser l'adresse du client au cas ou nous voudrions rendre notre API public.
## Installation
Avant de faire fonctionner le site, assurez vous d'avoir la plateforme Node JS d'installée. Installer ensuite les packages nécessaire au fonctionnement du site en vous rendant à la racine du projet et en executant la commande suivante : *npm install*
Pour démarrer le site il faut réaliser ces 2 étapes :
- Se rendre dans le dossier *db* se trouvant dans la hiérarchie du projet et taper la commande *docker-compose up -d*. Assurez-vous que le port 3306 est libre pour permettre au service MySQL de démarrer correctement.
- Se rendre dans le projet ou se trouve le fichier *hyperdrive-rest*.js et taper la commande *node hyperdrive-rest.js*. après vous être assurer que le port 8080 n'est pas utilisé par un autre service. Le site est accessible à l'adress de votre ordinateur sur le port 8080.
## Répartition
Fleury Noé :
- Upload / Download des fichiers
- Localisation de ceux-ci à l'upload
- JWT
- Partage des fichiers
Paschoud Nicolas :
- Base de donnée
- Requêtes SQL (sql-request.js)
- Affichage de l'arborescence dans le drive
- Affichage des informations du fichier
- Création d'un dossier
## Architecture
L'interraction entre les API se présente sous cette forme.
![hyperdrive](/Users/klaus/Documents/Web/Back/2019_tp2/documentation/hyperdrive.png)
- Le bloc Client fais des appels à l'API hyperdrive qui lui réponds avec les données que le client souhaite. Le client les traites et les affiches à sa guise.
- L'API Hyperdrive réponds à des requêtes des clients. Il ne fait appel qu'en cas de besoin aux API *whatismyipaddress* et *ip-api*.
- L'API *ip-api* est appelée par hyperdrive seulement lorsque le client upload un fichier. Cet appel permet de retourner l'addresse de la personne en fonction de son IP. Les latitudes et longitudes sont stockée par l'hyperdrive dans le bloc SQL
- Le bloc whatismyipaddress n'est util que dans le cadre du développement. Cette API nous sert à récupérer notre IP pour ensuite faire un appel à *ip-api*.
Voici comment se présente notre architecture
<img src="./architecture.png" height="1000px">
Nous avons plusieurs dossier principaux :
- /
A la racine se trouve les fichiers principaux de l'API :
- hyperdrive-rest.js
Il s'agit du fichier contenant le traitement pour chacune des routes.
- sql-request.js
Ce fichier permet de faire des requêtes SQL vers la base de données.
- front/
Ce dossier contient tout le frontend de l'application.
- images
Ce dossier contient 2 petites images faites main pour l'affichage des dossiers et des fichiers.
- styles
Il s'agit du dossier contenant tous le style du site.
- show-content.js
Ce fichier est le plus important du frontend. C'est lui qui s'occupe de faire des requêtes vers notre API et de faire l'affichage de nos données correctement
- db/
Ce dossier contient tous les fichiers en rapport avec la base de données ainsi que le fichier docker-compose qui nous permet de monter rapidement notre container MySQL
## Technologies
Pour la réalisation de ce projet, nous avons utilisé la plateform Node JS pour la réalisation de notre API REST. Nous avons aussi réaliser une base de données relationnelle MySQL qui se trouve dans un container. Tout notre projet a été réaliser en Javascript en utilisant les modules Node JS suivant :
- Express nous a permis de créer nos routes.
- MySQL nous a permis de faire des requêtes SQL vers la base de donnée
- Crypto-js nous a permis de faire la partie JWT
- http nous a permis de faire des appels vers les API public
Pour le frontend, nous avons 2 technologies principalement:
- jQuery nous a permis de faire des requêtes vers l'API REST
- JavaScript nous a permis de gérer l'affichage à la réception des données
## Routes
### /
La route principale retourne la page principale du site (index.html).
### /login
Cette route permet de créer un token pour l'utilisateur si il est inscrit au site.
Paramètre :
- pseudo : Pseudo de l'utilisateur.
- password : Mot de passe de l'utilisateur.
Retour :
Le retour de cette route est un objet JSON formé de cette manière :
```json
{
"route": "/login",
"resCode": 0,
"signedToken": jwt.signedToken,
"comment": `Password for user '${ user }' true.`
}
```
### /logout
Logout permet de supprimer un token lorsqu'un utilisateur se deconnecte.
Param :
- Token : Token de l'utilisateur a déconnecter.
### /register
Cette route permet d'inscrire un utilisateur au service de l'hyperdrive.
Paramètres :
- pseudo : Pseudo du nouvel utilisateur.
- password : Mot de passe du nouvel utilisateur.
### /share/:file_id/:to_user
Cette route permet de partager un fichier avec un utilisateur.
Paramètres :
- token : Il s'agit du token de l'utilisateur qui souhaite partage un fichier.
- file_id : Il s'agit de l'id du fichier à partager.
- to_user : Il s'agit de la personne à qui on souhaite partager le fichier.
### /upload
Cette fonction permet d'uploader un fichier dans un path.
Paramètre :
- token : Token d'authentification de l'utilisateur.
- file_name : Il s'agit du nom du fichier.
### /download/:file_id
Cette fonction permet de télécharger un fichier.
Paramètre :
- file_id : Id du fichier que l'on souhaite télécharger.
- token : Token d'authentification de l'utilisateur.
### /change-path*
Cette fonction permet d'afficher le contenu d'un dossier.
Paramètres :
- token : Token d'authentification de l'utilisateur.
- path : Il s'agit du dossier dont le contenu doit être affiché.
Retour :
Cette route retour un tableau d'objet JSON. Chaque object est soit un dossier, soit un fichier.
Voici l'exemple d'un objet fichier. Cet objet se trouve dans un tableau.
```json
{
"paths": "/a",
"login": "a",
"parent": null,
"file_id": "ab",
"file_name": "deux"
}
```
Voici l'exemple d'un objet dossier. Cet objet se trouve dans un tableau.
```json
{
"paths": "/a/coucou",
"login": "a",
"parent": "/a",
"file_id": null,
"file_name": null
}
```
Un dossier possède un parent, car il se trouve dans un dossier. Dans le cas du dossier, le champ *path* indique la ou se trouve le fichier ainsi que son nom. Le dernier élément est le nom, tandis que tout ce qui se trouve avant est la ou est stocké le fichier.
A l'inverse, un fichier se trouve dans un dossier, il a donc un *path*. Il est certe enfant d'un dossier, mais la seule information de ou il se trouve nous suffit.
### /create-path*
Cette fonction permet de créer un dossier à un endroit spécifique.
Paramètres :
- token : Token d'authentification de l'utilisateur.
- path : Il s'agit du nouveau dossier à créer.
### /get-info
La route get-info nous permet de récupérer les informations d'un fichier.
Paramètres :
- file_id : Id du fichier dont on souhaite avoir les informations.
- token : Il s'agit du token d'authentification.
### /show-shared-file
Cette route permet de récupérer tous les fichiers partagé avec un utilisateur.
Paramètres :
- token : Le token nous permet de récupérer l'id de l'utilisateur.
Retour :
La réponse est un tableau d'objet JSON. Chaque objet contient ces informations :
```json
{
"login": "b", // La personne qui a cherché le fichier
"file_id": "abcd", // Id du fichier
"file_name": "un" // Nom du fichier
}
```
## Conclusion
Lors du développement de ce drive, nous avons pu utiliser des technologies nouvelles ainsi qu'un manière intéressante de dévelloper. La programmation asynchrone fut difficile à prendre en main, mais nous y somme arrivé. Le développement de ce drive fut fort interessant et captivant, nous avons pris beaucoup de plaisir. Le temps nous a malheureusement manqué pour nous permettre de faire quelque chose qui nous satisfait à 100%.
Nous vous proposons quand même une version intéressante et bien aboutit. Certaines fonctionnalités prévue au début on été revue et même parfois supprimées car leur présence ne faisait aucun sens.
\ No newline at end of file
documentation/architecture.png

116 KiB

documentation/hyperdrive.png

38.2 KiB

USE hyperdrive;
INSERT INTO Users
VALUES
("a", "test"),
("b", "test"),
("c", "test"),
("d", "test"),
("e", "test");
INSERT INTO Paths
VALUES
("/a", "a", NULL),
("/a/coucou", "a", "/a"),
("/a/coucou/test", "a", "/a/coucou"),
("/b", "b", NULL),
("/c", "c", NULL),
("/c/test", "c", "/c"),
("/d", "d", NULL),
("/e", "e", NULL);
INSERT INTO Files
VALUES
("abcd", "un", "/a", 46.2054, 6.1459),
("adssb", "deux", "/a", 46.2054, 6.1459),
("accb", "deux", "/a/coucou", 46.2054, 6.1459),
("abnnnnn", "deux", "/a/coucou", 46.2054, 6.1459),
("@dfsg", "trois", "/c/test", 46.2054, 6.1459),
("gbvaf", "quatre", "/b", 46.2054, 6.1459),
("dsfgh", "cinq", "/d", 46.2054, 6.1459),
("sdfa", "six", "/e", 46.2054, 6.1459);
INSERT INTO Shares
VALUES
("a", "b", "abcd"),
("a", "c", "abcd"),
("a", "d", "abcd"),
("c", "e", "@dfsg");
version: '3'
services:
db:
image: mysql:5
restart: always
container_name: hyperdrive
environment:
MYSQL_ROOT_PASSWORD: superhyper
MYSQL_DATABASE: hyperdrive
MYSQL_USER: hyperdrive
MYSQL_PASSWORD: hyper
ports:
- '3306:3306'
expose:
- 3306
volumes:
- ./hyperdrive.sql:/docker-entrypoint-initdb.d/hyperdrive.sql
\ No newline at end of file
CREATE DATABASE IF NOT EXISTS `hyperdrive` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `hyperdrive`;
-- mysql -h localhost -P 3306 --protocol=tcp -u root -p
-- Creating tables
CREATE TABLE IF NOT EXISTS Users (
login varchar(60) NOT NULL,
passwd varchar(256) NOT NULL,
PRIMARY KEY (login)
);
CREATE TABLE IF NOT EXISTS Paths (
paths varchar(400) NOT NULL,
login varchar(60) NOT NULL,
parent varchar(400),
PRIMARY KEY (paths),
FOREIGN KEY (login) REFERENCES Users(login),
FOREIGN KEY (parent) REFERENCES Paths(paths)
);
CREATE TABLE IF NOT EXISTS Files (
file_id varchar(100) NOT NULL,
file_name varchar(50) NOT NULL,
login varchar(60) NOT NULL,
paths varchar(400) NOT NULL,
lat FLOAT,
lng FLOAT,
PRIMARY KEY (file_id),
FOREIGN KEY (paths) REFERENCES Paths(paths),
FOREIGN KEY (login) REFERENCES Users(login)
);
CREATE TABLE IF NOT EXISTS Shares (
pseudo_1 varchar(60) NOT NULL,
pseudo_2 varchar(60) NOT NULL,
file_id varchar(100) NOT NULL,
PRIMARY KEY (pseudo_1, pseudo_2, file_id),
FOREIGN KEY (pseudo_1) REFERENCES Users(login),
FOREIGN KEY (pseudo_2) REFERENCES Users(login),
FOREIGN KEY (file_id) REFERENCES Files(file_id)
);
-- Inserting datas
INSERT INTO Users
VALUES
("a", "test"),
("b", "test"),
("c", "test"),
("d", "test"),
("e", "test"),
("noe", "prov");
INSERT INTO Paths
VALUES
("/a", "a", NULL),
("/a/coucou", "a", "/a"),
("/b", "b", NULL),
("/c", "c", NULL),
("/c/test", "c", "/c"),
("/d", "d", NULL),
("/e", "e", NULL),
("/n", "noe", NULL);
INSERT INTO Files
VALUES
("abcd", "un", 'a', "/a", 46.2054, 6.1459),
("ab", "deux", 'a', "/a", 46.2054, 6.1459),
("@dfsg", "trois", 'c', "/c/test", 46.2054, 6.1459),
("gbvaf", "quatre", 'b', "/b", 46.2054, 6.1459),
("dsfgh", "cinq", 'd', "/d", 46.2054, 6.1459),
("sdfa", "six.txt", 'e', "/e", 46.2054, 6.1459),
("liblb", "myfile.txt", 'noe', "/n", 46.2054, 6.1459);
INSERT INTO Shares
VALUES
("a", "b", "abcd"),
("a", "c", "abcd"),
("a", "d", "abcd"),
("c", "e", "@dfsg");
SELECT pseudo_2, Files.file_id, Files.file_name
FROM Shares LEFT JOIN Files ON Shares.file_id=Files.file_id
WHERE pseudo_2='b';
\ No newline at end of file
-- Get content of a folder
-- paths | login | parent | file_id | file_name
SELECT Paths.paths, login, parent, Files.file_id, Files.file_name FROM Paths
LEFT JOIN Files ON Files.paths = Paths.paths
WHERE Files.file_id IS NOT NULL
AND login='a'
AND Paths.paths='/a/coucou'
OR Paths.parent='/a/coucou';
\ No newline at end of file
coucou nicolas
nothing to see here..
function new_file(file_name, file_id, document_id) {
content = `
<div class="file" id="${file_id}">
<p>
<button onclick="getInfo('${file_id}')">
<img src="/images/file_img.png" height="50px">
</button>
<p>${file_name}</p>
</p>
</div>
`
document.getElementById(document_id).innerHTML += content;
}
function new_folder (folder_name, path) {
content = `
<div class="folder">
<p>
<button onclick="change_path('${path}')">
<img src="/images/folder_img.png" height="50px">
</button>
<p>${folder_name}</p>
</p>
</div>
`;
document.getElementById("content-drive").innerHTML += content;
}
function show_info(infos){
let el = document.getElementById("info-content");
/*
addedon: 1576691707
file_id: "abcd"
file_name: "un"
lat: 46.2054
lng: 6.1459
login: "a"
paths: "/a"
*/
el.innerHTML = `
<p>File name : ${infos.file_name}</p>
<p>Path : ${infos.paths}</p>
<p>Owner : ${infos.login}</p>
<p>Localisation :<br>
lat : ${infos.lat}<br>
lng : ${infos.lng}
</p>
<p>Adresse : Mettre adresse avec gmap ou autre</p>
<button onclick="download('${infos.file_id}')">Download</button>
`;
}
\ No newline at end of file
projet/front/images/file_img.png

8.6 KiB

projet/front/images/folder_img.png

6.69 KiB

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="/styles/style.css">
<script src="jquery-3.4.1.min.js"></script>
<script src="element-style.js"></script>
<script src="show-content.js"></script>
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>Hyperdrive</h1>
<div id="hyperdrive">
<div id="menu">
<h3>Menu</h3>
<div id="login-div">
<input type="text" id="username"><br>
<input type="password" id="passwd"><br>
<button onclick="login()" id="login-button">Login</button>
</div>
<div id="menu-more" style="display: none;">
<input type="text" id="foldername" placeholder="folder name">
<button onclick="newFolder()">New Folder</button><br>
<input type="text" id="filename" placeholder="file name">
<button onclick="newFile()">New File</button><br>
<button onclick="showSharedContent()">Shared with me</button>
</div>
</div>
<div id="drive">
<h3>Drive</h3>
<div id="dir_name"></div>
<div id="content-drive">
</div>
<form action="/upload/n" method="POST" encType="multipart/form-data">
Choose a file :<br>
<input type="file" name="my_file"><br>
<input type="submit" value="Send">
</form>
</div>
<div id="info">
<h3>Infos</h3>
<div id="info-content">
</div>
</div>
<div id="shared">
<h3>Shared with me</h3>
<div id="shared-content">
</div>
</div>
</div>
</body>
</html>
\ No newline at end of file
This diff is collapsed.
"use strict";
let my_login = null;
let token = null;
function change_path(path) {
document.getElementById("content-drive").innerHTML = "";
$.ajax({url: 'change-path'+path+"/"+token, success: function(result){
let p = path.split("/");
if (p.length === 2){
p = null;
} else {
p.pop()
p = p.join("/");
}
appendLinkToParent(path, p);
for (let i in result){
if (result[i].file_id){
new_file(result[i].file_name, result[i].file_id, "content-drive");
} else {
if (path !== result[i].paths){
let name = result[i].paths.split("/");
new_folder(name[name.length-1], result[i].paths);
}
}
}
}});
}
function appendLinkToParent(path, parent) {
let el = document.getElementById("dir_name");
let btn = ""
if (parent) {
btn = `<button onclick="change_path('${parent}')"><-</button>`;
}
el.innerHTML = `
<p>Directory :</p>
<p id="path-dir-drive">${path}</p>
${btn}
`;
}
function login() {
let username = document.getElementById("username").value
let passwd = document.getElementById("passwd").value
$.ajax({url: 'login?user='+username+'&pass='+passwd, success: function(result){
my_login = username;
token = result.signedToken;
change_path('/' + username);
let el = document.getElementById("login-button");
el.innerHTML = "Disconnect";
el.onclick = disconnect;
document.getElementById("menu-more").style.display = "block";
}});
}
function disconnect(){
$.ajax({url: 'logout?token=' + token, success: function(result){
token = null;
let el = document.getElementById("login-button");
el.innerHTML = "Login";
el.onclick = login;
document.getElementById("content-drive").innerHTML = "";
document.getElementById("dir_name").innerHTML = "";
document.getElementById("menu-more").style.display = "none";
}});
}
function showSharedContent() {
let el = document.getElementById("shared-content");
$.ajax({url: '/show-shared-file?token=' + token,
success: function(result){
console.log(result);
for (let i in result){
new_file(result[i].file_name, result[i].file_id, "shared-content");
}
}
});
}
function newFolder() {
let foldername = document.getElementById("foldername").value;
let path = document.getElementById("path-dir-drive").textContent;
$.ajax({url: 'create-path' + path + "/" + foldername + '/' + token,
success: function(result){
change_path(path);
}
});
}
function newFile() {
filename = document.getElementById("filename").value;
console.log(filename);
}
function getInfo(file_id){
$.ajax({url: 'get-info?file_id=' + file_id + '&token=' + token,
success: function(result){
show_info(result[0]);
}
});
}
function download(file_id){
console.log("Download : " + file_id);
}
\ No newline at end of file
* {
margin: 2.5px;
padding: 2px;
box-sizing: border-box;
}
button {
border: none;
padding: 5px;
}
button:hover {
background-color: grey;
}
#menu {
border: solid grey 2px;
width: 30%;
float: left;
}
#drive {
border: solid grey 2px;
width: 30%;
float: left;
}
#info {
border: solid grey 2px;
width: 30%;
float: left;
}
#shared {
border: solid grey 2px;
width: 30%;
float: left;
}
.folder {
float: left;
}
.folder p{
font-size: 10pt;
text-align: center;
}
.file {
float: left;
}
.file p{
font-size: 10pt;
text-align: center;
}
\ No newline at end of file
"use strict";
const CryptoJS = require("crypto-js");
const http = require("http");
var fileupload = require("express-fileupload");
var multer = require('multer')
var storage = multer.diskStorage(
{
destination: './files/',
filename: function ( req, file, cb ) {
cb( null, Math.round(Math.random()*100) + Date.now().toString() );
}
}
);
var upload = multer( { storage: storage } );
const express = require('express');
const app = express();
const port = 8080;
const sql = require('./sql-request');
///// JWT part /////
var valid_tokens = [];
String.prototype.hashCode = function() {
var hash = 0, i, chr;
if (this.length === 0) return hash;
for (i = 0; i < this.length; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
};
function tob64(elem){
return Buffer.from(elem.toString()).toString('base64').slice(0, -2);
}
function Header(typ, alg){
this.typ = typ;
this.alg = alg;
this.toString = function(){ return "{" + this.typ + "," + this.alg + "}"};
}
function Payload(user, pass_enc){
this.user = user;
this.pass_enc = pass_enc;
this.toString = function(){ return "{" + this.user + "," + this.pass_enc + "}"};
}
function Signature(token){
const secret = "our super hyperdrive secret" + new Date();
return CryptoJS.HmacSHA512(token, secret);
}
function JWT(pl_user, pl_pass){
this.header = new Header("jwt", "HS512");
this.payload = new Payload(pl_user, pl_pass.hashCode());
let token = tob64(this.header) + "." + tob64(this.payload);
let signature = new Signature("token");
this.signedToken = token + "." + signature;
}
function add_token(token, user) {
for (let i = 0; i < valid_tokens.length; i++) {
if(Object.keys(valid_tokens[i])[0] == token){
valid_tokens.splice(i, 1);
console.log("Unable to add token. (token already present)");
break;
}
}
let obj = {}; obj[token.toString()] = user;
valid_tokens.push(obj);
console.log(valid_tokens)
console.log("Successfully added token.");
}
function remove_token(token) {
for (let i = 0; i < valid_tokens.length; i++) {
if(Object.keys(valid_tokens[i])[0] == token){
valid_tokens.splice(i, 1);
console.log("Successfully removed token from valid_tokens.");
return true;
}
}
console.log("Unable to remove token from valid_tokens. (Token not present)");
}
// verify the token
// return : user if exist
function verify_token(token) {
for (let i = 0; i < valid_tokens.length; i++) {
if(Object.keys(valid_tokens[i])[0] == token)
return valid_tokens[i][token];
}
return false;
}
///// End JWT part /////
app.get('/', (req, res) => {
res.sendFile(__dirname + '/front/index.html');
});
/* Login
* param : pseudo
* param : password
*/
// resCode : [ 0: User now logged in, 1: False password, 2: Invalid username, 3: Empty user or pass ]
app.get('/login', (req, res) => {
const user = req.query['user'];
const pass = req.query['pass'];
sql.userExist(user, pass, (element) => {
if (element)
check_login(user, pass, element, res);
});
});
function check_login(user, pass, userObject, res) {
if (!user || !pass) {
res.send({
"route": "/login",
"resCode": 4,
"comment": "Please enter a username and a password."
})
}
else{
if (userObject){
if (userObject.passwd == pass.hashCode()) {
let jwt = new JWT(user, pass);
res.send({
"route": "/login",
"resCode": 0,
"signedToken": jwt.signedToken,
"comment": `Password for user '${ user }' true.`
})
add_token(jwt.signedToken, user);
}
else {
res.send({
"route": "/login",
"resCode": 1,
"comment": `Password for user '${ user }' false.`
})
}
}
else {
res.send({
"route": "/login",
"resCode": 2,
"comment": `Username '${ user }' don't exist.`
})
}
}
}
// resCode : [ 0: Token is valid, 1: Token is not valid, 3: Empty token ]
app.get('/testmytoken', (req, res) => {
let token = req.query['token'];
if (!token) {
res.send({
"resCode": 3,
"comment": "Please enter a token."
})
}
if (verify_token(token)){
res.send({
"resCode": 0,
"comment": "Your token is valid."
})
}
else {
res.send({
"resCode": 1,
"comment": "Your token is not valid."
})
}
})
// resCode : [ 0: Logout ok, 1: Already logged out, 3: Empty token ]
app.get('/logout/', (req, res) => {
let token = req.query['token'];
if (!token) {
res.send({
"resCode": 3,
"comment": "Please enter a token."
})
}
else {
if (verify_token(token)){
remove_token(token);
res.send({
"resCode": 0,
"comment": "Your are now logged out."
})
}
else {
res.send({
"resCode": 1,
"comment": "Your are already logged out."
})
}
}
})
/**
* Request register
* param : pseudo
* param : password
*/
app.get('/register/', (req, res) => {
sql.addUser(req.query['login'], req.query['pass']);
res.send(`Request for a register (${req.query['login']}, ${req.query['pass']})`);
})
/**
* Request to share a file with a user
* param : file_id
* param : user1
* param : user2
* user1 share a file_id with user2
*/
app.get('/share/:file_id/:to_user', (req, res) => {
let token = req.query["token"]
let user = verify_token(token);
console.log("user : " + user)
if (req.params['to_user'] && req.params['file_id']){
let to_user = req.params['to_user'];
let file_id = req.params['file_id'];
sql.addSharing(user, to_user, file_id).then(function (r) {
res.send(r);
})
}
else{
res.send("Unable to share. Please provide a user to share with and a file_id.");
}
})
/**
* Request to upload a file
*/
// app.get('/upload/', (req, res) => {
// let d = new Date();
// let date_upload = d.getTime();
// // "abcd", "un", "/a", 46.2054, 6.1459, date_upload
// res.send(`Request for an upload (${req.query['file']})`)
// });
app.post('/upload*', upload.single('my_file'), (req, res) => {
// res.send(`Request for an upload (${req.query['file']})`)
let token = req.query["token"]
let user = verify_token(token)
if (user){
let path = req.params['0']
if (req.file){
var file_id = Math.round(Math.random() * 100) + Date.now();
var file_name = "test"
let lat;
let lon;
http.get('http://bot.whatismyipaddress.com', (result) => {
result.setEncoding('utf8');
result.on('data', function(chunk){
let ip = chunk;
http.get('http://ip-api.com/json/' + ip, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
lat = JSON.parse(data).lat.toFixed(3);
lon = JSON.parse(data).lon.toFixed(3);
// add to BDD
sql.addFile(file_id, file_name, user, path, lat, lon, (result) => {
res.send(result)
})
});
});
});
});
}
else{
console.log("Please enter a file");
}
}
else{
res.send("Please be connected")
}
})
app.get('/download/:file_id', (req, res) => {
let token = req.query["token"]
let user = verify_token(token);
if (user){
sql.verifyFileID(user, file_id, (filename) => {
console.log(filename)
if (filename){
res.download("files/" + file_id, filename);
}
else{
res.send("Can't download (not your file).")
}
})
}
else{
res.send("Can't download (please be connected).")
}
})
/**
* This function return the content of a path
* param path : Path of the folder we want to show
*/
app.get('/change-path*', (req, res) => {
let path = req.params['0'].split("/");
path.pop();
path = path.join("/");
let tok = req.params['0'].split("/").pop();
let name = verify_token(tok);
if (name) {
sql.changeDirectory(name, path,
(content) => {
res.send(content);
});
}
})
app.get('/create-path*', (req, res) => {
let c = req.params['0'];
let tok = c.split("/").pop();
let path = c.split("/");
path.pop();
path = path.join("/");
let parent = path.split("/");
parent.pop();
parent = parent.join("/");
let name = verify_token(tok);
if (name) {
sql.addPath(path, name, parent, (resp, msg) => {
console.log(resp, msg);
res.send(resp + " : " + msg);
});
}
})
/**
* Get info of a file
* @param {string} file_id Id of the file we want the infos
* @param {string} token Token of the client
*/
app.get('/get-info', (req, res) => {
let token = req.query["token"];
let file_id = req.query["file_id"];
let name = verify_token(token);
console.log(token);
if (name){
sql.getInfo(file_id, name, (resp, msg) => {
res.send(resp);
});
}
});
/**
*
*/
app.get('/show-shared-file', (req, res) => {
let token = req.query["token"];
let name = verify_token(token);
if (name){
sql.getSharedFile(name, (result) => {
if (result){
let content = [];
for (let i in result){
console.log(result[i]);
content.push({
login: result[i].pseudo_2,
file_id: result[i].file_id,
file_name: result[i].file_name
});
}
res.send(content);
}
});
}
});
app.use(express.static('front'));
app.use(fileupload());
var upload = multer({ dest: "files/" })
app.listen(port, () => console.log(`Hyperdrive listening on port ${port}!`))
../mime/cli.js
\ No newline at end of file
1.3.7 / 2019-04-29
==================
* deps: negotiator@0.6.2
- Fix sorting charset, encoding, and language with extra parameters
1.3.6 / 2019-04-28
==================
* deps: mime-types@~2.1.24
- deps: mime-db@~1.40.0
1.3.5 / 2018-02-28
==================
* deps: mime-types@~2.1.18
- deps: mime-db@~1.33.0
1.3.4 / 2017-08-22
==================
* deps: mime-types@~2.1.16
- deps: mime-db@~1.29.0
1.3.3 / 2016-05-02
==================
* deps: mime-types@~2.1.11
- deps: mime-db@~1.23.0
* deps: negotiator@0.6.1
- perf: improve `Accept` parsing speed
- perf: improve `Accept-Charset` parsing speed
- perf: improve `Accept-Encoding` parsing speed
- perf: improve `Accept-Language` parsing speed
1.3.2 / 2016-03-08
==================
* deps: mime-types@~2.1.10
- Fix extension of `application/dash+xml`
- Update primary extension for `audio/mp4`
- deps: mime-db@~1.22.0
1.3.1 / 2016-01-19
==================
* deps: mime-types@~2.1.9
- deps: mime-db@~1.21.0
1.3.0 / 2015-09-29
==================
* deps: mime-types@~2.1.7
- deps: mime-db@~1.19.0
* deps: negotiator@0.6.0
- Fix including type extensions in parameters in `Accept` parsing
- Fix parsing `Accept` parameters with quoted equals
- Fix parsing `Accept` parameters with quoted semicolons
- Lazy-load modules from main entry point
- perf: delay type concatenation until needed
- perf: enable strict mode
- perf: hoist regular expressions
- perf: remove closures getting spec properties
- perf: remove a closure from media type parsing
- perf: remove property delete from media type parsing
1.2.13 / 2015-09-06
===================
* deps: mime-types@~2.1.6
- deps: mime-db@~1.18.0
1.2.12 / 2015-07-30
===================
* deps: mime-types@~2.1.4
- deps: mime-db@~1.16.0
1.2.11 / 2015-07-16
===================
* deps: mime-types@~2.1.3
- deps: mime-db@~1.15.0
1.2.10 / 2015-07-01
===================
* deps: mime-types@~2.1.2
- deps: mime-db@~1.14.0
1.2.9 / 2015-06-08
==================
* deps: mime-types@~2.1.1
- perf: fix deopt during mapping
1.2.8 / 2015-06-07
==================
* deps: mime-types@~2.1.0
- deps: mime-db@~1.13.0
* perf: avoid argument reassignment & argument slice
* perf: avoid negotiator recursive construction
* perf: enable strict mode
* perf: remove unnecessary bitwise operator
1.2.7 / 2015-05-10
==================
* deps: negotiator@0.5.3
- Fix media type parameter matching to be case-insensitive
1.2.6 / 2015-05-07
==================
* deps: mime-types@~2.0.11
- deps: mime-db@~1.9.1
* deps: negotiator@0.5.2
- Fix comparing media types with quoted values
- Fix splitting media types with quoted commas
1.2.5 / 2015-03-13
==================
* deps: mime-types@~2.0.10
- deps: mime-db@~1.8.0
1.2.4 / 2015-02-14
==================
* Support Node.js 0.6
* deps: mime-types@~2.0.9
- deps: mime-db@~1.7.0
* deps: negotiator@0.5.1
- Fix preference sorting to be stable for long acceptable lists
1.2.3 / 2015-01-31
==================
* deps: mime-types@~2.0.8
- deps: mime-db@~1.6.0
1.2.2 / 2014-12-30
==================
* deps: mime-types@~2.0.7
- deps: mime-db@~1.5.0
1.2.1 / 2014-12-30
==================
* deps: mime-types@~2.0.5
- deps: mime-db@~1.3.1
1.2.0 / 2014-12-19
==================
* deps: negotiator@0.5.0
- Fix list return order when large accepted list
- Fix missing identity encoding when q=0 exists
- Remove dynamic building of Negotiator class
1.1.4 / 2014-12-10
==================
* deps: mime-types@~2.0.4
- deps: mime-db@~1.3.0
1.1.3 / 2014-11-09
==================
* deps: mime-types@~2.0.3
- deps: mime-db@~1.2.0
1.1.2 / 2014-10-14
==================
* deps: negotiator@0.4.9
- Fix error when media type has invalid parameter
1.1.1 / 2014-09-28
==================
* deps: mime-types@~2.0.2
- deps: mime-db@~1.1.0
* deps: negotiator@0.4.8
- Fix all negotiations to be case-insensitive
- Stable sort preferences of same quality according to client order
1.1.0 / 2014-09-02
==================
* update `mime-types`
1.0.7 / 2014-07-04
==================
* Fix wrong type returned from `type` when match after unknown extension
1.0.6 / 2014-06-24
==================
* deps: negotiator@0.4.7
1.0.5 / 2014-06-20
==================
* fix crash when unknown extension given
1.0.4 / 2014-06-19
==================
* use `mime-types`
1.0.3 / 2014-06-11
==================
* deps: negotiator@0.4.6
- Order by specificity when quality is the same
1.0.2 / 2014-05-29
==================
* Fix interpretation when header not in request
* deps: pin negotiator@0.4.5
1.0.1 / 2014-01-18
==================
* Identity encoding isn't always acceptable
* deps: negotiator@~0.4.0
1.0.0 / 2013-12-27
==================
* Genesis