Nueva versión de nomorepass

No suelo escribir aquí sobre estas cosas, pero hacía tiempo que no sacábamos ninguna novedad en nuestro gestor de contraseñas y como ahora mismo tenemos la versión 1.16.6 recién salida del horno en ambas tiendas (es raro que podamos lanzar a la vez en Android e iOs) pues os hago un reumen de lo que podéis encontrar nuevo (y mejorado).

Por fin la Wifi

Desde hace mucho tiempo nomorepass nos permite escanear los códigos QR con los que se comparten las credenciales de la WiFi, usar esas contraseñas era otra historia, o bien lo hacíamos con el sistema autofill de android, del que ya hablamos aquí, o bien copiabamos y pegábamos la contraseña en el diálogo de cambiar Wifi… Bien, esto ha cambiado y ahora ya podrás usar la contraseña de la wifi directamente desde la app.

Aquí te cuento como:

Como ves, nada más sencillo ahora que ya está integrado. En iOS funciona exactamente igual salvo que nos pedirá consentimiento antes y tarda un poco más en hacer efectivo el cambio.

Recuperar el backup que quieras

Tener tus contraseñas solo en el móvil es algo que requiere tener muy bien organizadas las copias de seguridad para que, en caso de percance, se puedan recuperar todas las contraseñas. Hasta ahora se almacenaban todas las copias asociadas al dispositivo que hacía las copias, de manera que no se podía recuperar una copia de seguridad de otro dispositivo en uno que ya había hecho alguna copia (me estoy refiriendo a copias en la nube, claro). Esto ha cambiado en esta versión como se cuenta en el mismo sitio web.

Ahora, cuando se solicita restaurar una copia de seguridad en la nube se nos ofrece la opción de elegir qué copia de seguridad queremos recuperar (y se marca con una barrita en la izquierda cual es la última copia que se hizo desde el dispositivo):

Además de la fecha se indica el «peso» que tiene el archivo, así evitaremos recuperar copias de seguridad de otros dispositivos con menos contraseñas…

Y eso es todo, espero que disfrutéis de esta nueva versión y, ya sabéis, cualquier problema se lo podéis consultar a [email protected].

Probando cosillas con arduino beetle

Lo que veis en la foto es un arduino beeetle, bueno, realmente es una placa pro micro con menos pines de los que debería y un conector directo a usb… Como véis es muy pequeño y podéis encontrarlo por un precio bastante económico, aquí, por ejemplo.

Yo ya había utilizado antes el arduino pro micro (leonardo compatible) para simular un teclado en otro proyecto, por lo que sabía que podría utilizar este también para algo similar. Dado su tamaño y lo fácil que se camufla como un «pincho» usb podría pasar desapercibido a la vista… Así que me decidí a ir un pasito más y añadirle un poco más de hardware para controlarlo. Qué mejor que ponerle un botón para indicarle cuando quiero que «teclee algo»… Para ello me aprovecho de que los pines digitales pueden actuar como pull-up y solo tenía que conectar el interruptor entre un pin digital y tierra. En mi caso lo conecté entre el D9 y GND como se puede ver en la foto:

Hice las soldaduras por detrás para proteger un poco más los componentes, pero podría ponerse por delante teniendo un poco más de cuidado.

Una vez el hardware preparado llega el momento de hacer las cosas interesantes… Tampoco es que vaya a ser muy original, pero aquí os dejo el programa que cargué inicialmente…. Funciona en windows y lo que consigues cuando pulsas el botón es que se te abra el chrome con la página web nomorepass.com… (igual sirve como propaganda y todo).

#include "Keyboard.h"
const int buttonPin = 9;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  Keyboard.begin();
}

void loop() {
  while (digitalRead(buttonPin) == HIGH) {
    delay(200);
  }
  delay(100);
  Keyboard.press(KEY_LEFT_GUI);
  Keyboard.press('r');
  Keyboard.releaseAll();
  delay(500);
  Keyboard.print("chrome https>&&nomorepass.com");
  Keyboard.write(KEY_RETURN);
  delay(500);
}

Básicamente lo único que hace es esperar a que el estado del pin al que está conectado el botón pase de alto a bajo (esto es así por la configuración INPUT_PULLUP) y cuando cambia, señal de que hemos pulsado el botón, lo que hace es enviar un COMMAND+r que abre el diálogo de ejecutar de windows y luego envía el texto chrome https://nomorepass.com. Como se puede ver he tenido que transliterar los caracteres que en el teclado americano están colocados en otro sitio (un defectillo de la librería de arduino).

