Premier commit

This commit is contained in:
Raphael 2024-12-29 16:03:49 +01:00
commit aa5176a04c
21 changed files with 3551 additions and 0 deletions

137
.gitignore vendored Normal file
View File

@ -0,0 +1,137 @@
# ---> Node
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
#data
data
data/*
private

9
LICENSE Normal file
View File

@ -0,0 +1,9 @@
MIT License
Copyright (c) 2023 infrastructure
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# neutral
Panel d'administration de Raphix

113
bin/auth.js Normal file
View File

@ -0,0 +1,113 @@
const { LogType } = require("loguix")
const fs = require("fs")
const path = require("path")
const { __glob } = require("./global-variables")
const alog = new LogType("Authentification")
const keygen = require("./keygen")
const users = require("./users")
/**
* Vérifie si le token est présent et appartient à un utilisateur
* @param {string} token
*/
module.exports.check = function(token) {
var isApproved = false;
var username = null
users.fetchUsers().forEach((fetchUser) => {
if(fetchUser.tokens.includes(token)) {
isApproved = true
username = fetchUser.username
}
})
if(isApproved) {
return true
} else {
if(token) {
alog.warn("Erreur d'authentification - Token n'existe pas : " + token)
}
return false
}
}
/**
* Permet de se connecter à Inventory
* @param {object} data
* @returns Token or AUTH_FAILED
*/
module.exports.login = function(data) {
var username = data.username
var password = data.password
if(users.fetchUsers().has(username)) {
const user = users.fetchUsers().get(username)
if(password == user.getPassword()) {
const token = user.generateToken()
alog.log("Connexion approuvé de l'utilisateur : " + username)
return token
} else {
alog.warn("Echec de connexion de l'utilisateur : " + username + " - Mot de passe incorrect")
return "AUTH_FAILED"
}
} else {
alog.warn("Echec de connexion de l'utilisateur : " + username + " - Utilisateur non-inscrit dans la base de donnée")
return "AUTH_FAILED"
}
}
/**
* Remove the token
* @param {string} token
* @returns
*/
module.exports.signout = function(token) {
var isDone = false;
var username = null
users.fetchUsers().forEach((fetchUser) => {
if(fetchUser.tokens.includes(token)) {
isDone = true
username = fetchUser.username
fetchUser.removeToken(token)
}
})
if(isDone) {
alog.log("Suppression du Token '" + token + "' de l'utilisateur : " + username)
return true
} else {
if(token) {
alog.warn("Erreur d'opération lors de la déconnexion - Token n'existe pas : " + token)
}
return false
}
}
module.exports.getUserByToken = function(token) {
var isApproved = false;
var userGetted = null
users.fetchUsers().forEach((fetchUser) => {
if(fetchUser.tokens.includes(token)) {
userGetted = fetchUser
}
})
if(userGetted) {
return userGetted
} else {
if(token) {
alog.warn("Erreur d'authentification - Token n'existe pas : " + token)
}
return false
}
}

43
bin/config.js Normal file
View File

@ -0,0 +1,43 @@
const { LogType } = require("loguix")
const fs = require("fs")
const path = require("path")
const { __glob } = require("./global-variables")
const clog = new LogType("Configuration")
setup()
function setup() {
if(!fs.existsSync(__glob.CONFIG)) {
clog.log("Création du fichier de configuration dans : " + __glob.CONFIG)
fs.writeFileSync(__glob.CONFIG, JSON.stringify({
ENCRYPTION_KEY: "1",
}, null, 2))
}
}
/**
*
* @returns Config File
*/
module.exports.getFile = function () {
const file = JSON.parse(fs.readFileSync(__glob.CONFIG))
return file
}
/**
* Update le fichier configuration avec un object
* @param {Array} file
*/
module.exports.updateFile = function (file) {
if(fs.existsSync(__glob.CONFIG)) {
clog.log("Mise à jour du fichier configuration dans : " + __glob.CONFIG)
fs.writeFileSync(__glob.CONFIG, JSON.stringify(file, null, 2))
}
}
module.exports.saveSettings = function (settings) {
const file = this.getFile()
file.JENKINS_TOKEN = settings.jenkins_token
file.OMEGA_KEY = settings.omega_token
this.updateFile(file)
}

17
bin/global-variables.js Normal file
View File

@ -0,0 +1,17 @@
const path = require("path");
const root = path.resolve(__dirname, '../')
const __glob = {
ROUTES: root + path.sep + "routes" + path.sep,
ROOT: root,
LOGS: root + path.sep + "logs",
DATA: root + path.sep + "data",
USERS: root + path.sep + "data" + path.sep + "users.json",
CONFIG: root + path.sep + "data" + path.sep + "config.json",
PACKAGE_JSON: root + path.sep + "package.json",
};
module.exports = { __glob };

29
bin/keygen.js Normal file
View File

@ -0,0 +1,29 @@
const { LogType } = require("loguix")
const fs = require("fs")
const path = require("path")
var CryptoJS = require("crypto-js")
const { __glob } = require("./global-variables")
const clog = new LogType("KeyGen")
const config = require("./config")
const keypass = config.getFile().ENCRYPTION_KEY
setup()
function setup() {
if(keypass) {
clog.log("Clé de chiffrement trouvé et importé")
} else {
clog.error("Clé de chiffrement inconnu : Passage en mode par défaut")
}
}
module.exports.encrypt = function (text) {
let encryptedText = CryptoJS.AES.encrypt(text, keypass).toString();
return encryptedText;
}
module.exports.decrypt = function(text) {
let decryptedText = CryptoJS.AES.decrypt(text, keypass).toString(CryptoJS.enc.Utf8);
return decryptedText;
}

430
bin/users.js Normal file
View File

@ -0,0 +1,430 @@
const { LogType } = require("loguix")
const fs = require("fs")
const path = require("path")
const { __glob } = require("./global-variables")
const ulog = new LogType("Users")
const keygen = require("./keygen")
const uuid = require("uuid")
var usersList = new Map()
setup()
function setup() {
if(!fs.existsSync(__glob.USERS)) {
ulog.log("Création du fichier utilisateur dans : " + __glob.USERS)
fs.writeFileSync(__glob.USERS, JSON.stringify([], null, 2))
}
}
module.exports.getAllUsers = async function() {
return new Promise(async (resolve, reject) => {
const users = await this.fetchUsers()
// Remove for every people the password & the tokens
for(var user of users) {
user = user[1]
user.password = null
user.tokens = null
}
resolve(JSON.stringify(Array.from(users)))
})
}
/**
* Get all users from Users Data Base
*/
module.exports.fetchUsers = function () {
ulog.step.init("fetch_user", "Récupération de tous les utilisateurs inscrit dans la base de donnée")
const userFile = getFile()
usersList = new Map()
for(var userFetched of userFile) {
const user = new this.User({
username: userFetched.username,
password: userFetched.password,
display_name: userFetched.display_name,
tokens: userFetched.tokens,
lastLogin: userFetched.lastLogin,
})
usersList.set(user.username, user)
}
if(usersList.size == 0) {
const adminUser = new this.User({
"username": "admin",
"password": "inventory",
"display_name": "Administrateur",
"tokens": [],
"lastLogin": "DEFAULT ACCOUNT",
})
adminUser.register()
}
ulog.step.end("fetch_user")
return usersList
}
/**
* User Class is used to access to default user's properties and methods
* @param {object} properties User properties with : username, password, display_name
*/
module.exports.User = class {
username = null
password = null;
display_name = null
tokens = []
lastLogin = new Date()
constructor(properties) {
if(properties) {
this.username = properties.username
this.password = keygen.encrypt(properties.password)
this.display_name = properties.display_name
this.tokens = properties.tokens
this.lastLogin = properties.lastLogin
const userFile = getFile()
for(var userFetched of userFile) {
if(properties.username == userFetched.username) {
ulog.log("Récupération dans la base de donnée, de l'utilisateur : " + userFetched.username)
this.username = userFetched.username
this.password = userFetched.password
this.display_name = userFetched.display_name
this.tokens = userFetched.tokens
this.lastLogin = userFetched.lastLogin
}
}
}
if(this.username == null) {
ulog.error("One of user is without username ! [IMPORANT_FIELD_IS_MISSING]")
this.username = Math.random()
}
if(this.password == null) {
ulog.error("'" + this.username + "' is without password ! Password reset to 'default' [IMPORANT_FIELD_IS_MISSING]")
this.password = keygen.encrypt("default")
}
if(this.display_name == null) {
ulog.warn("'" + this.username + "' is without display name !")
this.display_name = this.username
}
if(this.tokens == null) {
this.tokens = []
}
if(this.lastLogin == null) {
this.lastLogin = new Date()
}
}
register() {
var alreadyExist = false
const userFile = getFile()
for(var userFetched of userFile) {
if(userFetched.username == this.username) {
userFile.splice(userFile.indexOf(userFetched), 1)
ulog.log("Mise à jour dans la base de donnée, de l'utilisateur : " + this.username)
alreadyExist = true
}
}
if(!alreadyExist) {
ulog.log("Création dans la base de donnée de l'utilisateur : " + this.username)
}
userFile.push(this)
updateFile(userFile)
usersList.set(this.username, this)
}
unregister() {
var alreadyExist = false
const userFile = getFile()
for(var userFetched of userFile) {
if(userFetched.username == this.username) {
userFile.splice(userFile.indexOf(userFetched), 1)
ulog.log("Mise à jour dans la base de donnée, de l'utilisateur : " + this.username)
alreadyExist = true
}
}
if(!alreadyExist) {
ulog.log("L'utilisateur n'est pas enregistré dans la base de donnée : " + this.username)
}
updateFile(userFile)
usersList.delete(this.username)
}
setPassword(newPassword) {
this.#sync()
this.password = keygen.encrypt(newPassword)
this.register()
ulog.log("Le mot de passe de l'utilisateur a été modifié : " + this.username)
}
getPassword() {
this.#sync()
return keygen.decrypt(this.password)
}
generateToken() {
this.#sync()
const gToken = uuid.v4().toString()
this.tokens.push(gToken)
this.register()
return gToken
}
removeToken(token) {
this.#sync()
var haveToken = false
for(var aToken of this.tokens) {
if(token == aToken) {
haveToken = true
}
}
if(haveToken) {
this.tokens.splice(this.tokens.indexOf(token), 1)
this.register()
} else {
ulog.warn("'" + this.username + "' n'a pas le token : " + token)
return false
}
}
setDisplayName(text) {
this.#sync()
this.display_name = text
this.register()
ulog.log("Le nom d'affichage de l'utilisateur a été modifié : " + this.username)
}
setNewUsername(text) {
this.#sync()
module.exports.deleteUser(this.username)
this.username = text
this.register()
ulog.log("Le nom d'utilisateur de l'utilisateur a été modifié : " + this.username)
}
setLastLogin(text) {
this.#sync()
this.lastLogin = text
this.register()
}
clearTokens() {
this.#sync()
this.tokens = []
this.register()
}
#sync() {
for(var userGet of usersList.keys()) {
const userFetched = usersList.get(userGet)
if(this.username == userFetched.username) {
this.username = userFetched.username
this.password = userFetched.password
this.display_name = userFetched.display_name
this.tokens = userFetched.tokens
this.lastLogin = userFetched.lastLogin
}
}
}
}
module.exports.addUser = function(settings) {
if(settings.username == '') {
ulog.error("Le nom d'utilisateur est manquant")
return "USERNAME_MISSING"
} else if(settings.password == '') {
ulog.error("Le mot de passe est manquant")
return "PASSWORD_MISSING"
} else if(settings.display_name == '') {
ulog.error("Le nom d'affichage est manquant")
return "DISPLAY_NAME_MISSING"
} else if(this.getUser(settings.username)) {
ulog.error("L'utilisateur existe déjà : " + settings.username)
return "ALREADY_EXIST"
} else {
ulog.step.init("add_user", "Ajout d'un utilisateur dans la base de donnée : " + settings.username)
const user = new this.User({
username: settings.username,
display_name: settings.display_name
})
user.setPassword(settings.password)
user.register()
ulog.step.end("add_user")
}
}
module.exports.deleteUser = function(username) {
ulog.step.init("delete_user", "Suppression d'un utilisateur dans la base de donnée : " + username)
const user = this.getUser(username)
user.unregister()
ulog.step.end("delete_user")
return "OK"
}
module.exports.getUser = function(username) {
return usersList.get(username)
}
module.exports.editUser = function(settings) {
if(settings.username == '') {
ulog.error("Le nom d'utilisateur est manquant")
return "USERNAME_MISSING"
} else if(settings.display_name == '') {
ulog.error("Le nom d'affichage est manquant")
return "DISPLAY_NAME_MISSING"
} else {
ulog.step.init("edit_user", "Modification d'un utilisateur dans la base de donnée : " + settings.username)
const user = this.fetchUsers().get(settings.username)
if(user) {
if(settings.newusername && settings.newusername != settings.username) {
if(this.getUser(settings.newusername)) {
ulog.error("L'utilisateur existe déjà : " + settings.username)
return "ALREADY_EXIST"
} else {
user.setNewUsername(settings.newusername)
}
}
if(settings.display_name) {
user.setDisplayName(settings.display_name)
}
if(settings.password) {
user.setPassword(settings.password)
}
ulog.step.end("edit_user")
return "OK"
} else {
ulog.step.end("edit_user")
return "NOT_EXIST"
}
}
}
module.exports.editMySelf = function (settings, user) {
if(user.username == settings.username) {
if(settings.username == '') {
ulog.error("Le nom d'utilisateur est manquant")
return "USERNAME_MISSING"
} else if(settings.display_name == '') {
ulog.error("Le nom d'affichage est manquant")
return "DISPLAY_NAME_MISSING"
} else {
ulog.step.init("edit_user", "Modification d'un utilisateur dans la base de donnée : " + settings.username)
const user = this.fetchUsers().get(settings.username)
if(user) {
console.log(settings)
if(settings.newusername && settings.newusername != settings.username) {
if(this.getUser(settings.newusername)) {
ulog.error("L'utilisateur existe déjà : " + settings.username)
return "ALREADY_EXIST"
} else {
user.setNewUsername(settings.newusername)
}
}
if(settings.display_name) {
user.setDisplayName(settings.display_name)
}
if(settings.password) {
user.setPassword(settings.password)
}
ulog.step.end("edit_user")
return "OK"
} else {
ulog.step.end("edit_user")
return "NOT_EXIST"
}
}
} else {
ulog.error("Vous ne pouvez pas modifier les informations d'un autre utilisateur !")
return "NOT_ALLOWED"
}
}
module.exports.clearTokens = function(username) {
const user = this.fetchUsers().get(username)
user.clearTokens()
}
/**
*
* @returns User File
*/
function getFile() {
const file = JSON.parse(fs.readFileSync(__glob.USERS))
return file
}
/**
* Update le fichier utilisateur avec un object
* @param {Array} file
*/
function updateFile(file) {
if(fs.existsSync(__glob.USERS)) {
ulog.log("Mise à jour du fichier utilisateur dans : " + __glob.USERS)
fs.writeFileSync(__glob.USERS, JSON.stringify(file, null, 2))
}
}

