Problem: running a sync action (e.g. `:Pending gtasks push`) without being authenticated would silently abort with a warning, requiring the user to manually run `:Pending auth` first. Solution: `oauth.with_token()` now auto-triggers the browser auth flow when no token exists (for non-bundled credentials) and resumes the original action on success. `auth()` and `_exchange_code()` now call `on_complete(ok)` on all exit paths. S3 backends run `aws sts get-caller-identity` before every sync action, auto-triggering SSO login on expired sessions.
This commit is contained in:
parent
dbf0ab1221
commit
625ee01074
5 changed files with 256 additions and 5 deletions
|
|
@ -45,8 +45,28 @@ function M.with_token(client, name, callback)
|
|||
util.with_guard(name, function()
|
||||
local token = client:get_access_token()
|
||||
if not token then
|
||||
require('pending.log').warn(name .. ': Not authenticated — run :Pending auth.')
|
||||
return
|
||||
local creds = client:resolve_credentials()
|
||||
if creds.client_id == BUNDLED_CLIENT_ID then
|
||||
log.warn(name .. ': No credentials configured — run :Pending auth.')
|
||||
return
|
||||
end
|
||||
log.info(name .. ': Not authenticated — starting auth flow...')
|
||||
local co = coroutine.running()
|
||||
client:auth(function(ok)
|
||||
vim.schedule(function()
|
||||
coroutine.resume(co, ok)
|
||||
end)
|
||||
end)
|
||||
local auth_ok = coroutine.yield()
|
||||
if not auth_ok then
|
||||
log.error(name .. ': Authentication failed.')
|
||||
return
|
||||
end
|
||||
token = client:get_access_token()
|
||||
if not token then
|
||||
log.error(name .. ': Still not authenticated after auth flow.')
|
||||
return
|
||||
end
|
||||
end
|
||||
callback(token)
|
||||
end)
|
||||
|
|
@ -349,7 +369,7 @@ function OAuthClient:setup()
|
|||
end)
|
||||
end
|
||||
|
||||
---@param on_complete? fun(): nil
|
||||
---@param on_complete? fun(ok: boolean): nil
|
||||
---@return nil
|
||||
function OAuthClient:auth(on_complete)
|
||||
if _active_close then
|
||||
|
|
@ -360,6 +380,9 @@ function OAuthClient:auth(on_complete)
|
|||
local creds = self:resolve_credentials()
|
||||
if creds.client_id == BUNDLED_CLIENT_ID then
|
||||
log.error(self.name .. ': No credentials configured — run :Pending auth.')
|
||||
if on_complete then
|
||||
on_complete(false)
|
||||
end
|
||||
return
|
||||
end
|
||||
local port = self.port
|
||||
|
|
@ -411,6 +434,9 @@ function OAuthClient:auth(on_complete)
|
|||
if not bind_ok or bind_err == nil then
|
||||
close_server()
|
||||
log.error(self.name .. ': Port ' .. port .. ' already in use — try again in a moment.')
|
||||
if on_complete then
|
||||
on_complete(false)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -453,6 +479,9 @@ function OAuthClient:auth(on_complete)
|
|||
if not server_closed then
|
||||
close_server()
|
||||
log.warn(self.name .. ': OAuth callback timed out (120s).')
|
||||
if on_complete then
|
||||
on_complete(false)
|
||||
end
|
||||
end
|
||||
end, 120000)
|
||||
end
|
||||
|
|
@ -461,7 +490,7 @@ end
|
|||
---@param code string
|
||||
---@param code_verifier string
|
||||
---@param port integer
|
||||
---@param on_complete? fun(): nil
|
||||
---@param on_complete? fun(ok: boolean): nil
|
||||
---@return nil
|
||||
function OAuthClient:_exchange_code(creds, code, code_verifier, port, on_complete)
|
||||
local body = 'client_id='
|
||||
|
|
@ -491,6 +520,9 @@ function OAuthClient:_exchange_code(creds, code, code_verifier, port, on_complet
|
|||
if result.code ~= 0 then
|
||||
self:clear_tokens()
|
||||
log.error(self.name .. ': Token exchange failed.')
|
||||
if on_complete then
|
||||
on_complete(false)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -498,6 +530,9 @@ function OAuthClient:_exchange_code(creds, code, code_verifier, port, on_complet
|
|||
if not ok or not decoded.access_token then
|
||||
self:clear_tokens()
|
||||
log.error(self.name .. ': Invalid token response.')
|
||||
if on_complete then
|
||||
on_complete(false)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -505,7 +540,7 @@ function OAuthClient:_exchange_code(creds, code, code_verifier, port, on_complet
|
|||
self:save_tokens(decoded)
|
||||
log.info(self.name .. ': Authorized successfully.')
|
||||
if on_complete then
|
||||
on_complete()
|
||||
on_complete(true)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue