masks 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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: {