105
bin/www Normal file
View File

@ -0,0 +1,105 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
var log = require("loguix")
var {LogType} = require("loguix")
var { __glob } = require("./global-variables")
log.setup(__glob.LOGS, __glob.PACKAGE_JSON)
const wlog = new LogType("Serveur")
if(process.env.DEV ) {
wlog.log("MODE DEVELOPEMENT ACTIF")
}
wlog.step.init("start_server", "Démarrage du serveur Express JS")
var app = require('../main');
var http = require('http');
var config = require("./config")
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '5005');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
wlog.step.error("start_server", bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
wlog.step.error("start_server" , bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
wlog.log("Serveur entrain d'écouter sur le port : " + server.address().port)
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
wlog.step.end("start_server")
}

85
main.js Normal file
View File

@ -0,0 +1,85 @@
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
var favicon = require('express-favicon');
const app = express();
const fs = require("fs");
const log = require("loguix")
const { __glob } = require('./bin/global-variables');
const users = require("./bin/users")
const {User} = require("./bin/users")
var wlog = log.getInstance("Serveur")
setup()
function getRouters() {
wlog.log("Récupération de " + fs.readdirSync(__glob.ROUTES).length + " routeurs depuis : " + __glob.ROUTES)
for(var route of fs.readdirSync(__glob.ROUTES)) {
if(route == "index.js") {
app.use("/", require(__glob.ROUTES + "index"))
} else {
app.use("/" + route.replace(".js", ""), require(__glob.ROUTES + route))
}
}
}
function setup() {
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')))
getRouters()
users.fetchUsers()
// catch 404 and forward to error handler
app.use(function(req, res, next) {
res.locals.message = "Page non trouvé";
res.locals.error = {
"status": "404",
"stack": ""
}
// render the error page
res.status(404 || 404);
res.render('utils/error');
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('utils/error');
});
}
module.exports = app;

2314
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

38
package.json Normal file
View File

@ -0,0 +1,38 @@
{
"name": "inventory",
"version": "1.0.0",
"description": "Gestion de veteements",
"main": "index.js",
"scripts": {
"start": "nodemon ./bin/www",
"dev": "set DEV=true & nodemon ./bin/www"
},
"repository": {
"type": "git",
"url": "https://git.raphix.fr/raphix/inventory.git"
},
"nodemonConfig": {
"ext": "js, html",
"ignore": [
"*.json"
],
"delay": "10000000"
},
"keywords": [],
"dependencies": {
"cookie-parser": "~1.4.4",
"crypto-js": "^4.2.0",
"debug": "~2.6.9",
"ejs": "~2.6.1",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"loguix": "^1.4.2",
"nodemon": "^3.0.1",
"os-utils": "^0.0.14",
"pm2": "^5.3.0",
"express-favicon": "^2.0.4",
"uuid": "^9.0.1"
},
"author": "Raphix",
"license": "ISC"
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

25
routes/index.js Normal file
View File

@ -0,0 +1,25 @@
var express = require('express');
var router = express.Router();
var auth = require("../bin/auth")
/* GET home page. */
router.get('/', function(req, res, next) {
if(!auth.check(req.cookies.token)) {
res.clearCookie('token')
res.redirect(302, "/login")
} else {
if(process.env.DEV ) {
res.render('index', {dev: "<p class='view-item yellow'>DÉVELOPEMENT</p>"});
} else {
res.render('index', {dev: ""});
}
}
});
module.exports = router;

61
routes/login.js Normal file
View File

@ -0,0 +1,61 @@
var express = require('express');
var router = express.Router();
var auth = require("../bin/auth")
/* GET home page. */
router.get('/', function(req, res, next) {
if(auth.check(req.cookies.token)) {
res.redirect(302, "/")
} else {
res.clearCookie('token')
res.render('login', {version: require("../package.json").version});
}
});
module.exports = router;
router.post("/", (req, res) => {
const body = req.body
const token = auth.login({
username: body.username,
password: body.password
})
if(token == "AUTH_FAILED") {
setTimeout(() => {
res.status(403).send("AUTH_FAILED")
}, 1000)
} else {
res.cookie('token' , token, { maxAge: 900000000, httpOnly: true })
res.status(200).send("AUTH_SUCCESS")
}
})
router.get('/signout', function(req, res, next) {
if(!auth.check(req.cookies.token)) {
res.clearCookie('token')
res.redirect(302, "/")
} else {
auth.signout(req.cookies.token)
res.clearCookie('token')
res.redirect(302, "/")
}
});

9
routes/stylepage.js Normal file
View File

@ -0,0 +1,9 @@
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('utils/stylepage');
});
module.exports = router;

