summaryrefslogtreecommitdiffhomepage
path: root/lib/dispatch/adapter/claude/token_store.rb
blob: 88f90d0bb9aa3d1aaed754f39aed1903413e9a3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# frozen_string_literal: true

module Dispatch
  module Adapter
    class Claude < Base
      class TokenStore
        DEFAULT_PATH = File.join(Dir.home, ".config", "dispatch", "claude_oauth.json")

        def initialize(path: DEFAULT_PATH)
          @path = path
        end

        attr_reader :path

        def load
          return nil unless File.exist?(@path)

          File.open(@path, "r") do |f|
            f.flock(File::LOCK_SH)
            JSON.parse(f.read)
          end
        rescue JSON::ParserError
          nil
        end

        def save(creds)
          FileUtils.mkdir_p(File.dirname(@path))
          tmp = "#{@path}.#{Process.pid}.#{Thread.current.object_id}.#{SecureRandom.hex(4)}.tmp"
          File.open(tmp, File::RDWR | File::CREAT, 0o600) do |f|
            f.flock(File::LOCK_EX)
            f.truncate(0)
            f.write(JSON.pretty_generate(creds))
            f.flush
          end
          File.rename(tmp, @path)
          File.chmod(0o600, @path)
        ensure
          File.delete(tmp) if tmp && File.exist?(tmp)
        end

        def delete
          FileUtils.rm_f(@path)
        end
      end
    end
  end
end