selfsdk 0.0.195 → 0.0.198

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e41a8293552addc1b1de4266ae6116de304f94da70410d0c6edc159e579a6787
4
- data.tar.gz: 974a651863325ae66fd015af0cbcaf95757a79baf90b6336b4a79e15780d824b
3
+ metadata.gz: '07875d6dd8a8786b62dbb757976d48e6254e553f1baba1f6e804ac75c20984a3'
4
+ data.tar.gz: f21a0a69b9342b7f8b68b4c288337413183f57ca662e8bf8bd7ea4f2230e9c28
5
5
  SHA512:
6
- metadata.gz: b53fca4a9a5d211438f38e8c97768b2f84d9513e78adfc10282f1472bd8346e8aa8801659cff543f77d19909bc4588d3f987ca2ee65e909529b48585e5eeabfe
7
- data.tar.gz: 643f600065d4fad7c551bf57fd07ac3f316ac9a1f17f496f11aed4d67ec8618371247c1ce2b742d3d6b9a19525689e4e123328bae6e0db3b55e1b4acd21b7a4a
6
+ metadata.gz: ce37ab428a4e072f413f635114051c5d8b4fb31b96d27f019a8315d09adaec78f3a1a254bdb9511d4feca73c71287f7eb94bdbc521925ec818f51c948fc1de37
7
+ data.tar.gz: 6140b82f58d59acf6a087f8560d182f82f8e925deb6067688c05133807447ece403871fbd62bf045263e70dcda945731440b5c53ed82e68f6f0d6ebcc7d25f46
data/lib/authenticated.rb CHANGED
@@ -14,6 +14,7 @@ module SelfSDK
14
14
 
15
15
  def accepted?
16
16
  return false if @payload.nil?
17
+ return false if @payload[:auth] != true
17
18
 
18
19
  @payload[:status] == "accepted"
19
20
  end
@@ -41,8 +41,7 @@ module SelfSDK
41
41
  ciphertext = URI.open(input[:link], "Authorization" => "Bearer #{@token}").read
42
42
  break
43
43
  rescue => e
44
- SelfSDK.logger.info e.message
45
- SelfSDK.logger.info e.backtrace.join("\n")
44
+ SelfSDK.logger.info "error fetching #{input[:link]} : #{e.message}"
46
45
  sleep 1
47
46
  end
48
47
  end
@@ -24,7 +24,16 @@ module SelfSDK
24
24
  @expected_value = payload[:expected_value]
25
25
  @operator = payload[:operator]
26
26
  @fact_name = name.to_s
27
- unless payload[name].nil?
27
+ if payload[name].nil?
28
+ return if payload[:facts].nil?
29
+
30
+ payload[:facts].each do |f|
31
+ if f[:key] == name.to_s
32
+ @value = f[:value]
33
+ break
34
+ end
35
+ end
36
+ else
28
37
  @value = payload[name]
29
38
  end
30
39
  end
@@ -5,13 +5,14 @@
5
5
  require 'self_msgproto'
6
6
  require_relative 'base'
7
7
  require_relative '../ntptime'
8
- require_relative 'authentication_message'
9
8
 
10
9
  module SelfSDK
11
10
  module Messages
12
- class AuthenticationReq < AuthenticationMessage
13
- MSG_TYPE = "identities.authenticate.req"
14
- DEFAULT_EXP_TIMEOUT = 300
11
+ class ConnectionRequest < Base
12
+ MSG_TYPE = "identities.connections.req"
13
+ DEFAULT_EXP_TIMEOUT = 9000
14
+
15
+ attr_accessor :facts, :options, :auth
15
16
 
16
17
  def initialize(messaging)
17
18
  @typ = MSG_TYPE
@@ -22,34 +23,42 @@ module SelfSDK
22
23
  @id = SecureRandom.uuid
23
24
  @from = @client.jwt.id
24
25
  @to = selfid
25
-
26
- @id = opts[:cid] if opts.include?(:cid)
27
- @description = opts.include?(:description) ? opts[:description] : nil
28
26
  @exp_timeout = opts.fetch(:exp_timeout, DEFAULT_EXP_TIMEOUT)
