From 908f0ac33a8fe4ee0e081911cec228fb2154effa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20B=C3=A4dorf?= Date: Sun, 27 Nov 2022 02:47:13 +0100 Subject: [PATCH] Entertainment --- account/account.ftl | 65 +++++ account/applications.ftl | 86 ++++++ account/federatedIdentity.ftl | 42 +++ account/log.ftl | 35 +++ account/password.ftl | 75 +++++ account/resource-detail.ftl | 277 ++++++++++++++++++ account/resources.ftl | 403 ++++++++++++++++++++++++++ account/sessions.ftl | 44 +++ account/totp.ftl | 131 +++++++++ common/resources/css/index.css | 18 +- common/resources/scss/form-group.scss | 4 + common/resources/scss/header.scss | 10 +- common/resources/scss/page.scss | 2 +- login/template.ftl | 111 ++++--- 14 files changed, 1238 insertions(+), 65 deletions(-) create mode 100755 account/account.ftl create mode 100755 account/applications.ftl create mode 100755 account/federatedIdentity.ftl create mode 100644 account/log.ftl create mode 100755 account/password.ftl create mode 100755 account/resource-detail.ftl create mode 100755 account/resources.ftl create mode 100755 account/sessions.ftl create mode 100755 account/totp.ftl diff --git a/account/account.ftl b/account/account.ftl new file mode 100755 index 0000000..d5592bb --- /dev/null +++ b/account/account.ftl @@ -0,0 +1,65 @@ +<#import "template.ftl" as layout> +<@layout.mainLayout active='account' bodyClass='user'; section> + +
+
+

${msg("editAccountHtmlTitle")}

+
+
+ * ${msg("requiredFields")} +
+
+ +
+ + + + <#if !realm.registrationEmailAsUsername> +
+ + + disabled="disabled" value="${(account.username!'')}" + /> +
+ + +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+
+
+ <#if url.referrerURI??>${kcSanitize(msg("backToApplication")?no_esc)} + + +
+
+
+
+ + diff --git a/account/applications.ftl b/account/applications.ftl new file mode 100755 index 0000000..0c0906d --- /dev/null +++ b/account/applications.ftl @@ -0,0 +1,86 @@ +<#import "template.ftl" as layout> +<@layout.mainLayout active='applications' bodyClass='applications'; section> + +
+
+

${msg("applicationsHtmlTitle")}

+
+
+ +
+ + + + + + + + + + + + + + + + <#list applications.applications as application> + + + + + + + + + + + + + +
${msg("application")}${msg("availableRoles")}${msg("grantedPermissions")}${msg("additionalGrants")}${msg("action")}
+ <#if application.effectiveUrl?has_content> + + + <#if application.client.name?has_content>${advancedMsg(application.client.name)}<#else>${application.client.clientId} + <#if application.effectiveUrl?has_content> + + + + <#list application.realmRolesAvailable as role> + <#if role.description??>${advancedMsg(role.description)}<#else>${advancedMsg(role.name)} + <#if role_has_next>, + + <#list application.resourceRolesAvailable?keys as resource> + <#if application.realmRolesAvailable?has_content>, + <#list application.resourceRolesAvailable[resource] as clientRole> + <#if clientRole.roleDescription??>${advancedMsg(clientRole.roleDescription)}<#else>${advancedMsg(clientRole.roleName)} + ${msg("inResource")} <#if clientRole.clientName??>${advancedMsg(clientRole.clientName)}<#else>${clientRole.clientId} + <#if clientRole_has_next>, + + + + <#if application.client.consentRequired> + <#list application.clientScopesGranted as claim> + ${advancedMsg(claim)}<#if claim_has_next>, + + <#else> + ${msg("fullAccess")} + + + <#list application.additionalGrants as grant> + ${advancedMsg(grant)}<#if grant_has_next>, + + + <#if (application.client.consentRequired && application.clientScopesGranted?has_content) || application.additionalGrants?has_content> + + +
+
+ + diff --git a/account/federatedIdentity.ftl b/account/federatedIdentity.ftl new file mode 100755 index 0000000..c2eb769 --- /dev/null +++ b/account/federatedIdentity.ftl @@ -0,0 +1,42 @@ +<#import "template.ftl" as layout> +<@layout.mainLayout active='social' bodyClass='social'; section> + +
+
+