Visto que funciona… Pues ya solo queda hacer una cajita e imprimirla en 3d:

He dejado el diseño en thingiverse por lo que podéis aprovecharlo… Mientras, a inventarnos cosas que hacer con el trasto… «No demasiado diabólicas»..

Subir a maven central una librería propia

Ahora que ya acabas de construir una librería interesante en Java, la has hecho pública (en github, por ejemplo) y quieres que todo el mundo la use… Queda una tarea pendiente, subirla a un repositorio maven para ponerla a disposición de los que utilicen este sistema (o gradle, que hoy en día ya son casi todos).

Vamos a verlo con un ejemplo que he subido esta mañana… Hay cosas que todavía no entiendo del todo, pero el resultado ha sido bueno, por lo que, al menos, podremos usar esta receta como guía para próximas veces.

El código que intento subir es una librería simple que tengo alojada en github con su pom.xml básico y que si te descargas el proyecto podrías compilar e instalar en tu maven con mvn install. La dirección es esta:

https://github.com/yoprogramo/nomorepass-java/

Ahora, para que todo el mundo pueda descargárselo como dependencia y no tenga que hacer el mvn install del proyecto, tenemos que subirlo a un repositorio público, podemos ver una guía en esta página: Guide to Public Maven Repositories. Tal como explican en la página, lo más sencillo para publicar en Maven Central es usar el repositorio Sonatype. Dicho y hecho… Lo intentamos por aquí.

Lo primero es crear una cuenta en el Jira de Sonatype aquí. Lo siguiente, y esto es un poco «tricky» es crear un ticket solicitando un nuevo id de grupo en esta dirección. No se puede pedir cualquier id de grupo (en mi caso quería pedir com.nomorepass) y generalmente se pedirá alguna prueba de que el dominio es tuyo. En mi caso este es el ticket que creé: https://issues.sonatype.org/browse/OSSRH-49426, para demostrar que el dominio era mío cambié el DNS e incluí una entrada TXT con el identificador del ticket:

Una vez autorizado (tarda un poco, es un proceso manual) hay que modificar nuestro código y prepararlo para la subida, pero, antes de eso, tenemos que generar nuestras claves gpg para poder firmar el código. eso se hace con este comando:

gpg --gen-key

Una vez generada podremos acceder a la lista de claves con el comando:

gpg --list-keys

Toma nota del id de la clave y recuerda la contraseña que usaste para generarla, porque tendrás que recordarla. Además, tendrás que publicarla en algún servidor de claves públicas para que pueda ser comprobada.

gpg --keyserver hkp://keys.gnupg.net --send-keys <el-id-de-la-clave>

Ahora empezamos a modificar el pom.xml para que cumpla con los requisitos para el repositorio Maven Central. En nuestro caso pusimos esto:

<groupId>com.nomorepass</groupId>
  <artifactId>nomorepass</artifactId>
  <version>1.0</version>
  <packaging>jar</packaging>

  <name>Nomorepass java library</name>
  <description>NoMorePass protocol 2 implemented on Java.</description>
  <url>https://nomorepass.com</url>

  <licenses>
    <license>
      <name>Apache License, Version 2.0</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
      <distribution>repo</distribution>
    </license>
  </licenses>

  <developers>
    <developer>
      <name>Jose Antonio Espinosa</name>
      <email>[email protected]</email>
      <organization>Nomorepass</organization>
      <organizationUrl>https://nomorepass.com</organizationUrl>
    </developer>
  </developers>

  <scm>
    <connection>scm:git:git://github.com/yoprogramo/nomorepass-java.git</connection>
    <developerConnection>scm:git:ssh://github.com:yoprogramo/nomorepass-java.git</developerConnection>
    <url>https://github.com/yoprogramo/nomorepass-java/tree/master</url>
</scm>

Y, una vez informado de todo esto, hay que incluir los plugins que nos permitirán hacer el despliegue directamente. Yo añadí esto:

<distributionManagement>
    <snapshotRepository>
      <id>ossrh</id>
      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
      <id>ossrh</id>
      <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

Y puse en mi directorio de maven settings.xml los datos de mi usuario

<settings>
  <servers>
    <server>
      <id>ossrh</id>
      <username>xxxxxxxxxx</username>
      <password>xxxxxxxxxx</password>
    </server>
  </servers>
</settings>

