dotenv-vault 0.3.3 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8ab8101dc628ec297e5db57935ab4f3cba02140125730dc153817090e4d4ea1
4
- data.tar.gz: 12f52b1034404d78f29b2f5ccb73966e97c638ba54d0a8de38f53d2c86139e2f
3
+ metadata.gz: e49a9658a64cd656eee7128b70ef2f501e84f5101aafb3aaf54f7de400f0013f
4
+ data.tar.gz: de8dd440fdaf111b979706f62c27298f9ab7dc5c2f7ec3e875bde992c87c789d
5
5
  SHA512:
6
- metadata.gz: ec457fde8f33493026d739c3032e22e48d30ba58b36be1638a97eedfb748cda39cafb443d95980778bbb9357c53f752a2f45a96d856585c59a9f63e395e506b4
7
- data.tar.gz: cef3ee646ffbd151d32b74dce32dd588c2e346710231f0cef8ac054e2b442ab4d9a37a67e56718b232d14f210db0a55fcbdadf0ae40e8c24307f8a5b8cfa3c79
6
+ metadata.gz: 6f3529e9e8db857b8c6d439c81ccdde7baeb56852b3e5e5edf0f0e7e1c58e7b8589375022d755d239cc73fb6a5d2146fa468304ce7c2155827a02d956fcd1f9f
7
+ data.tar.gz: 6b081b51531f776a1136701cb840665959dea167a753a7943cd54679c7693a5b52372a91492ca7ea27aaf6710d95b2c2e9cc485882c41fb6803d7fb33dce0581
data/Gemfile.lock CHANGED
@@ -1,11 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dotenv-vault (0.3.3)
4
+ dotenv-vault (0.4.1)
5
5
  dotenv
6
- dotenv-vault-rails (0.3.3)
6
+ lockbox
7
+ dotenv-vault-rails (0.4.1)
7
8
  dotenv-rails
8
- dotenv-vault (= 0.3.3)
9
+ dotenv-vault (= 0.4.1)
9
10
 
10
11
  GEM
11
12
  remote: https://rubygems.org/
@@ -40,6 +41,7 @@ GEM
40
41
  erubi (1.11.0)
41
42
  i18n (1.12.0)
42
43
  concurrent-ruby (~> 1.0)
44
+ lockbox (1.0.0)
43
45
  loofah (2.19.0)
44
46
  crass (~> 1.0.2)
45
47
  nokogiri (>= 1.5.9)
data/dotenv-vault.gemspec CHANGED
@@ -26,6 +26,7 @@ Gem::Specification.new "dotenv-vault" do |spec|
26
26
  spec.require_paths = ["lib"]
27
27
 
28
28
  spec.add_dependency "dotenv"
29
+ spec.add_dependency "lockbox"
29
30
 
30
31
  spec.add_development_dependency "rake"
31
32
  spec.add_development_dependency "rspec"
@@ -1,3 +1,4 @@
1
+ require "dotenv-rails"
1
2
  require "dotenv-vault"
2
3
 
3
4
  # Fix for rake tasks loading in development
@@ -16,7 +17,7 @@ if defined?(Rake.application)
16
17
  end
17
18
  end
18
19
 
19
- DotenvVault.instrumenter = ActiveSupport::Notifications
20
+ Dotenv.instrumenter = ActiveSupport::Notifications
20
21
 
21
22
  # Watch all loaded env files with Spring
22
23
  begin
@@ -30,34 +31,13 @@ rescue LoadError, ArgumentError
30
31
  end
31
32
 
32
33
  module DotenvVault
33
- class Railtie < Rails::Railtie
34
+ class Railtie < ::Dotenv::Railtie
34
35
  def load
35
- Dotenv.load(*dotenv_files)
36
+ DotenvVault.load(*dotenv_files)
36
37
  end
37
38
 
38
39
  def overload
39
- Dotenv.overload(*dotenv_files)
40
+ DotenvVault.overload(*dotenv_files)
40
41
  end
41
-
42
- def root
43
- Rails.root || Pathname.new(ENV["RAILS_ROOT"] || Dir.pwd)
44
- end
45
-
46
- def self.load
47
- instance.load
48
- end
49
-
50
- private
51
-
52
- def dotenv_files
53
- [
54
- root.join(".env.#{Rails.env}.local"),
55
- (root.join(".env.local") unless Rails.env.test?),
56
- root.join(".env.#{Rails.env}"),
57
- root.join(".env")
58
- ].compact
59
- end
60
-
61
- config.before_configuration { load }
62
42
  end
63
43
  end
@@ -1,3 +1,3 @@
1
1
  module DotenvVault
2
- VERSION = "0.3.3"
2
+ VERSION = "0.4.1"
3
3
  end
data/lib/dotenv-vault.rb CHANGED
@@ -1,8 +1,15 @@
1
1
  require "dotenv"
2
+ require "lockbox"
2
3
  require "dotenv-vault/version"
3
4
 
4
5
  module DotenvVault
5
- class Error < StandardError; end
6
+ class NotFoundDotenvKey < ArgumentError; end
7
+ class NotFoundDotenvEnvironment < ArgumentError; end
8
+ class NotFoundDotenvVault < ArgumentError; end
9
+ class InvalidDotenvKey < ArgumentError; end
10
+ class DecryptionFailed < StandardError; end
11
+
12
+ include ::Dotenv
6
13
 
7
14
  class << self
8
15
  attr_accessor :instrumenter
@@ -11,27 +18,47 @@ module DotenvVault
11
18
  module_function
