First commit of the new Insider version on docker
This commit is contained in:
29
models/AuthUser.js
Normal file
29
models/AuthUser.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const pgp = require('pg-promise')
|
||||
const pool = require('../config/database');
|
||||
const bcrypt = require('bcrypt');
|
||||
|
||||
async function registerUser(username, password) {
|
||||
const hashedPassword = await bcrypt.hash(password, 10);
|
||||
const connection = await pool.getConnection();
|
||||
try {
|
||||
const [rows] = await connection.execute('INSERT INTO cdn (username, password) VALUES (?, ?)', [username, hashedPassword]);
|
||||
return rows.insertId;
|
||||
} finally {
|
||||
connection.release();
|
||||
}
|
||||
}
|
||||
|
||||
async function getUserByUsername(username) {
|
||||
const connection = await pool.getConnection();
|
||||
try {
|
||||
const [rows] = await connection.execute('SELECT * FROM cdn WHERE username = ?', [username]);
|
||||
return rows[0];
|
||||
} finally {
|
||||
connection.release();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
registerUser,
|
||||
getUserByUsername,
|
||||
};
|
||||
49
models/Passport-ActiveDirectory.js
Normal file
49
models/Passport-ActiveDirectory.js
Normal file
@@ -0,0 +1,49 @@
|
||||
const passport = require('passport');
|
||||
const ActiveDirectoryStrategy = require('passport-activedirectory');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { getUserData } = require('../Middlewares/watcherMiddleware');
|
||||
|
||||
const setupFilePath = path.join('setup.json');
|
||||
const setupData = JSON.parse(fs.readFileSync(setupFilePath, 'utf-8'));
|
||||
|
||||
passport.use(new ActiveDirectoryStrategy({
|
||||
integrated: false,
|
||||
ldap: {
|
||||
url: setupData.ldap.url,
|
||||
baseDN: setupData.ldap.baseDN,
|
||||
username: setupData.ldap.username,
|
||||
password: setupData.ldap.password
|
||||
}
|
||||
}, function (profile, ad, done) {
|
||||
ad.isUserMemberOf(profile._json.dn, 'CDN-Access', function (err, isMember) {
|
||||
if (err) return done(err);
|
||||
|
||||
if (!isMember) {
|
||||
return done(null, false, { message: 'L\'utilisateur n\'est pas autorisé.' });
|
||||
}
|
||||
|
||||
return done(null, profile);
|
||||
});
|
||||
}));
|
||||
|
||||
passport.serializeUser((user, done) => {
|
||||
done(null, user.name);
|
||||
});
|
||||
|
||||
passport.deserializeUser((id, done) => {
|
||||
const users = getUserData();
|
||||
|
||||
console.log('id:', id);
|
||||
console.log('users:', users);
|
||||
|
||||
const user = users.find(u => u.name === id.name || u.name === `.${id.name}`);
|
||||
|
||||
if (user) {
|
||||
return done(null, user);
|
||||
} else {
|
||||
return done(new Error('User not valid'), null);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = passport;
|
||||
46
models/Passport-Discord.js
Normal file
46
models/Passport-Discord.js
Normal file
@@ -0,0 +1,46 @@
|
||||
const passport = require('passport');
|
||||
const DiscordStrategy = require('passport-discord').Strategy;
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const setupFilePath = path.join('setup.json');
|
||||
const setupData = JSON.parse(fs.readFileSync(setupFilePath, 'utf-8'));
|
||||
|
||||
passport.use(new DiscordStrategy({
|
||||
clientID: setupData.discord.clientID,
|
||||
clientSecret: setupData.discord.clientSecret,
|
||||
callbackURL: `http://${setupData.domain}/auth/discord/callback`
|
||||
}, (accessToken, refreshToken, profile, done) => {
|
||||
fs.readFile('user.json', 'utf8', (err, data) => {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
const users = JSON.parse(data);
|
||||
const user = users.find(user => user.id === profile.id);
|
||||
|
||||
if (setupData.discord.authorizedIDs.length > 0 && !setupData.discord.authorizedIDs.includes(profile.id)) {
|
||||
return done(null, false, { message: 'L\'utilisateur n\'est pas autorisé.' });
|
||||
}
|
||||
|
||||
done(null, user);
|
||||
});
|
||||
}));
|
||||
|
||||
passport.serializeUser((user, done) => {
|
||||
done(null, user);
|
||||
});
|
||||
|
||||
passport.deserializeUser((id, done) => {
|
||||
fs.readFile('user.json', 'utf8', (err, data) => {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
const users = JSON.parse(data);
|
||||
const user = users.find(user => user.id === id);
|
||||
done(null, user);
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = passport;
|
||||
33
models/Passport-Google.js
Normal file
33
models/Passport-Google.js
Normal file
@@ -0,0 +1,33 @@
|
||||
const passport = require('passport');
|
||||
const GoogleStrategy = require('passport-google-oauth20').Strategy;
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const setupFilePath = path.join('setup.json');
|
||||
const setupData = JSON.parse(fs.readFileSync(setupFilePath, 'utf-8'));
|
||||
|
||||
passport.use(new GoogleStrategy({
|
||||
clientID: setupData.google.clientID,
|
||||
clientSecret: setupData.google.clientSecret,
|
||||
callbackURL: setupData.google.callbackURL
|
||||
},
|
||||
function(accessToken, refreshToken, profile, done) {
|
||||
// Ici, vous pouvez vérifier si l'utilisateur est autorisé ou non
|
||||
// Pour cet exemple, nous supposons que tous les utilisateurs Google sont autorisés
|
||||
return done(null, profile);
|
||||
}
|
||||
));
|
||||
|
||||
passport.serializeUser((user, done) => {
|
||||
done(null, user);
|
||||
});
|
||||
|
||||
passport.deserializeUser((user, done) => {
|
||||
if (user && (user.id)) {
|
||||
return done(null, user);
|
||||
} else {
|
||||
return done(new Error('User not valid'), null);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = passport;
|
||||
47
models/UserManagment.js
Normal file
47
models/UserManagment.js
Normal file
@@ -0,0 +1,47 @@
|
||||
const mysql = require('mysql2/promise');
|
||||
const pool = require('../config/database');
|
||||
|
||||
const userSchema = {
|
||||
username: {
|
||||
type: 'VARCHAR(255)',
|
||||
allowNull: false,
|
||||
unique: true
|
||||
},
|
||||
password: {
|
||||
type: 'VARCHAR(255)',
|
||||
allowNull: false
|
||||
},
|
||||
isAdmin: {
|
||||
type: 'BOOLEAN',
|
||||
allowNull: false,
|
||||
defaultValue: false
|
||||
}
|
||||
};
|
||||
|
||||
async function createUser(username, password, isAdmin) {
|
||||
const connection = await pool.getConnection();
|
||||
try {
|
||||
const [rows] = await connection.execute(
|
||||
'INSERT INTO cdn (username, password, isAdmin) VALUES (?, ?, ?)',
|
||||
[username, password, isAdmin]
|
||||
);
|
||||
return rows.insertId;
|
||||
} finally {
|
||||
connection.release();
|
||||
}
|
||||
}
|
||||
|
||||
async function getUserByUsername(username) {
|
||||
const connection = await pool.getConnection();
|
||||
try {
|
||||
const [rows] = await connection.execute('SELECT * FROM users WHERE username = ?', [username]);
|
||||
return rows[0];
|
||||
} finally {
|
||||
connection.release();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createUser,
|
||||
getUserByUsername
|
||||
};
|
||||
16
models/paramModel.js
Normal file
16
models/paramModel.js
Normal file
@@ -0,0 +1,16 @@
|
||||
const mysql = require('mysql2/promise');
|
||||
const pool = require('../config/database');
|
||||
|
||||
async function getUsers() {
|
||||
const connection = await pool.getConnection();
|
||||
try {
|
||||
const [rows] = await connection.execute('SELECT * FROM cdn');
|
||||
return rows || [];
|
||||
} finally {
|
||||
connection.release();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getUsers
|
||||
};
|
||||
100
models/reportManager.js
Normal file
100
models/reportManager.js
Normal file
@@ -0,0 +1,100 @@
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const ip = require('ip');
|
||||
const { logger, logRequestInfo, ErrorLogger } = require('../config/logs');
|
||||
const packageJson = require('../package.json');
|
||||
const si = require('systeminformation');
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
class SystemReport {
|
||||
static async generate() {
|
||||
const date = new Date();
|
||||
date.setDate(date.getDate() - 1);
|
||||
const previousDate = date.toISOString().split('T')[0];
|
||||
|
||||
const logFile = path.join(__dirname, '..', 'logs', `log-${previousDate}.log`);
|
||||
const logs = fs.readFileSync(logFile, 'utf-8');
|
||||
|
||||
const internalErrors = logs.split('\n').filter(line => /\[38;5;9mInternal-Error/.test(line));
|
||||
|
||||
if (internalErrors.length === 0) {
|
||||
logger.info('No internal errors in yesterday\'s logs. No report will be generated.');
|
||||
return null;
|
||||
}
|
||||
|
||||
function formatUptime(uptime) {
|
||||
const days = Math.floor(uptime / (24 * 60 * 60));
|
||||
uptime %= (24 * 60 * 60);
|
||||
const hours = Math.floor(uptime / (60 * 60));
|
||||
uptime %= (60 * 60);
|
||||
const minutes = Math.floor(uptime / 60);
|
||||
return `${days}d ${hours}h ${minutes}m`;
|
||||
}
|
||||
|
||||
const osInfo = {
|
||||
type: os.type(),
|
||||
platform: os.platform(),
|
||||
arch: os.arch(),
|
||||
release: os.release(),
|
||||
uptime: formatUptime(os.uptime()),
|
||||
loadavg: os.loadavg().map(load => (load / os.cpus().length) * 100)
|
||||
};
|
||||
|
||||
const networkInterfaces = os.networkInterfaces();
|
||||
const serverUptime = os.uptime();
|
||||
const systemLoad = os.loadavg();
|
||||
|
||||
const diskUsage = await si.fsSize();
|
||||
const cpuTemperature = await si.cpuTemperature();
|
||||
|
||||
const userInfo = os.userInfo();
|
||||
|
||||
const systemInfo = {
|
||||
memoryInfo: ((os.totalmem() - os.freemem()) / os.totalmem() * 100).toFixed(2),
|
||||
cpuInfo: (os.cpus().length / os.cpus().length * 100).toFixed(2),
|
||||
diskInfo: ((os.totalmem() - os.freemem()) / os.totalmem() * 100).toFixed(2),
|
||||
ipAddress: ip.address(),
|
||||
cdnVersion: packageJson.version,
|
||||
osInfo: osInfo,
|
||||
userInfo: userInfo,
|
||||
errors: internalErrors,
|
||||
networkInterfaces: networkInterfaces,
|
||||
serverUptime: serverUptime,
|
||||
systemLoad: systemLoad,
|
||||
diskUsage: diskUsage,
|
||||
cpuTemperature: cpuTemperature,
|
||||
};
|
||||
|
||||
const filename = path.join(__dirname, '..', 'report', `report_${previousDate}_${ip.address()}.json`);
|
||||
fs.writeFileSync(filename, JSON.stringify(systemInfo, null, 2));
|
||||
|
||||
logger.info("Preparing to send report...");
|
||||
logger.info("Report:", JSON.stringify(systemInfo, null, 2));
|
||||
|
||||
|
||||
try {
|
||||
const response = await fetch('https://apollon.dinawo.fr/api/report/receive', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(systemInfo)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
} else {
|
||||
const data = await response.json();
|
||||
logger.info('Report sent successfully. Response data:', data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
logger.error('Failed to send report. Error:', error);
|
||||
}
|
||||
|
||||
return systemInfo;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SystemReport;
|
||||
20
models/updateHelper.js
Normal file
20
models/updateHelper.js
Normal file
@@ -0,0 +1,20 @@
|
||||
const fs = require('fs');
|
||||
const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));
|
||||
const AdmZip = require('adm-zip');
|
||||
const { logger, ErrorLogger, logRequestInfo } = require('../config/logs');
|
||||
|
||||
function compareAndUpdate(currentPath, updatedPath) {
|
||||
}
|
||||
|
||||
async function downloadUpdate(updateUrl, destinationPath) {
|
||||
const response = await fetch(updateUrl);
|
||||
const buffer = await response.buffer();
|
||||
fs.writeFileSync(destinationPath, buffer);
|
||||
}
|
||||
|
||||
function unzipUpdate(zipPath, extractionPath) {
|
||||
const zip = new AdmZip(zipPath);
|
||||
zip.extractAllTo(extractionPath, /*overwrite*/ true);
|
||||
}
|
||||
|
||||
module.exports = { compareAndUpdate, downloadUpdate, unzipUpdate };
|
||||
141
models/updateManager.js
Normal file
141
models/updateManager.js
Normal file
@@ -0,0 +1,141 @@
|
||||
const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));
|
||||
const fs = require('fs').promises;
|
||||
const path = require('path');
|
||||
const AdmZip = require('adm-zip');
|
||||
const util = require('util');
|
||||
const ncp = util.promisify(require('ncp').ncp);
|
||||
const { downloadUpdate, unzipUpdate } = require('../models/updateHelper');
|
||||
const { logger, ErrorLogger } = require('../config/logs');
|
||||
|
||||
async function getFilesInVersion() {
|
||||
try {
|
||||
const response = await fetch('https://apollon.dinawo.fr/api/get/version');
|
||||
const data = await response.json();
|
||||
return data.update.files || [];
|
||||
} catch (error) {
|
||||
throw new Error(`Error getting files in version: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function listFilesInZip(zipFilePath) {
|
||||
try {
|
||||
const zip = new AdmZip(zipFilePath);
|
||||
const zipEntries = zip.getEntries();
|
||||
return zipEntries.map(entry => entry.entryName);
|
||||
} catch (error) {
|
||||
throw new Error(`Error listing files in zip: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteFileOrDirectory(filePath) {
|
||||
try {
|
||||
const stats = await fs.stat(filePath);
|
||||
if (stats.isDirectory()) {
|
||||
logger.info(`Skipped deletion of directory: ${filePath}`);
|
||||
} else {
|
||||
await fs.unlink(filePath);
|
||||
logger.info(`Updated file deleted: ${filePath}`);
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`Error deleting updated file or directory ${filePath}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
ncp.limit = 16;
|
||||
|
||||
async function moveFilesFromTemp(basePath, tempExtractFolder, filesInZip) {
|
||||
const entries = await fs.readdir(tempExtractFolder, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
const sourcePath = path.join(tempExtractFolder, entry.name);
|
||||
const targetPath = path.join(basePath, entry.name);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
await fs.mkdir(targetPath, { recursive: true });
|
||||
await ncp(sourcePath, targetPath);
|
||||
} else {
|
||||
const relativePath = path.relative(tempExtractFolder, sourcePath);
|
||||
|
||||
logger.info(`Processing file: ${relativePath}`);
|
||||
|
||||
if (filesInZip.includes(relativePath)) {
|
||||
const destinationPath = path.join(basePath, relativePath);
|
||||
await fs.mkdir(path.dirname(destinationPath), { recursive: true });
|
||||
|
||||
try {
|
||||
await fs.rename(sourcePath, destinationPath);
|
||||
logger.info(`File moved: ${relativePath}`);
|
||||
} catch (moveError) {
|
||||
logger.error(`Error moving file: ${relativePath}`, moveError);
|
||||
}
|
||||
} else {
|
||||
logger.info(`Skipped moving file: ${relativePath}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function applyUpdate(updateUrl, updateFolder) {
|
||||
const updateFilePath = path.join(updateFolder, 'update.zip');
|
||||
|
||||
try {
|
||||
await downloadUpdate(updateUrl, updateFilePath);
|
||||
|
||||
const filesInZip = await listFilesInZip(updateFilePath);
|
||||
logger.info('Zip contents:', filesInZip);
|
||||
|
||||
const filesInVersion = await getFilesInVersion();
|
||||
logger.info('Content of current version:', filesInVersion);
|
||||
|
||||
for (const file of filesInVersion) {
|
||||
try {
|
||||
await deleteFileOrDirectory(path.join(updateFolder, file));
|
||||
} catch (error) {
|
||||
ErrorLogger.error(`Error deleting updated file or directory ${file}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
const tempExtractFolder = path.join(updateFolder, 'temp_extract');
|
||||
await unzipUpdate(updateFilePath, tempExtractFolder);
|
||||
|
||||
await moveFilesFromTemp(updateFolder, tempExtractFolder, filesInZip);
|
||||
|
||||
logger.info('Update successful. The update has been applied successfully.');
|
||||
|
||||
} catch (error) {
|
||||
ErrorLogger.error(`Error applying update: ${error.message}`);
|
||||
} finally {
|
||||
await cleanUp(updateFolder, updateFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
async function cleanUp(basePath, zipFilePath) {
|
||||
const tempExtractFolder = path.join(basePath, 'temp_extract');
|
||||
await fs.rm(tempExtractFolder, { recursive: true });
|
||||
|
||||
await fs.unlink(zipFilePath);
|
||||
logger.info('Temporary files successfully deleted.');
|
||||
}
|
||||
|
||||
async function checkForUpdates() {
|
||||
try {
|
||||
logger.info('Checking for updates...');
|
||||
const response = await fetch('https://apollon.dinawo.fr/api/checkupdate');
|
||||
const result = await response.json();
|
||||
|
||||
if (result.updateAvailable) {
|
||||
const updateUrl = 'https://apollon.dinawo.fr/api/download/all';
|
||||
const updateFolder = path.join(__dirname, '..');
|
||||
|
||||
await fs.mkdir(updateFolder, { recursive: true });
|
||||
|
||||
await applyUpdate(updateUrl, updateFolder);
|
||||
} else {
|
||||
logger.info('No updates available.');
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error checking for updates:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { applyUpdate, listFilesInZip, checkForUpdates };
|
||||
Reference in New Issue
Block a user