aven 0.0.1 → 0.0.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/app/components/aven/views/oauth/error/component.html.erb +44 -0
  4. data/app/components/aven/views/oauth/error/component.rb +30 -0
  5. data/app/components/aven/views/static/index/component.html.erb +4 -4
  6. data/app/components/aven/views/static/index/component.rb +11 -0
  7. data/app/controllers/aven/admin/base.rb +4 -4
  8. data/app/controllers/aven/application_controller.rb +22 -0
  9. data/app/controllers/aven/auth_controller.rb +6 -58
  10. data/app/controllers/aven/oauth/auth0_controller.rb +84 -0
  11. data/app/controllers/aven/oauth/base_controller.rb +183 -0
  12. data/app/controllers/aven/oauth/documentation/auth0.md +387 -0
  13. data/app/controllers/aven/oauth/documentation/entra_id.md +608 -0
  14. data/app/controllers/aven/oauth/documentation/github.md +329 -0
  15. data/app/controllers/aven/oauth/documentation/google.md +253 -0
  16. data/app/controllers/aven/oauth/entra_id_controller.rb +92 -0
  17. data/app/controllers/aven/oauth/github_controller.rb +91 -0
  18. data/app/controllers/aven/oauth/google_controller.rb +64 -0
  19. data/app/controllers/aven/workspaces_controller.rb +20 -0
  20. data/app/controllers/concerns/aven/authentication.rb +49 -0
  21. data/app/controllers/concerns/aven/controller_helpers.rb +38 -0
  22. data/app/helpers/aven/application_helper.rb +2 -6
  23. data/app/models/aven/app_record.rb +1 -1
  24. data/app/models/aven/app_record_schema.rb +0 -1
  25. data/app/models/aven/log.rb +0 -1
  26. data/app/models/aven/loggable.rb +2 -3
  27. data/app/models/aven/user.rb +0 -23
  28. data/app/models/aven/workspace.rb +49 -5
  29. data/app/models/aven/workspace_role.rb +0 -1
  30. data/app/models/aven/workspace_user.rb +0 -1
  31. data/app/models/aven/workspace_user_role.rb +0 -1
  32. data/config/routes.rb +22 -7
  33. data/db/migrate/{20251003090752_create_aven_users.rb → 20200101000001_create_aven_users.rb} +1 -1
  34. data/db/migrate/{20251004182010_create_aven_workspace_users.rb → 20200101000003_create_aven_workspace_users.rb} +1 -1
  35. data/db/migrate/{20251004182020_create_aven_workspace_roles.rb → 20200101000004_create_aven_workspace_roles.rb} +1 -1
  36. data/db/migrate/{20251004182030_create_aven_workspace_user_roles.rb → 20200101000005_create_aven_workspace_user_roles.rb} +1 -1
  37. data/db/migrate/{20251004190000_create_aven_logs.rb → 20200101000006_create_aven_logs.rb} +2 -3
  38. data/db/migrate/{20251004190100_create_aven_app_record_schemas.rb → 20200101000007_create_aven_app_record_schemas.rb} +0 -1
  39. data/db/migrate/{20251004190110_create_aven_app_records.rb → 20200101000008_create_aven_app_records.rb} +0 -1
  40. data/lib/aven/configuration.rb +26 -10
  41. data/lib/aven/engine.rb +15 -16
  42. data/lib/aven/model/tenant_model.rb +91 -0
  43. data/lib/aven/model.rb +6 -0
  44. data/lib/aven/version.rb +1 -1
  45. metadata +42 -69
  46. data/config/initializers/devise.rb +0 -43
  47. /data/db/migrate/{20251004182000_create_aven_workspaces.rb → 20200101000002_create_aven_workspaces.rb} +0 -0
  48. /data/lib/tasks/{sqema_tasks.rake → aven_tasks.rake} +0 -0
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "json"
5
+
6
+ module Aven
7
+ module Oauth
8
+ class GithubController < BaseController
9
+ AUTHORIZATION_URL = "https://github.com/login/oauth/authorize"
10
+ TOKEN_URL = "https://github.com/login/oauth/access_token"
11
+ USER_INFO_URL = "https://api.github.com/user"
12
+ USER_EMAIL_URL = "https://api.github.com/user/emails"
13
+ DEFAULT_SCOPE = "user:email"
14
+
15
+ protected
16
+
17
+ def authorization_url(state)
18
+ params = {
19
+ client_id: oauth_config[:client_id],
20
+ redirect_uri: callback_url,
21
+ scope: oauth_config[:scope] || DEFAULT_SCOPE,
22
+ state:
23
+ }
24
+
25
+ "#{AUTHORIZATION_URL}?#{params.to_query}"
26
+ end
27
+
28
+ def exchange_code_for_token(code)
29
+ params = {
30
+ client_id: oauth_config[:client_id],
31
+ client_secret: oauth_config[:client_secret],
32
+ code:,
33
+ redirect_uri: callback_url
34
+ }
35
+
36
+ headers = { "Accept" => "application/json" }
37
+ oauth_request(URI(TOKEN_URL), params, headers)
38
+ end
39
+
40
+ def fetch_user_info(access_token)
41
+ # Fetch user profile
42
+ user_data = github_api_request(USER_INFO_URL, access_token)
43
+
44
+ # Fetch primary email if not public
45
+ email = user_data[:email]
46
+ if email.blank?
47
+ emails_data = github_api_request(USER_EMAIL_URL, access_token)
48
+ primary_email = emails_data.find { |e| e[:primary] && e[:verified] }
49
+ email = primary_email[:email] if primary_email
50
+ end
51
+
52
+ {
53
+ id: user_data[:id],
54
+ email:,
55
+ name: user_data[:name] || user_data[:login],
56
+ avatar_url: user_data[:avatar_url],
57
+ login: user_data[:login]
58
+ }
59
+ end
60
+
61
+ private
62
+
63
+ def callback_url
64
+ aven.oauth_github_callback_url(host: request.host, protocol: request.protocol)
65
+ end
66
+
67
+ def oauth_config
68
+ @oauth_config ||= Aven.configuration.oauth_providers[:github] || raise("GitHub OAuth not configured")
69
+ end
70
+
71
+ def github_api_request(url, access_token)
72
+ uri = URI(url)
73
+ http = Net::HTTP.new(uri.host, uri.port)
74
+ http.use_ssl = true
75
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if Rails.env.development?
76
+
77
+ request = Net::HTTP::Get.new(uri)
78
+ request["Authorization"] = "Bearer #{access_token}"
79
+ request["Accept"] = "application/vnd.github.v3+json"
80
+
81
+ response = http.request(request)
82
+
83
+ unless response.is_a?(Net::HTTPSuccess)
84
+ raise StandardError, "GitHub API request failed: #{response.body}"
85
+ end
86
+
87
+ JSON.parse(response.body, symbolize_names: true)
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "json"
5
+
6
+ module Aven
7
+ module Oauth
8
+ class GoogleController < BaseController
9
+ AUTHORIZATION_URL = "https://accounts.google.com/o/oauth2/v2/auth"
10
+ TOKEN_URL = "https://www.googleapis.com/oauth2/v4/token"
11
+ USER_INFO_URL = "https://www.googleapis.com/oauth2/v3/userinfo"
12
+ DEFAULT_SCOPE = "openid email profile"
13
+
14
+ protected
15
+
16
+ def authorization_url(state)
17
+ params = {
18
+ client_id: oauth_config[:client_id],
19
+ redirect_uri: callback_url,
20
+ response_type: "code",
21
+ scope: oauth_config[:scope] || DEFAULT_SCOPE,
22
+ state:,
23
+ access_type: oauth_config[:access_type] || "offline",
24
+ prompt: oauth_config[:prompt] || "select_account"
25
+ }
26
+
27
+ "#{AUTHORIZATION_URL}?#{params.to_query}"
28
+ end
29
+
30
+ def exchange_code_for_token(code)
31
+ params = {
32
+ code:,
33
+ client_id: oauth_config[:client_id],
34
+ client_secret: oauth_config[:client_secret],
35
+ redirect_uri: callback_url,
36
+ grant_type: "authorization_code"
37
+ }
38
+
39
+ oauth_request(URI(TOKEN_URL), params)
40
+ end
41
+
42
+ def fetch_user_info(access_token)
43
+ response = oauth_get_request(URI(USER_INFO_URL), access_token)
44
+
45
+ {
46
+ id: response[:sub],
47
+ email: response[:email],
48
+ name: response[:name],
49
+ picture: response[:picture]
50
+ }
51
+ end
52
+
53
+ private
54
+
55
+ def callback_url
56
+ aven.oauth_google_callback_url(host: request.host, protocol: request.protocol)
57
+ end
58
+
59
+ def oauth_config
60
+ @oauth_config ||= Aven.configuration.oauth_providers[:google] || raise("Google OAuth not configured")
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aven
4
+ class WorkspacesController < ApplicationController
5
+ before_action :authenticate_user!
6
+
7
+ # POST /workspaces/:id/switch
8
+ def switch
9
+ workspace = current_user.workspaces.friendly.find(params[:id])
10
+ self.current_workspace = workspace
11
+ redirect_to after_switch_workspace_path, notice: "Switched to #{workspace.label}"
12
+ end
13
+
14
+ private
15
+
16
+ def after_switch_workspace_path
17
+ Aven.configuration.resolve_authenticated_root_path || root_path
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aven
4
+ module Authentication
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ helper_method :current_user if respond_to?(:helper_method)
9
+ end
10
+
11
+ private
12
+ # Returns the currently signed-in user, if any
13
+ def current_user
14
+ @current_user ||= Aven::User.find_by(id: session[:user_id]) if session[:user_id]
15
+ end
16
+
17
+ # Signs in the given user by setting the session
18
+ def sign_in(user)
19
+ reset_session
20
+ session[:user_id] = user.id
21
+ @current_user = user
22
+ end
23
+
24
+ # Signs out the current user by clearing the session
25
+ def sign_out
26
+ reset_session
27
+ @current_user = nil
28
+ end
29
+
30
+ # Stores the current location to redirect back after authentication
31
+ def store_location
32
+ session[:return_to_after_authentication] = request.url if request.get?
33
+ end
34
+
35
+ # Returns and clears the stored location for redirect after authentication
36
+ # This method accepts a resource parameter for API compatibility with Devise
37
+ def stored_location_for(_resource = nil)
38
+ session.delete(:return_to_after_authentication)
39
+ end
40
+
41
+ # Requires user to be authenticated, redirects to root if not
42
+ def authenticate_user!
43
+ unless current_user
44
+ store_location
45
+ redirect_to main_app.root_path, alert: "You must be signed in to access this page."
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,38 @@
1
+ module Aven
2
+ module ControllerHelpers
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ helper_method :current_workspace if respond_to?(:helper_method)
7
+ end
8
+
9
+ # Get the current workspace from session
10
+ def current_workspace
11
+ return @current_workspace if defined?(@current_workspace)
12
+
13
+ @current_workspace = if session[:workspace_id].present? && current_user
14
+ current_user.workspaces.find_by(id: session[:workspace_id])
15
+ elsif current_user
16
+ # Auto-select first workspace if none selected
17
+ workspace = current_user.workspaces.first
18
+ session[:workspace_id] = workspace&.id
19
+ workspace
20
+ end
21
+ end
22
+
23
+ # Set the current workspace
24
+ def current_workspace=(workspace)
25
+ @current_workspace = workspace
26
+ session[:workspace_id] = workspace&.id
27
+ end
28
+
29
+ # Verify user has access to current workspace (similar to Devise's authenticate_user!)
30
+ def verify_workspace!
31
+ return unless current_user.present? && current_workspace.present?
32
+
33
+ unless current_user.workspaces.exists?(id: current_workspace.id)
34
+ render file: Rails.public_path.join("404.html"), status: :not_found, layout: false
35
+ end
36
+ end
37
+ end
38
+ end
@@ -8,13 +8,9 @@ module Aven
8
8
  ].compact, "\n"