${msg("federatedIdentitiesHtmlTitle")}

+
+
+ +
+ <#list federatedIdentity.identities as identity> +
+
+ +
+
+ +
+
+ <#if identity.connected> + <#if federatedIdentity.removeLinkPossible> +
+ + + + +
+ + <#else> +
+ + + + +
+ +
+
+ +
+ + diff --git a/account/log.ftl b/account/log.ftl new file mode 100644 index 0000000..29046cf --- /dev/null +++ b/account/log.ftl @@ -0,0 +1,35 @@ +<#import "template.ftl" as layout> +<@layout.mainLayout active='log' bodyClass='log'; section> + +
+
+

${msg("accountLogHtmlTitle")}

+
+
+ + + + + + + + + + + + + + <#list log.events as event> + + + + + + + + + + +
${msg("date")}${msg("event")}${msg("ip")}${msg("client")}${msg("details")}
${event.date?datetime}${event.event}${event.ipAddress}${event.client!}<#list event.details as detail>${detail.key} = ${detail.value} <#if detail_has_next>,
+ + \ No newline at end of file diff --git a/account/password.ftl b/account/password.ftl new file mode 100755 index 0000000..776792e --- /dev/null +++ b/account/password.ftl @@ -0,0 +1,75 @@ +<#import "template.ftl" as layout> +<@layout.mainLayout active='password' bodyClass='password'; section> + +
+
+

${msg("changePasswordHtmlTitle")}

+
+
+ ${msg("allFieldsRequired")} +
+
+ +
+ + + <#if password.passwordSet> +
+ + + +
+ + + + +
+ + + +
+ +
+ + + +
+ +
+
+
+ +
+
+
+
+ + diff --git a/account/resource-detail.ftl b/account/resource-detail.ftl new file mode 100755 index 0000000..2c963d7 --- /dev/null +++ b/account/resource-detail.ftl @@ -0,0 +1,277 @@ +<#import "template.ftl" as layout> +<@layout.mainLayout active='authorization' bodyClass='authorization'; section> + + + + +
+
+

+ ${msg("myResources")} <#if authorization.resource.displayName??>${authorization.resource.displayName}<#else>${authorization.resource.name} +

+
+
+ + <#if authorization.resource.iconUri??> + +
+ + +
+
+

+ ${msg("peopleAccessResource")} +

+
+
+
+
+ + + + + + + + + + + <#if authorization.resource.shares?size != 0> + <#list authorization.resource.shares as permission> + + + + + + + + + + + + + <#else> + + + + + +
${msg("user")}${msg("permission")}${msg("date")}${msg("action")}
+ <#if permission.requester.email??>${permission.requester.email}<#else>${permission.requester.username} + + <#if permission.scopes?size != 0> + <#list permission.scopes as scope> + <#if scope.granted && scope.scope??> + + <#else> + ${msg("anyPermission")} + + + <#else> + Any action + + + ${permission.createdDate?datetime} + + ${msg("doRevoke")} +
${msg("resourceIsNotBeingShared")}
+ +
+
+
+
+

+ ${msg("resourceManagedPolicies")} +

+
+
+
+
+ + + + + + + + + + <#if authorization.resource.policies?size != 0> + <#list authorization.resource.policies as permission> + + + + + + + + + + + + <#else> + + + + + +
${msg("description")}${msg("permission")}${msg("action")}
+ <#if permission.description??> + ${permission.description} + + + <#if permission.scopes?size != 0> + <#list permission.scopes as scope> + + + <#else> + ${msg("anyAction")} + + + ${msg("doRevoke")} +
+ ${msg("resourceNoPermissionsGrantingAccess")} +
+ +
+
+
+
+

+ ${msg("shareWithOthers")} +

