Similar Posts
QuickSearch: filtro de contenido con jQuery
QuickSearch es una librería bastante interesante que permite filtrar el contenido de elementos que contengan cierto texto. Tan solo hay que pasar una lista de elemtos y estos los filtrará para mostrar solo aquellos que cumplan cierto filtro de texto.
Se puede pasar lista de elementos (ul), párrafos, tablas, … Se le puede indicar el texto o la imagen que muestre que se está filtrando datos, indicar retraso, añadir clases css, …
QuickSearch
Vía / WebAppers
FireUnit: extensión para pruebas unitarias de Javascript
FireUnit es un plugin para Firefox que permite realizar pruebas unitarias de Javascript y mostrar los logs en una pestaña de Firebug. El plugin está desarrollado entre otras personas por John Resig, desarrollador de jQuery.
Se pueden realizar pruebas como las siguientes:
// Simular eventos del navegador
var input = document.getElementsByTagName("input")[0];
fireunit.mouseDown( input );
fireunit.click( input );
fireunit.focus( input );
fireunit.key( input, "a" );
Vía / John Resig
Laboratorio: eliminar HTML en cajas de texto con jQuery
Trasteando un poco con jQuery me ha dado por hacer una función que elimina las etiquetas HTML de una caja de texto de un formulario. Esto puede ser necesario cuando no se quiere que se introduzca HTML en un campo. Lógicamente, esto es la parte cliente, en el servidor debería haber una función similar que lo hiciera.
La función es sencilla, en cada input:text añadimos el evento change para que cuando se modifique el contenido, se ejecute la función de strip_tag, la cual crea un elemento DIV auxiliar, hago que su contenido sea el valor de la caja de texto, me quedo son con el texto e inserto este valor en el input:
$('document').ready(function() {
$(':text').change(function() {
$(this).attr('value', $('document').add('<div></div>').html($(this).attr('value')).text());
});
});
¿Dudas?, alguna. Si entre el texto pongo un <script>alert(1);</script> me ejecuta el script, algo no muy elegante. ¿Qué pasa con el elemento DIV creado?, ¿se queda en el limbo o se destruye?.
Bueno, para mis primeras pruebas con jQuery no está mal del todo.

Hapi.js + Vue.js accediendo a mongodb
Como ya dije, esta aplicación estará basada en Mongodb, y usaremos mongoose como ODM.
El primer paso es instalar mongoose:
npm i mongoose
Una vez instalado crearemos un controlador que nos permita usar la BD en toda la aplicación Hapi.js. Para ello haremos uso de los decorate del servidor. Los decorations permite extender objectos ofrecidos por Hapi.js, en nuestro caso server y request. Usando un plugin nos conectaremos a mongodb usando mongoose y añadiremos ese objecto con los decorate.
Creamos el fichero /plugins/db.js con el siguiente código:
/**
* DB controller
*
* It uses Mongoose and "stores" it in the server and the request using `decorate`
*/
const mongoose = require( 'mongoose' );
exports.plugin = {
name: 'db',
register: async function( server, options ) {
mongoose.connect( options.url, { useNewUrlParser: true } );
const db = mongoose.connection;
// eslint-disable-next-line
db.on( 'error', console.error.bind( console, 'connection error:' ) );
db.once( 'open', function() {
server.decorate( 'server', 'db', mongoose );
server.decorate( 'request', 'db', mongoose );
// eslint-disable-next-line
console.log( 'DB connected' );
} );
},
};
Para configurar la conectividad a mongodb tendremos que añadir los datos a la /config/index.js
const config = {
server: {
port: 3001,
},
website: {
name: `WP Desk`,
},
db: {
url: 'mongodb://localhost/wpdesk',
},
};
Y en el manifiest usado por glue, tendremos que añadir el nuevo plugin y las nuevas opciones de conexión:
const manifest = {
server: {
port: Config.get( '/server/port' ),
},
register: {
plugins: [
{
plugin: './api/home',
},
{
plugin: './plugins/db',
options: Config.get( '/db' ),
},
],
},
};
Ya tenemos casi todo configurado, ahora vamos a empezar con un ejemplo creando un esquema de moongose que nos permite acceder a colecciones de mongodb.
Lo más común es tener una colección de usuarios, que tendrá los siguientes campos:
- userName: de tipo String,
- firstName: de tipo String,
- lastName: de tipo String,
- email: de tipo String,
- role: que referencia a otro elemento de otra colección,
- isEnabled: de tipo Boolean,
- password: de tipo String,
- resetPassword: un objeto representado por:
- hash: de tipo String,
- active: de tipo Boolean,
También crearemos un método estático que devuelva todos los elementos de la colección users para realizar pruebas:
/**
* User model based on Mongoose
*/
const mongoose = require( 'mongoose' );
const Schema = mongoose.Schema;
// Mongoose schema
const userSchema = new mongoose.Schema( {
userName: String,
firstName: String,
lastName: String,
email: String,
role: Schema.Types.ObjectId,
isEnabled: Boolean,
password: String,
resetPassword: {
hash: String,
active: Boolean,
},
} );
/**
* User static model findAll
*
* @returns {array}
*/
userSchema.static( 'findAll', async function() {
const result = await new Promise( ( resolve, reject ) => {
this.model( 'User' ).find( {} ).exec( ( error, data ) => {
if ( error ) {
reject( error );
}
resolve( data );
} );
} );
return result;
} );
const User = mongoose.model( 'User', userSchema );
module.exports = User;
Ya está todo, ahora solo modificamos el handler de la ruta home.js para mostrar los valores de findAll:
/**
* Route handler
*
* @param {object} request
* @param {object} h Hapi object
* @returns {object}
*/
handler: async( request, h ) => { // eslint-disable-line
try {
const result = await User.findAll();
return result;
} catch ( error ) {
return { error: 500 };
}
},
Puedes bajarte el código aquí
Lista de ofuscadores para Javascript
Para aquellos que necesiten ofuscar su código Javascript para que sea más difÃcil de entender a los usuarios, les vendrá bastante bien esta lista de aplicaciones que modificarán nuestro código:
- Thicket™ Obfuscator for JavaScript: también válido para ECMAScript, a parte de modificar el código para dificultar su lectura, lo comprime.
- Jasob 2: modifica los nombres de variables, borra comentarios y elimina espacios entre muchas otras cosas.
- Javascript Obfuscator: trata los scripts y ficheros js contenidos en una página html, modificando los espacios, comentarios, nombres de variables y funciones y lo escribe todo en una única lÃnea, añadiendo punto y coma cuando sea necesario. Existe versión online.
- Stunnix JavaScript Obfuscator: modifica javascripts y ECMAScripts contenidos en ficheros HTML, PHP, ASP, JSP.
- JCE Pro: modifica el código javascript para que sea imposible su lectura.
- Scripts Encryptor (ScrEnc): ofusca los siguientes tipos de archivos: HTML, JavaScript/JScript, C/C++/MFC.
- Shane Ng’s GPL-licenced obfuscator: ofuscador con licencia GPL.
- Dean Edwards JavaScript Compressor/Obfuscator: online.
- ESC: ofuscador de código ECMAScript escrito en JScript.
- Jammer: modifica ficheros HTML, Javascript y VRML, comprimiendo su espacio y haciendo que sea difÃcil de entender.
- JSCruncher Pro: reduce una media del 60% del tamaño original.
- Strong JS: elimina caracteres innecesarios y modificando el nombre de variables.
- JavaScript Scrambler: fácil de usar.
- Javascript Encoder from scriptasylum.com: online.
VÃa / Ajax Digest

