Module: Crypt

Extended by:
Crypt
Included in:
Crypt
Defined in:
lib/common/crypt.rb

Constant Summary collapse

ALGORITHM =
'HS512'

Instance Method Summary collapse

Instance Method Details

#base64(str) ⇒ Object



21
22
23
# File 'lib/common/crypt.rb', line 21

def base64 str
  Base64.urlsafe_encode64(str)
end

#bcrypt(plain, check = nil) ⇒ Object



51
52
53
54
55
56
57
# File 'lib/common/crypt.rb', line 51

def bcrypt plain, check = nil
  if check
    BCrypt::Password.new(check) == [plain, secret].join('')
  else
    BCrypt::Password.create(plain + secret)
  end
end

#decrypt(token, opts = {}) ⇒ Object

Crypt.decrypt(‘secret’) Crypt.decrypt(‘secret’, password:‘pa$$w0rd’, unsafe: true)



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/common/crypt.rb', line 71

def decrypt token, opts={}
  opts = opts.to_hwia :password, :ttl

  token_data = JWT.decode token, secret+opts.password.to_s, true, { algorithm: ALGORITHM }
  data = token_data[0]

  if data['ttl'] && data['ttl'] < Time.now.to_i
    seconds = Time.now.to_i - data['ttl']
    before  = Time.respond_to?(:ago) ? Time.ago(Time.now - seconds) : "#{seconds} seconds"
    raise JWT::VerificationError, "Crypted data expired before #{before}. Please get a fresh token."
  end

  data['data']
rescue => err
  raise err unless opts[:unsafe]
end

#encrypt(data, opts = {}) ⇒ Object

Crypt.encrypt(‘secret’) Crypt.encrypt(‘secret’, ttl:1.hour, password:‘pa$$w0rd’)



61
62
63
64
65
66
67
# File 'lib/common/crypt.rb', line 61

def encrypt data, opts = {}
  opts          = opts.to_hwia :ttl, :password
  payload       = { data:data }
  payload[:ttl] = Time.now.to_i + opts.ttl.to_i if opts.ttl

  JWT.encode payload, secret+opts.password.to_s, ALGORITHM
end

#md5(str) ⇒ Object



39
40
41
# File 'lib/common/crypt.rb', line 39

def md5 str
  Digest::MD5.hexdigest(str.to_s + secret)
end

#random(length = 32) ⇒ Object



43
44
45
46
47
48
49
# File 'lib/common/crypt.rb', line 43

def random length=32
  chars = 'abcdefghjkmnpqrstuvwxyz0123456789'
  length
    .times
    .inject([]) { |t, _| t.push chars[rand(chars.size)] }
    .join('')
end

#secretObject



17
18
19
# File 'lib/common/crypt.rb', line 17

def secret
  ENV.fetch('SECRET') { Lux.config.secret } || die('Lux.config.secret not set')
end

#sha1(str) ⇒ Object



30
31
32
# File 'lib/common/crypt.rb', line 30

def sha1 str
  Digest::SHA1.hexdigest(str.to_s + secret)
end

#sha1s(str) ⇒ Object

sha1 shorter string



35
36
37
# File 'lib/common/crypt.rb', line 35

def sha1s str
  Integer(Digest::SHA1.hexdigest(str.to_s), 16).to_s(36)
end

#short_decrypt(data) ⇒ Object

Raises:

  • (ArgumentError)


99
100
101
102
103
104
105
106
107
108
109
# File 'lib/common/crypt.rb', line 99

def short_decrypt data
  check   = nil
  data    = data.sub(/^(.{8})/) { check = $1; ''}
  decoded = Base64.urlsafe_decode64(data)
  out     = JSON.load decoded

  raise ArgumentError.new('Invalid check') unless sha1(decoded + Lux.config.secret)[0,8] == check
  raise ArgumentError.new('Short code expired') if out[1] < Time.now.to_i

  out[0]
end

#short_encrypt(data, ttl = nil) ⇒ Object

encrypts data, with unsafe base64 + basic check not for sensitive data



90
91
92
93
94
95
96
97
# File 'lib/common/crypt.rb', line 90

def short_encrypt data, ttl = nil
  # expires in one day by deafult

  ttl ||= 1.day
  ttl   = ttl.to_i + Time.now.to_i

  data  = [data, ttl].to_json
  sha1(data + Lux.config.secret)[0,8] + base64(data).sub(/=+$/, '')
end

#simple_decode(str) ⇒ Object

works with Z.simpleEncode



112
113
114
# File 'lib/common/crypt.rb', line 112

def simple_decode str
  Base64.decode64 str.gsub('_', '/').tr('A-Za-z', 'N-ZA-Mn-za-m')
end

#simple_encode(str) ⇒ Object



116
117
118
# File 'lib/common/crypt.rb', line 116

def simple_encode str
  Base64.encode64(str).gsub('_', '/').tr('A-Za-z', 'N-ZA-Mn-za-m').gsub(/=+$/, '').gsub(/\s/, '')
end

#uid(size = nil) ⇒ Object



25
26
27
28
# File 'lib/common/crypt.rb', line 25

def uid size = nil
  # there is also StringBase.uid

  SecureRandom.alphanumeric(size || 32).downcase
end