diff --git a/lua/pending/init.lua b/lua/pending/init.lua index 1e05c36..446d375 100644 --- a/lua/pending/init.lua +++ b/lua/pending/init.lua @@ -828,6 +828,24 @@ function M.edit(id_str, rest) log.info('Task #' .. id .. ' updated: ' .. table.concat(feedback, ', ')) end +---@return nil +function M.auth() + local oauth = require('pending.sync.oauth') + vim.ui.select({ 'gtasks', 'gcal', 'both' }, { + prompt = 'Authenticate:', + }, function(choice) + if not choice then + return + end + local creds = oauth.google_client:resolve_credentials() + if creds.client_id == oauth.BUNDLED_CLIENT_ID then + oauth.google_client:setup() + else + oauth.google_client:auth() + end + end) +end + ---@param args string ---@return nil function M.command(args) @@ -841,6 +859,8 @@ function M.command(args) elseif cmd == 'edit' then local id_str, edit_rest = rest:match('^(%S+)%s*(.*)') M.edit(id_str, edit_rest) + elseif cmd == 'auth' then + M.auth() elseif SYNC_BACKEND_SET[cmd] then local action = rest:match('^(%S+)') run_sync(cmd, action) diff --git a/lua/pending/sync/gcal.lua b/lua/pending/sync/gcal.lua index bddb461..99b9e76 100644 --- a/lua/pending/sync/gcal.lua +++ b/lua/pending/sync/gcal.lua @@ -7,14 +7,6 @@ local M = {} M.name = 'gcal' local BASE_URL = 'https://www.googleapis.com/calendar/v3' -local SCOPE = 'https://www.googleapis.com/auth/calendar' - -local client = oauth.new({ - name = 'gcal', - scope = SCOPE, - port = 18392, - config_key = 'gcal', -}) ---@param access_token string ---@return table? name_to_id @@ -139,15 +131,15 @@ end ---@param callback fun(access_token: string): nil local function with_token(callback) oauth.async(function() - local token = client:get_access_token() + local token = oauth.google_client:get_access_token() if not token then - client:auth(function() + oauth.google_client:auth(function() oauth.async(function() - local fresh = client:get_access_token() + local fresh = oauth.google_client:get_access_token() if fresh then callback(fresh) else - log.error(client.name .. ': authorization failed or was cancelled') + log.error(oauth.google_client.name .. ': authorization failed or was cancelled') end end) end) @@ -157,14 +149,6 @@ local function with_token(callback) end) end -function M.setup() - client:setup() -end - -function M.auth() - client:auth() -end - function M.push() with_token(function(access_token) local calendars, cal_err = get_all_calendars(access_token) diff --git a/lua/pending/sync/gtasks.lua b/lua/pending/sync/gtasks.lua index d1ae10f..d747c51 100644 --- a/lua/pending/sync/gtasks.lua +++ b/lua/pending/sync/gtasks.lua @@ -7,14 +7,6 @@ local M = {} M.name = 'gtasks' local BASE_URL = 'https://tasks.googleapis.com/tasks/v1' -local SCOPE = 'https://www.googleapis.com/auth/tasks' - -local client = oauth.new({ - name = 'gtasks', - scope = SCOPE, - port = 18393, - config_key = 'gtasks', -}) ---@param access_token string ---@return table? name_to_id @@ -355,15 +347,15 @@ end ---@param callback fun(access_token: string): nil local function with_token(callback) oauth.async(function() - local token = client:get_access_token() + local token = oauth.google_client:get_access_token() if not token then - client:auth(function() + oauth.google_client:auth(function() oauth.async(function() - local fresh = client:get_access_token() + local fresh = oauth.google_client:get_access_token() if fresh then callback(fresh) else - log.error(client.name .. ': authorization failed or was cancelled') + log.error(oauth.google_client.name .. ': authorization failed or was cancelled') end end) end) @@ -373,14 +365,6 @@ local function with_token(callback) end) end -function M.setup() - client:setup() -end - -function M.auth() - client:auth() -end - function M.push() with_token(function(access_token) local tasklists, s, now_ts = sync_setup(access_token) @@ -462,11 +446,11 @@ M._gtask_to_fields = gtask_to_fields ---@return nil function M.health() oauth.health(M.name) - local tokens = client:load_tokens() + local tokens = oauth.google_client:load_tokens() if tokens and tokens.refresh_token then vim.health.ok('gtasks tokens found') else - vim.health.info('no gtasks tokens — run :Pending gtasks auth') + vim.health.info('no gtasks tokens — run :Pending auth') end end diff --git a/lua/pending/sync/oauth.lua b/lua/pending/sync/oauth.lua index cb490e4..30a46e7 100644 --- a/lua/pending/sync/oauth.lua +++ b/lua/pending/sync/oauth.lua @@ -501,5 +501,14 @@ end M._BUNDLED_CLIENT_ID = BUNDLED_CLIENT_ID M._BUNDLED_CLIENT_SECRET = BUNDLED_CLIENT_SECRET +M.BUNDLED_CLIENT_ID = BUNDLED_CLIENT_ID + +M.google_client = M.new({ + name = 'google', + scope = 'https://www.googleapis.com/auth/tasks' + .. ' https://www.googleapis.com/auth/calendar', + port = 18392, + config_key = 'google', +}) return M diff --git a/plugin/pending.lua b/plugin/pending.lua index f6ed6bb..cba4916 100644 --- a/plugin/pending.lua +++ b/plugin/pending.lua @@ -167,7 +167,7 @@ end, { nargs = '*', complete = function(arg_lead, cmd_line) local pending = require('pending') - local subcmds = { 'add', 'archive', 'due', 'edit', 'filter', 'undo' } + local subcmds = { 'add', 'archive', 'auth', 'due', 'edit', 'filter', 'undo' } for _, b in ipairs(pending.sync_backends()) do table.insert(subcmds, b) end diff --git a/spec/sync_spec.lua b/spec/sync_spec.lua index 20a85c1..a491dd3 100644 --- a/spec/sync_spec.lua +++ b/spec/sync_spec.lua @@ -73,15 +73,14 @@ describe('sync', function() assert.is_true(called) end) - it('routes auth action', function() + it('routes auth command', function() local called = false - local gcal = require('pending.sync.gcal') - local orig_auth = gcal.auth - gcal.auth = function() + local orig_auth = pending.auth + pending.auth = function() called = true end - pending.command('gcal auth') - gcal.auth = orig_auth + pending.command('auth') + pending.auth = orig_auth assert.is_true(called) end) end) @@ -102,11 +101,6 @@ describe('sync', function() assert.are.equal('gcal', gcal.name) end) - it('has auth function', function() - local gcal = require('pending.sync.gcal') - assert.are.equal('function', type(gcal.auth)) - end) - it('has push function', function() local gcal = require('pending.sync.gcal') assert.are.equal('function', type(gcal.push))