9
9
  end
10
10
 
11
- def view_component(name, *args, status: nil, **kwargs, &block)
11
+ def view_component(name, *args, **kwargs, &block)
12
12
  component = "Aven::Views::#{name.split("/").map(&:camelize).join("::")}::Component".constantize
13
- if status
14
- render(component.new(*args, **kwargs), status:, &block)
15
- else
16
- render(component.new(*args, **kwargs), &block)
17
- end
13
+ render(component.new(*args, **kwargs), &block)
18
14
  end
19
15
  end
20
16
  end
@@ -53,7 +53,7 @@ module Aven
53
53
  registry = JSONSkooma.create_registry("2020-12", assert_formats: true)
54
54
  schema_with_meta = app_record_schema.schema.dup
55
55
  schema_with_meta["$schema"] ||= "https://json-schema.org/draft/2020-12/schema"
56
- json_schema = JSONSkooma::JSONSchema.new(schema_with_meta, registry: registry)
56
+ json_schema = JSONSkooma::JSONSchema.new(schema_with_meta, registry:)
57
57
  result = json_schema.evaluate(data)
58
58
  unless result.valid?
59
59
  error_output = result.output(:basic)
@@ -44,4 +44,3 @@ module Aven
44
44
  end
45
45
  end
46
46
  end
