Class: Nquery::EmbedTokenService

Inherits:
Object
  • Object
show all
Defined in:
lib/nquery/embed_token_service.rb

Defined Under Namespace

Classes: Error

Class Method Summary collapse

Class Method Details

.generate_tokenObject



75
76
77
# File 'lib/nquery/embed_token_service.rb', line 75

def self.generate_token
  SecureRandom.urlsafe_base64(24)
end

.sign(resource_type:, resource_id:, params: {}, expires_at: 1.hour.from_now, creator: nil) ⇒ Object



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
# File 'lib/nquery/embed_token_service.rb', line 10

def self.sign(resource_type:, resource_id:, params: {}, expires_at: 1.hour.from_now, creator: nil)
  token = generate_token
  payload = {
    token: token,
    resource_type: resource_type,
    resource_id: resource_id,
    params: params,
    exp: expires_at.to_i
  }
  data = Base64.urlsafe_encode64(payload.to_json)

  signature = OpenSSL::HMAC.hexdigest("SHA256", signing_key, data)
  signed = "#{data}.#{signature}"

  EmbedToken.create!(
    token: token,
    resource_type: resource_type,
    resource_id: resource_id,
    creator: creator,
    params: params,
    expires_at: expires_at,
    active: true
  )

  { token: token, signed_token: signed, expires_at: expires_at }
end

.signed_token_for(record) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/nquery/embed_token_service.rb', line 62

def self.signed_token_for(record)
  payload = {
    token: record.token,
    resource_type: record.resource_type,
    resource_id: record.resource_id,
    params: record.params || {},
    exp: record.expires_at.to_i
  }
  data = Base64.urlsafe_encode64(payload.to_json)
  signature = OpenSSL::HMAC.hexdigest("SHA256", signing_key, data)
  "#{data}.#{signature}"
end

.signing_keyObject



79
80
81
# File 'lib/nquery/embed_token_service.rb', line 79

def self.signing_key
  Nquery.configuration.embed_signing_key
end

.verify(signed_token) ⇒ Object

Raises:



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/nquery/embed_token_service.rb', line 37

def self.verify(signed_token)
  data, signature = signed_token.to_s.split(".", 2)
  raise Error, "Invalid token format" unless data.present? && signature.present?

  expected_signature = OpenSSL::HMAC.hexdigest("SHA256", signing_key, data)
  unless ActiveSupport::SecurityUtils.secure_compare(expected_signature, signature)
    raise Error, "Invalid token signature"
  end

  payload = JSON.parse(Base64.urlsafe_decode64(data))
  raise Error, "Token expired" if payload["exp"].to_i <= Time.current.to_i

  record = EmbedToken.active.find_by(token: payload["token"])
  raise Error, "Token not found" unless record
  raise Error, "Token expired" if record.expired?
  raise Error, "Token mismatch" unless record.resource_type == payload["resource_type"] &&
                                       record.resource_id == payload["resource_id"].to_i

  {
    resource_type: record.resource_type,
    resource_id: record.resource_id,
    params: record.params
  }
end