Add invite button and routes for resending invitations

This commit is contained in:
Dan Milne
2025-10-25 13:49:10 +11:00
parent df834b6e57
commit 5921cf82c2
6 changed files with 21 additions and 12 deletions

View File

@@ -26,10 +26,10 @@ gem "bcrypt", "~> 3.1.7"
gem "rotp", "~> 6.3" gem "rotp", "~> 6.3"
# QR code generation for TOTP setup # QR code generation for TOTP setup
gem "rqrcode", "~> 2.0" gem "rqrcode", "~> 3.1"
# JWT for OIDC ID tokens # JWT for OIDC ID tokens
gem "jwt", "~> 2.9" gem "jwt", "~> 3.1"
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem "tzinfo-data", platforms: %i[ windows jruby ] gem "tzinfo-data", platforms: %i[ windows jruby ]

View File

@@ -145,7 +145,7 @@ GEM
actionview (>= 7.0.0) actionview (>= 7.0.0)
activesupport (>= 7.0.0) activesupport (>= 7.0.0)
json (2.15.1) json (2.15.1)
jwt (2.10.2) jwt (3.1.2)
base64 base64
kamal (2.8.1) kamal (2.8.1)
activesupport (>= 7.0) activesupport (>= 7.0)
@@ -276,10 +276,10 @@ GEM
io-console (~> 0.5) io-console (~> 0.5)
rexml (3.4.4) rexml (3.4.4)
rotp (6.3.0) rotp (6.3.0)
rqrcode (2.2.0) rqrcode (3.1.0)
chunky_png (~> 1.0) chunky_png (~> 1.0)
rqrcode_core (~> 1.0) rqrcode_core (~> 2.0)
rqrcode_core (1.2.0) rqrcode_core (2.0.0)
rubocop (1.81.6) rubocop (1.81.6)
json (~> 2.3) json (~> 2.3)
language_server-protocol (~> 3.17.0.2) language_server-protocol (~> 3.17.0.2)
@@ -312,9 +312,9 @@ GEM
ruby-vips (2.2.5) ruby-vips (2.2.5)
ffi (~> 1.12) ffi (~> 1.12)
logger logger
rubyzip (3.2.0) rubyzip (3.2.1)
securerandom (0.4.1) securerandom (0.4.1)
selenium-webdriver (4.37.0) selenium-webdriver (4.38.0)
base64 (~> 0.2) base64 (~> 0.2)
logger (~> 1.4) logger (~> 1.4)
rexml (~> 3.2, >= 3.2.5) rexml (~> 3.2, >= 3.2.5)
@@ -414,13 +414,13 @@ DEPENDENCIES
image_processing (~> 1.2) image_processing (~> 1.2)
importmap-rails importmap-rails
jbuilder jbuilder
jwt (~> 2.9) jwt (~> 3.1)
kamal kamal
propshaft propshaft
puma (>= 5.0) puma (>= 5.0)
rails (~> 8.1.0) rails (~> 8.1.0)
rotp (~> 6.3) rotp (~> 6.3)
rqrcode (~> 2.0) rqrcode (~> 3.1)
rubocop-rails-omakase rubocop-rails-omakase
selenium-webdriver selenium-webdriver
solid_cable solid_cable

View File

@@ -8,6 +8,7 @@ class User < ApplicationRecord
has_many :oidc_user_consents, dependent: :destroy has_many :oidc_user_consents, dependent: :destroy
# Token generation for passwordless flows # Token generation for passwordless flows
generates_token_for :invitation_login, expires_in: 24.hours
generates_token_for :invitation, expires_in: 7.days generates_token_for :invitation, expires_in: 7.days
generates_token_for :password_reset, expires_in: 1.hour generates_token_for :password_reset, expires_in: 1.hour
generates_token_for :magic_login, expires_in: 15.minutes generates_token_for :magic_login, expires_in: 15.minutes

View File

@@ -66,6 +66,9 @@
<%= user.groups.count %> <%= user.groups.count %>
</td> </td>
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-0"> <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-0">
<% if user.pending_invitation? %>
<%= button_to "Resend", resend_invitation_admin_user_path(user), method: :post, class: "text-yellow-600 hover:text-yellow-900 mr-4" %>
<% end %>
<%= link_to "Edit", edit_admin_user_path(user), class: "text-blue-600 hover:text-blue-900 mr-4" %> <%= link_to "Edit", edit_admin_user_path(user), class: "text-blue-600 hover:text-blue-900 mr-4" %>
<%= button_to "Delete", admin_user_path(user), method: :delete, data: { turbo_confirm: "Are you sure you want to delete this user?" }, class: "text-red-600 hover:text-red-900" %> <%= button_to "Delete", admin_user_path(user), method: :delete, data: { turbo_confirm: "Are you sure you want to delete this user?" }, class: "text-red-600 hover:text-red-900" %>
</td> </td>

View File

@@ -46,7 +46,7 @@
</div> </div>
<% else %> <% else %>
<!-- Public layout (signup/signin) --> <!-- Public layout (signup/signin) -->
<main class="container mx-auto mt-28 px-5 flex"> <main class="container mx-auto mt-28 px-5">
<%= render "shared/flash" %> <%= render "shared/flash" %>
<%= yield %> <%= yield %>
</main> </main>

View File

@@ -1,6 +1,7 @@
Rails.application.routes.draw do Rails.application.routes.draw do
resource :session resource :session
resources :passwords, param: :token resources :passwords, param: :token
resources :invitations, param: :token, only: [:show, :update]
mount ActionCable.server => "/cable" mount ActionCable.server => "/cable"
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
@@ -56,7 +57,11 @@ Rails.application.routes.draw do
# Admin routes # Admin routes
namespace :admin do namespace :admin do
root "dashboard#index" root "dashboard#index"
resources :users resources :users do
member do
post :resend_invitation
end
end
resources :applications do resources :applications do
member do member do
post :regenerate_credentials post :regenerate_credentials