+
+
+
+
+
+ +
+ * +
+
+
+
+ +
+
+
+ <#list authorization.resource.scopes as scope> + + +
+ +
+
+
+
+
+
+ diff --git a/account/resources.ftl b/account/resources.ftl new file mode 100755 index 0000000..d86e8bc --- /dev/null +++ b/account/resources.ftl @@ -0,0 +1,403 @@ +<#import "template.ftl" as layout> +<@layout.mainLayout active='authorization' bodyClass='authorization'; section> + + +
+
+

+ ${msg("myResources")} +

+
+
+ + <#if authorization.resourcesWaitingApproval?size != 0> +
+
+

+ ${msg("needMyApproval")} +

+
+
+
+
+ + + + + + + + + + + <#list authorization.resourcesWaitingApproval as resource> + <#list resource.permissions as permission> + + + + + + + + + + + + + + +
${msg("resource")}${msg("requestor")}${msg("permissionRequestion")}${msg("action")}
+ <#if resource.displayName??>${resource.displayName}<#else>${resource.name} + + <#if permission.requester.email??>${permission.requester.email}<#else>${permission.requester.username} + + <#list permission.scopes as scope> + <#if scope.scope??> + + <#else> + ${msg("anyPermission")} + + + + ${msg("doApprove")} + ${msg("doDeny")} +
+
+
+ + +
+
+

+ ${msg("myResourcesSub")} +

+
+
+
+
+ + + + + + + + + + + <#if authorization.resources?size != 0> + <#list authorization.resources as resource> + + + + + + + <#else> + + + + + +
${msg("resource")}${msg("application")}${msg("peopleSharingThisResource")}
+ + <#if resource.displayName??>${resource.displayName}<#else>${resource.name} + + + <#if resource.resourceServer.baseUri??> + ${resource.resourceServer.name} + <#else> + ${resource.resourceServer.name} + + + <#if resource.shares?size != 0> + ${resource.shares?size} + <#else> + ${msg("notBeingShared")} + +
${msg("notHaveAnyResource")}
+
+
+ +
+
+

+ ${msg("resourcesSharedWithMe")} +

+
+
+
+
+
+ + + + + + + + + + + + + + <#if authorization.sharedResources?size != 0> + <#list authorization.sharedResources as resource> + + + + + + + + + + <#else> + + + + + +
disabled="true" + ${msg("resource")}${msg("owner")}${msg("application")}${msg("permission")}${msg("date")}
+ + + <#if resource.displayName??>${resource.displayName}<#else>${resource.name} + + ${resource.ownerName} + + <#if resource.resourceServer.baseUri??> + ${resource.resourceServer.name} + <#else> + ${resource.resourceServer.name} + + + <#if resource.permissions?size != 0> +
    + <#list resource.permissions as permission> + <#list permission.scopes as scope> + <#if scope.granted && scope.scope??> +
  • + <#if scope.scope.displayName??> + ${scope.scope.displayName} + <#else> + ${scope.scope.name} + +
  • + <#else> + ${msg("anyPermission")} + + + +
+ <#else> + Any action + +
+ ${resource.permissions[0].grantedDate?datetime} +
${msg("noResourcesSharedWithYou")}
+
+
+ <#if authorization.sharedResources?size != 0> + + +
+ + <#if authorization.resourcesWaitingOthersApproval?size != 0> +
+
+
+

+ ${msg("requestsWaitingApproval")} +

+
+
+
+
+ ${msg("havePermissionRequestsWaitingForApproval",authorization.resourcesWaitingOthersApproval?size)} + ${msg("clickHereForDetails")} +
+
+
+
+
+
+
+
+
+ +
+
+ + + \ No newline at end of file diff --git a/account/sessions.ftl b/account/sessions.ftl new file mode 100755 index 0000000..89dbf65 --- /dev/null +++ b/account/sessions.ftl @@ -0,0 +1,44 @@ +<#import "template.ftl" as layout> +<@layout.mainLayout active='sessions' bodyClass='sessions'; section> + +
+
+