29
27
  end
30
28
 
29
+ def parse(input, envelope=nil)
30
+ super
31
+ @typ = MSG_TYPE
32
+ @body = @payload[:msg]
33
+ end
34
+
31
35
  def body
32
- { typ: MSG_TYPE,
36
+ {
37
+ typ: MSG_TYPE,
33
38
  iss: @jwt.id,
34
- sub: @to,
35
39
  aud: @to,
40
+ sub: @to,
36
41
  iat: SelfSDK::Time.now.strftime('%FT%TZ'),
37
42
  exp: (SelfSDK::Time.now + @exp_timeout).strftime('%FT%TZ'),
38
- cid: @id,
39
- jti: SecureRandom.uuid }
43
+ jti: SecureRandom.uuid,
44
+ require_confirmation: true,
45
+ }
40
46
  end
41
47
 
42
48
  protected
43
49
 
44
50
  def proto(to_device)
51
+ @to_device = to_device
52
+ recipient = "#{@to}:#{@to_device}"
53
+ ciphertext = encrypt_message(@jwt.prepare(body), [{id: @to, device_id: @to_device}])
54
+
45
55
  m = SelfMsg::Message.new
46
56
  m.id = @id
47
57
  m.sender = "#{@jwt.id}:#{@messaging.device_id}"
48
- m.recipient = "#{@to}:#{to_device}"
49
- m.ciphertext = encrypt_message(@jwt.prepare(body), [{ id: @to, device_id: to_device }])
58
+ m.recipient = recipient
59
+ m.ciphertext = ciphertext
50
60
  m
51
61
  end
52
-
53
62
  end
54
63
  end
55
64
  end
@@ -0,0 +1,52 @@
1
+ # Copyright 2020 Self Group Ltd. All Rights Reserved.
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require 'self_msgproto'
6
+ require_relative 'base'
7
+ require_relative '../ntptime'
8
+
9
+ module SelfSDK
10
+ module Messages
11
+ class ConnectionResponse < Base
12
+ MSG_TYPE = "identities.connections.resp"
13
+ DEFAULT_EXP_TIMEOUT = 900
14
+
15
+ attr_accessor :facts, :options, :auth
16
+
17
+ def initialize(messaging)
18
+ @typ = MSG_TYPE
19
+ super
20
+ end
21
+
22
+ def populate(selfid)
23
+ @id = SecureRandom.uuid
24
+ @from = @client.jwt.id
25
+ @to = selfid
26
+ end
27
+
28
+ def parse(input, envelope=nil)
29
+ @typ = MSG_TYPE
30
+ @payload = get_payload input
31
+ @body = @payload[:msg]
32
+ @status = @payload[:status]
33
+ end
34
+
35
+ def get_payload(input)
36
+ body = if input.is_a? String
37
+ input
38
+ else
39
+ input.ciphertext
40
+ end
41
+
42
+ jwt = JSON.parse(body, symbolize_names: true)
43
+ payload = JSON.parse(@jwt.decode(jwt[:payload]), symbolize_names: true)
44
+ header = JSON.parse(@jwt.decode(jwt[:protected]), symbolize_names: true)
45
+ @from = payload[:iss]
46
+ verify! jwt, header[:kid]
47
+ payload
48
+ end
49
+
50
+ end
51
+ end
52
+ end
data/lib/messages/fact.rb CHANGED
@@ -14,11 +14,15 @@ module SelfSDK
14
14
  end
15
15
 
16
16
  def parse(fact)
17
- @name = @messaging.source.normalize_fact_name! fact[:fact]
17
+ @name = @messaging.source.normalize_fact_name fact[:fact]
18
18
  @operator = @messaging.source.normalize_operator!(fact[:operator])
19
19
  @sources = []
20
20
  fact[:sources]&.each do |s|
21
- @sources << @messaging.source.normalize_source!(s)
21
+ @sources << s.to_s
22
+ end
23
+ @issuers = []
24
+ fact[:issuers]&.each do |i|
25
+ @issuers << i.to_s
22
26
  end
23
27
 
24
28
  @expected_value = fact[:expected_value] || ""
@@ -39,6 +43,7 @@ module SelfSDK
39
43
 
40
44
  def to_hash
41
45
  h = { fact: @name }
46
+ h[:issuers] = @issuers if @issuers.length > 0
42
47
  unless @sources.nil?
43
48
  h[:sources] = @sources if @sources.length > 0
44
49
  end
@@ -0,0 +1,94 @@
1
+ # Copyright 2020 Self Group Ltd. All Rights Reserved.
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require 'self_msgproto'
6
+ require_relative 'base'
7
+ require_relative '../ntptime'
8
+
9
+ module SelfSDK
10
+ module Messages
11
+ class FactIssue < Base
12
+ MSG_TYPE = "identities.facts.issue"
13
+ DEFAULT_EXP_TIMEOUT = 900
14
+
15
+ def initialize(messaging)
16
+ @typ = MSG_TYPE
17
+ super
18
+ end
19
+
20
+ def populate(selfid, facts, opts)
21
+ @id = opts.fetch(:cid, SecureRandom.uuid)
22
+ @exp_timeout = opts.fetch(:exp_timeout, DEFAULT_EXP_TIMEOUT)
23
+ @viewers = opts.fetch(:viewers, nil)
24
+
25
+ @from = @jwt.id
26
+ @to = selfid
27
+ @attestations = build_attestations!(facts)
28
+ end
29
+
30
+ def body
31
+ b = {
32
+ typ: MSG_TYPE,
33
+ iss: @jwt.id,
34
+ aud: @to,
35
+ sub: @to,
36
+ iat: SelfSDK::Time.now.strftime('%FT%TZ'),
37
+ exp: (SelfSDK::Time.now + @exp_timeout).strftime('%FT%TZ'),
38
+ cid: @id,
39
+ jti: SecureRandom.uuid,
40
+ status: 'verified',
41
+ attestations: @attestations
42
+ }
43
+ # viewers
44
+ b[:viewers] = @viewers unless @viewers.nil?
45
+ b
46
+ end
47
+
48
+ protected
49
+
50
+ def proto(to_device)
51
+ @to_device = to_device
52
+ recipient = "#{@to}:#{@to_device}"
53
+ ciphertext = encrypt_message(@jwt.prepare(body), [{id: @to, device_id: @to_device}])
54
+
55
+ m = SelfMsg::Message.new
56
+ m.id = @id
57
+ m.sender = "#{@jwt.id}:#{@messaging.device_id}"
58
+ m.recipient = recipient
59
+ m.ciphertext = ciphertext
60
+ m
61
+ end
62
+
63
+ private
64
+
65
+ def build_attestations!(facts)
66
+ raise 'facts must be provided in the form of an array' unless facts.kind_of?(Array)
67
+
68
+ attestations = []
69
+ facts.each do |fact|
70
+ att = fact.transform_keys(&:to_sym)
71
+ raise 'invalid attestation : does not provide a key' if !att.has_key?(:key) || att[:key].empty?
72
+
73
+ raise 'invalid attestation : does not provide a value' if !att.has_key?(:value) || att[:value].empty?
74
+ att.delete(:source)
75
+
76
+ attestations << sign(fact[:source], att)
77
+ end
78
+
79
+ attestations
80
+ end
81
+
82
+ def sign(source, facts)
83
+ fact = { jti: SecureRandom.uuid,
84
+ sub: @to,
85
+ iss: @from,
86
+ iat: SelfSDK::Time.now.strftime('%FT%TZ'),
87
+ source: source,
88
+ verified: true,
89
+ facts: [ facts ] }
90
+ @client.jwt.signed(fact)
91
+ end
92
+ end
93
+ end
94
+ end
@@ -12,7 +12,12 @@ module SelfSDK
12
12
  MSG_TYPE = "identities.facts.query.req"
13
13
  DEFAULT_EXP_TIMEOUT = 900
14
14
 
15
- attr_accessor :facts, :options
15
+ attr_accessor :facts, :options, :auth
16
+
17
+ def initialize(messaging)
18
+ @typ = MSG_TYPE
19
+ super
20
+ end
16
21
 
17
22
  def parse_facts(facts)
18
23
  @facts = []
