masks 0.3.1 → 0.4.0

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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/builds/masks/application.css +1 -1
  3. data/app/assets/builds/masks/application.js +2153 -726
  4. data/app/assets/builds/masks/application.js.map +4 -4
  5. data/app/assets/javascripts/controllers/application.js +1 -1
  6. data/app/assets/javascripts/controllers/index.js +9 -0
  7. data/app/assets/javascripts/controllers/table_controller.js +15 -0
  8. data/app/assets/stylesheets/application.css +12 -4
  9. data/app/controllers/concerns/masks/controller.rb +1 -1
  10. data/app/controllers/masks/manage/actors_controller.rb +72 -1
  11. data/app/controllers/masks/manage/base_controller.rb +10 -2
  12. data/app/controllers/masks/manage/clients_controller.rb +84 -0
  13. data/app/controllers/masks/manage/dashboard_controller.rb +15 -0
  14. data/app/controllers/masks/manage/devices_controller.rb +19 -0
  15. data/app/controllers/masks/openid/authorizations_controller.rb +45 -0
  16. data/app/controllers/masks/openid/discoveries_controller.rb +55 -0
  17. data/app/controllers/masks/openid/tokens_controller.rb +45 -0
  18. data/app/controllers/masks/openid/userinfo_controller.rb +28 -0
  19. data/app/controllers/masks/sessions_controller.rb +1 -1
  20. data/app/models/concerns/masks/access.rb +2 -2
  21. data/app/models/masks/access/actor_password.rb +2 -1
  22. data/app/models/masks/access/actor_signup.rb +1 -2
  23. data/app/models/masks/credentials/access_token.rb +60 -0
  24. data/app/models/masks/credentials/key.rb +1 -1
  25. data/app/models/masks/credentials/return_to.rb +27 -0
  26. data/app/models/masks/mask.rb +12 -1
  27. data/app/models/masks/openid/authorization.rb +116 -0
  28. data/app/models/masks/openid/token.rb +56 -0
  29. data/app/models/masks/rails/actor.rb +23 -1
  30. data/app/models/masks/rails/openid/access_token.rb +55 -0
  31. data/app/models/masks/rails/openid/authorization.rb +45 -0
  32. data/app/models/masks/rails/openid/client.rb +186 -0
  33. data/app/models/masks/rails/openid/id_token.rb +43 -0
  34. data/app/models/masks/sessions/access.rb +2 -1
  35. data/app/resources/masks/session_resource.rb +1 -1
  36. data/app/views/layouts/masks/manage.html.erb +22 -5
  37. data/app/views/masks/actor_mailer/recover_credentials.html.erb +2 -3
  38. data/app/views/masks/actor_mailer/verify_email.html.erb +2 -3
  39. data/app/views/masks/actors/current.html.erb +7 -14
  40. data/app/views/masks/application/_header.html.erb +3 -4
  41. data/app/views/masks/backup_codes/new.html.erb +34 -20
  42. data/app/views/masks/emails/new.html.erb +14 -8
  43. data/app/views/masks/keys/new.html.erb +7 -7
  44. data/app/views/masks/manage/actors/index.html.erb +101 -37
  45. data/app/views/masks/manage/{actor → actors}/show.html.erb +63 -17
  46. data/app/views/masks/manage/clients/index.html.erb +102 -0
  47. data/app/views/masks/manage/clients/show.html.erb +156 -0
  48. data/app/views/masks/manage/dashboard/index.html.erb +10 -0
  49. data/app/views/masks/manage/devices/index.html.erb +47 -0
  50. data/app/views/masks/one_time_code/new.html.erb +41 -24
  51. data/app/views/masks/openid/authorizations/error.html.erb +23 -0
  52. data/app/views/masks/openid/authorizations/new.html.erb +46 -0
  53. data/app/views/masks/passwords/edit.html.erb +20 -7
  54. data/app/views/masks/recoveries/new.html.erb +2 -4
  55. data/app/views/masks/recoveries/password.html.erb +2 -3
  56. data/app/views/masks/sessions/new.html.erb +22 -23
  57. data/config/initializers/inflections.rb +5 -0
  58. data/config/locales/en.yml +23 -2
  59. data/config/routes.rb +40 -3
  60. data/db/migrate/20240329182422_support_openid.rb +64 -0
  61. data/lib/generators/masks/install/templates/masks.json +4 -1
  62. data/lib/masks/configuration.rb +22 -9
  63. data/lib/masks/version.rb +1 -1
  64. data/lib/masks.rb +1 -0
  65. data/lib/tasks/masks_tasks.rake +3 -2
  66. data/masks.json +47 -6
  67. metadata +59 -11
  68. data/app/assets/builds/application.css +0 -4764
  69. data/app/assets/builds/application.js +0 -8236
  70. data/app/assets/builds/application.js.map +0 -7
  71. data/app/controllers/masks/manage/actor_controller.rb +0 -35
