Class: Dommy::Crypto

Inherits:
Object
  • Object
show all
Defined in:
lib/dommy/crypto.rb

Overview

‘Crypto` — mirror of `window.crypto`. Exposes `randomUUID()`, `getRandomValues(typedArray)`, and a minimal `subtle` surface (digest only, sufficient for most test fixtures).

Spec: w3c.github.io/webcrypto/

Instance Method Summary collapse

Constructor Details

#initialize(window = nil) ⇒ Crypto

Returns a new instance of Crypto.



14
15
16
# File 'lib/dommy/crypto.rb', line 14

def initialize(window = nil)
  @window = window
end

Instance Method Details

#__js_call__(method, args) ⇒ Object



65
66
67
68
69
70
71
72
# File 'lib/dommy/crypto.rb', line 65

def __js_call__(method, args)
  case method
  when "randomUUID"
    random_uuid
  when "getRandomValues"
    get_random_values(args[0])
  end
end

#__js_get__(key) ⇒ Object



58
59
60
61
62
63
# File 'lib/dommy/crypto.rb', line 58

def __js_get__(key)
  case key
  when "subtle"
    subtle
  end
end

#get_random_values(typed_array) ⇒ Object Also known as: getRandomValues

JS: crypto.getRandomValues(typedArray) — fills the supplied buffer in place and returns it. JS TypedArrays carry a ‘byteLength` property; we honor that to fill multi-byte element arrays (Uint16Array, etc.) correctly. Plain Ruby arrays fall back to `size` (1 byte per slot).



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/dommy/crypto.rb', line 30

def get_random_values(typed_array)
  return typed_array unless typed_array.respond_to?(:size) && typed_array.respond_to?(:[]=)

  byte_length = if typed_array.respond_to?(:byteLength)
    typed_array.byteLength
  elsif typed_array.respond_to?(:byte_length)
    typed_array.byte_length
  else
    typed_array.size
  end

  bytes_per_element = [byte_length / typed_array.size, 1].max
  bytes = SecureRandom.bytes(byte_length).bytes
  typed_array.size.times do |i|
    offset = i * bytes_per_element
    value = bytes[offset, bytes_per_element].reduce(0) { |acc, b| (acc << 8) | b }
    typed_array[i] = value
  end

  typed_array
end

#random_uuidObject Also known as: randomUUID

JS: crypto.randomUUID() → version-4 UUID string.



19
20
21
# File 'lib/dommy/crypto.rb', line 19

def random_uuid
  SecureRandom.uuid
end

#subtleObject



54
55
56
# File 'lib/dommy/crypto.rb', line 54

def subtle
  @subtle ||= SubtleCrypto.new(@window)
end