omni_events 0.1.1
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/.rspec +3 -0
- data/CHANGELOG.md +25 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +249 -0
- data/LICENSE.txt +21 -0
- data/README.md +461 -0
- data/Rakefile +8 -0
- data/app/controllers/omni_event/receiver_controller.rb +38 -0
- data/app/jobs/omni_event/new_relic_job.rb +45 -0
- data/app/jobs/omni_event/process_webhook_job.rb +10 -0
- data/app/models/omni_event/application_record.rb +5 -0
- data/app/models/omni_event/log.rb +20 -0
- data/app/models/omni_event/notifier.rb +34 -0
- data/app/models/omni_event/webhook_event.rb +35 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20240101000001_create_omni_event_notifiers.rb +13 -0
- data/db/migrate/20240101000002_create_omni_event_webhook_events.rb +14 -0
- data/db/migrate/20240101000003_create_omni_event_logs.rb +14 -0
- data/db/migrate/20240101000004_add_security_to_omni_event_notifiers.rb +8 -0
- data/lib/generators/omni_event/install_generator.rb +78 -0
- data/lib/omni_event/base_processor.rb +50 -0
- data/lib/omni_event/configuration.rb +23 -0
- data/lib/omni_event/engine.rb +5 -0
- data/lib/omni_event/process_dispatcher.rb +42 -0
- data/lib/omni_event/signature_verifier.rb +87 -0
- data/lib/omni_event/version.rb +5 -0
- data/lib/omni_event.rb +17 -0
- data/lib/tasks/omni_event_tasks.rake +12 -0
- data/sig/omni_event.rbs +4 -0
- metadata +148 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class CreateOmniEventLogs < ActiveRecord::Migration[6.1]
|
|
2
|
+
def change
|
|
3
|
+
create_table :omni_event_logs do |t|
|
|
4
|
+
t.references :loggable, polymorphic: true, null: true
|
|
5
|
+
t.string :action_type, null: false, default: 'system_info'
|
|
6
|
+
t.text :content
|
|
7
|
+
t.jsonb :metadata, null: false, default: {}
|
|
8
|
+
t.timestamps
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
add_index :omni_event_logs, :action_type
|
|
12
|
+
add_index :omni_event_logs, :created_at
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
class AddSecurityToOmniEventNotifiers < ActiveRecord::Migration[6.1]
|
|
2
|
+
def change
|
|
3
|
+
add_column :omni_event_notifiers, :secret_key, :string
|
|
4
|
+
add_column :omni_event_notifiers, :timestamp_tolerance, :integer, default: 300, null: false
|
|
5
|
+
|
|
6
|
+
add_index :omni_event_notifiers, :secret_key, unique: true, where: "secret_key IS NOT NULL"
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails/generators/migration'
|
|
4
|
+
|
|
5
|
+
module OmniEvent
|
|
6
|
+
module Generators
|
|
7
|
+
class InstallGenerator < Rails::Generators::Base
|
|
8
|
+
include Rails::Generators::Migration
|
|
9
|
+
|
|
10
|
+
source_root File.expand_path('templates', __dir__)
|
|
11
|
+
|
|
12
|
+
def copy_migrations
|
|
13
|
+
rake "omni_event:install:migrations"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def create_initializer
|
|
17
|
+
create_file "config/initializers/omni_event.rb", <<~RUBY
|
|
18
|
+
OmniEvent.configure do |config|
|
|
19
|
+
# ── Monitoring ────────────────────────────────────────────────────────────
|
|
20
|
+
config.new_relic_enabled = false
|
|
21
|
+
config.new_relic_api_key = ENV['NEW_RELIC_KEY']
|
|
22
|
+
config.new_relic_account_id = ENV['NEW_RELIC_ACCOUNT_ID']
|
|
23
|
+
|
|
24
|
+
# ── Processing ────────────────────────────────────────────────────────────
|
|
25
|
+
config.process_async = true # set false to process synchronously
|
|
26
|
+
config.retention_days = 30
|
|
27
|
+
|
|
28
|
+
# ── Custom log types ──────────────────────────────────────────────────────
|
|
29
|
+
# Define your domain-specific action types here.
|
|
30
|
+
config.custom_log_types = {
|
|
31
|
+
system_info: 0,
|
|
32
|
+
system_error: 1
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# ── Processor registry ────────────────────────────────────────────────────
|
|
36
|
+
# Map each OmniEvent::Notifier name to its processor class.
|
|
37
|
+
#
|
|
38
|
+
# config.processors = {
|
|
39
|
+
# "Siscomex" => SiscomexProcessor,
|
|
40
|
+
# "DHL" => DHLWebhookProcessor
|
|
41
|
+
# }
|
|
42
|
+
config.processors = {}
|
|
43
|
+
end
|
|
44
|
+
RUBY
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def create_local_models
|
|
48
|
+
create_file "app/models/log.rb", <<~RUBY
|
|
49
|
+
class Log < OmniEvent::Log
|
|
50
|
+
# Add custom scopes, validations or methods here.
|
|
51
|
+
end
|
|
52
|
+
RUBY
|
|
53
|
+
|
|
54
|
+
create_file "app/models/webhook_event.rb", <<~RUBY
|
|
55
|
+
class WebhookEvent < OmniEvent::WebhookEvent
|
|
56
|
+
end
|
|
57
|
+
RUBY
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def display_post_install_message
|
|
61
|
+
puts ""
|
|
62
|
+
puts "=" * 64
|
|
63
|
+
puts " OmniEvent #{OmniEvent::VERSION} installed successfully!"
|
|
64
|
+
puts ""
|
|
65
|
+
puts " Next steps:"
|
|
66
|
+
puts " 1. rails db:migrate"
|
|
67
|
+
puts " 2. Configure config/initializers/omni_event.rb"
|
|
68
|
+
puts " 3. Mount the engine in config/routes.rb:"
|
|
69
|
+
puts " mount OmniEvent::Engine => '/omni_events'"
|
|
70
|
+
puts " 4. Create a Notifier:"
|
|
71
|
+
puts " OmniEvent::Notifier.create!(name: 'My Partner')"
|
|
72
|
+
puts " 5. Register a processor in the initializer:"
|
|
73
|
+
puts " config.processors = { 'My Partner' => MyProcessor }"
|
|
74
|
+
puts "=" * 64
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OmniEvent
|
|
4
|
+
class BaseProcessor
|
|
5
|
+
attr_reader :event, :current_step
|
|
6
|
+
|
|
7
|
+
def self.steps(*method_names)
|
|
8
|
+
@steps_list = method_names
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.steps_list
|
|
12
|
+
@steps_list || []
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def initialize(event)
|
|
16
|
+
@event = event
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def process!
|
|
20
|
+
self.class.steps_list.each do |method_name|
|
|
21
|
+
execute_step(method_name)
|
|
22
|
+
end
|
|
23
|
+
rescue => e
|
|
24
|
+
raise e
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def execute_step(method_name)
|
|
30
|
+
@current_step = method_name.to_s.humanize
|
|
31
|
+
|
|
32
|
+
Rails.logger.info "[OmniEvent] Executing step: #{@current_step}"
|
|
33
|
+
|
|
34
|
+
send(method_name)
|
|
35
|
+
|
|
36
|
+
rescue => e
|
|
37
|
+
OmniEvent::Log.create!(
|
|
38
|
+
loggable: event,
|
|
39
|
+
action_type: :system_error,
|
|
40
|
+
content: "FAILURE in step [#{@current_step}]: #{e.message}",
|
|
41
|
+
metadata: {
|
|
42
|
+
error_class: e.class.name,
|
|
43
|
+
method: method_name,
|
|
44
|
+
backtrace: e.backtrace.first(3)
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
raise e
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OmniEvent
|
|
4
|
+
class Configuration
|
|
5
|
+
attr_accessor :new_relic_enabled,
|
|
6
|
+
:new_relic_api_key,
|
|
7
|
+
:new_relic_account_id,
|
|
8
|
+
:retention_days,
|
|
9
|
+
:process_async,
|
|
10
|
+
:custom_log_types,
|
|
11
|
+
:processors
|
|
12
|
+
|
|
13
|
+
def initialize
|
|
14
|
+
@new_relic_enabled = false
|
|
15
|
+
@new_relic_api_key = nil
|
|
16
|
+
@new_relic_account_id = nil
|
|
17
|
+
@retention_days = 30
|
|
18
|
+
@process_async = true
|
|
19
|
+
@custom_log_types = { system_info: 0, system_error: 1 }
|
|
20
|
+
@processors = {}
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OmniEvent
|
|
4
|
+
# Finds the registered processor for a given WebhookEvent and runs it.
|
|
5
|
+
#
|
|
6
|
+
# Register processors in your initializer:
|
|
7
|
+
#
|
|
8
|
+
# OmniEvent.configure do |config|
|
|
9
|
+
# config.processors = {
|
|
10
|
+
# "Siscomex" => SiscomexProcessor,
|
|
11
|
+
# "DHL" => DHLProcessor
|
|
12
|
+
# }
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
class ProcessDispatcher
|
|
16
|
+
def self.call(event)
|
|
17
|
+
processor_class = resolve(event)
|
|
18
|
+
|
|
19
|
+
unless processor_class
|
|
20
|
+
Rails.logger.warn "[OmniEvent] No processor registered for notifier '#{event.webhook_notifier.name}'. Marking as processed."
|
|
21
|
+
event.update!(status: :processed)
|
|
22
|
+
return
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
processor_class.new(event).process!
|
|
26
|
+
event.update!(status: :processed)
|
|
27
|
+
rescue => e
|
|
28
|
+
event.update!(status: :failed)
|
|
29
|
+
raise e
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private_class_method def self.resolve(event)
|
|
33
|
+
notifier_name = event.webhook_notifier.name
|
|
34
|
+
config = OmniEvent.configuration.processors
|
|
35
|
+
|
|
36
|
+
config[notifier_name] ||
|
|
37
|
+
config[notifier_name.to_sym] ||
|
|
38
|
+
config[notifier_name.downcase] ||
|
|
39
|
+
config[notifier_name.downcase.to_sym]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'openssl'
|
|
4
|
+
|
|
5
|
+
module OmniEvent
|
|
6
|
+
# Verifies the authenticity and freshness of an incoming webhook request.
|
|
7
|
+
#
|
|
8
|
+
# Two independent checks (both only active when secret_key is set):
|
|
9
|
+
#
|
|
10
|
+
# 1. Timestamp — rejects requests outside the tolerance window (replay attack protection).
|
|
11
|
+
# Header: X-OmniEvent-Timestamp (Unix timestamp, e.g. 1711800000)
|
|
12
|
+
#
|
|
13
|
+
# 2. HMAC Signature — verifies the payload was signed with the shared secret.
|
|
14
|
+
# Header: X-OmniEvent-Signature (e.g. "sha256=abc123...")
|
|
15
|
+
# Algorithm: HMAC-SHA256(secret_key, raw_body)
|
|
16
|
+
#
|
|
17
|
+
# If the Notifier has no secret_key, all checks are skipped (backward compatible).
|
|
18
|
+
#
|
|
19
|
+
# Usage:
|
|
20
|
+
# result = OmniEvent::SignatureVerifier.call(notifier, request)
|
|
21
|
+
# result.success? # => true / false
|
|
22
|
+
# result.error # => "Invalid signature — payload may have been tampered"
|
|
23
|
+
#
|
|
24
|
+
class SignatureVerifier
|
|
25
|
+
Result = Struct.new(:success?, :error)
|
|
26
|
+
|
|
27
|
+
TIMESTAMP_HEADER = 'X-OmniEvent-Timestamp'
|
|
28
|
+
SIGNATURE_HEADER = 'X-OmniEvent-Signature'
|
|
29
|
+
|
|
30
|
+
def self.call(notifier, request)
|
|
31
|
+
new(notifier, request).verify
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def initialize(notifier, request)
|
|
35
|
+
@notifier = notifier
|
|
36
|
+
@request = request
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def verify
|
|
40
|
+
# No secret configured — skip all checks (opt-in security)
|
|
41
|
+
return success unless @notifier.secret_key.present?
|
|
42
|
+
|
|
43
|
+
result = verify_timestamp
|
|
44
|
+
return result unless result.success?
|
|
45
|
+
|
|
46
|
+
verify_signature
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
# ── Timestamp check ────────────────────────────────────────────────────────
|
|
52
|
+
def verify_timestamp
|
|
53
|
+
tolerance = @notifier.timestamp_tolerance.to_i
|
|
54
|
+
return success if tolerance.zero?
|
|
55
|
+
|
|
56
|
+
header = @request.headers[TIMESTAMP_HEADER]
|
|
57
|
+
return failure("Missing #{TIMESTAMP_HEADER} header") if header.blank?
|
|
58
|
+
|
|
59
|
+
request_time = Time.at(header.to_i)
|
|
60
|
+
elapsed = (Time.current - request_time).abs
|
|
61
|
+
|
|
62
|
+
if elapsed > tolerance
|
|
63
|
+
failure("Request timestamp is #{elapsed.to_i}s old — outside the #{tolerance}s window (possible replay attack)")
|
|
64
|
+
else
|
|
65
|
+
success
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# ── HMAC signature check ───────────────────────────────────────────────────
|
|
70
|
+
def verify_signature
|
|
71
|
+
header = @request.headers[SIGNATURE_HEADER]
|
|
72
|
+
return failure("Missing #{SIGNATURE_HEADER} header") if header.blank?
|
|
73
|
+
|
|
74
|
+
raw_body = @request.raw_post
|
|
75
|
+
expected = "sha256=#{OpenSSL::HMAC.hexdigest('SHA256', @notifier.secret_key, raw_body)}"
|
|
76
|
+
|
|
77
|
+
unless ActiveSupport::SecurityUtils.secure_compare(expected, header)
|
|
78
|
+
failure("Invalid signature — payload may have been tampered or secret_key is wrong")
|
|
79
|
+
else
|
|
80
|
+
success
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def success = Result.new(true, nil)
|
|
85
|
+
def failure(msg) = Result.new(false, msg)
|
|
86
|
+
end
|
|
87
|
+
end
|
data/lib/omni_event.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require "omni_event/version"
|
|
2
|
+
require "omni_event/engine"
|
|
3
|
+
require "omni_event/configuration"
|
|
4
|
+
require "omni_event/base_processor"
|
|
5
|
+
require "omni_event/process_dispatcher"
|
|
6
|
+
require "omni_event/signature_verifier"
|
|
7
|
+
|
|
8
|
+
module OmniEvent
|
|
9
|
+
class << self
|
|
10
|
+
attr_accessor :configuration
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.configure
|
|
14
|
+
self.configuration ||= Configuration.new
|
|
15
|
+
yield(configuration)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
namespace :omni_event do
|
|
2
|
+
desc "Delete logs and webhook events older than the configured retention_days"
|
|
3
|
+
task cleanup: :environment do
|
|
4
|
+
retention_days = OmniEvent.configuration.retention_days
|
|
5
|
+
cutoff = retention_days.days.ago
|
|
6
|
+
|
|
7
|
+
deleted_logs = OmniEvent::Log.where("created_at < ?", cutoff).delete_all
|
|
8
|
+
deleted_events = OmniEvent::WebhookEvent.where("created_at < ?", cutoff).delete_all
|
|
9
|
+
|
|
10
|
+
puts "[OmniEvent] Cleanup complete: #{deleted_logs} logs and #{deleted_events} webhook events deleted (older than #{retention_days} days)."
|
|
11
|
+
end
|
|
12
|
+
end
|
data/sig/omni_event.rbs
ADDED
metadata
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: omni_events
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Antonio Neto
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-03-31 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rails
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '6.1'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '6.1'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: httparty
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0.21'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0.21'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec-rails
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '6.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '6.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: sqlite3
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '1.6'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '1.6'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: factory_bot_rails
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '6.2'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '6.2'
|
|
83
|
+
description: OmniEvent unifies external event ingestion with detailed internal auditing
|
|
84
|
+
via a step-based pipeline and asynchronous monitoring.
|
|
85
|
+
email:
|
|
86
|
+
- antoniocneto.dev@gmail.com
|
|
87
|
+
executables: []
|
|
88
|
+
extensions: []
|
|
89
|
+
extra_rdoc_files: []
|
|
90
|
+
files:
|
|
91
|
+
- ".rspec"
|
|
92
|
+
- CHANGELOG.md
|
|
93
|
+
- CODE_OF_CONDUCT.md
|
|
94
|
+
- Gemfile
|
|
95
|
+
- Gemfile.lock
|
|
96
|
+
- LICENSE.txt
|
|
97
|
+
- README.md
|
|
98
|
+
- Rakefile
|
|
99
|
+
- app/controllers/omni_event/receiver_controller.rb
|
|
100
|
+
- app/jobs/omni_event/new_relic_job.rb
|
|
101
|
+
- app/jobs/omni_event/process_webhook_job.rb
|
|
102
|
+
- app/models/omni_event/application_record.rb
|
|
103
|
+
- app/models/omni_event/log.rb
|
|
104
|
+
- app/models/omni_event/notifier.rb
|
|
105
|
+
- app/models/omni_event/webhook_event.rb
|
|
106
|
+
- config/routes.rb
|
|
107
|
+
- db/migrate/20240101000001_create_omni_event_notifiers.rb
|
|
108
|
+
- db/migrate/20240101000002_create_omni_event_webhook_events.rb
|
|
109
|
+
- db/migrate/20240101000003_create_omni_event_logs.rb
|
|
110
|
+
- db/migrate/20240101000004_add_security_to_omni_event_notifiers.rb
|
|
111
|
+
- lib/generators/omni_event/install_generator.rb
|
|
112
|
+
- lib/omni_event.rb
|
|
113
|
+
- lib/omni_event/base_processor.rb
|
|
114
|
+
- lib/omni_event/configuration.rb
|
|
115
|
+
- lib/omni_event/engine.rb
|
|
116
|
+
- lib/omni_event/process_dispatcher.rb
|
|
117
|
+
- lib/omni_event/signature_verifier.rb
|
|
118
|
+
- lib/omni_event/version.rb
|
|
119
|
+
- lib/tasks/omni_event_tasks.rake
|
|
120
|
+
- sig/omni_event.rbs
|
|
121
|
+
homepage: https://github.com/antoniocneto/omni_event
|
|
122
|
+
licenses:
|
|
123
|
+
- MIT
|
|
124
|
+
metadata:
|
|
125
|
+
allowed_push_host: https://rubygems.org
|
|
126
|
+
homepage_uri: https://github.com/antoniocneto/omni_event
|
|
127
|
+
source_code_uri: https://github.com/antoniocneto/omni_event
|
|
128
|
+
post_install_message:
|
|
129
|
+
rdoc_options: []
|
|
130
|
+
require_paths:
|
|
131
|
+
- lib
|
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
133
|
+
requirements:
|
|
134
|
+
- - ">="
|
|
135
|
+
- !ruby/object:Gem::Version
|
|
136
|
+
version: 3.0.0
|
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
|
+
requirements:
|
|
139
|
+
- - ">="
|
|
140
|
+
- !ruby/object:Gem::Version
|
|
141
|
+
version: '0'
|
|
142
|
+
requirements: []
|
|
143
|
+
rubygems_version: 3.4.1
|
|
144
|
+
signing_key:
|
|
145
|
+
specification_version: 4
|
|
146
|
+
summary: Rails Engine for unified Webhook ingestion, Polymorphic Logging, and Process
|
|
147
|
+
Traceability.
|
|
148
|
+
test_files: []
|