securial 0.4.2
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +90 -0
- data/Rakefile +8 -0
- data/app/controllers/concerns/securial/identity.rb +67 -0
- data/app/controllers/securial/accounts_controller.rb +60 -0
- data/app/controllers/securial/application_controller.rb +18 -0
- data/app/controllers/securial/passwords_controller.rb +35 -0
- data/app/controllers/securial/role_assignments_controller.rb +49 -0
- data/app/controllers/securial/roles_controller.rb +44 -0
- data/app/controllers/securial/sessions_controller.rb +76 -0
- data/app/controllers/securial/status_controller.rb +9 -0
- data/app/controllers/securial/users_controller.rb +53 -0
- data/app/jobs/securial/application_job.rb +4 -0
- data/app/mailers/securial/application_mailer.rb +6 -0
- data/app/mailers/securial/securial_mailer.rb +17 -0
- data/app/models/concerns/securial/password_resettable.rb +47 -0
- data/app/models/securial/application_record.rb +18 -0
- data/app/models/securial/current.rb +6 -0
- data/app/models/securial/role.rb +10 -0
- data/app/models/securial/role_assignment.rb +6 -0
- data/app/models/securial/session.rb +27 -0
- data/app/models/securial/user.rb +54 -0
- data/app/views/layouts/securial/mailer.html.erb +13 -0
- data/app/views/layouts/securial/mailer.text.erb +1 -0
- data/app/views/securial/accounts/show.json.jbuilder +1 -0
- data/app/views/securial/passwords/_password.json.jbuilder +2 -0
- data/app/views/securial/passwords/index.json.jbuilder +1 -0
- data/app/views/securial/passwords/show.json.jbuilder +1 -0
- data/app/views/securial/role_assignments/show.json.jbuilder +1 -0
- data/app/views/securial/roles/_securial_role.json.jbuilder +9 -0
- data/app/views/securial/roles/index.json.jbuilder +6 -0
- data/app/views/securial/roles/show.json.jbuilder +1 -0
- data/app/views/securial/securial_mailer/reset_password.html.erb +5 -0
- data/app/views/securial/securial_mailer/reset_password.text.erb +4 -0
- data/app/views/securial/sessions/_session.json.jbuilder +15 -0
- data/app/views/securial/sessions/index.json.jbuilder +6 -0
- data/app/views/securial/sessions/show.json.jbuilder +1 -0
- data/app/views/securial/status/show.json.jbuilder +3 -0
- data/app/views/securial/users/_securial_user.json.jbuilder +14 -0
- data/app/views/securial/users/index.json.jbuilder +6 -0
- data/app/views/securial/users/show.json.jbuilder +1 -0
- data/bin/securial +58 -0
- data/config/routes.rb +41 -0
- data/db/migrate/20250515104930_create_securial_roles.rb +12 -0
- data/db/migrate/20250517155521_create_securial_users.rb +18 -0
- data/db/migrate/20250518122749_create_securial_role_assignments.rb +10 -0
- data/db/migrate/20250519075407_create_securial_sessions.rb +15 -0
- data/db/migrate/20250524210207_add_password_reset_fields_to_securial_users.rb +6 -0
- data/lib/generators/factory_bot/model/model_generator.rb +31 -0
- data/lib/generators/factory_bot/templates/factory.erb +7 -0
- data/lib/generators/securial/install/install_generator.rb +37 -0
- data/lib/generators/securial/install/templates/securial_initializer.erb +109 -0
- data/lib/generators/securial/jbuilder/jbuilder_generator.rb +52 -0
- data/lib/generators/securial/jbuilder/templates/_resource.json.erb +10 -0
- data/lib/generators/securial/jbuilder/templates/index.json.erb +7 -0
- data/lib/generators/securial/jbuilder/templates/show.json.erb +1 -0
- data/lib/generators/securial/scaffold/scaffold_generator.rb +146 -0
- data/lib/generators/securial/scaffold/templates/controller.erb +44 -0
- data/lib/generators/securial/scaffold/templates/request_spec.erb +61 -0
- data/lib/generators/securial/scaffold/templates/routes.erb +11 -0
- data/lib/generators/securial/scaffold/templates/routing_spec.erb +31 -0
- data/lib/securial/configuration.rb +35 -0
- data/lib/securial/engine.rb +89 -0
- data/lib/securial/errors/config_errors.rb +12 -0
- data/lib/securial/errors/session_errors.rb +6 -0
- data/lib/securial/factories/securial/role_assignments.rb +6 -0
- data/lib/securial/factories/securial/roles.rb +18 -0
- data/lib/securial/factories/securial/sessions.rb +12 -0
- data/lib/securial/factories/securial/users.rb +17 -0
- data/lib/securial/helpers/auth_helper.rb +46 -0
- data/lib/securial/helpers/normalizing_helper.rb +17 -0
- data/lib/securial/helpers/regex_helper.rb +17 -0
- data/lib/securial/logger.rb +71 -0
- data/lib/securial/middleware/request_logger_tag.rb +18 -0
- data/lib/securial/route_inspector.rb +50 -0
- data/lib/securial/version.rb +3 -0
- data/lib/securial.rb +94 -0
- data/lib/tasks/securial_tasks.rake +4 -0
- metadata +435 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
module Securial
|
2
|
+
class Session < ApplicationRecord
|
3
|
+
belongs_to :user
|
4
|
+
|
5
|
+
validates :ip_address, presence: true
|
6
|
+
validates :user_agent, presence: true
|
7
|
+
validates :refresh_token, presence: true
|
8
|
+
|
9
|
+
def revoke!
|
10
|
+
update!(revoked: true)
|
11
|
+
end
|
12
|
+
|
13
|
+
def is_valid_session?
|
14
|
+
!revoked && refresh_token_expires_at > Time.current
|
15
|
+
end
|
16
|
+
|
17
|
+
def refresh!
|
18
|
+
raise Securial::SessionErrors::SessionRevokedError, "Session is revoked" if revoked
|
19
|
+
raise Securial::SessionErrors::SessionExpiredError, "Session is expired" if refresh_token_expires_at < Time.current
|
20
|
+
|
21
|
+
update!(refresh_token: SecureRandom.hex(64),
|
22
|
+
refresh_count: self.refresh_count + 1,
|
23
|
+
last_refreshed_at: Time.current,
|
24
|
+
refresh_token_expires_at: 1.week.from_now)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Securial
|
2
|
+
class User < ApplicationRecord
|
3
|
+
include Securial::PasswordResettable
|
4
|
+
|
5
|
+
normalizes :email_address, with: ->(e) { Securial::NormalizingHelper.normalize_email_address(e) }
|
6
|
+
|
7
|
+
validates :email_address,
|
8
|
+
presence: true,
|
9
|
+
uniqueness: true,
|
10
|
+
length: {
|
11
|
+
minimum: 5,
|
12
|
+
maximum: 255,
|
13
|
+
},
|
14
|
+
format: {
|
15
|
+
with: Securial::RegexHelper::EMAIL_REGEX,
|
16
|
+
message: "must be a valid email address",
|
17
|
+
}
|
18
|
+
|
19
|
+
validates :username,
|
20
|
+
presence: true,
|
21
|
+
uniqueness: { case_sensitive: false },
|
22
|
+
length: { maximum: 20 },
|
23
|
+
format: {
|
24
|
+
with: Securial::RegexHelper::USERNAME_REGEX,
|
25
|
+
message: "can only contain letters, numbers, underscores, and periods, but cannot start with a number or contain consecutive underscores or periods",
|
26
|
+
}
|
27
|
+
|
28
|
+
validates :first_name,
|
29
|
+
presence: true,
|
30
|
+
length: { maximum: 50 }
|
31
|
+
validates :last_name,
|
32
|
+
presence: true,
|
33
|
+
length: { maximum: 50 }
|
34
|
+
|
35
|
+
validates :phone,
|
36
|
+
length: { maximum: 15 },
|
37
|
+
allow_blank: true
|
38
|
+
validates :bio,
|
39
|
+
length: { maximum: 1000 },
|
40
|
+
allow_blank: true
|
41
|
+
|
42
|
+
has_many :role_assignments, dependent: :destroy
|
43
|
+
has_many :roles, through: :role_assignments
|
44
|
+
|
45
|
+
has_many :sessions, dependent: :destroy
|
46
|
+
|
47
|
+
|
48
|
+
def is_admin?
|
49
|
+
titleized_role_name = Securial.configuration.admin_role.to_s.strip.titleize
|
50
|
+
|
51
|
+
roles.exists?(role_name: titleized_role_name)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= yield %>
|
@@ -0,0 +1 @@
|
|
1
|
+
json.partial! "securial/users/securial_user", securial_user: @securial_user
|
@@ -0,0 +1 @@
|
|
1
|
+
json.array! @passwords, partial: "securial/passwords/password", as: :password
|
@@ -0,0 +1 @@
|
|
1
|
+
json.partial! "securial/passwords/password", password: @password
|
@@ -0,0 +1 @@
|
|
1
|
+
json.partial! "securial/users/securial_user", securial_user: @securial_user
|
@@ -0,0 +1,9 @@
|
|
1
|
+
json.id securial_role.id
|
2
|
+
|
3
|
+
json.role_name securial_role.role_name
|
4
|
+
json.hide_from_profile securial_role.hide_from_profile
|
5
|
+
|
6
|
+
json.created_at securial_role.created_at
|
7
|
+
json.updated_at securial_role.updated_at
|
8
|
+
|
9
|
+
json.url securial.roles_url(securial_role, format: :json)
|
@@ -0,0 +1 @@
|
|
1
|
+
json.partial! "securial/roles/securial_role", securial_role: @securial_role
|
@@ -0,0 +1,15 @@
|
|
1
|
+
json.id securial_session.id
|
2
|
+
|
3
|
+
json.ip_address securial_session.ip_address
|
4
|
+
json.user_agent securial_session.user_agent
|
5
|
+
json.refresh_count securial_session.refresh_count
|
6
|
+
json.refresh_token securial_session.refresh_token
|
7
|
+
json.last_refreshed_at securial_session.last_refreshed_at
|
8
|
+
json.refresh_token_expires_at securial_session.refresh_token_expires_at
|
9
|
+
json.revoked securial_session.revoked
|
10
|
+
json.user_id securial_session.user_id
|
11
|
+
|
12
|
+
json.created_at securial_session.created_at
|
13
|
+
json.updated_at securial_session.updated_at
|
14
|
+
|
15
|
+
json.url "No URL available for this action"
|
@@ -0,0 +1 @@
|
|
1
|
+
json.partial! "securial/sessions/session", securial_session: @securial_session
|
@@ -0,0 +1,14 @@
|
|
1
|
+
json.id securial_user.id
|
2
|
+
|
3
|
+
json.first_name securial_user.first_name
|
4
|
+
json.last_name securial_user.last_name
|
5
|
+
json.phone securial_user.phone
|
6
|
+
json.username securial_user.username
|
7
|
+
json.bio securial_user.bio
|
8
|
+
|
9
|
+
json.roles securial_user.roles, partial: "securial/roles/securial_role", as: :securial_role
|
10
|
+
|
11
|
+
json.created_at securial_user.created_at
|
12
|
+
json.updated_at securial_user.updated_at
|
13
|
+
|
14
|
+
json.url securial.user_url(securial_user, format: :json)
|
@@ -0,0 +1 @@
|
|
1
|
+
json.partial! "securial/users/securial_user", securial_user: @securial_user
|
data/bin/securial
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
|
5
|
+
def run(command, chdir: nil)
|
6
|
+
puts "→ #{command}"
|
7
|
+
if chdir
|
8
|
+
Dir.chdir(chdir) do
|
9
|
+
system(command) || abort("❌ Command failed: #{command}")
|
10
|
+
end
|
11
|
+
else
|
12
|
+
system(command) || abort("❌ Command failed: #{command}")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def securial_new(app_name, rails_options)
|
18
|
+
puts "🛠 Creating new Rails app: #{app_name}"
|
19
|
+
|
20
|
+
# Step 1: Forward options to `rails new`
|
21
|
+
rails_command = ["rails", "new", app_name, *rails_options].join(" ")
|
22
|
+
run(rails_command)
|
23
|
+
|
24
|
+
# Step 2: Append securial gem to the Gemfile
|
25
|
+
gemfile_path = File.join(app_name, "Gemfile")
|
26
|
+
File.open(gemfile_path, "a") do |f|
|
27
|
+
f.puts "\ngem 'securial'"
|
28
|
+
end
|
29
|
+
|
30
|
+
# Step 3: Install gems
|
31
|
+
run("bundle install", chdir: app_name)
|
32
|
+
|
33
|
+
# Step 4: Install securial
|
34
|
+
run("bin/rails generate securial:install", chdir: app_name)
|
35
|
+
run("bin/rails db:migrate", chdir: app_name)
|
36
|
+
|
37
|
+
# Step 5: Mount the engine
|
38
|
+
routes_path = File.join(app_name, "config/routes.rb")
|
39
|
+
routes = File.read(routes_path)
|
40
|
+
updated = routes.sub("Rails.application.routes.draw do") do |match|
|
41
|
+
"#{match}\n mount Securial::Engine => '/securial'"
|
42
|
+
end
|
43
|
+
File.write(routes_path, updated)
|
44
|
+
|
45
|
+
puts "\n✅ Done! Your app is ready at: ./#{app_name}"
|
46
|
+
puts "➡️ Next steps:"
|
47
|
+
puts " cd #{app_name}"
|
48
|
+
puts " rails server"
|
49
|
+
end
|
50
|
+
|
51
|
+
if ARGV[0] == "new" && ARGV[1]
|
52
|
+
app_name = ARGV[1]
|
53
|
+
rails_options = ARGV[2..] || []
|
54
|
+
securial_new(app_name, rails_options)
|
55
|
+
else
|
56
|
+
puts "Usage: securial new app_name [rails_options...]"
|
57
|
+
puts "Example: securial new myapp --api --database=postgresql"
|
58
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
Securial::Engine.routes.draw do
|
2
|
+
defaults format: :json do
|
3
|
+
get "/status", to: "status#show", as: :status
|
4
|
+
|
5
|
+
scope Securial.admin_namespace do
|
6
|
+
resources :roles
|
7
|
+
resources :users
|
8
|
+
namespace :role_assignments, as: "role_assignments" do
|
9
|
+
post "assign", action: :create, as: "assign"
|
10
|
+
delete "revoke", action: :destroy, as: "revoke"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
scope "accounts" do
|
15
|
+
get "me", to: "accounts#me", as: :me
|
16
|
+
get "account/:username", to: "accounts#show", as: :account_by_username
|
17
|
+
post "register", to: "accounts#register", as: :register
|
18
|
+
put "update", to: "accounts#update_profile", as: :update_profile
|
19
|
+
# post "update_avatar", to: "accounts#update_avatar"
|
20
|
+
# post "update_notification_settings", to: "accounts#update_notification_settings"
|
21
|
+
delete "delete_account", to: "accounts#delete_account", as: :delete_account
|
22
|
+
end
|
23
|
+
|
24
|
+
scope "sessions" do
|
25
|
+
get "", to: "sessions#index", as: :index_sessions
|
26
|
+
get "current", to: "sessions#show", as: :current_session
|
27
|
+
get "id/:id", to: "sessions#show", as: :session
|
28
|
+
post "login", to: "sessions#login", as: :login
|
29
|
+
delete "logout", to: "sessions#logout", as: :logout
|
30
|
+
put "refresh", to: "sessions#refresh", as: :refresh_session
|
31
|
+
delete "revoke", to: "sessions#revoke", as: :revoke_current_session
|
32
|
+
delete "id/:id/revoke", to: "sessions#revoke", as: :revoke_session_by_id
|
33
|
+
delete "revoke_all", to: "sessions#revoke_all", as: :revoke_all_sessions
|
34
|
+
end
|
35
|
+
|
36
|
+
scope "password" do
|
37
|
+
post "forgot", to: "passwords#forgot_password", as: :forgot_password
|
38
|
+
put "reset", to: "passwords#reset_password", as: :reset_password
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateSecurialRoles < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :securial_roles, id: :string do |t|
|
4
|
+
t.string :role_name
|
5
|
+
t.boolean :hide_from_profile, default: false, null: false
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
|
10
|
+
add_index :securial_roles, :role_name, unique: true
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CreateSecurialUsers < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :securial_users, id: :string do |t|
|
4
|
+
t.string :email_address
|
5
|
+
t.string :password_digest
|
6
|
+
t.string :first_name
|
7
|
+
t.string :last_name
|
8
|
+
t.string :phone
|
9
|
+
t.string :username
|
10
|
+
t.string :bio
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
|
15
|
+
add_index :securial_users, :email_address, unique: true
|
16
|
+
add_index :securial_users, :username, unique: true
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class CreateSecurialRoleAssignments < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :securial_role_assignments, id: :string do |t|
|
4
|
+
t.references :user, null: false, type: :string, foreign_key: { to_table: :securial_users }
|
5
|
+
t.references :role, null: false, type: :string, foreign_key: { to_table: :securial_roles }
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateSecurialSessions < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :securial_sessions, id: :string do |t|
|
4
|
+
t.references :user, null: false, type: :string, foreign_key: { to_table: :securial_users }
|
5
|
+
t.string :ip_address, null: false
|
6
|
+
t.string :user_agent, null: false
|
7
|
+
t.string :refresh_token, null: false
|
8
|
+
t.integer :refresh_count, default: 0
|
9
|
+
t.datetime :last_refreshed_at
|
10
|
+
t.datetime :refresh_token_expires_at
|
11
|
+
t.boolean :revoked, default: false, null: false
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "rails/generators"
|
2
|
+
require "rails/generators/named_base"
|
3
|
+
|
4
|
+
module FactoryBot
|
5
|
+
module Generators
|
6
|
+
class ModelGenerator < Rails::Generators::NamedBase
|
7
|
+
source_root File.expand_path("../templates", __dir__)
|
8
|
+
|
9
|
+
argument :attributes, type: :array, default: [], banner: "field[:type] field[:type]"
|
10
|
+
|
11
|
+
def create_factory_file
|
12
|
+
template "factory.erb", File.join("lib/securial/factories/securial", "#{file_name.pluralize}.rb")
|
13
|
+
end
|
14
|
+
|
15
|
+
# Helper method accessible in the template
|
16
|
+
def securial_attribute_defaults
|
17
|
+
{
|
18
|
+
string: '"MyString"',
|
19
|
+
text: '"MyText"',
|
20
|
+
integer: "1",
|
21
|
+
float: "1.5",
|
22
|
+
decimal: '"9.99"',
|
23
|
+
datetime: "Time.zone.now",
|
24
|
+
time: "Time.zone.now",
|
25
|
+
date: "Time.zone.now",
|
26
|
+
boolean: "false",
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "rails/generators"
|
2
|
+
require "rake"
|
3
|
+
|
4
|
+
module Securial
|
5
|
+
module Generators
|
6
|
+
class InstallGenerator < Rails::Generators::Base
|
7
|
+
source_root File.expand_path("templates", __dir__)
|
8
|
+
|
9
|
+
desc "initializes Securial in your application."
|
10
|
+
|
11
|
+
def copy_initializer
|
12
|
+
say_status("copying", "Securial Initializers", :green)
|
13
|
+
template "securial_initializer.erb", "config/initializers/securial.rb"
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_log_file
|
17
|
+
say_status("creating", "Securial Log file", :green)
|
18
|
+
log_dir = Rails.root.join("log")
|
19
|
+
securial_log = log_dir.join("securial.log")
|
20
|
+
|
21
|
+
FileUtils.mkdir_p(log_dir) unless File.directory?(log_dir)
|
22
|
+
FileUtils.touch(securial_log) unless File.exist?(securial_log)
|
23
|
+
end
|
24
|
+
|
25
|
+
def install_migrations
|
26
|
+
say_status("copying", "Securial migrations", :green)
|
27
|
+
Rails.application.load_tasks unless Rake::Task.task_defined?("securial:install:migrations")
|
28
|
+
|
29
|
+
should_not_invoke = Rails.root.to_s.include?("spec/dummy") ||
|
30
|
+
Rails.root.to_s.include?("tmp") ||
|
31
|
+
Rails.env.test?
|
32
|
+
|
33
|
+
Rake::Task["securial:install:migrations"].invoke unless should_not_invoke
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# This file was generated by the Securial engine.
|
2
|
+
|
3
|
+
Securial.configure do |config|
|
4
|
+
##### Logging Configuration
|
5
|
+
## Enable or disable logging to file
|
6
|
+
# Set to true to log to a file, false to disable file logging
|
7
|
+
config.log_to_file = true
|
8
|
+
|
9
|
+
## Enable or disable logging to STDOUT
|
10
|
+
# Set to true to log to STDOUT, false to disable STDOUT logging
|
11
|
+
config.log_to_stdout = true # Enable or disable logging to STDOUT
|
12
|
+
|
13
|
+
# Set log level for file logger: :debug, :info, :warn, :error, :fatal, or :unknown
|
14
|
+
config.log_file_level = :info
|
15
|
+
|
16
|
+
# Set log level for stdout logger
|
17
|
+
config.log_stdout_level = :info
|
18
|
+
|
19
|
+
##### User Roles
|
20
|
+
## Set the role for admin users
|
21
|
+
# This role is used to determine access levels and permissions
|
22
|
+
# for different user types in the application. including access
|
23
|
+
# to specific features and actions.
|
24
|
+
# e.g. if the admin role is set to :superuser, then users with this role
|
25
|
+
# will have access to the admin dashboard and other admin features.
|
26
|
+
# in the `/securial/superusers` namespace.
|
27
|
+
config.admin_role = :admin
|
28
|
+
|
29
|
+
#### Session Configuration
|
30
|
+
## Set the session expiration duration
|
31
|
+
# This is the time after which a session will be considered expired.
|
32
|
+
# After this time, the session will be invalidated and the user
|
33
|
+
# will need to log in again to refresh the session.
|
34
|
+
# The expiration time is set in seconds, minutes, or hours.
|
35
|
+
# The default is 3 minutes.
|
36
|
+
config.session_expiration_duration = 3.minutes
|
37
|
+
|
38
|
+
## Set the session renewal duration
|
39
|
+
# This is the time after which a session will be renewed.
|
40
|
+
# After this time, the session will be renewed and the expiration
|
41
|
+
# time will be extended. This is useful for keeping users logged in
|
42
|
+
# without requiring them to log in again. The renewal time is set
|
43
|
+
# in seconds, minutes, or hours. The default is 3 days.
|
44
|
+
config.session_renewal_duration = 3.days
|
45
|
+
|
46
|
+
## Set the session secret
|
47
|
+
# This secret is used to sign the session tokens and ensure
|
48
|
+
# that they cannot be tampered with. It is important to keep this
|
49
|
+
# secret secure and not share it with anyone.
|
50
|
+
# The default is "secret".
|
51
|
+
config.session_secret = "secret"
|
52
|
+
|
53
|
+
## Set the session algorithm
|
54
|
+
# This is the algorithm used to sign the session tokens.
|
55
|
+
# The default is :hs256, which is a HMAC SHA-256 algorithm.
|
56
|
+
# Other options include :hs256, :hs384, and :hs512
|
57
|
+
config.session_algorithm = :hs256
|
58
|
+
|
59
|
+
#### Securial Mailer Configuration
|
60
|
+
## Set the mailer sender address
|
61
|
+
# This is the email address that will be used as the sender
|
62
|
+
# for all emails sent by the Securial engine. This includes
|
63
|
+
# emails for password resets, account verification, and other
|
64
|
+
# notifications.
|
65
|
+
config.mailer_sender = "no-reply@example.com"
|
66
|
+
|
67
|
+
#### Password configuration
|
68
|
+
## Set the password reset email subject
|
69
|
+
# This is the subject line that will be used for the password reset
|
70
|
+
# email. The default is "Password Reset Instructions".
|
71
|
+
config.password_reset_email_subject = "Password Reset Instructions"
|
72
|
+
|
73
|
+
## Set the minimum password length
|
74
|
+
# This is the minimum length that a password must have
|
75
|
+
# in order to be considered valid. The default is 8 characters.
|
76
|
+
config.password_min_length = 8
|
77
|
+
|
78
|
+
## Set the maximum password length
|
79
|
+
# This is the maximum length that a password can have
|
80
|
+
# in order to be considered valid. The default is 128 characters.
|
81
|
+
config.password_max_length = 128
|
82
|
+
|
83
|
+
## Set the password complexity requirements
|
84
|
+
# This is a regular expression that defines the complexity
|
85
|
+
# requirements for a password. The default is a regex that
|
86
|
+
# requires at least one uppercase letter, one lowercase letter,
|
87
|
+
# one digit, and one special character.
|
88
|
+
config.password_complexity = Securial::RegexHelper::PASSWORD_REGEX
|
89
|
+
|
90
|
+
## Set the password expiration duration
|
91
|
+
# This is the time after which a password will be considered expired.
|
92
|
+
# After this time, the user will need to change their password
|
93
|
+
# in order to log in again. The expiration time is set in seconds,
|
94
|
+
# minutes, or hours. The default is 90 days.
|
95
|
+
config.password_expires_in = 90.days
|
96
|
+
|
97
|
+
## Set the password reset token expiration duration
|
98
|
+
# This is the time after which a password reset token will be considered expired.
|
99
|
+
# After this time, the token will no longer be valid and the user
|
100
|
+
# will need to request a new password reset token. The expiration time
|
101
|
+
# is set in seconds, minutes, or hours. The default is 2 hours.
|
102
|
+
config.reset_password_token_expires_in = 2.hours
|
103
|
+
|
104
|
+
## Set the password reset token secret
|
105
|
+
# This secret is used to sign the password reset tokens and ensure
|
106
|
+
# that they cannot be tampered with. It is important to keep this
|
107
|
+
# secret secure and not share it with anyone.
|
108
|
+
config.reset_password_token_secret = "reset_secret"
|
109
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Securial
|
2
|
+
module Generators
|
3
|
+
class JbuilderGenerator < Rails::Generators::NamedBase
|
4
|
+
source_root File.expand_path("templates", __dir__)
|
5
|
+
|
6
|
+
argument :attributes, type: :array, default: [], banner: "field:type field:type"
|
7
|
+
|
8
|
+
def create_view_files
|
9
|
+
create_resource_file
|
10
|
+
create_index_file
|
11
|
+
create_show_file
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def attributes_names
|
17
|
+
attributes.map(&:name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_resource_file
|
21
|
+
@resource_path_name = File.join(view_path, "_#{singular_table_name}.json.jbuilder")
|
22
|
+
say_status(status_behavior, " #{@resource_path_name}", status_color) unless Rails.env.test?
|
23
|
+
template "_resource.json.erb", @resource_path_name, verbose: false
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_index_file
|
27
|
+
@index_path_name = File.join(view_path, "index.json.jbuilder")
|
28
|
+
say_status(status_behavior, " #{@index_path_name}", status_color) unless Rails.env.test?
|
29
|
+
template "index.json.erb", @index_path_name, verbose: false
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_show_file
|
33
|
+
@show_path_name = File.join(view_path, "show.json.jbuilder")
|
34
|
+
say_status(status_behavior, " #{@show_path_name}", status_color) unless Rails.env.test?
|
35
|
+
template "show.json.erb", @show_path_name, verbose: false
|
36
|
+
end
|
37
|
+
|
38
|
+
def view_path
|
39
|
+
base_path = Rails.env.test? ? Rails.root.join("tmp/app/views/securial").to_s : "app/views/securial"
|
40
|
+
@view_path ||= File.join(base_path, name.pluralize.downcase)
|
41
|
+
end
|
42
|
+
|
43
|
+
def status_behavior
|
44
|
+
behavior == :invoke ? :create : :remove
|
45
|
+
end
|
46
|
+
|
47
|
+
def status_color
|
48
|
+
behavior == :invoke ? :green : :red
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
json.id <%= singular_table_name %>.id
|
2
|
+
|
3
|
+
<% attributes_names.each do |attr| -%>
|
4
|
+
json.<%= attr %> <%= singular_table_name %>.<%= attr %>
|
5
|
+
<% end -%>
|
6
|
+
|
7
|
+
json.created_at <%= singular_table_name %>.created_at
|
8
|
+
json.updated_at <%= singular_table_name %>.updated_at
|
9
|
+
|
10
|
+
json.url securial.<%= name.pluralize.downcase %>_url(<%= singular_table_name %>, format: :json)
|
@@ -0,0 +1,7 @@
|
|
1
|
+
json.records @<%= plural_table_name %> do |<%= singular_table_name %>|
|
2
|
+
json.partial! "securial/<%= name.pluralize.downcase %>/<%= singular_table_name %>", <%= singular_table_name %>: <%= singular_table_name %>
|
3
|
+
end
|
4
|
+
|
5
|
+
json.count @<%= plural_table_name %>.count
|
6
|
+
json.url securial.<%= name.pluralize.downcase %>_url(format: :json)
|
7
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
json.partial! "securial/<%= name.pluralize.downcase %>/<%= singular_table_name %>", <%= singular_table_name %>: @<%= singular_table_name %>
|