@@ -0,0 +1,102 @@
1
+ <div data-controller="dialog" data-action="click->dialog#backdropClose">
2
+ <div class="mb-4 flex items-center gap-2">
3
+ <%= lucide_icon('handshake', class: 'w-5 h-5') %>
4
+
5
+ <h1 class="font-bold flex-grow">
6
+ clients
7
+ </h1>
8
+
9
+ <button class="btn btn-sm btn-ghost btn-primary" data-action="dialog#open">
10
+ <span class="">
11
+ <%= lucide_icon('plus-square', class: 'w-5 h-5') %>
12
+ </span>
13
+
14
+ new
15
+ </button>
16
+ </div>
17
+
18
+ <dialog class="modal" data-dialog-target="dialog">
19
+ <div class="modal-box">
20
+ <form method="dialog">
21
+ <button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"><%= lucide_icon('x') %></button>
22
+ </form>
23
+
24
+ <h3 class="mb-4 ml-1 font-bold flex items-center gap-2">
25
+ <%= lucide_icon('plus-square', size: 16) %>
26
+ new client
27
+ </h3>
28
+ <%= form_with url: manage_clients_path, method: :post do |form| %>
29
+ <label class="form-control input input-bordered flex flex-row gap-4 items-center flex-grow mb-4">
30
+ name
31
+
32
+ <input placeholder="enter a name for the client..." type="text" name="name" class="grow" />
33
+ </label>
34
+
35
+ <div class="modal-actions">
36
+ <input type="submit" class="btn btn-sm btn-success" value="add" />
37
+ </div>
38
+ <% end %>
39
+ </div>
40
+ </dialog>
41
+
42
+ <% if flash[:errors]&.any? %>
43
+ <div role="alert" class="alert alert-error mb-4 mt-0">
44
+ <%= lucide_icon('x-circle') %>
45
+ <div>
46
+ <h3 class="font-bold">failed to add client...</h3>
47
+ <ul class="list-disc pl-4">
48
+ <% flash[:errors].each do |error| %>
49
+ <li><%= error %></li>
50
+ <% end %>
51
+ </ul>
52
+ </div>
53
+ </div>
54
+ <% end %>
55
+
56
+ <% if flash[:destroyed] %>
57
+ <div role="alert" class="alert alert-error mb-4 mt-0 flex items-center">
58
+ <%= lucide_icon('trash-2') %>
59
+ <div>
60
+ <h3 class="font-bold">"<%= flash[:destroyed] %>" deleted...</h3>
61
+ </div>
62
+ </div>
63
+ <% end %>
64
+
65
+ <div class="overflow-x-auto">
66
+ <table class="table table-fixed md:table-auto bg-base-100">
67
+ <thead>
68
+ <tr>
69
+ <th>name</th>
70
+ <th class="text-right">created</th>
71
+ </tr>
72
+ </thead>
73
+ <tbody>
74
+ <% if @clients.any? %>
75
+ <% @clients.each do |client| %>
76
+ <tr data-action="click->table#click" data-controller="table" class="cursor-pointer">
77
+ <td>
78
+ <a data-table-target="url" href="<%= manage_client_path(client) %>" class="flex flex-col">
79
+ <span class="font-bold truncate"><%= client.name %></span>
80
+ <span class="font-mono text-xs truncate"><%= client.key %></span>
81
+ </a>
82
+ </td>
83
+ <td class="text-right text-xs">
84
+ <%= time_ago_in_words(client.created_at) %> ago
85
+ </td>
86
+ </tr>
87
+ <% end %>
88
+ <% else %>
89
+ <tr>
90
+ <td colspan="2" class="text-center text-sm">
91
+ nothing found...
92
+ </td>
93
+ </tr>
94
+ <% end %>
95
+ </tbody>
96
+ </table>
97
+ </div>
98
+
99
+ <% if @pagy.pages > 1 %>
100
+ <%== pagy_nav(@pagy) %>
101
+ <% end%>
102
+ </div>
@@ -0,0 +1,156 @@
1
+ <%= form_with url: manage_client_path(@client), method: :patch, data: { turbo: false } do |form| %>
2
+ <div class="flex items-center gap-2 mb-6">
3
+ <%= lucide_icon('handshake', class: 'w-5 h-5') %>
4
+
5
+ <input name="name" type="text" class="input input-sm text-lg input-ghost font-bold flex-grow" value="<%= @client.name %>">
6
+ <input type="submit" name="submit" value="save" class="btn btn-sm btn-success">
7
+ </div>
8
+
9
+ <% if flash[:errors]&.any? %>
10
+ <div role="alert" class="alert alert-error mb-4 mt-0">
11
+ <%= lucide_icon('x-circle') %>
12
+ <div>
13
+ <h3 class="font-bold">error(s) occurred while saving...</h3>
14
+ <ul class="list-disc pl-4">
15
+ <% flash[:errors].each do |error| %>
16
+ <li><%= error %></li>
17
+ <% end %>
18
+ </ul>
19
+ </div>
20
+ </div>
21
+ <% end %>
22
+
23
+ <div class="bg-base-300 flex flex-col gap-2 p-4 rounded-xl mb-4">
24
+ <label class="form-control w-full">
25
+ <div class="label">
26
+ <span class="label-text">client type</span>
27
+ </div>
28
+
29
+ <select class="select select-bordered" name="response_type">
30
+ <option value="confidential" <%= @client.client_type == 'confidential' ? 'selected' : '' %>>confidential</option>
31
+ <option value="public" <%= @client.client_type == 'public' ? 'selected' : '' %>>public</option>
32
+ </select>
33
+ </label>
34
+
35
+ <div class="form-control pl-2 mb-1">
36
+ <label class="flex items-center gap-4">
37
+ <input name="consent" type="checkbox" class="toggle toggle-sm" <%= @client.consent ? 'checked' : '' %>>
38
+
39
+ <span class="label-text">require consent when authorizing this client</span>
40
+ </label>
41
+ </div>
42
+
43
+ <div class="form-control w-full">
44
+ <div class="label">
45
+ <span class="label-text">credentials</span>
46
+ </div>
47
+
48
+ <label class="input input-bordered flex items-center gap-4 mb-2 text-sm">
49
+ key
50
+ <input name="key" class="text-base" type="text" class="grow" value="<%= @client.key %>" disabled>
51
+ </label>
52
+
53
+ <label class="input input-bordered flex items-center gap-4 text-sm" data-controller="password-visibility">
54
+ secret
55
+ <input name="secret" class="text-base flex-grow" type="password" value="<%= @client.secret %>" data-password-visibility-target="input" spellcheck="false">
56
+ <button data-action="password-visibility#toggle" type="button">
57
+ <span data-password-visibility-target="icon"><%= lucide_icon('eye') %></span>
58
+ <span data-password-visibility-target="icon" class="hidden"><%= lucide_icon('eye-off') %></span>
59
+ </button>
60
+ </label>
61
+ </div>
62
+
63
+ <label class="form-control">
64
+ <div class="label">
65
+ <span class="label-text">redirect uri(s)</span>
66
+ </div>
67
+
68
+ <textarea name="redirect_uris" class="textarea textarea-bordered h-24" placeholder="separate by a newline..."><%= @client.redirect_uris&.join("\n") %></textarea>
69
+ </label>
70
+
71
+ <div class="form-control w-full">
72
+ <div class="label">
73
+ <span class="label-text">subject type</span>
74
+ </div>
75
+
76
+ <select name="subject_type" class="select select-bordered">
77
+ <option value="nickname" <%= @client.subject_type == 'nickname' ? 'selected' : '' %>>nickname</option>
78
+ <option value="email" <%= @client.subject_type == 'email' ? 'selected' : '' %>>email</option>
79
+ <option value="pairwise" <%= @client.subject_type == 'pairwise' ? 'selected' : '' %>>anonymized</option>
80
+ </select>
81
+ </div>
82
+
83
+ <div class="form-control w-full">
84
+ <div class="label">
85
+ <span class="label-text">lifetimes</span>
86
+ </div>
87
+
88
+ <label class="input input-bordered flex items-center gap-4 mb-2 text-sm">
89
+ auth codes
90
+ <input name="code_expires_in" type="text" class="grow" value="<%= @client.code_expires_in %>">
91
+ </label>
92
+
93
+ <label class="input input-bordered flex items-center gap-4 text-sm mb-2">
94
+ access tokens
95
+ <input name="token_expires_in" type="text" class="grow" value="<%= @client.token_expires_in %>">
96
+ </label>
97
+
98
+ <label class="input input-bordered flex items-center gap-4 text-sm">
99
+ refresh tokens
100
+ <input name="refresh_expires_in" type="text" class="grow" value="<%= @client.refresh_expires_in %>">
101
+ </label>
102
+ </div>
103
+ </div>
104
+ <% end %>
105
+
106
+ <div class="overflow-x-auto max-h-96 rounded-xl mb-4">
107
+ <table class="table table-pin-rows bg-base-300">
108
+ <thead>
109
+ <tr class="">
110
+ <th class="py-2 w-full">scopes</th>
111
+ <th class="py-2"></th>
112
+ </tr>
113
+ </thead>
114
+ <tbody>
115
+ <tr>
116
+ <td colspan="2">
117
+ <%= form_with url: manage_client_path(@client), method: :patch do |form| %>
118
+ <div class="flex items-center gap-2">
119
+ <%= lucide_icon('plus-square', class: 'text-base-300-content') %>
120
+ <input type="text" name="add_scope" class="flex-grow input input-sm" placeholder="add a scope...">
121
+ <input type="submit" class="btn btn-sm" value="add">
122
+ </div>
123
+ <% end %>
124
+ </td>
125
+ </tr>
126
+ <% @client.scopes.each do |scope| %>
127
+ <tr>
128
+ <td class="font-mono w-full"><%= scope %></td>
129
+ <td class="">
130
+ <%= form_with url: manage_client_path(@client), method: :patch do |form| %>
131
+ <input type="hidden" name="remove_scope" value="<%= scope %>">
132
+
133
+ <button type="submit" class="btn btn-ghost btn-error hover:btn-outline btn-xs" <%= scope == 'openid' ? 'disabled' : '' %>>
134
+ <%= lucide_icon('x', class: 'w-4 h-4') %>
135
+ </button>
136
+ <% end %>
137
+ </td>
138
+ </tr>
139
+ <% end %>
140
+ </tbody>
141
+ </table>
142
+ </div>
143
+
144
+ <%= form_with url: manage_client_path(@client), method: :delete do |form| %>
145
+ <div class="border border-error bg-base-300 flex gap-2 p-4 rounded-xl mb-4 items-center">
146
+ <p class="text-error">
147
+ <%= lucide_icon('trash-2') %>
148
+ </p>
149
+
150
+ <p class="flex-grow text-error">
151
+ <span class="font-bold">permanently</span> delete this client...
152
+ </p>
153
+
154
+ <input type="submit" class="btn btn-sm btn-error" value="delete" />
155
+ </div>
156
+ <% end %>
@@ -0,0 +1,10 @@
1
+ <div class="flex items-center gap-4 text-center">
2
+ <div class="bg-base-300 p-8 rounded-xl flex-grow">
3
+ <p class="text-4xl"><%= @actors %></p>
4
+ <p>actors</a>
5
+ </div>
6
+ <div class="bg-base-300 p-8 rounded-xl flex-grow">
7
+ <p class="text-4xl"><%= @clients %></p>
8
+ <p>clients</a>
9
+ </div>
10
+ </div>
@@ -0,0 +1,47 @@
1
+ <div class="mb-6 flex items-center gap-2">
2
+ <%= lucide_icon('monitor-smartphone', class: 'w-5 h-5') %>
3
+
4
+ <h1 class="font-bold flex-grow">
5
+ devices
6
+ </h1>
7
+ </div>
8
+
9
+ <div class="overflow-x-auto">
10
+ <table class="table bg-base-100">
11
+ <!-- head -->
12
+ <thead>
13
+ <tr>
14
+ <th class="w-10"></th>
15
+ <th>browser</th>
16
+ <th>os</th>
17
+ <th>ip address</th>
18
+ <th class="text-right">owner</th>
19
+ </tr>
20
+ </thead>
21
+ <tbody>
22
+ <% @devices.each do |device| %>
23
+ <tr>
24
+ <td class="w-10">
25
+ <%= lucide_icon(device_icon(device), size: 16) %>
26
+ </td>
27
+ <td class="truncate">
28
+ <%= device.name %>
29
+ </td>
30
+ <td class="text-xs whitespace-nowrap">
31
+ <%= device.os_name%>
32
+ </td>
33
+ <td class="text-xs whitespace-nowrap">
34
+ <%= device.ip_address %>
35
+ </td>
36
+ <td class="text-right">
37
+ <a class="underline" href="<%= manage_actor_path(device.actor) %>">
38
+ <%= device.actor&.nickname || 'unknown' %>
39
+ </a>
40
+ </td>
41
+ </tr>
42
+ <% end %>
43
+ </tbody>
44
+ </table>
45
+ </div>
46
+
47
+ <%== pagy_nav(@pagy) %>
@@ -17,12 +17,12 @@
17
17
  <% if !@actor.totp_secret %>
