diff --git a/config/services/services.yml b/config/services/services.yml index 52ed5be7d9..43acf96354 100644 --- a/config/services/services.yml +++ b/config/services/services.yml @@ -4,9 +4,15 @@ services: OpenConext\EngineBlock\Service\Wayf\IdpSplitter: + OpenConext\EngineBlockBundle\Service\RememberChoiceDurationFormatter: + autowire: true + arguments: + $lifetimeInSeconds: '%wayf.remember_choice_per_idp_lifetime%' + OpenConext\EngineBlockBundle\Service\WayfViewModelFactory: arguments: $wayfExtension: '@OpenConext\EngineBlockBundle\Twig\Extensions\Extension\Wayf' + $durationFormatter: '@OpenConext\EngineBlockBundle\Service\RememberChoiceDurationFormatter' OpenConext\EngineBlockBundle\Service\WayfRenderer: autowire: true diff --git a/languages/messages.en.php b/languages/messages.en.php index 3d5a44008f..67a4816dd0 100644 --- a/languages/messages.en.php +++ b/languages/messages.en.php @@ -86,6 +86,11 @@ // Remove cookies 'remember_choice' => 'Remember my choice', + 'remember_choice_per_idp' => 'Remember my choice for this service for %duration%', + 'remember_choice_duration_days' => '%count% days', + 'remember_choice_duration_minutes' => '%count% minutes', + 'remember_choice_tooltip_screenreader' => 'Why do we remember your choice?', + 'remember_choice_per_idp_tooltip' => 'If you enable this option, you won\'t need to choose how you want to log into this service for the next %duration%. The login screen will then be skipped. Please note: do you sometimes use a different account to log in? If so, please disable this option. You can reverse this setting later at profile.surfconext.nl.', 'cookie_removal_header' => 'Remove cookies', 'cookie_remove_button' => 'Remove', 'cookie_remove_all_button' => 'Remove all', diff --git a/languages/messages.nl.php b/languages/messages.nl.php index de5461a43a..94efed7627 100644 --- a/languages/messages.nl.php +++ b/languages/messages.nl.php @@ -85,6 +85,11 @@ // Remove cookies 'remember_choice' => 'Onthoud mijn keuze', + 'remember_choice_per_idp' => 'Onthoud mijn keuze voor deze dienst voor %duration%', + 'remember_choice_duration_days' => '%count% dagen', + 'remember_choice_duration_minutes' => '%count% minuten', + 'remember_choice_tooltip_screenreader' => 'Waarom onthouden we jouw keuze?', + 'remember_choice_per_idp_tooltip' => 'Als je deze optie aanzet, hoef je de komende %duration% voor deze dienst niet meer te kiezen hoe je wilt inloggen. Het inlogscherm wordt dan overgeslagen. Let op: gebruik je soms een ander account om in te loggen? Zet de optie dan uit. Je kunt de keuze later weer terugdraaien op profile.surfconext.nl.', 'cookie_removal_header' => 'Cookies verwijderen', 'cookie_remove_button' => 'Verwijderen', 'cookie_remove_all_button' => 'Alles verwijderen', diff --git a/languages/messages.pt.php b/languages/messages.pt.php index ab37c212c2..4df1ac031f 100644 --- a/languages/messages.pt.php +++ b/languages/messages.pt.php @@ -82,6 +82,11 @@ // Remove cookies 'remember_choice' => 'Relembrar a minha escolha', + 'remember_choice_per_idp' => 'Relembrar a minha escolha para este serviço durante %duration%', + 'remember_choice_duration_days' => '%count% dias', + 'remember_choice_duration_minutes' => '%count% minutos', + 'remember_choice_tooltip_screenreader' => 'Porque é que relembramos a sua escolha?', + 'remember_choice_per_idp_tooltip' => 'Se ativar esta opção, não terá de escolher como pretende iniciar sessão nos próximos %duration%. O ecrã de início de sessão será então ignorado. Atenção: por vezes utiliza uma conta diferente para iniciar sessão? Nesse caso, desative esta opção. Pode reverter esta opção mais tarde em profile.surfconext.nl.', 'cookie_removal_header' => 'Remover cookies', 'cookie_remove_button' => 'Remover', 'cookie_remove_all_button' => 'Remover todos', diff --git a/src/OpenConext/EngineBlockBundle/Service/RememberChoiceDurationFormatter.php b/src/OpenConext/EngineBlockBundle/Service/RememberChoiceDurationFormatter.php new file mode 100644 index 0000000000..61bc0bf339 --- /dev/null +++ b/src/OpenConext/EngineBlockBundle/Service/RememberChoiceDurationFormatter.php @@ -0,0 +1,46 @@ +lifetimeInSeconds < self::SECONDS_PER_DAY) { + $minutes = intdiv($this->lifetimeInSeconds, self::SECONDS_PER_MINUTE); + return $this->translator->trans('remember_choice_duration_minutes', ['%count%' => $minutes]); + } + + $days = intdiv($this->lifetimeInSeconds, self::SECONDS_PER_DAY); + return $this->translator->trans('remember_choice_duration_days', ['%count%' => $days]); + } +} diff --git a/src/OpenConext/EngineBlockBundle/Service/WayfViewModelFactory.php b/src/OpenConext/EngineBlockBundle/Service/WayfViewModelFactory.php index bf2cff7d92..a395ce764c 100644 --- a/src/OpenConext/EngineBlockBundle/Service/WayfViewModelFactory.php +++ b/src/OpenConext/EngineBlockBundle/Service/WayfViewModelFactory.php @@ -28,6 +28,7 @@ class WayfViewModelFactory { public function __construct( private readonly Wayf $wayfExtension, + private readonly RememberChoiceDurationFormatter $durationFormatter, ) { } @@ -70,6 +71,7 @@ public function create( regularIdpList: $regularIdpList, preferredIdpList: $preferredIdpList, rememberChoicePerIdp: $rememberChoicePerIdp, + rememberChoiceDuration: $rememberChoicePerIdp ? $this->durationFormatter->format() : '', ); } } diff --git a/src/OpenConext/EngineBlockBundle/ViewModel/WayfViewModel.php b/src/OpenConext/EngineBlockBundle/ViewModel/WayfViewModel.php index d47e8461ff..a51fc72351 100644 --- a/src/OpenConext/EngineBlockBundle/ViewModel/WayfViewModel.php +++ b/src/OpenConext/EngineBlockBundle/ViewModel/WayfViewModel.php @@ -53,6 +53,7 @@ public function __construct( /** @var WayfIdp[] */ public array $preferredIdpList, public bool $rememberChoicePerIdp = false, + public string $rememberChoiceDuration = '', ) { } diff --git a/src/OpenConext/EngineBlockFunctionalTestingBundle/Controllers/WayfController.php b/src/OpenConext/EngineBlockFunctionalTestingBundle/Controllers/WayfController.php index 550f3642fb..79e752319c 100644 --- a/src/OpenConext/EngineBlockFunctionalTestingBundle/Controllers/WayfController.php +++ b/src/OpenConext/EngineBlockFunctionalTestingBundle/Controllers/WayfController.php @@ -44,6 +44,7 @@ public function wayfAction(Request $request) $displayUnconnectedIdpsWayf = $request->query->getBoolean('displayUnconnectedIdpsWayf'); $addDiscoveries = $request->query->getBoolean('addDiscoveries', true); $rememberChoiceFeature = $request->query->getBoolean('rememberChoiceFeature'); + $rememberChoicePerIdp = $request->query->getBoolean('rememberChoicePerIdp'); $cutoffPointForShowingUnfilteredIdps = $request->query->getInt('cutoffPointForShowingUnfilteredIdps', 100); $showIdPBanner = $request->query->getBoolean('showIdPBanner', true); $defaultIdpEntityId = $request->query->get('defaultIdpEntityId', ''); @@ -70,6 +71,7 @@ public function wayfAction(Request $request) showRequestAccess: $displayUnconnectedIdpsWayf, requestId: 'bogus-request-id', serviceProvider: TestEntitySeeder::buildSp(), + rememberChoicePerIdp: $rememberChoicePerIdp, ); return new Response($output); diff --git a/tests/e2e/cypress/integration/skeune/wayf/wayf.general.spec.js b/tests/e2e/cypress/integration/skeune/wayf/wayf.general.spec.js index 76632774a2..42da89b10b 100644 --- a/tests/e2e/cypress/integration/skeune/wayf/wayf.general.spec.js +++ b/tests/e2e/cypress/integration/skeune/wayf/wayf.general.spec.js @@ -5,6 +5,9 @@ import { matchSelector, noResultSectionSelector, remainingIdpSelector, + rememberChoicePerIdpClass, + rememberChoiceTooltipToggleSelector, + rememberChoiceTooltipValueSelector, searchFieldSelector, searchResetSelector, searchSubmitSelector, @@ -202,6 +205,45 @@ context('WAYF behaviour not tied to mouse / keyboard navigation', () => { }); }); + describe('Should show the per-SP remember my choice option with a tooltip', () => { + it('Renders the per-SP checkbox with a tooltip toggle', () => { + cy.visit('https://engine.dev.openconext.local/functional-testing/wayf?connectedIdps=5&rememberChoiceFeature=true&rememberChoicePerIdp=true'); + cy.get(`.${rememberChoicePerIdpClass}`).should('exist'); + cy.get(rememberChoiceTooltipToggleSelector).should('exist'); + }); + + it('Hides the tooltip content until the toggle is activated', () => { + cy.visit('https://engine.dev.openconext.local/functional-testing/wayf?connectedIdps=5&rememberChoiceFeature=true&rememberChoicePerIdp=true'); + cy.get(rememberChoiceTooltipValueSelector).should('not.be.visible'); + cy.get(rememberChoiceTooltipToggleSelector).click({force: true}); + cy.get(rememberChoiceTooltipValueSelector).should('be.visible'); + cy.get(rememberChoiceTooltipToggleSelector).click({force: true}); + cy.get(rememberChoiceTooltipValueSelector).should('not.be.visible'); + }); + + it('Toggles aria-hidden and aria-expanded on the tooltip when the label is clicked', () => { + cy.visit('https://engine.dev.openconext.local/functional-testing/wayf?connectedIdps=5&rememberChoiceFeature=true&rememberChoicePerIdp=true'); + cy.get(rememberChoiceTooltipValueSelector).should('have.attr', 'aria-hidden', 'true'); + cy.get(rememberChoiceTooltipToggleSelector).should('have.attr', 'aria-expanded', 'false'); + cy.get('.wayf__rememberChoice label.tooltip').click(); + cy.get(rememberChoiceTooltipValueSelector).should('not.have.attr', 'aria-hidden'); + cy.get(rememberChoiceTooltipToggleSelector).should('have.attr', 'aria-expanded', 'true'); + }); + + it('Opens the tooltip when the label is focused and Enter is pressed', () => { + cy.visit('https://engine.dev.openconext.local/functional-testing/wayf?connectedIdps=5&rememberChoiceFeature=true&rememberChoicePerIdp=true'); + cy.get('.wayf__rememberChoice label.tooltip').focus().type('{enter}'); + cy.get(rememberChoiceTooltipValueSelector).should('not.have.attr', 'aria-hidden'); + }); + + it('Does not show the tooltip toggle for the global (non per-SP) variant', () => { + cy.visit('https://engine.dev.openconext.local/functional-testing/wayf?connectedIdps=5&rememberChoiceFeature=true&rememberChoicePerIdp=false'); + cy.get(`.${rememberChoicePerIdpClass}`).should('not.exist'); + cy.get(rememberChoiceTooltipToggleSelector).should('not.exist'); + cy.onPage('Remember my choice'); + }); + }); + describe('Preferred IdPs section heading', () => { it('Should show the preferred IdPs section with the correct heading when preferred IdPs are configured', () => { cy.visit('https://engine.dev.openconext.local/functional-testing/wayf?preferredIdpEntityIds%5B%5D=https%3A%2F%2Fexample.com%2FentityId%2F1'); diff --git a/tests/unit/OpenConext/EngineBlockBundle/Service/RememberChoiceDurationFormatterTest.php b/tests/unit/OpenConext/EngineBlockBundle/Service/RememberChoiceDurationFormatterTest.php new file mode 100644 index 0000000000..a260395415 --- /dev/null +++ b/tests/unit/OpenConext/EngineBlockBundle/Service/RememberChoiceDurationFormatterTest.php @@ -0,0 +1,58 @@ +shouldReceive('trans') + ->once() + ->with($expectedKey, $expectedParameters) + ->andReturn('formatted-duration'); + + $formatter = new RememberChoiceDurationFormatter($translator, $lifetimeInSeconds); + + $this->assertSame('formatted-duration', $formatter->format()); + } + + public static function lifetimeProvider(): array + { + return [ + 'ninety days (default lifetime)' => [7776000, 'remember_choice_duration_days', ['%count%' => 90]], + 'exactly one day' => [86400, 'remember_choice_duration_days', ['%count%' => 1]], + 'one second under a day' => [86399, 'remember_choice_duration_minutes', ['%count%' => 1439]], + 'forty-five minutes' => [2700, 'remember_choice_duration_minutes', ['%count%' => 45]], + 'zero seconds' => [0, 'remember_choice_duration_minutes', ['%count%' => 0]], + ]; + } +} diff --git a/tests/unit/OpenConext/EngineBlockBundle/Service/WayfViewModelFactoryTest.php b/tests/unit/OpenConext/EngineBlockBundle/Service/WayfViewModelFactoryTest.php new file mode 100644 index 0000000000..de33d85da6 --- /dev/null +++ b/tests/unit/OpenConext/EngineBlockBundle/Service/WayfViewModelFactoryTest.php @@ -0,0 +1,96 @@ +createMock(Wayf::class); + $wayfExtension->method('getConnectedIdps')->willReturn(new ConnectedIdps([], [])); + + $translator = $this->createStub(TranslatorInterface::class); + $translator->method('trans')->willReturn('90 days'); + $durationFormatter = new RememberChoiceDurationFormatter($translator, 7776000); + + $factory = new WayfViewModelFactory($wayfExtension, $durationFormatter); + + $viewModel = $factory->create( + idpList: [], + regularIdpList: [], + preferredIdpList: [], + showPreferredIdps: false, + action: '/sso', + greenHeader: 'SP', + helpLink: '/help', + backLink: false, + cutoffPointForShowingUnfilteredIdps: 100, + showIdPBanner: false, + rememberChoiceFeature: true, + showRequestAccess: false, + requestId: 'req-1', + serviceProvider: $this->createStub(ServiceProvider::class), + rememberChoicePerIdp: true, + ); + + $this->assertSame('90 days', $viewModel->rememberChoiceDuration); + } + + public function testRememberChoiceDurationIsEmptyWhenNotPerIdp(): void + { + $wayfExtension = $this->createMock(Wayf::class); + $wayfExtension->method('getConnectedIdps')->willReturn(new ConnectedIdps([], [])); + + $translator = $this->createStub(TranslatorInterface::class); + $translator->method('trans')->willReturn('90 days'); + $durationFormatter = new RememberChoiceDurationFormatter($translator, 7776000); + + $factory = new WayfViewModelFactory($wayfExtension, $durationFormatter); + + $viewModel = $factory->create( + idpList: [], + regularIdpList: [], + preferredIdpList: [], + showPreferredIdps: false, + action: '/sso', + greenHeader: 'SP', + helpLink: '/help', + backLink: false, + cutoffPointForShowingUnfilteredIdps: 100, + showIdPBanner: false, + rememberChoiceFeature: true, + showRequestAccess: false, + requestId: 'req-1', + serviceProvider: $this->createStub(ServiceProvider::class), + rememberChoicePerIdp: false, + ); + + $this->assertSame('', $viewModel->rememberChoiceDuration); + } +} diff --git a/tests/unit/OpenConext/EngineBlockBundle/Twig/WayfRememberChoiceRenderTest.php b/tests/unit/OpenConext/EngineBlockBundle/Twig/WayfRememberChoiceRenderTest.php new file mode 100644 index 0000000000..4b54dfc649 --- /dev/null +++ b/tests/unit/OpenConext/EngineBlockBundle/Twig/WayfRememberChoiceRenderTest.php @@ -0,0 +1,90 @@ +render(rememberChoiceFeature: true, rememberChoicePerIdp: false, rememberChoiceDuration: ''); + + $this->assertStringContainsString('remember_choice', $html); + $this->assertStringNotContainsString('remember_choice_per_idp', $html); + $this->assertStringNotContainsString('tooltip__value', $html); + } + + public function testPerIdpVariantRendersDurationAwareTextAndATooltip(): void + { + $html = $this->render(rememberChoiceFeature: true, rememberChoicePerIdp: true, rememberChoiceDuration: '90 days'); + + $this->assertStringContainsString('remember_choice_per_idp:90 days', $html); + $this->assertStringContainsString('wayf__rememberChoice--perIdp', $html); + $this->assertStringContainsString('class="tooltip__value"', $html); + $this->assertStringContainsString('remember_choice_per_idp_tooltip:90 days', $html); + } + + public function testFeatureDisabledRendersNothing(): void + { + $html = $this->render(rememberChoiceFeature: false, rememberChoicePerIdp: true, rememberChoiceDuration: '90 days'); + + $this->assertSame('', trim($html)); + } + + private function render(bool $rememberChoiceFeature, bool $rememberChoicePerIdp, string $rememberChoiceDuration): string + { + $basePath = realpath(__DIR__ . '/../../../../../'); + + $filesystemLoader = new FilesystemLoader(); + $filesystemLoader->addPath($basePath . '/theme/skeune/templates/modules', 'theme'); + $filesystemLoader->addPath($basePath . '/theme/base/templates/modules', 'theme'); + + $environment = new Environment($filesystemLoader); + + $translator = m::mock(TranslatorInterface::class); + $translator->shouldReceive('trans')->andReturnUsing(static function ($id, $parameters = []) { + if (empty($parameters)) { + return (string) $id; + } + return $id . ':' . implode(',', $parameters); + }); + $environment->addExtension(new TranslationExtension($translator)); + $environment->addExtension(new AttributeExtension(Spaceless::class)); + + return $environment->render('@theme/Authentication/View/Proxy/Partials/WAYF/rememberChoice.html.twig', [ + 'action' => '/sso', + 'rememberChoiceFeature' => $rememberChoiceFeature, + 'rememberChoicePerIdp' => $rememberChoicePerIdp, + 'rememberChoiceDuration' => $rememberChoiceDuration, + ]); + } +} diff --git a/theme/base/javascripts/handlers.js b/theme/base/javascripts/handlers.js index 0494fe1157..4bf87de5d8 100644 --- a/theme/base/javascripts/handlers.js +++ b/theme/base/javascripts/handlers.js @@ -82,5 +82,6 @@ export const wayfCallbackAfterLoad = () => { wayfKeyboardBehaviour(); mouseBehaviour(); searchBehaviour(); + addTooltipAndModalAriaHandlers(tooltipsAndModalLabels); + toggleTooltipPressedStates(); }; - diff --git a/theme/base/javascripts/selectors.js b/theme/base/javascripts/selectors.js index d5bfdca7c0..2904c1ee9f 100644 --- a/theme/base/javascripts/selectors.js +++ b/theme/base/javascripts/selectors.js @@ -109,6 +109,10 @@ export const emailFieldSelector = '#email'; export const emailErrorSelector = `${emailFieldSelector} + .form_error`; export const errorMessageSelector = '.notification__critical'; export const rememberChoiceId = 'rememberChoice'; +export const rememberChoicePerIdpClass = 'wayf__rememberChoice--perIdp'; +export const rememberChoiceTooltipToggleId = 'rememberChoiceTooltip'; +export const rememberChoiceTooltipToggleSelector = `#${rememberChoiceTooltipToggleId}`; +export const rememberChoiceTooltipValueSelector = `.tooltip__value[data-for="${rememberChoiceTooltipToggleId}"]`; export const defaultIdpId = 'defaultIdp'; export const defaultIdpClass = 'wayf__defaultIdpLink'; export const defaultIdpSelector = `.${defaultIdpClass}`; diff --git a/theme/base/javascripts/wayf/handleEnter.js b/theme/base/javascripts/wayf/handleEnter.js index b69f11e336..96958af7d9 100644 --- a/theme/base/javascripts/wayf/handleEnter.js +++ b/theme/base/javascripts/wayf/handleEnter.js @@ -46,6 +46,9 @@ export const handleEnter = (e) => { selectFirstIdPAndSubmitForm(); break; case defaultIdpClass: handleIdpBanner(e); break; + case 'tooltip': + e.preventDefault(); + fireClickEvent(e.target); break; } }); }; diff --git a/theme/base/stylesheets/pages/wayf/remainingIdps.scss b/theme/base/stylesheets/pages/wayf/remainingIdps.scss index 38196c01c9..f6d019a161 100644 --- a/theme/base/stylesheets/pages/wayf/remainingIdps.scss +++ b/theme/base/stylesheets/pages/wayf/remainingIdps.scss @@ -87,18 +87,31 @@ } > .wayf__rememberChoice { + align-items: center; + display: flex; + flex-wrap: wrap; margin-bottom: 3rem; - > label[for="rememberChoice"] { - @include mixins.font-style-large; - color: variables.$buttonBlue; - } - > #rememberChoice { + flex: 0 0 auto; height: 1.2rem; - margin: 0 0 0 10px; - vertical-align: sub; + margin: 0 .625rem 0 0; width: 1.2rem; } + + > label[for="rememberChoice"] { + color: variables.$black; + flex: 1 1 auto; + font-size: variables.$f-large; + font-weight: variables.$normal; + } + + > .ie11__label { + margin-left: .5rem; + + > label.tooltip { + display: inline-block; + } + } } } diff --git a/theme/base/templates/modules/Authentication/View/Proxy/Partials/WAYF/remainingIdps.html.twig b/theme/base/templates/modules/Authentication/View/Proxy/Partials/WAYF/remainingIdps.html.twig index 5c59895c7e..ca9be0a50a 100644 --- a/theme/base/templates/modules/Authentication/View/Proxy/Partials/WAYF/remainingIdps.html.twig +++ b/theme/base/templates/modules/Authentication/View/Proxy/Partials/WAYF/remainingIdps.html.twig @@ -36,6 +36,8 @@ {% include '@theme/Authentication/View/Proxy/Partials/WAYF/rememberChoice.html.twig' with { action: action, rememberChoiceFeature: rememberChoiceFeature, + rememberChoicePerIdp: rememberChoicePerIdp, + rememberChoiceDuration: rememberChoiceDuration, } only %} {% include '@theme/Authentication/View/Proxy/Partials/WAYF/idp/idpList.html.twig' with { idpList: idpListSorted, diff --git a/theme/base/templates/modules/Authentication/View/Proxy/Partials/WAYF/rememberChoice.html.twig b/theme/base/templates/modules/Authentication/View/Proxy/Partials/WAYF/rememberChoice.html.twig index 55af8161cd..47c6183de5 100644 --- a/theme/base/templates/modules/Authentication/View/Proxy/Partials/WAYF/rememberChoice.html.twig +++ b/theme/base/templates/modules/Authentication/View/Proxy/Partials/WAYF/rememberChoice.html.twig @@ -1,6 +1,14 @@ {% if rememberChoiceFeature %} -
- + + {% if rememberChoicePerIdp %} + + + {% include '@theme/Authentication/View/Proxy/Partials/WAYF/rememberChoiceTooltip.html.twig' with { + rememberChoiceDuration: rememberChoiceDuration, + } only %} + {% else %} + + {% endif %}
{% endif %} diff --git a/theme/base/templates/modules/Authentication/View/Proxy/Partials/WAYF/rememberChoiceTooltip.html.twig b/theme/base/templates/modules/Authentication/View/Proxy/Partials/WAYF/rememberChoiceTooltip.html.twig new file mode 100644 index 0000000000..3eca45dc12 --- /dev/null +++ b/theme/base/templates/modules/Authentication/View/Proxy/Partials/WAYF/rememberChoiceTooltip.html.twig @@ -0,0 +1,19 @@ +
+ {% include '@theme/Default/Partials/label.html.twig' with { + class: 'tooltip', + hideText: true, + ariaExpandable: true, + id: 'rememberChoiceTooltip', + text: 'remember_choice_tooltip_screenreader'|trans, + } only %} +
+{% apply spaceless %} + +{% endapply %} diff --git a/theme/base/templates/modules/Authentication/View/Proxy/wayf.html.twig b/theme/base/templates/modules/Authentication/View/Proxy/wayf.html.twig index 2e8f5c7185..c9211a0302 100644 --- a/theme/base/templates/modules/Authentication/View/Proxy/wayf.html.twig +++ b/theme/base/templates/modules/Authentication/View/Proxy/wayf.html.twig @@ -41,6 +41,8 @@ action: action, requestId: requestId, rememberChoiceFeature: rememberChoiceFeature, + rememberChoicePerIdp: rememberChoicePerIdp, + rememberChoiceDuration: rememberChoiceDuration, cutoffPointForShowingUnfilteredIdps: cutoffPointForShowingUnfilteredIdps, showRequestAccess: showRequestAccess, } only %}