strongmind-auth 1.0.3 → 1.0.6
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/README.md +6 -7
- data/app/controllers/concerns/strong_mind_nav.rb +26 -0
- data/app/controllers/logins_controller.rb +1 -0
- data/app/controllers/users/omniauth_callbacks_controller.rb +1 -0
- data/app/views/layouts/_loading_navbar.html.erb +30 -0
- data/lib/generators/strongmind/install_generator.rb +10 -2
- data/lib/strongmind/auth/version.rb +1 -1
- data/lib/strongmind/common_nav_fetcher.rb +94 -0
- metadata +5 -3
- data/app/views/layouts/strongmind/auth/application.html.erb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29554b31cde55064956270ba9bd557e8390a49ec9a847ff417cd13e0983d0460
|
4
|
+
data.tar.gz: 534b35f4fcfa0273ec3364b1bceca1b4e0bf9f1f99c681c21d2d489b97b861b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c00798ee297949194cb98ff045e46b222bcd3a5d60d244f9f78cf5ee336299c1ba19d9c1414cd2a9f14345cd8fd6372f09769bdcc928599bf610c325552ee342
|
7
|
+
data.tar.gz: caeb996433c23a339c251f4617a525ead271377fa97d0d027ae87ae9a694cce1e07c596ebdd21f3fd3a2aab2e10ccbcc210cb0c8c9885a5c826d82e02ba80df8
|
data/README.md
CHANGED
@@ -2,12 +2,11 @@
|
|
2
2
|
|
3
3
|
Ruby gem for authentication in a rails app
|
4
4
|
|
5
|
-
##
|
5
|
+
## Creating a new Rails app
|
6
6
|
|
7
|
-
1.
|
8
|
-
|
9
|
-
1. `
|
10
|
-
1. `rails g strongmind:install`
|
7
|
+
1. Use [Repository Dashboard](https://repository-dashboard.strongmind.com/repositories/new) to create a new repository
|
8
|
+
with the rails-template.
|
9
|
+
1. Navigate to the repo folder in a terminal and execute `rails g strongmind:install`
|
11
10
|
1. Move app root to authenticated root in routes. Should look like this:
|
12
11
|
```ruby
|
13
12
|
authenticated :user do
|
@@ -15,5 +14,5 @@ Ruby gem for authentication in a rails app
|
|
15
14
|
end
|
16
15
|
```
|
17
16
|
1. Create a new client in identity server and `IDENTITY_CLIENT_ID` and `IDENTITY_CLIENT_SECRET` values to .env file.
|
18
|
-
1. `rails dev:cache`
|
19
|
-
1. `bin/dev`
|
17
|
+
1. Execute `rails dev:cache` to turn on caching in development.
|
18
|
+
1. Execute `bin/dev`
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "strongmind/common_nav_fetcher"
|
2
|
+
|
3
|
+
module StrongMindNav
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def fetch_common_nav
|
7
|
+
begin
|
8
|
+
navbar = Strongmind::CommonNavFetcher.new(current_user, request).retrieve(menu_items)
|
9
|
+
|
10
|
+
@top_navbar_html = navbar[:top_navbar_html]
|
11
|
+
@bottom_navbar_html = navbar[:bottom_navbar_html]
|
12
|
+
@theme_css = navbar[:theme_css]
|
13
|
+
rescue Strongmind::CommonNavFetcher::TokenNotFoundError, Strongmind::CommonNavFetcher::UserNotFoundError
|
14
|
+
render 'logins/index'
|
15
|
+
rescue Faraday::TimeoutError
|
16
|
+
@top_navbar_html = render_to_string(partial: 'layouts/loading_navbar').html_safe
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def menu_items
|
21
|
+
[
|
22
|
+
{ name: 'Home', icon: 'fa-solid fa-house', path_method: :root_path }
|
23
|
+
]
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<a href="/" data-turbo="false">
|
2
|
+
<nav class="flex sm-top-nav">
|
3
|
+
<div class="flex-1 branding-container">
|
4
|
+
<img class="branding-logo-lg" src="https://prod-backpack-ui.strongmind.com/assets/images/sm-logo-2c-white.png"/>
|
5
|
+
<img class="branding-logo-sm" src="https://prod-backpack-ui.strongmind.com/assets/images/SMbulb.svg"/>
|
6
|
+
</div>
|
7
|
+
|
8
|
+
<div id="loading">
|
9
|
+
<canvas id="canvas" width="64" height="64"></canvas>
|
10
|
+
|
11
|
+
<script src="https://unpkg.com/@rive-app/canvas@2.9.3"></script>
|
12
|
+
<script>
|
13
|
+
const r = new rive.Rive({
|
14
|
+
src: "https://backpack.strongmind.com/assets/images/loader_dark_mode.riv",
|
15
|
+
canvas: document.getElementById("canvas"),
|
16
|
+
autoplay: true,
|
17
|
+
stateMachines: null,
|
18
|
+
onLoad: () => {
|
19
|
+
},
|
20
|
+
});
|
21
|
+
</script>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<div class="flex-1 justify-end sm-top-nav-controls">
|
25
|
+
<div class="profile-container">
|
26
|
+
<i class="fa-light fa-circle-user text-white fa-2xl"></i>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
</nav>
|
30
|
+
</a>
|
@@ -11,9 +11,16 @@ module Strongmind
|
|
11
11
|
copy_file "user.rb", "app/models/user.rb", force: true
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
14
|
+
def protect_app_files_and_add_nav
|
15
15
|
inject_into_file "app/controllers/application_controller.rb", after: "class ApplicationController < ActionController::Base\n" do
|
16
|
-
" before_action :authenticate_user!\n
|
16
|
+
" include StrongMindNav\n before_action :authenticate_user!\n before_action :fetch_common_nav\n
|
17
|
+
# Implement the list of menu items for the application
|
18
|
+
# def menu_items
|
19
|
+
# [
|
20
|
+
# { name: 'Home', icon: 'fa-solid fa-house', path_method: :root_path }
|
21
|
+
# ]
|
22
|
+
# end"
|
23
|
+
|
17
24
|
end
|
18
25
|
end
|
19
26
|
|
@@ -51,6 +58,7 @@ devise_scope :user do
|
|
51
58
|
def add_dotenv_file
|
52
59
|
copy_file "env", ".env"
|
53
60
|
end
|
61
|
+
|
54
62
|
end
|
55
63
|
|
56
64
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'platform_sdk'
|
4
|
+
|
5
|
+
module Strongmind
|
6
|
+
# This class is responsible for fetching the common navbar data from SM Central
|
7
|
+
class CommonNavFetcher
|
8
|
+
attr_reader :user, :request, :auth_client
|
9
|
+
|
10
|
+
include Rails.application.routes.url_helpers
|
11
|
+
|
12
|
+
class TokenNotFoundError < StandardError; end
|
13
|
+
|
14
|
+
class UserNotFoundError < StandardError; end
|
15
|
+
|
16
|
+
def initialize(user, request)
|
17
|
+
raise UserNotFoundError, 'User not found' unless user.present?
|
18
|
+
raise ArgumentError, 'Request not found' unless request.present?
|
19
|
+
|
20
|
+
@user = user
|
21
|
+
@request = request
|
22
|
+
@auth_client = PlatformSdk::Identity::AuthClient.new(
|
23
|
+
ENV.fetch('IDENTITY_BASE_URL'), ENV.fetch('IDENTITY_CLIENT_ID'), ENV.fetch('IDENTITY_CLIENT_SECRET')
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def retrieve(menu_items)
|
28
|
+
response = fetch_navbar_data(build_nav_items(menu_items))
|
29
|
+
parse_navbar(response)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def current_page?(url)
|
35
|
+
request.fullpath == URI.parse(url).path
|
36
|
+
end
|
37
|
+
|
38
|
+
def fetch_navbar_data(nav_items)
|
39
|
+
refresh_session if auth_client.token_expired?(token)
|
40
|
+
|
41
|
+
connection.post(navbar_endpoint, nav_items.to_json, 'Authorization' => "Bearer #{token}")
|
42
|
+
end
|
43
|
+
|
44
|
+
def connection
|
45
|
+
@connection ||= Faraday.new(url: ENV.fetch('SM_CENTRAL_BASE_URL')) do |conn|
|
46
|
+
conn.options.timeout = 3
|
47
|
+
conn.response :raise_error
|
48
|
+
conn.adapter Faraday.default_adapter
|
49
|
+
conn.headers['Content-Type'] = 'application/json'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def token
|
54
|
+
cache_data = Rails.cache.fetch(user.uid)
|
55
|
+
raise TokenNotFoundError, "Token not found for user #{user.id}" unless cache_data&.key?(:access_token)
|
56
|
+
|
57
|
+
cache_data[:access_token]
|
58
|
+
end
|
59
|
+
|
60
|
+
def refresh_session
|
61
|
+
begin
|
62
|
+
session = Rails.cache.fetch(user.uid)
|
63
|
+
auth_client.refresh_session(session:)
|
64
|
+
Rails.cache.write(user.uid, session)
|
65
|
+
rescue Faraday::BadRequestError => e
|
66
|
+
Sentry.capture_exception(e, extra: { session:, request_body: request.body })
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def navbar_endpoint
|
71
|
+
'/navbar'
|
72
|
+
end
|
73
|
+
|
74
|
+
def parse_navbar(response)
|
75
|
+
JSON.parse(response.body, symbolize_names: true) if response
|
76
|
+
end
|
77
|
+
|
78
|
+
def build_nav_items(menu_items)
|
79
|
+
{ nav_items: menu_items.map { |item| nav_item_data(item) } }
|
80
|
+
end
|
81
|
+
|
82
|
+
def nav_item_data(item)
|
83
|
+
url = send(item[:path_method])
|
84
|
+
{
|
85
|
+
name: item[:name],
|
86
|
+
icon: item[:icon],
|
87
|
+
url:,
|
88
|
+
is_disabled: item[:feature_flag] ? !user.feature_flag_enabled?(item[:feature_flag]) : false,
|
89
|
+
is_active: current_page?(url),
|
90
|
+
is_external: false
|
91
|
+
}
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strongmind-auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Team Belding
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-03-
|
11
|
+
date: 2024-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -105,13 +105,14 @@ files:
|
|
105
105
|
- Rakefile
|
106
106
|
- app/assets/config/strongmind_auth_manifest.js
|
107
107
|
- app/assets/stylesheets/strongmind/auth/application.css
|
108
|
+
- app/controllers/concerns/strong_mind_nav.rb
|
108
109
|
- app/controllers/logins_controller.rb
|
109
110
|
- app/controllers/users/omniauth_callbacks_controller.rb
|
110
111
|
- app/helpers/strongmind/auth/application_helper.rb
|
111
112
|
- app/jobs/rails/auth/application_job.rb
|
112
113
|
- app/mailers/rails/auth/application_mailer.rb
|
113
114
|
- app/models/user_base.rb
|
114
|
-
- app/views/layouts/
|
115
|
+
- app/views/layouts/_loading_navbar.html.erb
|
115
116
|
- app/views/logins/index.html.erb
|
116
117
|
- config/initializers/devise.rb
|
117
118
|
- config/routes.rb
|
@@ -123,6 +124,7 @@ files:
|
|
123
124
|
- lib/strongmind/auth.rb
|
124
125
|
- lib/strongmind/auth/engine.rb
|
125
126
|
- lib/strongmind/auth/version.rb
|
127
|
+
- lib/strongmind/common_nav_fetcher.rb
|
126
128
|
- lib/tasks/rails/auth_tasks.rake
|
127
129
|
- lib/tasks/strongmind/auth_tasks.rake
|
128
130
|
homepage: https://www.strongmind.com
|