47
-
@@ -64,4 +64,3 @@ module Aven
64
64
  end
65
65
  end
66
66
  end
67
-
@@ -2,8 +2,8 @@ module Aven
2
2
  module Loggable
3
3
  def log!(message:, level: "info", metadata: nil, **extra)
4
4
  attrs = {
5
- message: message,
6
- level: level,
5
+ message:,
6
+ level:,
7
7
  metadata: metadata || {}
8
8
  }
9
9
 
@@ -18,4 +18,3 @@ module Aven
18
18
  end
19
19
  end
20
20
  end
21
-
@@ -22,11 +22,6 @@
22
22
  #
23
23
  module Aven
24
24
  class User < ApplicationRecord
25
- devise(
26
- :omniauthable,
27
- omniauth_providers: Aven.configuration.auth.providers.map { |p| p[:provider] }
28
- )
29
-
30
25
  has_many :workspace_users, dependent: :destroy
31
26
  has_many :workspaces, through: :workspace_users
32
27
  has_many :workspace_user_roles, through: :workspace_users
@@ -41,23 +36,5 @@ module Aven
41
36
  validates :remote_id, uniqueness: { scope: :auth_tenant, case_sensitive: false }, allow_blank: true
42
37
 
43
38
  encrypts(:access_token)
44
-
45
- def self.create_from_omniauth!(request_env, auth_tenant)
46
- user = request_env.dig("omniauth.auth")
47
- remote_id = user["uid"]
48
- email = user.dig("info", "email") || "#{SecureRandom.uuid}@aven.dev"
49
-
50
- u = where(auth_tenant:, remote_id:).or(
51
- where(auth_tenant:, email:)
52
- ).first_or_initialize
53
-
54
- u.auth_tenant = auth_tenant
55
- u.remote_id = remote_id
56
- u.email = email
57
- u.access_token = user.dig("credentials", "token")
58
- u.save!
59
-
60
- u
61
- end
62
39
  end
63
40
  end
@@ -16,6 +16,9 @@
16
16
  #
17
17
  module Aven
18
18
  class Workspace < ApplicationRecord
19
+ extend FriendlyId
20
+ friendly_id :label, use: :slugged
21
+
19
22
  self.table_name = "aven_workspaces"
20
23
 
21
24
  has_many :workspace_users, class_name: "Aven::WorkspaceUser", dependent: :destroy
@@ -27,13 +30,54 @@ module Aven
27
30
  validates :label, length: { maximum: 255 }, allow_blank: true
28
31
  validates :description, length: { maximum: 1000 }, allow_blank: true
29
32
 
30
- before_validation :generate_slug, if: -> { slug.blank? && label.present? }
33
+ # Tenant model registry (inspired by Flipper's group registry pattern)
34
+ class << self
35
+ # Returns array of all registered tenant model classes
36
+ def tenant_models
37
+ @tenant_models ||= []
38
+ end
39
+
40
+ # Register a model class as workspace-scoped
41
+ # Called automatically when a model includes Aven::TenantModel
42
+ def register_tenant_model(model_class)
43
+ return if tenant_models.include?(model_class)
44
+
45
+ tenant_models << model_class
46
+ define_tenant_association(model_class)
47
+ end
48
+
49
+ # Get all registered tenant model class names
50
+ def tenant_model_names
51
+ tenant_models.map(&:name)
52
+ end
53
+
54
+ private
55
+
56
+ # Define association method for a tenant model
57
+ # Creates query method that returns ActiveRecord::Relation
58
+ def define_tenant_association(model_class)
59
+ association_name = model_class.workspace_association_name
31
60
 
