Skip to content

Commit

Permalink
added turbo click event to session extend button
Browse files Browse the repository at this point in the history
  • Loading branch information
GeorgeCodes19 committed Feb 25, 2025
1 parent 80e2fd3 commit 48a1e9c
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 77 deletions.
48 changes: 48 additions & 0 deletions app/app/controllers/api/sessions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
class Api::SessionsController < ApplicationController
# Skip CSRF protection for API calls if you're using protect_from_forgery
# skip_before_action :verify_authenticity_token, only: [:extend]

def extend
Rails.logger.info "API::SessionsController#extend called"

# Reset the Devise timeout timer
request.env['devise.skip_timeout'] = true

if current_user
Rails.logger.info "Current user found: #{current_user.id}"
current_user.remember_me! if current_user.respond_to?(:remember_me!)
current_user.remember_me = true if current_user.respond_to?(:remember_me=)
sign_in(current_user, force: true)

respond_to do |format|
format.json {
Rails.logger.info "Responding with JSON"
render json: { success: true, message: "Session extended successfully" }
}
format.html {
Rails.logger.info "Responding with HTML redirect"
redirect_back(fallback_location: root_path)
}
format.any {
Rails.logger.info "Responding with 406 Not Acceptable"
head :not_acceptable
}
end
else
Rails.logger.warn "No current user found"
respond_to do |format|
format.json { render json: { success: false, error: "No active session" }, status: :unauthorized }
format.html { redirect_to new_user_session_path }
format.any { head :unauthorized }
end
end
rescue => e
Rails.logger.error "Error in extend session: #{e.message}"
Rails.logger.error e.backtrace.join("\n")
respond_to do |format|
format.json { render json: { success: false, error: e.message }, status: :internal_server_error }
format.html { redirect_to root_path, alert: "An error occurred while extending your session." }
format.any { head :internal_server_error }
end
end
end
16 changes: 0 additions & 16 deletions app/app/controllers/cbv/sessions_controller.rb

This file was deleted.

77 changes: 24 additions & 53 deletions app/app/javascript/controllers/cbv/sessions/timeout_controller.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import { Controller } from "@hotwired/stimulus"
import { sessionAdapter } from "../../../utilities/sessionAdapter"

