codeword 0.2.0.beta3 → 0.2.0.beta4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -1
- data/README.md +5 -11
- data/app/controllers/codeword/codeword_controller.rb +12 -4
- data/app/helpers/codeword/codeword_helper.rb +1 -1
- data/codeword.gemspec +3 -3
- data/lib/codeword/authentication.rb +17 -0
- data/lib/codeword/configuration.rb +30 -0
- data/lib/codeword/version.rb +1 -1
- data/lib/codeword.rb +2 -43
- metadata +10 -9
- data/script/rails +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb390e385a9ce1fe7f4e8f987be5e02d1542795d209d74d282887f93cbc03c33
|
4
|
+
data.tar.gz: 9f53cfbc92b062d4c531d025535f93213ac7bebed588233aa37b7c7036501764
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 966df1e8a10079976ff0efe940935c67a634ae0de335d702e6c74a8af314d88c18d1beb97edf7dbdeb93e09e1c5e305ed355ae898a1799879d33c701b019cc5b
|
7
|
+
data.tar.gz: a62f1f572a373e268f661bfedfab93049f85ec034d07547735a7b5049d8920defd71a82aad11dba4137ae905278c3de4500eb94c4225ddefe2ce2b35aa0a3f97
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
- BREAKING: Only support namespaced Rails credentials under `codeword` (e.g. `codeword.codeword`, `codeword.hint`, `codeword.cookie_lifetime_in_weeks`)
|
3
4
|
- BREAKING: Drop support for Rails < 7.2
|
4
5
|
- BREAKING: Rename `check_for_codeword` to `require_codeword!`
|
5
6
|
- BREAKING: Deprecate Rails secrets in favor of Rails credentials
|
6
|
-
- BREAKING:
|
7
|
+
- BREAKING: Remove lowercase ENV variable support (only uppercase ENV variables are now supported)
|
8
|
+
|
9
|
+
- Prevent open redirects by using `allow_other_host: false`
|
10
|
+
- Harden cookie with `httponly: true`, `same_site: :lax`, and `secure: request.ssl?`
|
11
|
+
- `codeword_cookie_lifetime` now returns an `ActiveSupport::Duration`; cookie expiry uses `from_now`
|
12
|
+
- Updated crawler detection regex (removed duplicate `spider` and generic `click` token)
|
7
13
|
|
8
14
|
## [0.1.1] - 2021-12-17
|
9
15
|
|
data/README.md
CHANGED
@@ -21,22 +21,22 @@ gem 'codeword'
|
|
21
21
|
mount Codeword::Engine, at: '/codeword'
|
22
22
|
```
|
23
23
|
|
24
|
-
4. Include the `Codeword` module in your application_controller.rb file and check for codeword:
|
24
|
+
4. Include the `Codeword::Authentication` module in your application_controller.rb file and check for codeword:
|
25
25
|
|
26
26
|
```ruby
|
27
27
|
# app/controllers/application_controller.rb
|
28
28
|
class ApplicationController < ActionController::Base
|
29
|
-
include Codeword
|
29
|
+
include Codeword::Authentication
|
30
30
|
|
31
31
|
before_action :require_codeword!
|
32
32
|
end
|
33
33
|
```
|
34
34
|
|
35
|
-
5. Skip the check for codeword in the controller(s) you would like to
|
35
|
+
5. Skip the check for codeword in the controller(s) you would like to allow:
|
36
36
|
|
37
37
|
```ruby
|
38
38
|
class APIController < ApplicationController
|
39
|
-
skip_before_action :require_codeword
|
39
|
+
skip_before_action :require_codeword!
|
40
40
|
end
|
41
41
|
```
|
42
42
|
|
@@ -56,17 +56,11 @@ ENV['CODEWORD_HINT'] = 'Something that you do not tell everyone.'
|
|
56
56
|
|
57
57
|
You can add your codeword via Rails credentials in your `credentials.yml.enc` file (`$ bin/rails credentials:edit`):
|
58
58
|
|
59
|
-
```yml
|
60
|
-
codeword: "love"
|
61
|
-
codeword_hint: "Pepé Le Pew"
|
62
|
-
```
|
63
|
-
|
64
|
-
Alternately, credentials in Rails >= 5.2 may be organized under the `codeword` namespace:
|
65
|
-
|
66
59
|
```yml
|
67
60
|
codeword:
|
68
61
|
codeword: "love"
|
69
62
|
hint: "Pepé Le Pew"
|
63
|
+
cookie_lifetime_in_weeks: 4
|
70
64
|
```
|
71
65
|
|
72
66
|
**Codewords are not case-sensitive, by design. Keep it simple.**
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Codeword
|
2
2
|
class CodewordController < Codeword::ApplicationController
|
3
|
-
CRAWLER_REGEX = /crawl|googlebot|slurp|spider|bingbot|tracker|
|
3
|
+
CRAWLER_REGEX = /crawl|googlebot|slurp|spider|bingbot|tracker|parser/
|
4
4
|
|
5
5
|
skip_before_action :require_codeword!, raise: false
|
6
6
|
|
@@ -14,7 +14,7 @@ module Codeword
|
|
14
14
|
if params[:codeword].present?
|
15
15
|
@codeword = params[:codeword].to_s.downcase
|
16
16
|
@return_to = params[:return_to]
|
17
|
-
if @codeword == codeword_code.to_s.downcase
|
17
|
+
if @codeword == Codeword::Configuration.codeword_code.to_s.downcase
|
18
18
|
set_cookie
|
19
19
|
run_redirect
|
20
20
|
else
|
@@ -28,15 +28,23 @@ module Codeword
|
|
28
28
|
private
|
29
29
|
|
30
30
|
def set_cookie
|
31
|
-
cookies[:codeword] = {
|
31
|
+
cookies[:codeword] = {
|
32
|
+
value: @codeword.to_s.downcase,
|
33
|
+
expires: Codeword::Configuration.codeword_cookie_lifetime.from_now,
|
34
|
+
httponly: true,
|
35
|
+
secure: request.ssl?,
|
36
|
+
same_site: :lax
|
37
|
+
}
|
32
38
|
end
|
33
39
|
|
34
40
|
def run_redirect
|
35
41
|
if @return_to.present?
|
36
|
-
redirect_to @return_to.to_s
|
42
|
+
redirect_to @return_to.to_s, allow_other_host: false
|
37
43
|
else
|
38
44
|
redirect_to '/'
|
39
45
|
end
|
46
|
+
rescue ActionController::Redirecting::UnsafeRedirectError
|
47
|
+
redirect_to '/'
|
40
48
|
end
|
41
49
|
end
|
42
50
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Codeword
|
4
4
|
module CodewordHelper
|
5
5
|
def codeword_hint
|
6
|
-
@codeword_hint ||= ENV['CODEWORD_HINT'] ||
|
6
|
+
@codeword_hint ||= ENV['CODEWORD_HINT'] || Codeword::Configuration.from_credentials(:hint)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
data/codeword.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ['Dan Kim', 'gb Studio']
|
9
9
|
spec.email = ['git@dan.kim']
|
10
10
|
|
11
|
-
spec.summary = 'Lock staging servers from search engines and prying
|
11
|
+
spec.summary = 'Lock staging servers from search engines and prying eyes.'
|
12
12
|
spec.description = 'A simple gem to more elegantly place a staging server or other in-progress application behind a basic codeword. It’s easy to implement, share with clients/collaborators, and more beautiful than the typical password-protection sheet.'
|
13
13
|
spec.homepage = 'https://github.com/dankimio/codeword'
|
14
14
|
spec.license = 'MIT'
|
@@ -23,8 +23,8 @@ Gem::Specification.new do |spec|
|
|
23
23
|
|
24
24
|
spec.add_dependency 'rails', '>= 7.2'
|
25
25
|
|
26
|
-
spec.add_development_dependency 'capybara'
|
26
|
+
spec.add_development_dependency 'capybara'
|
27
27
|
spec.add_development_dependency 'debug'
|
28
28
|
spec.add_development_dependency 'launchy', '~> 2.4'
|
29
|
-
spec.add_development_dependency 'rspec-rails', '~>
|
29
|
+
spec.add_development_dependency 'rspec-rails', '~> 7.0'
|
30
30
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Codeword
|
2
|
+
module Authentication
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def require_codeword!
|
6
|
+
return unless respond_to?(:codeword) && Codeword::Configuration.codeword_code
|
7
|
+
return if cookies[:codeword].present? && cookies[:codeword] == Codeword::Configuration.codeword_code.to_s.downcase
|
8
|
+
|
9
|
+
redirect_to codeword.unlock_path(
|
10
|
+
return_to: request.fullpath.split('?codeword')[0],
|
11
|
+
codeword: params[:codeword]
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method :check_for_codeword, :require_codeword!
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Codeword
|
4
|
+
module Configuration
|
5
|
+
def self.from_credentials(setting)
|
6
|
+
store = Rails.application.credentials
|
7
|
+
|
8
|
+
store.dig(:codeword, setting)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.cookie_lifetime
|
12
|
+
@cookie_lifetime ||=
|
13
|
+
ENV['COOKIE_LIFETIME_IN_WEEKS'] ||
|
14
|
+
from_credentials(:cookie_lifetime_in_weeks)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.codeword_code
|
18
|
+
@codeword_code ||= ENV['CODEWORD'] || from_credentials(:codeword)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.codeword_cookie_lifetime
|
22
|
+
weeks = cookie_lifetime.to_f
|
23
|
+
if weeks.positive?
|
24
|
+
weeks.weeks
|
25
|
+
else
|
26
|
+
5.years
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/codeword/version.rb
CHANGED
data/lib/codeword.rb
CHANGED
@@ -1,49 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'codeword/engine'
|
4
|
+
require 'codeword/authentication'
|
5
|
+
require 'codeword/configuration'
|
4
6
|
|
5
7
|
module Codeword
|
6
|
-
extend ActiveSupport::Concern
|
7
|
-
|
8
|
-
def self.from_config(setting)
|
9
|
-
store = Rails.application.credentials
|
10
|
-
|
11
|
-
store.codeword.respond_to?(:fetch) &&
|
12
|
-
store.codeword.fetch(setting, store.public_send("codeword_#{setting}")) ||
|
13
|
-
store.public_send("codeword_#{setting}") || store.public_send(setting)
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def require_codeword!
|
19
|
-
return unless respond_to?(:codeword) && codeword_code
|
20
|
-
return if cookies[:codeword].present? && cookies[:codeword] == codeword_code.to_s.downcase
|
21
|
-
|
22
|
-
redirect_to codeword.unlock_path(
|
23
|
-
return_to: request.fullpath.split('?codeword')[0],
|
24
|
-
codeword: params[:codeword]
|
25
|
-
)
|
26
|
-
end
|
27
|
-
|
28
|
-
alias_method :check_for_codeword, :require_codeword!
|
29
|
-
|
30
|
-
def cookie_lifetime
|
31
|
-
@cookie_lifetime ||=
|
32
|
-
ENV['COOKIE_LIFETIME_IN_WEEKS'] ||
|
33
|
-
ENV['cookie_lifetime_in_weeks'] ||
|
34
|
-
Codeword.from_config(:cookie_lifetime_in_weeks)
|
35
|
-
end
|
36
|
-
|
37
|
-
def codeword_code
|
38
|
-
@codeword_code ||= ENV['CODEWORD'] || ENV['codeword'] || Codeword.from_config(:codeword)
|
39
|
-
end
|
40
|
-
|
41
|
-
def codeword_cookie_lifetime
|
42
|
-
seconds = (cookie_lifetime.to_f * 1.week).to_i
|
43
|
-
if seconds.positive?
|
44
|
-
seconds
|
45
|
-
else
|
46
|
-
5.years
|
47
|
-
end
|
48
|
-
end
|
49
8
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: codeword
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.0.
|
4
|
+
version: 0.2.0.beta4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Kim
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: capybara
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: debug
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '7.0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '7.0'
|
83
83
|
description: A simple gem to more elegantly place a staging server or other in-progress
|
84
84
|
application behind a basic codeword. It’s easy to implement, share with clients/collaborators,
|
85
85
|
and more beautiful than the typical password-protection sheet.
|
@@ -106,11 +106,12 @@ files:
|
|
106
106
|
- codeword.gemspec
|
107
107
|
- config/routes.rb
|
108
108
|
- lib/codeword.rb
|
109
|
+
- lib/codeword/authentication.rb
|
110
|
+
- lib/codeword/configuration.rb
|
109
111
|
- lib/codeword/engine.rb
|
110
112
|
- lib/codeword/version.rb
|
111
113
|
- mise.toml
|
112
114
|
- screenshot.png
|
113
|
-
- script/rails
|
114
115
|
homepage: https://github.com/dankimio/codeword
|
115
116
|
licenses:
|
116
117
|
- MIT
|
@@ -134,5 +135,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
135
|
requirements: []
|
135
136
|
rubygems_version: 3.7.1
|
136
137
|
specification_version: 4
|
137
|
-
summary: Lock staging servers from search engines and prying
|
138
|
+
summary: Lock staging servers from search engines and prying eyes.
|
138
139
|
test_files: []
|
data/script/rails
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
3
|
-
|
4
|
-
ENGINE_ROOT = File.expand_path('..', __dir__)
|
5
|
-
ENGINE_PATH = File.expand_path('../lib/codeword/engine', __dir__)
|
6
|
-
|
7
|
-
require 'rails/all'
|
8
|
-
require 'rails/engine/commands'
|