atproto utils for zig
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

replace libc gettimeofday with Io.Timestamp in jwt/oauth

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

zzstoatzz 9e375b5c 261dcc50

+14 -15
+1
.gitignore
··· 1 1 .zig-cache/ 2 2 zig-out/ 3 + zig-pkg/ 3 4 .env 4 5 .env.* 5 6
+1 -1
build.zig.zon
··· 1 1 .{ 2 2 .name = .zat, 3 - .version = "0.3.0-alpha.6", 3 + .version = "0.3.0-alpha.7", 4 4 .fingerprint = 0x8da9db57ee82fbe4, 5 5 .minimum_zig_version = "0.16.0", 6 6 .dependencies = .{
+7 -8
src/internal/crypto/jwt.zig
··· 7 7 8 8 const std = @import("std"); 9 9 const crypto = std.crypto; 10 + const Io = std.Io; 10 11 const json = @import("../xrpc/json.zig"); 11 12 const multibase = @import("multibase.zig"); 12 13 const multicodec = @import("multicodec.zig"); 13 14 14 - fn timestamp() i64 { 15 - var tv: std.c.timeval = undefined; 16 - _ = std.c.gettimeofday(&tv, null); 17 - return tv.sec; 15 + fn timestamp(io: Io) i64 { 16 + return @intCast(@divFloor(Io.Timestamp.now(io, .real).nanoseconds, std.time.ns_per_s)); 18 17 } 19 18 20 19 /// JWT signing algorithm ··· 145 144 } 146 145 147 146 /// check if the token is expired 148 - pub fn isExpired(self: *const Jwt) bool { 149 - const now = timestamp(); 147 + pub fn isExpired(self: *const Jwt, io: Io) bool { 148 + const now = timestamp(io); 150 149 return now > self.payload.exp; 151 150 } 152 151 153 152 /// check if the token is expired with clock skew tolerance (in seconds) 154 - pub fn isExpiredWithSkew(self: *const Jwt, skew_seconds: i64) bool { 155 - const now = timestamp(); 153 + pub fn isExpiredWithSkew(self: *const Jwt, io: Io, skew_seconds: i64) bool { 154 + const now = timestamp(io); 156 155 return now > (self.payload.exp + skew_seconds); 157 156 } 158 157
+5 -6
src/internal/oauth.zig
··· 7 7 8 8 const std = @import("std"); 9 9 const crypto = std.crypto; 10 + const Io = std.Io; 10 11 const Allocator = std.mem.Allocator; 11 12 const Keypair = @import("crypto/keypair.zig").Keypair; 12 13 const jwt = @import("crypto/jwt.zig"); 13 14 14 - fn timestamp() i64 { 15 - var tv: std.c.timeval = undefined; 16 - _ = std.c.gettimeofday(&tv, null); 17 - return tv.sec; 15 + fn timestamp(io: Io) i64 { 16 + return @intCast(@divFloor(Io.Timestamp.now(io, .real).nanoseconds, std.time.ns_per_s)); 18 17 } 19 18 20 19 /// create a signed JWT from header and payload JSON strings. ··· 55 54 defer allocator.free(jti); 56 55 57 56 const alg = @tagName(keypair.algorithm()); 58 - const now = timestamp(); 57 + const now = timestamp(io); 59 58 60 59 // header: {"typ":"dpop+jwt","alg":"...","jwk":{...}} 61 60 const header = try std.fmt.allocPrint(allocator, ··· 99 98 defer allocator.free(kid); 100 99 101 100 const alg = @tagName(keypair.algorithm()); 102 - const now = timestamp(); 101 + const now = timestamp(io); 103 102 104 103 const header = try std.fmt.allocPrint(allocator, 105 104 \\{{"typ":"JWT","alg":"{s}","kid":"{s}"}}