12
19
 
13
20
  def load(*filenames)
14
- Dotenv.load(*filenames)
21
+ if using_vault?
22
+ load_vault(*filenames)
23
+ else
24
+ Dotenv.load(*filenames) # fallback
25
+ end
15
26
  end
16
27
 
17
28
  # same as `load`, but raises Errno::ENOENT if any files don't exist
18
29
  def load!(*filenames)
19
- Dotenv.load!(*filenames)
30
+ if using_vault?
31
+ load_vault(*filenames)
32
+ else
33
+ Dotenv.load!(*filenames)
34
+ end
20
35
  end
21
36
 
22
37
  # same as `load`, but will override existing values in `ENV`
23
38
  def overload(*filenames)
24
- Dotenv.overload(*filenames)
39
+ if using_vault?
40
+ overload_vault(*filenames)
41
+ else
42
+ Dotenv.overload(*filenames)
43
+ end
25
44
  end
26
45
 
27
46
  # same as `overload`, but raises Errno:ENOENT if any files don't exist
28
47
  def overload!(*filenames)
29
- Dotenv.overload!(*filenames)
48
+ if using_vault?
49
+ overload_vault(*filenames)
50
+ else
51
+ Dotenv.overload!(*filenames)
52
+ end
30
53
  end
31
54
 
32
55
  # returns a hash of parsed key/value pairs but does not modify ENV
33
56
  def parse(*filenames)
34
- Dotenv.parse(*filenames)
57
+ if using_vault?
58
+ parse_vault(*filenames)
59
+ else
60
+ Dotenv.parse(*filenames)
61
+ end
35
62
  end
36
63
 
37
64
  # Internal: Helper to expand list of filenames.
@@ -52,4 +79,75 @@ module DotenvVault
52
79
  def ignoring_nonexistent_files
53
80
  Dotenv.ignoring_nonexistent_files
54
81
  end
82
+
83
+ # Vault: Load from .env.vault
84
+ #
85
+ # Decrypts and loads to ENV
86
+ def load_vault(*filenames)
87
+ parsed = parse_vault(*filenames)
88
+
89
+ # Set ENV
90
+ parsed.each { |k, v| ENV[k] ||= v }
91
+
92
+ { parsed: parsed }
93
+ end
94
+
95
+ # Vault: Overload from .env.vault
96
+ #
97
+ # Decrypts and overloads to ENV
98
+ def overload_vault(*filenames)
99
+ parsed = parse_vault(*filenames)
100
+
101
+ # Set ENV
102
+ parsed.each { |k, v| ENV[k] = v }
103
+
104
+ { parsed: parsed }
105
+ end
106
+
107
+ def parse_vault(*filenames)
108
+ # Warn the developer unless both are set
109
+ raise NotFoundDotenvKey, "NOT_FOUND_DOTENV_KEY: Cannot find ENV['DOTENV_KEY']" unless present?(ENV["DOTENV_KEY"])
110
+ raise NotFoundDotenvEnvironment, "NOT_FOUND_DOTENV_ENVIRONMENT: Cannot find ENV['DOTENV_ENVIRONMENT']" unless present?(ENV["DOTENV_ENVIRONMENT"])
111
+
112
+ # Locate .env.vault
113
+ vault_path = ".env.vault"
114
+ raise NotFoundDotenvVault, "NotFoundDotenvVault: Cannot find .env.vault at ${vaultPath}" unless File.file?(vault_path)
115
+
116
+ # Parse .env.vault
117
+ parsed = Dotenv.parse(vault_path)
118
+
119
+ # Get ciphertext
120
+ environment_key = "DOTENV_VAULT_#{ENV["DOTENV_ENVIRONMENT"].upcase}"
121
+ ciphertext = parsed[environment_key] # DOTENV_VAULT_PRODUCTION
122
+ raise NotFoundDotenvEnvironment, "NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate #{environment_key} in .env.vault" unless ciphertext
123
+
124
+ # Decrypt ciphertext
125
+ decrypted = decrypt(ciphertext)
126
+
127
+ # Parse decrypted .env string
128
+ Dotenv::Parser.call(decrypted, true)
129
+ end
130
+
131
+ def using_vault?
132
+ present?(ENV["DOTENV_ENVIRONMENT"]) && present?(ENV["DOTENV_KEY"])
133
+ end
134
+
135
+ def present?(str)
136
+ !(str.nil? || str.empty?)
137
+ end
138
+
139
+ def decrypt(ciphertext)
140
+ raise NotFoundDotenvKey, "NOT_FOUND_DOTENV_KEY: Cannot find ENV['DOTENV_KEY']" unless present?(ENV["DOTENV_KEY"])
141
+
142
+ key = ENV["DOTENV_KEY"][-64..-1] # last 64 characters. allows for passing keys with preface like key_*****
143
+
144
+ raise InvalidDotenvKey, "INVALID_DOTENV_KEY: It must be 64 characters long (or more)" unless key.to_s.length == 64
145
+
146
+ lockbox = Lockbox.new(key: key, encode: true)
147
+ begin
148
+ lockbox.decrypt(ciphertext)
149
+ rescue Lockbox::Error
150
+ raise DecryptionFailed, "DECRYPTION_FAILED: Please check your DOTENV_KEY"
151
+ end
152
+ end
55
153
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dotenv-vault
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - motdotla
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-09-15 00:00:00.000000000 Z
11
+ date: 2022-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dotenv
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: lockbox
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement