Module: MixinBot::API::Pin

Included in:
MixinBot::API
Defined in:
lib/mixin_bot/api/pin.rb

Instance Method Summary collapse

Instance Method Details

#decrypt_pin(msg) ⇒ Object



64
65
66
# File 'lib/mixin_bot/api/pin.rb', line 64

def decrypt_pin(msg)
  MixinBot.utils.decrypt_pin msg, shared_key: generate_shared_key_with_server
end

#encrypt_pin(pin, iterator: nil) ⇒ Object



60
61
62
# File 'lib/mixin_bot/api/pin.rb', line 60

def encrypt_pin(pin, iterator: nil)
  MixinBot.utils.encrypt_pin(pin, iterator:, shared_key: generate_shared_key_with_server)
end

#generate_shared_key_with_serverObject



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/mixin_bot/api/pin.rb', line 68

def generate_shared_key_with_server
  if config.server_public_key.size == 32
    JOSE::JWA::X25519.x25519(
      config.session_private_key_curve25519,
      config.server_public_key_curve25519
    )
  else
    JOSE::JWA::PKCS1.rsaes_oaep_decrypt(
      'SHA256',
      config.server_public_key,
      OpenSSL::PKey::RSA.new(config.session_private_key),
      session_id
    )
  end
end

#prepare_tip_key(counter = 0) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/mixin_bot/api/pin.rb', line 48

def prepare_tip_key(counter = 0)
  ed25519_key = JOSE::JWA::Ed25519.keypair

  private_key = ed25519_key[1].unpack1('H*')
  public_key = (ed25519_key[0].bytes + MixinBot::Utils.encode_uint_64(counter + 1)).pack('c*').unpack1('H*')

  {
    private_key:,
    public_key:
  }
end

#update_pin(pin:, old_pin: nil) ⇒ Object

Raises:



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/mixin_bot/api/pin.rb', line 32

def update_pin(pin:, old_pin: nil)
  old_pin ||= MixinBot.config.pin
  raise ArgumentError, 'invalid old pin' if old_pin.present? && old_pin.length != 6

  path = '/pin/update'
  encrypted_old_pin = old_pin.nil? ? '' : encrypt_pin(old_pin, iterator: Time.now.utc.to_i)

  encrypted_pin = encrypt_pin(pin, iterator: Time.now.utc.to_i + 1)
  payload = {
    old_pin_base64: encrypted_old_pin,
    pin_base64: encrypted_pin
  }

  client.post path, **payload
end

#verify_pin(pin = nil) ⇒ Object

Raises:



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/mixin_bot/api/pin.rb', line 7

def verify_pin(pin = nil)
  pin ||= MixinBot.config.pin
  raise ArgumentError, 'invalid pin' if pin.blank?

  path = '/pin/verify'

  payload =
    if pin.length > 6
      timestamp = (Time.now.utc.to_f * 1e9).to_i
      pin_base64 = encrypt_tip_pin pin, 'TIP:VERIFY:', timestamp.to_s.rjust(32, '0')

      {
        pin_base64:,
        timestamp:
      }
    else
      {
        pin: MixinBot.utils.encrypt_pin(pin)
      }
    end

  client.post path, **payload
end