export default class extends Controller {
static targets = ["modal"]
static targets = ["modal", "trigger", "extendButton"]
static values = {
warningTime: { type: Number, default: 5000 },
warningTime: { type: Number, default: 5000 }, // 5 seconds for testing
// warningTime: { type: Number, default: 25 * 60 * 1000 }, // 25 minutes in milliseconds
timeoutTime: { type: Number, default: 30 * 60 * 1000 } // 30 minutes in milliseconds
}

connect() {
console.log('Timeout controller connected')
console.log('Warning will show in:', this.warningTimeValue, 'ms')
console.log('Timeout will occur in:', this.timeoutTimeValue, 'ms')
this.createModalTrigger()
this.resetTimers()
this.addActivityListeners()
}
Expand All @@ -21,12 +18,12 @@ export default class extends Controller {
console.log('Timeout controller disconnected')
this.clearTimers()
this.removeActivityListeners()
this.removeTriggerButton()
}

resetTimers() {
console.log('Resetting timers')
this.clearTimers()

console.log('Setting warning timer for', this.warningTimeValue, 'ms')
this.warningTimer = setTimeout(() => {
console.log('Warning timer triggered')
Expand Down Expand Up @@ -82,62 +79,36 @@ export default class extends Controller {

// Wait 1 second after last activity before resetting timers
this.activityTimeout = setTimeout(() => {
console.log('No activity for 1 second, resetting timers')
this.resetTimers()
}, 1000)
}

createModalTrigger() {
// Remove any existing trigger
this.removeTriggerButton()

// Create the trigger link matching the help link structure
const trigger = document.createElement('a')
trigger.id = 'session-timeout-trigger'
trigger.href = '#cbv-session-timeout-content'
trigger.className = 'usa-button'
trigger.setAttribute('aria-controls', 'cbv-session-timeout-content')
trigger.dataset.openModal = true // Set to true instead of empty string
trigger.textContent = 'Open Session Timeout Modal'

// Add to DOM in a visible location
const container = document.createElement('div')
container.style.position = 'fixed'
container.style.top = '20px'
container.style.right = '20px'
container.style.zIndex = '9999'
container.appendChild(trigger)
document.body.appendChild(container)
console.log('Created modal trigger:', trigger)
}

removeTriggerButton() {
const existingTrigger = document.getElementById('session-timeout-trigger')
if (existingTrigger) {
const container = existingTrigger.parentElement
if (container) {
container.remove()
} else {
existingTrigger.remove()
}
console.log('Removed existing trigger button')
}
}

showWarning() {
console.log('Attempting to show warning modal')
const triggerButton = document.getElementById('session-timeout-trigger')
if (!triggerButton) {
console.error('Modal trigger button not found')
return
if (this.hasTriggerTarget) {
this.triggerTarget.click()
} else {
console.error('Trigger target not found when trying to show warning')
}

console.log('Clicking modal trigger button')
triggerButton.click()
}

timeout() {
console.log('Session timed out, redirecting to root')
window.location = '/'
}

async extendSession() {
try {
console.log('Calling sessionAdapter.extendSession()')
const response = await sessionAdapter.extendSession()
console.log('Session extended successfully, response:', response)

// Close the modal
if (this.hasModalTarget) {
console.log('Closing modal')
this.resetTimers()
}
} catch (error) {
console.error('Failed to extend session:', error)
}
}
}
28 changes: 28 additions & 0 deletions app/app/javascript/utilities/sessionAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { fetchInternalAPIService } from './fetchInternalAPIService';

export const sessionAdapter = {
/**
* Extends the current user session
* @returns {Promise<Response>} The fetch response
*/
extendSession: async () => {
console.log('sessionAdapter.extendSession called');
try {
console.log('Sending POST request to /api/extend_session');

const response = await fetchInternalAPIService('/api/extend_session', {
method: 'POST',
headers: {
'Accept': 'application/json'
},
credentials: 'same-origin'
});

console.log('Response data:', response);
return response;
} catch (error) {
console.error('Error extending session:', error);
throw error;
}
}
};
28 changes: 25 additions & 3 deletions app/app/views/cbv/sessions/_timeout_modal.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="usa-modal" id="cbv-session-timeout-content" aria-labelledby="cbv-session-timeout-heading" aria-describedby="cbv-session-timeout-description">
<div class="usa-modal" data-cbv-sessions-timeout-target="modal" id="cbv-session-timeout-modal" aria-labelledby="cbv-session-timeout-heading" aria-describedby="cbv-session-timeout-description">
<div class="usa-modal__content">
<div class="usa-modal__main">
<h2 class="usa-modal__heading" id="cbv-session-timeout-heading">
Expand All @@ -12,13 +12,35 @@
<div class="usa-modal__footer">
<ul class="usa-button-group">
<li class="usa-button-group__item">
<%= button_to t('session_timeout.modal.extend_button'), cbv_flow_extend_session_path, class: "usa-button", data: { turbo: true } %>
<button type="button" class="usa-button"
data-action="click->cbv-sessions-timeout#extendSession"
data-cbv-sessions-timeout-target="extendButton"
id="extend-session-button">
<%= t('session_timeout.modal.extend_button') %>
</button>
</li>
<li class="usa-button-group__item">
<%= button_to t('session_timeout.modal.end_button'), destroy_user_session_path, method: :delete, class: "usa-button usa-button--outline" %>
</li>
</ul>
<div class="usa-alert usa-alert--info usa-alert--slim margin-top-2 display-none" data-cbv-sessions-timeout-target="statusMessage" id="session-extension-status">
<div class="usa-alert__body">
<p class="usa-alert__text" data-cbv-sessions-timeout-target="statusText"></p>
</div>
</div>
</div>
</div>

</div>
</div>
</div>

<%= link_to t('session_timeout.modal.trigger'), "#cbv-session-timeout-modal", {
aria: { controls: "cbv-session-timeout-modal" },
data: {
open_modal: true,
source: "session-timeout",
cbv_sessions_timeout_target: "trigger"
},
id: "session-timeout-trigger",
class: "visually-hidden"
}.compact %>
6 changes: 1 addition & 5 deletions app/app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,8 @@
</section>
</main>
<%= render "application/footer" %>

<div data-cbv-sessions-timeout-target="modal" class="hidden">
<%= render "cbv/sessions/timeout_modal" %>
</div>
<%= render partial: "cbv/sessions/timeout_modal" %>
</div>

<%= render partial: "help/help_modal", locals: { help_path: help_path(locale: I18n.locale, r: SecureRandom.hex(4)) } %>
</body>
</html>
2 changes: 2 additions & 0 deletions app/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
scope :events do
post :user_action, to: "user_events#user_action"
end

post '/extend_session', to: 'sessions#extend'
end

match "/404", to: "pages#error_404", via: :all
Expand Down

0 comments on commit 48a1e9c

Please sign in to comment.