Compare commits

...
2 Commits
Author SHA1 Message Date
raphix b17ab480a4 Version 1.0.0 - Basic Web Application 2024-12-29 15:18:26 +01:00
raphix 6f637968bd Version 1.0.0 - Basic Web Application 2024-12-29 15:18:12 +01:00
50 changed files with 37 additions and 6638 deletions

No files matched your search

Vendored
-19
View File
@@ -1,19 +0,0 @@
pipeline {
agent any
stages {
stage('[Neutral] - Déploiement') {
steps {
script {
echo "[Neutral-Deploy] - Deploy Stage"
sh "ssh raphix@raphix.fr sudo apt update -y"
sh "ssh raphix@raphix.fr sudo apt upgrade -y"
sh "ssh raphix@raphix.fr sudo -S -u gitlab-ci /home/gitlab-ci/neutral_deploy.sh"
}
}
}
}
}
+1 -1
View File
@@ -34,7 +34,7 @@ module.exports.check = function(token) {
}
/**
* Permet de se connecter à Neutral
* Permet de se connecter à Inventory
* @param {object} data
* @returns Token or AUTH_FAILED
*/
-5
View File
@@ -35,11 +35,6 @@ module.exports.updateFile = function (file) {
}
}
module.exports.getSettings = function () {
const file = this.getFile()
return {"jenkins_token": file.JENKINS_TOKEN, "omega_token": file.OMEGA_KEY}
}
module.exports.saveSettings = function (settings) {
const file = this.getFile()
file.JENKINS_TOKEN = settings.jenkins_token
-268
View File
@@ -1,268 +0,0 @@
const { LogType } = require("loguix")
const fs = require("fs")
const path = require("path")
const { __glob } = require("./global-variables")
const clog = new LogType("Fichier")
const os = require("os");
const uuid = require('uuid');
var mime = require('mime-types');
// check if shared folder exist, if not create it
if(!fs.existsSync(__glob.SHARED)) {
fs.mkdirSync(__glob.SHARED)
}
module.exports.getFiles = function(root) {
var response = new Object()
response.content = new Array()
try{
if(root == "homepath") {
root = os.homedir()
}
if(root == "sharepath") {
root = __glob.SHARED
}
if(root == "logpath") {
root = __glob.LOGS
}
if(!fs.existsSync(root)) {
response.content = "NOT_EXIST"
} else {
for(var file of fs.readdirSync(root)) {
const stat = fs.statSync(root + path.sep + file)
response.content.push({"name":file, id: uuid.v4().toString() ,"fileDirectory" : root + path.sep + file , "type":mime.lookup(file), "size":stat.size, "lastedition":stat.mtimeMs, "directory":stat.isDirectory()})
}
}
}catch(err) {
response.content = "NOT_PERMITTED"
}
response.root = root
response.parent = path.dirname(root)
return response
}
module.exports.createFolder = function(root) {
// Check if folder already exist
if(!fs.existsSync(root)) {
try {
fs.mkdirSync(root)
return "OK"
} catch(err) {
return "NOT_PERMITTED"
}
} else {
return 'EXIST'
}
}
module.exports.deleteFile = function(root) {
if(fs.existsSync(root)) {
try {
fs.rmSync(root, { recursive: true, force: true })
return "OK"
} catch(err) {
console.log(err)
return "NOT_PERMITTED"
}
} else {
return "NOT_EXIST"
}
}
module.exports.renameFile = function(settings) {
if(fs.existsSync(settings.root)) {
try {
fs.renameSync(settings.root + path.sep + settings.oldName, settings.root + path.sep + settings.newName)
return "OK"
} catch(err) {
return "NOT_PERMITTED"
}
} else {
return "NOT_EXIST"
}
}
module.exports.shareFile = function(settings) {
if(fs.existsSync(settings.root)) {
try {
//Create a sybolic link to shared folder
fs.symlinkSync(settings.root + path.sep + settings.name, __glob.SHARED + path.sep + settings.name)
// return the link of the file shared
if(process.env.DEV) {
return "http://localhost:3001/shared/" + settings.name
} else {
return "https://neutral.raphix.fr/shared/" + settings.name
}
} catch(err) {
console.log(err)
return "NOT_PERMITTED"
}
} else {
return "NOT_EXIST"
}
}
module.exports.getFile = function(root) {
if(fs.existsSync(root)) {
try {
// Check if the file is an image and if it is return the base64
if(mime.lookup(root).includes("image")) {
return "data:" + mime.lookup(root) + ";base64," + fs.readFileSync(root, "base64")
} else {
return fs.readFileSync(root, "utf-8")
}
} catch(err) {
console.log(err)
return "NOT_PERMITTED"
}
} else {
return "NOT_EXIST"
}
}
module.exports.saveFile = function(settings) {
try {
fs.writeFileSync(settings.root + path.sep + settings.name, settings.content)
return "OK"
} catch(err) {
console.log(err)
return "NOT_PERMITTED"
}
}
module.exports.downloadFile = function(root) {
if(fs.existsSync(root)) {
try {
return fs.readFileSync(root)
} catch(err) {
console.log(err)
return "NOT_PERMITTED"
}
} else {
return "NOT_EXIST"
}
}
module.exports.uploadFile = function(settings) {
try {
fs.writeFileSync(settings.root + path.sep + settings.name, settings.file)
return "OK"
} catch(err) {
console.log(err)
return "NOT_PERMITTED"
}
}
module.exports.newFile = function(settings) {
if(!fs.existsSync(settings)) {
try {
fs.writeFileSync(settings, "")
return "OK"
} catch(err) {
console.log(err)
return "NOT_PERMITTED"
}
} else {
return "EXIST"
}
}
module.exports.pasteFile = function(settings) {
if(settings.action == "cut") {
try {
fs.renameSync(settings.file.fileDirectory, settings.newPath + path.sep + settings.name)
return "OK"
} catch(err) {
console.log(err)
return "NOT_PERMITTED"
}
} else if(settings.action == "copy") {
try {
fs.copyFileSync(settings.file.fileDirectory, settings.newPath + path.sep + settings.name)
return "OK"
} catch(err) {
console.log(err)
return "NOT_PERMITTED"
}
}
}
-3
View File
@@ -5,12 +5,9 @@ const __glob = {
ROUTES: root + path.sep + "routes" + path.sep,
ROOT: root,
LOGS: root + path.sep + "logs",
ICON: root + path.sep + "public" + path.sep + 'images' + path.sep + "FormatLogo_WHITE.ico",
DATA: root + path.sep + "data",
USERS: root + path.sep + "data" + path.sep + "users.json",
CONFIG: root + path.sep + "data" + path.sep + "config.json",
SHARED: root + path.sep + "data" + path.sep + "shared",
USERS_IMAGES: root + path.sep + "data" + path.sep + "user_images",
PACKAGE_JSON: root + path.sep + "package.json",
};
-106
View File
@@ -1,106 +0,0 @@
const { LogType } = require("loguix")
const fs = require("fs")
const path = require("path")
const { __glob } = require("./global-variables")
const ulog = new LogType("Links")
const uuid = require("uuid")
const config = require("./config")
const {ApplyLinks} = require("../routes/link")
if(!fs.existsSync(__glob.DATA + path.sep + "links.json")) {
fs.writeFileSync(__glob.DATA + path.sep + "links.json", JSON.stringify([], null, 2))
}
module.exports.getLinks = function() {
return JSON.parse(fs.readFileSync(__glob.DATA + path.sep + "links.json"))
}
const FirstLinkManager = new ApplyLinks(this.getLinks())
module.exports.addLink = function(settings) {
var canDo = true
const links = this.getLinks()
var id = makeid(8)
if(settings.abstractLink) {
settings.dest = id.toString()
}
// Check if a destination already exists between links and if it's the case, we return an error "ALREADY_EXiST"
links.forEach((link) => {
if(link.dest == settings.dest) {
canDo = false
}
})
const link = {
id: id,
title: settings.title,
url: settings.url,
dest: settings.dest,
}
if(canDo) {
links.push(link)
fs.writeFileSync(__glob.DATA + path.sep + "links.json", JSON.stringify(links, null, 2))
const LinkManager = new ApplyLinks(this.getLinks())
return "OK"
} else {
return "ALREADY_EXIST"
}
}
module.exports.removeLink = function(id) {
const links = this.getLinks()
const newLinks = []
links.forEach((link) => {
if(link.id != id) {
newLinks.push(link)
}
})
fs.writeFileSync(__glob.DATA + path.sep + "links.json", JSON.stringify(newLinks, null, 2))
const LinkManager = new ApplyLinks(this.getLinks())
return "OK"
}
module.exports.updateLink = function(id, settings) {
const links = this.getLinks()
const newLinks = []
links.forEach((link) => {
if(link.id == id) {
link.title = settings.title
link.url = settings.url
}
newLinks.push(link)
})
fs.writeFileSync(__glob.DATA + path.sep + "links.json", JSON.stringify(newLinks, null, 2))
const LinkManager = new ApplyLinks(this.getLinks())
return "OK"
}
function makeid(length) {
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const charactersLength = characters.length;
let counter = 0;
while (counter < length) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
counter += 1;
}
return result;
}
-128
View File
@@ -1,128 +0,0 @@
const { LogType } = require("loguix")
const fs = require("fs")
const path = require("path")
var CryptoJS = require("crypto-js")
const { __glob } = require("./global-variables")
const { captureRejectionSymbol } = require("events")
const clog = new LogType("Metrics")
if(!fs.existsSync(__glob.DATA + path.sep + "metrics.json")) {
fs.writeFileSync(__glob.DATA + path.sep + "metrics.json", JSON.stringify([], null, 2))
}
module.exports.getDataMetrics = function() {
return JSON.parse(fs.readFileSync(__glob.DATA + path.sep + "metrics.json"))
}
module.exports.getMetrics = function() {
const metrics = this.getDataMetrics()
var metricsToReturn = new Array()
return new Promise(async (resolve, reject) => {
// Count the number processed
var processed = 0
if(metrics.length == 0) {
resolve(metricsToReturn)
}
await metrics.forEach(async (metric) => {
// Try to connect to the metric server with the key in query params named "privatekey"
// If the connection is successful, we add the metric to the list of metrics to return
const url = `http://${metric.address}:${metric.port}/metrics?privatekey=${metric.key}`
const fet = await fetch(url, {
method: "GET",
headers: {
"Accept": "application/json",
},
credentials: "include"
}).then(res => res.json())
.then(res => {
if(res) {
metric.data = res
metricsToReturn.push(metric)
processed++
} else {
metric.data = "ERROR"
metricsToReturn.push(metric)
}
if(processed == metrics.length) {
resolve(metricsToReturn)
}
}).catch((err) => {
metric.data = "ERROR"
metricsToReturn.push(metric)
processed++
if(processed == metrics.length) {
resolve(metricsToReturn)
}
})
})
})
}
module.exports.addMetric = function(settings) {
const metrics = this.getDataMetrics()
const metric = {
id: makeid(8),
name: settings.name,
address: settings.address,
port: settings.port,
key: settings.key,
}
metrics.push(metric)
fs.writeFileSync(__glob.DATA + path.sep + "metrics.json", JSON.stringify(metrics, null, 2))
return "OK"
}
module.exports.deleteMetric = function(id) {
const metrics = this.getDataMetrics()
metrics.forEach((metric) => {
if(metric.id == id) {
metrics.splice(metrics.indexOf(metric), 1)
}
})
fs.writeFileSync(__glob.DATA + path.sep + "metrics.json", JSON.stringify(metrics, null, 2))
return "OK"
}
function makeid(length) {
var result = [];
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
var charactersLength = characters.length;
for ( var i = 0; i < length; i++ ) {
result.push(characters.charAt(Math.floor(Math.random() *
charactersLength)));
}
return result.join('');
}
-138
View File
@@ -1,138 +0,0 @@
const { LogType } = require("loguix")
const fs = require("fs")
const path = require("path")
const { __glob } = require("./global-variables")
const clog = new LogType("Pïpeline")
const config = require("./config")
const tokenkey = config.getFile().JENKINS_TOKEN
module.exports.getAllPipelines = function() {
return new Promise((resolve, reject) => {
fetch(`https://jenkins.raphix.fr/api/json`, {
method: "GET",
headers: {
"Accept": "application/json",
"Authorization": `Basic ${tokenkey}`
},
credentials: "include"
})
.then(res => res.json())
.then(async list => {
const pipelinesJobs = new Array()
for(const job of list.jobs) {
await fetch(`${job.url}/api/json`, {
method: "GET",
headers: {
"Accept": "application/json",
"Authorization": `Basic ${tokenkey}`
},
credentials: "include"
})
.then(res => res.json())
.then(async res => {
if(res._class == "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject") {
await getJobMain(res).then(resJ => {
res.jobs[0] = resJ
pipelinesJobs.push(res)
})
} else {
pipelinesJobs.push(res)
}
})
}
list.jobs = pipelinesJobs
resolve(list)
})
.catch(err => {
resolve("UNAVAILABLE")
})
})
}
module.exports.startPipeline = function(pipeline) {
// If it's a freestyle job, build with params
if(pipeline.type == "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject") {
return new Promise((resolve, reject) => {
fetch(`${pipeline.url}/job/${pipeline.jobname}/build?delay=0sec`, {
method: "POST",
headers: {
"Authorization": `Basic ${tokenkey}`
},
credentials: "include"
})
.then(res => {
resolve("OK")
})
})
} else {
return new Promise((resolve, reject) => {
const parameters = pipeline.fields
const formatedParams = new URLSearchParams()
for(const param of parameters) {
formatedParams.append(param.name, param.value)
}
fetch(`${pipeline.url}/buildWithParameters?delay=0sec`, {
method: "POST",
headers: {
"Authorization": `Basic ${tokenkey}`,
"Content-Type": "application/x-www-form-urlencoded"
},
credentials: "include",
body: formatedParams
})
.then(res => {
resolve("OK")
})
})
}
}
function getJobMain(res) {
return new Promise(async (resolve, reject) => {
await fetch(`${res.jobs[0].url}/api/json`, {
method: "GET",
headers: {
'Accept': 'application/json',
'Authorization': `Basic ${tokenkey}`
},
credentials: 'include'
}).then(res => res.json())
.then(res => {
resolve(res)
})
})
}
-74
View File
@@ -1,74 +0,0 @@
const { LogType } = require("loguix")
const fs = require("fs")
const path = require("path")
const { __glob } = require("./global-variables")
const clog = new LogType("Serveur Metrics")
const osutils = require("os-utils")
const os = require("os")
const { statfs } = require("fs")
const config = require("./config")
module.exports.getMetrics = async function(server) {
return new Promise((resolve, reject) => {
if(server == "Alpha") {
var resp = "NULL"
const space = statfs("/", (err, stats) => {
if (err) {
throw err
}
osutils.cpuUsage(function(cpuUsage) {
resp = {
cpu: Math.round(cpuUsage * 1000),
usedram: osutils.totalmem() - osutils.freemem(),
totalram: osutils.totalmem(),
usedisk: stats.blocks - stats.bfree,
totaldisk: stats.blocks,
name: server
}
resolve(resp)
})
})
} else if(server == "Omega") {
const key = config.getFile().OMEGA_KEY;
fetch("http://omega.raphix.fr:4000/metrics?key="+key, {
method: "GET",
headers: {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7",
"Cache-Control": "no-cache",
"Connection": "keep-alive"
}
})
.then(response => response.json())
.then(raw => {
raw.name = server;
resolve(raw);
})
.catch(error => {
reject(error);
});
}
})
}
-296
View File
@@ -1,296 +0,0 @@
const { LogType } = require("loguix")
const fs = require("fs")
const path = require("path")
const { __glob } = require("./global-variables.js")
const auth = require("./auth.js")
const users = require("./users.js")
const files = require("./files.js")
const config = require("./config.js")
const links = require("./links.js")
const service = require("./services.js")
const pipeline = require("./pipelines.js")
const plog = new LogType("Web")
const cook = require("cookie")
const http = require("http")
const servermetrics = require("./server-metrics.js")
const metrics = require("./metrics.js")
const pm2 = require('pm2');
/**
* NOTE INTERNE
*
* Changer les pictures de users autre part
*/
/**
*
* @param {http.Server} server
*/
module.exports.serverIO = function(server) {
const io = require('socket.io')(server, {
maxHttpBufferSize: 1e8,
pingTimeout: 60000
})
io.on("connection", (socket) => {
let token = cook.parse(socket.handshake.headers.cookie).token
var user = auth.getUserByToken(token)
if(user) {
plog.log("Connexion au panel par '" + user.username + "' avec le socket : " + socket.id)
user.setLastLogin(new Date())
/**
* GET REQUEST
*/
// Get Users
GetRequest("USERINFO", () => {
user = auth.getUserByToken(token)
GetAnswer("USERINFO", {username: user.username, display_name: user.display_name ,picture: user.picture, permission: user.permission})
})
/**
* POST REQUEST
*/
PostRequest("US_EDIT_PERSONNAL", async (settings) => {
user = auth.getUserByToken(token)
PostAnswer("US_EDIT_PERSONNAL", await users.editMySelf(settings, user))
})
if(user.checkPermission("FILES_EXPLORER")) {
PostRequest("FX_GET", (root) => {
PostAnswer("FX_GET", files.getFiles(root))
})
PostRequest("FX_NEW_FOLDER", (root) => {
PostAnswer("FX_NEW_FOLDER", files.createFolder(root))
})
PostRequest("FX_DELETE", (root) => {
PostAnswer("FX_DELETE", files.deleteFile(root))
} )
PostRequest("FX_RENAME", (settings) => {
PostAnswer("FX_RENAME", files.renameFile(settings))
})
PostRequest("FX_SHARE", (settings) => {
PostAnswer("FX_SHARE", files.shareFile(settings))
})
PostRequest("FX_GETFILE", (root) => {
PostAnswer("FX_GETFILE", files.getFile(root))
})
PostRequest("FX_SAVEFILE", (settings) => {
PostAnswer("FX_SAVEFILE", files.saveFile(settings))
})
PostRequest("FX_NEW_FILE", (settings) => {
PostAnswer("FX_NEW_FILE", files.newFile(settings))
})
PostRequest("FX_UPLOAD", (settings) => {
PostAnswer("FX_UPLOAD", files.uploadFile(settings))
})
PostRequest("FX_PASTE", (settings) => {
PostAnswer("FX_PASTE", files.pasteFile(settings))
})
}
if(user.checkPermission("SERVICES")) {
PostRequest("SV_GET_SERVICE_STATUS", async (sv) => {
PostAnswer("SV_GET_SERVICE_STATUS", {answer: await service.getServiceStatus(sv), name: sv})
})
PostRequest("SV_START_SERVICE", async (sv) => {
PostAnswer("SV_START_SERVICE", {answer: await service.startService(sv), name: sv})
})
PostRequest("SV_STOP_SERVICE", async (sv) => {
PostAnswer("SV_STOP_SERVICE", {answer: await service.stopService(sv), name: sv})
})
PostRequest("SV_RESTART_SERVICE", async (sv) => {
PostAnswer("SV_RESTART_SERVICE", {answer: await service.restartService(sv), name: sv})
})
}
if(user.checkPermission("LINKS")) {
PostRequest("LINKS_GET_ALL", () => {
PostAnswer("LINKS_GET_ALL", {answer: "OK", links: links.getLinks()})
})
PostRequest("LINKS_ADD", (settings) => {
PostAnswer("LINKS_ADD", {answer: links.addLink(settings)})
})
PostRequest("LINKS_DELETE", (id) => {
PostAnswer("LINKS_DELETE", links.removeLink(id))
})
PostRequest("LINKS_EDIT", (settings) => {
PostAnswer("LINKS_EDIT", links.updateLink(settings.id, settings))
})
}
if(user.checkPermission("SERVERS")) {
PostRequest("SERVER_GET_METRICS_Alpha", async (settings) => {
PostAnswer("SERVER_GET_METRICS_Alpha", {answer: "OK", metrics: await servermetrics.getMetrics(settings), name: settings});
});
PostRequest("SERVER_GET_METRICS_Omega", async (settings) => {
PostAnswer("SERVER_GET_METRICS_Omega", {answer: "OK", metrics: await servermetrics.getMetrics(settings), name: settings});
});
}
if(user.checkPermission("PIPELINES")) {
GetRequest("PL_GET_ALL", async () => {
GetAnswer("PL_GET_ALL", await pipeline.getAllPipelines())
})
PostRequest("PL_START", async (settings) => {
PostAnswer("PL_START", await pipeline.startPipeline(settings))
})
}
if(user.checkPermission("USERS")) {
GetRequest("US_ALL", async () => {
GetAnswer("US_ALL", await users.getAllUsers())
})
PostRequest("US_ADD", async (settings) => {
PostAnswer("US_ADD", await users.addUser(settings))
})
PostRequest("US_DELETE", async (settings) => {
PostAnswer("US_DELETE", await users.deleteUser(settings))
})
PostRequest("US_EDIT", async (settings) => {
PostAnswer("US_EDIT", await users.editUser(settings))
})
PostRequest("US_CLEAR_TOKENS", async (settings) => {
PostAnswer("US_CLEAR_TOKENS", await users.clearTokens(settings))
})
}
if(user.checkPermission("SETTINGS")) {
PostRequest("SETTINGS_SAVE", async (settings) => {
PostAnswer("SETTINGS_SAVE", await config.saveSettings(settings))
})
PostRequest("SERVER_RESTART", async () => {
pm2.restart('Neutral')
})
PostRequest("SERVER_STOP", async () => {
pm2.stop('Neutral')
})
GetRequest("SERVER_GET_LOGS", async () => {
GetAnswer("SERVER_GET_LOGS", await fs.readdirSync(__glob.LOGS))
})
PostRequest("SERVER_READ_LOG", async (logs) => {
PostAnswer("SERVER_READ_LOG", await fs.readFileSync(__glob.LOGS + path.sep + logs).toString())
})
GetRequest("SETTINGS_GET", async () => {
GetAnswer("SETTINGS_GET", await config.getSettings())
})
}
if(user.checkPermission("METRICS")) {
GetRequest("MT_ALL", async () => {
GetAnswer("MT_ALL", await metrics.getMetrics())
})
PostRequest("MT_ADD", async (settings) => {
PostAnswer("MT_ADD", await metrics.addMetric(settings))
})
PostRequest("MT_DELETE", async (settings) => {
PostAnswer("MT_DELETE", await metrics.deleteMetric(settings))
})
}
socket.on("disconnect", (reason) => {
plog.log("Déconnexion du panel par '" + user.username + "' avec le socket : " + socket.id)
})
socket.on("connect_error", (err) => {
console.log(err)
console.log(err.message); // prints the message associated with the error
});
function GetRequest(GQname, GQcallback) {
socket.on("GET/" + GQname, () => {
plog.log(user.username + " - Socket : " + socket.id + " - GET/" + GQname + " - [RECIEVED]")
GQcallback()
})
}
function GetAnswer(GRname, GRvalue) {
plog.log(user.username + " - Socket : " + socket.id + " - GET/" + GRname + " - [ANSWERED]")
socket.emit("ANSWER/GET/" + GRname, GRvalue)
}
function PostRequest(GQname, GQcallback) {
socket.on("POST/" + GQname, (value) => {
plog.log(user.username + " - Socket : " + socket.id + " - POST/" + GQname + " - [RECIEVED]")
GQcallback(value)
})
}
function PostAnswer(GRname, GRvalue) {
plog.log(user.username + " - Socket : " + socket.id + " - POST/" + GRname + " - [ANSWERED]")
socket.emit("ANSWER/POST/" + GRname, GRvalue)
}
} else {
socket.disconnect()
plog.warn("Connexion directe vers le panel avec un token inexistant : " + this.token)
}
})
}
-137
View File
@@ -1,137 +0,0 @@
const { LogType } = require("loguix")
const fs = require("fs")
const path = require("path")
const { __glob } = require("./global-variables")
const clog = new LogType("Services")
const http = require('http');
const https = require('https');
module.exports.getServiceStatus = function(service) {
const protocol = service.startsWith('https') ? https : http;
const url = new URL(service);
const options = {
method: 'HEAD',
host: url.hostname,
port: url.port,
path: url.pathname,
};
return new Promise((resolve, reject) => {
const req = protocol.request(options, (res) => {
if(res.statusCode !== 502) {
resolve("ONLINE");
} else {
resolve("OFFLINE");
}
});
req.on('error', (err) => {
resolve("OFFLINE");
});
req.end();
});
}
module.exports.stopService = function(service) {
return new Promise((resolve, reject) => {
const child_process = require('child_process');
if(service == `https://subsonics.raphix.fr`) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@alpha.raphix.fr sudo -S -u gitlab-ci 'pm2 stop "Subsonics"'`)
resolve("OK")
} else if(service == `https://git.raphix.fr` ) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@omega.raphix.fr sudo -S systemctl stop gitea`)
resolve("OK")
} else if(service == `https://jenkins.raphix.fr`) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@omega.raphix.fr sudo -S systemctl stop jenkins `)
resolve("OK")
} else if(service == `https://raphix.fr`) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@alpha.raphix.fr sudo -S -u gitlab-ci 'pm2 stop "Website - Raphix"'`)
resolve("OK")
} else if(service == `https://cv.raphix.fr`) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@alpha.raphix.fr sudo -S -u gitlab-ci 'pm2 stop "CV - Raphael"'`)
resolve("OK")
} else if(service == `http://omega.raphix.fr:2333`) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@omega.raphix.fr sudo -S systemctl stop lavalink `)
resolve("OK")
} else {
resolve(false)
}
});
}
module.exports.startService = function(service) {
return new Promise((resolve, reject) => {
const child_process = require('child_process');
if(service == `https://subsonics.raphix.fr`) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@alpha.raphix.fr sudo -S -u gitlab-ci 'pm2 start /home/gitlab-ci/subsonic.config.js'`)
resolve("OK")
} else if(service == `https://git.raphix.fr` ) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@omega.raphix.fr sudo -S systemctl start gitea`)
resolve("OK")
} else if(service == `https://jenkins.raphix.fr`) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@omega.raphix.fr sudo -S systemctl start jenkins `)
resolve("OK")
} else if(service == `https://raphix.fr`) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@alpha.raphix.fr sudo -S -u gitlab-ci 'pm2 start /home/gitlab-ci/website.config.js'`)
resolve("OK")
} else if(service == `https://cv.raphix.fr`) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@alpha.raphix.fr sudo -S -u gitlab-ci 'pm2 start /home/gitlab-ci/cv.config.js'`)
resolve("OK")
} else if(service == `http://omega.raphix.fr:2333`) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@omega.raphix.fr sudo -S systemctl start lavalink `)
resolve("OK")
} else {
resolve(false)
}
});
}
module.exports.restartService = function(service) {
return new Promise((resolve, reject) => {
const child_process = require('child_process');
if(service == `https://subsonics.raphix.fr`) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@alpha.raphix.fr sudo -S -u gitlab-ci 'pm2 restart "Subsonics"'`)
resolve("OK")
} else if(service == `https://git.raphix.fr` ) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@omega.raphix.fr sudo -S systemctl restart gitea`)
resolve("OK")
} else if(service == `https://jenkins.raphix.fr`) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@omega.raphix.fr sudo -S systemctl restart jenkins `)
resolve("OK")
} else if(service == `https://raphix.fr`) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@alpha.raphix.fr sudo -S -u gitlab-ci 'pm2 restart "Website - Raphix"'`)
resolve("OK")
} else if(service == `https://cv.raphix.fr`) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@alpha.raphix.fr sudo -S -u gitlab-ci 'pm2 restart "CV - Raphael"'`)
resolve("OK")
} else if(service == `http://omega.raphix.fr:2333`) {
let req = child_process.exec(`ssh -o StrictHostKeyChecking=no raphix@omega.raphix.fr sudo -S systemctl restart lavalink `)
resolve("OK")
} else {
resolve(false)
}
});
}
+5 -119
View File
@@ -50,10 +50,8 @@ module.exports.fetchUsers = function () {
username: userFetched.username,
password: userFetched.password,
display_name: userFetched.display_name,
permission: userFetched.permission,
tokens: userFetched.tokens,
lastLogin: userFetched.lastLogin,
picture: userFetched.picture
})
@@ -63,21 +61,10 @@ module.exports.fetchUsers = function () {
if(usersList.size == 0) {
const adminUser = new this.User({
"username": "admin",
"password": "neutral",
"password": "inventory",
"display_name": "Administrateur",
"permission": [
"FILES_EXPLORER",
"SERVICES",
"SERVERS",
"PIPELINES",
"METRICS",
"USERS",
"LINKS",
"SETTINGS"
],
"tokens": [],
"lastLogin": "DEFAULT ACCOUNT",
"picture": "/images/default.jpg"
})
@@ -94,16 +81,14 @@ module.exports.fetchUsers = function () {
/**
* User Class is used to access to default user's properties and methods
* @param {object} properties User properties with : username, password, display_name, permission...
* @param {object} properties User properties with : username, password, display_name
*/
module.exports.User = class {
username = null
password = null;
display_name = null
permission = []
tokens = []
lastLogin = new Date()
picture = "/images/default.jpg"
constructor(properties) {
@@ -112,10 +97,8 @@ module.exports.User = class {
this.username = properties.username
this.password = keygen.encrypt(properties.password)
this.display_name = properties.display_name
this.permission = properties.permission
this.tokens = properties.tokens
this.lastLogin = properties.lastLogin
this.picture = properties.picture
const userFile = getFile()
@@ -125,7 +108,6 @@ module.exports.User = class {
this.username = userFetched.username
this.password = userFetched.password
this.display_name = userFetched.display_name
this.permission = userFetched.permission
this.tokens = userFetched.tokens
this.lastLogin = userFetched.lastLogin
}
@@ -150,22 +132,14 @@ module.exports.User = class {
ulog.warn("'" + this.username + "' is without display name !")
this.display_name = this.username
}
if(this.permission == null) {
ulog.warn("'" + this.username + "' has no longer permission !")
}
if(this.tokens == null) {
this.tokens = []
}
if(this.permission == null) {
this.permission = []
}
if(this.lastLogin == null) {
this.lastLogin = new Date()
}
if(this.picture == null) {
this.picture = "/images/default.jpg"
}
}
@@ -211,47 +185,7 @@ module.exports.User = class {
usersList.delete(this.username)
}
checkPermission(name) {
this.#sync()
if(this.permission.includes(name)) {
return true
} else {
return false
}
}
addPermission(name) {
this.#sync()
for(var perms of this.permission) {
if(name == perms) {
ulog.warn("'" + this.username + "' a déjà la permission : " + name)
return false
}
}
this.permission.push(name)
this.register()
}
removePermission(name) {
this.#sync()
var havePermission = false
for(var perms of this.permission) {
if(name == perms) {
havePermission = true
}
}
if(havePermission) {
this.permission.splice(this.permission.indexOf(name), 1)
this.register()
} else {
ulog.warn("'" + this.username + "' n'a pas la permission : " + name)
return false
}
}
setPassword(newPassword) {
this.#sync()
@@ -293,14 +227,6 @@ module.exports.User = class {
}
setPicture(text) {
this.#sync()
this.picture = text
this.register()
ulog.log("La photo de l'utilisateur a été modifié : " + this.username)
}
setDisplayName(text) {
this.#sync()
this.display_name = text
@@ -325,24 +251,6 @@ module.exports.User = class {
this.register()
}
setPicture(file) {
this.#sync()
var pictureDir = __glob.USERS_IMAGES + path.sep + uuid.v4().toString() + ".png"
if(!fs.existsSync(__glob.USERS_IMAGES)) {
fs.mkdirSync(__glob.USERS_IMAGES)
}
fs.writeFileSync(pictureDir, file)
this.picture = pictureDir.replace(__glob.USERS_IMAGES + path.sep, "/users/")
this.register()
}
setPermissions(permissions) {
this.#sync()
this.permission = permissions
this.register()
}
clearTokens() {
this.#sync()
this.tokens = []
@@ -357,7 +265,6 @@ module.exports.User = class {
this.username = userFetched.username
this.password = userFetched.password
this.display_name = userFetched.display_name
this.permission = userFetched.permission
this.tokens = userFetched.tokens
this.lastLogin = userFetched.lastLogin
}
@@ -382,23 +289,10 @@ module.exports.addUser = function(settings) {
return "ALREADY_EXIST"
} else {
ulog.step.init("add_user", "Ajout d'un utilisateur dans la base de donnée : " + settings.username)
var pictureDir = null
if(settings.picture == null) {
pictureDir = "/images/default.jpg"
} else {
pictureDir = __glob.USERS_IMAGES + path.sep + uuid.v4().toString() + ".png"
fs.writeFileSync(pictureDir, settings.picture)
}
const user = new this.User({
username: settings.username,
display_name: settings.display_name,
permission: settings.permissions,
picture: pictureDir.replace(__glob.USERS_IMAGES + path.sep, "/images/users/")
display_name: settings.display_name
})
@@ -451,13 +345,8 @@ module.exports.editUser = function(settings) {
user.setPassword(settings.password)
}
if(settings.picture) {
user.setPicture(settings.picture)
}
if(settings.permissions) {
user.setPermissions(settings.permissions)
}
ulog.step.end("edit_user")
return "OK"
} else {
@@ -498,9 +387,6 @@ module.exports.editMySelf = function (settings, user) {
user.setPassword(settings.password)
}
if(settings.picture) {
user.setPicture(settings.picture)
}
ulog.step.end("edit_user")
return "OK"
} else {
+1 -3
View File
@@ -20,13 +20,12 @@ wlog.step.init("start_server", "Démarrage du serveur Express JS")
var app = require('../main');
var http = require('http');
var config = require("./config")
var serverIO = require("./servers")
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3001');
var port = normalizePort(process.env.PORT || '5005');
app.set('port', port);
/**
@@ -34,7 +33,6 @@ app.set('port', port);
*/
var server = http.createServer(app);
serverIO.serverIO(server)
/**
* Listen on provided port, on all network interfaces.
+1 -3
View File
@@ -2,7 +2,7 @@ const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
var favicon = require('serve-favicon');
var favicon = require('express-favicon');
const app = express();
const fs = require("fs");
const log = require("loguix")
@@ -47,8 +47,6 @@ function setup() {
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')))
app.use("/shared", express.static(__glob.SHARED))
app.use("/users", express.static(__glob.USERS_IMAGES))
getRouters()
+14 -223
View File
@@ -1,12 +1,12 @@
{
"name": "neutral",
"version": "0.7.0",
"name": "inventory",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "neutral",
"version": "0.7.0",
"name": "inventory",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"cookie-parser": "~1.4.4",
@@ -14,14 +14,12 @@
"debug": "~2.6.9",
"ejs": "~2.6.1",
"express": "~4.16.1",
"express-favicon": "^2.0.4",
"http-errors": "~1.6.3",
"install": "^0.13.0",
"loguix": "^1.4.2",
"nodemon": "^3.0.1",
"os-utils": "^0.0.14",
"pm2": "^5.3.0",
"serve-favicon": "^2.0.4",
"socket.io": "^4.7.2",
"uuid": "^9.0.1"
}
},
@@ -294,32 +292,10 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/@socket.io/component-emitter": {
"version": "3.1.0",
"license": "MIT"
},
"node_modules/@tootallnate/quickjs-emscripten": {
"version": "0.23.0",
"license": "MIT"
},
"node_modules/@types/cookie": {
"version": "0.4.1",
"license": "MIT"
},
"node_modules/@types/cors": {
"version": "2.8.15",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/node": {
"version": "20.8.10",
"license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/abbrev": {
"version": "1.1.1",
"license": "ISC"
@@ -468,13 +444,6 @@
"version": "1.0.2",
"license": "MIT"
},
"node_modules/base64id": {
"version": "2.0.0",
"license": "MIT",
"engines": {
"node": "^4.5.0 || >= 5.9"
}
},
"node_modules/basic-ftp": {
"version": "5.0.4",
"license": "MIT",
@@ -683,17 +652,6 @@
"version": "1.0.6",
"license": "MIT"
},
"node_modules/cors": {
"version": "2.8.5",
"license": "MIT",
"dependencies": {
"object-assign": "^4",
"vary": "^1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/croner": {
"version": "4.1.97",
"license": "MIT"
@@ -772,51 +730,6 @@
"node": ">= 0.8"
}
},
"node_modules/engine.io": {
"version": "6.5.3",
"license": "MIT",
"dependencies": {
"@types/cookie": "^0.4.1",
"@types/cors": "^2.8.12",
"@types/node": ">=10.0.0",
"accepts": "~1.3.4",
"base64id": "2.0.0",
"cookie": "~0.4.1",
"cors": "~2.8.5",
"debug": "~4.3.1",
"engine.io-parser": "~5.2.1",
"ws": "~8.11.0"
},
"engines": {
"node": ">=10.2.0"
}
},
"node_modules/engine.io-parser": {
"version": "5.2.1",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/engine.io/node_modules/debug": {
"version": "4.3.4",
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/engine.io/node_modules/ms": {
"version": "2.1.2",
"license": "MIT"
},
"node_modules/enquirer": {
"version": "2.3.6",
"license": "MIT",
@@ -935,6 +848,15 @@
"node": ">= 0.10.0"
}
},
"node_modules/express-favicon": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/express-favicon/-/express-favicon-2.0.4.tgz",
"integrity": "sha512-JDGzumJdwF+WcJf+qwyhdpF1yzducuMCxZa+G6hxR3hor7ae/1CqpAPj8FXCGaGtqBA6ExDMfeszjuYRw5GUuQ==",
"license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/express/node_modules/cookie": {
"version": "0.3.1",
"license": "MIT",
@@ -1223,13 +1145,6 @@
"version": "1.3.8",
"license": "ISC"
},
"node_modules/install": {
"version": "0.13.0",
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/ip": {
"version": "1.1.8",
"license": "MIT"
@@ -1523,13 +1438,6 @@
"version": "0.4.14",
"license": "MIT"
},
"node_modules/object-assign": {
"version": "4.1.1",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/on-finished": {
"version": "2.3.0",
"license": "MIT",
@@ -2099,28 +2007,6 @@
"node": ">= 0.8.0"
}
},
"node_modules/serve-favicon": {
"version": "2.5.0",
"license": "MIT",
"dependencies": {
"etag": "~1.8.1",
"fresh": "0.5.2",
"ms": "2.1.1",
"parseurl": "~1.3.2",
"safe-buffer": "5.1.1"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/serve-favicon/node_modules/ms": {
"version": "2.1.1",
"license": "MIT"
},
"node_modules/serve-favicon/node_modules/safe-buffer": {
"version": "5.1.1",
"license": "MIT"
},
"node_modules/serve-static": {
"version": "1.13.2",
"license": "MIT",
@@ -2164,78 +2050,6 @@
"npm": ">= 3.0.0"
}
},
"node_modules/socket.io": {
"version": "4.7.2",
"license": "MIT",
"dependencies": {
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"cors": "~2.8.5",
"debug": "~4.3.2",
"engine.io": "~6.5.2",
"socket.io-adapter": "~2.5.2",
"socket.io-parser": "~4.2.4"
},
"engines": {
"node": ">=10.2.0"
}
},
"node_modules/socket.io-adapter": {
"version": "2.5.2",
"license": "MIT",
"dependencies": {
"ws": "~8.11.0"
}
},
"node_modules/socket.io-parser": {
"version": "4.2.4",
"license": "MIT",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socket.io-parser/node_modules/debug": {
"version": "4.3.4",
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/socket.io-parser/node_modules/ms": {
"version": "2.1.2",
"license": "MIT"
},
"node_modules/socket.io/node_modules/debug": {
"version": "4.3.4",
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/socket.io/node_modules/ms": {
"version": "2.1.2",
"license": "MIT"
},
"node_modules/socks": {
"version": "2.7.1",
"license": "MIT",
@@ -2417,10 +2231,6 @@
"version": "2.0.5",
"license": "MIT"
},
"node_modules/undici-types": {
"version": "5.26.5",
"license": "MIT"
},
"node_modules/universalify": {
"version": "0.1.2",
"license": "MIT",
@@ -2484,25 +2294,6 @@
"version": "1.0.2",
"license": "ISC"
},
"node_modules/ws": {
"version": "8.11.0",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/yallist": {
"version": "4.0.0",
"license": "ISC"
+5 -7
View File
@@ -1,7 +1,7 @@
{
"name": "neutral",
"version": "1.1.0",
"description": "Panel d'administration de Raphix",
"name": "inventory",
"version": "1.0.0",
"description": "Gestion de veteements",
"main": "index.js",
"scripts": {
"start": "nodemon ./bin/www",
@@ -9,7 +9,7 @@
},
"repository": {
"type": "git",
"url": "https://git.raphix.fr/infrastructure/neutral.git"
"url": "https://git.raphix.fr/raphix/inventory.git"
},
"nodemonConfig": {
"ext": "js, html",
@@ -26,13 +26,11 @@
"ejs": "~2.6.1",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"install": "^0.13.0",
"loguix": "^1.4.2",
"nodemon": "^3.0.1",
"os-utils": "^0.0.14",
"pm2": "^5.3.0",
"serve-favicon": "^2.0.4",
"socket.io": "^4.7.2",
"express-favicon": "^2.0.4",
"uuid": "^9.0.1"
},
"author": "Raphix",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 455 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

-50
View File
@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 481.43 481.43">
<defs>
<style>
.cls-1 {
stroke-width: 40px;
}
.cls-1, .cls-2, .cls-3, .cls-4, .cls-5 {
stroke: #1d1d1b;
stroke-miterlimit: 10;
}
.cls-1, .cls-3, .cls-5 {
fill: none;
}
.cls-2, .cls-3 {
stroke-width: 2px;
}
.cls-2, .cls-4 {
fill: #1d1d1b;
}
.cls-5 {
stroke-width: 10px;
}
</style>
</defs>
<circle class="cls-1" cx="240.78" cy="240.65" r="190.13"/>
<circle class="cls-1" cx="240.78" cy="240.65" r="112.42"/>
<circle class="cls-5" cx="240.78" cy="240.65" r="52"/>
<circle class="cls-5" cx="240.78" cy="240.65" r="36"/>
<circle class="cls-3" cx="240.78" cy="240.65" r="17.5"/>
<line class="cls-2" x1="240.78" y1="187.65" x2="240.78" y2="204.13"/>
<line class="cls-2" x1="293.78" y1="240.65" x2="276.29" y2="240.65"/>
<path class="cls-2" d="m228.23,252.44c-3.81,3.81-7.62,7.62-11.43,11.43"/>
<path class="cls-4" d="m240.05,7.01c7.99,14.68,16.4,32.59,23.67,53.57,6.88,19.85,11.25,38.14,14.07,53.93-9.15-2.76-22.44-5.68-38.61-5.59-15.41.08-28.12,2.87-37.04,5.55,2.78-15.73,7.13-34.02,14.04-53.88,7.32-21.05,15.82-38.96,23.86-53.57Z"/>
<path class="cls-4" d="m240.86,474.3c7.99-14.68,16.4-32.59,23.67-53.57,6.88-19.85,11.25-38.14,14.07-53.93-9.15,2.76-22.44,5.68-38.61,5.59-15.41-.08-28.12-2.87-37.04-5.55,2.78,15.73,7.13,34.02,14.04,53.88,7.32,21.05,15.82,38.96,23.86,53.57Z"/>
<path class="cls-4" d="m7.05,240.83c14.68-7.99,32.59-16.4,53.57-23.67,19.85-6.88,38.14-11.25,53.93-14.07-2.76,9.15-5.68,22.44-5.59,38.61.08,15.41,2.87,28.12,5.55,37.04-15.73-2.78-34.02-7.13-53.88-14.04-21.05-7.32-38.96-15.82-53.57-23.86Z"/>
<path class="cls-4" d="m474.27,240.61c-14.68-7.99-32.59-16.4-53.57-23.67-19.85-6.88-38.14-11.25-53.93-14.07,2.76,9.15,5.68,22.44,5.59,38.61-.08,15.41-2.87,28.12-5.55,37.04,15.73-2.78,34.02-7.13,53.88-14.04,21.05-7.32,38.96-15.82,53.57-23.86Z"/>
<line class="cls-2" x1="203.8" y1="240.69" x2="186.31" y2="240.69"/>
<line class="cls-2" x1="240.78" y1="275.18" x2="240.78" y2="291.66"/>
<path class="cls-2" d="m264.13,216.54c-3.94,3.94-7.87,7.87-11.81,11.81"/>
<g>
<path class="cls-2" d="m253.02,253.15c3.81,3.81,7.62,7.62,11.43,11.43"/>
<path class="cls-2" d="m217.12,217.25c3.94,3.94,7.87,7.87,11.81,11.81"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

-50
View File
@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 481.43 481.43">
<defs>
<style>
.cls-1 {
stroke-width: 40px;
}
.cls-1, .cls-2, .cls-3, .cls-4, .cls-5 {
stroke: #ffffff;
stroke-miterlimit: 10;
}
.cls-1, .cls-3, .cls-5 {
fill: none;
}
.cls-2, .cls-3 {
stroke-width: 2px;
}
.cls-2, .cls-4 {
fill: #ffffff;
}
.cls-5 {
stroke-width: 10px;
}
</style>
</defs>
<circle class="cls-1" cx="240.78" cy="240.65" r="190.13"/>
<circle class="cls-1" cx="240.78" cy="240.65" r="112.42"/>
<circle class="cls-5" cx="240.78" cy="240.65" r="52"/>
<circle class="cls-5" cx="240.78" cy="240.65" r="36"/>
<circle class="cls-3" cx="240.78" cy="240.65" r="17.5"/>
<line class="cls-2" x1="240.78" y1="187.65" x2="240.78" y2="204.13"/>
<line class="cls-2" x1="293.78" y1="240.65" x2="276.29" y2="240.65"/>
<path class="cls-2" d="m228.23,252.44c-3.81,3.81-7.62,7.62-11.43,11.43"/>
<path class="cls-4" d="m240.05,7.01c7.99,14.68,16.4,32.59,23.67,53.57,6.88,19.85,11.25,38.14,14.07,53.93-9.15-2.76-22.44-5.68-38.61-5.59-15.41.08-28.12,2.87-37.04,5.55,2.78-15.73,7.13-34.02,14.04-53.88,7.32-21.05,15.82-38.96,23.86-53.57Z"/>
<path class="cls-4" d="m240.86,474.3c7.99-14.68,16.4-32.59,23.67-53.57,6.88-19.85,11.25-38.14,14.07-53.93-9.15,2.76-22.44,5.68-38.61,5.59-15.41-.08-28.12-2.87-37.04-5.55,2.78,15.73,7.13,34.02,14.04,53.88,7.32,21.05,15.82,38.96,23.86,53.57Z"/>
<path class="cls-4" d="m7.05,240.83c14.68-7.99,32.59-16.4,53.57-23.67,19.85-6.88,38.14-11.25,53.93-14.07-2.76,9.15-5.68,22.44-5.59,38.61.08,15.41,2.87,28.12,5.55,37.04-15.73-2.78-34.02-7.13-53.88-14.04-21.05-7.32-38.96-15.82-53.57-23.86Z"/>
<path class="cls-4" d="m474.27,240.61c-14.68-7.99-32.59-16.4-53.57-23.67-19.85-6.88-38.14-11.25-53.93-14.07,2.76,9.15,5.68,22.44,5.59,38.61-.08,15.41-2.87,28.12-5.55,37.04,15.73-2.78,34.02-7.13,53.88-14.04,21.05-7.32,38.96-15.82,53.57-23.86Z"/>
<line class="cls-2" x1="203.8" y1="240.69" x2="186.31" y2="240.69"/>
<line class="cls-2" x1="240.78" y1="275.18" x2="240.78" y2="291.66"/>
<path class="cls-2" d="m264.13,216.54c-3.94,3.94-7.87,7.87-11.81,11.81"/>
<g>
<path class="cls-2" d="m253.02,253.15c3.81,3.81,7.62,7.62,11.43,11.43"/>
<path class="cls-2" d="m217.12,217.25c3.94,3.94,7.87,7.87,11.81,11.81"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 455 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

-1
View File
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="main_outline" x="0px" y="0px" viewBox="0 0 640 640" style="enable-background:new 0 0 640 640;" xml:space="preserve"><g><path id="teabag" style="fill:#ffffff00" d="M395.9,484.2l-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5,21.2-17.9,33.8-11.8 c17.2,8.3,27.1,13,27.1,13l-0.1-109.2l16.7-0.1l0.1,117.1c0,0,57.4,24.2,83.1,40.1c3.7,2.3,10.2,6.8,12.9,14.4 c2.1,6.1,2,13.1-1,19.3l-61,126.9C423.6,484.9,408.4,490.3,395.9,484.2z"/><g><g><path style="fill: white;" d="M622.7,149.8c-4.1-4.1-9.6-4-9.6-4s-117.2,6.6-177.9,8c-13.3,0.3-26.5,0.6-39.6,0.7c0,39.1,0,78.2,0,117.2 c-5.5-2.6-11.1-5.3-16.6-7.9c0-36.4-0.1-109.2-0.1-109.2c-29,0.4-89.2-2.2-89.2-2.2s-141.4-7.1-156.8-8.5 c-9.8-0.6-22.5-2.1-39,1.5c-8.7,1.8-33.5,7.4-53.8,26.9C-4.9,212.4,6.6,276.2,8,285.8c1.7,11.7,6.9,44.2,31.7,72.5 c45.8,56.1,144.4,54.8,144.4,54.8s12.1,28.9,30.6,55.5c25,33.1,50.7,58.9,75.7,62c63,0,188.9-0.1,188.9-0.1s12,0.1,28.3-10.3 c14-8.5,26.5-23.4,26.5-23.4s12.9-13.8,30.9-45.3c5.5-9.7,10.1-19.1,14.1-28c0,0,55.2-117.1,55.2-231.1 C633.2,157.9,624.7,151.8,622.7,149.8z M125.6,353.9c-25.9-8.5-36.9-18.7-36.9-18.7S69.6,321.8,60,295.4 c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5,38.5-30c13.8-3.7,31-3.1,31-3.1s7.1,59.4,15.7,94.2c7.2,29.2,24.8,77.7,24.8,77.7 S142.5,359.9,125.6,353.9z M425.9,461.5c0,0-6.1,14.5-19.6,15.4c-5.8,0.4-10.3-1.2-10.3-1.2s-0.3-0.1-5.3-2.1l-112.9-55 c0,0-10.9-5.7-12.8-15.6c-2.2-8.1,2.7-18.1,2.7-18.1L322,273c0,0,4.8-9.7,12.2-13c0.6-0.3,2.3-1,4.5-1.5c8.1-2.1,18,2.8,18,2.8 l110.7,53.7c0,0,12.6,5.7,15.3,16.2c1.9,7.4-0.5,14-1.8,17.2C474.6,363.8,425.9,461.5,425.9,461.5z"/><path style="fill:white;" d="M326.8,380.1c-8.2,0.1-15.4,5.8-17.3,13.8c-1.9,8,2,16.3,9.1,20c7.7,4,17.5,1.8,22.7-5.4 c5.1-7.1,4.3-16.9-1.8-23.1l24-49.1c1.5,0.1,3.7,0.2,6.2-0.5c4.1-0.9,7.1-3.6,7.1-3.6c4.2,1.8,8.6,3.8,13.2,6.1 c4.8,2.4,9.3,4.9,13.4,7.3c0.9,0.5,1.8,1.1,2.8,1.9c1.6,1.3,3.4,3.1,4.7,5.5c1.9,5.5-1.9,14.9-1.9,14.9 c-2.3,7.6-18.4,40.6-18.4,40.6c-8.1-0.2-15.3,5-17.7,12.5c-2.6,8.1,1.1,17.3,8.9,21.3c7.8,4,17.4,1.7,22.5-5.3 c5-6.8,4.6-16.3-1.1-22.6c1.9-3.7,3.7-7.4,5.6-11.3c5-10.4,13.5-30.4,13.5-30.4c0.9-1.7,5.7-10.3,2.7-21.3 c-2.5-11.4-12.6-16.7-12.6-16.7c-12.2-7.9-29.2-15.2-29.2-15.2s0-4.1-1.1-7.1c-1.1-3.1-2.8-5.1-3.9-6.3c4.7-9.7,9.4-19.3,14.1-29 c-4.1-2-8.1-4-12.2-6.1c-4.8,9.8-9.7,19.7-14.5,29.5c-6.7-0.1-12.9,3.5-16.1,9.4c-3.4,6.3-2.7,14.1,1.9,19.8 C343.2,346.5,335,363.3,326.8,380.1z"/></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

-1
View File
@@ -1 +0,0 @@
<svg viewBox="-80.5 0 417 417" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" fill="#000000"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <g> <path d="M250.741085,169.277519 C250.741085,238.734884 195.671318,295.094574 127.702326,295.094574 C59.7333333,295.094574 4.66356589,238.734884 4.66356589,169.277519 C4.66356589,99.820155 59.7333333,43.4604651 127.702326,43.4604651 C195.671318,43.4604651 250.741085,99.820155 250.741085,169.277519" fill="#D33833"> </path> <path d="M9.72403101,200.434109 C9.72403101,200.434109 0.79379845,69.2589147 121.748837,65.4883721 L113.314729,51.3984496 L47.7271318,73.4263566 L28.9736434,94.9581395 L12.6015504,126.313178 L3.2744186,162.827907 L6.05271318,187.237209" fill="#EF3D3A"> </path> <path d="M43.4604651,83.448062 C21.9286822,105.575194 8.53333333,136.037209 8.53333333,169.773643 L8.53333333,169.773643 C8.53333333,203.510078 21.9286822,233.972093 43.4604651,256.099225 L43.4604651,256.099225 C65.0914729,278.226357 94.7596899,291.820155 127.702326,291.820155 L127.702326,291.820155 C160.644961,291.820155 190.313178,278.226357 211.944186,256.099225 L211.944186,256.099225 C233.475969,233.972093 246.871318,203.510078 246.871318,169.773643 L246.871318,169.773643 C246.871318,136.037209 233.475969,105.575194 211.944186,83.448062 L211.944186,83.448062 C190.313178,61.420155 160.644961,47.7271318 127.702326,47.7271318 L127.702326,47.7271318 C94.8589147,47.7271318 65.0914729,61.3209302 43.4604651,83.448062 L43.4604651,83.448062 L43.4604651,83.448062 Z M38.0031008,261.35814 C15.0821705,237.941085 0.893023256,205.494574 0.893023256,169.773643 L0.893023256,169.773643 C0.893023256,134.052713 15.0821705,101.606202 38.0031008,78.0899225 L38.0031008,78.0899225 C60.924031,54.6728682 92.675969,40.0868217 127.702326,40.0868217 L127.702326,40.0868217 C162.728682,40.0868217 194.48062,54.6728682 217.40155,78.0899225 L217.40155,78.0899225 C240.322481,101.506977 254.511628,133.953488 254.511628,169.773643 L254.511628,169.773643 C254.511628,205.494574 240.322481,237.941085 217.40155,261.35814 L217.40155,261.35814 C194.48062,284.874419 162.728682,299.36124 127.702326,299.36124 L127.702326,299.36124 C92.675969,299.36124 60.924031,284.874419 38.0031008,261.35814 L38.0031008,261.35814 L38.0031008,261.35814 Z" fill="#231F20"> </path> <path d="M179.497674,169.972093 L160.744186,172.750388 L135.44186,175.627907 L119.069767,176.024806 L103.094574,175.528682 L90.8899225,171.75814 L80.0744186,160.049612 L71.6403101,136.136434 L69.7550388,130.976744 L58.5426357,127.206202 L51.9937984,116.390698 L47.3302326,100.911628 L52.4899225,87.3178295 L64.6945736,83.0511628 L74.5178295,87.7147287 L79.1813953,98.0341085 L84.8372093,97.1410853 L86.7224806,94.7596899 L84.8372093,83.944186 L84.3410853,70.3503876 L87.1193798,51.5968992 L87.020155,40.8806202 L95.5534884,27.1875969 L110.536434,16.372093 L136.731783,5.15968992 L165.804651,9.42635659 L191.106977,27.6837209 L202.815504,46.4372093 L210.356589,60.0310078 L212.24186,93.7674419 L206.586047,122.84031 L196.266667,148.63876 L186.542636,162.431008" fill="#F0D6B7"> </path> <path d="M163.621705,251.03876 L96.6449612,253.817054 L96.6449612,265.029457 L102.300775,304.421705 L99.5224806,307.696124 L52.6883721,291.72093 L49.4139535,286.065116 L44.7503876,233.07907 L33.7364341,201.327132 L31.3550388,193.786047 L68.8620155,167.987597 L80.5705426,163.324031 L90.8899225,176.024806 L99.820155,183.962791 L110.139535,187.237209 L114.803101,188.626357 L120.458915,213.035659 L124.725581,218.195349 L135.541085,214.424806 L128,229.010853 L168.682171,248.260465 L163.621705,251.03876" fill="#335061"> </path> <path d="M52.4899225,87.5162791 L64.6945736,83.2496124 L74.5178295,87.9131783 L79.1813953,98.2325581 L84.8372093,97.3395349 L86.2263566,91.6837209 L83.448062,80.8682171 L86.2263566,55.0697674 L83.8449612,40.979845 L92.2790698,31.1565891 L110.536434,16.6697674 L105.376744,9.6248062 L79.5782946,22.3255814 L68.7627907,30.7596899 L62.7100775,43.8573643 L53.3829457,56.5581395 L50.6046512,71.5410853 L52.4899225,87.5162791" fill="#6D6B6D"> </path> <path d="M71.7395349,43.4604651 C71.7395349,43.4604651 78.7844961,26.096124 106.865116,17.6620155 C134.945736,9.22790698 108.254264,11.6093023 108.254264,11.6093023 L77.7922481,23.3178295 L66.0837209,35.0263566 L60.924031,44.3534884 L71.7395349,43.4604651" fill="#DCD9D8"> </path> <path d="M57.6496124,84.2418605 C57.6496124,84.2418605 47.8263566,51.3984496 85.3333333,46.7348837 L83.944186,41.0790698 L58.1457364,47.1317829 L50.6046512,71.5410853 L52.4899225,87.5162791 L57.6496124,84.2418605" fill="#DCD9D8"> </path> <path d="M72.6325581,127.80155 L78.7844961,121.848062 C78.7844961,121.848062 81.5627907,122.145736 82.0589147,125.420155 C82.5550388,128.694574 83.944186,158.263566 104.086822,174.139535 C105.972093,175.627907 89.103876,171.75814 89.103876,171.75814 L74.1209302Line truncated

Before

Width:  |  Height:  |  Size: 47 KiB

-48
View File
@@ -1,48 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 100 100"
width="100%"
height="100%"
version="1.1"
id="svg13"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs7">
<linearGradient
id="grad"
x1="0"
y1="0"
x2="100"
y2="100"
spreadMethod="pad"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
stop-color="#ff8c00"
id="stop2"
style="stop-color:#fa9800;stop-opacity:1;" />
<stop
offset="100"
stop-color="#ff0000"
id="stop4"
style="stop-color:#ff005e;stop-opacity:1;" />
</linearGradient>
</defs>
<rect
width="100%"
height="100%"
fill="url(#grad)"
id="rect9"
x="0"
y="0"
style="fill:url(#grad)" />
<path
style="vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:1.27808;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;stop-color:#000000"
d="m 57,25 h 13 l -7,27 h 12 l -2,8.5 H 48 Z"
id="path724-5" />
<path
style="opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:1.33907;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;stop-color:#000000;stop-opacity:1"
d="m 37.5,25 h 14 l -10,40 H 72 L 70,75 H 25 Z"
id="path724" />
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

File diff suppressed because it is too large. Load diff
-786
View File
@@ -1,786 +0,0 @@
document.addEventListener("contextmenu", (e) => {
e.preventDefault()
})
explorer.createWindow(() => {
var inCopyOrCut = null;
const View = new ViewWindow({
title: `<i class="fa fa-folder"></i> Gestionnaire de fichiers`,
width: "1000px",
height: "600px"
})
goHomePath()
function goHomePath() {
const rFiles = post("FX_GET", "homepath")
rFiles.then((result) => {
loadFiles(result)
})
}
function goSharePath() {
const rFiles = post("FX_GET", "sharepath")
rFiles.then((result) => {
loadFiles(result)
})
}
View.setContent(`
<div class="fx-window">
<div class='fx-bar'>
<span id='${View.getViewTitle()}_home' class='btn-cover'><i class='fa fa-home'></i></span>
<span id='${View.getViewTitle()}_sharebtn' class='btn-cover'><i class="fa-solid fa-share-from-square"></i></span>
<input class='fx-root-input' type="text" id='${View.getViewTitle()}_rootInput'>
<div class='fx-bar-actions'>
<button id='${View.getViewTitle()}_newFolder' class='btn blue'><span><i class='fa fa-folder'></i> Nouv. dossier</span></button>
<button id='${View.getViewTitle()}_newFile' class='btn green'><span><i class="fa-solid fa-file-arrow-up"></i> Nouveau</span></button>
</div>
</div>
<div id='${View.getViewTitle()}_explorer' class='fx-explorer'>
<div style='font-size: 24px; margin-top: 225px;' class='t-center'>
<p><i class="fa-solid fa-rotate fa-spin"></i> Chargement en cours ...</p>
</div>
</div>
</div>
`)
const rootInput = getID(View.getViewTitle() + '_rootInput')
const explorer = getID(View.getViewTitle() + '_explorer')
const newFolder = getID(View.getViewTitle() + '_newFolder')
const newFile = getID(View.getViewTitle() + '_newFile')
const home = getID(View.getViewTitle() + '_home')
const sharebtn = getID(View.getViewTitle() + '_sharebtn')
View.ViewWindowDiv.addEventListener("contextmenu", () => {
if(inCopyOrCut != null) {
const dMenu = new DroppableMenu()
dMenu.add("paste", "<i class='fa fa-paste'></i> Coller")
dMenu.show()
dMenu.get("paste").addEventListener("click", () => {
console.log({newPath: rootInput.value, action: inCopyOrCut.action, file: inCopyOrCut.file, name: inCopyOrCut.file.name, orginalPath: inCopyOrCut.orginalPath})
dMenu.hide()
const reqFiles = post("FX_PASTE", {newPath: rootInput.value, action: inCopyOrCut.action, file: inCopyOrCut.file, name: inCopyOrCut.file.name, orginalPath: inCopyOrCut.orginalPath})
reqFiles.then((result) => {
if(result == "OK") {
const reqFiles = post("FX_GET", rootInput.value)
reqFiles.then((result) => {
loadFiles(result)
})
} else if(result == "NOT_PERMITTED") {
const reqFiles = post("FX_GET", rootInput.value)
reqFiles.then((result) => {
loadFiles(result)
})
View.createPopup({
title: `<i class='fa fa-warning'></i> Erreur`,
content: `<p class='yellow'>Vous n'avez pas les permissions pour coller ce fichier.</p>`
})
} else {
const reqFiles = post("FX_GET", rootInput.value)
reqFiles.then((result) => {
loadFiles(result)
})
View.createPopup({
title: `<i class='fa fa-warning'></i> Erreur`,
content: `<p class='yellow'>Une erreur est survenue.</p>`
})
}
})
inCopyOrCut = null
})
} else {
console.log("LISTENER : " + rootInput.value)
}
})
home.addEventListener("click", () => {
goHomePath()
})
sharebtn.addEventListener("click", () => {
goSharePath()
})
newFolder.addEventListener("click", () => {
View.createPopup({
title: `<i class='fa fa-folder'></i> Nouveau dossier`,
content: `
<input type='text' class='field' id='${View.getViewTitle()}_foldername'>
<div id='${View.getViewTitle()}_folderInfo'></div>
<button class='btn green' id='${View.getViewTitle()}_foldercreate'><span><i class='fa fa-add'></i> Créer</span></button>
`})
const foldername = getID(View.getViewTitle() + "_foldername")
const foldercreate = getID(View.getViewTitle() + "_foldercreate")
const folderInfo = new TextResponse(View.getViewTitle() + "_folderInfo")
folderInfo.setSize("13px")
foldercreate.addEventListener("click", () => {
folderInfo.clear()
if(foldername.value.length < 1) {
folderInfo.err("Le nom du dossier est trop court.")
return
}
const regex = new RegExp(/^[a-zA-Z0-9-_]+$/)
if(!regex.test(foldername.value) | foldername.value.replace(/\s/g, '').length < 1) {
folderInfo.err("Le nom du dossier est invalide.")
return
}
const reqFiles = post("FX_NEW_FOLDER", rootInput.value + "/" + foldername.value)
reqFiles.then((result) => {
if(result == "OK") {
View.destroyPopup(`<i class="fa fa-folder"></i> Nouveau dossier`)
const reqFiles = post("FX_GET", rootInput.value)
reqFiles.then((result) => {
loadFiles(result)
})
} else if(result == "EXIST") {
folderInfo.err("Le dossier existe déjà.")
} else if(result == "NOT_PERMITTED") {
folderInfo.err("Vous n'avez pas les permissions pour créer un dossier ici.")
} else {
folderInfo.err("Une erreur est survenue.")
}
})
})
})
// Create a new file with a popup wth 2 options, upload or create, if create give a input name or if upload, upload a file
newFile.addEventListener("click", () => {
View.createPopup({
title: `<i class='fa-solid fa-file-arrow-up'></i> Nouveau fichier`,
content: `
<input type='text' class='field' id='${View.getViewTitle()}_filename'>
<div id='${View.getViewTitle()}_fileInfo'></div>
<button class='btn green' id='${View.getViewTitle()}_filecreate'><span><i class='fa fa-add'></i> Créer</span></button>
<button class='btn blue' id='${View.getViewTitle()}_fileupload'><span><i class='fa fa-upload'></i> Upload</span></button>
`})
const filename = getID(View.getViewTitle() + "_filename")
const filecreate = getID(View.getViewTitle() + "_filecreate")
const fileupload = getID(View.getViewTitle() + "_fileupload")
const fileInfo = new TextResponse(View.getViewTitle() + "_fileInfo")
fileInfo.setSize("13px")
filecreate.addEventListener("click", () => {
fileInfo.clear()
if(filename.value.length < 1) {
fileInfo.err("Le nom du fichier est trop court.")
return
}
const regex = new RegExp(/^[a-zA-Z0-9-_.]+$/)
if(!regex.test(filename.value) | filename.value.replace(/\s/g, '').length < 1) {
fileInfo.err("Le nom du fichier est invalide.")
return
}
const reqFiles = post("FX_NEW_FILE", rootInput.value + "/" + filename.value)
reqFiles.then((result) => {
if(result == "OK") {
View.destroyPopup(`<i class="fa-solid fa-file-arrow-up"></i> Nouveau fichier`)
const reqFiles = post("FX_GET", rootInput.value)
reqFiles.then((result) => {
loadFiles(result)
})
} else if(result == "EXIST") {
fileInfo.err("Le fichier existe déjà.")
} else if(result == "NOT_PERMITTED") {
fileInfo.err("Vous n'avez pas les permissions pour créer un fichier ici.")
} else {
fileInfo.err("Une erreur est survenue.")
}
})
})
fileupload.addEventListener("click", () => {
fileInfo.clear()
View.destroyPopup(`<i class="fa-solid fa-file-arrow-up"></i> Nouveau fichier`)
View.createPopup({
title: `<i class='fa-solid fa-file-arrow-up'></i> Upload`,
content: `
<input type='file' class='field' id='${View.getViewTitle()}_fileuploadInput'>
<div id='${View.getViewTitle()}_fileuploadInfo'></div>
<button class='btn green' id='${View.getViewTitle()}_fileuploadBtn'><span><i class='fa fa-upload'></i> Upload</span></button>
`})
const fileuploadInput = getID(View.getViewTitle() + "_fileuploadInput")
const fileuploadBtn = getID(View.getViewTitle() + "_fileuploadBtn")
const fileuploadInfo = new TextResponse(View.getViewTitle() + "_fileuploadInfo")
fileuploadBtn.addEventListener("click", () => {
fileuploadInfo.clear()
if(fileuploadInput.files.length < 1) {
fileuploadInfo.err("Aucun fichier sélectionné.")
return
}
const file = fileuploadInput.files[0]
console.log(file)
const reqFiles = post("FX_UPLOAD", {name: file.name ,root: rootInput.value, file: file})
reqFiles.then((result) => {
if(result == "OK") {
View.destroyPopup(`<i class="fa-solid fa-file-arrow-up"></i> Upload`)
const reqFiles = post("FX_GET", rootInput.value)
reqFiles.then((result) => {
loadFiles(result)
})
}
if(result == "EXIST") {
fileuploadInfo.err("Le fichier existe déjà.")
}
if(result == "NOT_PERMITTED") {
fileuploadInfo.err("Vous n'avez pas les permissions pour uploader un fichier ici.")
}
if(result == "NOT_FILE") {
fileuploadInfo.err("Le fichier n'est pas valide.")
}
if(result == "NOT_EXIST") {
fileuploadInfo.err("Le fichier n'existe pas.")
}
if(result == "TOO_BIG") {
fileuploadInfo.err("Le fichier est trop volumineux.")
}
if(result == "ERROR") {
fileuploadInfo.err("Une erreur est survenue.")
}
})
})
})
})
rootInput.addEventListener("change", () => {
const reqFiles = post("FX_GET", rootInput.value)
reqFiles.then((result) => {
loadFiles(result)
})
})
function loadFiles(files) {
rootInput.value = files.root
var fileElements = new Array()
if(files.content == "NOT_PERMITTED") {
fileElements.unshift(`<div id='fx-parent' class='fx-element'><p><i class="fa-solid fa-rotate-left"></i> Revenir au dossier parent </p></div>`)
fileElements.push("<p class='yellow' style='text-align: center;'><i class='fa fa-warning'></i> Vous n'avez pas les permissions pour accéder à ce dossier.</p>")
} else if(files.content == "NOT_EXIST") {
fileElements.unshift(`<div id='fx-parent' class='fx-element'><p><i class="fa-solid fa-rotate-left"></i> Revenir au dossier parent </p></div>`)
explorer.innerHTML = "<p class='yellow' style='text-align: center;'><i class='fa fa-warning'></i> Ce dossier n'existe pas.</p>"
} else {
for(const file of files.content) {
if(file.directory) {
file.size = "Dossier"
} else {
console.log('------------')
console.log(file.size)
console.log(bytesToSize(file.size))
console.log('------------')
file.size = bytesToSize(file.size)
}
fileElements.push(`<div id='${file.id}' class='fx-element'>
<div>
${getIcon(file)}
<p>${file.name}</p>
</div>
<p>Taille : ${file.size}</p>
<p>Date de modification : ${getFormattedDate(file.lastedition)}</p>
</div>`)
}
// Sort the files by directory and then by name
fileElements.sort((a, b) => {
if(a.includes("Dossier") && !b.includes("Dossier")) {
return -1
} else if(!a.includes("Dossier") && b.includes("Dossier")) {
return 1
} else {
return 0
}
})
fileElements.unshift(`<div id='fx-parent' class='fx-element'><p><i class="fa-solid fa-rotate-left"></i> Revenir au dossier parent </p></div>`)
}
explorer.innerHTML = fileElements.join("")
const parent = document.getElementById("fx-parent")
parent.addEventListener("click", () => {
const reqFiles = post("FX_GET", files.parent)
reqFiles.then((result) => {
loadFiles(result)
})
})
if(files.content != "NOT_PERMITTED" && files.content != "NOT_EXIST") {
// If it's a directory, get the file directory and make the request to get the files in it and loadIt
for(const file of files.content) {
const element = document.getElementById(file.id)
if(file.directory) {
element.addEventListener("click", () => {
const reqFiles = post("FX_GET", file.fileDirectory)
reqFiles.then((result) => {
loadFiles(result)
})
})
} else {
element.addEventListener("dblclick", () => {
editFile()
})
}
getID(file.id).addEventListener("contextmenu", () => {
const dropMenu = new DroppableMenu()
if(!file.directory) {
dropMenu.add("edit", "<i class='fa-solid fa-pen'></i> Editer")
dropMenu.add("share", "<i class='fa fa-share'></i> Partager")
dropMenu.add("download", "<i class='fa fa-download'></i> Télécharger")
}
dropMenu.add("copy", "<i class='fa fa-copy'></i> Copier")
dropMenu.add("cut", "<i class='fa fa-cut'></i> Couper")
dropMenu.add("rename", "<i class='fa-solid fa-file-signature'></i> Renommer")
dropMenu.add("delete", "<i class='fa fa-trash'></i> Supprimer")
dropMenu.show()
dropMenu.get("copy").addEventListener("click", () => {
dropMenu.hide()
inCopyOrCut = {"action": "copy", "file": file, "orginalPath": files.root}
})
dropMenu.get("cut").addEventListener("click", () => {
dropMenu.hide()
inCopyOrCut = {"action": "cut", "file": file, "orginalPath": files.root}
})
dropMenu.get("delete").addEventListener("click", () => {
dropMenu.hide()
const reqFiles = post("FX_DELETE", file.fileDirectory)
reqFiles.then((result) => {
if(result == "OK") {
const reqFiles = post("FX_GET", files.root)
reqFiles.then((result) => {
loadFiles(result)
})
} else if(result == "NOT_PERMITTED") {
const reqFiles = post("FX_GET", files.root)
reqFiles.then((result) => {
loadFiles(result)
})
View.createPopup({
title: `<i class='fa fa-warning'></i> Erreur`,
content: `<p class='yellow'>Vous n'avez pas les permissions pour supprimer ce fichier.</p>`
})
} else {
const reqFiles = post("FX_GET", files.root)
reqFiles.then((result) => {
loadFiles(result)
})
View.createPopup({
title: `<i class='fa fa-warning'></i> Erreur`,
content: `<p class='yellow'>Une erreur est survenue.</p>`
})
}
})
})
dropMenu.get("rename").addEventListener("click", () => {
dropMenu.hide()
View.createPopup({
title: `<i class='fa fa-file-signature'></i> Renommer`,
content: `
<input type='text' class='field' id='${View.getViewTitle()}_rename'>
<div id='${View.getViewTitle()}_renameInfo'></div>
<button class='btn green' id='${View.getViewTitle()}_renameBtn'><span><i class='fa fa-pen'></i> Renommer</span></button>
`})
const rename = getID(View.getViewTitle() + "_rename")
const renameBtn = getID(View.getViewTitle() + "_renameBtn")
const renameInfo = new TextResponse(View.getViewTitle() + "_renameInfo")
renameInfo.setSize("13px")
rename.value = file.name
rename.focus()
rename.select()
renameBtn.addEventListener("click", () => {
renameInfo.clear()
if(rename.value.length < 1) {
renameInfo.err("Le nom du fichier / dossier est trop court.")
return
}
const regex = new RegExp(/^[a-zA-Z0-9-_.]+$/)
if(!regex.test(rename.value) | rename.value.replace(/\s/g, '').length < 1) {
renameInfo.err("Le nom du fichier / dossier est invalide.")
return
}
const reqFiles = post("FX_RENAME", {root: files.root, oldName: file.name, newName: rename.value})
reqFiles.then((result) => {
if(result == "OK") {
View.destroyPopup(`<i class="fa fa-file-signature"></i> Renommer`)
const reqFiles = post("FX_GET", files.root)
reqFiles.then((result) => {
loadFiles(result)
})
} else if(result == "EXIST") {
renameInfo.err("Le fichier / dossier existe déjà.")
} else if(result == "NOT_PERMITTED") {
renameInfo.err("Vous n'avez pas les permissions pour renommer ce fichier / dossier.")
} else {
renameInfo.err("Une erreur est survenue.")
}
})
})
})
if(!file.directory) {
dropMenu.get("share").addEventListener("click", () => {
dropMenu.hide()
const reqFiles = post("FX_SHARE", {root: files.root, name: file.name})
reqFiles.then((result) => {
if(result == "NOT_PERMITTED") {
View.createPopup({
title: `<i class='fa fa-warning'></i> Erreur`,
content: `<p class='yellow'>Vous n'avez pas les permissions pour partager ce fichier.</p>`
})
} else {
View.createPopup({
title: `<i class='fa fa-share'></i> Partager`,
content: `
<input style='width: 300px' type='text' class='field' id='${View.getViewTitle()}_sharelink'>
<div id='${View.getViewTitle()}_shareInfo'></div>
<button class='btn green' id='${View.getViewTitle()}_shareBtn'><span><i class='fa fa-share'></i> Copier</span></button>
`})
const sharelink = getID(View.getViewTitle() + "_sharelink")
const shareBtn = getID(View.getViewTitle() + "_shareBtn")
const shareInfo = new TextResponse(View.getViewTitle() + "_shareInfo")
shareInfo.setSize("13px")
sharelink.value = result
sharelink.focus()
sharelink.select()
shareBtn.addEventListener("click", () => {
sharelink.focus()
sharelink.select()
window.navigator.clipboard.writeText(sharelink.value)
shareInfo.ok("Copié !")
})
}
})
})
// Edit file with an ViewWindow with 2 options close & save and the name of the window is like File - Editor
dropMenu.get("edit").addEventListener("click", () => {
dropMenu.hide()
editFile()
})
dropMenu.get("download").addEventListener("click", () => {
dropMenu.hide()
const reqFiles = post("FX_GETFILE", file.fileDirectory)
reqFiles.then((result) => {
if(result == "NOT_PERMITTED") {
View.createPopup({
title: `<i class='fa fa-warning'></i> Erreur`,
content: `<p class='yellow'>Vous n'avez pas les permissions pour télécharger ce fichier.</p>`
})
} else {
// Make Download using result
const element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(result));
element.setAttribute('download', file.name);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
})
})
}
})
function editFile() {
const reqFiles = post("FX_GETFILE", file.fileDirectory)
//Create a popup for the loading
View.createPopup({
title: `<i class='fa-solid fa-file-pen'></i> Editeur`,
content: `<p><i class='fa-solid fa-rotate fa-spin'></i> Chargement en cours ...</p>`
})
reqFiles.then((result) => {
View.destroyPopup(`<i class='fa-solid fa-file-pen'></i> Editeur}`)
if(result == "NOT_PERMITTED") {
View.createPopup({
title: `<i class='fa fa-warning'></i> Erreur`,
content: `<p class='yellow'>Vous n'avez pas les permissions pour éditer ce fichier.</p>`
})
} else {
const editor = new ViewWindow({
title: `<i class="fa-solid fa-file-pen"></i> Editeur - ${file.fileDirectory}`,
width: "1000px",
height: "650px"
})
if(file.type == "image/png" | file.type == "image/jpeg") {
editor.setContent(`
<div style='width: 100%; text-align: center;'>
<img style='width: 500px;' src='${result}'/>
</div>`)
} else {
editor.setContent(`
<div class='fx-bar'>
<span id='${editor.getViewTitle()}_save' class='btn-cover'><i class='fa fa-save'></i></span>
</div>
<textarea id='${editor.getViewTitle()}_editorContent' class='fx-editor-content'>${result}</textarea>
`)
const editorSave = getID(editor.getViewTitle() + "_save")
const editorContent = getID(editor.getViewTitle() + "_editorContent")
// Sauvegarder le fichier en l'envoyant
editorSave.addEventListener("click", () => {
const reqFiles = post("FX_SAVEFILE", {root: files.root, name: file.name, content: editorContent.value})
reqFiles.then((result) => {
if(result == "OK") {
editor.destroy()
const reqFiles = post("FX_GET", files.root)
reqFiles.then((result) => {
loadFiles(result)
})
} else if(result == "NOT_PERMITTED") {
editor.createPopup({
title: `<i class='fa fa-warning'></i> Erreur`,
content: `<p class='yellow'>Vous n'avez pas les permissions pour éditer ce fichier.</p>`
})
} else {
editor.createPopup({
title: `<i class='fa fa-warning'></i> Erreur`,
content: `<p class='yellow'>Une erreur est survenue.</p>`
})
}
})
})
//forbid textarea resize
editorContent.style.resize = "none"
}
}
})
}
}
}
}
})
function getIcon(file) {
if(file.type == "application/json") {
return '<i style="color:rgb(179, 141, 4);" class="fa-sharp fa-code"></i>'
}
if(file.type == "application/msword" | file.type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document") {
return '<i style="color:rgb(47, 94, 247);" class="fa-solid fa-file-word"></i>'
}
if(file.type == "application/vnd.ms-powerpoint") {
return '<i style="color:rgb(255, 112, 51);" class="fa-solid fa-file-powerpoint"></i>'
}
if(file.type == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | file.type == "application/vnd.ms-excel") {
return '<i style="color:rgb(51, 255, 61);" class="fa-solid fa-file-excel"></i>'
}
if(file.type == "application/java-archive") {
return '<i style="color:rgb(255, 202, 150);" class="fa-brands fa-java"></i>'
}
if(file.type == "application/x-sh") {
return '<i style="color:rgb(171, 226, 255);" class="fa-solid fa-file-code"></i>'
}
if(file.type == "application/x-msdos-program" | file.type == "application/x-msdownload") {
return'<i style="color:rgb(53, 191, 255);" class="fa-brands fa-windows"></i>'
}
if(file.type == "application/javascript") {
return '<i style="color:rgb(179, 141, 4);" class="fa-brands fa-js"></i>'
}
if(file.type == "image/png" | file.type == "image/jpeg") {
return '<i style="color:rgb(189, 104, 189);" class="fa-solid fa-file-image"></i>'
}
if(file.type == "text/html") {
return '<i style="color:tomato;" class="fa-brands fa-html5"></i>'
}
if(file.type == "text/css") {
return '<i style="color:rgb(66, 135, 245);" class="fa-brands fa-css3-alt"></i>'
}
if(file.type == "application/zip") {
return '<i style="color:rgb(255, 139, 38);" class="fa-solid fa-file-zipper"></i>'
}
if(file.type == "audio/mpeg") {
return '<i style="color:rgb(38, 222, 255);" class="fa-solid fa-file-audio"></i>'
}
if(file.type == "application/pdf") {
return '<i style="color:rgb(255, 71, 51);" class="fa-solid fa-file-pdf"></i>'
}
if(file.directory) {
return '<i style="color:yellow;" class="fa fa-folder"></i>'
} else {
return '<i class="fa fa-file"></i>'
}
}
function bytesToSize(bytes) {
var sizes = ['o', 'Ko', 'Mo', 'Go', 'To'];
if (bytes == 0) return '0 o';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
}
-68
View File
@@ -1,68 +0,0 @@
// User Request
loadUserInfo()
function loadUserInfo() {
const infoUsername = getID("infoUsername")
const infoUserimage = getID("infoUserimage")
const infoDisplayname = getID("infoDisplayname")
const views = getID("views")
const panelBox = getID("panel-box")
const REQ_user = get("USERINFO")
REQ_user.then((ANS_user) => {
console.log(ANS_user)
infoUserimage.src = ANS_user.picture
infoUsername.innerHTML = ANS_user.username
infoDisplayname.innerHTML = ANS_user.display_name
const permissions = ANS_user.permission
const AvailableViews = new Array()
//
permissions.forEach((permValue) => {
AllComponents.forEach((component) => {
if(component.permission == permValue) {
component.inject(AvailableViews)
}
})
})
if(AvailableViews.join("") == "") {
AvailableViews.push("<p style='width: 100%;' class='yellow t-center'><i class='fa-solid fa-warning'></i> Aucune permission ne semble vous êtes accordée<br>Demandez à Raphix afin de résoudre ce problème</p>")
views.classList.remove("views-box")
panelBox.style.justifyContent = "unset"
console.log(panelBox.style)
} else {
views.classList.add("views-box")
}
views.innerHTML = AvailableViews.join("")
// BindView
AllComponents.forEach((component) => {
component.bindView()
})
})
}
-62
View File
@@ -1,62 +0,0 @@
// Socket IO - Communication
var socketLink = null
fetch('/internal/socketlink', {
method: "GET"
}).then(link => {socketLink = link})
const socket = io(socketLink);
socket.on("connect", () => {
console.log("Connecté au serveur par le Socket avec l'ID : " + socket.id)
});
socket.on("disconnect", (log) => {
window.location.href = "/"
})
function get(request) {
return new Promise((resolve, reject) => {
socket.emit("GET/" + request)
console.log("Envoi de la requête GET : " + request)
socket.once("ANSWER/GET/" + request, (answer) => {
console.log("Réponse pour la requête : " + request)
resolve(answer)
})
})
}
function post(request, value) {
return new Promise((resolve, reject) => {
socket.emit("POST/" + request, value)
console.log("Envoi de la requête POST : " + request)
socket.once("ANSWER/POST/" + request, (answer) => {
console.log("Réponse pour la requête : " + request)
resolve(answer)
})
})
}
function getSocket() {
return socket
}
-299
View File
@@ -1,299 +0,0 @@
links.createWindow(() => {
const View = new ViewWindow({
title: `<i class="fa-solid fa-link"></i> Générateur de liens`,
width: "600px",
height: "600px",
})
View.setContent(`
<div class='ln-bar'>
<button id='${View.getViewTitle()}_add' class='btn blue'><span><i class='fa fa-add'></i> Ajouter un lien</span></button>
</div>
<div class='ln-links' id='${View.getViewTitle()}_links'>
<div style='font-size: 24px; margin-top: 225px;' class='t-center'>
<p><i class="fa-solid fa-rotate fa-spin"></i> Chargement en cours ...</p>
</div>
</div>
`)
const addBtn = getID(`${View.getViewTitle()}_add`)
const linksDiv = getID(`${View.getViewTitle()}_links`)
var links = new Array()
addBtn.addEventListener("click", () => {
View.createPopup({
title: `<i class='fa fa-add'></i> Ajouter un lien`,
content: `
<div class='ln-create'>
<input id='${View.getViewTitle()}_title' class='field' type='text' placeholder='Titre du lien'>
<input id='${View.getViewTitle()}_url' class='field' type='text' placeholder='URL du lien'>
<div class='ln-abstract-div'>
<p class='ln-abstract-label'>Abstraire le lien :</p>
<input id='${View.getViewTitle()}_ablink' type='checkbox'>
</div>
<span id='${View.getViewTitle()}_newlink_span'></span>
<p id='${View.getViewTitle()}_info'></p>
<button id='${View.getViewTitle()}_confirm' class='btn blue'><span><i class='fa fa-add'></i> Ajouter</span></button>
</div>
`
})
const titleInput = getID(`${View.getViewTitle()}_title`)
const urlInput = getID(`${View.getViewTitle()}_url`)
const addBtn = getID(`${View.getViewTitle()}_confirm`)
const info = new TextResponse(`${View.getViewTitle()}_info`)
const ablink = getID(`${View.getViewTitle()}_ablink`)
const newlinkSpan = getID(`${View.getViewTitle()}_newlink_span`)
ablink.checked = true
ablink.addEventListener("click", () => {
if(!ablink.checked) {
newlinkSpan.innerHTML = `
<input id='${View.getViewTitle()}_newlink' class='field' type='text' placeholder='URL du nouveau lien'>
`
} else {
newlinkSpan.innerHTML = ""
}
})
addBtn.addEventListener("click", () => {
info.clear()
console.log(ablink.checked)
if(!titleInput.value) {
info.err("Un titre est nécéssaire")
} else if(!urlInput.value) {
info.err("Une URL est nécéssaire")
} else {
var newlink = getID(`${View.getViewTitle()}_newlink`)
if(!newlink) {
newlink = { value: "" }
} else {
if(!newlink.value) {
info.err("Un nouveau lien est nécéssaire")
return false
}
if(!newlink.value.match(/^[a-zA-Z0-9-_]+$/)) {
info.err("L'URL n'est pas valide")
return false
}
}
const request = post(`LINKS_ADD`, {
title: titleInput.value,
url: urlInput.value,
abstractLink: ablink.checked,
dest: newlink.value
})
request.then((answer) => {
if(answer.answer == "OK") {
info.info("Le lien a bien été ajouté")
View.destroyPopup()
getLinks()
} else if(answer.answer == "ALREADY_EXISTS") {
info.err("Ce lien existe déjà")
} else {
info.err("Impossible d'ajouter le lien")
}
})
}
})
})
getLinks()
function getLinks() {
linksDiv.innerHTML = ""
links = new Array()
const request = post(`LINKS_GET_ALL`)
request.then((answer) => {
if(answer.answer == "OK") {
if(answer.links.length == 0) {
linksDiv.innerHTML = `<p class='lightred' style='text-align: center;'>Aucun lien disponible</p>`
}
answer.links.forEach((link) => {
links.push(link)
})
links.forEach((link) => {
linksDiv.innerHTML += `
<div class='ln-link'>
<p class='ln-link-title'>${link.title}</p>
<div>
<p class='ln-link-url'><i class="fa-solid fa-bookmark"></i> Lien original : <a href='${link.url}'>${link.url}</a></p>
<p class='ln-link-url'><i class="fa-solid fa-paperclip"></i> Lien modifié : <a href='https://neutral.raphix.fr/link/${link.dest}'> https://neutral.raphix.fr/link/${link.dest}</a></p>
</div>
<div class='ln-link-actions'>
<button id='${link.id}_edit' class='btn blue'><span><i class='fa fa-edit'></i> Modifier</span></button>
<button id='${link.id}_remove' class='btn red'><span><i class='fa fa-trash'></i> Supprimer</span></button>
</div>
</div>
`
})
links.forEach((link) => {
const editBtn = getID(`${link.id}_edit`)
editBtn.addEventListener("click", () => {
View.createPopup({
title: `<i class='fa fa-edit'></i> Modifier un lien`,
content: `
<div class='ln-create'>
<input id='${View.getViewTitle()}_edittitle' class='field' type='text' placeholder='Titre du lien' value='${link.title}'>
<input id='${View.getViewTitle()}_editurl' class='field' type='text' placeholder='URL du lien' value='${link.url}'>
<p id='${View.getViewTitle()}_editinfo'></p>
<button id='${View.getViewTitle()}_editconfirm' class='btn blue'><span><i class='fa fa-edit'></i> Modifier</span></button>
</div>
`
})
const titleInput = getID(`${View.getViewTitle()}_edittitle`)
const urlInput = getID(`${View.getViewTitle()}_editurl`)
const editBtnConfirm = getID(`${View.getViewTitle()}_editconfirm`)
const info = new TextResponse(`${View.getViewTitle()}_editinfo`)
titleInput.value = link.title
urlInput.value = link.url
editBtnConfirm.addEventListener("click", () => {
if(!titleInput.value) {
info.err("Un titre est nécéssaire")
} else if(!urlInput.value) {
info.err("Une URL est nécéssaire")
} else {
const request = post(`LINKS_EDIT`, {
id: link.id,
title: titleInput.value,
url: urlInput.value
})
request.then((answer) => {
if(answer == "OK") {
info.info("Le lien a bien été modifié")
View.destroyPopup()
getLinks()
} else {
info.err("Impossible de modifier le lien")
}
})
}
})
})
const delBtn = getID(`${link.id}_remove`)
delBtn.addEventListener("click", () => {
const request = post(`LINKS_DELETE`, link.id)
request.then((answer) => {
if(answer != "OK") {
View.createPopup({
title: `<i class='fa fa-warning'></i> Erreur`,
content: `
<p>Impossible de supprimer le lien</p>
`
})
} else {
getLinks()
}
})
})
})
} else {
info.err("Impossible de récupérer les liens")
}
})
}
})
-67
View File
@@ -1,67 +0,0 @@
const username = getID("username")
const password = getID("password")
const submit = getID("submit")
const loginInfo = new TextResponse("login-info")
loginInfo.clear()
submit.addEventListener("click", () => {
if(!username.value) {
loginInfo.err("Un nom d'utilisateur est nécéssaire pour se connecter !")
} else if(!password.value) {
loginInfo.err("Un mot de passe est nécéssaire pour se connecter !")
} else {
login()
}
})
password.addEventListener("keyup", (event) => {
if (event.key === "Enter") {
login()
}
});
function login() {
loginInfo.clear()
fetch('/login', {
method: 'POST',
redirect: 'follow',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: username.value,
password: password.value
})
})
.then(response => redirect(response))
async function redirect(response) {
response = await response.text()
if(response == "AUTH_FAILED") {
loginInfo.err("Le nom d'utilisateur et le mot de passe sont incorrects.")
} else if(response == "AUTH_SUCCESS") {
window.location.href = "/"
}
}
}
-144
View File
@@ -1,144 +0,0 @@
metrics.createWindow(() => {
const View = new ViewWindow({
title: `<i class="fa-solid fa-square-poll-vertical"></i> Web Metrik`,
width: "600px",
height: "600px",
})
loadMetrics()
function loadMetrics() {
View.setContent(`
<div class="metrics">
<div class='mt-bar'>
<p> <strong>WebMetrik</strong> : <span id='${View.getViewTitle()}_number'><i>Calcul en cours</i></span></p>
<div>
<button id='${View.getViewTitle()}_refresh' class='btn green'><span><i class='fa fa-rotate-left'></i> Rafraîchir</span></button>
<button id='${View.getViewTitle()}_add' class='btn blue'><span><i class='fa fa-add'></i> Ajouter un WebMetrik</span></button>
</div>
</div>
<div class='mt-metrics' id='${View.getViewTitle()}_metrics'>
<div style='font-size: 24px; margin-top: 180px;' class='t-center'>
<p><i class="fa-solid fa-rotate fa-spin"></i> Chargement en cours ...</p>
</div>
</div>`)
const metricsList = new Array()
const metricsComponent = new Array()
const metricsReq = get("MT_ALL")
const metricsDiv = document.getElementById(`${View.getViewTitle()}_metrics`)
const metricsNumber = document.getElementById(`${View.getViewTitle()}_number`)
const addButton = document.getElementById(`${View.getViewTitle()}_add`)
const refreshButton = document.getElementById(`${View.getViewTitle()}_refresh`)
const metricsView = document.getElementById(`${View.getViewTitle()}_metrics`)
refreshButton.addEventListener("click", () => {
loadMetrics()
})
metricsReq.then((ANS_metrics) => {
console.log(ANS_metrics)
if(ANS_metrics != "UNAVAILABLE") {
metricsList.length = 0
if(ANS_metrics.length == 0) {
metricsList.push(`<div style='font-size: 24px; margin-top: 180px;' class='yellow t-center'>
<p><i class="fa-solid fa-warning"></i> Aucune WebMetrik n'a été ajoutée</p>
</div>`)
}
ANS_metrics.forEach((metric) => {
const metricComponent = new Metric({
properties: metric,
Component: metrics,
View: View
})
metricsList.push(metricComponent.generateHTML())
metricsComponent.push(metricComponent)
})
metricsDiv.innerHTML = metricsList.join("")
metricsNumber.innerHTML = ANS_metrics.length
for(const metric of metricsComponent) {
metric.loadScript()
}
} else {
metricsDiv.innerHTML = `<div style='font-size: 24px; margin-top: 180px;' class='t-center'>
<p><i class="fa-solid fa-warning"></i> Une erreur est survenue lors du chargement des WebMetrik</p>
</div>`
}
})
// Generate a pop to add metrics with 3 settings, the adress, the port, the name of the metrics and the key to authentificate
addButton.addEventListener("click", () => {
View.createPopup({
title: "Ajouter un WebMetrik",
content: `
<div class='mt-add'>
<p>Adresse</p>
<input class='field' type="text" id="mt-add-address" placeholder="Adresse">
<p>Port</p>
<input class='field' type="number" id="mt-add-port" placeholder="Port">
<p>Nom</p>
<input class='field' type="text" id="mt-add-name" placeholder="Nom">
<p>Clé d'authentification</p>
<input class='field' type="password" id="mt-add-key" placeholder="Clé d'authentification">
<span id='mtaddinfo'></span>
<button id='mt-add-btn' class='btn blue'><span><i class='fa fa-add'></i> Ajouter</span></button>
</div>
`
})
const addBtn = document.getElementById("mt-add-btn")
const address = document.getElementById("mt-add-address")
const port = document.getElementById("mt-add-port")
const name = document.getElementById("mt-add-name")
const key = document.getElementById("mt-add-key")
const infoMTAdd = new TextResponse("mtaddinfo")
addBtn.addEventListener("click", () => {
// Check if all fields are filled
if(address.value == "" || port.value == "" || name.value == "" || key.value == "") {
infoMTAdd.err("Veuillez remplir tous les champs")
return
}
post("MT_ADD", {
address: address.value,
port: port.value,
name: name.value,
key: key.value
}).then((res) => {
if(res != "ERROR") {
View.destroyPopup()
loadMetrics()
} else {
View.createPopup({
title: "Erreur",
content: `<p class='yellow'><i class='fa fa-warning'></i> Une erreur est survenue lors de l'ajout de la WebMetrik</p>`
})
}
})
})
})
}
})
/*
<div style='font-size: 24px; margin-top: 180px;' class='t-center'>
<p><i class="fa-solid fa-rotate fa-spin"></i> Chargement en cours ...</p>
</div>*/
-59
View File
@@ -1,59 +0,0 @@
// My View Component
const explorer = new ViewComponent({
name: "Explorateur de fichier",
icon: "fa-solid fa-folder",
permission: "FILES_EXPLORER"
})
const services = new ViewComponent({
name: "Gestion des services",
icon: "fa-solid fa-layer-group",
permission: "SERVICES"
})
const servers = new ViewComponent({
name: "Gestion des serveurs",
icon: "fa fa-server",
permission: "SERVERS"
})
const pipelines = new ViewComponent({
name: "Gestion des pipelines",
icon: "fa-solid fa-code-merge",
permission: "PIPELINES"
})
const metrics = new ViewComponent({
name: "Web Metrik",
icon: "fa-solid fa-square-poll-vertical",
permission: "METRICS"
})
const users = new ViewComponent({
name: "Gestion des utilisateurs",
icon: "fa-solid fa-users",
permission: "USERS"
})
const links = new ViewComponent({
name: "Générateur des liens",
icon: "fa-solid fa-link",
permission: "LINKS"
})
const settings = new ViewComponent({
name: "Paramètres",
icon: "fa-solid fa-cog",
permission: "SETTINGS"
})
-119
View File
@@ -1,119 +0,0 @@
const menulogo = getID("menu-logo")
const usersettingsBtn = getID("user-settings-button")
menu.style.display = "none"
menulogo.addEventListener("click", () => {
const menu = getID("menu")
if(menu.style.display == "block") {
menu.style.display = "none"
} else {
menu.style.display = "block"
}
})
usersettingsBtn.addEventListener("click", () => {
const View = new ViewWindow({
title: `<i class="fa fa-user"></i> Mon Compte`,
width: "600px",
height: "650px"
})
View.setContent(`
<div class="user-settings">
<p>Mes informations</p>
<div class="us-settings">
<img class='us-settings-image' id="us-settings-image" src="">
<div class="us-settings-info">
<p>Nom d'utilisateur</p>
<input class="field" type="text" id="us-settings-username" placeholder="Nom d'utilisateur">
<p>Nom d'affichage</p>
<input class="field" type="text" id="us-settings-displayname" placeholder="Nom d'affichage">
<p>Mot de passe</p>
<input class="field" type="password" id="us-settings-password" placeholder="Mot de passe">
<p>Photo de profil</p>
<input type="file" id="us-settings-picture" accept="image/png, image/jpeg">
</div>
<br>
<span id='us-settings-return-info'></span>
<button id="us-settings-save" class="btn green"><span> Sauvegarder</span></button>
</div>
<p>Mes permissions</p>
<div id="us-settings-permissions">
</div>
</div>
`)
const usSettingsImage = getID("us-settings-image")
const usSettingsUsername = getID("us-settings-username")
const usSettingsDisplayname = getID("us-settings-displayname")
const usSettingsPassword = getID("us-settings-password")
const usSettingsPermissions = getID("us-settings-permissions")
const usSettingsSave = getID("us-settings-save")
const usSettingsPicture = getID("us-settings-picture")
const returnInfo = new TextResponse("us-settings-return-info")
const REQ_user = get("USERINFO")
var actualUsername = ""
REQ_user.then((ANS_user) => {
usSettingsImage.src = ANS_user.picture
usSettingsUsername.value = ANS_user.username
usSettingsDisplayname.value = ANS_user.display_name
actualUsername = ANS_user.username
const permissions = ANS_user.permission
const permValid = new Array()
permissions.forEach((permValue) => {
permValid.push("<p>" + permValue + "</p>")
})
usSettingsPermissions.innerHTML = permValid.join("")
})
usSettingsSave.addEventListener("click", () => {
const request = post(`US_EDIT_PERSONNAL`, {username: actualUsername, newusername: usSettingsUsername.value, display_name: usSettingsDisplayname.value, password: usSettingsPassword.value, picture: usSettingsPicture.files[0]})
request.then((answer) => {
if(answer == "ALREADY_EXIST") {
returnInfo.err("L'utilisateur existe déjà !")
} else if(answer == "USERNAME_MISSING") {
returnInfo.err("Le nom d'utilisateur est manquant !")
} else if(answer == "DISPLAY_NAME_MISSING") {
returnInfo.err("Le nom d'affichage est manquant !")
} else if(answer == "PASSWORD_MISSING") {
returnInfo.err("Le mot de passe est manquant !")
} else {
View.destroy()
loadUserInfo()
}
})
})
})
document.addEventListener("click", (e) => {
if(e.target != menulogo) {
menu.style.display = "none"
}
})
-66
View File
@@ -1,66 +0,0 @@
pipelines.createWindow(() => {
const View = new ViewWindow({
title: `<i class="fa fa-code-merge"></i> Gestion des pipelines`,
width: "900px",
height: "600px"
})
const pipelinesList = new Array()
View.setContent(`<div style='font-size: 24px; margin-top: 225px;' class='t-center'>
<p><i class="fa-solid fa-rotate fa-spin"></i> Chargement en cours ...</p>
</div>`)
var AllPipelines = new Array()
function getPipelines() {
const pipes = get("PL_GET_ALL")
pipes.then((ANS_pipes) => {
AllPipelines.length = 0
pipelinesList.length = 0
if(ANS_pipes != "UNAVAILABLE") {
ANS_pipes.jobs.forEach((pipe) => {
console.log(pipe)
const pipeline = new Pipeline({
pipeline: pipe,
View: View
})
pipelinesList.push(pipeline.generateHTML())
AllPipelines.push(pipeline)
})
View.setContent(`
<div class="pipelines">
<button id='reload_Btn_pipeline' class='btn blue'><span><i class='fa fa-rotate-left'></i> Recharger les pipelines</span></button>
${pipelinesList.join("")}
</div>`)
for(const pipeline of AllPipelines) {
pipeline.loadScript()
}
getID("reload_Btn_pipeline").addEventListener("click", () => {
View.setContent(`<div style='font-size: 24px; margin-top: 225px;' class='t-center'>
<p><i class="fa-solid fa-rotate fa-spin"></i> Chargement en cours ...</p>
</div>`)
getPipelines()
})
} else {
View.setContent(`<div style='font-size: 24px; margin-top: 225px;' class='t-center lightred'>
<p><i class="fa-solid fa-warning"></i> Une erreur est survenue lors du chargement des pipelines</p>
</div>`)
}
})
}
getPipelines()
})
-73
View File
@@ -1,73 +0,0 @@
servers.createWindow(async () => {
const View = new ViewWindow({
title: `<i class="fa fa-server"></i> Gestion des serveurs`,
width: "1000px",
height: "450px"
})
const serversList = new Array()
const alpha = new Server({
name: "Alpha",
description: "Serveur principal",
icon: "fa-solid fa-hourglass-start",
})
const omega = new Server({
name: "Omega",
description: "Serveur secondaire",
icon: "fa-solid fa-stop",
})
serversList.push(alpha.generateHTML())
serversList.push(omega.generateHTML())
View.setContent(`
<div class="servers">
${serversList.join("")}
</div>`)
await alpha.loadScript()
await omega.loadScript()
})
/**
<div class="servers-box">
<div class="servers-box-title">
<div class='servers-box-title-info'>
<i class="fa fa-server"></i>
<p>Alpha</p>
</div>
<button class="btn yellow"><span>Redémarrer</span></button>
</div>
<div class="servers-box-content">
<div class='servers-metrics'>
<div class='servers-metrics-box'>
<div>
<i class='fa-solid fa-memory'></i>
<p>RAM</p>
</div>
<p>1.5 Go / 2 Go</p>
</div>
<div class='servers-metrics-box'>
<div>
<i class='fa-solid fa-microchip'></i>
<p>CPU</p>
</div>
<p>1.5 Go / 2 Go</p>
</div>
<div class='servers-metrics-box'>
<div>
<i class='fa-solid fa-hdd'></i>
<p>DISK</p>
</div>
<p>1.5 Go / 2 Go</p>
</div>
</div>
</div>
</div>
*/
-88
View File
@@ -1,88 +0,0 @@
services.createWindow(async () => {
/**
* CODE OF SERVICE.JS
*/
const allServices = new Array()
const View = new ViewWindow({
title: '<i class="fa fa-layer-group"></i> Gestion des services',
width: "700px",
height: "600px"
})
const subsonicsService = new Service({
name: "Subsonics",
description: "Bot de streaming musical sur Discord",
icon: "/images/services/subsonics.png",
url: "https://subsonics.raphix.fr" ,
canAccess: true,
View: View
})
const giteaService = new Service({
name: "Gitea",
description: "Gestionnaire de dépôt Git",
icon: "/images/services/gitea.svg",
url: "https://git.raphix.fr" ,
canAccess: true,
View: View
})
const jenkinsService = new Service({
name: "Jenkins",
description: "Gestionnaire de pipeline",
icon: "/images/services/jenkins.svg",
url: "https://jenkins.raphix.fr" ,
canAccess: true,
View: View
})
const raphixwebsite = new Service({
name: "Raphix.fr",
description: "Site web de Raphix",
icon: "/images/services/raphix.png",
url: "https://raphix.fr",
canAccess: true,
View: View
})
const cvraphix = new Service({
name: "CV Raphix",
description: "Curriculum Vitae de Raphix",
icon: "/images/services/cv.png",
url: "https://cv.raphix.fr",
canAccess: true,
View: View
})
const lavalink = new Service({
name: "Lavalink",
description: "Serveur Lavalink pour Subsonics",
icon: "/images/services/lavalink.svg",
url: "http://omega.raphix.fr:2333",
canAccess: false,
View: View
})
allServices.push(subsonicsService.generateHTML())
allServices.push(lavalink.generateHTML())
allServices.push(giteaService.generateHTML())
allServices.push(jenkinsService.generateHTML())
allServices.push(raphixwebsite.generateHTML())
allServices.push(cvraphix.generateHTML())
View.setContent(`<div class='sv-list'>${allServices.join("")}</div>`)
await subsonicsService.loadScript()
await giteaService.loadScript()
await jenkinsService.loadScript()
await raphixwebsite.loadScript()
await cvraphix.loadScript()
await lavalink.loadScript()
})
-123
View File
@@ -1,123 +0,0 @@
settings.createWindow(async () => {
const View = new ViewWindow({
title: `<i class="fa fa-cog"></i> Paramètres`,
width: "500px",
height: "620px"
})
View.setContent(`
<div style='overflow-y: auto; height: 550px;'>
<div class="category">
<p>Options d'alimentation</p>
<div class='st-act'>
<button id="st-restart" class="btn yellow"><span>Redémarrer</span></button>
<button id="st-stop" class="btn red"><span> Arrêter</span></button>
</div>
</div>
<div class="category">
<p>Configuration des Tokens</p>
<p class='user-line-displayname'>Jenkins</p>
<input class='field' type="text" id="jenkins_token" placeholder="Token Jenkins">
<p class='user-line-displayname'> Omega </p>
<input class='field' type="text" id="omega_token" placeholder="Token Omega">
<button id="st-save" class="btn green"><span> Sauvegarder</span></button>
</div>
<div class="category">
<p>Accès aux logs</p>
<select id="all-logs" class="field">
<option>Chargment en cours ...</option>
</select>
<button id="read-logs" class="btn green"><span>Lire</span></button>
</div>
</div>
`)
const allLogs = document.getElementById("all-logs")
const readLogs = document.getElementById("read-logs")
get("SERVER_GET_LOGS").then((logs) => {
logs.reverse()
allLogs.innerHTML = logs.map((log) => {
return `<option value="${log}">${log}</option>`
}).join("")
})
readLogs.addEventListener("click", () => {
const log = allLogs.value
post("SERVER_READ_LOG", log).then((logContent) => {
const logView = new ViewWindow({
title: `<i class="fa fa-file"></i> ${log}`,
width: "1000px",
height: "520px"
})
logContent = logContent.replaceAll("[INFO]", "<span class='blue'>[INFO]</span>")
logContent = logContent.replaceAll("[WARN]", "<span class='yellow'>[WARN]</span>")
logContent = logContent.replaceAll("[ERROR]", "<span class='lightred'>[ERROR]</span>")
logContent = logContent.replaceAll("[STEP]", "<span class='green'>[STEP]</span>")
logContent = logContent.replaceAll("[Users]", "<span style='color:#c7b8ff; '>[Users]</span>")
logContent = logContent.replaceAll("[Web]", "<span style='color:#fffd8a; '>[Web]</span>")
logContent = logContent.replaceAll("[Serveur]", "<span style='color:#ff7a5c; '>[Serveur]</span>")
logContent = logContent.replaceAll("[Authentification]", "<span style='color:#d9e6ff; '>[Authentification]</span>")
// Get every line of logs and add a set the style in blue when it's the date in []
const logLines = logContent.split("\n")
const newLogLines = new Array()
logLines.forEach((line) => {
if(line.startsWith("[") && line.includes("]")) {
const date = line.split("]")[0] + "]"
const content = line.replace(date, "")
newLogLines.push(`<span style='color: #a6c2f7;'>${date}</span>${content}\n`)
} else {
newLogLines.push(`${line}\n`)
}
})
logView.setContent(`
<div style='overflow-y: auto; height: 450px;'>
<pre style='font-size: 12px'>${newLogLines.join("")}</pre>
</div>
`)
})
})
const restartButton = document.getElementById("st-restart")
const stopButton = document.getElementById("st-stop")
const saveButton = document.getElementById("st-save")
const jenkinsToken = document.getElementById("jenkins_token")
const omegaToken = document.getElementById("omega_token")
get("SETTINGS_GET").then((settings) => {
jenkinsToken.value = settings.jenkins_token
omegaToken.value = settings.omega_token
})
restartButton.addEventListener("click", () => {
post("SERVER_RESTART")
})
stopButton.addEventListener("click", () => {
post("SERVER_STOP")
})
saveButton.addEventListener("click", () => {
post("SETTINGS_SAVE", {
jenkins_token: jenkinsToken.value,
omega_token: omegaToken.value
})
get("SETTINGS_GET").then((settings) => {
jenkinsToken.value = settings.jenkins_token
omegaToken.value = settings.omega_token
})
})
})
-183
View File
@@ -1,183 +0,0 @@
users.createWindow(async () => {
const usersComponent = users
const View = new ViewWindow({
title: `<i class="fa fa-users"></i> Gestion des utilisateurs`,
width: "500px",
height: "700px"
})
loadUsers()
function loadUsers() {
View.setContent(`
<div class="users">
<div class='us-bar'>
<p> <strong>Utilisateurs</strong> : <span id='${View.getViewTitle()}_number'><i>Calcul en cours</i></span></p>
<button id='${View.getViewTitle()}_add' class='btn blue'><span><i class='fa fa-add'></i> Ajouter un utilisateur</span></button>
</div>
<div class='us-users' id='${View.getViewTitle()}_users'>
<div style='font-size: 24px; margin-top: 180px;' class='t-center'>
<p><i class="fa-solid fa-rotate fa-spin"></i> Chargement en cours ...</p>
</div>
</div>
</div>`)
const usersList = new Array()
const users = get("US_ALL")
const usersDiv = document.getElementById(`${View.getViewTitle()}_users`)
const usersNumber = document.getElementById(`${View.getViewTitle()}_number`)
const addButton = document.getElementById(`${View.getViewTitle()}_add`)
addButton.addEventListener("click", () => {
View.createPopup({
title: "Ajouter un utilisateur",
content: `
<div class='us-add'>
<p>Nom d'utilisateur</p>
<input class='field' type="text" id="us-add-username" placeholder="Nom d'utilisateur">
<p>Nom d'affichage</p>
<input class='field' type="text" id="us-add-displayname" placeholder="Nom d'affichage">
<p>Mot de passe</p>
<input class='field' type="password" id="us-add-password" placeholder="Mot de passe">
<p>Permissions</p>
<div class='permissions'>
<div>
<input type="checkbox" id="perm_FILES_EXPLORER">
<label for="perm_FILES_EXPLORER">Fichiers</label>
</div>
<div>
<input type="checkbox" id="perm_SERVICES">
<label for="perm_SERVICES">Services</label>
</div>
<div>
<input type="checkbox" id="perm_LINKS">
<label for="perm_LINKS">Liens</label>
</div>
<div>
<input type="checkbox" id="perm_SERVERS">
<label for="perm_SERVERS">Serveurs</label>
</div>
<div>
<input type="checkbox" id="perm_PIPELINES">
<label for="perm_PIPELINES">Pipelines</label>
</div>
<div>
<input type="checkbox" id="perm_METRICS">
<label for="perm_METRICS">Metrics</label>
</div>
<div>
<input type="checkbox" id="perm_USERS">
<label for="perm_USERS">Utilisateurs</label>
</div>
<div>
<input type="checkbox" id="perm_SETTINGS">
<label for="perm_SETTINGS">Paramètres</label>
</div>
</div>
<p>Photo de profil</p>
<input type="file" id="us-add-picture" accept="image/png, image/jpeg">
<span id='user-addreturn-info'></span>
<button id='us-add-button' class='btn green'><span>Ajouter</span></button>
</div>
`
})
const addCButton = document.getElementById("us-add-button")
const username = document.getElementById("us-add-username")
const displayname = document.getElementById("us-add-displayname")
const password = document.getElementById("us-add-password")
const picture = document.getElementById("us-add-picture")
const permissions = document.getElementsByClassName("permissions")[0].children
const returnInfo = new TextResponse("user-addreturn-info")
addCButton.addEventListener("click", () => {
var permissionsList = new Array()
for(var permission of permissions) {
console.log(permission.children[0].checked)
if(permission.children[0].checked) {
permissionsList.push(permission.children[0].id.replace("perm_", ""))
}
}
post("US_ADD", {
username: username.value,
display_name: displayname.value,
password: password.value,
picture: picture.files[0],
permissions: permissionsList
}).then((answer) => {
if(answer == "ALREADY_EXIST") {
returnInfo.err("L'utilisateur existe déjà !")
} else if(answer == "USERNAME_MISSING") {
returnInfo.err("Le nom d'utilisateur est manquant !")
} else if(answer == "DISPLAY_NAME_MISSING") {
returnInfo.err("Le nom d'affichage est manquant !")
} else if(answer == "PASSWORD_MISSING") {
returnInfo.err("Le mot de passe est manquant !")
} else {
View.destroyPopup()
loadUsers()
}
})
})
})
users.then(users => {
users = new Map(JSON.parse(users))
for(var user of users) {
user = user[1]
console.log(user)
const userComponent = new User({
username: user.username,
display_name: user.display_name,
picture: user.picture,
permission: user.permission,
window: View,
component: usersComponent
})
usersList.push(userComponent)
}
usersNumber.innerHTML = usersList.length
const usersContent = new Array()
for(var user of usersList) {
usersContent.push(user.generateHTML())
}
usersDiv.innerHTML = usersContent.join("")
for(var user of usersList) {
user.loadScript()
}
})
}
})
File diff suppressed because it is too large. Load diff
-16
View File
@@ -1,16 +0,0 @@
var express = require('express');
var router = express.Router();
var path = require("path")
router.get("/socketlink", (req,res,next) => {
if(process.env.DEV == true) {
res.send("ws://localhost:3001")
} else {
res.send("ws://neutral.raphix.fr")
}
})
module.exports = router;
-23
View File
@@ -1,23 +0,0 @@
var express = require('express');
var router = express.Router();
var path = require("path")
module.exports = router;
module.exports.ApplyLinks = class {
constructor(links) {
// Remove all routes
router.stack = []
for(var link of links) {
const url = link.url
router.get("/" + link.dest, (req,res,next) => {
res.redirect(302, url)
})
}
module.exports = router;
}
}
+2 -55
View File
@@ -1,65 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>Neutral</title>
<title>Inventory</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body class="LOG_body">
<div id='panel-box' class="panel-box m-align t-center">
<div class="logo"><img class="logo-img" src="/images/FormatLogo_WHITE.svg"><p>Neutral</p></div>
<body>
<div id="views" class="views-box">
<p style="position: absolute; width: 100%;" class='yellow t-center'><i class='fa-solid fa-warning'></i> Aucune permission ne semble vous êtes accordée<br>Demandez à Raphix afin de résoudre ce problème</p>
</div>
</div>
<div class="taskbar-box m-align t-center">
<div id="menu" class="menu-drop">
<div id="user-settings-button" class="menu-settings">
<i class="fas fa-gear"></i>
<p>Paramètres du compte</p>
</div>
<div class="menu-signout menu-settings" onclick="window.location = '/login/signout'">
<i class="fas fa-sign-out-alt"></i>
<p>Déconnexion</p>
</div>
</div>
<div class="taskbar-content">
<div class="taskbar-actions">
<img id="menu-logo" class="taskbar-logo" src="/images/FormatLogo_WHITE.svg">
<div id="views-items" class="views-items">
<%- dev %>
</div>
</div>
<div class="taskbar-user">
<div class="taskbar-userinfo">
<p id="infoDisplayname" class="taskbar-dispname">DisplayName</p>
<p id="infoUsername" class="taskbar-username">Username</p>
</div>
<img id="infoUserimage" class="taskbar-image" src="/images/default.jpg">
</div>
</div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script defer="" src="https://use.fontawesome.com/releases/v6.4.2/js/all.js" crossorigin="anonymous"></script>
<script src="/javascripts/basics.js"></script>
<script src="/javascripts/middle.js"></script>
<script src="/javascripts/io.js"></script>
<script src="/javascripts/indexscript.js"></script>
<script src="/javascripts/link.js"></script>
<script src="/javascripts/service.js"></script>
<script src="/javascripts/server.js"></script>
<script src="/javascripts/pipeline.js"></script>
<script src="/javascripts/filexplorer.js"></script>
<script src="/javascripts/user.js"></script>
<script src="/javascripts/metric.js"></script>
<script src="/javascripts/setting.js"></script>
<script src="/javascripts/personal.js"></script>
</body>
</html>
+3 -20
View File
@@ -1,31 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Neutral</title>
<title>Inventory</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body class="LOG_body">
<div class=" form-box m-align t-center">
<body>
<div class="logo"><img class="logo-img" src="/images/FormatLogo_WHITE.svg"><p>Neutral</p></div>
<div>
<p>Nom d'utilisateur</p>
<input id="username" type="text" class="field m-align">
</div>
<div>
<p>Mot de passe</p>
<input id="password" type="password" class="field m-align">
</div>
<p id="login-info"></p>
<button id="submit" class="btn green m-align LOG_btn"><span><i class="fa-solid fa-right-to-bracket"></i> Connexion</span></button>
<p style="font-size: 12px;">Version : <%- version %></p>
<p style="font-size: 12px;">Panel d'administration</p>
<a href="https://raphix.fr" style="font-size: 12px;">Revenir sur raphix.fr</a>
</div>
<script defer="" src="https://use.fontawesome.com/releases/v6.4.2/js/all.js" crossorigin="anonymous"></script>
<script src="/javascripts/basics.js"></script>
<script src="/javascripts/loginscript.js"></script>
</body>
</html>
+1 -1
View File
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<title>Neutral - Erreur</title>
<title>Inventory - Erreur</title>
<link rel='stylesheet' href='/stylesheets/style.css'/>
<style>
body {
+4 -4
View File
@@ -1,16 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<title>Neutral</title>
<title>Inventory</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1>Neutral - Page de style</h1>
<p>Cette page est dédiée au développement et n'est pas en relation avec le Panel Neutral.</p>
<h1>Inventory - Page de style</h1>
<p>Cette page est dédiée au développement et n'est pas en relation avec Inventory.</p>
<a href="/"><button class="btn red"><span>Revenir sur le panel</span></button></a>
<hr>
<p>Police : <code>'Roboto', sans-serif</code></p>
<p>Liens : <a href="/stylepage">https://neutral.raphix.fr/stylepage</a></p>
<p>Liens : <a href="/stylepage">https://inventory.raphix.fr/stylepage</a></p>
<hr>
<br>
<style>