summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--flake.nix2
-rw-r--r--roseh.moe.go61
2 files changed, 48 insertions, 15 deletions
diff --git a/flake.nix b/flake.nix
index ad0970c..6fa885a 100644
--- a/flake.nix
+++ b/flake.nix
@@ -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)