Compare commits
50 Commits
a164e91b73
...
main
Author | SHA1 | Date | |
---|---|---|---|
d7d39e85ac | |||
1e924472bb | |||
3f10bd7a95 | |||
10581b44b1 | |||
add791e087 | |||
7f22479d29
|
|||
ec69c49371
|
|||
f526c20e78 | |||
85d715ad00 | |||
ac2a6c1753 | |||
eb9fafdc96 | |||
82df4ba11d | |||
7cd9da93aa | |||
2aaef7bab0 | |||
9fe94e6ce7 | |||
f943915553 | |||
9feb042414 | |||
65d61005c4 | |||
d33ba9590f | |||
1a21f4c1ab | |||
1c01bfd00f | |||
f89f7be21c | |||
b084b18e5a | |||
5ad9090417 | |||
51fb2029f0 | |||
fccad406d3 | |||
1f4fec6aa3 | |||
854ec97956 | |||
e49ee45709 | |||
b736318908 | |||
b595726742 | |||
fed3f486aa | |||
15d0773bce | |||
037aaf63eb | |||
57eeabe134 | |||
5f08b3ea3a | |||
581fbd415c | |||
49d8906b92 | |||
5954f22939 | |||
795b1d0539 | |||
1e69982156 | |||
c9e5477b12
|
|||
0296bd97d6
|
|||
9e15ffecef
|
|||
df66e3116a
|
|||
09f914057c
|
|||
4e2415e807
|
|||
1134b4572b
|
|||
c215e7997f
|
|||
49fe169288
|
19
.drone.yml
Normal file
19
.drone.yml
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
kind: pipeline
|
||||
name: deploy to autonomic-ruangrupa
|
||||
steps:
|
||||
- name: deploy new theme
|
||||
image: 3wordchant/docker-cp-deploy:latest
|
||||
settings:
|
||||
host: lumbung.space
|
||||
service: login_lumbung_space_app
|
||||
source: lumbung.space
|
||||
dest: /opt/keycloak/themes
|
||||
deploy_key:
|
||||
from_secret: drone_ssh_lumbung.space
|
||||
trigger:
|
||||
branch:
|
||||
- main
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
33
README.md
33
README.md
@ -1,7 +1,40 @@
|
||||
# login.lumbung.space
|
||||
|
||||
[](https://drone.autonomic.zone/ruangrupa/login.lumbung.space)
|
||||
|
||||
> [login.lumbung.space](https://login.lumbung.space)
|
||||
|
||||
[Custom theming](https://www.keycloak.org/docs/latest/server_development/index.html#_themes) for the Keycloak SSO service.
|
||||
|
||||
Please see [default-themes/README.md](./default-themes/README.md) and [lumbung.space/README.md](./lumbung.space/README.md) for more info.
|
||||
|
||||
## Deployment
|
||||
|
||||
Just send commits and the [Drone CI/CD configuration](./.drone.yml) will take care of the rest.
|
||||
|
||||
## Custom theming workflow
|
||||
|
||||
You'll need a local [Docker](https://docs.docker.com/engine/install/debian/) installation.
|
||||
|
||||
Then run a local Keycloak instance and mount the theme into the container with the following ([makefile source](./makefile)):
|
||||
|
||||
```
|
||||
$ make
|
||||
```
|
||||
|
||||
An example workflow for customising the login theme would be:
|
||||
|
||||
- Log into [localhost:8080](http://localhost:8080) with username: `admin` and password: `admin`
|
||||
- Go to [Realm Settings > Themes](http://localhost:8080/auth/admin/master/console/#/realms/master/theme-settings)
|
||||
- Choose a custom login theme via Login Theme > lumbung.space and click Save
|
||||
- Sign out and you'll be redirected to the login page
|
||||
- Now, test you can make an edit and it is reflected on reload, change the "Username or email" string in [mesages_en.properties](./lumbung.space/login/messages/messages_en.properties)
|
||||
- Reload the page, your change should be live
|
||||
|
||||
See related documentation and tutorials for the hacking:
|
||||
|
||||
- [Create a custom theme for Keycloak](https://auscunningham.medium.com/create-a-custom-theme-for-keycloak-8781207be604)
|
||||
- [Change Login Theme in Keycloak Docker image](https://austincunningham.ddns.net/2020/changekeycloakdockertheme)
|
||||
- [Keycloak themes documentation](https://www.keycloak.org/docs/latest/server_development/index.html#_themes)
|
||||
- [Keycloak Github repo for default themes](https://github.com/keycloak/keycloak/tree/master/themes/src/main/resources/theme)
|
||||
- [Keycloak container documentation](https://github.com/keycloak/keycloak-containers/tree/master/server)
|
||||
|
5
bin/disable-theme-cache.cli
Normal file
5
bin/disable-theme-cache.cli
Normal file
@ -0,0 +1,5 @@
|
||||
embed-server --std-out=echo --server-config=standalone-ha.xml
|
||||
/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheThemes,value=false)
|
||||
/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheTemplates,value=false)
|
||||
/subsystem=keycloak-server/theme=defaults/:write-attribute(name=staticMaxAge,value=-1)
|
||||
stop-embedded-server
|
@ -19,11 +19,11 @@
|
||||
~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||
-->
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Welcome to ${productNameFull}</title>
|
||||
<title>Welcome to ${productName}</title>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
@ -49,9 +49,10 @@
|
||||
<div class="col-sm-10 col-sm-offset-1 col-md-8 col-md-offset-2 col-lg-8 col-lg-offset-2">
|
||||
<div class="welcome-header">
|
||||
<img src="${resourcesPath}/logo.png" alt="${productName}" border="0" />
|
||||
<h1>Welcome to <strong>${productNameFull}</strong></h1>
|
||||
<h1>Welcome to <strong>${productName}</strong></h1>
|
||||
</div>
|
||||
<div class="row">
|
||||
<#if adminConsoleEnabled>
|
||||
<div class="col-xs-12 col-sm-4">
|
||||
<div class="card-pf h-l">
|
||||
<#if successMessage?has_content>
|
||||
@ -60,15 +61,15 @@
|
||||
<p class="alert error">${errorMessage}</p>
|
||||
<h3><img src="welcome-content/user.png">Administration Console</h3>
|
||||
<#elseif bootstrap>
|
||||
<#if localUser>
|
||||
<h3><img src="welcome-content/user.png">Administration Console</h3>
|
||||
<p>Please create an initial admin user to get started.</p>
|
||||
<#else>
|
||||
<p class="welcome-message">
|
||||
<img src="welcome-content/alert.png">You need local access to create the initial admin user. <br><br>Open <a href="http://localhost:8080/auth">http://localhost:8080/auth</a>
|
||||
<br>or use the add-user-keycloak script.
|
||||
</p>
|
||||
</#if>
|
||||
<#if localUser>
|
||||
<h3><img src="welcome-content/user.png">Administration Console</h3>
|
||||
<p>Please create an initial admin user to get started.</p>
|
||||
<#else>
|
||||
<p class="welcome-message">
|
||||
<img src="welcome-content/alert.png">You need local access to create the initial admin user. <br><br>Open <a href="${localAdminUrl}">${localAdminUrl}</a>
|
||||
<br>${adminUserCreationMessage}.
|
||||
</p>
|
||||
</#if>
|
||||
</#if>
|
||||
|
||||
<#if bootstrap && localUser>
|
||||
@ -93,14 +94,16 @@
|
||||
<button id="create-button" type="submit" class="btn btn-primary">Create</button>
|
||||
</form>
|
||||
</#if>
|
||||
|
||||
<div class="welcome-primary-link">
|
||||
<h3><a href="${adminUrl}"><img src="welcome-content/user.png">Administration Console <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
|
||||
<div class="description">
|
||||
Centrally manage all aspects of the ${productNameFull} server
|
||||
Centrally manage all aspects of the ${productName} server
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</#if> <#-- adminConsoleEnabled -->
|
||||
<div class="col-xs-12 col-sm-4">
|
||||
<div class="card-pf h-l">
|
||||
<h3><a href="${properties.documentationUrl}"><img class="doc-img" src="welcome-content/admin-console.png">Documentation <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
|
||||
@ -120,18 +123,14 @@
|
||||
<h3><a href="https://groups.google.com/forum/#!forum/keycloak-user"><img src="welcome-content/mail.png">Mailing List <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
|
||||
</div>
|
||||
<div class="card-pf h-m">
|
||||
<h3><a href="https://issues.jboss.org/browse/KEYCLOAK"><img src="welcome-content/bug.png">Report an issue <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
|
||||
<h3><a href="https://github.com/keycloak/keycloak/issues"><img src="welcome-content/bug.png">Report an issue <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
|
||||
</div>
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
<div class='footer'>
|
||||
<#if properties.displayCommunityLinks = "true">
|
||||
<a href="http://www.jboss.org"><img src="welcome-content/jboss_community.png" alt="JBoss and JBoss Community"></a>
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
# lumbung.space
|
||||
|
||||
Custom theme for [login.lumung.space](https://login.lumbung.space).
|
||||
|
||||
- [login](./login) was copied from [default-themes/base/login](../default-themes/base/login)
|
||||
|
||||
## N.N themeing workflow:
|
||||
|
||||
If the browser complains about resource `was blocked due to MIME type (“”) mismatch (X-Content-Type-Options: nosniff).` is _actually_ the fact that it can not find that resource, it won't throw a 404 instead..
|
||||
|
5
lumbung.space/email/html/email-test.ftl
Normal file
5
lumbung.space/email/html/email-test.ftl
Normal file
@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
${kcSanitize(msg("emailTestBodyHtml",realmName))?no_esc}
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
${kcSanitize(msg("emailVerificationBodyCodeHtml",code))?no_esc}
|
||||
</body>
|
||||
</html>
|
5
lumbung.space/email/html/email-verification.ftl
Normal file
5
lumbung.space/email/html/email-verification.ftl
Normal file
@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
${kcSanitize(msg("emailVerificationBodyHtml",link, linkExpiration, realmName, linkExpirationFormatter(linkExpiration)))?no_esc}
|
||||
</body>
|
||||
</html>
|
5
lumbung.space/email/html/event-login_error.ftl
Normal file
5
lumbung.space/email/html/event-login_error.ftl
Normal file
@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
${kcSanitize(msg("eventLoginErrorBodyHtml",event.date,event.ipAddress))?no_esc}
|
||||
</body>
|
||||
</html>
|
5
lumbung.space/email/html/event-remove_totp.ftl
Normal file
5
lumbung.space/email/html/event-remove_totp.ftl
Normal file
@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
${kcSanitize(msg("eventRemoveTotpBodyHtml",event.date, event.ipAddress))?no_esc}
|
||||
</body>
|
||||
</html>
|
5
lumbung.space/email/html/event-update_password.ftl
Normal file
5
lumbung.space/email/html/event-update_password.ftl
Normal file
@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
${kcSanitize(msg("eventUpdatePasswordBodyHtml",event.date, event.ipAddress))?no_esc}
|
||||
</body>
|
||||
</html>
|
5
lumbung.space/email/html/event-update_totp.ftl
Normal file
5
lumbung.space/email/html/event-update_totp.ftl
Normal file
@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
${kcSanitize(msg("eventUpdateTotpBodyHtml",event.date, event.ipAddress))?no_esc}
|
||||
</body>
|
||||
</html>
|
9
lumbung.space/email/html/executeActions.ftl
Executable file
9
lumbung.space/email/html/executeActions.ftl
Executable file
@ -0,0 +1,9 @@
|
||||
<#outputformat "plainText">
|
||||
<#assign requiredActionsText><#if requiredActions??><#list requiredActions><#items as reqActionItem>${msg("requiredAction.${reqActionItem}")}<#sep>, </#sep></#items></#list></#if></#assign>
|
||||
</#outputformat>
|
||||
|
||||
<html>
|
||||
<body>
|
||||
${kcSanitize(msg("executeActionsBodyHtml",link, linkExpiration, realmName, requiredActionsText, linkExpirationFormatter(linkExpiration)))?no_esc}
|
||||
</body>
|
||||
</html>
|
5
lumbung.space/email/html/identity-provider-link.ftl
Normal file
5
lumbung.space/email/html/identity-provider-link.ftl
Normal file
@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
${kcSanitize(msg("identityProviderLinkBodyHtml", identityProviderAlias, realmName, identityProviderContext.username, link, linkExpiration, linkExpirationFormatter(linkExpiration)))?no_esc}
|
||||
</body>
|
||||
</html>
|
5
lumbung.space/email/html/password-reset.ftl
Executable file
5
lumbung.space/email/html/password-reset.ftl
Executable file
@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
${kcSanitize(msg("passwordResetBodyHtml",link, linkExpiration, realmName, linkExpirationFormatter(linkExpiration)))?no_esc}
|
||||
</body>
|
||||
</html>
|
50
lumbung.space/email/messages/messages_en.properties
Executable file
50
lumbung.space/email/messages/messages_en.properties
Executable file
@ -0,0 +1,50 @@
|
||||
emailVerificationSubject=lumbung[dot]space: verify email
|
||||
emailVerificationBody=Someone has created a {2} account with this email address. If this was you, click the link below to verify your email address\n\n{0}\n\nThis link will expire within {3}.\n\nIf you didn''t create this account, just ignore this message.
|
||||
emailVerificationBodyHtml=<p>We''re excited to have you here! One more step to join! Please verify your account by pressing the link below.</p><p><a href="{0}">Link to e-mail address verification</a></p><p>Warmest regards, lumbung.space working group</p>
|
||||
emailTestSubject=[KEYCLOAK] - SMTP test message
|
||||
emailTestBody=This is a test message
|
||||
emailTestBodyHtml=<p>This is a test message</p>
|
||||
identityProviderLinkSubject=Link {0}
|
||||
identityProviderLinkBody=Someone wants to link your "{1}" account with "{0}" account of user {2} . If this was you, click the link below to link accounts\n\n{3}\n\nThis link will expire within {5}.\n\nIf you don''t want to link account, just ignore this message. If you link accounts, you will be able to login to {1} through {0}.
|
||||
identityProviderLinkBodyHtml=<p>Someone wants to link your <b>{1}</b> account with <b>{0}</b> account of user {2} . If this was you, click the link below to link accounts</p><p><a href="{3}">Link to confirm account linking</a></p><p>This link will expire within {5}.</p><p>If you don''t want to link account, just ignore this message. If you link accounts, you will be able to login to {1} through {0}.</p>
|
||||
passwordResetSubject=Reset password
|
||||
passwordResetBody=Someone just requested to change your {2} account''s credentials. If this was you, click on the link below to reset them.\n\n{0}\n\nThis link and code will expire within {3}.\n\nIf you don''t want to reset your credentials, just ignore this message and nothing will be changed.
|
||||
passwordResetBodyHtml=<p>Someone just requested to change your {2} account''s credentials. If this was you, click on the link below to reset them.</p><p><a href="{0}">Link to reset credentials</a></p><p>This link will expire within {3}.</p><p>If you don''t want to reset your credentials, just ignore this message and nothing will be changed.</p>
|
||||
executeActionsSubject=Update Your Account
|
||||
executeActionsBody=Your administrator has just requested that you update your {2} account by performing the following action(s): {3}. Click on the link below to start this process.\n\n{0}\n\nThis link will expire within {4}.\n\nIf you are unaware that your administrator has requested this, just ignore this message and nothing will be changed.
|
||||
executeActionsBodyHtml=<p>Your administrator has just requested that you update your {2} account by performing the following action(s): {3}. Click on the link below to start this process.</p><p><a href="{0}">Link to account update</a></p><p>This link will expire within {4}.</p><p>If you are unaware that your administrator has requested this, just ignore this message and nothing will be changed.</p>
|
||||
eventLoginErrorSubject=Login error
|
||||
eventLoginErrorBody=A failed login attempt was detected to your account on {0} from {1}. If this was not you, please contact an administrator.
|
||||
eventLoginErrorBodyHtml=<p>A failed login attempt was detected to your account on {0} from {1}. If this was not you, please contact an administrator.</p>
|
||||
eventRemoveTotpSubject=Remove OTP
|
||||
eventRemoveTotpBody=OTP was removed from your account on {0} from {1}. If this was not you, please contact an administrator.
|
||||
eventRemoveTotpBodyHtml=<p>OTP was removed from your account on {0} from {1}. If this was not you, please contact an administrator.</p>
|
||||
eventUpdatePasswordSubject=Update password
|
||||
eventUpdatePasswordBody=Your password was changed on {0} from {1}. If this was not you, please contact an administrator.
|
||||
eventUpdatePasswordBodyHtml=<p>Your password was changed on {0} from {1}. If this was not you, please contact an administrator.</p>
|
||||
eventUpdateTotpSubject=Update OTP
|
||||
eventUpdateTotpBody=OTP was updated for your account on {0} from {1}. If this was not you, please contact an administrator.
|
||||
eventUpdateTotpBodyHtml=<p>OTP was updated for your account on {0} from {1}. If this was not you, please contact an administrator.</p>
|
||||
|
||||
requiredAction.CONFIGURE_TOTP=Configure OTP
|
||||
requiredAction.terms_and_conditions=Terms and Conditions
|
||||
requiredAction.UPDATE_PASSWORD=Update Password
|
||||
requiredAction.UPDATE_PROFILE=Update Profile
|
||||
requiredAction.VERIFY_EMAIL=lumbung[dot]space: verify email
|
||||
|
||||
# units for link expiration timeout formatting
|
||||
linkExpirationFormatter.timePeriodUnit.seconds=seconds
|
||||
linkExpirationFormatter.timePeriodUnit.seconds.1=second
|
||||
linkExpirationFormatter.timePeriodUnit.minutes=minutes
|
||||
linkExpirationFormatter.timePeriodUnit.minutes.1=minute
|
||||
#for language which have more unit plural forms depending on the value (eg. Czech and other Slavic langs) you can override unit text for some other values like this:
|
||||
#linkExpirationFormatter.timePeriodUnit.minutes.2=minuty
|
||||
#linkExpirationFormatter.timePeriodUnit.minutes.3=minuty
|
||||
#linkExpirationFormatter.timePeriodUnit.minutes.4=minuty
|
||||
linkExpirationFormatter.timePeriodUnit.hours=hours
|
||||
linkExpirationFormatter.timePeriodUnit.hours.1=hour
|
||||
linkExpirationFormatter.timePeriodUnit.days=days
|
||||
linkExpirationFormatter.timePeriodUnit.days.1=day
|
||||
|
||||
emailVerificationBodyCode=Please verify your email address by entering in the following code.\n\n{0}\n\n.
|
||||
emailVerificationBodyCodeHtml=<p>Please verify your email address by entering in the following code.</p><p><b>{0}</b></p>
|
2
lumbung.space/email/text/email-test.ftl
Normal file
2
lumbung.space/email/text/email-test.ftl
Normal file
@ -0,0 +1,2 @@
|
||||
<#ftl output_format="plainText">
|
||||
${msg("emailTestBody", realmName)}
|
@ -0,0 +1,2 @@
|
||||
<#ftl output_format="plainText">
|
||||
${msg("emailVerificationBodyCode",code)}
|
2
lumbung.space/email/text/email-verification.ftl
Normal file
2
lumbung.space/email/text/email-verification.ftl
Normal file
@ -0,0 +1,2 @@
|
||||
<#ftl output_format="plainText">
|
||||
${msg("emailVerificationBody",link, linkExpiration, realmName, linkExpirationFormatter(linkExpiration))}
|
2
lumbung.space/email/text/event-login_error.ftl
Normal file
2
lumbung.space/email/text/event-login_error.ftl
Normal file
@ -0,0 +1,2 @@
|
||||
<#ftl output_format="plainText">
|
||||
${msg("eventLoginErrorBody",event.date,event.ipAddress)}
|
2
lumbung.space/email/text/event-remove_totp.ftl
Normal file
2
lumbung.space/email/text/event-remove_totp.ftl
Normal file
@ -0,0 +1,2 @@
|
||||
<#ftl output_format="plainText">
|
||||
${msg("eventRemoveTotpBody",event.date, event.ipAddress)}
|
2
lumbung.space/email/text/event-update_password.ftl
Normal file
2
lumbung.space/email/text/event-update_password.ftl
Normal file
@ -0,0 +1,2 @@
|
||||
<#ftl output_format="plainText">
|
||||
${msg("eventUpdatePasswordBody",event.date, event.ipAddress)}
|
2
lumbung.space/email/text/event-update_totp.ftl
Normal file
2
lumbung.space/email/text/event-update_totp.ftl
Normal file
@ -0,0 +1,2 @@
|
||||
<#ftl output_format="plainText">
|
||||
${msg("eventUpdateTotpBody",event.date, event.ipAddress)}
|
4
lumbung.space/email/text/executeActions.ftl
Executable file
4
lumbung.space/email/text/executeActions.ftl
Executable file
@ -0,0 +1,4 @@
|
||||
<#ftl output_format="plainText">
|
||||
<#assign requiredActionsText><#if requiredActions??><#list requiredActions><#items as reqActionItem>${msg("requiredAction.${reqActionItem}")}<#sep>, </#items></#list><#else></#if></#assign>
|
||||
|
||||
${msg("executeActionsBody",link, linkExpiration, realmName, requiredActionsText, linkExpirationFormatter(linkExpiration))}
|
2
lumbung.space/email/text/identity-provider-link.ftl
Normal file
2
lumbung.space/email/text/identity-provider-link.ftl
Normal file
@ -0,0 +1,2 @@
|
||||
<#ftl output_format="plainText">
|
||||
${msg("identityProviderLinkBody", identityProviderAlias, realmName, identityProviderContext.username, link, linkExpiration, linkExpirationFormatter(linkExpiration))}
|
2
lumbung.space/email/text/password-reset.ftl
Executable file
2
lumbung.space/email/text/password-reset.ftl
Executable file
@ -0,0 +1,2 @@
|
||||
<#ftl output_format="plainText">
|
||||
${msg("passwordResetBody",link, linkExpiration, realmName, linkExpirationFormatter(linkExpiration))}
|
7
lumbung.space/login/cli_splash.ftl
Normal file
7
lumbung.space/login/cli_splash.ftl
Normal file
@ -0,0 +1,7 @@
|
||||
_ __ _ _
|
||||
| |/ /___ _ _ ___| | ___ __ _| | __
|
||||
| ' // _ \ | | |/ __| |/ _ \ / _` | |/ /
|
||||
| . \ __/ |_| | (__| | (_) | (_| | <
|
||||
|_|\_\___|\__, |\___|_|\___/ \__,_|_|\_\
|
||||
|___/
|
||||
|
19
lumbung.space/login/code.ftl
Executable file
19
lumbung.space/login/code.ftl
Executable file
@ -0,0 +1,19 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout; section>
|
||||
<#if section = "header">
|
||||
<#if code.success>
|
||||
${msg("codeSuccessTitle")}
|
||||
<#else>
|
||||
${msg("codeErrorTitle", code.error)}
|
||||
</#if>
|
||||
<#elseif section = "form">
|
||||
<div id="kc-code">
|
||||
<#if code.success>
|
||||
<p>${msg("copyCodeInstruction")}</p>
|
||||
<input id="code" class="${properties.kcTextareaClass!}" value="${code.code}"/>
|
||||
<#else>
|
||||
<p id="error">${code.error}</p>
|
||||
</#if>
|
||||
</div>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
33
lumbung.space/login/delete-account-confirm.ftl
Normal file
33
lumbung.space/login/delete-account-confirm.ftl
Normal file
@ -0,0 +1,33 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout; section>
|
||||
|
||||
<#if section = "header">
|
||||
${msg("deleteAccountConfirm")}
|
||||
|
||||
<#elseif section = "form">
|
||||
|
||||
<form action="${url.loginAction}" class="form-vertical" method="post">
|
||||
|
||||
<div class="alert alert-warning" style="margin-top:0 !important;margin-bottom:30px !important">
|
||||
<span class="pficon pficon-warning-triangle-o"></span>
|
||||
${msg("irreversibleAction")}
|
||||
</div>
|
||||
|
||||
<p>${msg("deletingImplies")}</p>
|
||||
<ul style="color: #72767b;list-style: disc;list-style-position: inside;">
|
||||
<li>${msg("loggingOutImmediately")}</li>
|
||||
<li>${msg("errasingData")}</li>
|
||||
</ul>
|
||||
|
||||
<p class="delete-account-text">${msg("finalDeletionConfirmation")}</p>
|
||||
|
||||
<div id="kc-form-buttons">
|
||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doConfirmDelete")}" />
|
||||
<#if triggered_from_aia>
|
||||
<button class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" style="margin-left: calc(100% - 220px)" type="submit" name="cancel-aia" value="true" />${msg("doCancel")}</button>
|
||||
</#if>
|
||||
</div>
|
||||
</form>
|
||||
</#if>
|
||||
|
||||
</@layout.registrationLayout>
|
13
lumbung.space/login/error.ftl
Executable file
13
lumbung.space/login/error.ftl
Executable file
@ -0,0 +1,13 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout displayMessage=false; section>
|
||||
<#if section = "header">
|
||||
${msg("errorTitle")}
|
||||
<#elseif section = "form">
|
||||
<div id="kc-error-message">
|
||||
<p class="instruction">${message.summary?no_esc}</p>
|
||||
<#if client?? && client.baseUrl?has_content>
|
||||
<p><a id="backToApplication" href="${client.baseUrl}">${kcSanitize(msg("backToApplication"))?no_esc}</a></p>
|
||||
</#if>
|
||||
</div>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
24
lumbung.space/login/info.ftl
Executable file
24
lumbung.space/login/info.ftl
Executable file
@ -0,0 +1,24 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout displayMessage=false; section>
|
||||
<#if section = "header">
|
||||
<#if messageHeader??>
|
||||
${messageHeader}
|
||||
<#else>
|
||||
${message.summary}
|
||||
</#if>
|
||||
<#elseif section = "form">
|
||||
<div id="kc-info-message">
|
||||
<p class="instruction">${message.summary}<#if requiredActions??><#list requiredActions>: <b><#items as reqActionItem>${msg("requiredAction.${reqActionItem}")}<#sep>, </#items></b></#list><#else></#if></p>
|
||||
<#if skipLink??>
|
||||
<#else>
|
||||
<#if pageRedirectUri?has_content>
|
||||
<p><a href="${pageRedirectUri}">${kcSanitize(msg("backToApplication"))?no_esc}</a></p>
|
||||
<#elseif actionUri?has_content>
|
||||
<p><a href="${actionUri}">${kcSanitize(msg("proceedWithAction"))?no_esc}</a></p>
|
||||
<#elseif (client.baseUrl)?has_content>
|
||||
<p><a href="${client.baseUrl}">${kcSanitize(msg("backToApplication"))?no_esc}</a></p>
|
||||
</#if>
|
||||
</#if>
|
||||
</div>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
31
lumbung.space/login/login-config-totp-text.ftl
Executable file
31
lumbung.space/login/login-config-totp-text.ftl
Executable file
@ -0,0 +1,31 @@
|
||||
<#ftl output_format="plainText">
|
||||
${msg("loginTotpIntro")}
|
||||
|
||||
${msg("loginTotpStep1")}
|
||||
|
||||
<#list totp.policy.supportedApplications as app>
|
||||
* ${app}
|
||||
</#list>
|
||||
|
||||
${msg("loginTotpManualStep2")}
|
||||
|
||||
${totp.totpSecretEncoded}
|
||||
|
||||
|
||||
${msg("loginTotpManualStep3")}
|
||||
|
||||
- ${msg("loginTotpType")}: ${msg("loginTotp." + totp.policy.type)}
|
||||
- ${msg("loginTotpAlgorithm")}: ${totp.policy.getAlgorithmKey()}
|
||||
- ${msg("loginTotpDigits")}: ${totp.policy.digits}
|
||||
<#if totp.policy.type = "totp">
|
||||
- ${msg("loginTotpInterval")}: ${totp.policy.period}
|
||||
|
||||
<#elseif totp.policy.type = "hotp">
|
||||
- ${msg("loginTotpCounter")}: ${totp.policy.initialCounter}
|
||||
|
||||
</#if>
|
||||
|
||||
Enter in your one time password so we can verify you have installed it correctly.
|
||||
|
||||
|
||||
|
108
lumbung.space/login/login-config-totp.ftl
Executable file
108
lumbung.space/login/login-config-totp.ftl
Executable file
@ -0,0 +1,108 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout displayRequiredFields=false displayMessage=!messagesPerField.existsError('totp','userLabel'); section>
|
||||
|
||||
<#if section = "header">
|
||||
${msg("loginTotpTitle")}
|
||||
<#elseif section = "form">
|
||||
<ol id="kc-totp-settings">
|
||||
<li>
|
||||
<p>${msg("loginTotpStep1")}</p>
|
||||
|
||||
<ul id="kc-totp-supported-apps">
|
||||
<#list totp.policy.supportedApplications as app>
|
||||
<li>${app}</li>
|
||||
</#list>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<#if mode?? && mode = "manual">
|
||||
<li>
|
||||
<p>${msg("loginTotpManualStep2")}</p>
|
||||
<p><span id="kc-totp-secret-key">${totp.totpSecretEncoded}</span></p>
|
||||
<p><a href="${totp.qrUrl}" id="mode-barcode">${msg("loginTotpScanBarcode")}</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p>${msg("loginTotpManualStep3")}</p>
|
||||
<p>
|
||||
<ul>
|
||||
<li id="kc-totp-type">${msg("loginTotpType")}: ${msg("loginTotp." + totp.policy.type)}</li>
|
||||
<li id="kc-totp-algorithm">${msg("loginTotpAlgorithm")}: ${totp.policy.getAlgorithmKey()}</li>
|
||||
<li id="kc-totp-digits">${msg("loginTotpDigits")}: ${totp.policy.digits}</li>
|
||||
<#if totp.policy.type = "totp">
|
||||
<li id="kc-totp-period">${msg("loginTotpInterval")}: ${totp.policy.period}</li>
|
||||
<#elseif totp.policy.type = "hotp">
|
||||
<li id="kc-totp-counter">${msg("loginTotpCounter")}: ${totp.policy.initialCounter}</li>
|
||||
</#if>
|
||||
</ul>
|
||||
</p>
|
||||
</li>
|
||||
<#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>
|
||||
</li>
|
||||
</#if>
|
||||
<li>
|
||||
<p>${msg("loginTotpStep3")}</p>
|
||||
<p>${msg("loginTotpStep3DeviceName")}</p>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<form action="${url.loginAction}" class="${properties.kcFormClass!}" id="kc-totp-settings-form" method="post">
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<div class="${properties.kcInputWrapperClass!}">
|
||||
<label for="totp" class="control-label">${msg("authenticatorCode")}</label> <span class="required">*</span>
|
||||
</div>
|
||||
<div class="${properties.kcInputWrapperClass!}">
|
||||
<input type="text" id="totp" name="totp" autocomplete="off" class="${properties.kcInputClass!}"
|
||||
aria-invalid="<#if messagesPerField.existsError('totp')>true</#if>"
|
||||
/>
|
||||
|
||||
<#if messagesPerField.existsError('totp')>
|
||||
<span id="input-error-otp-code" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('totp'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
|
||||
</div>
|
||||
<input type="hidden" id="totpSecret" name="totpSecret" value="${totp.totpSecret}" />
|
||||
<#if mode??><input type="hidden" id="mode" name="mode" value="${mode}"/></#if>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<div class="${properties.kcInputWrapperClass!}">
|
||||
<label for="userLabel" class="control-label">${msg("loginTotpDeviceName")}</label> <#if totp.otpCredentials?size gte 1><span class="required">*</span></#if>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcInputWrapperClass!}">
|
||||
<input type="text" class="${properties.kcInputClass!}" id="userLabel" name="userLabel" autocomplete="off"
|
||||
aria-invalid="<#if messagesPerField.existsError('userLabel')>true</#if>"
|
||||
/>
|
||||
|
||||
<#if messagesPerField.existsError('userLabel')>
|
||||
<span id="input-error-otp-label" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('userLabel'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<#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>
|
||||
</form>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
13
lumbung.space/login/login-idp-link-confirm.ftl
Normal file
13
lumbung.space/login/login-idp-link-confirm.ftl
Normal file
@ -0,0 +1,13 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout; section>
|
||||
<#if section = "header">
|
||||
${msg("confirmLinkIdpTitle")}
|
||||
<#elseif section = "form">
|
||||
<form id="kc-register-form" action="${url.loginAction}" method="post">
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" name="submitAction" id="updateProfile" value="updateProfile">${msg("confirmLinkIdpReviewProfile")}</button>
|
||||
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" name="submitAction" id="linkAccount" value="linkAccount">${msg("confirmLinkIdpContinue", idpDisplayName)}</button>
|
||||
</div>
|
||||
</form>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
16
lumbung.space/login/login-idp-link-email.ftl
Normal file
16
lumbung.space/login/login-idp-link-email.ftl
Normal file
@ -0,0 +1,16 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout; section>
|
||||
<#if section = "header">
|
||||
${msg("emailLinkIdpTitle", idpDisplayName)}
|
||||
<#elseif section = "form">
|
||||
<p id="instruction1" class="instruction">
|
||||
${msg("emailLinkIdp1", idpDisplayName, brokerContext.username, realm.displayName)}
|
||||
</p>
|
||||
<p id="instruction2" class="instruction">
|
||||
${msg("emailLinkIdp2")} <a href="${url.loginAction}">${msg("doClickHere")}</a> ${msg("emailLinkIdp3")}
|
||||
</p>
|
||||
<p id="instruction3" class="instruction">
|
||||
${msg("emailLinkIdp4")} <a href="${url.loginAction}">${msg("doClickHere")}</a> ${msg("emailLinkIdp5")}
|
||||
</p>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
41
lumbung.space/login/login-oauth-grant.ftl
Executable file
41
lumbung.space/login/login-oauth-grant.ftl
Executable file
@ -0,0 +1,41 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout bodyClass="oauth"; section>
|
||||
<#if section = "header">
|
||||
<#if client.name?has_content>
|
||||
${msg("oauthGrantTitle",advancedMsg(client.name))}
|
||||
<#else>
|
||||
${msg("oauthGrantTitle",client.clientId)}
|
||||
</#if>
|
||||
<#elseif section = "form">
|
||||
<div id="kc-oauth" class="content-area">
|
||||
<h3>${msg("oauthGrantRequest")}</h3>
|
||||
<ul>
|
||||
<#if oauth.clientScopesRequested??>
|
||||
<#list oauth.clientScopesRequested as clientScope>
|
||||
<li>
|
||||
<span>${advancedMsg(clientScope.consentScreenText)}</span>
|
||||
</li>
|
||||
</#list>
|
||||
</#if>
|
||||
</ul>
|
||||
|
||||
<form class="form-actions" action="${url.oauthAction}" method="POST">
|
||||
<input type="hidden" name="code" value="${oauth.code}">
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<div id="kc-form-options">
|
||||
<div class="${properties.kcFormOptionsWrapperClass!}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="kc-form-buttons">
|
||||
<div class="${properties.kcFormButtonsWrapperClass!}">
|
||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="accept" id="kc-login" type="submit" value="${msg("doYes")}"/>
|
||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" name="cancel" id="kc-cancel" type="submit" value="${msg("doNo")}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
31
lumbung.space/login/login-oauth2-device-verify-user-code.ftl
Normal file
31
lumbung.space/login/login-oauth2-device-verify-user-code.ftl
Normal file
@ -0,0 +1,31 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout; section>
|
||||
<#if section = "header">
|
||||
${msg("oauth2DeviceVerificationTitle")}
|
||||
<#elseif section = "form">
|
||||
<form id="kc-user-verify-device-user-code-form" class="${properties.kcFormClass!}" action="${url.oauth2DeviceVerificationAction}" method="post">
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<div class="${properties.kcLabelWrapperClass!}">
|
||||
<label for="device-user-code" class="${properties.kcLabelClass!}">${msg("verifyOAuth2DeviceUserCode")}</label>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcInputWrapperClass!}">
|
||||
<input id="device-user-code" name="device_user_code" autocomplete="off" type="text" class="${properties.kcInputClass!}" autofocus />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
||||
<div class="${properties.kcFormOptionsWrapperClass!}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
|
||||
<div class="${properties.kcFormButtonsWrapperClass!}">
|
||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
50
lumbung.space/login/login-otp.ftl
Executable file
50
lumbung.space/login/login-otp.ftl
Executable file
@ -0,0 +1,50 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('totp'); section>
|
||||
<#if section="header">
|
||||
${msg("doLogIn")}
|
||||
<#elseif section="form">
|
||||
<form id="kc-otp-login-form" class="${properties.kcFormClass!}" action="${url.loginAction}"
|
||||
method="post">
|
||||
<#if otpLogin.userOtpCredentials?size gt 1>
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<div class="${properties.kcInputWrapperClass!}">
|
||||
<#list otpLogin.userOtpCredentials as otpCredential>
|
||||
<input id="kc-otp-credential-${otpCredential?index}" class="${properties.kcLoginOTPListInputClass!}" type="radio" name="selectedCredentialId" value="${otpCredential.id}" <#if otpCredential.id == otpLogin.selectedCredentialId>checked="checked"</#if>>
|
||||
<label for="kc-otp-credential-${otpCredential?index}" class="${properties.kcLoginOTPListClass!}" tabindex="${otpCredential?index}">
|
||||
<span class="${properties.kcLoginOTPListItemHeaderClass!}">
|
||||
<span class="${properties.kcLoginOTPListItemIconBodyClass!}">
|
||||
<i class="${properties.kcLoginOTPListItemIconClass!}" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span class="${properties.kcLoginOTPListItemTitleClass!}">${otpCredential.userLabel}</span>
|
||||
</span>
|
||||
</label>
|
||||
</#list>
|
||||
</div>
|
||||
</div>
|
||||
</#if>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<div class="${properties.kcLabelWrapperClass!}">
|
||||
<label for="otp" class="${properties.kcLabelClass!}">${msg("loginOtpOneTime")}</label>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcInputWrapperClass!}">
|
||||
<input id="otp" name="otp" autocomplete="off" type="text" class="${properties.kcInputClass!}"
|
||||
autofocus aria-invalid="<#if messagesPerField.existsError('totp')>true</#if>"/>
|
||||
|
||||
<#if messagesPerField.existsError('totp')>
|
||||
<span id="input-error-otp-code" class="${properties.kcInputErrorMessageClass!}"
|
||||
aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('totp'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<input
|
||||
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
|
||||
name="login" id="kc-login" type="submit" value="${msg("doLogIn")}" />
|
||||
</form>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
11
lumbung.space/login/login-page-expired.ftl
Normal file
11
lumbung.space/login/login-page-expired.ftl
Normal file
@ -0,0 +1,11 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout; section>
|
||||
<#if section = "header">
|
||||
${msg("pageExpiredTitle")}
|
||||
<#elseif section = "form">
|
||||
<p id="instruction1" class="instruction">
|
||||
${msg("pageExpiredMsg1")} <a id="loginRestartLink" href="${url.loginRestartFlowUrl}">${msg("doClickHere")}</a> .<br/>
|
||||
${msg("pageExpiredMsg2")} <a id="loginContinueLink" href="${url.loginAction}">${msg("doClickHere")}</a> .
|
||||
</p>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
43
lumbung.space/login/login-password.ftl
Executable file
43
lumbung.space/login/login-password.ftl
Executable file
@ -0,0 +1,43 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('password'); section>
|
||||
<#if section = "header">
|
||||
${msg("doLogIn")}
|
||||
<#elseif section = "form">
|
||||
<div id="kc-form">
|
||||
<div id="kc-form-wrapper">
|
||||
<form id="kc-form-login" onsubmit="login.disabled = true; return true;" action="${url.loginAction}"
|
||||
method="post">
|
||||
<div class="${properties.kcFormGroupClass!} no-bottom-margin">
|
||||
<hr/>
|
||||
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label>
|
||||
<input tabindex="2" id="password" class="${properties.kcInputClass!}" name="password"
|
||||
type="password" autocomplete="on"
|
||||
aria-invalid="<#if messagesPerField.existsError('password')>true</#if>"
|
||||
/>
|
||||
<#if messagesPerField.existsError('password')>
|
||||
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('password'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!} ${properties.kcFormSettingClass!}">
|
||||
<div id="kc-form-options">
|
||||
</div>
|
||||
<div class="${properties.kcFormOptionsWrapperClass!}">
|
||||
<#if realm.resetPasswordAllowed>
|
||||
<span><a tabindex="5"
|
||||
href="${url.loginResetCredentialsUrl}">${msg("doForgotPassword")}</a></span>
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="kc-form-buttons" class="${properties.kcFormGroupClass!}">
|
||||
<input tabindex="4" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" name="login" id="kc-login" type="submit" value="${msg("doLogIn")}"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</#if>
|
||||
|
||||
</@layout.registrationLayout>
|
36
lumbung.space/login/login-reset-password.ftl
Executable file
36
lumbung.space/login/login-reset-password.ftl
Executable file
@ -0,0 +1,36 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout displayInfo=true displayMessage=!messagesPerField.existsError('username'); section>
|
||||
<#if section = "header">
|
||||
${msg("emailForgotTitle")}
|
||||
<#elseif section = "form">
|
||||
<form id="kc-reset-password-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<label for="username" class="${properties.kcLabelClass!}"><#if !realm.loginWithEmailAllowed>${msg("username")}<#elseif !realm.registrationEmailAsUsername>${msg("usernameOrEmail")}<#else>${msg("email")}</#if></label>
|
||||
<#if auth?has_content && auth.showUsername()>
|
||||
<input type="text" id="username" name="username" class="${properties.kcInputClass!}" autofocus value="${auth.attemptedUsername}" aria-invalid="<#if messagesPerField.existsError('username')>true</#if>"/>
|
||||
<#else>
|
||||
<input type="text" id="username" name="username" class="${properties.kcInputClass!}" autofocus aria-invalid="<#if messagesPerField.existsError('username')>true</#if>"/>
|
||||
</#if>
|
||||
|
||||
<#if messagesPerField.existsError('username')>
|
||||
<span id="input-error-username" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('username'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
</div>
|
||||
<div class="${properties.kcFormGroupClass!} ${properties.kcFormSettingClass!}">
|
||||
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
||||
<div class="${properties.kcFormOptionsWrapperClass!}">
|
||||
<span><a href="${url.loginUrl}">${kcSanitize(msg("backToLogin"))?no_esc}</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
|
||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<#elseif section = "info" >
|
||||
${msg("emailInstruction")}
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
61
lumbung.space/login/login-update-password.ftl
Executable file
61
lumbung.space/login/login-update-password.ftl
Executable file
@ -0,0 +1,61 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('password','password-confirm'); section>
|
||||
<#if section = "header">
|
||||
${msg("updatePasswordTitle")}
|
||||
<#elseif section = "form">
|
||||
<form id="kc-passwd-update-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
||||
<input type="text" id="username" name="username" value="${username}" autocomplete="username"
|
||||
readonly="readonly" style="display:none;"/>
|
||||
<input type="password" id="password" name="password" autocomplete="current-password" style="display:none;"/>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<label for="password-new" class="${properties.kcLabelClass!}">${msg("passwordNew")}</label>
|
||||
<input type="password" id="password-new" name="password-new" class="${properties.kcInputClass!}"
|
||||
autofocus autocomplete="new-password"
|
||||
aria-invalid="<#if messagesPerField.existsError('password','password-confirm')>true</#if>"
|
||||
|
||||
<#if messagesPerField.existsError('password')>
|
||||
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('password'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<label for="password-confirm" class="${properties.kcLabelClass!}">${msg("passwordConfirm")}</label>
|
||||
<input type="password" id="password-confirm" name="password-confirm"
|
||||
class="${properties.kcInputClass!}"
|
||||
autocomplete="new-password"
|
||||
aria-invalid="<#if messagesPerField.existsError('password-confirm')>true</#if>"
|
||||
/>
|
||||
|
||||
<#if messagesPerField.existsError('password-confirm')>
|
||||
<span id="input-error-password-confirm" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('password-confirm'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
||||
<div class="${properties.kcFormOptionsWrapperClass!}">
|
||||
<#if isAppInitiatedAction??>
|
||||
<div class="checkbox">
|
||||
<label><input type="checkbox" id="logout-sessions" name="logout-sessions" value="on" checked> ${msg("logoutOtherSessions")}</label>
|
||||
</div>
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<#if isAppInitiatedAction??>
|
||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}" />
|
||||
<button class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" type="submit" name="cancel-aia" value="true" />${msg("doCancel")}</button>
|
||||
<#else>
|
||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}" />
|
||||
</#if>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
79
lumbung.space/login/login-update-profile.ftl
Executable file
79
lumbung.space/login/login-update-profile.ftl
Executable file
@ -0,0 +1,79 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('username','email','firstName','lastName'); section>
|
||||
<#if section = "header">
|
||||
${msg("loginProfileTitle")}
|
||||
<#elseif section = "form">
|
||||
<form id="kc-update-profile-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
||||
<#if user.editUsernameAllowed>
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<label for="username" class="${properties.kcLabelClass!}">${msg("username")}</label>
|
||||
<input type="text" id="username" name="username" value="${(user.username!'')}"
|
||||
class="${properties.kcInputClass!}"
|
||||
aria-invalid="<#if messagesPerField.existsError('username')>true</#if>"
|
||||
/>
|
||||
|
||||
<#if messagesPerField.existsError('username')>
|
||||
<span id="input-error-username" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('username'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
</div>
|
||||
</#if>
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<label for="email" class="${properties.kcLabelClass!}">${msg("email")}</label>
|
||||
<input type="text" id="email" name="email" value="${(user.email!'')}"
|
||||
class="${properties.kcInputClass!}"
|
||||
aria-invalid="<#if messagesPerField.existsError('email')>true</#if>"
|
||||
/>
|
||||
|
||||
<#if messagesPerField.existsError('email')>
|
||||
<span id="input-error-email" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('email'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<label for="firstName" class="${properties.kcLabelClass!}">${msg("firstName")}</label>
|
||||
<input type="text" id="firstName" name="firstName" value="${(user.firstName!'')}"
|
||||
class="${properties.kcInputClass!}"
|
||||
aria-invalid="<#if messagesPerField.existsError('firstName')>true</#if>"
|
||||
/>
|
||||
|
||||
<#if messagesPerField.existsError('firstName')>
|
||||
<span id="input-error-firstname" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('firstName'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<label for="lastName" class="${properties.kcLabelClass!}">${msg("lastName")}</label>
|
||||
<input type="text" id="lastName" name="lastName" value="${(user.lastName!'')}"
|
||||
class="${properties.kcInputClass!}"
|
||||
aria-invalid="<#if messagesPerField.existsError('lastName')>true</#if>"
|
||||
/>
|
||||
|
||||
<#if messagesPerField.existsError('lastName')>
|
||||
<span id="input-error-lastname" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('lastName'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
||||
<div class="${properties.kcFormOptionsWrapperClass!}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<#if isAppInitiatedAction??>
|
||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}" />
|
||||
<button class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" type="submit" name="cancel-aia" value="true" />${msg("doCancel")}</button>
|
||||
<#else>
|
||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}" />
|
||||
</#if>
|
||||
</div>
|
||||
</form>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
92
lumbung.space/login/login-username.ftl
Executable file
92
lumbung.space/login/login-username.ftl
Executable file
@ -0,0 +1,92 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('username') displayInfo=(realm.password && realm.registrationAllowed && !registrationDisabled??); section>
|
||||
<#if section = "header">
|
||||
${msg("loginAccountTitle")}
|
||||
<#elseif section = "form">
|
||||
<div id="kc-form">
|
||||
<div id="kc-form-wrapper">
|
||||
<#if realm.password>
|
||||
<form id="kc-form-login" onsubmit="login.disabled = true; return true;" action="${url.loginAction}"
|
||||
method="post">
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<label for="username"
|
||||
class="${properties.kcLabelClass!}"><#if !realm.loginWithEmailAllowed>${msg("username")}<#elseif !realm.registrationEmailAsUsername>${msg("usernameOrEmail")}<#else>${msg("email")}</#if></label>
|
||||
|
||||
<#if usernameEditDisabled??>
|
||||
<input tabindex="1" id="username"
|
||||
aria-invalid="<#if message?has_content && message.type = 'error'>true</#if>"
|
||||
class="${properties.kcInputClass!}" name="username"
|
||||
value="${(login.username!'')}"
|
||||
type="text" disabled/>
|
||||
<#else>
|
||||
<input tabindex="1" id="username"
|
||||
aria-invalid="<#if messagesPerField.existsError('username')>true</#if>"
|
||||
class="${properties.kcInputClass!}" name="username"
|
||||
value="${(login.username!'')}"
|
||||
type="text" autofocus autocomplete="off"/>
|
||||
</#if>
|
||||
|
||||
<#if messagesPerField.existsError('username')>
|
||||
<span id="input-error-username" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('username'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!} ${properties.kcFormSettingClass!}">
|
||||
<div id="kc-form-options">
|
||||
<#if realm.rememberMe && !usernameEditDisabled??>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<#if login.rememberMe??>
|
||||
<input tabindex="3" id="rememberMe" name="rememberMe" type="checkbox"
|
||||
checked> ${msg("rememberMe")}
|
||||
<#else>
|
||||
<input tabindex="3" id="rememberMe" name="rememberMe"
|
||||
type="checkbox"> ${msg("rememberMe")}
|
||||
</#if>
|
||||
</label>
|
||||
</div>
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="kc-form-buttons" class="${properties.kcFormGroupClass!}">
|
||||
<input tabindex="4"
|
||||
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
|
||||
name="login" id="kc-login" type="submit" value="${msg("doLogIn")}"/>
|
||||
</div>
|
||||
</form>
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
<#if realm.password && social.providers??>
|
||||
<div id="kc-social-providers" class="${properties.kcFormSocialAccountSectionClass!}">
|
||||
<hr/>
|
||||
<h4>${msg("identity-provider-login-label")}</h4>
|
||||
|
||||
<ul class="${properties.kcFormSocialAccountListClass!} <#if social.providers?size gt 3>${properties.kcFormSocialAccountListGridClass!}</#if>">
|
||||
<#list social.providers as p>
|
||||
<a id="social-${p.alias}" class="${properties.kcFormSocialAccountListButtonClass!} <#if social.providers?size gt 3>${properties.kcFormSocialAccountGridItem!}</#if>"
|
||||
type="button" href="${p.loginUrl}">
|
||||
<#if p.iconClasses?has_content>
|
||||
<i class="${properties.kcCommonLogoIdP!} ${p.iconClasses!}" aria-hidden="true"></i>
|
||||
<span class="${properties.kcFormSocialAccountNameClass!} kc-social-icon-text">${p.displayName}</span>
|
||||
<#else>
|
||||
<span class="${properties.kcFormSocialAccountNameClass!}">${p.displayName}</span>
|
||||
</#if>
|
||||
</a>
|
||||
</#list>
|
||||
</ul>
|
||||
</div>
|
||||
</#if>
|
||||
|
||||
<#elseif section = "info" >
|
||||
<#if realm.password && realm.registrationAllowed && !registrationDisabled??>
|
||||
<div id="kc-registration">
|
||||
<span>${msg("noAccount")} <a tabindex="6" href="${url.registrationUrl}">${msg("doRegister")}</a></span>
|
||||
</div>
|
||||
</#if>
|
||||
</#if>
|
||||
|
||||
</@layout.registrationLayout>
|
2
lumbung.space/login/login-verify-email-code-text.ftl
Normal file
2
lumbung.space/login/login-verify-email-code-text.ftl
Normal file
@ -0,0 +1,2 @@
|
||||
<#ftl output_format="plainText">
|
||||
${msg("console-verify-email",email, code)}
|
14
lumbung.space/login/login-verify-email.ftl
Executable file
14
lumbung.space/login/login-verify-email.ftl
Executable file
@ -0,0 +1,14 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout displayInfo=true; section>
|
||||
<#if section = "header">
|
||||
${msg("emailVerifyTitle")}
|
||||
<#elseif section = "form">
|
||||
<p class="instruction">${msg("emailVerifyInstruction1")}</p>
|
||||
<#elseif section = "info">
|
||||
<p class="instruction">
|
||||
${msg("emailVerifyInstruction2")}
|
||||
<br/>
|
||||
<a href="${url.loginAction}">${msg("doClickHere")}</a> ${msg("emailVerifyInstruction3")}
|
||||
</p>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
55
lumbung.space/login/login-x509-info.ftl
Normal file
55
lumbung.space/login/login-x509-info.ftl
Normal file
@ -0,0 +1,55 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout; section>
|
||||
<#if section = "header">
|
||||
${msg("doLogIn")}
|
||||
<#elseif section = "form">
|
||||
|
||||
<form id="kc-x509-login-info" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
|
||||
<div class="${properties.kcLabelWrapperClass!}">
|
||||
<label for="certificate_subjectDN" class="${properties.kcLabelClass!}">${msg("clientCertificate")}</label>
|
||||
</div>
|
||||
<#if x509.formData.subjectDN??>
|
||||
<div class="${properties.kcLabelWrapperClass!}">
|
||||
<label id="certificate_subjectDN" class="${properties.kcLabelClass!}">${(x509.formData.subjectDN!"")}</label>
|
||||
</div>
|
||||
<#else>
|
||||
<div class="${properties.kcLabelWrapperClass!}">
|
||||
<label id="certificate_subjectDN" class="${properties.kcLabelClass!}">${msg("noCertificate")}</label>
|
||||
</div>
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
|
||||
<#if x509.formData.isUserEnabled??>
|
||||
<div class="${properties.kcLabelWrapperClass!}">
|
||||
<label for="username" class="${properties.kcLabelClass!}">${msg("doX509Login")}</label>
|
||||
</div>
|
||||
<div class="${properties.kcLabelWrapperClass!}">
|
||||
<label id="username" class="${properties.kcLabelClass!}">${(x509.formData.username!'')}</label>
|
||||
</div>
|
||||
</#if>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
||||
<div class="${properties.kcFormOptionsWrapperClass!}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
|
||||
<div class="${properties.kcFormButtonsWrapperClass!}">
|
||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="login" id="kc-login" type="submit" value="${msg("doContinue")}"/>
|
||||
<#if x509.formData.isUserEnabled??>
|
||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" name="cancel" id="kc-cancel" type="submit" value="${msg("doIgnore")}"/>
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</#if>
|
||||
|
||||
</@layout.registrationLayout>
|
119
lumbung.space/login/login.ftl
Executable file
119
lumbung.space/login/login.ftl
Executable file
File diff suppressed because one or more lines are too long
415
lumbung.space/login/messages/messages_en.properties
Executable file
415
lumbung.space/login/messages/messages_en.properties
Executable file
@ -0,0 +1,415 @@
|
||||
doLogIn=sign in
|
||||
doRegister=Register
|
||||
doCancel=Cancel
|
||||
doSubmit=Submit
|
||||
doBack=Back
|
||||
doYes=Yes
|
||||
doNo=No
|
||||
doContinue=Continue
|
||||
doIgnore=Ignore
|
||||
doAccept=Accept
|
||||
doDecline=Decline
|
||||
doForgotPassword=Forgot Password?
|
||||
doClickHere=Click here
|
||||
doImpersonate=Impersonate
|
||||
doTryAgain=Try again
|
||||
doTryAnotherWay=Try Another Way
|
||||
doConfirmDelete=Confirm deletion
|
||||
errorDeletingAccount=Error happened while deleting account
|
||||
deletingAccountForbidden=You do not have enough permissions to delete your own account, contact admin.
|
||||
kerberosNotConfigured=Kerberos Not Configured
|
||||
kerberosNotConfiguredTitle=Kerberos Not Configured
|
||||
bypassKerberosDetail=Either you are not logged in by Kerberos or your browser is not set up for Kerberos login. Please click continue to login in through other means
|
||||
kerberosNotSetUp=Kerberos is not set up. You cannot login.
|
||||
registerTitle=Register
|
||||
loginAccountTitle= sign in to
|
||||
loginTitle=Sign in to {0}
|
||||
loginTitleHtml={0}
|
||||
impersonateTitle={0} Impersonate User
|
||||
impersonateTitleHtml=<strong>{0}</strong> Impersonate User
|
||||
realmChoice=Realm
|
||||
unknownUser=Unknown user
|
||||
loginTotpTitle=Mobile Authenticator Setup
|
||||
loginProfileTitle=Update Account Information
|
||||
loginTimeout=Your login attempt timed out. Login will start from the beginning.
|
||||
oauthGrantTitle=Grant Access to {0}
|
||||
oauthGrantTitleHtml={0}
|
||||
errorTitle=We are sorry...
|
||||
errorTitleHtml=We are <strong>sorry</strong> ...
|
||||
emailVerifyTitle=Email verification
|
||||
emailForgotTitle=Forgot Your Password?
|
||||
updatePasswordTitle=Update password
|
||||
codeSuccessTitle=Success code
|
||||
codeErrorTitle=Error code\: {0}
|
||||
displayUnsupported=Requested display type unsupported
|
||||
browserRequired=Browser required to login
|
||||
browserContinue=Browser required to complete login
|
||||
browserContinuePrompt=Open browser and continue login? [y/n]:
|
||||
browserContinueAnswer=y
|
||||
|
||||
|
||||
termsTitle=Terms and Conditions
|
||||
termsText=<p>Terms and conditions to be defined</p>
|
||||
termsPlainText=Terms and conditions to be defined.
|
||||
|
||||
recaptchaFailed=Invalid Recaptcha
|
||||
recaptchaNotConfigured=Recaptcha is required, but not configured
|
||||
consentDenied=Consent denied.
|
||||
|
||||
noAccount=New user?
|
||||
username=Username
|
||||
usernameOrEmail=username or email
|
||||
firstName=First name
|
||||
givenName=Given name
|
||||
fullName=Full name
|
||||
lastName=Last name
|
||||
familyName=Family name
|
||||
email=Email
|
||||
password=password
|
||||
passwordConfirm=Confirm password
|
||||
passwordNew=New Password
|
||||
passwordNewConfirm=New Password confirmation
|
||||
rememberMe=Remember me
|
||||
authenticatorCode=One-time code
|
||||
address=Address
|
||||
street=Street
|
||||
locality=City or Locality
|
||||
region=State, Province, or Region
|
||||
postal_code=Zip or Postal code
|
||||
country=Country
|
||||
emailVerified=Email verified
|
||||
website=Web page
|
||||
phoneNumber=Phone number
|
||||
phoneNumberVerified=Phone number verified
|
||||
gender=Gender
|
||||
birthday=Birthdate
|
||||
zoneinfo=Time zone
|
||||
gssDelegationCredential=GSS Delegation Credential
|
||||
logoutOtherSessions=Sign out from other devices
|
||||
|
||||
profileScopeConsentText=User profile
|
||||
emailScopeConsentText=Email address
|
||||
addressScopeConsentText=Address
|
||||
phoneScopeConsentText=Phone number
|
||||
offlineAccessScopeConsentText=Offline Access
|
||||
samlRoleListScopeConsentText=My Roles
|
||||
rolesScopeConsentText=User roles
|
||||
|
||||
restartLoginTooltip=Restart login
|
||||
|
||||
loginTotpIntro=You need to set up a One Time Password generator to access this account
|
||||
loginTotpStep1=Install one of the following applications on your mobile:
|
||||
loginTotpStep2=Open the application and scan the barcode:
|
||||
loginTotpStep3=Enter the one-time code provided by the application and click Submit to finish the setup.
|
||||
loginTotpStep3DeviceName=Provide a Device Name to help you manage your OTP devices.
|
||||
loginTotpManualStep2=Open the application and enter the key:
|
||||
loginTotpManualStep3=Use the following configuration values if the application allows setting them:
|
||||
loginTotpUnableToScan=Unable to scan?
|
||||
loginTotpScanBarcode=Scan barcode?
|
||||
loginCredential=Credential
|
||||
loginOtpOneTime=One-time code
|
||||
loginTotpType=Type
|
||||
loginTotpAlgorithm=Algorithm
|
||||
loginTotpDigits=Digits
|
||||
loginTotpInterval=Interval
|
||||
loginTotpCounter=Counter
|
||||
loginTotpDeviceName=Device Name
|
||||
|
||||
loginTotp.totp=Time-based
|
||||
loginTotp.hotp=Counter-based
|
||||
|
||||
loginChooseAuthenticator=Select login method
|
||||
|
||||
oauthGrantRequest=Do you grant these access privileges?
|
||||
inResource=in
|
||||
|
||||
oauth2DeviceVerificationTitle=Device Login
|
||||
verifyOAuth2DeviceUserCode=Enter the code provided by your device and click Submit
|
||||
oauth2DeviceInvalidUserCodeMessage=Invalid code, please try again.
|
||||
oauth2DeviceExpiredUserCodeMessage=The code has expired. Please go back to your device and try connecting again.
|
||||
oauth2DeviceVerificationCompleteHeader=Device Login Successful
|
||||
oauth2DeviceVerificationCompleteMessage=You may close this browser window and go back to your device.
|
||||
oauth2DeviceVerificationFailedHeader=Device Login Failed
|
||||
oauth2DeviceVerificationFailedMessage=You may close this browser window and go back to your device and try connecting again.
|
||||
oauth2DeviceConsentDeniedMessage=Consent denied for connecting the device.
|
||||
oauth2DeviceAuthorizationGrantDisabledMessage=Client is not allowed to initiate OAuth 2.0 Device Authorization Grant. The flow is disabled for the client.
|
||||
|
||||
emailVerifyInstruction1=An email with instructions to verify your email address has been sent to you.
|
||||
emailVerifyInstruction2=Haven''t received a verification code in your email?
|
||||
emailVerifyInstruction3=to re-send the email. Don''t forget to check your spam folder! Feel free to mail contact@lumbung.space if you are still having problems, we''re happy to help out.
|
||||
|
||||
emailLinkIdpTitle=Link {0}
|
||||
emailLinkIdp1=An email with instructions to link {0} account {1} with your {2} account has been sent to you.
|
||||
emailLinkIdp2=Haven''t received a verification code in your email?
|
||||
emailLinkIdp3=to re-send the email.
|
||||
emailLinkIdp4=If you already verified the email in different browser
|
||||
emailLinkIdp5=to continue.
|
||||
|
||||
backToLogin=« Back to Login
|
||||
|
||||
emailInstruction=Enter your username or email address and we will send you instructions on how to create a new password.
|
||||
|
||||
copyCodeInstruction=Please copy this code and paste it into your application:
|
||||
|
||||
pageExpiredTitle=Page has expired
|
||||
pageExpiredMsg1=To restart the login process
|
||||
pageExpiredMsg2=To continue the login process
|
||||
|
||||
personalInfo=Personal Info:
|
||||
role_admin=Admin
|
||||
role_realm-admin=Realm Admin
|
||||
role_create-realm=Create realm
|
||||
role_create-client=Create client
|
||||
role_view-realm=View realm
|
||||
role_view-users=View users
|
||||
role_view-applications=View applications
|
||||
role_view-clients=View clients
|
||||
role_view-events=View events
|
||||
role_view-identity-providers=View identity providers
|
||||
role_manage-realm=Manage realm
|
||||
role_manage-users=Manage users
|
||||
role_manage-applications=Manage applications
|
||||
role_manage-identity-providers=Manage identity providers
|
||||
role_manage-clients=Manage clients
|
||||
role_manage-events=Manage events
|
||||
role_view-profile=View profile
|
||||
role_manage-account=Manage account
|
||||
role_manage-account-links=Manage account links
|
||||
role_read-token=Read token
|
||||
role_offline-access=Offline access
|
||||
client_account=Account
|
||||
client_account-console=Account Console
|
||||
client_security-admin-console=Security Admin Console
|
||||
client_admin-cli=Admin CLI
|
||||
client_realm-management=Realm Management
|
||||
client_broker=Broker
|
||||
|
||||
requiredFields=Required fields
|
||||
|
||||
invalidUserMessage=Invalid username or password.
|
||||
invalidUsernameMessage=Invalid username.
|
||||
invalidUsernameOrEmailMessage=Invalid username or email.
|
||||
invalidPasswordMessage=Invalid password.
|
||||
invalidEmailMessage=Invalid email address.
|
||||
accountDisabledMessage=Account is disabled, contact your administrator.
|
||||
accountTemporarilyDisabledMessage=Account is temporarily disabled; contact your administrator or retry later.
|
||||
expiredCodeMessage=Login timeout. Please sign in again.
|
||||
expiredActionMessage=Action expired. Please continue with login now.
|
||||
expiredActionTokenNoSessionMessage=Action expired.
|
||||
expiredActionTokenSessionExistsMessage=Action expired. Please start again.
|
||||
|
||||
missingFirstNameMessage=Please specify first name.
|
||||
missingLastNameMessage=Please specify last name.
|
||||
missingEmailMessage=Please specify email.
|
||||
missingUsernameMessage=Please specify username.
|
||||
missingPasswordMessage=Please specify password.
|
||||
missingTotpMessage=Please specify authenticator code.
|
||||
missingTotpDeviceNameMessage=Please specify device name.
|
||||
notMatchPasswordMessage=Passwords don''t match.
|
||||
|
||||
invalidPasswordExistingMessage=Invalid existing password.
|
||||
invalidPasswordBlacklistedMessage=Invalid password: password is blacklisted.
|
||||
invalidPasswordConfirmMessage=Password confirmation doesn''t match.
|
||||
invalidTotpMessage=Invalid authenticator code.
|
||||
|
||||
usernameExistsMessage=Username already exists.
|
||||
emailExistsMessage=Email already exists.
|
||||
|
||||
federatedIdentityExistsMessage=User with {0} {1} already exists. Please login to account management to link the account.
|
||||
federatedIdentityUnavailableMessage=User {0} authenticated with identity provider {1} does not exists. Please contact your administrator.
|
||||
|
||||
confirmLinkIdpTitle=Account already exists
|
||||
federatedIdentityConfirmLinkMessage=User with {0} {1} already exists. How do you want to continue?
|
||||
federatedIdentityConfirmReauthenticateMessage=Authenticate to link your account with {0}
|
||||
nestedFirstBrokerFlowMessage=The {0} user {1} is not linked to any known user.
|
||||
confirmLinkIdpReviewProfile=Review profile
|
||||
confirmLinkIdpContinue=Add to existing account
|
||||
|
||||
configureTotpMessage=You need to set up Mobile Authenticator to activate your account.
|
||||
updateProfileMessage=You need to update your user profile to activate your account.
|
||||
updatePasswordMessage=You need to change your password to activate your account.
|
||||
resetPasswordMessage=You need to change your password.
|
||||
verifyEmailMessage=You need to verify your email address to activate your account.
|
||||
linkIdpMessage=You need to verify your email address to link your account with {0}.
|
||||
|
||||
emailSentMessage=You should receive an email shortly with further instructions.
|
||||
emailSendErrorMessage=Failed to send email, please try again later.
|
||||
|
||||
accountUpdatedMessage=Your account has been updated.
|
||||
accountPasswordUpdatedMessage=Your password has been updated.
|
||||
|
||||
delegationCompleteHeader=Login Successful
|
||||
delegationCompleteMessage=You may close this browser window and go back to your console application.
|
||||
delegationFailedHeader=Login Failed
|
||||
delegationFailedMessage=You may close this browser window and go back to your console application and try logging in again.
|
||||
|
||||
noAccessMessage=No access
|
||||
|
||||
invalidPasswordMinLengthMessage=Invalid password: minimum length {0}.
|
||||
invalidPasswordMinDigitsMessage=Invalid password: must contain at least {0} numerical digits.
|
||||
invalidPasswordMinLowerCaseCharsMessage=Invalid password: must contain at least {0} lower case characters.
|
||||
invalidPasswordMinUpperCaseCharsMessage=Invalid password: must contain at least {0} upper case characters.
|
||||
invalidPasswordMinSpecialCharsMessage=Invalid password: must contain at least {0} special characters.
|
||||
invalidPasswordNotUsernameMessage=Invalid password: must not be equal to the username.
|
||||
invalidPasswordNotEmailMessage=Invalid password: must not be equal to the email.
|
||||
invalidPasswordRegexPatternMessage=Invalid password: fails to match regex pattern(s).
|
||||
invalidPasswordHistoryMessage=Invalid password: must not be equal to any of last {0} passwords.
|
||||
invalidPasswordGenericMessage=Invalid password: new password doesn''t match password policies.
|
||||
|
||||
failedToProcessResponseMessage=Failed to process response
|
||||
httpsRequiredMessage=HTTPS required
|
||||
realmNotEnabledMessage=Realm not enabled
|
||||
invalidRequestMessage=Invalid Request
|
||||
failedLogout=Logout failed
|
||||
unknownLoginRequesterMessage=Unknown login requester
|
||||
loginRequesterNotEnabledMessage=Login requester not enabled
|
||||
bearerOnlyMessage=Bearer-only applications are not allowed to initiate browser login
|
||||
standardFlowDisabledMessage=Client is not allowed to initiate browser login with given response_type. Standard flow is disabled for the client.
|
||||
implicitFlowDisabledMessage=Client is not allowed to initiate browser login with given response_type. Implicit flow is disabled for the client.
|
||||
invalidRedirectUriMessage=Invalid redirect uri
|
||||
unsupportedNameIdFormatMessage=Unsupported NameIDFormat
|
||||
invalidRequesterMessage=Invalid requester
|
||||
registrationNotAllowedMessage=Registration not allowed
|
||||
resetCredentialNotAllowedMessage=Reset Credential not allowed
|
||||
|
||||
permissionNotApprovedMessage=Permission not approved.
|
||||
noRelayStateInResponseMessage=No relay state in response from identity provider.
|
||||
insufficientPermissionMessage=Insufficient permissions to link identities.
|
||||
couldNotProceedWithAuthenticationRequestMessage=Could not proceed with authentication request to identity provider.
|
||||
couldNotObtainTokenMessage=Could not obtain token from identity provider.
|
||||
unexpectedErrorRetrievingTokenMessage=Unexpected error when retrieving token from identity provider.
|
||||
unexpectedErrorHandlingResponseMessage=Unexpected error when handling response from identity provider.
|
||||
identityProviderAuthenticationFailedMessage=Authentication failed. Could not authenticate with identity provider.
|
||||
couldNotSendAuthenticationRequestMessage=Could not send authentication request to identity provider.
|
||||
unexpectedErrorHandlingRequestMessage=Unexpected error when handling authentication request to identity provider.
|
||||
invalidAccessCodeMessage=Invalid access code.
|
||||
sessionNotActiveMessage=Session not active.
|
||||
invalidCodeMessage=An error occurred, please login again through your application.
|
||||
identityProviderUnexpectedErrorMessage=Unexpected error when authenticating with identity provider
|
||||
identityProviderMissingStateMessage=Missing state parameter in response from identity provider.
|
||||
identityProviderNotFoundMessage=Could not find an identity provider with the identifier.
|
||||
identityProviderLinkSuccess=You successfully verified your email. Please go back to your original browser and continue there with the login.
|
||||
staleCodeMessage=This page is no longer valid, please go back to your application and sign in again
|
||||
realmSupportsNoCredentialsMessage=Realm does not support any credential type.
|
||||
credentialSetupRequired=Cannot login, credential setup required.
|
||||
identityProviderNotUniqueMessage=Realm supports multiple identity providers. Could not determine which identity provider should be used to authenticate with.
|
||||
emailVerifiedMessage=Your email address has been verified.
|
||||
staleEmailVerificationLink=The link you clicked is an old stale link and is no longer valid. Maybe you have already verified your email.
|
||||
identityProviderAlreadyLinkedMessage=Federated identity returned by {0} is already linked to another user.
|
||||
confirmAccountLinking=Confirm linking the account {0} of identity provider {1} with your account.
|
||||
confirmEmailAddressVerification=Confirm validity of e-mail address {0}.
|
||||
confirmExecutionOfActions=Perform the following action(s)
|
||||
|
||||
locale_ca=Catal\u00E0
|
||||
locale_cs=\u010Ce\u0161tina
|
||||
locale_da=Dansk
|
||||
locale_de=Deutsch
|
||||
locale_en=English
|
||||
locale_es=Espa\u00F1ol
|
||||
locale_fr=Fran\u00E7ais
|
||||
locale_hu=Magyar
|
||||
locale_it=Italiano
|
||||
locale_ja=\u65E5\u672C\u8A9E
|
||||
locale_lt=Lietuvi\u0173
|
||||
locale_nl=Nederlands
|
||||
locale_no=Norsk
|
||||
locale_pl=Polski
|
||||
locale_pt_BR=Portugu\u00EAs (Brasil)
|
||||
locale_pt-BR=Portugu\u00EAs (Brasil)
|
||||
locale_ru=\u0420\u0443\u0441\u0441\u043A\u0438\u0439
|
||||
locale_sk=Sloven\u010Dina
|
||||
locale_sv=Svenska
|
||||
locale_tr=T\u00FCrk\u00E7e
|
||||
locale_zh-CN=\u4E2D\u6587\u7B80\u4F53
|
||||
|
||||
backToApplication=« Back to Application
|
||||
missingParameterMessage=Missing parameters\: {0}
|
||||
clientNotFoundMessage=Client not found.
|
||||
clientDisabledMessage=Client disabled.
|
||||
invalidParameterMessage=Invalid parameter\: {0}
|
||||
alreadyLoggedIn=You are already logged in.
|
||||
differentUserAuthenticated=You are already authenticated as different user ''{0}'' in this session. Please sign out first.
|
||||
brokerLinkingSessionExpired=Requested broker account linking, but current session is no longer valid.
|
||||
proceedWithAction=» Click here to proceed
|
||||
|
||||
requiredAction.CONFIGURE_TOTP=Configure OTP
|
||||
requiredAction.terms_and_conditions=Terms and Conditions
|
||||
requiredAction.UPDATE_PASSWORD=Update Password
|
||||
requiredAction.UPDATE_PROFILE=Update Profile
|
||||
requiredAction.VERIFY_EMAIL=Verify Email
|
||||
|
||||
doX509Login=You will be logged in as\:
|
||||
clientCertificate=X509 client certificate\:
|
||||
noCertificate=[No Certificate]
|
||||
|
||||
|
||||
pageNotFound=Page not found
|
||||
internalServerError=An internal server error has occurred
|
||||
|
||||
console-username=Username:
|
||||
console-password=Password:
|
||||
console-otp=One Time Password:
|
||||
console-new-password=New Password:
|
||||
console-confirm-password=Confirm Password:
|
||||
console-update-password=Update of your password is required.
|
||||
console-verify-email=You need to verify your email address. We sent an email to {0} that contains a verification code. Please enter this code into the input below.
|
||||
console-email-code=Email Code:
|
||||
console-accept-terms=Accept Terms? [y/n]:
|
||||
console-accept=y
|
||||
|
||||
# Openshift messages
|
||||
openshift.scope.user_info=User information
|
||||
openshift.scope.user_check-access=User access information
|
||||
openshift.scope.user_full=Full Access
|
||||
openshift.scope.list-projects=List projects
|
||||
|
||||
# SAML authentication
|
||||
saml.post-form.title=Authentication Redirect
|
||||
saml.post-form.message=Redirecting, please wait.
|
||||
saml.post-form.js-disabled=JavaScript is disabled. We strongly recommend to enable it. Click the button below to continue.
|
||||
saml.artifactResolutionServiceInvalidResponse=Unable to resolve artifact.
|
||||
|
||||
#authenticators
|
||||
otp-display-name=Authenticator Application
|
||||
otp-help-text=Enter a verification code from authenticator application.
|
||||
password-display-name=Password
|
||||
password-help-text=Sign in by entering your password.
|
||||
auth-username-form-display-name=Username
|
||||
auth-username-form-help-text=Start sign in by entering your username
|
||||
auth-username-password-form-display-name=Username and password
|
||||
auth-username-password-form-help-text=Sign in by entering your username and password.
|
||||
|
||||
# WebAuthn
|
||||
webauthn-display-name=Security Key
|
||||
webauthn-help-text=Use your security key to sign in.
|
||||
webauthn-passwordless-display-name=Security Key
|
||||
webauthn-passwordless-help-text=Use your security key for passwordless sign in.
|
||||
webauthn-login-title=Security Key login
|
||||
webauthn-registration-title=Security Key Registration
|
||||
webauthn-available-authenticators=Available authenticators
|
||||
webauthn-unsupported-browser-text=WebAuthn is not supported by this browser. Try another one or contact your administrator.
|
||||
|
||||
# WebAuthn Error
|
||||
webauthn-error-title=Security Key Error
|
||||
webauthn-error-registration=Failed to register your Security key.<br/> {0}
|
||||
webauthn-error-api-get=Failed to authenticate by the Security key.<br/> {0}
|
||||
webauthn-error-different-user=First authenticated user is not the one authenticated by the Security key.
|
||||
webauthn-error-auth-verification=Security key authentication result is invalid.<br/> {0}
|
||||
webauthn-error-register-verification=Security key registration result is invalid.<br/> {0}
|
||||
webauthn-error-user-not-found=Unknown user authenticated by the Security key.
|
||||
|
||||
# Identity provider
|
||||
identity-provider-redirector=Connect with another Identity Provider
|
||||
identity-provider-login-label=Or sign in with
|
||||
|
||||
finalDeletionConfirmation=If you delete your account, it cannot be restored. To keep your account, click Cancel.
|
||||
irreversibleAction=This action is irreversible
|
||||
deleteAccountConfirm=Delete account confirmation
|
||||
|
||||
deletingImplies=Deleting your account implies:
|
||||
errasingData=Erasing all your data
|
||||
loggingOutImmediately=Logging you out immediately
|
||||
accountUnusable=Any subsequent use of the application will not be possible with this account
|
||||
userDeletedSuccessfully=User deleted successfully
|
||||
|
||||
access-denied=Access denied
|
113
lumbung.space/login/register.ftl
Executable file
113
lumbung.space/login/register.ftl
Executable file
@ -0,0 +1,113 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('firstName','lastName','email','username','password','password-confirm'); section>
|
||||
<#if section = "header">
|
||||
${msg("registerTitle")}
|
||||
<#elseif section = "form">
|
||||
<form id="kc-register-form" class="${properties.kcFormClass!}" action="${url.registrationAction}" method="post">
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<label for="firstName" class="${properties.kcLabelClass!}">${msg("firstName")}</label>
|
||||
<input type="text" id="firstName" class="${properties.kcInputClass!}" name="firstName"
|
||||
value="${(register.formData.firstName!'')}"
|
||||
aria-invalid="<#if messagesPerField.existsError('firstName')>true</#if>"
|
||||
/>
|
||||
<#if messagesPerField.existsError('firstName')>
|
||||
<span id="input-error-firstname" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('firstName'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<label for="lastName" class="${properties.kcLabelClass!}">${msg("lastName")}</label>
|
||||
<input type="text" id="lastName" class="${properties.kcInputClass!}" name="lastName"
|
||||
value="${(register.formData.lastName!'')}"
|
||||
aria-invalid="<#if messagesPerField.existsError('lastName')>true</#if>"
|
||||
/>
|
||||
<#if messagesPerField.existsError('lastName')>
|
||||
<span id="input-error-lastname" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('lastName'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<label for="email" class="${properties.kcLabelClass!}">${msg("email")}</label>
|
||||
<input type="text" id="email" class="${properties.kcInputClass!}" name="email"
|
||||
value="${(register.formData.email!'')}" autocomplete="email"
|
||||
aria-invalid="<#if messagesPerField.existsError('email')>true</#if>"
|
||||
/>
|
||||
<#if messagesPerField.existsError('email')>
|
||||
<span id="input-error-email" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('email'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
|
||||
</div>
|
||||
|
||||
<#if !realm.registrationEmailAsUsername>
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<label for="username" class="${properties.kcLabelClass!}">${msg("username")}</label>
|
||||
<input type="text" id="username" class="${properties.kcInputClass!}" name="username"
|
||||
value="${(register.formData.username!'')}" autocomplete="username"
|
||||
aria-invalid="<#if messagesPerField.existsError('username')>true</#if>"
|
||||
/>
|
||||
<#if messagesPerField.existsError('username')>
|
||||
<span id="input-error-username" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('username'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
|
||||
</div>
|
||||
</#if>
|
||||
|
||||
<#if passwordRequired??>
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label>
|
||||
<input type="password" id="password" class="${properties.kcInputClass!}" name="password"
|
||||
autocomplete="new-password"
|
||||
aria-invalid="<#if messagesPerField.existsError('password','password-confirm')>true</#if>"
|
||||
/>
|
||||
<#if messagesPerField.existsError('password')>
|
||||
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('password'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<label for="password-confirm"
|
||||
class="${properties.kcLabelClass!}">${msg("passwordConfirm")}</label>
|
||||
<input type="password" id="password-confirm" class="${properties.kcInputClass!}"
|
||||
name="password-confirm"
|
||||
aria-invalid="<#if messagesPerField.existsError('password-confirm')>true</#if>"
|
||||
/>
|
||||
|
||||
<#if messagesPerField.existsError('password-confirm')>
|
||||
<span id="input-error-password-confirm" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||
${kcSanitize(messagesPerField.get('password-confirm'))?no_esc}
|
||||
</span>
|
||||
</#if>
|
||||
</div>
|
||||
</#if>
|
||||
|
||||
<#if recaptchaRequired??>
|
||||
<div class="form-group">
|
||||
<div class="g-recaptcha" data-size="compact" data-sitekey="${recaptchaSiteKey}"></div>
|
||||
</div>
|
||||
</#if>
|
||||
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
||||
<div class="${properties.kcFormOptionsWrapperClass!}">
|
||||
<span><a href="${url.loginUrl}">${kcSanitize(msg("backToLogin"))?no_esc}</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
|
||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doRegister")}"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
16
lumbung.space/login/resources/assets/lumbung-space-logo.svg
Normal file
16
lumbung.space/login/resources/assets/lumbung-space-logo.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 29 KiB |
295
lumbung.space/login/resources/css/login.css
Normal file
295
lumbung.space/login/resources/css/login.css
Normal file
@ -0,0 +1,295 @@
|
||||
@font-face {
|
||||
font-family: Gudea;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(../fonts/gudea.woff2) format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Gudea;
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: url(../fonts/gudea-italic.woff2) format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Gudea;
|
||||
font-style: bold;
|
||||
font-weight: 700;
|
||||
src: url(../fonts/gudea-bold.woff2) format("woff2");
|
||||
}
|
||||
|
||||
body {
|
||||
font-size:1.3em;
|
||||
font-family: Gudea, sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #1B4C8A;
|
||||
}
|
||||
|
||||
|
||||
.card-pf {
|
||||
border:2px solid black;
|
||||
max-width:500px;
|
||||
margin:auto;
|
||||
margin-top: 4em;
|
||||
}
|
||||
|
||||
.col-xs-12.col-sm-12.col-md-12.col-lg-12 {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/*Login form */
|
||||
|
||||
.login-pf-header {
|
||||
background-color: #BCE1D1;
|
||||
height: 3.6em;
|
||||
}
|
||||
|
||||
|
||||
.header-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: -3em;
|
||||
}
|
||||
|
||||
.logo {
|
||||
background-color: white;
|
||||
border: 1px solid black;
|
||||
margin-left: 5.5em;
|
||||
transform: rotate(5deg);
|
||||
}
|
||||
|
||||
#kc-page-title {
|
||||
margin-left: 0.75em;
|
||||
font-size: 1em;
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#kc-form-wrapper {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
#kc-terms-text {
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
#terms-form {
|
||||
padding-left: 1em;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
#kc-form-login {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
flex-direction: column;
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
font-size: 14px;
|
||||
margin: 10px auto;
|
||||
width: 440px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
}
|
||||
|
||||
.form-group.login-pf-settings {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
vertical-align: baseline;
|
||||
align-items: baseline;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#kc-username.form-group{
|
||||
border: none;
|
||||
padding-left: 1em;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
|
||||
#kc-form-buttons {
|
||||
all: unset;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 2em;
|
||||
align-self: center;
|
||||
background-color: #AFAFAF;
|
||||
border-top: 2px solid black;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#kc-form-buttons:hover {
|
||||
background-color: #bce1d1;
|
||||
}
|
||||
|
||||
#kc-form-buttons:hover .login-button {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.login-button {
|
||||
all: unset;
|
||||
display: block;
|
||||
border: none;
|
||||
color: #FFFFFF;
|
||||
font-size: 1em;
|
||||
font-weight: bold;
|
||||
margin: auto;
|
||||
padding: 0.3em;
|
||||
}
|
||||
|
||||
.btn-lg {
|
||||
all: unset;
|
||||
display: block;
|
||||
border: none;
|
||||
color: #FFFFFF;
|
||||
font-size: 1em;
|
||||
font-weight: bold;
|
||||
margin: auto;
|
||||
padding: 0.2em;
|
||||
}
|
||||
|
||||
#terms-form .btn-lg {
|
||||
all: unset;
|
||||
display: block;
|
||||
border: none;
|
||||
color: black;
|
||||
font-size: 1em;
|
||||
font-weight: bold;
|
||||
margin: auto;
|
||||
padding: 0.2em;
|
||||
}
|
||||
|
||||
#terms-form .btn-lg:hover {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.pf-c-form-control {
|
||||
border: none;
|
||||
padding: 5px 5px 5px 5px;
|
||||
border: 2px solid black;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
/*OTP Login*/
|
||||
|
||||
#kc-username.form-group {
|
||||
padding-left: 1em;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#kc-attempted-username {
|
||||
padding: 0;
|
||||
font-style: unset;
|
||||
}
|
||||
|
||||
div#kc-username:before{
|
||||
content: "Logging in as: ";
|
||||
}
|
||||
|
||||
.kc-login-tooltip {
|
||||
text-align: right;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
/*Login form + options*/
|
||||
|
||||
#kc-info {
|
||||
padding: 0.5em;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.pf-c-form__helper-text {
|
||||
display: block;
|
||||
border-top: 2px solid black;
|
||||
text-align: right;
|
||||
padding-right: 1em;
|
||||
padding: 0.2em;
|
||||
}
|
||||
|
||||
.required{
|
||||
background-color: salmon;
|
||||
}
|
||||
|
||||
/*Register form*/
|
||||
|
||||
#kc-register-form {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
/*Page has expired message*/
|
||||
|
||||
#instruction1 {
|
||||
margin: 2em;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
#input-error {
|
||||
border-top: 2px solid black;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
display: inline-block;
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Reset */
|
||||
|
||||
.pf-c-alert__title .kc-feedback-text{
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Register */
|
||||
|
||||
|
||||
.pf-c-form__helper-text .pf-m-error .required .kc-feedback-text{
|
||||
border-top: 2px solid black;
|
||||
}
|
||||
|
||||
|
||||
/* media queries */
|
||||
|
||||
@media screen and (max-width: 530px) {
|
||||
|
||||
#kc-page-title {
|
||||
border: unset;
|
||||
}
|
||||
|
||||
#kc-register-form {
|
||||
margin: unset;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.logo {
|
||||
max-width: 320px;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.logo svg {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
width: 88vw;
|
||||
}
|
||||
|
||||
.form-group.login-pf-settings {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
}
|
0
lumbung.space/login/resources/css/login.css.bak
Normal file
0
lumbung.space/login/resources/css/login.css.bak
Normal file
BIN
lumbung.space/login/resources/fonts/gudea-bold.woff2
Normal file
BIN
lumbung.space/login/resources/fonts/gudea-bold.woff2
Normal file
Binary file not shown.
BIN
lumbung.space/login/resources/fonts/gudea-italic.woff2
Normal file
BIN
lumbung.space/login/resources/fonts/gudea-italic.woff2
Normal file
Binary file not shown.
BIN
lumbung.space/login/resources/fonts/gudea.woff2
Normal file
BIN
lumbung.space/login/resources/fonts/gudea.woff2
Normal file
Binary file not shown.
114
lumbung.space/login/resources/js/base64url.js
Normal file
114
lumbung.space/login/resources/js/base64url.js
Normal file
@ -0,0 +1,114 @@
|
||||
// for embedded scripts, quoted and modified from https://github.com/swansontec/rfc4648.js by William Swanson
|
||||
'use strict';
|
||||
var base64url = base64url || {};
|
||||
(function(base64url) {
|
||||
|
||||
function parse (string, encoding, opts = {}) {
|
||||
// Build the character lookup table:
|
||||
if (!encoding.codes) {
|
||||
encoding.codes = {};
|
||||
for (let i = 0; i < encoding.chars.length; ++i) {
|
||||
encoding.codes[encoding.chars[i]] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// The string must have a whole number of bytes:
|
||||
if (!opts.loose && (string.length * encoding.bits) & 7) {
|
||||
throw new SyntaxError('Invalid padding');
|
||||
}
|
||||
|
||||
// Count the padding bytes:
|
||||
let end = string.length;
|
||||
while (string[end - 1] === '=') {
|
||||
--end;
|
||||
|
||||
// If we get a whole number of bytes, there is too much padding:
|
||||
if (!opts.loose && !(((string.length - end) * encoding.bits) & 7)) {
|
||||
throw new SyntaxError('Invalid padding');
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate the output:
|
||||
const out = new (opts.out || Uint8Array)(((end * encoding.bits) / 8) | 0);
|
||||
|
||||
// Parse the data:
|
||||
let bits = 0; // Number of bits currently in the buffer
|
||||
let buffer = 0; // Bits waiting to be written out, MSB first
|
||||
let written = 0; // Next byte to write
|
||||
for (let i = 0; i < end; ++i) {
|
||||
// Read one character from the string:
|
||||
const value = encoding.codes[string[i]];
|
||||
if (value === void 0) {
|
||||
throw new SyntaxError('Invalid character ' + string[i]);
|
||||
}
|
||||
|
||||
// Append the bits to the buffer:
|
||||
buffer = (buffer << encoding.bits) | value;
|
||||
bits += encoding.bits;
|
||||
|
||||
// Write out some bits if the buffer has a byte's worth:
|
||||
if (bits >= 8) {
|
||||
bits -= 8;
|
||||
out[written++] = 0xff & (buffer >> bits);
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that we have received just enough bits:
|
||||
if (bits >= encoding.bits || 0xff & (buffer << (8 - bits))) {
|
||||
throw new SyntaxError('Unexpected end of data');
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
function stringify (data, encoding, opts = {}) {
|
||||
const { pad = true } = opts;
|
||||
const mask = (1 << encoding.bits) - 1;
|
||||
let out = '';
|
||||
|
||||
let bits = 0; // Number of bits currently in the buffer
|
||||
let buffer = 0; // Bits waiting to be written out, MSB first
|
||||
for (let i = 0; i < data.length; ++i) {
|
||||
// Slurp data into the buffer:
|
||||
buffer = (buffer << 8) | (0xff & data[i]);
|
||||
bits += 8;
|
||||
|
||||
// Write out as much as we can:
|
||||
while (bits > encoding.bits) {
|
||||
bits -= encoding.bits;
|
||||
out += encoding.chars[mask & (buffer >> bits)];
|
||||
}
|
||||
}
|
||||
|
||||
// Partial character:
|
||||
if (bits) {
|
||||
out += encoding.chars[mask & (buffer << (encoding.bits - bits))];
|
||||
}
|
||||
|
||||
// Add padding characters until we hit a byte boundary:
|
||||
if (pad) {
|
||||
while ((out.length * encoding.bits) & 7) {
|
||||
out += '=';
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
const encoding = {
|
||||
chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
|
||||
bits: 6
|
||||
}
|
||||
|
||||
base64url.decode = function (string, opts) {
|
||||
return parse(string, encoding, opts);
|
||||
}
|
||||
|
||||
base64url.encode = function (data, opts) {
|
||||
return stringify(data, encoding, opts)
|
||||
}
|
||||
|
||||
return base64url;
|
||||
}(base64url));
|
||||
|
||||
|
25
lumbung.space/login/saml-post-form.ftl
Normal file
25
lumbung.space/login/saml-post-form.ftl
Normal file
@ -0,0 +1,25 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout; section>
|
||||
<#if section = "header">
|
||||
${msg("saml.post-form.title")}
|
||||
<#elseif section = "form">
|
||||
<script>window.onload = function() {document.forms[0].submit()};</script>
|
||||
<p>${msg("saml.post-form.message")}</p>
|
||||
<form name="saml-post-binding" method="post" action="${samlPost.url}">
|
||||
<#if samlPost.SAMLRequest??>
|
||||
<input type="hidden" name="SAMLRequest" value="${samlPost.SAMLRequest}"/>
|
||||
</#if>
|
||||
<#if samlPost.SAMLResponse??>
|
||||
<input type="hidden" name="SAMLResponse" value="${samlPost.SAMLResponse}"/>
|
||||
</#if>
|
||||
<#if samlPost.relayState??>
|
||||
<input type="hidden" name="RelayState" value="${samlPost.relayState}"/>
|
||||
</#if>
|
||||
|
||||
<noscript>
|
||||
<p>${msg("saml.post-form.js-disabled")}</p>
|
||||
<input type="submit" value="${msg("doContinue")}"/>
|
||||
</noscript>
|
||||
</form>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
43
lumbung.space/login/select-authenticator.ftl
Normal file
43
lumbung.space/login/select-authenticator.ftl
Normal file
@ -0,0 +1,43 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout displayInfo=false; section>
|
||||
<#if section = "header" || section = "show-username">
|
||||
<script type="text/javascript">
|
||||
function fillAndSubmit(authExecId) {
|
||||
document.getElementById('authexec-hidden-input').value = authExecId;
|
||||
document.getElementById('kc-select-credential-form').submit();
|
||||
}
|
||||
</script>
|
||||
<#if section = "header">
|
||||
${msg("loginChooseAuthenticator")}
|
||||
</#if>
|
||||
<#elseif section = "form">
|
||||
|
||||
<form id="kc-select-credential-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
||||
<div class="${properties.kcSelectAuthListClass!}">
|
||||
<#list auth.authenticationSelections as authenticationSelection>
|
||||
<div class="${properties.kcSelectAuthListItemClass!}" onclick="fillAndSubmit('${authenticationSelection.authExecId}')">
|
||||
|
||||
<div class="${properties.kcSelectAuthListItemIconClass!}">
|
||||
<i class="${properties['${authenticationSelection.iconCssClass}']!authenticationSelection.iconCssClass} fa-2x"></i>
|
||||
</div>
|
||||
<div class="${properties.kcSelectAuthListItemBodyClass!}">
|
||||
<div class="${properties.kcSelectAuthListItemHeadingClass!}">
|
||||
${msg('${authenticationSelection.displayName}')}
|
||||
</div>
|
||||
<div class="${properties.kcSelectAuthListItemDescriptionClass!}">
|
||||
${msg('${authenticationSelection.helpText}')}
|
||||
</div>
|
||||
</div>
|
||||
<div class="${properties.kcSelectAuthListItemFillClass!}"></div>
|
||||
<div class="${properties.kcSelectAuthListItemArrowClass!}">
|
||||
<i class="${properties.kcSelectAuthListItemArrowIconClass!}"></i>
|
||||
</div>
|
||||
</div>
|
||||
</#list>
|
||||
<input type="hidden" id="authexec-hidden-input" name="authenticationExecution" />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
||||
|
152
lumbung.space/login/template.ftl
Normal file
152
lumbung.space/login/template.ftl
Normal file
@ -0,0 +1,152 @@
|
||||
<#macro registrationLayout bodyClass="" displayInfo=false displayMessage=true displayRequiredFields=false showAnotherWayIfPresent=true>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="${properties.kcHtmlClass!}">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
|
||||
<#if properties.meta?has_content>
|
||||
<#list properties.meta?split(' ') as meta>
|
||||
<meta name="${meta?split('==')[0]}" content="${meta?split('==')[1]}"/>
|
||||
</#list>
|
||||
</#if>
|
||||
<title>${msg("loginTitle",(realm.displayName!''))}</title>
|
||||
<link rel="icon" href="${url.resourcesPath}/img/favicon.ico" />
|
||||
<#if properties.stylesCommon?has_content>
|
||||
<#list properties.stylesCommon?split(' ') as style>
|
||||
<link href="${url.resourcesCommonPath}/${style}" rel="stylesheet" />
|
||||
</#list>
|
||||
</#if>
|
||||
<#if properties.styles?has_content>
|
||||
<#list properties.styles?split(' ') as style>
|
||||
<link href="${url.resourcesPath}/${style}" rel="stylesheet" />
|
||||
</#list>
|
||||
</#if>
|
||||
<#if properties.scripts?has_content>
|
||||
<#list properties.scripts?split(' ') as script>
|
||||
<script src="${url.resourcesPath}/${script}" type="text/javascript"></script>
|
||||
</#list>
|
||||
</#if>
|
||||
<#if scripts??>
|
||||
<#list scripts as script>
|
||||
<script src="${script}" type="text/javascript"></script>
|
||||
</#list>
|
||||
</#if>
|
||||
</head>
|
||||
|
||||
<body class="${properties.kcBodyClass!}">
|
||||
<div class="${properties.kcLoginClass!}">
|
||||
<div id="kc-header" class="${properties.kcHeaderClass!}">
|
||||
<div id="kc-header-wrapper"
|
||||
class="${properties.kcHeaderWrapperClass!}">${kcSanitize(msg("loginTitleHtml",(realm.displayNameHtml!'')))?no_esc}</div>
|
||||
</div>
|
||||
<div class="${properties.kcFormCardClass!}">
|
||||
<header class="${properties.kcFormHeaderClass!}">
|
||||
<#if realm.internationalizationEnabled && locale.supported?size gt 1>
|
||||
<div class="${properties.kcLocaleMainClass!}" id="kc-locale">
|
||||
<div id="kc-locale-wrapper" class="${properties.kcLocaleWrapperClass!}">
|
||||
<div id="kc-locale-dropdown" class="${properties.kcLocaleDropDownClass!}">
|
||||
<a href="#" id="kc-current-locale-link">${locale.current}</a>
|
||||
<ul class="${properties.kcLocaleListClass!}">
|
||||
<#list locale.supported as l>
|
||||
<li class="${properties.kcLocaleListItemClass!}">
|
||||
<a class="${properties.kcLocaleItemClass!}" href="${l.url}">${l.label}</a>
|
||||
</li>
|
||||
</#list>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</#if>
|
||||
<#if !(auth?has_content && auth.showUsername() && !auth.showResetCredentials())>
|
||||
<#if displayRequiredFields>
|
||||
<div class="${properties.kcContentWrapperClass!}">
|
||||
<div class="${properties.kcLabelWrapperClass!} subtitle">
|
||||
<span class="subtitle"><span class="required">*</span> ${msg("requiredFields")}</span>
|
||||
</div>
|
||||
<div class="col-md-10">
|
||||
<h1 id="kc-page-title"><#nested "header"></h1>
|
||||
</div>
|
||||
</div>
|
||||
<#else>
|
||||
<h1 id="kc-page-title"><#nested "header"></h1>
|
||||
</#if>
|
||||
<#else>
|
||||
<#if displayRequiredFields>
|
||||
<div class="${properties.kcContentWrapperClass!}">
|
||||
<div class="${properties.kcLabelWrapperClass!} subtitle">
|
||||
<span class="subtitle"><span class="required">*</span> ${msg("requiredFields")}</span>
|
||||
</div>
|
||||
<div class="col-md-10">
|
||||
<#nested "show-username">
|
||||
<div id="kc-username" class="${properties.kcFormGroupClass!}">
|
||||
<label id="kc-attempted-username">${auth.attemptedUsername}</label>
|
||||
<a id="reset-login" href="${url.loginRestartFlowUrl}">
|
||||
<div class="kc-login-tooltip">
|
||||
<i class="${properties.kcResetFlowIcon!}"></i>
|
||||
<span class="kc-tooltip-text">${msg("restartLoginTooltip")}</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<#else>
|
||||
<#nested "show-username">
|
||||
<div id="kc-username" class="${properties.kcFormGroupClass!}">
|
||||
<label id="kc-attempted-username">${auth.attemptedUsername}</label>
|
||||
<a id="reset-login" href="${url.loginRestartFlowUrl}">
|
||||
<div class="kc-login-tooltip">
|
||||
<i class="${properties.kcResetFlowIcon!}"></i>
|
||||
<span class="kc-tooltip-text">${msg("restartLoginTooltip")}</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</#if>
|
||||
</#if>
|
||||
</header>
|
||||
<div id="kc-content">
|
||||
<div id="kc-content-wrapper">
|
||||
|
||||
<#-- 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??)>
|
||||
<div class="alert-${message.type} ${properties.kcAlertClass!} pf-m-<#if message.type = 'error'>danger<#else>${message.type}</#if>">
|
||||
<div class="pf-c-alert__icon">
|
||||
<#if message.type = 'success'><span class="${properties.kcFeedbackSuccessIcon!}"></span></#if>
|
||||
<#if message.type = 'warning'><span class="${properties.kcFeedbackWarningIcon!}"></span></#if>
|
||||
<#if message.type = 'error'><span class="${properties.kcFeedbackErrorIcon!}"></span></#if>
|
||||
<#if message.type = 'info'><span class="${properties.kcFeedbackInfoIcon!}"></span></#if>
|
||||
</div>
|
||||
<span class="${properties.kcAlertTitleClass!}">${kcSanitize(message.summary)?no_esc}</span>
|
||||
</div>
|
||||
</#if>
|
||||
|
||||
<#nested "form">
|
||||
|
||||
<#if auth?has_content && auth.showTryAnotherWayLink() && showAnotherWayIfPresent>
|
||||
<form id="kc-select-try-another-way-form" action="${url.loginAction}" method="post">
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<input type="hidden" name="tryAnotherWay" value="on"/>
|
||||
<a href="#" id="try-another-way"
|
||||
onclick="document.forms['kc-select-try-another-way-form'].submit();return false;">${msg("doTryAnotherWay")}</a>
|
||||
</div>
|
||||
</form>
|
||||
</#if>
|
||||
|
||||
<#if displayInfo>
|
||||
<div id="kc-info" class="${properties.kcSignUpClass!}">
|
||||
<div id="kc-info-wrapper" class="${properties.kcInfoAreaWrapperClass!}">
|
||||
<#nested "info">
|
||||
</div>
|
||||
</div>
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</#macro>
|
37
lumbung.space/login/terms.ftl
Executable file
37
lumbung.space/login/terms.ftl
Executable file
@ -0,0 +1,37 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout displayMessage=false; section>
|
||||
<#if section = "header">
|
||||
${msg("termsTitle")}
|
||||
<#elseif section = "form">
|
||||
<div id="kc-terms-text">
|
||||
<h2>Welcome to lumbung.space</h2>
|
||||
|
||||
<p>lumbung.space is an experimental social and publishing platform by and for the lumbung-interlokal and lumbung artists. It is built on open platforms, co-operative governance and as a community infrastructure meant for our practices to develop and thrive.</p
|
||||
|
||||
<p>Along side the Community Guidelines and the Privacy Statement, these terms of service lumbung.space is:</p>
|
||||
<ul>
|
||||
<li>non-profit, non-extractive, owned and operated by is community of users, that means you!</li>
|
||||
<li>currently made up of parts, cloud, tv, social, books, pen, and the members page</li>
|
||||
<li>experimental and a place of learning, we are trying to find out what a social platform for a lumbung practice looks like</li>
|
||||
</ul>
|
||||
|
||||
<h3>A shared resource</h3>
|
||||
<p>lumbung.space is a shared resource and an environment that strives to be welcoming, generous, funny and critical. Be considerate to others, respectful to the resources, be ready to ask for help if you need it, or to give help if others do! Feel free to try, play, modify and use as you see fit! A shared resource that does not sell, trade, or otherwise transfer to outside parties your personally identifiable information.</p>
|
||||
|
||||
<h3>Account/Site</h3>
|
||||
<p>If you create/have an account on the lumbung.space, you are responsible for maintaining the security of your account, and you are fully responsible for all activities that occur under the account and any other actions taken in connection with the lumbung.space's ecosystem (various apps). You must not describe or assign keywords to lumbung.space in a misleading or unlawful manner, including in a manner intended to trade on the name or reputation of others, and lumbung.space's moderator may change or remove any description or keyword that it considers inappropriate or unlawful, or otherwise likely to cause lumbung.space.</p>
|
||||
|
||||
<h3>Liability</h3>
|
||||
<p>lumbung.space is built to prioritize the safety of your data. There are back-up routines in place and encryption is used everywhere. Despite all that, storing data on-line comes with risks. By using lumbung.space you agree that lumbung.space is not liable for unexpected downtime, data loss or breaches. You take care of your own backups and don't use lumbung.space as the only place to store materials.</p>
|
||||
|
||||
<h3>Data & content policy</h3>
|
||||
<p>You own all the data you upload or create on lumbung.space. That means lumbung.space will not lay claim to it but also that you do not infringe on other's copyright. Whenever you publish something on lumbung.space so that third parties can see it, for example by publishing it on the front page, you do so with the explicit understanding that you have the right to publish it.You can always delete your accounts and your data at any time or contact us to help you do so.</p>
|
||||
|
||||
</div>
|
||||
<form id="terms-form" class="form-actions" action="${url.loginAction}" method="POST">
|
||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="accept" id="kc-accept" type="submit" value="${msg("doAccept")}"/>
|
||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" name="cancel" id="kc-decline" type="submit" value="${msg("doDecline")}"/>
|
||||
</form>
|
||||
<div class="clearfix"></div>
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
130
lumbung.space/login/theme.properties
Normal file
130
lumbung.space/login/theme.properties
Normal file
@ -0,0 +1,130 @@
|
||||
parent=base
|
||||
import=common/keycloak
|
||||
|
||||
styles=css/login.css
|
||||
scripts=css/test.js
|
||||
|
||||
meta=viewport==width=device-width,initial-scale=1
|
||||
|
||||
kcHtmlClass=login-pf
|
||||
kcLoginClass=login-pf-page
|
||||
|
||||
kcLogoLink=http://www.keycloak.org
|
||||
|
||||
kcLogoClass=login-pf-brand
|
||||
|
||||
kcContainerClass=container-fluid
|
||||
kcContentClass=col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 col-lg-6 col-lg-offset-3
|
||||
|
||||
kcHeaderClass=login-pf-page-header
|
||||
kcFeedbackAreaClass=col-md-12
|
||||
kcLocaleClass=col-xs-12 col-sm-1
|
||||
|
||||
## Locale
|
||||
kcLocaleMainClass=pf-c-dropdown
|
||||
kcLocaleListClass=pf-c-dropdown__menu pf-m-align-right
|
||||
kcLocaleItemClass=pf-c-dropdown__menu-item
|
||||
|
||||
## Alert
|
||||
kcAlertClass=pf-c-alert pf-m-inline
|
||||
kcAlertTitleClass=pf-c-alert__title kc-feedback-text
|
||||
|
||||
kcFormAreaClass=col-sm-10 col-sm-offset-1 col-md-8 col-md-offset-2 col-lg-8 col-lg-offset-2
|
||||
kcFormCardClass=card-pf
|
||||
|
||||
### Social providers
|
||||
kcFormSocialAccountListClass=pf-c-login__main-footer-links kc-social-links
|
||||
kcFormSocialAccountListGridClass=pf-l-grid kc-social-grid
|
||||
kcFormSocialAccountListButtonClass=pf-c-button pf-m-control pf-m-block kc-social-item kc-social-gray
|
||||
kcFormSocialAccountGridItem=pf-l-grid__item
|
||||
|
||||
kcFormSocialAccountNameClass=kc-social-provider-name
|
||||
kcFormSocialAccountLinkClass=pf-c-login__main-footer-links-item-link
|
||||
kcFormSocialAccountSectionClass=kc-social-section kc-social-gray
|
||||
kcFormHeaderClass=login-pf-header
|
||||
|
||||
kcFeedbackErrorIcon=fa fa-fw fa-exclamation-circle
|
||||
kcFeedbackWarningIcon=fa fa-fw fa-exclamation-triangle
|
||||
kcFeedbackSuccessIcon=fa fa-fw fa-check-circle
|
||||
kcFeedbackInfoIcon=fa fa-fw fa-info-circle
|
||||
|
||||
kcResetFlowIcon=pficon pficon-arrow fa
|
||||
kcWebAuthnKeyIcon=pficon pficon-key
|
||||
|
||||
kcFormClass=form-horizontal
|
||||
kcFormGroupClass=form-group
|
||||
kcFormGroupErrorClass=has-error
|
||||
kcLabelClass=pf-c-form__label pf-c-form__label-text
|
||||
kcLabelWrapperClass=col-xs-12 col-sm-12 col-md-12 col-lg-12
|
||||
kcInputClass=pf-c-form-control
|
||||
kcInputErrorMessageClass=pf-c-form__helper-text pf-m-error required kc-feedback-text
|
||||
kcInputWrapperClass=col-xs-12 col-sm-12 col-md-12 col-lg-12
|
||||
kcFormOptionsClass=col-xs-12 col-sm-12 col-md-12 col-lg-12
|
||||
kcFormButtonsClass=col-xs-12 col-sm-12 col-md-12 col-lg-12
|
||||
kcFormSettingClass=login-pf-settings
|
||||
kcTextareaClass=form-control
|
||||
kcSignUpClass=login-pf-signup
|
||||
|
||||
|
||||
kcInfoAreaClass=col-xs-12 col-sm-4 col-md-4 col-lg-5 details
|
||||
|
||||
##### css classes for form buttons
|
||||
# main class used for all buttons
|
||||
kcButtonClass=pf-c-button
|
||||
# classes defining priority of the button - primary or default (there is typically only one priority button for the form)
|
||||
kcButtonPrimaryClass=pf-m-primary
|
||||
kcButtonDefaultClass=btn-default
|
||||
# classes defining size of the button
|
||||
kcButtonLargeClass=btn-lg
|
||||
kcButtonBlockClass=pf-m-block
|
||||
|
||||
##### css classes for input
|
||||
kcInputLargeClass=input-lg
|
||||
|
||||
##### css classes for form accessability
|
||||
kcSrOnlyClass=sr-only
|
||||
|
||||
##### css classes for select-authenticator form
|
||||
kcSelectAuthListClass=pf-l-stack select-auth-container
|
||||
kcSelectAuthListItemClass=pf-l-stack__item select-auth-box-parent pf-l-split
|
||||
kcSelectAuthListItemIconClass=pf-l-split__item select-auth-box-icon
|
||||
kcSelectAuthListItemBodyClass=pf-l-split__item pf-l-stack
|
||||
kcSelectAuthListItemHeadingClass=pf-l-stack__item select-auth-box-headline pf-c-title
|
||||
kcSelectAuthListItemDescriptionClass=pf-l-stack__item select-auth-box-desc
|
||||
kcSelectAuthListItemFillClass=pf-l-split__item pf-m-fill
|
||||
kcSelectAuthListItemArrowClass=pf-l-split__item select-auth-box-arrow
|
||||
kcSelectAuthListItemArrowIconClass=fa fa-angle-right fa-lg
|
||||
|
||||
##### css classes for the authenticators
|
||||
kcAuthenticatorDefaultClass=fa list-view-pf-icon-lg
|
||||
kcAuthenticatorPasswordClass=fa fa-unlock list-view-pf-icon-lg
|
||||
kcAuthenticatorOTPClass=fa fa-mobile list-view-pf-icon-lg
|
||||
kcAuthenticatorWebAuthnClass=fa fa-key list-view-pf-icon-lg
|
||||
kcAuthenticatorWebAuthnPasswordlessClass=fa fa-key list-view-pf-icon-lg
|
||||
|
||||
##### css classes for the OTP Login Form
|
||||
kcLoginOTPListClass=pf-c-tile
|
||||
kcLoginOTPListInputClass=pf-c-tile__input
|
||||
kcLoginOTPListItemHeaderClass=pf-c-tile__header
|
||||
kcLoginOTPListItemIconBodyClass=pf-c-tile__icon
|
||||
kcLoginOTPListItemIconClass=fa fa-mobile
|
||||
kcLoginOTPListItemTitleClass=pf-c-tile__title
|
||||
|
||||
##### css classes for identity providers logos
|
||||
kcCommonLogoIdP=kc-social-provider-logo kc-social-gray
|
||||
|
||||
## Social
|
||||
kcLogoIdP-facebook=fa fa-facebook
|
||||
kcLogoIdP-google=fa fa-google
|
||||
kcLogoIdP-github=fa fa-github
|
||||
kcLogoIdP-linkedin=fa fa-linkedin
|
||||
kcLogoIdP-instagram=fa fa-instagram
|
||||
## windows instead of microsoft - not included in PF4
|
||||
kcLogoIdP-microsoft=fa fa-windows
|
||||
kcLogoIdP-bitbucket=fa fa-bitbucket
|
||||
kcLogoIdP-gitlab=fa fa-gitlab
|
||||
kcLogoIdP-paypal=fa fa-paypal
|
||||
kcLogoIdP-stackoverflow=fa fa-stack-overflow
|
||||
kcLogoIdP-twitter=fa fa-twitter
|
||||
kcLogoIdP-openshift-v4=pf-icon pf-icon-openshift
|
||||
kcLogoIdP-openshift-v3=pf-icon pf-icon-openshift
|
115
lumbung.space/login/webauthn-authenticate.ftl
Normal file
115
lumbung.space/login/webauthn-authenticate.ftl
Normal file
@ -0,0 +1,115 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout showAnotherWayIfPresent=false; section>
|
||||
<#if section = "title">
|
||||
title
|
||||
<#elseif section = "header">
|
||||
${kcSanitize(msg("webauthn-login-title"))?no_esc}
|
||||
<#elseif section = "form">
|
||||
|
||||
<form id="webauth" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<input type="hidden" id="clientDataJSON" name="clientDataJSON"/>
|
||||
<input type="hidden" id="authenticatorData" name="authenticatorData"/>
|
||||
<input type="hidden" id="signature" name="signature"/>
|
||||
<input type="hidden" id="credentialId" name="credentialId"/>
|
||||
<input type="hidden" id="userHandle" name="userHandle"/>
|
||||
<input type="hidden" id="error" name="error"/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<#if authenticators??>
|
||||
<form id="authn_select" class="${properties.kcFormClass!}">
|
||||
<#list authenticators.authenticators as authenticator>
|
||||
<input type="hidden" name="authn_use_chk" value="${authenticator.credentialId}"/>
|
||||
</#list>
|
||||
</form>
|
||||
</#if>
|
||||
|
||||
<script type="text/javascript" src="${url.resourcesCommonPath}/node_modules/jquery/dist/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="${url.resourcesPath}/js/base64url.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
window.onload = () => {
|
||||
let isUserIdentified = ${isUserIdentified};
|
||||
if (!isUserIdentified) {
|
||||
doAuthenticate([]);
|
||||
return;
|
||||
}
|
||||
checkAllowCredentials();
|
||||
};
|
||||
|
||||
function checkAllowCredentials() {
|
||||
let allowCredentials = [];
|
||||
let authn_use = document.forms['authn_select'].authn_use_chk;
|
||||
|
||||
if (authn_use !== undefined) {
|
||||
if (authn_use.length === undefined) {
|
||||
allowCredentials.push({
|
||||
id: base64url.decode(authn_use.value, {loose: true}),
|
||||
type: 'public-key',
|
||||
});
|
||||
} else {
|
||||
for (let i = 0; i < authn_use.length; i++) {
|
||||
allowCredentials.push({
|
||||
id: base64url.decode(authn_use[i].value, {loose: true}),
|
||||
type: 'public-key',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
doAuthenticate(allowCredentials);
|
||||
}
|
||||
|
||||
|
||||
function doAuthenticate(allowCredentials) {
|
||||
|
||||
// Check if WebAuthn is supported by this browser
|
||||
if (!window.PublicKeyCredential) {
|
||||
$("#error").val("${msg("webauthn-unsupported-browser-text")?no_esc}");
|
||||
$("#webauth").submit();
|
||||
return;
|
||||
}
|
||||
|
||||
let challenge = "${challenge}";
|
||||
let userVerification = "${userVerification}";
|
||||
let rpId = "${rpId}";
|
||||
let publicKey = {
|
||||
rpId : rpId,
|
||||
challenge: base64url.decode(challenge, { loose: true })
|
||||
};
|
||||
|
||||
if (allowCredentials.length) {
|
||||
publicKey.allowCredentials = allowCredentials;
|
||||
}
|
||||
|
||||
if (userVerification !== 'not specified') publicKey.userVerification = userVerification;
|
||||
|
||||
navigator.credentials.get({publicKey})
|
||||
.then((result) => {
|
||||
window.result = result;
|
||||
|
||||
let clientDataJSON = result.response.clientDataJSON;
|
||||
let authenticatorData = result.response.authenticatorData;
|
||||
let signature = result.response.signature;
|
||||
|
||||
$("#clientDataJSON").val(base64url.encode(new Uint8Array(clientDataJSON), { pad: false }));
|
||||
$("#authenticatorData").val(base64url.encode(new Uint8Array(authenticatorData), { pad: false }));
|
||||
$("#signature").val(base64url.encode(new Uint8Array(signature), { pad: false }));
|
||||
$("#credentialId").val(result.id);
|
||||
if(result.response.userHandle) {
|
||||
$("#userHandle").val(base64url.encode(new Uint8Array(result.response.userHandle), { pad: false }));
|
||||
}
|
||||
$("#webauth").submit();
|
||||
})
|
||||
.catch((err) => {
|
||||
$("#error").val(err);
|
||||
$("#webauth").submit();
|
||||
})
|
||||
;
|
||||
}
|
||||
|
||||
</script>
|
||||
<#elseif section = "info">
|
||||
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
55
lumbung.space/login/webauthn-error.ftl
Normal file
55
lumbung.space/login/webauthn-error.ftl
Normal file
@ -0,0 +1,55 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout displayMessage=true; section>
|
||||
<#if section = "header">
|
||||
${kcSanitize(msg("webauthn-error-title"))?no_esc}
|
||||
<#elseif section = "form">
|
||||
|
||||
<script type="text/javascript">
|
||||
refreshPage = () => {
|
||||
document.getElementById('isSetRetry').value = 'retry';
|
||||
document.getElementById('executionValue').value = '${execution}';
|
||||
document.getElementById('kc-error-credential-form').submit();
|
||||
}
|
||||
</script>
|
||||
|
||||
<form id="kc-error-credential-form" class="${properties.kcFormClass!}" action="${url.loginAction}"
|
||||
method="post">
|
||||
<input type="hidden" id="executionValue" name="authenticationExecution"/>
|
||||
<input type="hidden" id="isSetRetry" name="isSetRetry"/>
|
||||
</form>
|
||||
|
||||
<#if authenticators??>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>${kcSanitize(msg("webauthn-available-authenticators"))?no_esc}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<#list authenticators.authenticators as authenticator>
|
||||
<tr>
|
||||
<th>
|
||||
<span id="kc-webauthn-authenticator">${kcSanitize(authenticator.label)?no_esc}</span>
|
||||
</th>
|
||||
</tr>
|
||||
</#list>
|
||||
</tbody>
|
||||
</table>
|
||||
</#if>
|
||||
|
||||
<input tabindex="4" onclick="refreshPage()" type="button"
|
||||
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
|
||||
name="try-again" id="kc-try-again" value="${kcSanitize(msg("doTryAgain"))?no_esc}"
|
||||
/>
|
||||
|
||||
<#if isAppInitiatedAction??>
|
||||
<form action="${url.loginAction}" class="${properties.kcFormClass!}" id="kc-webauthn-settings-form" method="post">
|
||||
<button type="submit"
|
||||
class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
|
||||
id="cancelWebAuthnAIA" name="cancel-aia" value="true"/>${msg("doCancel")}
|
||||
</button>
|
||||
</form>
|
||||
</#if>
|
||||
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
174
lumbung.space/login/webauthn-register.ftl
Normal file
174
lumbung.space/login/webauthn-register.ftl
Normal file
@ -0,0 +1,174 @@
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.registrationLayout; section>
|
||||
<#if section = "title">
|
||||
title
|
||||
<#elseif section = "header">
|
||||
<span class="${properties.kcWebAuthnKeyIcon}"></span>
|
||||
${kcSanitize(msg("webauthn-registration-title"))?no_esc}
|
||||
<#elseif section = "form">
|
||||
|
||||
<form id="register" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<input type="hidden" id="clientDataJSON" name="clientDataJSON"/>
|
||||
<input type="hidden" id="attestationObject" name="attestationObject"/>
|
||||
<input type="hidden" id="publicKeyCredentialId" name="publicKeyCredentialId"/>
|
||||
<input type="hidden" id="authenticatorLabel" name="authenticatorLabel"/>
|
||||
<input type="hidden" id="error" name="error"/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script type="text/javascript" src="${url.resourcesCommonPath}/node_modules/jquery/dist/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="${url.resourcesPath}/js/base64url.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
function registerSecurityKey() {
|
||||
|
||||
// Check if WebAuthn is supported by this browser
|
||||
if (!window.PublicKeyCredential) {
|
||||
$("#error").val("${msg("webauthn-unsupported-browser-text")?no_esc}");
|
||||
$("#register").submit();
|
||||
return;
|
||||
}
|
||||
|
||||
// mandatory parameters
|
||||
let challenge = "${challenge}";
|
||||
let userid = "${userid}";
|
||||
let username = "${username}";
|
||||
|
||||
let signatureAlgorithms = "${signatureAlgorithms}";
|
||||
let pubKeyCredParams = getPubKeyCredParams(signatureAlgorithms);
|
||||
|
||||
let rpEntityName = "${rpEntityName}";
|
||||
let rp = {name: rpEntityName};
|
||||
|
||||
let publicKey = {
|
||||
challenge: base64url.decode(challenge, {loose: true}),
|
||||
rp: rp,
|
||||
user: {
|
||||
id: base64url.decode(userid, {loose: true}),
|
||||
name: username,
|
||||
displayName: username
|
||||
},
|
||||
pubKeyCredParams: pubKeyCredParams,
|
||||
};
|
||||
|
||||
// optional parameters
|
||||
let rpId = "${rpId}";
|
||||
publicKey.rp.id = rpId;
|
||||
|
||||
let attestationConveyancePreference = "${attestationConveyancePreference}";
|
||||
if (attestationConveyancePreference !== 'not specified') publicKey.attestation = attestationConveyancePreference;
|
||||
|
||||
let authenticatorSelection = {};
|
||||
let isAuthenticatorSelectionSpecified = false;
|
||||
|
||||
let authenticatorAttachment = "${authenticatorAttachment}";
|
||||
if (authenticatorAttachment !== 'not specified') {
|
||||
authenticatorSelection.authenticatorAttachment = authenticatorAttachment;
|
||||
isAuthenticatorSelectionSpecified = true;
|
||||
}
|
||||
|
||||
let requireResidentKey = "${requireResidentKey}";
|
||||
if (requireResidentKey !== 'not specified') {
|
||||
if (requireResidentKey === 'Yes')
|
||||
authenticatorSelection.requireResidentKey = true;
|
||||
else
|
||||
authenticatorSelection.requireResidentKey = false;
|
||||
isAuthenticatorSelectionSpecified = true;
|
||||
}
|
||||
|
||||
let userVerificationRequirement = "${userVerificationRequirement}";
|
||||
if (userVerificationRequirement !== 'not specified') {
|
||||
authenticatorSelection.userVerification = userVerificationRequirement;
|
||||
isAuthenticatorSelectionSpecified = true;
|
||||
}
|
||||
|
||||
if (isAuthenticatorSelectionSpecified) publicKey.authenticatorSelection = authenticatorSelection;
|
||||
|
||||
let createTimeout = ${createTimeout};
|
||||
if (createTimeout != 0) publicKey.timeout = createTimeout * 1000;
|
||||
|
||||
let excludeCredentialIds = "${excludeCredentialIds}";
|
||||
let excludeCredentials = getExcludeCredentials(excludeCredentialIds);
|
||||
if (excludeCredentials.length > 0) publicKey.excludeCredentials = excludeCredentials;
|
||||
|
||||
navigator.credentials.create({publicKey})
|
||||
.then(function (result) {
|
||||
window.result = result;
|
||||
let clientDataJSON = result.response.clientDataJSON;
|
||||
let attestationObject = result.response.attestationObject;
|
||||
let publicKeyCredentialId = result.rawId;
|
||||
|
||||
$("#clientDataJSON").val(base64url.encode(new Uint8Array(clientDataJSON), {pad: false}));
|
||||
$("#attestationObject").val(base64url.encode(new Uint8Array(attestationObject), {pad: false}));
|
||||
$("#publicKeyCredentialId").val(base64url.encode(new Uint8Array(publicKeyCredentialId), {pad: false}));
|
||||
|
||||
let initLabel = "WebAuthn Authenticator (Default Label)";
|
||||
let labelResult = window.prompt("Please input your registered authenticator's label", initLabel);
|
||||
if (labelResult === null) labelResult = initLabel;
|
||||
$("#authenticatorLabel").val(labelResult);
|
||||
|
||||
$("#register").submit();
|
||||
|
||||
})
|
||||
.catch(function (err) {
|
||||
$("#error").val(err);
|
||||
$("#register").submit();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function getPubKeyCredParams(signatureAlgorithms) {
|
||||
let pubKeyCredParams = [];
|
||||
if (signatureAlgorithms === "") {
|
||||
pubKeyCredParams.push({type: "public-key", alg: -7});
|
||||
return pubKeyCredParams;
|
||||
}
|
||||
let signatureAlgorithmsList = signatureAlgorithms.split(',');
|
||||
|
||||
for (let i = 0; i < signatureAlgorithmsList.length; i++) {
|
||||
pubKeyCredParams.push({
|
||||
type: "public-key",
|
||||
alg: signatureAlgorithmsList[i]
|
||||
});
|
||||
}
|
||||
return pubKeyCredParams;
|
||||
}
|
||||
|
||||
function getExcludeCredentials(excludeCredentialIds) {
|
||||
let excludeCredentials = [];
|
||||
if (excludeCredentialIds === "") return excludeCredentials;
|
||||
|
||||
let excludeCredentialIdsList = excludeCredentialIds.split(',');
|
||||
|
||||
for (let i = 0; i < excludeCredentialIdsList.length; i++) {
|
||||
excludeCredentials.push({
|
||||
type: "public-key",
|
||||
id: base64url.decode(excludeCredentialIdsList[i],
|
||||
{loose: true})
|
||||
});
|
||||
}
|
||||
return excludeCredentials;
|
||||
}
|
||||
</script>
|
||||
|
||||
<#if !isSetRetry?has_content && isAppInitiatedAction?has_content>
|
||||
<input type="submit"
|
||||
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
|
||||
id="registerWebAuthnAIA" value="${msg("doRegister")}" onclick="registerSecurityKey()"
|
||||
/>
|
||||
<form action="${url.loginAction}" class="${properties.kcFormClass!}" id="kc-webauthn-settings-form"
|
||||
method="post">
|
||||
<button type="submit"
|
||||
class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
|
||||
id="cancelWebAuthnAIA" name="cancel-aia" value="true"/>${msg("doCancel")}
|
||||
</button>
|
||||
</form>
|
||||
<#else>
|
||||
<script>
|
||||
registerSecurityKey();
|
||||
</script>
|
||||
</#if>
|
||||
|
||||
</#if>
|
||||
</@layout.registrationLayout>
|
18
makefile
Normal file
18
makefile
Normal file
@ -0,0 +1,18 @@
|
||||
default: run
|
||||
|
||||
run: ## run a new container
|
||||
@docker run \
|
||||
-p 8080:8080 \
|
||||
-v $$(pwd)/lumbung.space:/opt/jboss/keycloak/themes/lumbung.space \
|
||||
-v $$(pwd)/bin/disable-theme-cache.cli:/opt/jboss/startup-scripts/disable-theme-cache.cli \
|
||||
-e KEYCLOAK_USER=admin \
|
||||
-e KEYCLOAK_PASSWORD=admin \
|
||||
--name keycloakdev \
|
||||
--rm \
|
||||
jboss/keycloak:12.0.4
|
||||
|
||||
shell: ## get a shell in the container
|
||||
@docker exec -it keycloakdev /bin/bash
|
||||
|
||||
stop: ## tear down the container
|
||||
@docker stop keycloakdev && docker rm keycloakdev
|
Reference in New Issue
Block a user