@@ -82,6 +87,7 @@ module SelfSDK
82
87
  b = {
83
88
  typ: MSG_TYPE,
84
89
  iss: @jwt.id,
90
+ aud: @to,
85
91
  sub: @to,
86
92
  iat: SelfSDK::Time.now.strftime('%FT%TZ'),
87
93
  exp: (SelfSDK::Time.now + @exp_timeout).strftime('%FT%TZ'),
@@ -13,6 +13,11 @@ module SelfSDK
13
13
 
14
14
  attr_accessor :facts, :audience, :auth
15
15
 
16
+ def initialize(messaging)
17
+ @typ = MSG_TYPE
18
+ super
19
+ end
20
+
16
21
  def parse(input, envelope=nil)
17
22
  @input = input
18
23
  @typ = MSG_TYPE
@@ -43,7 +48,7 @@ module SelfSDK
43
48
  end
44
49
 
45
50
  def fact(name)
46
- name = @messaging.source.normalize_fact_name!(name)
51
+ name = @messaging.source.normalize_fact_name(name)
47
52
  @facts.select{|f| f.name == name}.first
48
53
  end
49
54
 
@@ -84,6 +89,10 @@ module SelfSDK
84
89
  auth: @auth }
85
90
  end
86
91
 
92
+ def auth_response?
93
+ @auth == true
94
+ end
95
+
87
96
  protected
88
97
 
89
98
  def proto(to_device)
@@ -4,8 +4,6 @@
4
4
 
5
5
  require_relative "fact_request"
6
6
  require_relative "fact_response"
7
- require_relative "authentication_resp"
8
- require_relative "authentication_req"
9
7
  require_relative "chat_message"
10
8
  require_relative "chat_message_read"
11
9
  require_relative "chat_message_delivered"
@@ -13,6 +11,7 @@ require_relative "chat_invite"
13
11
  require_relative "chat_join"
14
12
  require_relative "chat_remove"
15
13
  require_relative "document_sign_resp"
14
+ require_relative "connection_response"
16
15
 
17
16
  module SelfSDK
18
17
  module Messages
@@ -30,18 +29,12 @@ module SelfSDK
30
29
  payload = JSON.parse(messaging.jwt.decode(jwt[:payload]), symbolize_names: true)
31
30
 
32
31
  case payload[:typ]
33
- when "identities.facts.query.req"
32
+ when SelfSDK::Messages::FactRequest::MSG_TYPE
34
33
  m = FactRequest.new(messaging)
35
34
  m.parse(body, envelope)
36
- when "identities.facts.query.resp"
35
+ when SelfSDK::Messages::FactResponse::MSG_TYPE
37
36
  m = FactResponse.new(messaging)
38
37
  m.parse(body, envelope)
39
- when "identities.authenticate.resp"
40
- m = AuthenticationResp.new(messaging)
41
- m.parse(body, envelope)
42
- when "identities.authenticate.req"
43
- m = AuthenticationReq.new(messaging)
44
- m.parse(body, envelope)
45
38
  when SelfSDK::Messages::ChatMessage::MSG_TYPE
46
39
  m = ChatMessage.new(messaging)
47
40
  m.parse(body, envelope)
@@ -63,6 +56,9 @@ module SelfSDK
63
56
  when SelfSDK::Messages::DocumentSignResponse::MSG_TYPE
64
57
  m = DocumentSignResponse.new(messaging)
65
58
  m.parse(body, envelope)
59
+ when SelfSDK::Messages::ConnectionResponse::MSG_TYPE
60
+ m = ConnectionResponse.new(messaging)
61
+ m.parse(body, envelope)
66
62
  else
67
63
  raise StandardError.new("Invalid message type #{payload[:typ]}.")
68
64
  end
data/lib/messaging.rb CHANGED
@@ -430,9 +430,8 @@ module SelfSDK
430
430
  message.validate! @uuid_observer[message.id][:original_message] if @uuid_observer.include? message.id
431
431
  notify_observer(message)
432
432
  end
433
-
434
433
  rescue StandardError => e
435
- p "Error processing incoming message #{input.to_json}"
434
+ p "Error processing incoming message #{e.message}"
436
435
  SelfSDK.logger.info e
437
436
  # p e.backtrace
438
437
  nil
data/lib/selfsdk.rb CHANGED
@@ -17,6 +17,7 @@ require_relative 'authenticated'
17
17
  require_relative 'acl'
18
18
  require_relative 'sources'
19
19
  require_relative 'services/auth'
20
+ require_relative 'services/requester'
20
21
  require_relative 'services/facts'
21
22
  require_relative 'services/identity'
22
23
  require_relative 'services/messaging'
@@ -66,12 +67,12 @@ module SelfSDK
66
67
 
67
68
  # Provides access to SelfSDK::Services::Facts service
68
69
  def facts
69
- @facts ||= SelfSDK::Services::Facts.new(messaging, @client)
70
+ @facts ||= SelfSDK::Services::Facts.new(requester)
70
71
  end
71
72
 
72
73
  # Provides access to SelfSDK::Services::Authentication service
73
74
  def authentication
74
- @authentication ||= SelfSDK::Services::Authentication.new(messaging, @client)
75
+ @authentication ||= SelfSDK::Services::Authentication.new(requester)
75
76
  end
76
77
 
77
78
  # Provides access to SelfSDK::Services::Identity service
@@ -109,6 +110,10 @@ module SelfSDK
109
110
 
110
111
  protected
111
112
 
113
+ def requester
114
+ @requester ||= SelfSDK::Services::Requester.new(messaging, @client)
115
+ end
116
+
112
117
  def base_url(opts)
113
118
  return opts[:base_url] if opts.key? :base_url
114
119
  return "https://api.#{opts[:env].to_s}.joinself.com" if opts.key? :env
data/lib/services/auth.rb CHANGED
@@ -16,10 +16,8 @@ module SelfSDK
16
16
  # @param client [SelfSDK::Client] http client object.
17
17
  #
18
18
  # @return [SelfSDK::Services::Authentication] authentication service.
19
- def initialize(messaging, client)
20
- @messaging = messaging.client
21
- @messaging_service = messaging
22
- @client = client
19
+ def initialize(requester)
20
+ @requester = requester
23
21
  end
24
22
 
25
23
  # Sends an authentication request to the specified selfid.
@@ -30,6 +28,7 @@ module SelfSDK
30
28
  # @param [String] selfid the receiver of the authentication request.
31
29
  # @param [Hash] opts the options to authenticate.
32
30
  # @option opts [String] :cid The unique identifier of the authentication request.
31
+ # @option opts [Array] :facts array of facts to be requested
33
32
  # @yield [request] Invokes the block with an authentication response for each result.
34
33
  # @return [String, String] conversation id or encoded body.
35
34
  #
@@ -38,29 +37,21 @@ module SelfSDK
38
37
  # @param [Hash] opts the options to authenticate.
39
38
  # @option [Boolean] :async if the request is asynchronous.
40
39
  # @option opts [String] :cid The unique identifier of the authentication request.
40
+ # @option opts [Array] :facts array of facts to be requested
41
41
  # @return [String, String] conversation id or encoded body.
42
42
  def request(selfid, opts = {}, &block)
43
- SelfSDK.logger.info "authenticating #{selfid}"
44
- rq = opts.fetch(:request, true)
45
- if rq
46
- raise "You're not permitting connections from #{selfid}" unless @messaging_service.is_permitted?(selfid)
47
- end
48
-
49
- req = SelfSDK::Messages::AuthenticationReq.new(@messaging)
50
- req.populate(selfid, opts)
51
-
52
- body = @client.jwt.prepare(req.body)
53
- return body unless rq
54
- return req.send_message if opts.fetch(:async, false)
55
-
56
- # when a block is given the request will always be asynchronous.
57
- if block_given?
58
- @messaging.set_observer(req, timeout: req.exp_timeout, &block)
59
- return req.send_message
60
- end
61
-
62
- # Otherwise the request is synchronous
63
- req.request
43
+ opts[:auth] = true
44
+ facts = opts.fetch(:facts, [])
45
+
46
+ @requester.request(selfid, facts, opts, &block)
47
+ end
48
+
49
+ # Adds an observer for a fact response
50
+ # Whenever you receive a fact response registered observers will receive a notification.
51
+ #
52
+ # @yield [request] Invokes the block with a fact response message.
53
+ def subscribe(&block)
54
+ @requester.subscribe(true, &block)
64
55
  end
