Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,9 @@ protected String authUrl() {
protected String openWalletPage() {
driver.open(authUrl());
String html = driver.driver().getPageSource();
Matcher matcher = Pattern.compile("openid4vp://[^\"'\\s]+").matcher(html);
assertTrue(matcher.find(), "Wallet login page did not contain an openid4vp:// link");
return matcher.group().replace("&", "&");
Matcher matcher = Pattern.compile("id=\"oid4vp-open-wallet\"[^>]*href=\"([^\"]+)\"").matcher(html);
assertTrue(matcher.find(), "Wallet login page did not contain the same device wallet link");
return matcher.group(1).replace("&", "&");
}

// The cross device wallet url rendered into the QR code, exposed as a data attribute on the image.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class LoginConfigTotpPage extends LogoutSessionsPage {
@FindBy(id = "userLabel")
private WebElement totpLabelInput;

@FindBy(css = "input[type=\"submit\"]")
@FindBy(id = "saveTOTPBtn")
private WebElement submitButton;

@FindBy(name = "cancel-aia")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ delegationScopeConsentText=Déléguer le jeton à l''administrateur {0} ?
oid4vpLoginTitle=Se connecter avec votre portefeuille
oid4vpOpenWalletApp=Ouvrir l''appli de portefeuille
identity-provider-login-label-divider=ou se connecter avec
identity-provider-login-label-short=ou
orLabel=ou
signInWithProvider=Se connecter avec {0}
webauthn-error-registration-not-allowed-aaguid=Ce modèle de clé de sécurité n''est pas autorisé (AAGUID {0}). Veuillez utiliser une clé de sécurité différente.
webauthn-error-registration-aaguid-attestation-required=Votre organisation demande des clés de sécurité vérifiées. Le format d''attestation ''none'' n''est pas accepté ; veuillez utiliser une clé qui fournit une attestation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ credentialOfferStep2=Continue o login no aplicativo após reivindicar {0} com su
credentialOfferUri=URL da oferta
naturalPersonScopeConsentText=Credencial verificável de pessoa física
identity-provider-login-label-divider=ou entre com
identity-provider-login-label-short=ou
orLabel=ou
signInWithProvider=Entrar com {0}
orgMemberAlready=Você já é membro da organização {1}.
orgDisabledMessage=A organização não está disponível no momento e não pode aceitar novos membros.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ naturalPersonScopeConsentText=Natural person verifiable credential
identity-provider-redirector=Connect with another Identity Provider
identity-provider-login-label=Or sign in with
identity-provider-login-label-divider=or sign in with
identity-provider-login-label-short=or
orLabel=or
signInWithProvider=Sign in with {0}
idp-email-verification-display-name=Email Verification
idp-email-verification-help-text=Link your account by validating your email.
Expand Down Expand Up @@ -590,6 +590,7 @@ traceIdSupportMessage=If you contact support, please provide the following trace

oid4vpLoginTitle=Sign in with your wallet
oid4vpOpenWalletApp=Open wallet app
oid4vpScanQrCode=Or scan the QR code with the wallet on another device
oid4vpScanQrCodeTitle=Scan QR code
oid4vpScanQrCode=Use your wallet app on another device to scan this code
oid4vpQrCodeAlt=QR code to sign in with a wallet on another device
oid4vpQrExpired=The QR code is no longer valid. To restart the login process
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<#macro or text=msg("orLabel")>
Comment thread
mabartos marked this conversation as resolved.
<div class="${properties.kcLoginDivider!}">
<span class="${properties.kcLoginMainFooterHelperText!}">
${text}
</span>
</div>
</#macro>
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<#import "template.ftl" as layout>
<#import "field.ftl" as field>
<#import "buttons.ftl" as buttons>
<#import "password-commons.ftl" as passwordCommons>
<#import "qr-code.ftl" as qr>
<@layout.registrationLayout displayRequiredFields=false displayMessage=!messagesPerField.existsError('totp','userLabel'); section>
<!-- template: login-config-totp.ftl -->

Expand Down Expand Up @@ -42,8 +44,9 @@
<#else>
<li>
<p>${msg("loginTotpStep2")}</p>
<img id="kc-totp-secret-qr-code" src="data:image/png;base64, ${totp.totpSecretQrCode}" alt="Figure: Barcode"><br/>
<p><a href="${totp.manualUrl}" id="mode-manual">${msg("loginTotpUnableToScan")}</a></p>
<@qr.qrCode id="kc-totp-secret-qr-code" content=totp.totpSecretQrCode alt=msg("loginTotpStep2")>
<a href="${totp.manualUrl}" id="mode-manual">${msg("loginTotpUnableToScan")}</a>
</@qr.qrCode>
</li>
</#if>
<li>
Expand Down Expand Up @@ -100,25 +103,16 @@
<@passwordCommons.logoutOtherSessions/>
</div>

<div class="pf-v5-c-form__group pf-m-action">
<div class="pf-v5-c-form__actions">
<#if isAppInitiatedAction??>
<input type="submit"
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}"
id="saveTOTPBtn" value="${msg("doSubmit")}"
/>
<button type="submit"
class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!} ${properties.kcButtonLargeClass!}"
id="cancelTOTPBtn" name="cancel-aia" value="true">${msg("doCancel")}
</button>
<#else>
<input type="submit"
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
id="saveTOTPBtn" value="${msg("doSubmit")}"
/>
</#if>
</div>
</div>
<#if isAppInitiatedAction??>
<@buttons.actionGroup horizontal=true>
<@buttons.button id="saveTOTPBtn" label="doSubmit" />
<@buttons.button id="cancelTOTPBtn" name="cancel-aia" label="doCancel" type="secondary" value="true" />
</@buttons.actionGroup>
<#else>
<@buttons.actionGroup>
<@buttons.button id="saveTOTPBtn" label="doSubmit" />
</@buttons.actionGroup>
</#if>
</form>
</#if>
</@layout.registrationLayout>
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
<#import "template.ftl" as layout>
<#import "divider.ftl" as divider>
<#import "qr-code.ftl" as qr>
<@layout.registrationLayout displayInfo=false; section>
<#if section = "header">
${msg("oid4vpLoginTitle")}
<#elseif section = "form">
<#if (sameDeviceWalletUrl!'')?has_content>
<div class="${properties.kcFormGroupClass!}">
<a id="oid4vp-open-wallet"
href="${sameDeviceWalletUrl}"
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}">
${msg("oid4vpOpenWalletApp")}
</a>
</div>
</#if>
<#if (crossDeviceQrCode!'')?has_content>
<div id="oid4vp-qr-block" class="${properties.kcFormGroupClass!}" style="text-align: center">
<p id="oid4vp-qr-instruction" class="instruction">${msg("oid4vpScanQrCode")}</p>
<img id="oid4vp-qr-code"
src="data:image/png;base64, ${crossDeviceQrCode}"
alt="${msg("oid4vpQrCodeAlt")}"
data-oid4vp-wallet-url="${crossDeviceWalletUrl!''}">
<div id="oid4vp-qr-block" class="${properties.kcFormGroupClass!}"
data-oid4vp-wallet-url="${crossDeviceWalletUrl!''}">
<@qr.qrCode id="oid4vp-qr-code" content=crossDeviceQrCode alt=msg("oid4vpQrCodeAlt") title=msg("oid4vpScanQrCodeTitle") label=msg("oid4vpScanQrCode") />
</div>
<div id="oid4vp-qr-expired" class="${properties.kcFormGroupClass!}" style="text-align: center" role="status" aria-live="polite" hidden>
${msg("oid4vpQrExpired")} <a id="oid4vp-restart-login" href="${url.loginRestartFlowUrl}">${msg("doClickHere")}</a> .
Expand All @@ -37,5 +27,17 @@
</#outputformat>
</script>
</#if>
<#if (sameDeviceWalletUrl!'')?has_content>
<#if (crossDeviceQrCode!'')?has_content>
<@divider.or />
</#if>
<div class="${properties.kcFormGroupClass!}">
<a id="oid4vp-open-wallet"
href="${sameDeviceWalletUrl}"
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}">
${msg("oid4vpOpenWalletApp")}
</a>
</div>
</#if>
</#if>
</@layout.registrationLayout>
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<#import "template.ftl" as layout>
<#import "field.ftl" as field>
<#import "buttons.ftl" as buttons>
<#import "password-commons.ftl" as passwordCommons>
<#import "qr-code.ftl" as qr>
<@layout.registrationLayout displayRequiredFields=false displayMessage=!messagesPerField.existsError('credentialOffer'); section>
<!-- template: oid4vc-credential-offer.ftl -->