32
- private
61
+ # Define instance method for querying tenant records
62
+ define_method(association_name) do
63
+ model_class.where(workspace_id: id)
64
+ end
65
+ end
66
+ end
33
67
 
34
- def generate_slug
35
- self.slug = label.parameterize if label.present?
68
+ # Find a tenant record by type and ID
69
+ def find_tenant_record(model_name, record_id)
70
+ model_class = self.class.tenant_models.find { |m| m.name == model_name }
71
+ return nil unless model_class
72
+
73
+ model_class.where(workspace_id: id).find(record_id)
74
+ end
75
+
76
+ # Destroy all tenant data for this workspace
77
+ def destroy_tenant_data
78
+ self.class.tenant_models.each do |model_class|
79
+ model_class.where(workspace_id: id).destroy_all
36
80
  end
81
+ end
37
82
  end
38
83
  end
39
-
@@ -44,4 +44,3 @@ module Aven
44
44
  end
45
45
  end
46
46
  end
47
-
@@ -52,4 +52,3 @@ module Aven
52
52
  end
53
53
  end
54
54
  end
55
-
@@ -36,4 +36,3 @@ module Aven
36
36
  scope :with_role, ->(role_label) { joins(:workspace_role).where(aven_workspace_roles: { label: role_label }) }
37
37
  end
38
38
  end
39
-
data/config/routes.rb CHANGED
@@ -1,12 +1,27 @@
1
1
  Aven::Engine.routes.draw do
2
- devise_for(
3
- :users, class_name: "Aven::User", module: :devise, format: false,
4
- controllers: { omniauth_callbacks: "aven/auth" }
5
- )
2
+ # Logout route
3
+ get(:logout, to: "auth#logout", as: :logout)
6
4
 
7
- # Additional auth routes
8
- get("/auth/:provider/authenticate", to: "auth#authenticate", as: :authenticate)
9
- get("/auth/logout", to: "auth#logout", as: :logout)
5
+ # OAuth routes
6
+ namespace :oauth do
7
+ # Error page
8
+ get "error", to: "base#error", as: :error
9
+
10
+ # Google OAuth
11
+ get "google", to: "google#create", as: :google
12
+ get "google/callback", to: "google#callback", as: :google_callback
13
+
14
+ # GitHub OAuth
15
+ get "github", to: "github#create", as: :github
16
+ get "github/callback", to: "github#callback", as: :github_callback
17
+
18
+ # Auth0 OAuth
19
+ get "auth0", to: "auth0#create", as: :auth0
20
+ get "auth0/callback", to: "auth0#callback", as: :auth0_callback
21
+ end
22
+
23
+ # Workspace switching
24
+ post("/workspaces/:id/switch", to: "workspaces#switch", as: :switch_workspace)
10
25
 