Por último, toda la sección de build (que no tenía) la sustituí por esto:

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-gpg-plugin</artifactId>
        <executions>
          <execution>
            <id>sign-artifacts</id>
            <phase>verify</phase>
            <goals>
              <goal>sign</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.sonatype.plugins</groupId>
        <artifactId>nexus-staging-maven-plugin</artifactId>
        <version>1.6.7</version>
        <extensions>true</extensions>
        <configuration>
          <serverId>ossrh</serverId>
          <nexusUrl>https://oss.sonatype.org/</nexusUrl>
          <autoReleaseAfterClose>true</autoReleaseAfterClose>
        </configuration>
      </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-source-plugin</artifactId>
          <version>2.2.1</version>
          <executions>
            <execution>
              <id>attach-sources</id>
              <goals>
                <goal>jar-no-fork</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-javadoc-plugin</artifactId>
          <version>2.9.1</version>
          <executions>
            <execution>
              <id>attach-javadocs</id>
              <goals>
                <goal>jar</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
    </plugins>
</build>

Y ya, finalmente, pude ejecutar el mágico:

mvn clean deploy

Si todo ha ido bien, el artefacto estará subido a un repositorio que tendremos que promocionar a «Release» para que se sincronice con el repositorio central… Pero al final ya lo tendremos disponible para todo el mundo…

Aquí podéis encontrar lo que acabo de subir: https://search.maven.org/artifact/com.nomorepass/nomorepass/1.0/jar

Construyendo un dispositivo inteligente con nodemcu y un display OLED

Últimamente se están poniendo de moda los dispositivos «inteligentes» que, básicamente, consiste en cacharros que están conectados de una manera o de otra a internet o a nuestra red doméstica y que aceptan comandos desde la red para controlar sus distintas funciones.

La verdad es que han bajado mucho de precio y el poder controlarlas desde los distintos asistentes de voz le dan un extra adicional. He trasteado un poco con Alexa y con Google Home, pero todavía estoy en el proceso de encontrarle el sitio correcto. En cualqueir caso, como soy un alma inquieta he preferido ver cuanto me costaba crear mi propio «dispositivo inteligente» con los materiales que tenía a mano… Esto es lo que he usado:

  • Pantalla OLED de 1,3″ con el chip SSH1106 de 128×64. En concreto esta.
  • Una placa Weimos D1 mini (compatible), que se basa en el chip ESP8266. En concreto esta.
  • Un relé preparado para 5V. En mi caso este.

El chip ESP8266 es una maravilla que integra wifi junto con un microcontrolador que puede ser programado desde el IDE del Arduino (entre otras formas) y el empaquetado en forma de placa nocemcu hace que sea muy sencillo hacer proyectos con este, siendo más barato y más potente que un arduino habitual. De hecho los componentes de este proyecto comprados en aliexpress (quitando cables y gastos de envío) no suman más de 6 Euros… Irresistible para montar un prototipo.

Al lío… Es esquema de conexiones es este:

En realidad el pulsador no hace falta, lo he incluido para poder comunicar al dispositivo manualmente el cambio de estado (es un rollo tener que hacerlo todo en remoto) y no es necesario para la primera versión.

Para poder programar la placa desde el IDE del Arduino vamos a tener que ir a la sección de Archivo->Preferencias y añadir la url http://arduino.esp8266.com/stable/package_esp8266com_index.json en el campo Gestor de URLs Adicionales de Tarjetas, quedando como en la imagen:

Luego nos vamos a Herramientas->Placas->Gestión de tarjetas y buscamos ESP8266 e instalamos la versión de ESP8266 Community.

Con esto ya nos aparecerá el tipo de tarjeta Wemos o NodeMCU en la lista de tarjetas que podemos conectar con el IDE.

Lo siguiente es encontrar una librería que nos permita interactuar por I2C con nuestra pantalla (y que sea lo más flexible posible para usos futuros). Esto es lo que me llevó más tiempo, básicamente porque los ejemplos que proporcionan están preparados para otro chip y la nomenclatura de los pines es diferente… Al final la mejor es esta:

https://github.com/ThingPulse/esp8266-oled-ssd1306

Yo he usado como base el ejemplo que viene al instalar la placa y se llama WIFIServer (creo que lo han cambiado por una versión nueva, os dejo el código completo al final de todas formas). El funcionamiento es de tal manera que al arrancar se conecta a la red wifi que tengamos configurada y queda esperando conexiones, cuando recibe una petición https://server_ip/gpio/0 ponemos a cero el GPIO2 y si recibimos una https://server_ip/gpio/1 lo ponemos a 1… Como esa salida la tenemos conectada al relé, pues ya podemos encender o apagar lo que queramos desde la web.

Para sacar la información por la pantalla, básicamente, utilizo la función drawString que me imprime en las coordenadas dadas de la pantalla una cadena (y en la fuente que hayamos seleccionado antes)… Podéis verlo en funcionamiento en este video:

