Skip to content

Commit f7996e3

Browse files
committed
Honor Dynamic UI home page on redirect
When no intended URL cookie is present, HomeController now checks for a tenant-configured DynamicUI home page and redirects there if available. This preserves per-tenant landing pages while still falling back to the existing requests/home routes. Tests added: INTENDED_DEEP_LINK constant; ensure redirect-to-intended honors the cookie; ensure the intended cookie takes precedence over a DynamicUI home (regression for SAML flow); verify the intended cookie is cleared after use; and verify fallback to route('home') when no cookie and no dashboard is configured.
1 parent da9e81b commit f7996e3

2 files changed

Lines changed: 93 additions & 5 deletions

File tree

ProcessMaker/Http/Controllers/HomeController.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@ public function redirectToIntended()
6060
return redirect($url)->withCookie(\Cookie::forget('processmaker_intended'));
6161
}
6262

63+
// No intended URL. Honor the tenant's package-dynamic-ui home page
64+
// if it's installed, so admins'configured landing pages are still
65+
// respected, before falling back to /requests.
66+
if (Auth::check() && class_exists(\ProcessMaker\Package\PackageDynamicUI\Models\DynamicUI::class)) {
67+
$homePage = \ProcessMaker\Package\PackageDynamicUI\Models\DynamicUI::getHomePage(Auth::user());
68+
if (!empty($homePage)) {
69+
return redirect($homePage);
70+
}
71+
}
72+
6373
return redirect()->route('requests.index');
6474
}
6575
}

tests/Feature/HomeControllerTest.php

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,22 @@
22

33
namespace Tests\Feature;
44

5-
use Tests\TestCase;
6-
use ProcessMaker\Models\User;
75
use ProcessMaker\Models\Group;
6+
use ProcessMaker\Models\User;
87
use ProcessMaker\Package\PackageDynamicUI\Models\DynamicUI;
98
use Tests\Feature\Shared\RequestHelper;
9+
use Tests\TestCase;
1010

1111
class HomeControllerTest extends TestCase
1212
{
1313
use RequestHelper;
1414

15+
/**
16+
* Sample deep-link URL used as the "originally requested" page for the
17+
* redirect-to-intended tests.
18+
*/
19+
private const INTENDED_DEEP_LINK = '/designer/scripts/123/edit';
20+
1521
protected function setUp(): void
1622
{
1723
parent::setUp();
@@ -32,7 +38,7 @@ public function testRedirectsToLoginWhenNotAuthenticated()
3238
public function testRedirectsToCustomDashboardWhenUserHasDashboard()
3339
{
3440
$user = User::factory()->create();
35-
41+
3642
// Create a custom dashboard for the user
3743
DynamicUI::create([
3844
'type' => 'DASHBOARD',
@@ -68,7 +74,7 @@ public function testRedirectsToCustomDashboardWhenGroupHasDashboard()
6874
public function testRedirectsToTasksOnMobileWithoutCustomDashboard()
6975
{
7076
$user = User::factory()->create();
71-
77+
7278
// Mock MobileHelper to return true
7379
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1';
7480
$_COOKIE['isMobile'] = 'true';
@@ -84,7 +90,7 @@ public function testRedirectsToTasksOnMobileWithoutCustomDashboard()
8490
public function testRedirectsToInboxOnDesktopWithoutCustomDashboard()
8591
{
8692
$user = User::factory()->create();
87-
93+
8894
// Mock MobileHelper to return false
8995
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36';
9096
$_COOKIE['isMobile'] = 'false';
@@ -131,4 +137,76 @@ public function testRedirectsToGroupUrlRedirect()
131137
$response = $this->actingAs($user)->get('/');
132138
$response->assertRedirect('https://processmaker.com/home');
133139
}
140+
141+
/** @test */
142+
public function testRedirectToIntendedHonorsCookie()
143+
{
144+
$user = User::factory()->create();
145+
$response = $this->actingAs($user)
146+
->withCookie('processmaker_intended', self::INTENDED_DEEP_LINK)
147+
->get(route('redirect_to_intended'));
148+
$response->assertRedirect(self::INTENDED_DEEP_LINK);
149+
}
150+
151+
/**
152+
* Regression test for the SAML "land on home instead of intended URL"
153+
* bug: when the user comes back from the SSO callback through the
154+
* /redirect-to-intended recovery hop with a valid `processmaker_intended`
155+
* cookie, the cookie wins -- the configured Dynamic UI home page does
156+
* not preempt it.
157+
*
158+
* @test
159+
*/
160+
public function testRedirectToIntendedCookieTakesPrecedenceOverDynamicUiHome()
161+
{
162+
$user = User::factory()->create();
163+
164+
DynamicUI::create([
165+
'type' => 'URL',
166+
'assignable_id' => $user->id,
167+
'assignable_type' => User::class,
168+
'homepage' => 'https://processmaker.com/configured-landing',
169+
]);
170+
171+
$response = $this->actingAs($user)
172+
->withCookie('processmaker_intended', self::INTENDED_DEEP_LINK)
173+
->get(route('redirect_to_intended'));
174+
175+
$response->assertRedirect(self::INTENDED_DEEP_LINK);
176+
}
177+
178+
/**
179+
* The intended-URL cookie is single-use: once we've consumed it we must
180+
* tell the browser to drop it, otherwise it would keep deflecting every
181+
* subsequent SSO callback to the same stale URL.
182+
*
183+
* @test
184+
*/
185+
public function testRedirectToIntendedClearsCookieAfterUse()
186+
{
187+
$user = User::factory()->create();
188+
189+
$response = $this->actingAs($user)
190+
->withCookie('processmaker_intended', self::INTENDED_DEEP_LINK)
191+
->get(route('redirect_to_intended'));
192+
193+
$response->assertRedirect(self::INTENDED_DEEP_LINK);
194+
$response->assertCookieExpired('processmaker_intended');
195+
}
196+
197+
/**
198+
* When there's no intended URL at all we still need to send the user somewhere.
199+
* With no dashboard configured, DynamicUI::getHomePage() falls through to route('home')
200+
* which HomeController::index() will then re-route to /inbox (or /tasks on mobile) on the next request.
201+
*
202+
* @test
203+
*/
204+
public function testRedirectToIntendedFallsBackToHomeWhenNoCookieAndNoDashboard()
205+
{
206+
$user = User::factory()->create();
207+
208+
$response = $this->actingAs($user)->get(route('redirect_to_intended'));
209+
210+
$response->assertRedirect(route('home'));
211+
}
134212
}

0 commit comments

Comments
 (0)