18
18
  <div class='divider my-2 mb-4'></div>
19
19
  <div class="">
20
- <div class="">
21
- <div class="flex gap-4">
22
- <div class="w-[125px] h-[125px] rounded-md overflow-hidden">
23
- <%= totp_svg(@actor.totp_uri, module_size: 2.35, fill: "fff", offset: 5) %>
20
+ <div>
21
+ <div class="flex gap-4 mb-3">
22
+ <div class="w-[125px] h-[125px] overflow-hidden">
23
+ <%= totp_svg(@actor.totp_uri, module_size: 2.25, fill: "fff", offset: 5) %>
24
24
  </div>
25
- <div class="max-w-[175px] space-y-3 mb-2">
25
+ <div class="max-w-[175px] max-w-[250px] space-y-3 mb-2">
26
26
  <div>
27
27
  <%= t(".enable_qr") %>
28
28
  </div>
@@ -40,8 +40,7 @@
40
40
  <input
41
41
  class="input input-xs w-full"
42
42
  name="secret"
43
- value="<%= @actor.random_totp_secret %>"
44
- />
43
+ value="<%= @actor.random_totp_secret %>">
45
44
  </span>
46
45
  </div>
47
46
  <div class='divider mt-3 mb-2 text-xs'></div>
@@ -64,30 +63,43 @@
64
63
  <input
65
64
  type="hidden"
66
65
  name="one_time_code[secret]"
67
- value="<%= @actor.random_totp_secret %>"
68
- />
69
- <label class="flex gap-3 items-center">
66
+ value="<%= @actor.random_totp_secret %>">
67
+ <label class="flex gap-3 items-center w-full flex-grow input input-bordered" data-controller="password-visibility">
70
68
  <%= lucide_icon("shield-check") %>
69
+
71
70
  <input
72
71
  type="password"
73
72
  data-one-time-password-target="password"
74
73
  data-action="one_time_code#updatePassword"
74
+ data-password-visibility-target="input"
75
+ spellcheck="false"
75
76
  placeholder="<%= t('.placeholder.password') %>"
76
77
  name="session[password]"
77
- class="input w-full"
78
- />
78
+ class="w-full flex-grow">
79
+
80
+ <button data-action="password-visibility#toggle" type="button" class="btn btn-sm btn-ghost -mr-2">
81
+ <span data-password-visibility-target="icon"><%= lucide_icon('eye') %></span>
82
+ <span data-password-visibility-target="icon" class="hidden"><%= lucide_icon('eye-off') %></span>
83
+ </button>
79
84
  </label>
80
85
  <div class="flex items-center gap-2">
81
- <label class="flex gap-3 items-center">
86
+ <label class="flex gap-3 items-center input input-bordered flex-grow" data-controller="password-visibility">
82
87
  <%= lucide_icon("key-square") %>
88
+
83
89
  <input
84
90
  type="password"
85
91
  data-one-time-password-target="code"
86
92
  data-action="one_time_code#updateCode"
87
93
  placeholder="<%= t('.placeholder.otp') %>"
94
+ data-password-visibility-target="input"
95
+ spellcheck="false"
88
96
  name="one_time_code[code]"
89
- class="input w-full"
90
- />
97
+ class="w-full flex-grow">
98
+
99
+ <button data-action="password-visibility#toggle" type="button" class="btn btn-sm btn-ghost -mr-2">
100
+ <span data-password-visibility-target="icon"><%= lucide_icon('eye') %></span>
101
+ <span data-password-visibility-target="icon" class="hidden"><%= lucide_icon('eye-off') %></span>
102
+ </button>
91
103
  </label>
92
104
  <%= form.submit t(".submit"),
93
105
  class: "btn btn-secondary",
@@ -108,8 +120,7 @@
108
120
  </div>
109
121
  <div
110
122
  class="join-item card bg-base-100 pt-2 pb-3 px-4 w-full text-right"
111
- role="alert"
112
- >
123
+ role="alert">
113
124
  <a href="<%= backup_codes_path %>" class="text-sm underline">
114
125
  <%= t(@actor.should_save_backup_codes? ? ".backup_codes" : ".reset_codes") %>
115
126
  </a>
@@ -122,21 +133,27 @@
122
133
  <input
123
134
  type="hidden"
124
135
  name="one_time_code[secret]"
125
- value="<%= @actor.random_totp_secret %>"
126
- />
136
+ value="<%= @actor.random_totp_secret %>">
127
137
 
128
- <div class="alert py-2">
129
- <%= lucide_icon("shield-check") %>
130
- <label class="flex gap-3 items-center flex-grow">
138
+ <div class="flex gap-2">
139
+ <label class="flex gap-3 items-center flex-grow input input-sm input-bordered" data-controller="password-visibility">
140
+ <%= lucide_icon("shield-check") %>
131
141
  <input
132
142
  type="password"
133
143
  data-one-time-password-target="password"
134
144
  data-action="one_time_code#updatePassword"
145
+ data-password-visibility-target="input"
146
+ spellcheck="false"
135
147
  placeholder="<%= t('.placeholder.delete') %>"
136
148
  name="session[password]"
137
- class="input input-sm input-bordered w-full"
138
- />
149
+ class="w-full flex-grow">
150
+
151
+ <button data-action="password-visibility#toggle" type="button" class="btn btn-xs btn-ghost -mr-2">
152
+ <span data-password-visibility-target="icon"><%= lucide_icon('eye', size: 16) %></span>
153
+ <span data-password-visibility-target="icon" class="hidden"><%= lucide_icon('eye-off', size: 16) %></span>
154
+ </button>
139
155
  </label>
156
+
140
157
  <div>
141
158
  <%= form.submit t(".delete"),
142
159
  class: "btn hover:btn-error btn-outline btn-sm",
@@ -0,0 +1,23 @@
1
+ <div class="hero">
2
+ <div class="hero-content text-left">
3
+ <div>
4
+ <div class="flex items-center gap-4 mb-4 justify-center">
5
+ <span class="text-warning pt-1">
6
+ <%= lucide_icon('alert-triangle', size: 28) %>
7
+ </span>
8
+
9
+ <h1 class="text-3xl font-bold text-black dark:text-white">
10
+ <%= t('.title') %>
11
+ </h1>
12
+ </div>
13
+ <p class="mb-6 text-center">
14
+ <%= t('.description') %>
15
+ </p>
16
+ <div class="flex items-center gap-4 justify-center">
17
+ <a href="/" class="btn btn-primary btn-sm">
18
+ <%= t('.home') %>
19
+ </a>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ </div>
@@ -0,0 +1,46 @@
1
+ <div>
2
+ <%= form_with url: request.url, method: :post, data: { turbo: false } do |form| %>
3
+ <div class="hero">
4
+ <div class="hero-content text-left">
5
+ <div class="">
6
+ <h1 class="text-4xl font-bold mb-4 text-black dark:text-white">
7
+ <%= t(".authorize_client", name: @authorization.client.name) %>
8
+ </h1>
9
+
10
+ <p class="mb-4 text-left">
11
+ <% if @authorization.scopes.any? %>
12
+ <%= t('.authorize_scoped', name: @authorization.client.name) %>
13
+ <% else %>
14
+ <%= t('.authorize_account', name: @authorization.client.name) %>
15
+ <% end %>
16
+ </p>
17
+
18
+ <% if @authorization.scopes.any? %>
19
+ <div class="divider my-0"></div>
20
+
21
+ <table class="table">
22
+ <tbody>
23
+ <% @authorization.scopes.each do |scope| %>
24
+ <tr>
25
+ <th><%= t("scope.#{scope}_name") %></td>
26
+ <td>
27
+ <%= t("scope.#{scope}_desc") %>
28
+ </td>
29
+ </tr>
30
+ <% end %>
31
+ </tbody>
32
+ </table>
33
+
34
+ <div class="divider mt-0 mb-4"></div>
35
+ <% end %>
36
+
37
+ <div class="flex items-center gap-4 justify-center">
38
+ <input type="submit" name="approve" value="<%= t('.approve') %>" class="btn btn-success btn-sm">
39
+ <span>or</span>
40
+ <input type="submit" name="deny" value="<%= t('.deny') %>" class="btn btn-error btn-sm">
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ <% end %>
46
+ </div>
@@ -25,28 +25,41 @@
25
25
  <% end %>
26
26
 
27
27
  <%= form_with url: password_path, method: :post, class: 'pt-2 flex flex-col gap-2', data: { password_target: 'add' } do |form| %>
28
- <label class="flex gap-3 items-center">
28
+ <label class="flex gap-3 items-center input input-bordered" data-controller="password-visibility">
29
29
  <%= lucide_icon("shield-plus") %>
30
30
  <input
31
31
  type="password"
32
32
  data-password-target="code"
33
33
  data-action="password#updateChanged"
34
+ data-password-visibility-target="input"
35
+ spellcheck="false"
34
36
  placeholder="<%= t('.placeholder.change') %>"
35
37
  name="password[change]"
36
- class="input w-full"
37
- />
38
+ class="w-full">
39
+
40
+ <button data-action="password-visibility#toggle" type="button" class="btn btn-sm btn-ghost -mr-2">
41
+ <span data-password-visibility-target="icon"><%= lucide_icon('eye') %></span>
42
+ <span data-password-visibility-target="icon" class="hidden"><%= lucide_icon('eye-off') %></span>
43
+ </button>
38
44
  </label>
39
- <div class="flex items-center gap-2">
40
- <label class="flex gap-3 items-center">
45
+ <div class="flex items-center gap-2" data-controller="password-visibility">
46
+ <label class="flex gap-3 items-center w-full flex-grow input input-bordered">
41
47
  <%= lucide_icon("shield-check") %>
48
+
42
49
  <input
43
50
  type="password"
44
51
  data-password-target="password"
45
52
  data-action="password#updatePassword"
53
+ data-password-visibility-target="input"
54
+ spellcheck="false"
46
55
  placeholder="<%= t('.placeholder.password') %>"
47
56
  name="session[password]"
48
- class="input w-full"
49
- />
57
+ class="w-full flex-grow">
58
+
59
+ <button data-action="password-visibility#toggle" type="button" class="btn btn-sm btn-ghost -mr-2">
60
+ <span data-password-visibility-target="icon"><%= lucide_icon('eye') %></span>
61
+ <span data-password-visibility-target="icon" class="hidden"><%= lucide_icon('eye-off') %></span>
62
+ </button>
50
63
  </label>
51
64
  <%= form.submit t(".submit"),
52
65
  class: "btn btn-secondary",
@@ -20,8 +20,7 @@
20
20
  class="
21
21
  dropdown-content z-[1] mt-4 card card-compact w-[275px] px-2 pb-2 shadow bg-info
22
22
  text-info-content
23
- "
24
- >
23
+ ">
25
24
  <div class="card-body">
26
25
  <h4 class="card-title"><%= t(".help_title") %></h4>
27
26
  <span><%= t(".help_body") %></span>
@@ -51,8 +50,7 @@
51
50
  data-action="recover#updateInput"
52
51
  placeholder="<%= t('.placeholder') %>"
53
52
  name="recover[value]"
54
- class="input input-bordered w-full"
55
- />
53
+ class="input input-bordered w-full">
56
54
  </label>
57
55
  <div class="flex items-center gap-4">
58
56
  <%= form.submit t(".submit"),
@@ -22,15 +22,14 @@
22
22
  <%= form_with url: recover_password_path, method: :post do |form| %>
23
23
  <div class="flex flex-col gap-4">
24
24
  <div class="flex items-center gap-4">
25
- <input type="hidden" name="token" value="<%= @recovery.token %>"/>
25
+ <input type="hidden" name="token" value="<%= @recovery.token %>">
26
26
  <input
27
27
  type="text"
28
28
  data-recover-password-target="password"
29
29
  data-action="recover-password#updatePassword"
30
30
  placeholder="<%= t('.placeholder') %>"
31
31
  name="recover[password]"
32
- class="input input-bordered w-full"
33
- />
32
+ class="input input-bordered w-full">
34
33
  <%= form.submit t(".submit"),
35
34
  class: "btn btn-warning btn-info",
36
35
  data: {