Compare commits

...

9 commits

Author SHA1 Message Date
7ee081c77f Aggiorna api_v1/server.js 2026-02-20 19:27:58 +08:00
6f08bab103 Aggiorna package.json 2026-02-20 19:04:07 +08:00
f4f2387739 Aggiungi api_v1/scanphoto.js 2026-02-20 19:02:13 +08:00
5c3dc82778 Aggiorna api_v1/scanphoto.js.old 2026-02-20 19:01:38 +08:00
fb6e4e7df6 Aggiorna .env 2026-02-20 19:00:53 +08:00
90619f2d99 Aggiorna public/index.html 2026-02-20 18:59:55 +08:00
8ce422c5a7 Aggiungi .env 2026-02-20 18:58:49 +08:00
030e9011d6 Aggiorna public/index.html 2026-02-20 18:57:21 +08:00
2c2f125ef7 Aggiorna api_v1/server.js 2026-02-20 18:56:34 +08:00
6 changed files with 512 additions and 329 deletions

7
.env Normal file
View 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

View file

@ -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
View 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;

View file

@ -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} ...`);
});

View file

@ -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",

View file

@ -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>