fix(sync): auto-trigger auth flow on unauthenticated sync actions (#120)
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
422f8f9b05
commit
149f2dac2e
5 changed files with 256 additions and 5 deletions
|
|
@ -232,4 +232,98 @@ describe('oauth', function()
|
|||
assert.equals('test', c.config_key)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('with_token', function()
|
||||
it('auto-triggers auth when not authenticated', function()
|
||||
local c = oauth.new({ name = 'test_auth', scope = 'x', port = 0, config_key = 'gtasks' })
|
||||
local call_count = 0
|
||||
c.get_access_token = function()
|
||||
call_count = call_count + 1
|
||||
if call_count == 1 then
|
||||
return nil
|
||||
end
|
||||
return 'new-token'
|
||||
end
|
||||
c.resolve_credentials = function()
|
||||
return { client_id = 'real-id', client_secret = 'real-secret' }
|
||||
end
|
||||
local auth_called = false
|
||||
c.auth = function(_, on_complete)
|
||||
auth_called = true
|
||||
vim.schedule(function()
|
||||
on_complete(true)
|
||||
end)
|
||||
end
|
||||
local received_token
|
||||
oauth.with_token(c, 'test_auth', function(token)
|
||||
received_token = token
|
||||
end)
|
||||
vim.wait(1000, function()
|
||||
return received_token ~= nil
|
||||
end)
|
||||
assert.is_true(auth_called)
|
||||
assert.equals('new-token', received_token)
|
||||
end)
|
||||
|
||||
it('bails on bundled credentials without calling auth', function()
|
||||
local c = oauth.new({ name = 'test_bail', scope = 'x', port = 0, config_key = 'gtasks' })
|
||||
c.get_access_token = function()
|
||||
return nil
|
||||
end
|
||||
c.resolve_credentials = function()
|
||||
return { client_id = oauth.BUNDLED_CLIENT_ID, client_secret = 'x' }
|
||||
end
|
||||
local auth_called = false
|
||||
c.auth = function()
|
||||
auth_called = true
|
||||
end
|
||||
local callback_called = false
|
||||
oauth.with_token(c, 'test_bail', function()
|
||||
callback_called = true
|
||||
end)
|
||||
vim.wait(500, function()
|
||||
return false
|
||||
end)
|
||||
assert.is_false(auth_called)
|
||||
assert.is_false(callback_called)
|
||||
end)
|
||||
|
||||
it('stops when auth fails', function()
|
||||
local c = oauth.new({ name = 'test_fail', scope = 'x', port = 0, config_key = 'gtasks' })
|
||||
c.get_access_token = function()
|
||||
return nil
|
||||
end
|
||||
c.resolve_credentials = function()
|
||||
return { client_id = 'real-id', client_secret = 'real-secret' }
|
||||
end
|
||||
c.auth = function(_, on_complete)
|
||||
vim.schedule(function()
|
||||
on_complete(false)
|
||||
end)
|
||||
end
|
||||
local callback_called = false
|
||||
oauth.with_token(c, 'test_fail', function()
|
||||
callback_called = true
|
||||
end)
|
||||
vim.wait(500, function()
|
||||
return false
|
||||
end)
|
||||
assert.is_false(callback_called)
|
||||
end)
|
||||
|
||||
it('proceeds directly when already authenticated', function()
|
||||
local c = oauth.new({ name = 'test_ok', scope = 'x', port = 0, config_key = 'gtasks' })
|
||||
c.get_access_token = function()
|
||||
return 'existing-token'
|
||||
end
|
||||
local received_token
|
||||
oauth.with_token(c, 'test_ok', function(token)
|
||||
received_token = token
|
||||
end)
|
||||
vim.wait(1000, function()
|
||||
return received_token ~= nil
|
||||
end)
|
||||
assert.equals('existing-token', received_token)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue