class SelfSDK::Services::Facts
Input class to handle authentication requests on self network.
Public Class Methods
Creates a new facts service. Facts
service mainly manages fact requests against self users wanting to share their verified facts with your app.
@param messaging [SelfSDK::Messaging] messaging object. @param client [SelfSDK::Client] http client object.
@return [SelfSDK::Services::Facts] facts service.
# File lib/services/facts.rb, line 21 def initialize(messaging, client) @messaging = messaging.client @messaging_service = messaging @client = client end
Public Instance Methods
Generates a deep link to authenticate with self app.
@param facts [Array] a list of facts to be requested. @param callback [String] the url you'll be redirected if the app is not installed. @option opts [String] :selfid the user selfid you want to authenticate. @option opts [String] :cid The unique identifier of the authentication request.
@return [String, String] conversation id or encoded body.
# File lib/services/facts.rb, line 112 def generate_deep_link(facts, callback, opts = {}) opts[:request] = false selfid = opts.fetch(:selfid, "-") body = @client.jwt.encode(request(selfid, facts, opts)) if @client.env.empty? return "https://joinself.page.link/?link=#{callback}%3Fqr=#{body}&apn=com.joinself.app" elsif @client.env == 'development' return "https://joinself.page.link/?link=#{callback}%3Fqr=#{body}&apn=com.joinself.app.dev" end "https://joinself.page.link/?link=#{callback}%3Fqr=#{body}&apn=com.joinself.app.#{@client.env}" end
Generates a QR code so users can send facts to your app.
@param facts [Array] a list of facts to be requested. @option opts [String] :cid The unique identifier of the authentication request. @option opts [String] :options Options you want to share with the identity.
@return [String, String] conversation id or encoded body.
# File lib/services/facts.rb, line 97 def generate_qr(facts, opts = {}) opts[:request] = false selfid = opts.fetch(:selfid, "-") req = request(selfid, facts, opts) ::RQRCode::QRCode.new(req, level: 'l') end
Sends a fact request to the specified selfid. An fact request allows your app to access trusted facts of your user with its permission.
@overload request(selfid, facts, opts = {}, &block)
@param selfid [string] the receiver of the authentication request. @param [Hash] opts the options to authenticate. @option opts [String] :cid The unique identifier of the authentication request. @yield [request] Invokes the block with a street name for each result. @return [Object] SelfSDK:::Messages::FactRequest
@overload request(selfid, facts, opts = {})
@param selfid [string] the receiver of the authentication request. @param [Hash] opts the options to authenticate. @option opts [String] :cid The unique identifier of the authentication request. @option opts [Integer] :exp_timeout timeout in seconds to expire the request. @return [Object] SelfSDK:::Messages::FactRequest
# File lib/services/facts.rb, line 44 def request(selfid, facts, opts = {}, &block) SelfSDK.logger.info "authenticating #{selfid}" rq = opts.fetch(:request, true) if rq raise "You're not permitting connections from #{selfid}" unless @messaging_service.is_permitted?(selfid) end req = SelfSDK::Messages::FactRequest.new(@messaging) req.populate(selfid, prepare_facts(facts), opts) body = @client.jwt.prepare(req.body) return body unless rq # when a block is given the request will always be asynchronous. if block_given? @messaging.set_observer(req, timeout: req.exp_timeout, &block) return req.send_message end # Otherwise the request is synchronous req.request end
Sends a request through an intermediary. An intermediary is an entity trusted by the user and acting as a proxy between you and the recipient of your fact request. Intermediaries usually do not provide the original user facts, but they create its own assertions based on your request and the user's facts.
@param selfid [string] the receiver of the authentication request. @param [Hash] opts the options to authenticate. @option opts [String] intermediary an intermediary identity to be used. @return [Object] SelfSDK:::Messages::FactRequest
# File lib/services/facts.rb, line 77 def request_via_intermediary(selfid, facts, opts = {}, &block) opts[:intermediary] = opts.fetch(:intermediary, DEFAULT_INTERMEDIARY) request(selfid, facts, opts, &block) end
Adds an observer for a fact response Whenever you receive a fact response registered observers will receive a notification.
@yield [request] Invokes the block with a fact response message.
# File lib/services/facts.rb, line 86 def subscribe(&block) @messaging.subscribe(:fact_response, &block) end
Private Instance Methods
As request facts can accept an array of strings this populates with necessary structure this short fact definitions.
@param facts [Array] an array of strings or hashes. @return [Array] a list of hashed facts.
# File lib/services/facts.rb, line 132 def prepare_facts(facts) fs = [] facts.each do |f| fact = if f.is_a?(Hash) f else { fact: f } end # validate_fact!(fact) fs << fact end fs end
# File lib/services/facts.rb, line 146 def validate_fact!(f) errInvalidFactToSource = 'provided source does not support given fact' errInvalidSource = 'provided fact does not specify a valid source' raise 'provided fact does not specify a name' if f[:fact].empty? return unless f.has_key? :sources valid_sources = [SOURCE_USER_SPECIFIED, SOURCE_PASSPORT, SOURCE_DRIVING_LICENSE, SOURCE_IDENTITY_CARD] factsForPassport = [ FACT_DOCUMENT_NUMBER, FACT_SURNAME, FACT_GIVEN_NAMES, FACT_DATE_OF_BIRTH, FACT_DATE_OF_EXPIRATION, FACT_SEX, FACT_NATIONALITY, FACT_COUNTRY_OF_ISSUANCE ] factsForDL = [ FACT_DOCUMENT_NUMBER, FACT_SURNAME, FACT_GIVEN_NAMES, FACT_DATE_OF_BIRTH, FACT_DATE_OF_ISSUANCE, FACT_DATE_OF_EXPIRATION, FACT_ADDRESS, FACT_ISSUING_AUTHORITY, FACT_PLACE_OF_BIRTH, FACT_COUNTRY_OF_ISSUANCE ] factsForUser = [ FACT_DOCUMENT_NUMBER, FACT_DISPLAY_NAME, FACT_EMAIL, FACT_PHONE ] f[:sources].each do |s| raise errInvalidSource unless valid_sources.include? s.to_s if s.to_s == SOURCE_PASSPORT || s.to_s == SOURCE_IDENTITY_CARD raise errInvalidFactToSource unless factsForPassport.include? f[:fact] end if s.to_s == SOURCE_DRIVING_LICENSE raise errInvalidFactToSource unless factsForDL.include? f[:fact] end if s.to_s == SOURCE_USER_SPECIFIED raise errInvalidFactToSource unless factsForUser.include? f[:fact].to_s end end end