lesli_shield 1.1.5 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69361ff3627e408be1fad248e31cfb48ac07d59c8700680fc7a24af338c131b4
4
- data.tar.gz: 35f1faca2f1d88e43dd54a16a54eccaf3e023f7f773a99d571d2f8dcb5a257f7
3
+ metadata.gz: cfeffedc6c4eb8c8176e07a981f42735eaf374518038d999a85fa815c4c69f2e
4
+ data.tar.gz: 57ff36f838b198f72dcb621051a3fee62a90310c0932368224d92e1d8bb171c4
5
5
  SHA512:
6
- metadata.gz: b15ced78b1ccb293d91ee648c4a8bf3ad394a4536b15df527ef34e74560c98e2d8fe4cb214c4f7d67b3a851598e566322d1eb31f00457534d95484e6d7a8aa24
7
- data.tar.gz: 3ab5a50c5cb90b1d2b3e3507f5dc6ee8936c94a5c37c50b2a93dde3170872f8efc752cd5c07a6790f7f84e78275df19cf9e7f551fba3f1f3cbe907518d5380d5
6
+ metadata.gz: 3a3c7407848c3323fb5b3ddcda2b9cf1f5b58b5bc97c4fde773a94b15acbe805b7a0a2dc59c24367e78f6b0a9f2b286c89393dc99a1e9db5a0fda4f6ce2321e5
7
+ data.tar.gz: cbb695a526bf0f350777562c659ac60a4d876c46de196a4f90ee16f661aac9f90228dafd90daba5738de7707e2bdce36ee16346681f152aebfc600c142484ed9
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading:initial;--tw-font-weight:initial;--tw-outline-style:solid}}}@layer theme{:root,:host{--color-slate-600:oklch(44.6% .043 257.281);--color-slate-800:oklch(27.9% .041 260.031);--spacing:.25rem;--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-semibold:600;--leading-tight:1.25;--radius-sm:.25rem}}@layer utilities{.mt-6{margin-top:calc(var(--spacing) * 6)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-1{margin-bottom:var(--spacing)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.flex{display:flex}.inline-flex{display:inline-flex}.min-w-0{min-width:0}.shrink-0{flex-shrink:0}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-center{justify-content:center}.gap-4{gap:calc(var(--spacing) * 4)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}.text-center{text-align:center}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.break-all{word-break:break-all}.text-\[var\(--lesli-color-primary\)\]{color:var(--lesli-color-primary)}.text-slate-600{color:var(--color-slate-600)}.text-slate-800{color:var(--color-slate-800)}@media (hover:hover){.hover\:underline:hover{text-decoration-line:underline}}.focus-visible\:rounded-sm:focus-visible{border-radius:var(--radius-sm)}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\:outline-\[var\(--lesli-color-primary\)\]:focus-visible{outline-color:var(--lesli-color-primary)}@media (min-width:48rem){.md\:flex-row{flex-direction:row}.md\:justify-start{justify-content:flex-start}.md\:text-left{text-align:left}}}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}
@@ -302,6 +302,68 @@ Building a better future, one line of code at a time.
302
302
  @website https://www.lesli.tech
303
303
  @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
304
304
 
305
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
306
+ // ·
307
+ */
308
+ /*
309
+
310
+ Lesli
311
+
312
+ Copyright (c) 2026, Lesli Technologies, S. A.
313
+
314
+ This program is free software: you can redistribute it and/or modify
315
+ it under the terms of the GNU General Public License as published by
316
+ the Free Software Foundation, either version 3 of the License, or
317
+ (at your option) any later version.
318
+
319
+ This program is distributed in the hope that it will be useful,
320
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
321
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
322
+ GNU General Public License for more details.
323
+
324
+ You should have received a copy of the GNU General Public License
325
+ along with this program. If not, see http://www.gnu.org/licenses/.
326
+
327
+ Lesli · SCSS Utilities for websites and web applications.
328
+
329
+ Made with ♥ by LesliTech
330
+ Building a better future, one line of code at a time.
331
+
332
+ @contact hello@lesli.tech
333
+ @website https://www.lesli.tech
334
+ @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
335
+
336
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
337
+ // ·
338
+ */
339
+ /*
340
+
341
+ Lesli
342
+
343
+ Copyright (c) 2026, Lesli Technologies, S. A.
344
+
345
+ This program is free software: you can redistribute it and/or modify
346
+ it under the terms of the GNU General Public License as published by
347
+ the Free Software Foundation, either version 3 of the License, or
348
+ (at your option) any later version.
349
+
350
+ This program is distributed in the hope that it will be useful,
351
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
352
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
353
+ GNU General Public License for more details.
354
+
355
+ You should have received a copy of the GNU General Public License
356
+ along with this program. If not, see http://www.gnu.org/licenses/.
357
+
358
+ Lesli · SCSS Utilities for websites and web applications.
359
+
360
+ Made with ♥ by LesliTech
361
+ Building a better future, one line of code at a time.
362
+
363
+ @contact hello@lesli.tech
364
+ @website https://www.lesli.tech
365
+ @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
366
+
305
367
  // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
306
368
  // ·
307
369
  */
@@ -41,13 +41,9 @@ module LesliShield
41
41
 
42
42
  # GET /users/1
43
43
  def show
44
- @user_roles = @user.result.roles
45
- @activities = @user.result.logs
46
- .order(id: :desc)
47
- .select(:id, :operation, :description, Date2.new.db_column('created_at', as:'date'))
48
- .limit(7)
49
- .as_json
50
- @sessions = @user.result.sessions
44
+ @user_roles = @user.roles
45
+ @activities = @user.logs
46
+ @sessions = @user.sessions
51
47
  @user = @user.show
52
48
  end
53
49
 
@@ -39,13 +39,13 @@ module LesliShield
39
39
 
40
40
  # # check if user has an active session
41
41
  # if current_session.equal? nil or !current_session.active?
42
- # current_user.logs.create({ title: "system_session_logout", description: "session finished by the system"})
42
+ # current_user.log(operation: "system_session_logout", description: "session finished by the system")
43
43
  # sign_out current_user
44
44
  # redirect_to "#{engine_path}/logout" and return
45
45
  # end
46
46
 
47
47
  # if !current_session.expiration_at.blank? && current_session.expiration_at < Time.current
48
- # current_user.logs.create({ title: "system_session_logout", description: "session expired by the system"})
48
+ # current_user.log(operation: "system_session_logout", description: "session expired by the system")
49
49
  # sign_out current_user
50
50
  # redirect_to "#{engine_path}/logout" and return
51
51
  # end
@@ -53,7 +53,7 @@ module LesliShield
53
53
  # # check password expiration date
54
54
  # if current_user.has_expired_password?
55
55
  # unless controller_name == "profiles"
56
- # current_user.logs.create({ description: "redirect_due_to_expired_password" })
56
+ # current_user.log(operation: "redirect_due_to_expired_password")
57
57
  # redirect_to "/administration/profile#force-password-reset", notice: I18n.t("core.users/sessions.messages_danger_password_expired")
58
58
  # return
59
59
  # end
@@ -154,10 +154,7 @@ module LesliShield
154
154
  unless @resource.active? && @resource.locked_until != nil
155
155
 
156
156
  # save a locked log for the requested user
157
- @resource.logs.create({
158
- title: "session_creation_failed",
159
- description: "user_locked"
160
- })
157
+ log_failure("user_locked")
161
158
 
162
159
  return false
163
160
 
@@ -172,10 +169,7 @@ module LesliShield
172
169
  unless @resource.confirmed?
173
170
 
174
171
  # save a invalid credentials log for the requested user
175
- @resource.logs.create({
176
- title: "session_creation_failed",
177
- description: "email_not_confirmed"
178
- })
172
+ log_failure("email_not_confirmed")
179
173
 
180
174
  return false
181
175
 
@@ -190,10 +184,7 @@ module LesliShield
190
184
  # check if user has roles assigned
191
185
  if @resource.roles.empty?
192
186
 
193
- @resource.logs.create({
194
- title: "session_creation_failed",
195
- description: "user_has_no_assigned_role"
196
- })
187
+ log_failure("user_has_no_assigned_role")
197
188
 
198
189
  return true
199
190
 
@@ -207,15 +198,22 @@ module LesliShield
207
198
 
208
199
  # check user has at least one active role before authorize the sign-in request
209
200
  unless (@resource.roles.map {|role| role.active}.include? true)
210
- @resource.logs.create({
211
- title: "session_creation_failed",
212
- description: "user_has_no_active_role"
213
- })
201
+ log_failure("user_has_no_active_role")
214
202
 
215
203
  return false
216
204
  end
217
205
 
218
206
  return true
219
207
  end
208
+
209
+ def log_failure(description)
210
+ @resource.log(
211
+ engine: LesliShield,
212
+ source: self.class.name,
213
+ action: "validate",
214
+ operation: "session_creation_failed",
215
+ description: description
216
+ )
217
+ end
220
218
  end
221
219
  end
@@ -1,49 +1,39 @@
1
- <div class="user-information-card level mb-4 mt-6">
2
- <div class="level-left">
3
- <div class="level-item">
4
- <%= render LesliView::Elements::Avatar.new(
5
- name: @user.full_name
6
- ) %>
7
- </div>
8
- <div class="level-item">
9
- <div>
10
- <h5 class="title is-size-5 mb-0">
11
- <%= @user.full_name %>
12
- </h5>
13
- <p class="mb-1"><%= @user.title %></p>
14
- <div class="level is-mobile">
15
- <div class="level-left">
16
- <a class="level-item"
17
- href="mailto:<%= @user.email %>">
18
- <span class="icon is-small mr-2">
19
- <span class="material-symbols">
20
- email
21
- </span>
22
- </span>
23
- <%= @user.email %>
24
- </a>
25
- <a class="level-item mx-2"
26
- href="tel:<%= @user.telephone %>">
27
- <span class="icon is-small mr-2">
28
- <span class="material-symbols">
29
- phone
30
- </span>
31
- </span>
32
- <%= @user.telephone %>
33
- </a>
1
+ <div class="user-information-card mt-6 mb-4 flex flex-col items-center gap-4 text-center md:flex-row md:text-left">
2
+ <div class="shrink-0">
3
+ <%= render LesliView::Elements::Avatar.new(
4
+ name: @user.full_name
5
+ ) %>
6
+ </div>
7
+
8
+ <div class="min-w-0">
9
+ <h5 class="text-xl font-semibold leading-tight text-slate-800">
10
+ <%= @user.full_name %>
11
+ </h5>
12
+
13
+ <p class="mb-1 text-slate-600"><%= @user.title %></p>
14
+
15
+ <div class="flex flex-wrap items-center justify-center gap-x-4 gap-y-2 md:justify-start">
16
+ <a
17
+ class="inline-flex min-w-0 items-center text-[var(--lesli-color-primary)] hover:underline focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--lesli-color-primary)]"
18
+ href="mailto:<%= @user.email %>"
19
+ >
20
+ <span class="material-symbols mr-2 shrink-0 text-xl" aria-hidden="true">email</span>
21
+ <span class="break-all"><%= @user.email %></span>
22
+ </a>
23
+
24
+ <a
25
+ class="inline-flex items-center text-[var(--lesli-color-primary)] hover:underline focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--lesli-color-primary)]"
26
+ href="tel:<%= @user.telephone %>"
27
+ >
28
+ <span class="material-symbols mr-2 shrink-0 text-xl" aria-hidden="true">phone</span>
29
+ <%= @user.telephone %>
30
+ </a>
34
31
 
35
- <!-- Show the max role -->
36
- <p class="level-item" v-if="storeUser.role_names">
37
- <span class="icon is-small mr-2">
38
- <span class="material-symbols">
39
- security
40
- </span>
41
- </span>
42
- <%= @user.role_names %>
43
- </p>
44
- </div>
45
- </div>
46
- </div>
32
+ <!-- Show the max role -->
33
+ <p class="inline-flex items-center text-slate-600" v-if="storeUser.role_names">
34
+ <span class="material-symbols mr-2 shrink-0 text-xl" aria-hidden="true">security</span>
35
+ <%= @user.role_names %>
36
+ </p>
47
37
  </div>
48
38
  </div>
49
39
  </div>
@@ -34,6 +34,12 @@ module LesliShield
34
34
  class Engine < ::Rails::Engine
35
35
  isolate_namespace LesliShield
36
36
 
37
+ config.to_prepare do
38
+ unless Lesli::User < LesliShield::UserSecurity
39
+ Lesli::User.include(LesliShield::UserSecurity)
40
+ end
41
+ end
42
+
37
43
  initializer :lesli_shield do |app|
38
44
 
39
45
  # register assets manifest
@@ -1,4 +1,4 @@
1
1
  module LesliShield
2
- VERSION = "1.1.5"
3
- BUILD = "1789353654"
2
+ VERSION = "1.1.6"
3
+ BUILD = "1791607001"
4
4
  end
data/readme.md CHANGED
@@ -73,7 +73,7 @@ Add the engine to the host Rails application and prepare its database:
73
73
 
74
74
  ```shell
75
75
  bundle add lesli_shield
76
- bin/rails db:prepare
76
+ bin/rails lesli:db:prepare
77
77
  ```
78
78
 
79
79
  ### Mount the engine
@@ -124,7 +124,7 @@ Install dependencies, prepare the host database, and start Rails:
124
124
 
125
125
  ```shell
126
126
  bundle install
127
- bin/rails db:prepare
127
+ bin/rails lesli:db:prepare
128
128
  bin/rails server
129
129
  ```
130
130
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lesli_shield
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.5
4
+ version: 1.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Lesli Development Team