Compare commits
9 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ee081c77f | |||
| 6f08bab103 | |||
| f4f2387739 | |||
| 5c3dc82778 | |||
| fb6e4e7df6 | |||
| 90619f2d99 | |||
| 8ce422c5a7 | |||
| 030e9011d6 | |||
| 2c2f125ef7 |
6 changed files with 512 additions and 329 deletions
7
.env
Normal file
7
.env
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
SERVER_PROTOCOL=https
|
||||||
|
SERVER_HOST=192.168.1.4
|
||||||
|
SERVER_PORT=4000
|
||||||
|
BASE_URL=https://prova.patachina.it
|
||||||
|
EMAIL=fabio@gmail.com
|
||||||
|
PASSWORD=master66
|
||||||
|
|
||||||
|
|
@ -1,182 +1,144 @@
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const ExifReader = require('exifreader');
|
const ExifReader = require('exifreader');
|
||||||
const sharp = require('sharp');
|
const sharp = require('sharp');
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
const loc = require('./geo.js');
|
|
||||||
|
|
||||||
//var productsDatabase = { photos: []}
|
const BASE_URL = process.env.BASE_URL;
|
||||||
//var i = 1;
|
const EMAIL = process.env.EMAIL;
|
||||||
//var s = 0;
|
const PASSWORD = process.env.PASSWORD;
|
||||||
//console.log("start search");
|
|
||||||
async function searchFile(dir, fileExt) {
|
|
||||||
var i = 1;
|
|
||||||
var s = 0;
|
|
||||||
s++;
|
|
||||||
// read the contents of the directory
|
|
||||||
console.log("è una directory?");
|
|
||||||
if(fs.existsSync('./public/photos')){
|
|
||||||
var ff = fs.statSync('./public/photos');
|
|
||||||
if(!ff.isDirectory()){
|
|
||||||
console.log("non è una dir");
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const files = fs.readdirSync(dir);
|
|
||||||
// search through the files
|
|
||||||
for (let k = 0; k < files.length; k++) {
|
|
||||||
file = files[k];
|
|
||||||
const filePath = path.join(dir, file);
|
|
||||||
|
|
||||||
// get the file stats
|
// -----------------------------------------------------
|
||||||
const fileStat = fs.statSync(filePath);
|
// LOGIN → ottiene token JWT
|
||||||
// if the file is a directory, recursively search the directory
|
// -----------------------------------------------------
|
||||||
if (fileStat.isDirectory()) {
|
async function getToken() {
|
||||||
await searchFile(filePath, fileExt);
|
|
||||||
} else if (path.extname(file).toLowerCase() == fileExt) {
|
|
||||||
// if the file is a match, print it
|
|
||||||
var dd = dir.split("/");
|
|
||||||
var d = dd.slice(1);
|
|
||||||
var d1 = dd.slice(1);
|
|
||||||
d1[1]= "thumbs";
|
|
||||||
var ff = file.split(".");
|
|
||||||
var fn = ff.slice(0,-1).join(".");
|
|
||||||
var f1 = fn+'_min'+'.'+ff.at(-1);
|
|
||||||
var f2 = fn+'_avg'+'.'+ff.at(-1);
|
|
||||||
var f3 = fn+'_sharp'+'.'+ff.at(-1);
|
|
||||||
var extFilePath = path.join(d.join("/"),file);
|
|
||||||
var extThumbMinPath = path.join(d1.join("/"),f1);
|
|
||||||
var extThumbAvgPath = path.join(d1.join("/"),f2);
|
|
||||||
var extThumbSharpPath = path.join("public",d1.join("/"),f3);
|
|
||||||
var thumbMinPath = path.join("public",extThumbMinPath);
|
|
||||||
var thumbAvgPath = path.join("public",extThumbAvgPath);
|
|
||||||
var dt = path.join("public",d1.join("/"));
|
|
||||||
if (!fs.existsSync(dt)){
|
|
||||||
fs.mkdirSync(dt, { recursive: true });
|
|
||||||
}
|
|
||||||
var data;
|
|
||||||
try {
|
|
||||||
data = fs.readFileSync(filePath);
|
|
||||||
} catch (err) {
|
|
||||||
//console.error(err);
|
|
||||||
}
|
|
||||||
const tags = await ExifReader.load(filePath, {expanded: true});
|
|
||||||
//console.log(tags);
|
|
||||||
var time = tags.exif.DateTimeOriginal;
|
|
||||||
if (time === undefined){} else {time=time.value[0]}
|
|
||||||
var gps = tags['gps'];
|
|
||||||
//console.log(gps.Latitude);
|
|
||||||
//console.log(gps.latitude);
|
|
||||||
//var loc;
|
|
||||||
var locat;
|
|
||||||
//console.log("ora");
|
|
||||||
if (gps === undefined){} else {
|
|
||||||
// locat = await loc(gps.Longitude,gps.Latitude);
|
|
||||||
}
|
|
||||||
//if (time === undefined ){console.log(filePath)}
|
|
||||||
//console.log("read: "+filePath);
|
|
||||||
await sharp(data)
|
|
||||||
.resize(100,100,"inside")
|
|
||||||
.withMetadata()
|
|
||||||
.toFile(thumbMinPath, (err, info) => {});
|
|
||||||
await sharp(data)
|
|
||||||
.resize(400)
|
|
||||||
.withMetadata()
|
|
||||||
.toFile(thumbAvgPath, (err, info) => {});
|
|
||||||
console.log(i+" - "+file);
|
|
||||||
scrivi({
|
|
||||||
id: i,
|
|
||||||
name: file,
|
|
||||||
path: extFilePath,
|
|
||||||
thub1: extThumbMinPath,
|
|
||||||
thub2: extThumbAvgPath,
|
|
||||||
gps: tags['gps'],
|
|
||||||
data: time,
|
|
||||||
location: locat
|
|
||||||
});
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if(k == files.length-1) {
|
|
||||||
if (s == 1) {
|
|
||||||
//scrivi(productsDatabase.photos);
|
|
||||||
//return;
|
|
||||||
//console.log("finito1");
|
|
||||||
//console.log(productsDatabase);
|
|
||||||
} else {
|
|
||||||
s--;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async function thumb(filePath, opt){
|
|
||||||
try {
|
try {
|
||||||
const thumbnail = await imageThumbnail(filePath, opt);
|
const res = await axios.post(`${BASE_URL}/auth/login`, {
|
||||||
//console.log(thumbnail);
|
email: EMAIL,
|
||||||
return thumbnail;
|
password: PASSWORD
|
||||||
|
});
|
||||||
|
return res.data.token;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
//console.error(err);
|
console.error("ERRORE LOGIN:", err.message);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// start the search in the current directory
|
|
||||||
async function scanPhoto(dir){
|
|
||||||
await searchFile(dir, '.jpg');
|
|
||||||
//console.log("finito2");
|
|
||||||
}
|
|
||||||
|
|
||||||
function scrivi(json) {
|
// -----------------------------------------------------
|
||||||
fetch('http://192.168.1.3:7771/auth/login', {
|
// INVIA FOTO AL SERVER
|
||||||
method: 'POST',
|
// -----------------------------------------------------
|
||||||
headers: {
|
async function sendPhoto(json) {
|
||||||
'Content-Type': 'application/json',
|
const token = await getToken();
|
||||||
},
|
if (!token) {
|
||||||
body: JSON.stringify({'email':'fabio@gmail.com', 'password':'master66'}),
|
console.error("Token non ottenuto, impossibile inviare foto");
|
||||||
})
|
return;
|
||||||
.then(response => response.json())
|
}
|
||||||
.then(user1 => {
|
|
||||||
const myHeaders = new Headers();
|
|
||||||
myHeaders.append('Authorization', 'Bearer ' + user1.token);
|
|
||||||
myHeaders.append('Content-Type', 'application/json');
|
|
||||||
//console.log(myHeaders.get("Content-Type"));
|
|
||||||
//console.log(myHeaders.get("Authorization"));
|
|
||||||
fetch('http://192.168.1.3:7771/photos', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: myHeaders,
|
|
||||||
body: JSON.stringify(json),
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
//.then(user => console.log("caricato"));
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
await axios.post(`${BASE_URL}/photos`, json, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Errore invio foto:", err.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function azzera() {
|
// -----------------------------------------------------
|
||||||
fetch('http://192.168.1.3:7771/auth/login', {
|
// CREA THUMBNAILS
|
||||||
method: 'POST',
|
// -----------------------------------------------------
|
||||||
headers: {
|
async function createThumbnails(filePath, thumbMinPath, thumbAvgPath) {
|
||||||
'Content-Type': 'application/json',
|
try {
|
||||||
},
|
await sharp(filePath)
|
||||||
body: JSON.stringify({'email':'fabio@gmail.com', 'password':'master66'}),
|
.resize(100, 100, { fit: "inside" })
|
||||||
})
|
.withMetadata()
|
||||||
.then(response => response.json())
|
.toFile(thumbMinPath);
|
||||||
.then(user1 => {
|
|
||||||
const myHeaders = new Headers();
|
|
||||||
myHeaders.append('Authorization', 'Bearer ' + user1.token);
|
|
||||||
myHeaders.append('Content-Type', 'application/json');
|
|
||||||
//console.log(myHeaders.get("Content-Type"));
|
|
||||||
//console.log(myHeaders.get("Authorization"));
|
|
||||||
fetch('http://192.168.1.3:7771/photos', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: myHeaders,
|
|
||||||
body: "",
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(user => console.log("azzerato totalmente"));
|
|
||||||
|
|
||||||
|
await sharp(filePath)
|
||||||
|
.resize(400)
|
||||||
|
.withMetadata()
|
||||||
|
.toFile(thumbAvgPath);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Errore creazione thumbnails:", err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// SCANSIONE RICORSIVA
|
||||||
|
// -----------------------------------------------------
|
||||||
|
async function scanDir(dir, ext, results = []) {
|
||||||
|
const files = fs.readdirSync(dir);
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
const filePath = path.join(dir, file);
|
||||||
|
const stat = fs.statSync(filePath);
|
||||||
|
|
||||||
|
if (stat.isDirectory()) {
|
||||||
|
await scanDir(filePath, ext, results);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.extname(file).toLowerCase() !== ext) continue;
|
||||||
|
|
||||||
|
console.log("Trovato:", file);
|
||||||
|
|
||||||
|
const relDir = dir.replace("public/", "");
|
||||||
|
const thumbDir = path.join("public", relDir.replace("original", "thumbs"));
|
||||||
|
|
||||||
|
if (!fs.existsSync(thumbDir)) {
|
||||||
|
fs.mkdirSync(thumbDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseName = path.parse(file).name;
|
||||||
|
const extName = path.parse(file).ext;
|
||||||
|
|
||||||
|
const thumbMin = path.join(thumbDir, `${baseName}_min${extName}`);
|
||||||
|
const thumbAvg = path.join(thumbDir, `${baseName}_avg${extName}`);
|
||||||
|
|
||||||
|
await createThumbnails(filePath, thumbMin, thumbAvg);
|
||||||
|
|
||||||
|
// EXIF
|
||||||
|
let tags = {};
|
||||||
|
try {
|
||||||
|
tags = await ExifReader.load(filePath, { expanded: true });
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
const time = tags?.exif?.DateTimeOriginal?.value?.[0] || null;
|
||||||
|
const gps = tags?.gps || null;
|
||||||
|
|
||||||
|
results.push({
|
||||||
|
name: file,
|
||||||
|
path: relDir + "/" + file,
|
||||||
|
thub1: thumbMin.replace("public/", ""),
|
||||||
|
thub2: thumbAvg.replace("public/", ""),
|
||||||
|
gps,
|
||||||
|
data: time,
|
||||||
|
location: null
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// FUNZIONE PRINCIPALE
|
||||||
|
// -----------------------------------------------------
|
||||||
|
async function scanPhoto(dir) {
|
||||||
|
console.log("Inizio scansione:", dir);
|
||||||
|
|
||||||
|
const photos = await scanDir(dir, ".jpg");
|
||||||
|
|
||||||
|
console.log("Trovate", photos.length, "foto");
|
||||||
|
|
||||||
|
for (const p of photos) {
|
||||||
|
await sendPhoto(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Scansione completata");
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = scanPhoto;
|
module.exports = scanPhoto;
|
||||||
182
api_v1/scanphoto.js.old
Normal file
182
api_v1/scanphoto.js.old
Normal file
|
|
@ -0,0 +1,182 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const ExifReader = require('exifreader');
|
||||||
|
const sharp = require('sharp');
|
||||||
|
const axios = require('axios');
|
||||||
|
const loc = require('./geo.js');
|
||||||
|
|
||||||
|
//var productsDatabase = { photos: []}
|
||||||
|
//var i = 1;
|
||||||
|
//var s = 0;
|
||||||
|
//console.log("start search");
|
||||||
|
async function searchFile(dir, fileExt) {
|
||||||
|
var i = 1;
|
||||||
|
var s = 0;
|
||||||
|
s++;
|
||||||
|
// read the contents of the directory
|
||||||
|
console.log("è una directory?");
|
||||||
|
if(fs.existsSync('./public/photos')){
|
||||||
|
var ff = fs.statSync('./public/photos');
|
||||||
|
if(!ff.isDirectory()){
|
||||||
|
console.log("non è una dir");
|
||||||
|
};
|
||||||
|
};
|
||||||
|
const files = fs.readdirSync(dir);
|
||||||
|
// search through the files
|
||||||
|
for (let k = 0; k < files.length; k++) {
|
||||||
|
file = files[k];
|
||||||
|
const filePath = path.join(dir, file);
|
||||||
|
|
||||||
|
// get the file stats
|
||||||
|
const fileStat = fs.statSync(filePath);
|
||||||
|
// if the file is a directory, recursively search the directory
|
||||||
|
if (fileStat.isDirectory()) {
|
||||||
|
await searchFile(filePath, fileExt);
|
||||||
|
} else if (path.extname(file).toLowerCase() == fileExt) {
|
||||||
|
// if the file is a match, print it
|
||||||
|
var dd = dir.split("/");
|
||||||
|
var d = dd.slice(1);
|
||||||
|
var d1 = dd.slice(1);
|
||||||
|
d1[1]= "thumbs";
|
||||||
|
var ff = file.split(".");
|
||||||
|
var fn = ff.slice(0,-1).join(".");
|
||||||
|
var f1 = fn+'_min'+'.'+ff.at(-1);
|
||||||
|
var f2 = fn+'_avg'+'.'+ff.at(-1);
|
||||||
|
var f3 = fn+'_sharp'+'.'+ff.at(-1);
|
||||||
|
var extFilePath = path.join(d.join("/"),file);
|
||||||
|
var extThumbMinPath = path.join(d1.join("/"),f1);
|
||||||
|
var extThumbAvgPath = path.join(d1.join("/"),f2);
|
||||||
|
var extThumbSharpPath = path.join("public",d1.join("/"),f3);
|
||||||
|
var thumbMinPath = path.join("public",extThumbMinPath);
|
||||||
|
var thumbAvgPath = path.join("public",extThumbAvgPath);
|
||||||
|
var dt = path.join("public",d1.join("/"));
|
||||||
|
if (!fs.existsSync(dt)){
|
||||||
|
fs.mkdirSync(dt, { recursive: true });
|
||||||
|
}
|
||||||
|
var data;
|
||||||
|
try {
|
||||||
|
data = fs.readFileSync(filePath);
|
||||||
|
} catch (err) {
|
||||||
|
//console.error(err);
|
||||||
|
}
|
||||||
|
const tags = await ExifReader.load(filePath, {expanded: true});
|
||||||
|
//console.log(tags);
|
||||||
|
var time = tags.exif.DateTimeOriginal;
|
||||||
|
if (time === undefined){} else {time=time.value[0]}
|
||||||
|
var gps = tags['gps'];
|
||||||
|
//console.log(gps.Latitude);
|
||||||
|
//console.log(gps.latitude);
|
||||||
|
//var loc;
|
||||||
|
var locat;
|
||||||
|
//console.log("ora");
|
||||||
|
if (gps === undefined){} else {
|
||||||
|
// locat = await loc(gps.Longitude,gps.Latitude);
|
||||||
|
}
|
||||||
|
//if (time === undefined ){console.log(filePath)}
|
||||||
|
//console.log("read: "+filePath);
|
||||||
|
await sharp(data)
|
||||||
|
.resize(100,100,"inside")
|
||||||
|
.withMetadata()
|
||||||
|
.toFile(thumbMinPath, (err, info) => {});
|
||||||
|
await sharp(data)
|
||||||
|
.resize(400)
|
||||||
|
.withMetadata()
|
||||||
|
.toFile(thumbAvgPath, (err, info) => {});
|
||||||
|
console.log(i+" - "+file);
|
||||||
|
scrivi({
|
||||||
|
id: i,
|
||||||
|
name: file,
|
||||||
|
path: extFilePath,
|
||||||
|
thub1: extThumbMinPath,
|
||||||
|
thub2: extThumbAvgPath,
|
||||||
|
gps: tags['gps'],
|
||||||
|
data: time,
|
||||||
|
location: locat
|
||||||
|
});
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if(k == files.length-1) {
|
||||||
|
if (s == 1) {
|
||||||
|
//scrivi(productsDatabase.photos);
|
||||||
|
//return;
|
||||||
|
//console.log("finito1");
|
||||||
|
//console.log(productsDatabase);
|
||||||
|
} else {
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async function thumb(filePath, opt){
|
||||||
|
try {
|
||||||
|
const thumbnail = await imageThumbnail(filePath, opt);
|
||||||
|
//console.log(thumbnail);
|
||||||
|
return thumbnail;
|
||||||
|
} catch (err) {
|
||||||
|
//console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// start the search in the current directory
|
||||||
|
async function scanPhoto(dir){
|
||||||
|
await searchFile(dir, '.jpg');
|
||||||
|
//console.log("finito2");
|
||||||
|
}
|
||||||
|
|
||||||
|
function scrivi(json) {
|
||||||
|
fetch('http://192.168.1.3:7771/auth/login', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({'email':'fabio@gmail.com', 'password':'master66'}),
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(user1 => {
|
||||||
|
const myHeaders = new Headers();
|
||||||
|
myHeaders.append('Authorization', 'Bearer ' + user1.token);
|
||||||
|
myHeaders.append('Content-Type', 'application/json');
|
||||||
|
//console.log(myHeaders.get("Content-Type"));
|
||||||
|
//console.log(myHeaders.get("Authorization"));
|
||||||
|
fetch('http://192.168.1.3:7771/photos', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: myHeaders,
|
||||||
|
body: JSON.stringify(json),
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
//.then(user => console.log("caricato"));
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function azzera() {
|
||||||
|
fetch('http://192.168.1.3:7771/auth/login', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({'email':'fabio@gmail.com', 'password':'master66'}),
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(user1 => {
|
||||||
|
const myHeaders = new Headers();
|
||||||
|
myHeaders.append('Authorization', 'Bearer ' + user1.token);
|
||||||
|
myHeaders.append('Content-Type', 'application/json');
|
||||||
|
//console.log(myHeaders.get("Content-Type"));
|
||||||
|
//console.log(myHeaders.get("Authorization"));
|
||||||
|
fetch('http://192.168.1.3:7771/photos', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: myHeaders,
|
||||||
|
body: "",
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(user => console.log("azzerato totalmente"));
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = scanPhoto;
|
||||||
273
api_v1/server.js
273
api_v1/server.js
|
|
@ -1,190 +1,153 @@
|
||||||
/**
|
require('dotenv').config();
|
||||||
* Require necessary libraries
|
|
||||||
*/
|
const fs = require('fs');
|
||||||
const fs = require('fs')
|
const bodyParser = require('body-parser');
|
||||||
const bodyParser = require('body-parser')
|
const jsonServer = require('json-server');
|
||||||
const jsonServer = require('json-server')
|
const jwt = require('jsonwebtoken');
|
||||||
const jwt = require('jsonwebtoken')
|
const bcrypt = require('bcrypt');
|
||||||
const bcrypt = require('bcrypt')
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const scanPhoto = require('./scanphoto.js')
|
const scanPhoto = require('./scanphoto.js');
|
||||||
|
|
||||||
|
const SECRET_KEY = process.env.JWT_SECRET || '123456789';
|
||||||
|
const EXPIRES_IN = process.env.JWT_EXPIRES || '1h';
|
||||||
|
const PORT = process.env.SERVER_PORT || 4000;
|
||||||
|
|
||||||
// JWT confing data
|
const server = jsonServer.create();
|
||||||
const SECRET_KEY = '123456789'
|
|
||||||
const expiresIn = '1h'
|
|
||||||
|
|
||||||
// Create server
|
// -----------------------------------------------------
|
||||||
var server = jsonServer.create()
|
// STATIC FILES
|
||||||
|
// -----------------------------------------------------
|
||||||
|
server.use(jsonServer.defaults({
|
||||||
|
static: path.join(__dirname, '../public')
|
||||||
|
}));
|
||||||
|
|
||||||
// Create router
|
// -----------------------------------------------------
|
||||||
if(fs.existsSync('./api_v1/db.json')){
|
// CONFIG ENDPOINT (PUBBLICO)
|
||||||
var router = jsonServer.router('./api_v1/db.json')
|
// -----------------------------------------------------
|
||||||
|
server.get('/config', (req, res) => {
|
||||||
|
res.json({
|
||||||
|
baseUrl: process.env.BASE_URL
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// ROUTER DB
|
||||||
|
// -----------------------------------------------------
|
||||||
|
let router;
|
||||||
|
if (fs.existsSync('./api_v1/db.json')) {
|
||||||
|
router = jsonServer.router('./api_v1/db.json');
|
||||||
} else {
|
} else {
|
||||||
const initialData = fs.readFileSync('api_v1/initialDB.json', 'utf8');
|
const initialData = fs.readFileSync('api_v1/initialDB.json', 'utf8');
|
||||||
// to update (sync) current database (db.json) file
|
fs.writeFileSync('api_v1/db.json', initialData);
|
||||||
fs.writeFileSync('api_v1/db.json', initialData);
|
router = jsonServer.router('./api_v1/db.json');
|
||||||
var router = jsonServer.router('./api_v1/db.json')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create router
|
// -----------------------------------------------------
|
||||||
var router = jsonServer.router('./api_v1/db.json')
|
// USERS DB
|
||||||
|
// -----------------------------------------------------
|
||||||
|
const userdb = JSON.parse(fs.readFileSync('./api_v1/users.json', 'UTF-8'));
|
||||||
|
|
||||||
// Users database
|
server.use(bodyParser.urlencoded({ extended: true }));
|
||||||
const userdb = JSON.parse(fs.readFileSync('./api_v1/users.json', 'UTF-8'))
|
server.use(bodyParser.json());
|
||||||
|
|
||||||
// Default middlewares
|
// -----------------------------------------------------
|
||||||
server.use(bodyParser.urlencoded({ extended: true }))
|
// JWT HELPERS
|
||||||
server.use(bodyParser.json())
|
// -----------------------------------------------------
|
||||||
|
|
||||||
// Create a token from a payload
|
|
||||||
function createToken(payload) {
|
function createToken(payload) {
|
||||||
return jwt.sign(payload, SECRET_KEY, { expiresIn })
|
return jwt.sign(payload, SECRET_KEY, { expiresIn: EXPIRES_IN });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the token
|
|
||||||
function verifyToken(token) {
|
function verifyToken(token) {
|
||||||
return jwt.verify(
|
return jwt.verify(token, SECRET_KEY, (err, decode) => decode || err);
|
||||||
token,
|
|
||||||
SECRET_KEY,
|
|
||||||
(err, decode) => (decode !== undefined ? decode : err)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the user exists in database
|
|
||||||
function isAuthenticated({ email, password }) {
|
function isAuthenticated({ email, password }) {
|
||||||
return (
|
return userdb.users.findIndex(
|
||||||
userdb.users.findIndex(
|
user => user.email === email && bcrypt.compareSync(password, user.password)
|
||||||
user =>
|
) !== -1;
|
||||||
user.email === email && bcrypt.compareSync(password, user.password)
|
|
||||||
) !== -1
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function azz(){
|
// -----------------------------------------------------
|
||||||
const initialData = fs.readFileSync('api_v1/initialDB.json', 'utf8');
|
// RESET DB
|
||||||
// to update (sync) current database (db.json) file
|
// -----------------------------------------------------
|
||||||
fs.writeFileSync('api_v1/db.json', initialData);
|
function resetDB() {
|
||||||
router.db.setState(JSON.parse(initialData));
|
const initialData = fs.readFileSync('api_v1/initialDB.json', 'utf8');
|
||||||
console.log('DB resettato');
|
fs.writeFileSync('api_v1/db.json', initialData);
|
||||||
|
router.db.setState(JSON.parse(initialData));
|
||||||
|
console.log('DB resettato');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
// con 192.168.1.3:7771/ apre http:192.168.1.3:7771/public.index.html
|
// HOME
|
||||||
|
// -----------------------------------------------------
|
||||||
server.get('/', (req, res) => {
|
server.get('/', (req, res) => {
|
||||||
//console.log(req.query)
|
res.sendFile(path.resolve("public/index.html"));
|
||||||
res.sendFile(path.resolve("public/index.html"))
|
});
|
||||||
})
|
|
||||||
|
|
||||||
// scansiona le foto
|
// -----------------------------------------------------
|
||||||
|
// SCAN FOTO
|
||||||
|
// -----------------------------------------------------
|
||||||
server.get('/scan', async (req, res) => {
|
server.get('/scan', async (req, res) => {
|
||||||
azz();
|
resetDB();
|
||||||
await scanPhoto('./public/photos/original')
|
await scanPhoto('./public/photos/original');
|
||||||
console.log("Ricaricato")
|
console.log("Ricaricato");
|
||||||
res.send({status: 'Ricaricato'})
|
res.send({ status: 'Ricaricato' });
|
||||||
})
|
});
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
// esempio http:192.168.1.3:7771/files?file=mio.txt
|
// FILE STATICI
|
||||||
|
// -----------------------------------------------------
|
||||||
server.get('/files', (req, res) => {
|
server.get('/files', (req, res) => {
|
||||||
console.log(req.query)
|
res.sendFile(path.resolve("public/" + req.query.file));
|
||||||
res.sendFile(path.resolve("public/"+req.query.file))
|
|
||||||
})
|
|
||||||
|
|
||||||
server.get('/initDB1',(req, res, next) => {
|
|
||||||
const Data = { photos: []};
|
|
||||||
// to update (sync) current database (db.json) file
|
|
||||||
fs.writeFileSync('api_v1/db.json', JSON.stringify(Data));
|
|
||||||
router.db.setState(Data);
|
|
||||||
res.send({status: 'DB resettato'});
|
|
||||||
//res.sendStatus(200);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
server.get('/initDB',(req, res, next) => {
|
// -----------------------------------------------------
|
||||||
const initialData = fs.readFileSync('api_v1/initialDB.json', 'utf8');
|
// RESET DB MANUALE
|
||||||
// to update (sync) current database (db.json) file
|
// -----------------------------------------------------
|
||||||
fs.writeFileSync('api_v1/db.json', initialData);
|
server.get('/initDB', (req, res) => {
|
||||||
router.db.setState(JSON.parse(initialData));
|
resetDB();
|
||||||
//router = jsonServer.router('./api_v1/db.json')
|
res.send({ status: 'DB resettato' });
|
||||||
res.send({status: 'DB resettato'});
|
|
||||||
//res.sendStatus(200);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
server.get('/log', (req, res) => {
|
// -----------------------------------------------------
|
||||||
console.log(server)
|
// LOGIN (PUBBLICO)
|
||||||
})
|
// -----------------------------------------------------
|
||||||
/*
|
|
||||||
server.use((req, res, next) => {
|
|
||||||
console.log(req.headers);
|
|
||||||
console.log(req.method);
|
|
||||||
console.log(req.path);
|
|
||||||
var a = req.path.split("/");
|
|
||||||
if (req.method === 'GET' && a[1] == 'pub' && a.length > 2) {
|
|
||||||
//console.log(req.headers.host);
|
|
||||||
//console.log(a.slice(2).join("/"));
|
|
||||||
res.status(200).sendFile(path.resolve("public/"+a.slice(2).join("/")));
|
|
||||||
//res.sendStatus(200);
|
|
||||||
} else {
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
*/
|
|
||||||
server.use((req, res, next) => {
|
|
||||||
console.log(req.headers);
|
|
||||||
console.log(req.method);
|
|
||||||
console.log(req.path);
|
|
||||||
var a = req.path.split("/");
|
|
||||||
if (req.method === 'GET' && a[1] == 'pub' && a.length > 2) {
|
|
||||||
//console.log(req.headers.host);
|
|
||||||
//console.log(a.slice(2).join("/"));
|
|
||||||
res.status(200).sendFile(path.resolve("public/"+req.path));
|
|
||||||
//res.sendStatus(200);
|
|
||||||
} else {
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method: POST
|
|
||||||
* Endpoint: /auth/login
|
|
||||||
*/
|
|
||||||
server.post('/auth/login', (req, res) => {
|
server.post('/auth/login', (req, res) => {
|
||||||
const { email, password } = req.body
|
const { email, password } = req.body;
|
||||||
if (isAuthenticated({ email, password }) === false) {
|
|
||||||
const status = 401
|
|
||||||
const message = 'Incorrect email or password'
|
|
||||||
res.status(status).json({ status, message })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const token = createToken({ email, password })
|
|
||||||
res.status(200).json({ token })
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
if (!isAuthenticated({ email, password })) {
|
||||||
* Middleware: Check authorization
|
return res.status(401).json({ status: 401, message: 'Incorrect email or password' });
|
||||||
*/
|
}
|
||||||
|
|
||||||
|
const token = createToken({ email });
|
||||||
|
res.status(200).json({ token });
|
||||||
|
});
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// JWT MIDDLEWARE (TUTTO IL RESTO È PROTETTO)
|
||||||
|
// -----------------------------------------------------
|
||||||
server.use(/^(?!\/auth).*$/, (req, res, next) => {
|
server.use(/^(?!\/auth).*$/, (req, res, next) => {
|
||||||
if (
|
if (!req.headers.authorization || req.headers.authorization.split(' ')[0] !== 'Bearer') {
|
||||||
req.headers.authorization === undefined ||
|
return res.status(401).json({ status: 401, message: 'Bad authorization header' });
|
||||||
req.headers.authorization.split(' ')[0] !== 'Bearer'
|
|
||||||
) {
|
|
||||||
const status = 401
|
|
||||||
const message = 'Bad authorization header'
|
|
||||||
res.status(status).json({ status, message })
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
verifyToken(req.headers.authorization.split(' ')[1])
|
|
||||||
next()
|
|
||||||
} catch (err) {
|
|
||||||
const status = 401
|
|
||||||
const message = 'Error: access_token is not valid'
|
|
||||||
res.status(status).json({ status, message })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Server mount
|
try {
|
||||||
server.use(router)
|
verifyToken(req.headers.authorization.split(' ')[1]);
|
||||||
server.listen(3000, () => {
|
next();
|
||||||
console.log('Auth API server runing on port 3000 ...')
|
} catch (err) {
|
||||||
})
|
res.status(401).json({ status: 401, message: 'Error: access_token is not valid' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// ROUTER JSON-SERVER
|
||||||
|
// -----------------------------------------------------
|
||||||
|
server.use(router);
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// START SERVER
|
||||||
|
// -----------------------------------------------------
|
||||||
|
server.listen(PORT, () => {
|
||||||
|
console.log(`Auth API server running on port ${PORT} ...`);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
"description": "Building a Fake and JWT Protected REST API with json-server",
|
"description": "Building a Fake and JWT Protected REST API with json-server",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "json-server --watch ./api_v1/db.json --host 0.0.0.0 -p 4000 -s ./public",
|
"start-no-auth": "json-server --watch ./api_v1/db.json --host 0.0.0.0 -p 4000 -s ./public",
|
||||||
"start-auth": "node ./api_v1/server.js --host 0.0.0.0 -p 4000 -s ./public",
|
"start": "node ./api_v1/server.js --host 0.0.0.0 -p 4000 -s ./public",
|
||||||
"mock-data": "node ./api_v1/generateData.js > ./api_v1/db.json",
|
"mock-data": "node ./api_v1/generateData.js > ./api_v1/db.json",
|
||||||
"hash": "node ./api_v1/tools.js",
|
"hash": "node ./api_v1/tools.js",
|
||||||
"search": "node ./api_v1/search.js",
|
"search": "node ./api_v1/search.js",
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,82 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
</head>
|
<meta charset="UTF-8">
|
||||||
<body>
|
<title>Gestione Foto</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
<script>
|
<h1>Gestione Foto</h1>
|
||||||
window.addEventListener("load", (event) => {
|
|
||||||
window.location.href = "pub/index.html";
|
<button onclick="scan()">Scansiona</button>
|
||||||
});
|
<button onclick="readDB()">Leggi DB</button>
|
||||||
</script>
|
<button onclick="resetDB()">Reset DB</button>
|
||||||
</body>
|
<button onclick="deleteAll()">Cancella tutto</button>
|
||||||
|
|
||||||
|
<pre id="out"></pre>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let BASE_URL = null;
|
||||||
|
let tok = null;
|
||||||
|
let db = [];
|
||||||
|
|
||||||
|
async function loadConfig() {
|
||||||
|
const res = await fetch('/config');
|
||||||
|
const cfg = await res.json();
|
||||||
|
BASE_URL = cfg.baseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function start() {
|
||||||
|
await loadConfig();
|
||||||
|
await login();
|
||||||
|
await readDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function login() {
|
||||||
|
const res = await fetch(`${BASE_URL}/auth/login`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ email: 'fabio@gmail.com', password: 'master66' })
|
||||||
|
});
|
||||||
|
const data = await res.json();
|
||||||
|
tok = data.token;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function readDB() {
|
||||||
|
const res = await fetch(`${BASE_URL}/photos`, {
|
||||||
|
headers: { 'Authorization': 'Bearer ' + tok }
|
||||||
|
});
|
||||||
|
db = await res.json();
|
||||||
|
document.getElementById('out').textContent = JSON.stringify(db, null, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function scan() {
|
||||||
|
await fetch(`${BASE_URL}/scan`, {
|
||||||
|
headers: { 'Authorization': 'Bearer ' + tok }
|
||||||
|
});
|
||||||
|
await readDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function resetDB() {
|
||||||
|
await fetch(`${BASE_URL}/initDB`, {
|
||||||
|
headers: { 'Authorization': 'Bearer ' + tok }
|
||||||
|
});
|
||||||
|
await readDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteAll() {
|
||||||
|
for (const item of db) {
|
||||||
|
await fetch(`${BASE_URL}/photos/${item.id}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: { 'Authorization': 'Bearer ' + tok }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await readDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
start();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Loading…
Reference in a new issue