Snippets: items para hacer como nuevo manager de un equipo


Leadership

Hace unos días encontré este blog post: What I learned after managing a small team for 2 years, y me gustó mucho la idea de un framework con un checklist de cosas para hacer cuando tomas el rol de lider en un proyecto/equipo existente.

Dejo los items aqui para fácil acceso (y así no tengo que estar cavando y buscando en mi email, a ver si me dejé el link por ahí):

La idea de snippets, es tener a la mano los detalles que me hicieron eco cuando encuentro cosas online.

Saludos,
Gorka


Nuevos juguetes: Status Keycard


Status Keycard

Hace unas semanas me crucé con un par de personas del equipo de Status, nos juntamos en un co-working space para trabajar en Aragon y justo estaban ahí también.

Platicando de ideas y proyectos y lo que estamos haciendo cada quien por su lado para el mundo Web 3.0 tuve la suerte que me regalaran una de estas tarjetas.

La idea es fantástica, la tarjeta es similar a una hardware wallet (ya escribiré un post acerca de otro de estos que tmb tengo), es decir, la llave privada con la que se firman transacciones la tiene la tarjeta, y no hay manera de obtenerla en uso normal, por lo que se puede entender como segura.

Cuando se necesita firmar algo, la tarjeta lo hace a través de NFC (similar a usar un celular/reloj para pagar). Se envía la data que se necesita firmar a la tarjeta, y esta regresa la data firmada con la llave privada.

Definitivamente es muy interesante, tiene un poco de hipo aún: hay que tener la tarjeta bien firme (que no se mueva) por los segundos que está firmando o puede fallar la operación - no es deal breaker pero por ahora si puede ser difícil usarla.

Se pueden crear combinaciones interesantes con otras hardware y software wallets, algo como: usar la keycard como llave privada de uso diario derivando la llave privada desde otra hardware wallet de uso de largo plazo. En fin, ya veremos y les iré contando.

Saludos,
Gorka


Nuevos juguetes: Raspberry Pi


Raspberry Pi 3

Hace unas semanas me animé a comprar uno de estos (con el paquete para iniciar).

No es nada del otro mundo pero es barato, hay otras opciones de servidores pequeños con un poco más de specs, pero no es algo que me haga falta para experimentar.

El starter-kit vino con todos los cables y gadgets necesarios para ensamblar la raspi y echarla a andar.

Nota importante: ya tenía un teclado y mouse externos que son necesarios para empezar a usar la raspi, así como un monitor, de monitor se puede usar una televisión que tenga entrada HDMI (el kit venía con un cable HDMI).

Iniciar todo es trivial, cuando enchufas y conectas la Raspberry Pi te guía para conecarte a Internet e iniciar la instalación. La tarjeta de memoria ya traía el software precargado para instalar Raspbian (una distro de Linux basada en Debian). Una vez terminada la instalación listo. Ya se puede jugar con la Raspberry Pi como si fuera una computadora normal.

Entre las cosas que quiero experimentar es usar la Raspberry Pi como un servidor personal donde voy a guardar la data/info de las apps que uso (este es un proyecto más grande que estoy trabajando y obviamente precisa de cierta infrestructura para que las apps usen/guarden la data en este personal server). No sé si la Rasberry Pi aguanta estar prendida y conectada todo el tiempo, capaz y se necesita algo más para este tipo de uso, pero como dije, es de prueba y los details los iré trabajando sobre la marcha.

Saludos,
Gorka


Kanpo: exponer local server via WebRTC


Límites

Hace unos días me pasó algo curioso: ayudando a un amigo hicimos un “puente” usando ngrok a su servidor local (nada raro hasta aquí), después de un par de peticiones empecé a recibir mensajes de error por parte de ngrok, decía que me estaba pasando del límite requests - ngrok mismo dice que es raro que te vayas a pasar:

Limits are imposed on connections, not requests. If your HTTP clients use persistent connections aka HTTP keep-alive (most modern ones do), you’ll likely never hit this limit.

https://ngrok.com/pricing

Pero pasó. Y me vino la idea de usar WebRTC (como ultimamente me pasa, WebRTC para todo).

De ahí nació Kanpo - aviso, es un work in progress.

Las ventajas de usar esta herramienta contra los servicios que usan servidores para comunnicar la data son 1) WebRTC por default usa ssl, entonces las comunicacione están cifradas y no pueden espiar; 2) No se usa un punto central que puede fallar, es decir, no dependes de un servicio que hoy funciona y quien sabe como siga mañana; y 3) No hay que pagar para evitar que limiten los datos que van a estar pasando por sus servidores lo que abre la puerta a 4) Se pueden mandar miles y miles de requests por segundo si así se quiere.

Aca les dejo un par de opciones “conocidas” para exponer servidores locales que usan servidores de relay (en lo que funciona Kanpo):

Ya iré avisando cuando Kanpo vaya siendo actualizado y funcional.

Saludos,
Gorka


Iframes y Web Workers


Sandbox

Resulta que por cuestiones de trabajo me vengo a enterar que los Web Workers tienen acceso a los recursos de localStorage cuando no se les ejecuta con un origen opaco (opaque origin - referencia).

La propuesta sería entonces restringir ese origen para poder limitar el acceso, pero cuando el Web Worker va a recibir un script grande (más de 2 megas grande), esto se nota - osea, tarda la ejecución y pues no es la mejor experiencia para el usuario.

