lol, 64bit integer overflows are fun to debug

specially when running a multi-arch cluster and HA with poor observability. a `time.Duration` was being casted to an `int` (because I clearly have no clue of what I'm doing). All is well on 64-bit processors, but 32-bit processors choke on the very long micro-second precision int, overflow, and turn `7d`, around `604800` seconds into `-114753536` seconds, which the browser happily (and correctly) turns into a cookie sent to /dev/null. lol.
This commit is contained in:
Roberto Hidalgo 2023-02-11 12:01:04 -06:00
parent e57ebc7108
commit 038e09b202
8 changed files with 120 additions and 28 deletions

View File

@ -130,30 +130,30 @@
</div>
</header>
<form action="/api/user/:id" class="user-info-panel-details hidden">
<label for="name">Nombre</label>
<input name="name" value="" placeholder="João Gilberto" required />
<label for="edit-name">Nombre</label>
<input id="edit-name" name="name" value="" placeholder="João Gilberto" required />
<label for="greeting">Saludo</label>
<input name="greeting" placeholder="Olá Joãzinho!" />
<label for="edit-edit-greeting">Saludo</label>
<input id="edit-greeting" name="greeting" placeholder="Olá Joãzinho!" />
<label for="password">Password</label>
<input type="password" name="password" />
<label for="edit-password">Password</label>
<input id="edit-password" type="password" name="password" />
<label for="schedule">Horarios</label>
<input type="text" name="schedule" placeholder="days=1-5 hours=8-20:35" autocorrect="off"/>
<label for="edit-schedule">Horarios</label>
<input id="edit-schedule" type="text" name="schedule" placeholder="days=1-5 hours=8-20:35" autocorrect="off"/>
<label for="expires">Expires</label>
<input type="datetime-local" name="expires" placeholder="2023-01-01T00:00:00Z" />
<label for="edit-expires">Expires</label>
<input id="edit-expires" type="datetime-local" name="expires" placeholder="2023-01-01T00:00:00Z" />
<label for="ttl">TTL</label>
<input type="text" name="max_ttl" placeholder="30d" autocorrect="off"/>
<label for="edit-ttl">TTL</label>
<input id="edit-max_ttl" type="text" name="max_ttl" placeholder="30d" autocorrect="off"/>
<div>
<input type="checkbox" name="is_admin" /><label for="admin">Admin?</label>
<input id="edit-is_admin" type="checkbox" name="is_admin" /><label for="edit-admin">Admin?</label>
</div>
<div>
<input type="checkbox" name="second_factor" /><label for="admin">Requiere 2FA?</label>
<input id="edit-second_factor" type="checkbox" name="second_factor" /><label for="edit-second_factor">Requiere 2FA?</label>
</div>
<div id="actions">

View File

@ -9,6 +9,7 @@
<link rel="stylesheet" href="https://cdn.rob.mx/css/fonts.css" />
<link rel="stylesheet" href="https://cdn.rob.mx/nidito/index.css" />
<link rel="stylesheet" href="/static/index.css" />
<!-- link rel="manifest" href="/static/manifest.webmanifest" /-->
</head>
<body>
<header id="main-header">

View File

@ -9,6 +9,7 @@
<link rel="stylesheet" href="https://cdn.rob.mx/css/fonts.css" />
<link rel="stylesheet" href="https://cdn.rob.mx/nidito/index.css" />
<link rel="stylesheet" href="/static/index.css" />
<!--link rel="manifest" href="/static/manifest.webmanifest" /-->
</head>
<body>
<header id="main-header">
@ -19,12 +20,12 @@
</header>
<main class="container">
<form id="login" method="post" action="/api/login">
<span class="error"></span>
<h2 class="error"></h2>
<label for="user">Usuario</label>
<input type="text" name="user" autocorrect="false" />
<input id="user" type="text" name="user" autocorrect="false" />
<label for="password">Password</label>
<input type="password" name="password" />
<input id="password" type="password" name="password" />
<button id="auth" type="submit">Iniciar Sesión</button>
</form>
</main>

View File

@ -11,6 +11,10 @@ button {
transition: all ease-in-out .5s;
}
.container {
box-sizing: border-box;
}
#rex {
font-size: 5em;
border-radius: 100%;
@ -76,13 +80,16 @@ input[type=checkbox] {
height: .8em;
}
@media screen and (max-width: 768px) {
input {
max-width: auto;
}
}
.hidden {
display: none
}
@media screen and (max-width: 768px) {
input {
max-width: 100%;
}
button {
max-width: 100%;
}
}

View File

@ -0,0 +1,15 @@
{
"background_color": "#ffc6d7",
"description": "Abre la puerta del Castillo de Chapultebob",
"display": "fullscreen",
"icons": [
{
"src": "static/icon@192.png",
"sizes": "192x192",
"type": "image/png"
}
],
"name": "Puerta Nidito",
"short_name": "Puerta",
"start_url": "/"
}

View File

@ -6,13 +6,12 @@ importScripts(
workbox.loadModule('workbox-strategies');
self.addEventListener("install", event => {
console.log("Service worker installed");
const urlsToCache = ["/login", "/", "index.css", "/index.js", "/login.js", "/webauthn.js"];
event.waitUntil(
caches.open("pwa-assets")
caches.open("assets")
.then(cache => {
return cache.addAll(urlsToCache);
})

View File

@ -66,7 +66,7 @@ func (ttl *TTL) Scan(value any) error {
}
}
if value == "" {
if src == "" {
return nil
}
@ -99,7 +99,7 @@ func (ttl *TTL) FromNow() time.Time {
}
func (ttl *TTL) Seconds() int {
return int(ttl.duration)
return int(ttl.duration.Seconds())
}
var _ sql.Scanner = &TTL{}

69
internal/user/ttl_test.go Normal file
View File

@ -0,0 +1,69 @@
package user_test
import (
"fmt"
"testing"
"git.rob.mx/nidito/puerta/internal/user"
)
func TestParse(t *testing.T) {
ttl := user.TTL{}
err := ttl.Scan("")
if err != nil {
t.Fatalf("Failed scanning empty string: %s", err)
}
err = ttl.Scan("7d")
if err != nil {
t.Fatalf("Failed scanning 7d: %s", err)
}
if ttl.Seconds() != 604800 {
t.Fatalf("parsed bad seconds %d", ttl.Seconds())
}
// conn := sqlite.ConnectionURL{
// Database: "test.db",
// Options: map[string]string{
// "_journal": "WAL",
// "_busy_timeout": "5000",
// },
// }
// _db, err := sqlite.Open(conn)
// if err != nil {
// t.Fatal(err)
// }
// user := &user.User{}
// if err := _db.Get(user, db.Cond{"handle": "test"}); err != nil {
// t.Fatalf("could not get user: %s", err)
// }
// t.Fatalf("user ttl (%v): %d, from now: %s", user.TTL, user.TTL.Seconds(), user.TTL.FromNow())
}
func TestMarshalDB(t *testing.T) {
ttl := user.TTL{}
err := ttl.Scan("7d")
if err != nil {
t.Fatalf("Failed scanning 7d: %s", err)
}
if ttl.Seconds() != 60*60*24*7 {
t.Fatalf("parsed bad seconds %d", ttl.Seconds())
}
data, err := ttl.MarshalDB()
if err != nil {
t.Fatalf("could not marshal ttl %s", err)
}
expected := `"7d"`
if fmt.Sprintf("%s", data) != expected {
t.Fatalf("encoded data mismatch. expected %s, got %s", expected, data)
}
}