class Rmega::Nodes::Node

Constants

TYPES

Attributes

data[R]
session[R]

Public Class Methods

each_chunk(size) { |start, size - start| ... } click to toggle source
# File lib/rmega/nodes/node.rb, line 110
def self.each_chunk(size, &block)
  start, p = 0, 0

  return if size <= 0

  loop do
    offset = p < 8 ? (131072 * (p += 1)) : 1048576
    next_start = offset + start

    if next_start >= size
      yield(start, size - start)
      break
    else
      yield(start, offset)
      start = next_start
    end
  end
end
new(session, data) click to toggle source
# File lib/rmega/nodes/node.rb, line 18
def initialize(session, data)
  @session = session
  @data = data
end

Public Instance Methods

attributes() click to toggle source
# File lib/rmega/nodes/node.rb, line 146
def attributes
  encrypted = data['a'] || data['at']
  return if !encrypted or encrypted.empty?
  node_key = NodeKey.load(decrypted_file_key)
  encrypted = Utils.base64urldecode(encrypted)
  encrypted.strip! if encrypted.size % 16 != 0 # Fix possible errors
  json = aes_cbc_decrypt(node_key.aes_key, encrypted)
  # Remove invalid bytes at the end of the string
  json.strip!
  json.gsub!(/^MEGA\{(.+)\}.*/, '{\1}')
  return JSON.parse(json)
end
decrypted_file_key() click to toggle source
# File lib/rmega/nodes/node.rb, line 133
def decrypted_file_key
  h, shared_key = *process_shared_key

  if shared_key
    aes_ecb_decrypt(shared_key, file_keys[h])
  elsif file_key
    aes_ecb_decrypt(master_key, file_key)
  else
    ary = Rmega::Nodes::Factory.public_handle_and_key_from_url(public_url)
    Utils.base64urldecode(ary[1])
  end
end
each_chunk(&block) click to toggle source
# File lib/rmega/nodes/node.rb, line 129
def each_chunk(&block)
  self.class.each_chunk(filesize, &block)
end
file_key() click to toggle source
# File lib/rmega/nodes/node.rb, line 78
def file_key
  k = file_keys.values.first
  return k ? k : nil
end
file_keys() click to toggle source
# File lib/rmega/nodes/node.rb, line 67
def file_keys
  return {} unless data['k']

  pairs = data['k'].split('/')
  pairs.inject({}) do |hash, pair|
    h, k = pair.split(':')
    hash[h] = Utils.base64urldecode(k)
    hash
  end
end
handle() click to toggle source
# File lib/rmega/nodes/node.rb, line 55
def handle
  data['h']
end
name() click to toggle source
# File lib/rmega/nodes/node.rb, line 63
def name
  attributes['n'] if attributes
end
parent_handle() click to toggle source
# File lib/rmega/nodes/node.rb, line 59
def parent_handle
  data['p']
end
process_shared_key() click to toggle source
# File lib/rmega/nodes/node.rb, line 87
def process_shared_key
  h = (shared_keys.keys & file_keys.keys).first
  return [h, shared_keys[h]] if h

  sk = data['sk']

  return unless sk

  shared_key = if sk.size > 22
    # Decrypt sk
    sk = Utils.base64_mpi_to_bn(sk)
    sk = rsa_decrypt(sk, rsa_privk)
    sk = sk.to_s(16)
    sk = '0' + sk if sk.size % 2 > 0
    Utils.hexstr_to_bstr(sk)[0..15]
  else
    aes_ecb_decrypt(master_key, Utils.base64urldecode(sk))
  end

  shared_keys[handle] = shared_key
  [handle, shared_key]
end
public_handle() click to toggle source
# File lib/rmega/nodes/node.rb, line 27
def public_handle
  @public_handle ||= request(a: 'l', n: handle)
end
public_url() click to toggle source
# File lib/rmega/nodes/node.rb, line 23
def public_url
  @public_url ||= "https://mega.nz/file/#{public_handle}\##{Utils.base64urlencode(decrypted_file_key)}"
end
rename(new_name) click to toggle source
# File lib/rmega/nodes/node.rb, line 38
def rename(new_name)
  node_key = NodeKey.load(decrypted_file_key)

  _attr = serialize_attributes(attributes.merge("n" => Utils.utf8(new_name)))
  _attr = aes_cbc_encrypt(node_key.aes_key, _attr)
  _attr = Utils.base64urlencode(_attr)

  resp = request(:a => "a", :attr => _attr, :key => Utils.base64urlencode(node_key.aes_key), :n => handle)

  if resp != 0
    raise("Rename failed")
  else
    @data['a'] = _attr
    return self
  end
end
serialize_attributes(hash) click to toggle source
# File lib/rmega/nodes/node.rb, line 31
def serialize_attributes(hash)
  str = "MEGA"
  str << hash.to_json
  str << ("\x00" * (16 - (str.bytesize % 16)))
  return str
end
shared_root?() click to toggle source
# File lib/rmega/nodes/node.rb, line 83
def shared_root?
  data['su'] && data['sk'] && data['k']
end
type() click to toggle source
# File lib/rmega/nodes/node.rb, line 159
def type
  TYPES[data['t']]
end