diff options
| author | t <t@tjp.lol> | 2026-06-13 14:24:31 -0600 |
|---|---|---|
| committer | t <t@tjp.lol> | 2026-06-15 15:08:32 -0600 |
| commit | 20e6e08a42240aef0b36ecf627cbcde921912071 (patch) | |
| tree | fd7e1f860f28ffa41d33416fb6277a95e530191e /src/auth_manager.zig | |
| parent | fbee69ca8c4b485b7b2d6fe7448b13367c4716c8 (diff) | |
auth: flatten [auth.<name>] config + ${...} substitution
Collapse the auth schema: infer `type` from keys, replace key/key_env_var with
a single `key` (resolved via substitution), flatten the exchange to flat
`exchange_*` keys, and drop the auth-level headers tables in favor of reusing
the provider's `extra_headers` on the auth HTTP calls. Add `${sibling}` and
`${env:VAR}` substitution over auth values (GitHub Enterprise = set `domain`).
Restore api_key-empty → provider-drop. Update default config, docs, and tests.
Diffstat (limited to 'src/auth_manager.zig')
| -rw-r--r-- | src/auth_manager.zig | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/auth_manager.zig b/src/auth_manager.zig index 87b20ae..e26e28a 100644 --- a/src/auth_manager.zig +++ b/src/auth_manager.zig @@ -95,7 +95,10 @@ pub const AuthManager = struct { .oauth_device => |oauth| { _ = self.cred_arena.reset(.retain_capacity); const arena = self.cred_arena.allocator(); - const cred = try self.resolveOAuth(arena, oauth, prov.auth_name, force, presenter); + // The provider's identity headers ride on every auth HTTP call + // (exchange/device/poll), the same way they ride on the model + // request. + const cred = try self.resolveOAuth(arena, oauth, prov.auth_name, prov.extra_headers, force, presenter); try patchCredential(live, prov, cred, arena); }, } @@ -109,6 +112,7 @@ pub const AuthManager = struct { arena: Allocator, oauth: panto.OAuthDeviceAuth, name: []const u8, + headers: []const panto.Header, force: bool, presenter: ?panto.Presenter, ) anyerror!panto.ResolvedCredential { @@ -120,7 +124,7 @@ pub const AuthManager = struct { // Working token set; strings borrow from `loaded` or `arena`. var ts: panto.TokenSet = if (loaded) |l| l.value else blk: { const p = presenter orelse return Error.LoginRequired; - const toks = try panto.oauthLogin(arena, self.io, self.client, oauth, p); + const toks = try panto.oauthLogin(arena, self.io, self.client, oauth, p, headers); const fresh = try panto.tokensToTokenSet(arena, oauth, toks, now); try self.saveToken(name, fresh); break :blk fresh; @@ -128,7 +132,7 @@ pub const AuthManager = struct { // Refresh the access token if it's near expiry (or forced). if ((force or panto.needsRefresh(ts, now, refresh_margin_secs)) and ts.refresh_token != null) { - const toks = try panto.refreshTokens(arena, self.client, oauth, ts.refresh_token.?); + const toks = try panto.refreshTokens(arena, self.client, oauth, ts.refresh_token.?, headers); var refreshed = try panto.tokensToTokenSet(arena, oauth, toks, now); // Refresh responses may omit the refresh token / id_token; keep // the prior values so the session stays renewable. @@ -144,7 +148,7 @@ pub const AuthManager = struct { if (oauth.exchange) |exchange| { if (force or panto.needsExchange(oauth, ts, now, refresh_margin_secs)) { const access = ts.access_token orelse return Error.LoginRequired; - const ex = try panto.runExchange(arena, self.client, exchange, access); + const ex = try panto.runExchange(arena, self.client, exchange, access, headers); ts.exchange = ex; try self.saveToken(name, ts); } |