65
56
 
66
57
  # Generates a QR code so users can authenticate to your app.
@@ -70,10 +61,10 @@ module SelfSDK
70
61
  #
71
62
  # @return [String, String] conversation id or encoded body.
72
63
  def generate_qr(opts = {})
73
- opts[:request] = false
74
- selfid = opts.fetch(:selfid, "-")
75
- req = request(selfid, opts)
76
- ::RQRCode::QRCode.new(req, level: 'l')
64
+ opts[:auth] = true
65
+ facts = opts.fetch(:facts, [])
66
+
67
+ @requester.generate_qr(facts, opts)
77
68
  end
78
69
 
79
70
  # Generates a deep link to authenticate with self app.
@@ -84,24 +75,10 @@ module SelfSDK
84
75
  #
85
76
  # @return [String, String] conversation id or encoded body.
86
77
  def generate_deep_link(callback, opts = {})
87
- opts[:request] = false
88
- selfid = opts.fetch(:selfid, "-")
89
- body = @client.jwt.encode(request(selfid, opts))
90
-
91
- if @client.env.empty?
92
- return "https://links.joinself.com/?link=#{callback}%3Fqr=#{body}&apn=com.joinself.app"
93
- elsif @client.env == 'development'
94
- return "https://links.joinself.com/?link=#{callback}%3Fqr=#{body}&apn=com.joinself.app.dev"
95
- end
96
- "https://#{@client.env}.links.joinself.com/?link=#{callback}%3Fqr=#{body}&apn=com.joinself.app.#{@client.env}"
97
- end
78
+ opts[:auth] = true
79
+ facts = opts.fetch(:facts, [])
98
80
 
99
- # Adds an observer for an authentication response
100
- def subscribe(&block)
101
- @messaging.subscribe :authentication_response do |res|
102
- valid_payload(res.input)
103
- yield(res)
104
- end
81
+ @requester.generate_deep_link(facts, callback, opts)
105
82
  end
106
83
 
107
84
  private
@@ -130,27 +107,6 @@ module SelfSDK
130
107
  nil
131
108
  end
132
109
 
133
- # Prepares an authentication payload to be sent to a user.
134
- #
135
- # @param selfid [string] the selfid of the user you want to send the auth request to.
136
- # @param cid [string] the conversation id to be used.
137
- def prepare_payload(selfid, cid)
138
- # TODO should this be moved to its own message/auth_req.rb?
139
- body = {
140
- typ: 'identities.authenticate.req',
141
- aud: @client.self_url,
142
- iss: @client.jwt.id,
143
- sub: selfid,
144
- iat: SelfSDK::Time.now.strftime('%FT%TZ'),
145
- exp: (SelfSDK::Time.now + 3600).strftime('%FT%TZ'),
146
- cid: cid,
147
- jti: SecureRandom.uuid,
148
- device_id: @messaging.device_id,
149
- }
150
-
151
- @client.jwt.prepare(body)
152
- end
153
-
154
110
  def parse_payload(response)
155
111
  jws = @client.jwt.parse(response)
156
112
  return unless jws.include? :payload
@@ -161,7 +117,7 @@ module SelfSDK
161
117
  identity = @client.entity(payload[:sub])
162
118
  return if identity.nil?
163
119
 
164
- return payload
120
+ payload
165
121
  end
166
122
  end
167
123
  end
data/lib/services/chat.rb CHANGED
@@ -6,6 +6,8 @@ require 'self_crypto'
6
6
  require_relative '../chat/file_object'
7
7
  require_relative '../chat/group'
8
8
  require_relative '../chat/message'
9
+ require_relative "../messages/connection_request"
10
+
9
11
  module SelfSDK
10
12
  module Services
11
13
  class Chat
@@ -15,7 +17,7 @@ module SelfSDK
15
17
  @messaging = messaging
16
18
  @client = client