12
views/index.ejs Normal file
View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>Inventory</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<script defer="" src="https://use.fontawesome.com/releases/v6.4.2/js/all.js" crossorigin="anonymous"></script>
</body>
</html>

14
views/login.ejs Normal file
View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Inventory</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<script defer="" src="https://use.fontawesome.com/releases/v6.4.2/js/all.js" crossorigin="anonymous"></script>
</body>
</html>

32
views/utils/error.ejs Normal file
View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<title>Inventory - Erreur</title>
<link rel='stylesheet' href='/stylesheets/style.css'/>
<style>
body {
padding: 2%;
}
div {
background-color: rgb(32, 32, 32);
border-radius: 1vw;
padding: 2%;
}
</style>
</head>
<body>
<div>
<h1>Erreur <%= error.status %></h1>
<h2><%= message %> - <%= error.status %></h1>
<pre><%= error.stack %></pre>
</div>
<br>
<a href="/"><button class="btn red"><span>Retourner sur le panel</span></button></a>
</body>
</html>

75
views/utils/stylepage.ejs Normal file
View File

@ -0,0 +1,75 @@
<!DOCTYPE html>
<html>
<head>
<title>Inventory</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<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://inventory.raphix.fr/stylepage</a></p>
<hr>
<br>
<style>
.box-color {
width: 100px;
height: 100px;
transition: 0.2s;
border: 1px solid;
}
.box-color:hover {
transform: scale(1.1);
}
.box-color:active {
transform: scale(1);
color: rgb(58, 255, 3);
}
button {
width: fit-content ;
}
</style>
<div class="col">
<p>Classe : <code>btn</code></p>
<div class="row">
<button class="btn red"><span>Error Button</span></button>
<button class="btn blue "><span>Info Button</span></button>
<button class="btn yellow"><span>Warning Button</span></button>
<button class="btn green"><span>Confirm Button</span></button>
<button class="btn"><span>Default Button</span></button>
</div>
<p>Classe : <code>btn min</code></p>
<div class="row">
<button class="btn min red"><span><i class="fa fa-xmark"></i></span></button>
<button class="btn min blue"><span><i class="fa fa-info"></i></span></button>
<button class="btn min"><span><i class="fa fa-def"></i></span></button>
</div>
<div class="row">
<div onclick="copyToClipboard('#323031')" style='background-color: #323031;' class="box-color"><p style="text-align: center;">#323031</p></div>
<div onclick="copyToClipboard('#f10000')" style='background-color: #f10000;' class="box-color"><p style="text-align: center;">#f10000</p></div>
<div onclick="copyToClipboard('#605e5863')" style='background-color: #605e5863;' class="box-color"><p style="text-align: center;">#605e5863</p></div>
</div>
<p>Classe : <code>field</code></p>
<input type="text" class="field">
<script>
function copyToClipboard(text) {
navigator.clipboard.writeText(text)
}
</script>
<script defer="" src="https://use.fontawesome.com/releases/v6.4.2/js/all.js" crossorigin="anonymous"></script>
</body>
</html>