${msg("sessionsHtmlTitle")}

+
+
+ + + + + + + + + + + + + + <#list sessions.sessions as session> + + + + + + + + + + +
${msg("ip")}${msg("started")}${msg("lastAccess")}${msg("expires")}${msg("clients")}
${session.ipAddress}${session.started?datetime}${session.lastAccess?datetime}${session.expires?datetime} + <#list session.clients as client> + ${client}
+ +
+ +
+ + +
+ + diff --git a/account/totp.ftl b/account/totp.ftl new file mode 100755 index 0000000..10a9cd2 --- /dev/null +++ b/account/totp.ftl @@ -0,0 +1,131 @@ +<#import "template.ftl" as layout> +<@layout.mainLayout active='totp' bodyClass='totp'; section> + +
+
+

${msg("authenticatorTitle")}

+
+ <#if totp.otpCredentials?size == 0> +
+ * ${msg("requiredFields")} +
+ +
+ + <#if totp.enabled> + + + <#if totp.otpCredentials?size gt 1> + + + + <#else> + + + + + + + <#list totp.otpCredentials as credential> + + + <#if totp.otpCredentials?size gt 1> + + + + + + + +
${msg("configureAuthenticators")}
${msg("configureAuthenticators")}
${msg("mobile")}${credential.id}${credential.userLabel!} +
+ + + + +
+
+ <#else> + +
+ +
    +
  1. +

    ${msg("totpStep1")}

    + +
      + <#list totp.supportedApplications as app> +
    • ${msg(app)}
    • + +
    +
  2. + + <#if mode?? && mode = "manual"> +
  3. +

    ${msg("totpManualStep2")}

    +

    ${totp.totpSecretEncoded}

    +

    ${msg("totpScanBarcode")}

    +
  4. +
  5. +

    ${msg("totpManualStep3")}

    +
      +
    • ${msg("totpType")}: ${msg("totp." + totp.policy.type)}
    • +
    • ${msg("totpAlgorithm")}: ${totp.policy.getAlgorithmKey()}
    • +
    • ${msg("totpDigits")}: ${totp.policy.digits}
    • + <#if totp.policy.type = "totp"> +
    • ${msg("totpInterval")}: ${totp.policy.period}
    • + <#elseif totp.policy.type = "hotp"> +
    • ${msg("totpCounter")}: ${totp.policy.initialCounter}
    • + +
    +
  6. + <#else> +
  7. +

    ${msg("totpStep2")}

    +

    Figure: Barcode

    +

    ${msg("totpUnableToScan")}

    +
  8. + +
  9. +

    ${msg("totpStep3")}

    +

    ${msg("totpStep3DeviceName")}

    +
  10. +
