Skip to content

Commit a444d61

Browse files
committed
Redirect to reset_app after singin in native apps
1 parent ae1125c commit a444d61

File tree

15 files changed

+199
-14
lines changed

15 files changed

+199
-14
lines changed

app/components/menu.rb

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,34 @@ def view_template
2222

2323
if hotwire_native_app? || (@controller_name == "pages" && @action_name == "show")
2424
if user_signed_in?
25-
menu_link(path: destroy_user_session_path, text: t("navbar.sign_out"), icon: Hero::ArrowLeftStartOnRectangle.new(variant: :outline, class: "size-5 ltr:transform ltr:-scale-x-100"))
26-
Separator(class: "my-2")
25+
Link(
26+
variant: :link,
27+
href: destroy_user_session_path,
28+
class: "flex items-center justify-start gap-x-2 text-xl text-muted-foreground",
29+
data: {
30+
controller: "bridge--sign-out",
31+
bridge__sign_out_path_value: api_v1_auth_path,
32+
action: [
33+
("click->ruby-ui--sheet-content#close" if hotwire_native_app?),
34+
"bridge--sign-out#signOut"
35+
],
36+
turbo_method: :delete
37+
}
38+
) do
39+
Hero::ArrowLeftStartOnRectangle(variant: :outline, class: "size-5 ltr:transform ltr:-scale-x-100")
40+
41+
plain t("navbar.sign_out")
42+
end
2743
else
28-
menu_link(path: new_user_session_path, text: t("navbar.sign_in"), icon: Hero::ArrowLeftStartOnRectangle.new(variant: :outline, class: "size-5 ltr:transform ltr:-scale-x-100"))
29-
Separator(class: "my-2")
44+
menu_link(
45+
path: new_user_session_path,
46+
text: t("navbar.sign_in"),
47+
icon: Hero::ArrowLeftOnRectangle.new(variant: :outline, class: "size-5 ltr:transform ltr:-scale-x-100"),
48+
)
3049
end
3150

