diff --git a/lua/pending/sync/gcal.lua b/lua/pending/sync/gcal.lua index 2ae5e05..69c175d 100644 --- a/lua/pending/sync/gcal.lua +++ b/lua/pending/sync/gcal.lua @@ -136,17 +136,31 @@ local function delete_event(access_token, calendar_id, event_id) return err end +---@param callback fun(access_token: string): nil +local function with_token(callback) + oauth.async(function() + local token = client:get_access_token() + if not token then + client:auth(function() + oauth.async(function() + local fresh = client:get_access_token() + if fresh then + callback(fresh) + end + end) + end) + return + end + callback(token) + end) +end + function M.auth() client:auth() end function M.push() - oauth.async(function() - local access_token = client:get_access_token() - if not access_token then - return - end - + with_token(function(access_token) local calendars, cal_err = get_all_calendars(access_token) if cal_err or not calendars then log.error(cal_err or 'failed to fetch calendars') diff --git a/lua/pending/sync/gtasks.lua b/lua/pending/sync/gtasks.lua index f627eb7..d383c77 100644 --- a/lua/pending/sync/gtasks.lua +++ b/lua/pending/sync/gtasks.lua @@ -337,23 +337,38 @@ local function pull_pass(access_token, tasklists, s, now_ts, by_gtasks_id) return created, updated end ----@return string? access_token +---@param access_token string ---@return table? tasklists ----@return pending.Store? store +---@return pending.Store? s ---@return string? now_ts -local function sync_setup() - local access_token = client:get_access_token() - if not access_token then - return nil - end +local function sync_setup(access_token) local tasklists, tl_err = get_all_tasklists(access_token) if tl_err or not tasklists then log.error(tl_err or 'failed to fetch task lists') - return nil + return nil, nil, nil end local s = require('pending').store() local now_ts = os.date('!%Y-%m-%dT%H:%M:%SZ') --[[@as string]] - return access_token, tasklists, s, now_ts + return tasklists, s, now_ts +end + +---@param callback fun(access_token: string): nil +local function with_token(callback) + oauth.async(function() + local token = client:get_access_token() + if not token then + client:auth(function() + oauth.async(function() + local fresh = client:get_access_token() + if fresh then + callback(fresh) + end + end) + end) + return + end + callback(token) + end) end function M.auth() @@ -361,12 +376,11 @@ function M.auth() end function M.push() - oauth.async(function() - local access_token, tasklists, s, now_ts = sync_setup() - if not access_token then + with_token(function(access_token) + local tasklists, s, now_ts = sync_setup(access_token) + if not tasklists then return end - ---@cast tasklists table ---@cast s pending.Store ---@cast now_ts string local by_gtasks_id = build_id_index(s) @@ -382,12 +396,11 @@ function M.push() end function M.pull() - oauth.async(function() - local access_token, tasklists, s, now_ts = sync_setup() - if not access_token then + with_token(function(access_token) + local tasklists, s, now_ts = sync_setup(access_token) + if not tasklists then return end - ---@cast tasklists table ---@cast s pending.Store ---@cast now_ts string local by_gtasks_id = build_id_index(s) @@ -403,12 +416,11 @@ function M.pull() end function M.sync() - oauth.async(function() - local access_token, tasklists, s, now_ts = sync_setup() - if not access_token then + with_token(function(access_token) + local tasklists, s, now_ts = sync_setup(access_token) + if not tasklists then return end - ---@cast tasklists table ---@cast s pending.Store ---@cast now_ts string local by_gtasks_id = build_id_index(s) diff --git a/lua/pending/sync/oauth.lua b/lua/pending/sync/oauth.lua index dc9eb5c..88eaf35 100644 --- a/lua/pending/sync/oauth.lua +++ b/lua/pending/sync/oauth.lua @@ -236,11 +236,7 @@ function OAuthClient:get_access_token() local creds = self:resolve_credentials() local tokens = self:load_tokens() if not tokens or not tokens.refresh_token then - self:auth() - tokens = self:load_tokens() - if not tokens then - return nil - end + return nil end local now = os.time() local obtained = tokens.obtained_at or 0 @@ -255,8 +251,9 @@ function OAuthClient:get_access_token() return tokens.access_token end +---@param on_complete? fun(): nil ---@return nil -function OAuthClient:auth() +function OAuthClient:auth(on_complete) local creds = self:resolve_credentials() local port = self.port @@ -329,7 +326,7 @@ function OAuthClient:auth() close_server() if code then vim.schedule(function() - self:_exchange_code(creds, code, code_verifier, port) + self:_exchange_code(creds, code, code_verifier, port, on_complete) end) end end) @@ -347,8 +344,9 @@ end ---@param code string ---@param code_verifier string ---@param port integer +---@param on_complete? fun(): nil ---@return nil -function OAuthClient:_exchange_code(creds, code, code_verifier, port) +function OAuthClient:_exchange_code(creds, code, code_verifier, port, on_complete) local body = 'client_id=' .. M.url_encode(creds.client_id) .. '&client_secret=' @@ -387,6 +385,9 @@ function OAuthClient:_exchange_code(creds, code, code_verifier, port) decoded.obtained_at = os.time() self:save_tokens(decoded) log.info(self.name .. ' authorized successfully.') + if on_complete then + on_complete() + end end ---@param opts { name: string, scope: string, port: integer, config_key: string }