11
26
  namespace(:admin) do
12
27
  root(to: "dashboard#index")
@@ -13,7 +13,7 @@ class CreateAvenUsers < ActiveRecord::Migration[8.0]
13
13
  t.timestamps
14
14
  end
15
15
 
16
- add_index(:aven_users, [:email, :auth_tenant], unique: true)
16
+ add_index(:aven_users, [ :email, :auth_tenant ], unique: true)
17
17
  add_index(:aven_users, :reset_password_token, unique: true)
18
18
  end
19
19
  end
@@ -7,6 +7,6 @@ class CreateAvenWorkspaceUsers < ActiveRecord::Migration[8.0]
7
7
  t.timestamps
8
8
  end
9
9
 
10
- add_index :aven_workspace_users, [:user_id, :workspace_id], unique: true, name: "idx_aven_workspace_users_on_user_workspace"
10
+ add_index :aven_workspace_users, [ :user_id, :workspace_id ], unique: true, name: "idx_aven_workspace_users_on_user_workspace"
11
11
  end
12
12
  end
@@ -8,6 +8,6 @@ class CreateAvenWorkspaceRoles < ActiveRecord::Migration[8.0]
8
8
  t.timestamps
9
9
  end
10
10
 
11
- add_index :aven_workspace_roles, [:workspace_id, :label], unique: true, name: "idx_aven_workspace_roles_on_ws_label"
11
+ add_index :aven_workspace_roles, [ :workspace_id, :label ], unique: true, name: "idx_aven_workspace_roles_on_ws_label"
12
12
  end
13
13
  end
@@ -7,6 +7,6 @@ class CreateAvenWorkspaceUserRoles < ActiveRecord::Migration[8.0]
7
7
  t.timestamps
8
8
  end
9
9
 
10
- add_index :aven_workspace_user_roles, [:workspace_role_id, :workspace_user_id], unique: true, name: "idx_aven_ws_user_roles_on_role_user"
10
+ add_index :aven_workspace_user_roles, [ :workspace_role_id, :workspace_user_id ], unique: true, name: "idx_aven_ws_user_roles_on_role_user"
11
11
  end
12
12
  end
@@ -15,8 +15,7 @@ class CreateAvenLogs < ActiveRecord::Migration[8.0]
15
15
 
16
16
  add_index :aven_logs, :created_at
17
17
  add_index :aven_logs, :level
18
- add_index :aven_logs, [:loggable_type, :loggable_id], name: "index_aven_logs_on_loggable"
19
- add_index :aven_logs, [:loggable_type, :loggable_id, :run_id, :state, :created_at], name: "idx_aven_logs_on_loggable_run_state_created_at"
18
+ add_index :aven_logs, [ :loggable_type, :loggable_id ], name: "index_aven_logs_on_loggable"
19
+ add_index :aven_logs, [ :loggable_type, :loggable_id, :run_id, :state, :created_at ], name: "idx_aven_logs_on_loggable_run_state_created_at"
20
20
  end
21
21
  end
22
-
@@ -9,4 +9,3 @@ class CreateAvenAppRecordSchemas < ActiveRecord::Migration[8.0]
9
9
  add_index :aven_app_record_schemas, :schema, using: :gin
10
10
  end
11
11
  end
12
-
@@ -9,4 +9,3 @@ class CreateAvenAppRecords < ActiveRecord::Migration[8.0]
9
9
  add_index :aven_app_records, :data, using: :gin
10
10
  end
11
11
  end
12
-
@@ -1,23 +1,39 @@
1
1
  module Aven
2
2
  class Configuration
3
- attr_reader :auth
4
3
  attr_accessor :authenticated_root_path
4
+ attr_accessor :oauth_providers
5
5
 