17
19
  @app_id = @messaging.client.client.jwt.id
18
- @auth_token = @messaging.client.client.jwt.auth_token
20
+ @jwt = @messaging.client.client.jwt
19
21
  @self_url = @messaging.client.client.self_url
20
22
  end
21
23
 
@@ -34,7 +36,7 @@ module SelfSDK
34
36
  payload[:rid] = opts[:rid] if opts.key? :rid
35
37
  payload[:objects] = opts[:objects] if opts.key? :objects
36
38
 
37
- m = SelfSDK::Chat::Message.new(self, recipients, payload, @auth_token, @self_url)
39
+ m = SelfSDK::Chat::Message.new(self, recipients, payload, @jwt.auth_token, @self_url)
38
40
  _req = send(m.recipients, m.payload)
39
41
 
40
42
  m
@@ -43,7 +45,7 @@ module SelfSDK
43
45
  # Subscribes to an incoming chat message
44
46
  def on_message(opts = {}, &block)
45
47
  @messaging.subscribe :chat_message do |msg|
46
- cm = SelfSDK::Chat::Message.new(self, msg.payload[:aud], msg.payload, @auth_token, @self_url)
48
+ cm = SelfSDK::Chat::Message.new(self, msg.payload[:aud], msg.payload, @jwt.auth_token, @self_url)
47
49
 
48
50
  cm.mark_as_delivered unless opts[:mark_as_delivered] == false
49
51
  cm.mark_as_read if opts[:mark_as_read] == true
@@ -128,7 +130,7 @@ module SelfSDK
128
130
  members: members }
129
131
 
130
132
  if opts.key? :data
131
- obj = SelfSDK::Chat::FileObject.new(@auth_token, @self_url)
133
+ obj = SelfSDK::Chat::FileObject.new(@jwt.auth_token, @self_url)
132
134
  obj_payload = obj.build_from_data("", opts[:data], opts[:mime]).to_payload
133
135
  obj_payload.delete(:name)
134
136
  payload.merge! obj_payload
@@ -160,6 +162,46 @@ module SelfSDK
160
162
  send(members, typ: "chat.remove", gid: gid )
161
163
  end
162
164
 
165
+ # Generates a connection request in form of QR
166
+ #
167
+ # @opts opts [Integer] :exp_timeout timeout in seconds to expire the request.
168
+ def generate_connection_qr(opts = {})
169
+ req = SelfSDK::Messages::ConnectionRequest.new(@messaging)
170
+ req.populate(@jwt.id, opts)
171
+ body = @jwt.prepare(req.body)
172
+
173
+ ::RQRCode::QRCode.new(body, level: 'l')
174
+ end
175
+
176
+ # Generates a connection request in form of deep link
177
+ #
178
+ # @param callback [String] the url you'll be redirected if the app is not installed.
179
+ # @opts opts [Integer] :exp_timeout timeout in seconds to expire the request.
180
+ def generate_connection_deep_link(callback, opts = {})
181
+ req = SelfSDK::Messages::ConnectionRequest.new(@messaging)
182
+ req.populate(@jwt.id, opts)
183
+ body = @jwt.prepare(req.body)
184
+ body = @jwt.encode(body)
185
+
186
+ env = @messaging.client.client.env
187
+ if env.empty?
188
+ return "https://links.joinself.com/?link=#{callback}%3Fqr=#{body}&apn=com.joinself.app"
189
+ elsif env == 'development'
190
+ return "https://links.joinself.com/?link=#{callback}%3Fqr=#{body}&apn=com.joinself.app.dev"
191
+ end
192
+
193
+ "https://#{env}.links.joinself.com/?link=#{callback}%3Fqr=#{body}&apn=com.joinself.app.#{env}"
194
+ end
195
+
196
+ # Subscribes to a connection response
197
+ #
198
+ # @yield [request] Invokes the block with a connection response message.
199
+ def on_connection(&block)
200
+ @messaging.subscribe :connection_response do |msg|
201
+ block.call(msg)
202
+ end
203
+ end
204
+
163
205
  private
164
206
 
165
207
  # sends a confirmation for a list of messages to a list of recipients.