+ +
+ +
+ +
+ + + + +
+ +
+ + + +
+ +
+
+
+ + +
+
+
+
+ + + diff --git a/common/resources/css/index.css b/common/resources/css/index.css index cb6b927..b8a2629 100644 --- a/common/resources/css/index.css +++ b/common/resources/css/index.css @@ -74,6 +74,8 @@ html { .ps-form-group { display: flex; flex-direction: column; } + .ps-form-group--label { + display: flex; } .ps-main { display: flex; @@ -100,17 +102,23 @@ html { padding: 0; } .ps-header { - border-bottom: 0.5rem solid var(--foreground); - background-color: var(--background); display: flex; padding: 0; margin: 0; } .ps-header--title { font-size: 1.5rem; - margin: 0; } + padding: 0 1rem; + margin: 0; + border-bottom: 0.5rem solid var(--foreground); + background-color: var(--background); + border-right: 0.5rem solid var(--foreground); } .ps-header--nav { margin-left: auto; - display: flex; } + display: flex; + border-bottom: 0.5rem solid var(--foreground); + border-left: 0.5rem solid var(--foreground); + background-color: var(--background); + padding-left: 1rem; } .ps-header--nav-list { display: flex; justify-content: flex-end; @@ -198,7 +206,7 @@ html { .ps-page--section-link-icon { margin-left: 8px; } .ps-page--section-contents { - margin: 5vw; + margin: 2rem; margin-bottom: 0; font-weight: 500; line-height: 1.4; } diff --git a/common/resources/scss/form-group.scss b/common/resources/scss/form-group.scss index adbf268..3338c5a 100644 --- a/common/resources/scss/form-group.scss +++ b/common/resources/scss/form-group.scss @@ -1,4 +1,8 @@ .ps-form-group { display: flex; flex-direction: column; + + &--label { + display: flex; + } } diff --git a/common/resources/scss/header.scss b/common/resources/scss/header.scss index e5fb2a4..4cccd5c 100644 --- a/common/resources/scss/header.scss +++ b/common/resources/scss/header.scss @@ -1,18 +1,24 @@ .ps-header { - border-bottom: 0.5rem solid var(--foreground); - background-color: var(--background); display: flex; padding: 0; margin: 0; &--title { font-size: 1.5rem; + padding: 0 1rem; margin: 0; + border-bottom: 0.5rem solid var(--foreground); + background-color: var(--background); + border-right: 0.5rem solid var(--foreground); } &--nav { margin-left: auto; display: flex; + border-bottom: 0.5rem solid var(--foreground); + border-left: 0.5rem solid var(--foreground); + background-color: var(--background); + padding-left: 1rem; } &--nav-list { diff --git a/common/resources/scss/page.scss b/common/resources/scss/page.scss index a82f4fc..14352fb 100644 --- a/common/resources/scss/page.scss +++ b/common/resources/scss/page.scss @@ -93,7 +93,7 @@ } &--section-contents { - margin: 5vw; + margin: 2rem; margin-bottom: 0; font-weight: 500; line-height: 1.4; diff --git a/login/template.ftl b/login/template.ftl index ec8112d..18f6834 100644 --- a/login/template.ftl +++ b/login/template.ftl @@ -39,7 +39,7 @@ - +
-
-
- <#if realm.internationalizationEnabled && locale.supported?size gt 1> -
- ${locale.current} -
-
    - <#list locale.supported as l> -
  • - ${l.label} -
  • - -
-
-
- +
<#if !(auth?has_content && auth.showUsername() && !auth.showResetCredentials())> +

<#nested "header">

<#if displayRequiredFields> -
-
- * ${msg("requiredFields")} -
-

<#nested "header">

+
+ * ${msg("requiredFields")}
- <#else> -

<#nested "header">

<#else> <#if displayRequiredFields> @@ -118,44 +99,60 @@
+ <#if realm.internationalizationEnabled && locale.supported?size gt 1> +
+ ${locale.current} +
+
    + <#list locale.supported as l> +
  • + ${l.label} +
  • + +
+
+
+
-
- <#-- App-initiated actions should not see warning messages about the need to complete the action --> - <#-- during login. --> - <#if displayMessage && message?has_content && (message.type != 'warning' || !isAppInitiatedAction??)> -
-
- <#if message.type = 'success'> - <#if message.type = 'warning'> - <#if message.type = 'error'> - <#if message.type = 'info'> -
- ${kcSanitize(message.summary)?no_esc} -
- +
+
+ <#-- App-initiated actions should not see warning messages about the need to complete the action --> + <#-- during login. --> + <#if displayMessage && message?has_content && (message.type != 'warning' || !isAppInitiatedAction??)> +
+
+ <#if message.type = 'success'> + <#if message.type = 'warning'> + <#if message.type = 'error'> + <#if message.type = 'info'> +
+ ${kcSanitize(message.summary)?no_esc} +
+ - <#nested "form"> + <#nested "form"> - <#if auth?has_content && auth.showTryAnotherWayLink()> -
- -
- + <#if auth?has_content && auth.showTryAnotherWayLink()> +
+ +
+ - <#nested "socialProviders"> + <#nested "socialProviders"> - <#if displayInfo> -
-
- <#nested "info"> -
-
- -
+ <#if displayInfo> +
+
+ <#nested "info"> +
+
+ +
+