@codice-progressio/easy-permissions
Advanced tools
| const permisos = { | ||
| } | ||
| module.exports = permisos |
| const assert = require("chai").should() | ||
| const ep = require("../index") | ||
| describe("Configuraciones", () => { | ||
| describe("Defaults", () => { | ||
| ep.config() | ||
| it("configuraciones debe ser un objeto", () => { | ||
| ep.configuraciones.should.be.a("object") | ||
| }) | ||
| it("Debe contener las llaves", () => { | ||
| // Debe de incluir todas estas llaves. | ||
| ep.configuraciones.should.keys([ | ||
| "generarPermisos", | ||
| "modoProduccion", | ||
| "nombreArchivoPermisos", | ||
| "nombreCarpetaPermisos", | ||
| "nombreParametroRequest", | ||
| "path", | ||
| ]) | ||
| }) | ||
| it("Debe tener los valores por defecto", () => { | ||
| ep.configuraciones["path"].should.be.eq("./") | ||
| ep.configuraciones["nombreArchivoPermisos"].should.be.eq( | ||
| "permisos.seguridad.js" | ||
| ) | ||
| ep.configuraciones["nombreCarpetaPermisos"].should.be.eq("seguridad") | ||
| ep.configuraciones["modoProduccion"].should.be.eq(true) | ||
| ep.configuraciones["nombreParametroRequest"].should.be.eq( | ||
| "permisoSolicitado" | ||
| ) | ||
| ep.configuraciones["generarPermisos"].should.be.eq(false) | ||
| }) | ||
| }) | ||
| }) |
+137
-2
@@ -1,3 +0,138 @@ | ||
| module.exports = function () { | ||
| return "Hola mundo" | ||
| const fs = require("fs") | ||
| const guard = require("express-jwt-permissions")() | ||
| let rutaCompletaFichero = "" | ||
| const configuraciones = { | ||
| // El path del fichero en el cual se van a estar agregando | ||
| // los permisos. | ||
| path: "./", | ||
| // El nombre del archivo que se buscara. | ||
| nombreArchivoPermisos: "permisos.seguridad.js", | ||
| // El nombre de la carpeta | ||
| nombreCarpetaPermisos: "seguridad", | ||
| // Generalmente recibe process.env.NODE_ENV | ||
| modoProduccion: true, | ||
| // Parametro que se adjunta al request y contiene el | ||
| // permiso definido el middleware. Su mejor función es | ||
| // cuando hay un error de permisos y se quiere saber cual fue | ||
| // el permiso solicitado. | ||
| nombreParametroRequest: "permisoSolicitado", | ||
| // Por defecto detiene la generación del archivo. Mantenerlo por defecto | ||
| // en false impide que se registre cada tecla nueva dentro del permiso como | ||
| // una nueva linea en caso de usar auto-guardado. | ||
| generarPermisos: false, | ||
| } | ||
| module.exports.configuraciones = configuraciones | ||
| module.exports.config = function (conf = configuraciones) { | ||
| Object.keys(conf).forEach(x => { | ||
| if (configuraciones.hasOwnProperty(x)) configuraciones[x] = conf[x] | ||
| else throw new Error(msj("[ easyPermissions ] ", "Opcion invalida: " + x)) | ||
| }) | ||
| const tieneError = comprobarConfiguraciones(configuraciones) | ||
| if (tieneError) throw new Error(msj("[ easyPermissions ] ", tieneError)) | ||
| rutaCompletaFichero = comprobarFicheroPermisos(configuraciones) | ||
| } | ||
| function comprobarFicheroPermisos(conf) { | ||
| //El fichero debe de existir, si no se crea. | ||
| const dir = conf.path.concat(conf.nombreCarpetaPermisos) | ||
| const file = conf.nombreArchivoPermisos | ||
| const dirFichero = dir.concat("/" + file) | ||
| if (!fs.existsSync(dir)) fs.mkdirSync(dir) | ||
| let datos = `const permisos = {\r\n\r\n}\r\nmodule.exports = permisos` | ||
| if (!fs.existsSync(dirFichero)) fs.appendFileSync(dirFichero, datos) | ||
| return dirFichero | ||
| } | ||
| function comprobarConfiguraciones(conf) { | ||
| // El path debe ser obligatorio | ||
| if (!conf.hasOwnProperty("path")) return "Debes definir 'path'" | ||
| // El path no puede estar vacio | ||
| if (conf.path === null || conf.path?.length === 0) | ||
| return "El path no puede ser nulo" | ||
| if ( | ||
| conf.nombreCarpetaPermisos === null || | ||
| conf.nombreCarpetaPermisos?.length === 0 | ||
| ) | ||
| return "El nombre de la carpeta no puede ser nulo" | ||
| if (conf.nombreParametroRequest?.length === 0) | ||
| return "nombreParametroRequest no puede estar vacio" | ||
| //Si todo esta correcto mandamos null | ||
| return | ||
| } | ||
| /** | ||
| *Comprueba que el permiso esta definido. Si el estring | ||
| esta definido lo retorna, si no, manda un error. | ||
| * | ||
| * @param {string} permiso El permiso que se quiere definir | ||
| * @param {boolean} esMiddleware Por defecto en true. Retorna un middleware en | ||
| * lugar de retornar explicitamente el permiso. Esto se usa para comprobar los | ||
| * permisos en modo producción, y en modo desarrollo, escribe el permiso en el | ||
| * fichero definido. | ||
| * @returns String | Middleware | ||
| */ | ||
| module.exports.$ = ( | ||
| permiso, | ||
| descripcion = "Sin descripción", | ||
| opciones = { | ||
| esMiddleware: true, | ||
| } | ||
| ) => { | ||
| // En caso de que sea midleware debe retornar una funcion | ||
| const funcion = function (req, res, next) { | ||
| // Para fines de control, adjuntamos el mensaje de error en el req | ||
| // con el nombre definido en la configuracion | ||
| req[configuraciones.nombreParametroRequest] = permiso | ||
| return guard.check(permiso)(req, res, next) | ||
| } | ||
| try { | ||
| // Modificamos este mismo archivo para agregar los permisos | ||
| // directamente. | ||
| // Leemos este mesmo archivo. | ||
| var data = fs.readFileSync(rutaCompletaFichero, "utf-8") | ||
| // En modo produccion, o en caso de que el permiso exista, regresa el permiso | ||
| // la funcion segun este definido. | ||
| if (configuraciones.modoProduccion || data.includes(permiso)) | ||
| return opciones.esMiddleware ? funcion : permiso | ||
| // Evita la continua generacion de elementos si no has terminado de | ||
| // escribir permisos | ||
| if (!configuraciones.generarPermisos) | ||
| return opciones.esMiddleware ? funcion : permiso | ||
| // Si no existe el permiso lo agregamos. | ||
| let texto = data.toString().split("\n") | ||
| // Estructuramos | ||
| let nuevaLinea = ` "${permiso}":"${descripcion}",` | ||
| // Separamos el archivo en lineas. | ||
| // Agregamos una nueva linea siempre en la segunda posicion | ||
| texto.splice(1, 0, nuevaLinea) | ||
| // Escribimos el archivo | ||
| fs.writeFileSync(rutaCompletaFichero, texto.join("\n")) | ||
| } catch (error) { | ||
| throw new Error(msj("[ easyPermissions ] ", error)) | ||
| } | ||
| // Y para poder seguir trabajando en modo desarrollo | ||
| // devolvemos la funcion | ||
| return opciones.esMiddleware ? funcion : permiso | ||
| } | ||
| function msj(textRed, text) { | ||
| return `\x1b[0m\x1b[31m\x1b[40m${textRed}\x1b[0m${text}` | ||
| } |
+11
-2
| { | ||
| "name": "@codice-progressio/easy-permissions", | ||
| "version": "0.0.2", | ||
| "version": "0.1.0", | ||
| "description": "Permisos fáciles de crear y administrar.", | ||
| "main": "index.js", | ||
| "scripts": { | ||
| "test": "mocha" | ||
| "test": "nyc --reporter=html --reporter=text mocha", | ||
| "coverage": "nyc report --reporter=text-lcov | coveralls" | ||
| }, | ||
@@ -21,3 +22,11 @@ "author": "Rafael Ramirez", | ||
| "access": "public" | ||
| }, | ||
| "dependencies": { | ||
| "chai": "^4.2.0", | ||
| "express-jwt-permissions": "^1.3.3" | ||
| }, | ||
| "devDependencies": { | ||
| "coveralls": "^3.1.0", | ||
| "nyc": "^15.1.0" | ||
| } | ||
| } |
+76
-0
| # easy-permissions | ||
| Gestión rápida y fácil de permisos en express. | ||
| > Crea un fichero `segudirad/permisos.seguridad.js` y registra en el todos los permisos que se definan en la apliación con la función `$()` | ||
| ## Instalacion | ||
| `npm i @codice-progressio/easy-permissions` | ||
| ## Uso | ||
| ```javascript | ||
| // Importa la libreria | ||
| const easyPermissions = require("@codice-progressio/easy-permissions") | ||
| // Setea los parametros básicos de configuración | ||
| easyPermissions.config({ | ||
| modoProduccion: false, | ||
| generarPermisos: true, | ||
| }) | ||
| ``` | ||
| ### Llamamos la función `$` desde cada archivo de rutas que queramos asegurar. | ||
| ```javascript | ||
| const $ = require("@codice-progressio/easy-permissions").$ | ||
| app.get("/", $("nuevo-permiso", "cam"), (req, res, next) => { | ||
| res.send("ok") | ||
| }) | ||
| ``` | ||
| ### Recuperar permiso faltante. | ||
| Es posible recuperar el permiso faltante en caso de que `express-jwt-permissions` detecte que no existe dentro del token desencriptado. | ||
| ```javascript | ||
| //El middleware de captura de errores. | ||
| app.use((err, req, res, next)=>{ | ||
| let nombreParametroRequest = easyPermissions.configuraciones.nombreParametroRequest | ||
| if(req[nombreParametroRequest]){ | ||
| let leyenda = "No tienes permiso: " + req[nombreParametroRequest] | ||
| return res.status(401).send(leyenda) | ||
| } | ||
| }) | ||
| ``` | ||
| ### Registrar solo texto | ||
| Por defecto `$` devuelve un callback que funciona como medio para ejecutar la comprobación de seguridad de la ruta con `express-jwt-permissions`, pero es posible solo registrar el permiso seteando las opcion `{esMiddleware:false}`. | ||
| ```javascript | ||
| const MiMenu = [ | ||
| { | ||
| titulo: "Menu que requiere permisos", | ||
| permissions: [ | ||
| // Retorna solo "menus:menus-con-permisos" | ||
| $( | ||
| "menus:menus-con-permisos", | ||
| "Este menú requiere este permisos para visualizarze", | ||
| { esMiddleware: false } | ||
| ), | ||
| ], | ||
| }, | ||
| ] | ||
| ``` | ||
| ### Configuraciones disponibles y valores por defecto. | ||
| | Opción | Valor por defecto | Descripción | | ||
| | ---------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | path | "./" | El path del fichero en el cual se van a estar agregando los permisos. | | ||
| | nombreArchivoPermisos | "permisos.seguridad.js" | El nombre del archivo que se buscara. | | ||
| | nombreCarpetaPermisos | "seguridad" | El nombre de la carpeta | | ||
| | modoProduccion | true | Generalmente recibe process.env.NODE_ENV | | ||
| | nombreParametroRequest | "permisoSolicitado" | Parametro que se adjunta al request y contiene el permiso definido el middleware. Su mejor función en cuando hay un error de permisos y se quiere saber cual fue el permiso solicitado. | | ||
| | generarPermisos | false | Por defecto detiene la generación del archivo. Mantenerlo por defecto en false impide que se registre cada tecla nueva dentro del permiso como una nueva linea en caso de usar auto-guardado. | |
| const assert = require("assert") | ||
| const easyPermissions = require("../index") | ||
| describe("Hola mundo", () => { | ||
| it("Debe retornar hola mundo", () => { | ||
| assert.strictEqual(easyPermissions(), "Hola mundo") | ||
| }) | ||
| }) |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Trivial Package
Supply chain riskPackages less than 10 lines of code are easily copied into your own project and may not warrant the additional supply chain risk of an external dependency.
Found 1 instance in 1 package
10681
1018.43%5
25%151
1410%80
1900%0
-100%2
Infinity%2
Infinity%2
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added