Break out of Turbo Frame on Devise 401 redirect

After 2 days of trial and error, here is a workaround. Hopefully there will be an official solution to request interception soon.

  # In my layout, I attached a turbo controller to the `body` element. 
  # <b>turbo:before-fetch-response</b> is one of the two events I found working in turbo frames. 
  # The other one is <b>turbo:before-fetch-request</b>
  body data-controller="unauthorized" data-action="turbo:before-fetch-response->unauthorized#intercept"
    = yield
// in unauthorized_controller.js

import { Controller } from "stimulus"

export default class extends Controller {
  intercept(event) {
    const {url} = event.detail.fetchResponse.response;
    // I was not able to intercept the 401 response, only the one after which.
    // This is response is a 200 response. I had to use the url to match.
    // This method is sufficient for my project, but not enough to be an general solution
    if (url.match("runtime/project_users/projects/\\d+/sign_in")) {
      event.preventDefault()
      // Here you may ask, "shouldn't we redirect to the url in the url variable above?"
      // The reason being, devise stores the location before signing out by default, 
      // to redirect the user back after a successful authorization. The url before signing out
      // here, is the turbo frame request, which is part of the the current page, therefore may not
      // an ideal target for the user to visit. The current page, which is the container of the turbo
      // frame, is a more appropriate candidate.
      window.location = window.location.href
    }
  }
}
1 Like