diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 6553e3a..90f4e35 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -11,7 +11,7 @@ jobs:
- name: Setup Ruby and install gems
uses: ruby/setup-ruby@v1
with:
- ruby-version: 3.3.3
+ ruby-version: 3.3.4
bundler-cache: true
- name: Run rubocop
run: |
@@ -53,7 +53,7 @@ jobs:
- name: Setup Ruby and install gems
uses: ruby/setup-ruby@v1
with:
- ruby-version: 3.3.3
+ ruby-version: 3.3.4
bundler-cache: true
- name: Setup test database
env:
diff --git a/.ruby-version b/.ruby-version
index 619b537..a0891f5 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-3.3.3
+3.3.4
diff --git a/Gemfile b/Gemfile
index 6e0e128..bd99405 100644
--- a/Gemfile
+++ b/Gemfile
@@ -3,25 +3,3 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
# Specify your gem's dependencies in audits1984.gemspec.
gemspec
-
-gem 'sqlite3'
-gem 'pg'
-gem 'mysql2'
-
-group :development do
- gem 'rubocop-rails-omakase', require: false
-end
-
-group :test do
- gem 'minitest'
-
- gem 'rails'
- gem 'sprockets-rails'
- gem 'puma'
-
- gem 'capybara'
- gem 'cuprite'
-end
-
-# To use a debugger
-# gem 'byebug', group: [:development, :test]
diff --git a/Gemfile.lock b/Gemfile.lock
index 986d48c..819b319 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -3,6 +3,7 @@ PATH
specs:
audits1984 (0.1.7)
console1984
+ importmap-rails (>= 1.2.1)
rinku
rouge
turbo-rails
@@ -99,6 +100,9 @@ GEM
capybara (~> 3.0)
ferrum (~> 0.14.0)
date (3.3.4)
+ debug (1.9.2)
+ irb (~> 1.10)
+ reline (>= 0.3.8)
erubi (1.12.0)
ferrum (0.14)
addressable (~> 2.5)
@@ -109,6 +113,10 @@ GEM
activesupport (>= 5.0)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
+ importmap-rails (2.0.3)
+ actionpack (>= 6.0.0)
+ activesupport (>= 6.0.0)
+ railties (>= 6.0.0)
io-console (0.7.2)
irb (1.14.0)
rdoc (>= 4.0.0)
@@ -133,6 +141,7 @@ GEM
date
net-protocol
net-pop (0.1.2)
+ net-protocol
net-protocol (0.2.2)
timeout
net-smtp (0.4.0)
@@ -145,6 +154,11 @@ GEM
parser (3.2.2.1)
ast (~> 2.4.1)
pg (1.5.3)
+ propshaft (1.1.0)
+ actionpack (>= 7.0.0)
+ activesupport (>= 7.0.0)
+ rack
+ railties (>= 7.0.0)
psych (5.1.2)
stringio
public_suffix (5.0.1)
@@ -220,13 +234,6 @@ GEM
rubocop-performance
rubocop-rails
ruby-progressbar (1.13.0)
- sprockets (4.2.0)
- concurrent-ruby (~> 1.0)
- rack (>= 2.2.4, < 4)
- sprockets-rails (3.4.2)
- actionpack (>= 5.2)
- activesupport (>= 5.2)
- sprockets (>= 3.0.0)
sqlite3 (1.6.3)
mini_portile2 (~> 2.8.0)
stringio (3.1.1)
@@ -257,14 +264,16 @@ DEPENDENCIES
audits1984!
capybara
cuprite
+ debug
minitest
mysql2
pg
+ propshaft
puma
- rails
+ rubocop (~> 1.52.0)
+ rubocop-performance
rubocop-rails-omakase
- sprockets-rails
sqlite3
BUNDLED WITH
- 2.2.33
+ 2.5.23
diff --git a/README.md b/README.md
index b0bb779..c74db61 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,21 @@ Mount the engine in your `routes.rb`:
mount Audits1984::Engine => "/console"
```
+### API-only apps or apps using `vite_rails` and other asset pipelines outside Rails
+
+If you want to use this gem with an [API-only Rails app](https://guides.rubyonrails.org/api_app.html) or an app that's using `vite_ruby`/`vite_rails`, or some other custom asset pipeline different from Sprockets and Propshaft, you need just one more thing: configure an asset pipeline so you can serve the JavaScript and CSS included in this gem. We recommend to use [`Propshaft`](https://github.com/rails/propshaft). You simply need to add this line to your application's Gemfile:
+
+```ruby
+gem "propshaft"
+```
+
+Then execute
+```bash
+$ bundle install
+```
+
+And you should be ready to go.
+
### Authenticate auditors
By default, the library controllers will inherit from the host application's `ApplicationController`. To authenticate auditors, you need to implement a method `#find_current_auditor` in your `ApplicationController`. This method must return a record representing the auditing user. It can be any model but it has to respond to `#name`.
diff --git a/app/assets/javascripts/audits1984/application.js b/app/assets/javascripts/audits1984/application.js
deleted file mode 100644
index fb85420..0000000
--- a/app/assets/javascripts/audits1984/application.js
+++ /dev/null
@@ -1,3 +0,0 @@
-//= include turbo
-
-//= require_directory .
\ No newline at end of file
diff --git a/app/controllers/audits1984/application_controller.rb b/app/controllers/audits1984/application_controller.rb
index 7ec2eae..b308d5b 100644
--- a/app/controllers/audits1984/application_controller.rb
+++ b/app/controllers/audits1984/application_controller.rb
@@ -1,9 +1,16 @@
module Audits1984
class ApplicationController < Audits1984.base_controller_class.constantize
+ ActionController::Base::MODULES.each do |mod|
+ include mod unless self < mod
+ end
+
before_action :authenticate_auditor
layout "audits1984/application"
+ helper Audits1984::ApplicationHelper unless self < Audits1984::ApplicationHelper
+ helper Importmap::ImportmapTagsHelper unless self < Importmap::ImportmapTagsHelper
+
private
def authenticate_auditor
unless respond_to?(:find_current_auditor, true)
diff --git a/app/javascript/audits1984/application.js b/app/javascript/audits1984/application.js
new file mode 100644
index 0000000..e524d16
--- /dev/null
+++ b/app/javascript/audits1984/application.js
@@ -0,0 +1,2 @@
+// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
+import "@hotwired/turbo-rails"
diff --git a/app/views/audits1984/sessions/index.html.erb b/app/views/audits1984/sessions/index.html.erb
index 3463b56..6337f45 100644
--- a/app/views/audits1984/sessions/index.html.erb
+++ b/app/views/audits1984/sessions/index.html.erb
@@ -1,8 +1,6 @@
<%= render "audits1984/sessions/filter", filtered_sessions: @filtered_sessions %>
<%= render "audits1984/sessions/summary", sessions: @sessions %>
-
-
- <%= render partial: "audits1984/sessions/session", collection: @sessions, cached: true %>
-
-
+
+ <%= render partial: "audits1984/sessions/session", collection: @sessions, cached: true %>
+
diff --git a/app/views/layouts/audits1984/application.html.erb b/app/views/layouts/audits1984/application.html.erb
index 594beb4..13bb11b 100644
--- a/app/views/layouts/audits1984/application.html.erb
+++ b/app/views/layouts/audits1984/application.html.erb
@@ -4,11 +4,11 @@
<%= @title || "Audits1984" %>
- <%= stylesheet_link_tag "audits1984/bulma.min" %>
<%= csrf_meta_tags %>
- <%= javascript_include_tag "audits1984/application", nonce: true, data: { turbo_track: :reload } %>
+ <%= stylesheet_link_tag "audits1984/bulma.min" %>
+ <%= javascript_importmap_tags "application", importmap: Audits1984.importmap %>
<%= stylesheet_link_tag "audits1984/application", media: :all, data: { turbo_track: :reload } %>
diff --git a/audits1984.gemspec b/audits1984.gemspec
index c1b6228..490869b 100644
--- a/audits1984.gemspec
+++ b/audits1984.gemspec
@@ -20,7 +20,21 @@ Gem::Specification.new do |spec|
spec.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]
spec.add_dependency "rouge"
+ spec.add_dependency "importmap-rails", ">= 1.2.1"
spec.add_dependency "turbo-rails"
spec.add_dependency "rinku"
spec.add_dependency "console1984"
+
+ spec.add_development_dependency "sqlite3"
+ spec.add_development_dependency "pg"
+ spec.add_development_dependency "mysql2"
+ spec.add_development_dependency "debug"
+ spec.add_development_dependency "rubocop", "~> 1.52.0"
+ spec.add_development_dependency "rubocop-performance"
+ spec.add_development_dependency "rubocop-rails-omakase"
+ spec.add_development_dependency "propshaft"
+ spec.add_development_dependency "puma"
+ spec.add_development_dependency "minitest"
+ spec.add_development_dependency "capybara"
+ spec.add_development_dependency "cuprite"
end
diff --git a/bin/setup b/bin/setup
index b404283..5c540c0 100755
--- a/bin/setup
+++ b/bin/setup
@@ -2,8 +2,14 @@
set -eu
cd "$(dirname "${BASH_SOURCE[0]}")"
-docker-compose up -d --remove-orphans
-docker-compose ps
+if docker compose version &> /dev/null; then
+ DOCKER_COMPOSE_CMD="docker compose"
+else
+ DOCKER_COMPOSE_CMD="docker-compose"
+fi
+
+$DOCKER_COMPOSE_CMD up -d --remove-orphans
+$DOCKER_COMPOSE_CMD ps
bundle
diff --git a/config/importmap.rb b/config/importmap.rb
new file mode 100644
index 0000000..acc37d8
--- /dev/null
+++ b/config/importmap.rb
@@ -0,0 +1,2 @@
+pin "application", to: "audits1984/application.js", preload: true
+pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
diff --git a/docker-compose.yml b/docker-compose.yml
index 87077ef..fa7dcea 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -5,12 +5,12 @@ volumes:
services:
mysql:
- image: percona:5.7.22
+ image: mysql:8.0.31
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
volumes:
- db:/var/lib/mysql
- ports: [ "127.0.0.1:33307:3306" ]
+ ports: [ "127.0.0.1:33060:3306" ]
postgres:
image: postgres:13.4
environment:
diff --git a/lib/audits1984.rb b/lib/audits1984.rb
index 2f66d3c..18f21de 100644
--- a/lib/audits1984.rb
+++ b/lib/audits1984.rb
@@ -9,4 +9,5 @@ module Audits1984
mattr_accessor :auditor_class, default: "::User"
mattr_accessor :auditor_name_attribute, default: :name
mattr_accessor :base_controller_class, default: "::ApplicationController"
+ mattr_accessor :importmap, default: Importmap::Map.new
end
diff --git a/lib/audits1984/engine.rb b/lib/audits1984/engine.rb
index cf6a58c..eb01dff 100644
--- a/lib/audits1984/engine.rb
+++ b/lib/audits1984/engine.rb
@@ -1,10 +1,19 @@
require "console1984"
-require 'rinku'
+require "importmap-rails"
+require "turbo-rails"
+require "rinku"
module Audits1984
class Engine < ::Rails::Engine
isolate_namespace Audits1984
+ initializer "audits1984.middleware" do |app|
+ if app.config.api_only
+ app.middleware.use ActionDispatch::Flash
+ app.middleware.use ::Rack::MethodOverride
+ end
+ end
+
config.audits1984 = ActiveSupport::OrderedOptions.new
initializer "audits1984.config" do
@@ -19,8 +28,19 @@ class Engine < ::Rails::Engine
end
end
- initializer "audits1984.assets.precompile" do |app|
+ initializer "audits1984.assets" do |app|
+ app.config.assets.paths << root.join("app/assets/stylesheets")
+ app.config.assets.paths << root.join("app/javascript")
app.config.assets.precompile << "audits1984_manifest.js"
end
+
+ initializer "audits1984.importmap", after: "importmap" do |app|
+ Audits1984.importmap.draw(root.join("config/importmap.rb"))
+ Audits1984.importmap.cache_sweeper(watches: root.join("app/javascript"))
+
+ ActiveSupport.on_load(:action_controller_base) do
+ before_action { Audits1984.importmap.cache_sweeper.execute_if_updated }
+ end
+ end
end
end
diff --git a/test/dummy/app/assets/config/manifest.js b/test/dummy/app/assets/config/manifest.js
deleted file mode 100644
index 558723b..0000000
--- a/test/dummy/app/assets/config/manifest.js
+++ /dev/null
@@ -1,3 +0,0 @@
-//= link_tree ../images
-//= link_directory ../stylesheets .css
-//= link audits1984_manifest.js
diff --git a/test/dummy/app/javascript/packs/application.js b/test/dummy/app/javascript/packs/application.js
deleted file mode 100644
index 67ce467..0000000
--- a/test/dummy/app/javascript/packs/application.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// This is a manifest file that'll be compiled into application.js, which will include all the files
-// listed below.
-//
-// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
-// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
-//
-// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
-// compiled file. JavaScript code in this file should be added after the last require_* statement.
-//
-// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
-// about supported directives.
-//
-//= require rails-ujs
-//= require activestorage
-//= require_tree .
diff --git a/test/dummy/config/application.rb b/test/dummy/config/application.rb
index 5869611..1d883bf 100644
--- a/test/dummy/config/application.rb
+++ b/test/dummy/config/application.rb
@@ -1,6 +1,7 @@
require_relative "boot"
require "rails/all"
+require "propshaft"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
diff --git a/test/dummy/db/seeds.rb b/test/dummy/db/seeds.rb
new file mode 100644
index 0000000..1d0be49
--- /dev/null
+++ b/test/dummy/db/seeds.rb
@@ -0,0 +1,65 @@
+# Clear existing data to avoid duplication
+Console1984::User.destroy_all
+Console1984::Session.destroy_all
+Console1984::Command.destroy_all
+Console1984::SensitiveAccess.destroy_all
+
+# Seed Users
+users = [
+ { username: "alice_wonder" },
+ { username: "bob_builder" },
+ { username: "charlie_day" }
+].map do |user_attrs|
+ Console1984::User.create!(user_attrs)
+end
+
+puts "#{Console1984::User.count} users created!"
+
+# Seed Sessions
+sessions = users.map do |user|
+ Array.new(2) do # Create 2 sessions per user
+ Console1984::Session.create!(
+ user: user,
+ reason: [ "Debugging issue", "Performance testing", "Feature testing" ].sample,
+ created_at: rand(1..30).days.ago,
+ updated_at: Time.now
+ )
+ end
+end.flatten
+
+puts "#{Console1984::Session.count} sessions created!"
+
+# Seed SensitiveAccess
+sensitive_accesses = sessions.map do |session|
+ Array.new(2) do # Create 2 sensitive accesses per session
+ Console1984::SensitiveAccess.create!(
+ session: session,
+ justification: [ "Accessing protected data", "Investigating security issues" ].sample,
+ created_at: rand(1..30).days.ago,
+ updated_at: Time.now
+ )
+ end
+end.flatten
+
+puts "#{Console1984::SensitiveAccess.count} sensitive accesses created!"
+
+# Seed Commands with Ruby statements
+commands = sessions.map do |session|
+ Array.new(5) do # Create 5 commands per session
+ Console1984::Command.create!(
+ session: session,
+ sensitive_access: [ nil, sensitive_accesses.sample ].sample, # Randomly associate with a sensitive access or not
+ statements: [
+ "User.find_by(username: 'alice_wonder')",
+ "Project.all.map(&:name)",
+ "User.last.update!(admin: true)",
+ "Order.pending.count",
+ "Rails.logger.info 'Debugging session started'"
+ ].sample,
+ created_at: rand(1..30).days.ago,
+ updated_at: Time.now
+ )
+ end
+end.flatten
+
+puts "#{Console1984::Command.count} commands created!"