51+
Separator(class: "my-2")
52+
3253
if hotwire_native_app?
3354
menu_link(
3455
path: new_contact_path,
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Api::V1::AuthsController < ApplicationController
2+
skip_before_action :verify_authenticity_token, only: [ :destroy ]
3+
4+
def destroy
5+
sign_out(current_user)
6+
7+
render json: {}
8+
end
9+
end

app/controllers/application_controller.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,21 @@ class ApplicationController < ActionController::Base
55
# Only allow browsers supporting TailwindCSS v4.
66
allow_browser versions: { chrome: 111, safari: 16.4, firefox: 128 }, block: :handle_outdated_browser
77

8+
before_action if: -> { devise_controller? && hotwire_native_app? } do
9+
request.env["warden"].params["hotwire_native_form"] = true
10+
end
11+
812
before_action :check_rack_mini_profiler
913
before_action { Rails.error.set_context(request_url: request.original_url, params: params, session: session.inspect) }
1014

1115
private
1216

17+
def after_sign_in_path_for(resource_or_scope)
18+
return "/reset_app" if hotwire_native_app?
19+
20+
super
21+
end
22+
1323
def check_rack_mini_profiler
1424
Rack::MiniProfiler.authorize_request if current_user&.admin?
1525
end
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
class Hotwire::Ios::PathConfigurationsController < ApplicationController
2+
def show
3+
render json: {
4+
settings: {
5+
register_with_account: false,
6+
require_authentication: false,
7+
tabs: [
8+
{
9+
title: "الرئيسية",
10+
path: "/",
11+
ios_system_image_name: "house"
12+
},
13+
{
14+
title: "التصنيفات",
15+
path: "/categories",
16+
ios_system_image_name: "square.grid.2x2"
17+
},
18+
{
19+
title: "المؤلفون",
20+
path: "/authors",
21+
ios_system_image_name: "person.3"
22+
},
23+
{
24+
title: "الكتب",
25+
path: "/books",
26+
ios_system_image_name: "books.vertical"
27+
}
28+
]
29+
},
30+
rules: [
31+
{
32+
patterns: [
33+
"/new$",
34+
"/edit$",
35+
"/users/sign_up",
36+
"/users/sign_in"
37+
],
38+
properties: {
39+
context: "modal"
40+
}
41+
},
42+
{
43+
patterns: [ "^/unauthorized" ],
44+
properties: {
45+
view_controller: "unauthorized"
46+
}
47+
},
48+
{
49+
patterns: [ "^/reset_app$" ],
50+
properties: {
51+
view_controller: "reset_app"
52+
}
53+
},
54+
{
55+
patterns: [ "/?sign_in_token=.*" ],
56+
properties: {
57+
presentation: "replace"
58+
}
59+
}
60+
]
61+
}
62+
end
63+
end

app/controllers/native/sessions_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ def handoff
88

99
sign_in(user)
1010

11-
redirect_to after_sign_in_path_for(user)
11+
redirect_to "/reset_app"
1212
end
1313
end

app/controllers/site_controller.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class SiteController < ApplicationController
2+
def reset_app
3+
# Hotwire Native needs an empty page to route authentication and reset the app.
4+
# We can't head: 200 because we also need the Turbo JavaScript in <head>.
5+
6+
render Views::Site::ResetApp.new
7+
end
8+
end

app/controllers/static_controller.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
class StaticController < ApplicationController
2+
include Devise::Controllers::Rememberable
3+
24
CATEGORY_IDS = {
35
faith: [ 24, 34, 35, 36, 37, 38, 39, 40, 54 ],
46
quran: [ 1, 17, 20, 21, 22, 88, 101 ],
@@ -10,6 +12,15 @@ class StaticController < ApplicationController
1012
}
1113

1214
def home
15+
if params[:sign_in_token].present?
16+
user = User.find_signed(params[:sign_in_token], purpose: "native_handoff")
17+
18+
if user.present?
19+
sign_in(user)
20+
remember_me(user)
21+
end
22+
end
23+
1324
results = search
1425

1526
if results.present? && params[:qid].blank? && request.headers["X-Sec-Purpose"] != "prefetch"

app/controllers/users/omniauth_callbacks_controller.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
module Users
22
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
3+
include Devise::Controllers::Rememberable
4+
35
def google_oauth2 = process_oauth_callback("Google")
46

57
private
@@ -16,13 +18,15 @@ def process_oauth_callback(provider)
1618

1719
def handle_successful_authentication(user, provider)
1820
sign_out_all_scopes
19-
sign_in(user)
2021

2122
if native_oauth_request?
22-
token = user.signed_id(purpose: "native_handoff", expires_in: 5.minutes)
23+
token = user.signed_id(purpose: "native_handoff", expires_in: 30.seconds)
2324

24-
redirect_to handoff_native_session_url(token:)
25+
redirect_to root_path(sign_in_token: token, locale: nil)
2526
else
27+
sign_in(user)
28+
remember_me(user)
29+
2630
flash[:notice] = t("devise.omniauth_callbacks.success", kind: provider) if is_navigational_format?
2731

2832
redirect_to after_sign_in_path_for(user)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { BridgeComponent } from "@hotwired/hotwire-native-bridge"
2+
3+
// Connects to data-controller="bridge--sign-out"
4+
export default class extends BridgeComponent {
5+
static component = "sign-out"
6+
7+
static values = {
8+
path: String,
9+
}
10+
11+
signOut(event) {
12+
event.preventDefault()
13+
event.stopImmediatePropagation()
14+
15+
const path = this.pathValue
16+
this.send("signOut", { path }, () => {})
17+
}
18+
}

app/javascript/controllers/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ application.register("bridge--menu-button", Bridge__MenuButtonController)
1919
import Bridge__ShareController from "./bridge/share_controller"
2020
application.register("bridge--share", Bridge__ShareController)
2121

22+
import Bridge__SignOutController from "./bridge/sign_out_controller"
23+
application.register("bridge--sign-out", Bridge__SignOutController)
24+
2225
import Bridge__ThemeController from "./bridge/theme_controller"
2326
application.register("bridge--theme", Bridge__ThemeController)
2427

0 commit comments

Comments
 (0)