Se vieron e intentaron varias propuestas (acá están si a alguien le intersan) pero ninguna fue final. Tirando ideas llegó otra que proponía usar los Web Workers dentro de un iframe limitado por sandbox (sanboxed iframes), así que me puse a hackear para ver si lo podía hacer funcionar.

El tema es que el código que se va a ejectuar en el Web Worker es “dinámico”, osea, no le vamos simplemente dar una URL donde está el script que va a ejecutar, sino que hay que darle un Blob, por lo cual va a haber problemas. Resumiendo:

Solución propuesta:

class IframeWorker extends EventTarget {
  constructor(scriptUrl, id) {
    super()
    this.id = id
    this.iframe = document.createElement('iframe')
    this.iframe.sandbox = 'allow-scripts'

    const source = `
      <script>
        const init = async () => {
          const res = await fetch(url, { mode: 'cors' })
          const blob = await res.blob()
          const workerURL = URL.createObjectURL(blob)
          const worker = new Worker(workerUrl, { name: '${id}' })
          worker.addEventListener('error', error => window.parent.postMessage({ from: '${id}', error }, '*'), false)
          worker.addEventListener('message', event => window.parent.postMessage({ from: '${id}', msg: event.data }, '*'), false)
          window.addEventListener('message', ({ data }) => worker.postMessage(data))
          URL.revokeObjectURL(workerUrl)
        }
        init()
      </script>
    `
    this.iframe.srcdoc = source
    document.body.appendChild(this.iframe)
    window.addEventListener('message', this.handleIframeMessage, false)
  }

  postMessage(msg) {
    this.iframe.contentWindow.postMessage(msg, '*')
  }

  destroy() {
    window.removeListener('message', this.handleIframeMessage)
    document.removeChild(this.iframe)
    this.iframe = null
  }

  handleIframeMessage = ({ source, data: { from, error, msg } }) => {
    if (source === this.iframe.contentWindow && from === this.id) {
      this.dispatchEvent(
        new MessageEvent(error ? 'error' : 'message', {
          data: error || msg,
        })
      )
    }
  }
}

export default iframeWorker

Lo que se hizo cumple con lo que queríamos:

  1. Inyectar el código directamente en la clase, para lo cual se recivbe scriptUrl, que se transforma en un blob, así se puede usar directamente en el Worker en el iframe.
  2. Para que el iframe ejecute el código inyectado hay que settear la propiedad srcdoc en lugar de src o de modificar el cuerpo dinámicamente (esos métodos tirarían DOM Exception por que el iframe está en un sandbox).
  3. Simular la interfaz de un Worker para hacer comunicación transparente, en este caso está el método postMessage y la emisión de eventos del tipo MessageEvent
  4. Nota la implementación del método handleIframeMessage necesita de un transpilador para mantener contexto, de lo contrario tendría que hacerse un bind en el constructor (this.handleIframeMessage = this.handleIframeMessage.bind(this))

Y así quedó la fiesta.

Bueno, con esta clase se pueden tener Workers ejectuandose un contexto JS sin que tengan acceso a los stores de IndexedDB del mismo. No es algo normal pero es algo que le va a venir bien a quien lo esté buscando.

Saludos,
Gorka


Encriptar y decriptar


Encriptar y decriptar

He estado leyendo y tratando de aprender como encriptar y luego decriptar información de manera segura (y tal vez algún día pueda decir: en la manera correcta).

Sin entrar a detalles que podrían mandarme por un agujero de conejo, describo lo que quiero hacer y luego lo que he encontrado:

Contexto:

El proceso:

  1. La webapp hace un request a un primer endpoint (algo así como /knock)
  2. El servidor recibe el request y genera una frase de manera random, entonces cifra la frase con la llave pública, guarda un hash de la frase y envía el texto cifrado como respuesta
  3. La webapp recibe el challenge, lo decifra usando la llave privada y entonces genera un hash (usando el mismo proceso que el servidor para generar el hash) y manda al server el hash al siguiente endpoint (algo como /answer)
  4. El servidor recibe los datos y compara los hashes, si son iguales entonces sabemos que la webapp tiene la llave privada correspondiente a la llave pública usada para cifrar el challenge

Para facilidad saqué otros puntos del proceso, pero esto describe la parte núcleo a resolver.

Encontré varias librerías que pueden hacer esto, pero, hay un requisito extra: el par de llaves tienen que ser del tipo correspondiente a Ethereum: ECDSA.

Las librerías con las que estuve jugando son:

Por ahora tengo una implementación funcional que usa eth-crypto PERO (gran pero), solo puede encriptar/decriptar mensajes de menos de 16 letras :( Le dejé un issue acerca de esto y no me han respondido (capaz nunca lo hagan), así que sigo aprendiendo para ver como resolver esto de manera genérica.

Ya iré avisando.

Saludos,
Gorka


Random hypothesis: PI projection in 4D


De la misma manera que se pueden hacer proyecciones de circulos 3D a 2D lo mismo se puede hacer para “elementos” de 4D (y dimensiones superiores) a gráficos 3D.

La idea que tuve es graficar los digitos de PI en un espacio de 3 ejes (potencialmente no se verá nada), pero esta podría ser una proyección de algo más, algo “causal” en 4D y lo que entendemos en PI es sólamenta la proyección en 3D (y por eso no “vemos” nada).

Bueno, ya veré si en algún momento me pongo a jugar con esto.

Saludos,
Gorka


Pagination