diff options
| -rw-r--r-- | flake.nix | 2 | ||||
| -rw-r--r-- | roseh.moe.go | 61 |
2 files changed, 48 insertions, 15 deletions
@@ -48,7 +48,7 @@ # remember to bump this hash when your dependencies change. # vendorHash = pkgs.lib.fakeHash; - vendorHash = "sha256-1SZw/xXJS5Vz4ZxD4M+DiILSbOgl72ME6L05cxtvb24="; + vendorHash = "sha256-/Ciog57YcusaM8PvTRnBgxKcbNgxot4R8PhImu5m3Us="; }; }); diff --git a/roseh.moe.go b/roseh.moe.go index 5c88422..64d5e83 100644 --- a/roseh.moe.go +++ b/roseh.moe.go @@ -346,25 +346,59 @@ func verify(msg []byte) ([]byte, bool) { return msg, true } -func makeToken() (string, error) { - b, err := time.Now().MarshalBinary() - if err != nil { - return "", err +func marshalInt(x int64) []byte { + ux := uint64(x) << 1 + if x < 0 { + ux = ^ux + } + buf := make([]byte, 8) + binary.BigEndian.PutUint64(buf, ux) + for len(buf) > 0 && buf[0] == 0 { + buf = buf[1:] + } + return buf +} + +func unmarshalInt(b []byte) (int64, bool) { + if len(b) > 8 { + return 0, false + } + buf := make([]byte, 8) + copy(buf[8-len(b):], b) + ux := binary.BigEndian.Uint64(buf) + x := int64(ux >> 1) + if ux&1 != 0 { + x = ^x + } + return x, true +} + +const yearOffset = 2089 + +func marshalTime(t time.Time) []byte { + year, month, day := t.UTC().Date() + return marshalInt((int64(year)-yearOffset)<<9 | int64(month)<<5 | int64(day)) +} + +func unmarshalTime(b []byte) (time.Time, bool) { + n, ok := unmarshalInt(b) + if !ok { + return time.Time{}, false } - return base64.RawURLEncoding.EncodeToString(sign(b)), nil + return time.Date(int(n>>9+yearOffset), time.Month(n>>5&0xf), int(n&0x1f), 0, 0, 0, 0, time.UTC), true +} + +func makeToken() string { + return base64.RawURLEncoding.EncodeToString(sign(marshalTime(time.Now()))) } const cookieExpiration = 7 * 24 * time.Hour const authCookieName = "roseh.moe.auth" -func attachCookie(w http.ResponseWriter) error { - token, err := makeToken() - if err != nil { - return err - } +func attachCookie(w http.ResponseWriter) { http.SetCookie(w, &http.Cookie{ Name: authCookieName, - Value: token, + Value: makeToken(), Path: "/", Domain: *domain, Expires: time.Now().Add(cookieExpiration), @@ -373,7 +407,6 @@ func attachCookie(w http.ResponseWriter) error { SameSite: http.SameSiteStrictMode, Partitioned: true, }) - return nil } func cookieAuth(w http.ResponseWriter, r *http.Request) bool { @@ -389,8 +422,8 @@ func cookieAuth(w http.ResponseWriter, r *http.Request) bool { if !ok { return false } - var t time.Time - if err := t.UnmarshalBinary(msg); err != nil { + t, ok := unmarshalTime(msg) + if !ok { return false } cookieAge := time.Since(t) |