6
6
  def initialize
7
- @auth = Auth.new
8
7
  @authenticated_root_path = nil
8
+ @oauth_providers = {}
9
9
  end
10
10
 
11
- class Auth
12
- attr_reader :providers
11
+ # Configure OAuth providers
12
+ #
13
+ # @param provider [Symbol] The OAuth provider name (:github, :google, etc.)
14
+ # @param credentials [Hash] Configuration hash with:
15
+ # - :client_id [String] OAuth client ID
16
+ # - :client_secret [String] OAuth client secret
17
+ # - :scope [String] Optional. OAuth scopes to request
18
+ # - Any other provider-specific options
19
+ #
20
+ # @example
21
+ # config.configure_oauth(:github, {
22
+ # client_id: "abc123",
23
+ # client_secret: "secret",
24
+ # scope: "user:email,repo,workflow"
25
+ # })
26
+ def configure_oauth(provider, credentials = {})
27
+ @oauth_providers[provider.to_sym] = credentials
28
+ end
13
29
 
14
- def initialize
15
- @providers = []
16
- end
30
+ # Resolves authenticated_root_path, calling it if it's a lambda/proc
31
+ #
32
+ # @return [String] The resolved path
33
+ def resolve_authenticated_root_path
34
+ return nil if @authenticated_root_path.nil?
17
35
 
18
- def add(provider, *args, **options)
19
- @providers << { provider: provider, args: args, options: options }
20
- end
36
+ @authenticated_root_path.respond_to?(:call) ? @authenticated_root_path.call : @authenticated_root_path
21
37
  end
22
38
  end
23
39
 
data/lib/aven/engine.rb CHANGED
@@ -1,13 +1,11 @@
1
- require "devise"
2
- require "omniauth"
3
- require "omniauth/rails_csrf_protection"
4
- require "repost"
5
1
  require "importmap-rails"
6
2
  require "view_component-contrib"
7
3
  require "dry-effects"
8
4
  require "tailwind_merge"
9
5
  require "json_skooma"
10
6
  require "aeros"
7
+ require "friendly_id"
8
+ require "aven/model"
11
9
 
12
10
  module Aven
13
11
  class << self
@@ -20,24 +18,25 @@ module Aven
20
18
  Aeros::EngineHelpers.setup_assets(self, namespace: Aven)
21
19
  Aeros::EngineHelpers.setup_importmap(self, namespace: Aven)
22
20
 
23
- # Ensure migrations are available to the host app
24
- initializer "aven.migrations" do
25
- unless Rails.env.test? || Rails.application.class.module_parent_name == "Dummy"
21
+ # Append engine migrations to the main app
22
+ initializer :append_migrations do |app|
23
+ unless app.root.to_s.include?("test/dummy")
26
24
  config.paths["db/migrate"].expanded.each do |expanded_path|
27
- Rails.application.config.paths["db/migrate"] << expanded_path
25
+ app.config.paths["db/migrate"] << expanded_path
28
26
  end
29
27
  end
30
28
  end
31
29
 
32
- initializer "aven.devise", after: :load_config_initializers do
33
- # Configure OmniAuth providers from Aven configuration
34
- providers = Aven.configuration.auth.providers
30
+ # Include engine route helpers, authentication, and controller helpers in controllers and views
31
+ initializer "aven.helpers" do
32
+ ActiveSupport.on_load(:action_controller) do
33
+ include Aven::Engine.routes.url_helpers
34
+ include Aven::Authentication
35
+ include Aven::ControllerHelpers
36
+ end
35
37
 
36
- # Add OmniAuth middleware
37
- Rails.application.config.middleware.use OmniAuth::Builder do
38
- providers.each do |provider_config|
39
- provider provider_config[:provider], *provider_config[:args], **provider_config[:options]
40
- end
38
+ ActiveSupport.on_load(:action_view) do
39
+ include Aven::Engine.routes.url_helpers
41
40
  end
42
41
  end
43
42
  end