Hapi.js + Vue.js modelos mejorados
En este caso voy a explicar cómo añadir una ruta en el backend para gestionar usuarios.
Antes de nada vamos a instalar tres paquetes:
- @hapi/joi para validar los datos de entrada
- @hapi/boom para mostrar errores HTTP de forma sencilla
- bcrypt para encriptar la contraseña
npm i @hapi/joi
npm i @hapi/boom
npm i bcrypt
Tendremos que añadir la ruta al manifest de glee
const manifest = {
server: {
port: Config.get( '/server/port' ),
},
register: {
plugins: [
{
plugin: './api/home',
},
{
plugin: './api/user',
},
{
plugin: './plugins/db',
options: Config.get( '/db' ),
},
],
},
};
Ahora solo falta crear el controlador para las rutas de usuarios, dos en este caso:
- GET /user/[user] para recuperar un usuario
- PUT /user para crear un nuevo usuario
Lógicamente aún no hay nada de autenticación, por lo que cualquiera puede crear un usuario realizando una llamada PUT a la URL indicando userName, email y password.
Para comprobar la validez de los datos introducidos, usaremos joi. Usando las opciones de la ruta, indicaremos las reglas que deberá cumplir cada parámetro introducido. Así, para recuperar un usuario, se comprobará que user sea string, alfanumérico y que tenga una longitud de 3 a 20 caracteres:
validate: {
params: {
user: Joi.string().alphanum().min( 3 ).max( 20 ),
},
},
Así de fácil.
En el caso de comprobar los datos de entrada de la llamada PUT, en vez de usar params, usaremos payload:
validate: {
payload: {
userName: Joi.string().alphanum().min( 3 ).max( 20 ).required(),
email: Joi.string().email().required(),
password: Joi.string().min( 8 ).required(),
},
},
Por último mostrar el código para crear un nuevo usuario. Primero se comprueba si existe un usuario con ese nickname o email. Si es así, se devuelve error usando boom, si no, se genera la contraseña encriptada (aquí no me he molestado mucho en ello, ya lo haré más adelante), y se crea el usuario usando el método create de moongose:
/**
* Route handler
*
* @param {object} request
* @param {object} h Hapi object
* @returns {object}
*/
handler: async( request, h ) => { // eslint-disable-line
try {
// TODO: Add role
const user = await User
.findOne( {
$or: [
{ userName: request.payload.username },
{ email: request.payload.email },
],
} )
.exec();
if ( user ) {
return Boom.badData( 'User exists' );
}
const password = await bcrypt.hash( request.payload.password, Config.get( '/hash/PASSWORD_HASH' ) );
const userData = Object.assign( {}, request.payload, { password } );
const newUser = await User.create( userData );
return newUser ?
{
response: true,
message: 'User created',
userId: newUser.id,
} :
Boom.boomify( {
response: false,
message: 'There was an error during user creation',
}, { statusCode: 400 } );
} catch ( error ) {
return Boom.badImplementation( 'Error', { error } );
}
},
Como último apunte, he modificado la configuración para que admita ficheros .env con los datos necesarios.
Como siempre te puedes bajar el código aquí