Expand All @@ -10,34 +12,22 @@
<ol id="kc-cred-offer-settings" class="pf-v5-c-list pf-v5-u-mb-md">
<li>
<p>${msg("credentialOfferStep1", credentialDisplayName)}</p>
<img id="kc-credential-offer-qr-code" src="data:image/png;base64, ${credentialOffer.qrCode}" alt="Figure: Barcode"><br/>
<p><span id="kc-credential-offer-uri"><a href="${credentialOffer.uri}" id="credential-offer-uri-link">${msg("credentialOfferUri")}</a></span></p>
<@qr.qrCode id="kc-credential-offer-qr-code" content=credentialOffer.qrCode alt="QR code to claim a credential with a wallet">
<span id="kc-credential-offer-uri"><a href="${credentialOffer.uri}" id="credential-offer-uri-link">${msg("credentialOfferUri")}</a></span>
</@qr.qrCode>
</li>
<li>
<p>${msg("credentialOfferStep2", credentialDisplayName)}</p>
</li>
</ol>

<form action="${url.loginAction}" class="${properties.kcFormClass!}" id="kc-cred-offer-settings-form" method="post" novalidate="novalidate">
<div class="pf-v5-c-form__group pf-m-action">
<div class="pf-v5-c-form__actions">
<#if skipCancelButton??>
<input type="submit"
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
id="continue-vc-offer" value="${msg("doContinue")}"
/>
<#else>
<input type="submit"
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}"
id="continue-vc-offer" value="${msg("doContinue")}"
/>
<button type="submit"
class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!} ${properties.kcButtonLargeClass!}"
id="cancel-vc-offer" name="cancel-aia" value="true">${msg("doCancel")}
</button>
</#if>
</div>
</div>
<@buttons.actionGroup horizontal=true>
<@buttons.button id="continue-vc-offer" label="doContinue" />
<#if !skipCancelButton??>
<@buttons.button id="cancel-vc-offer" name="cancel-aia" label="doCancel" type="secondary" value="true" />
Comment thread
mabartos marked this conversation as resolved.
</#if>
</@buttons.actionGroup>
</form>
</#if>
</@layout.registrationLayout>
12 changes: 12 additions & 0 deletions themes/src/main/resources/theme/keycloak.v2/login/qr-code.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<#macro qrCode id content alt title="" label="">
<div class="${properties.kcLoginQrCode!}">
<img id="${id}" src="data:image/png;base64, ${content}" alt="${alt}">
<#if title?has_content>
<p class="${properties.kcLoginQrCodeTitle!}">${title}</p>
</#if>
<#if label?has_content>
<p class="${properties.kcLoginMainFooterHelperText!}">${label}</p>
</#if>
<#nested>
</div>
</#macro>
Original file line number Diff line number Diff line change
Expand Up @@ -145,20 +145,37 @@ hr {

/* Named divider */

.kc-social-providers-divider {
.kc-login-divider {
display: flex;
align-items: center;
gap: var(--pf-v5-global--spacer--md);
margin: var(--pf-v5-global--spacer--md) 0 var(--pf-v5-global--spacer--md);
}

.kc-social-providers-divider::before,
.kc-social-providers-divider::after {
.kc-login-divider::before,
.kc-login-divider::after {
content: '';
flex: 1;
border-bottom: 1px solid var(--pf-v5-global--BorderColor--100);
}

/* QR code */

.kc-qr-code img {
width: 200px;
height: 200px;
border-radius: 10px;
border: 2px solid var(--pf-v5-global--BorderColor--100);
box-shadow: var(--pf-v5-global--BoxShadow--lg-right);
}

@media (prefers-color-scheme: dark) {
.kc-qr-code img {
border: none;
box-shadow: none;
}
}

@media (min-width: 768px) {
div.pf-v5-c-login__main-header:has(.pf-v5-c-login__main-header-utilities) {
grid-template-columns: 70% 30%;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
<#import "divider.ftl" as divider>
<#macro show social>
<#assign useGrid = (social.providers?size gt 3)>
<div class="${properties.kcLoginSocialProvidersDivider!}">
<span class="${properties.kcLoginMainFooterHelperText!}">
<#if useGrid>
${msg("identity-provider-login-label-divider")}
<#else>
${msg("identity-provider-login-label-short")}
</#if>
</span>
</div>
<@divider.or text=msg(useGrid?then("identity-provider-login-label-divider", "orLabel")) />
<div id="kc-social-providers" class="${properties.kcFormSocialAccountSectionClass!}">
<ul class="${properties.kcFormSocialAccountListClass!} <#if useGrid>${properties.kcFormSocialAccountListGridClass!}</#if>">
<#list social.providers as p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ kcLoginMainFooter=pf-v5-c-login__main-footer
kcLoginMainFooterBand=pf-v5-c-login__main-footer-band
kcLoginMainFooterBandItem=pf-v5-c-login__main-footer-band-item
kcLoginMainFooterHelperText=pf-v5-u-font-size-sm pf-v5-u-color-200
kcLoginSocialProvidersDivider=kc-social-providers-divider
kcLoginDivider=kc-login-divider
kcLoginQrCode=kc-qr-code pf-v5-u-display-flex pf-v5-u-flex-direction-column pf-v5-u-align-items-center pf-v5-u-my-sm
kcLoginQrCodeTitle=pf-v5-u-font-weight-bold pf-v5-u-font-size-md pf-v5-u-pt-sm
kcLoginMainTitle=pf-v5-c-title pf-m-3xl
kcLoginMainHeaderUtilities=pf-v5-c-login__main-header-utilities
kcLoginMainBody=pf-v5-c-login__main-body
Expand Down
Loading