Module: OPP::Presence

Defined in:
lib/opp/presence.rb

Constant Summary collapse

REQUIRED =
%w[type version subject public_key issued_at services signature].freeze
TYPES =
{
  "type" => String,
  "version" => String,
  "subject" => String,
  "public_key" => String,
  "issued_at" => String,
  "services" => Array,
  "signature" => Hash,
  "expires_at" => String
}.freeze
TIMESTAMP_PATTERN =
/\A(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})T(?<hour>\d{2}):(?<minute>\d{2}):(?<second>\d{2})(?:\.(?<fraction>\d+))?Z\z/

Class Method Summary collapse

Class Method Details

.sign(document, private_key:) ⇒ Object

Raises:



22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/opp/presence.rb', line 22

def sign(document, private_key:)
  raise ValidationError, "document must be an object" unless document.is_a?(Hash)

  pair = KeyPair.from_private_key(private_key)
  unsigned = copy(document).tap { |value| value.delete("signature") }.merge(
    "public_key" => pair.public_key,
    "subject" => Subject.derive(pair.public_key)
  )
  errors = validate(unsigned, at: nil, signature_required: false)
  raise errors.first unless errors.empty?

  Signature.sign(unsigned, private_key:)
end

.verify(input, at: Time.now.utc) ⇒ Object



36
37
38
39
40
41
# File 'lib/opp/presence.rb', line 36

def verify(input, at: Time.now.utc)
  document = input.is_a?(String) ? OPP::JSON.parse(input) : copy(input)
  VerificationResult.new(validate(document, at:, signature_required: true))
rescue OPP::Error => error
  VerificationResult.new([error])
end

.verify!(input, at: Time.now.utc) ⇒ Object



43
44
45
46
47
48
# File 'lib/opp/presence.rb', line 43

def verify!(input, at: Time.now.utc)
  result = verify(input, at:)
  raise result.errors.first unless result.valid?

  true
end