Os pongo el código antes de integrar lo del botón… Básicamente lo que falta por poner es que cuando detectemos una pulsación del botón (D3 pase a cero) cambiemos el estado del pin conectado al relé (así tenemos control manual, cosa que echo de menos en las bombillas inteligentes, por ejemplo).


#include <ESP8266WiFi.h>
#include "SH1106Wire.h"

const char* ssid = "tussid";
const char* password = "tupassword";

SH1106Wire display(0x3c, 4, 5);

WiFiServer server(80);

void setup() {
 
  Serial.begin(115200);
  delay(10);

  pinMode(2, OUTPUT);
  digitalWrite(2, 0);
  
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  display.init();
  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);

  display.clear();
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.drawString(0,0,"Connecting...");
  display.display();
      
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  
  display.clear();
  display.drawString(0,0,String(ssid));
  display.drawString(0,10, "IP: "+WiFi.localIP().toString());
  display.display();
    
  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }
  
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();
  
  int val;
  if (req.indexOf("/gpio/0") != -1)
    val = 0;
  else if (req.indexOf("/gpio/1") != -1)
    val = 1;
  else {
    Serial.println("invalid request");
    client.stop();
    return;
  }

  digitalWrite(2, val);
  display.setColor(BLACK);
  display.fillRect(0, 26, 100, 10);
  display.setColor(WHITE);
  display.drawString(0,26,"GPIO: "+String(val));
  display.display();
  
  client.flush();

  String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
  s += (val)?"high":"low";
  s += "</html>\n";

  client.print(s);
  delay(1);
  Serial.println("Client disonnected");
}

Si habéis leido el código veréis que hay algunas cosas que se hacen de más, por ejemplo, pintamos un rectángulo en negro para borrar la línea antes de pintarla de nuevo con el valor del GPIO. Eso es debido a que esta librería está pensada para borrar la pantalla cada vez que la actualicemos y, por eso, no limpia el hueco en el que va a escribir (igual podemos hacer un fork que lo solucione, ya veremos) y sin esa limpieza las letras se escriben unas encima de otras.

Una nota final… El servidor no envía cabeceras CORS, por lo que si vais a utilizarlo desde javascript en cualquier otro servidor os saltará un error en la consola (y en mac ni siquiera hará la llamada real), en linux y windows funcionará aunque no recibiréis la respuesta.

Sigo modificando el código y demás a ver qué termino consiguiendo… Hasta es posible que le diseñe un PCB… Ya os iré contando.

Olvidarse de las contraseñas DEFINITIVAMENTE en Android

Una de las preguntas más redundantes que nos han hecho en los múltiples eventos en los que hemos presentado NoMorePass es ¿Puedo usarlo para hacer login en el propio móvil? Nuestra respuesta, como siempre, era positiva, pero con restricciones, hasta el momento solo podíamos copiar-pegar la contraseña… Y digo hasta ahora porque Android 8 incluyó una novedad que nos venía al pelo: el Autofill Framework.

Este framework permite a algunas aplicaciones registrarse como servicio proveedor de credenciales de forma que, si el usuario selecciona esa aplicación, el sistema permite que la aplicación «recomiende» valores posibles para los campos a rellenar en las aplicaciones… Dicho y hecho, esto es lo que los usuarios de NoMorePass nos estaban pidiendo y esto es lo que hemos conseguido (dentro video:)

Autocompletar con NoMorePass

Como véis es algo sumamente sencillo, seleccionar NoMorePass como proveedor de autocompletar y a partir de ese momento todas las contraseñas estarán disponibles para autorellenado cuando las necesitemos.

La primera vez que usamos una contraseña para una app nos preguntará qué contraseña enviar (y usaremos el mismo método que con las webs) y, lo que es más, si metemos a mano una contraseña se nos preguntará si queremos registrar esa contraseña en NoMorePass y así no tener que volver a meterla nunca más… Así hacemos realidad nuestro lema: Olvida tus contraseñas.

¿Y qué pasa con iOS? bueno, apple nunca nos ha puesto las cosas fáciles, más teniendo en cuenta su empeño con quedarse con las credenciales de todo el mundo en su iCloud. Sin embargo, a partir de iOS 12, Apple ha abierto un poco la mano a esta posibilidad y ofrece Servicios de autenticación que, cómo no, vamos a integrar lo antes que podamos.

Mientras… Si tienes Android 8.0 o superior, puedes disfrutar de esta nueva funcionalidad descargádote la versión 1.11.1 o superior de la app.