cerraduras, registros y leer en el ferry
Hoy salieron juntas tres cosas pequeñas, de esa clase silenciosa que hace el sitio más sólido en vez de más brillante.
Una cerradura que eliges tú. Las cuentas ya pueden activar el inicio de sesión en dos pasos: un código de una app de autenticación además de la contraseña. Quiero ser claro con la filosofía, porque me importa: nada aquí te va a dar la lata con esto, nunca. Ni banners, ni "¡protege tu cuenta hoy!", ni inscripción forzosa. Si nunca abres la pestaña de seguridad, nunca sabrás que la función existe. Yo la activé en mi propia cuenta de administrador, porque esa cuenta puede hacerlo todo, y me pareció lo correcto. Para ti es enteramente tu decisión.

El paso de alta: un secreto para tu app de autenticación, y luego un código para demostrar que funciona.
La generación de códigos la escribí yo mismo en vez de traer una librería, porque bajo el nombre intimidante de TOTP hay un truco pequeño y precioso de un RFC antiguo: calcula un HMAC y deja que los últimos cuatro bits del resumen elijan de dónde leer el código. El corazón entero:
mac := hmac.New(sha1.New, secret)
mac.Write(counterBytes[:])
sum := mac.Sum(nil)
// Dynamic truncation (RFC 4226 section 5.3).
offset := sum[len(sum)-1] & 0x0f
code := (uint32(sum[offset]&0x7f) << 24) |
(uint32(sum[offset+1]) << 16) |
(uint32(sum[offset+2]) << 8) |
uint32(sum[offset+3])También hay códigos de recuperación, y un par de salidas de emergencia para que un teléfono perdido nunca signifique un blog perdido. Probé más duro los caminos feos: el mismo código dos veces se rechaza, un código de recuperación gastado sigue gastado, y una cuenta que nunca se inscribió inicia sesión exactamente igual que antes, al byte.
Un registro para los idiomas. Con cinco idiomas y casi cincuenta entradas, "qué traducción me falta" se estaba volviendo un ejercicio de memoria. La página de idiomas del panel ahora muestra la cuadrícula completa también para las entradas, con las celdas faltantes y desactualizadas marcadas, a un clic de cualquier hueco hasta el editor correcto.
Y lectura sin conexión. El sitio ahora es instalable, y las entradas que hayas abierto siguen legibles sin conexión, que por aquí significa sobre todo: en el ferry. La parte difícil era invisible, las páginas en caché resolvían sus recursos relativos a la dirección equivocada y se rompían en silencio, esa clase de fallo que solo aparece cuando de verdad apagas la red y miras. Así que eso hice, y ahora funciona.