new configuration version

This commit is contained in:
aca 2025-02-26 12:49:54 +00:00
parent cdfa3e9629
commit f4021b0a9d
221 changed files with 68184 additions and 0 deletions

View File

@ -0,0 +1,61 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisComponent"
metadata:
name: "ob-auth-v1"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-auth-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "d00b0dcbe241793d30daf91c"
spec:
type: "NevisAuth"
replicas: 1
version: "8.2411.1"
gitInitVersion: "1.3.0"
runAsNonRoot: true
ports:
management: 9000
soap: 8991
resources:
limits:
cpu: "1000m"
memory: "1000Mi"
requests:
cpu: "20m"
memory: "200Mi"
livenessProbe:
soap:
tcpSocket: true
periodSeconds: 5
timeoutSeconds: 4
readinessProbe:
management:
httpGet:
path: "/nevisauth/liveness"
periodSeconds: 5
timeoutSeconds: 6
startupProbe:
management:
httpGet:
path: "/nevisauth/liveness"
periodSeconds: 5
timeoutSeconds: 6
failureThreshold: 50
podDisruptionBudget:
maxUnavailable: "50%"
git:
tag: "r-ba59b3f1caf0da0e0f0589650bcae5845f2d05b1"
dir: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT/DEFAULT-DEFAULT-ADN-AGOV-OB-INV/ob-auth-v1"
credentials: "git-credentials"
keystores:
- "ob-auth-v1-default-identity"
- "ob-auth-v1-ob-realm-accessapp-registration-nevisfido-tls-client"
truststores:
- "ob-auth-v1-ob-realm-accessapp-registration-nevisfido-tls-trust"
- "ob-auth-v1-default-tls-client-trust"
- "ob-auth-v1-agov-work-internal-trust-store"
podSecurity:
policy: "baseline"
automountServiceAccountToken: false
timeZone: "Europe/Zurich"

View File

@ -0,0 +1,14 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisTrustStore"
metadata:
name: "ob-auth-v1-agov-work-internal-trust-store"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-auth-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "d00b0dcbe241793d30daf91c"
spec:
keystores: []
extraCerts:
- "-----BEGIN CERTIFICATE-----\nMIIBcTCCARagAwIBAgIQWRl1eifIt8yohQYzh6yr/jAKBggqhkjOPQQDAjAYMRYw\nFAYDVQQDEw1zZWxmc2lnbmVkLWNhMB4XDTIzMDYyODE0MzI0MFoXDTQzMDYyODE0\nMzI0MFowGDEWMBQGA1UEAxMNc2VsZnNpZ25lZC1jYTBZMBMGByqGSM49AgEGCCqG\nSM49AwEHA0IABEwcjsIhSyyh0i9zP1G7ReOkFt/djzlGoUtSd5v3ZEk5QoZYjfl9\n04HdaZzrmveB2aRppbXgW7//s2Ma8wTd5uejQjBAMA4GA1UdDwEB/wQEAwICpDAP\nBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBT7YRoWIjHwkvFicwvk0Tx/yA4uUTAK\nBggqhkjOPQQDAgNJADBGAiEAgyg9t0qgb+czuscs07pNGI+12BedrD+y71psIlqx\nt2UCIQC/85UXyjYI9zg7Mg7rROTbGNCU3Jq/KIC3VzbbD+68VA==\n-----END CERTIFICATE-----\n"

View File

@ -0,0 +1,18 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisKeyStore"
metadata:
name: "ob-auth-v1-default-identity"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-auth-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "d00b0dcbe241793d30daf91c"
spec:
cn: "ob-auth-v1"
usage: "<reserved for future use>"
san:
dns:
- "ob-auth-v1"
- "ob-auth-v1.adn-agov-nevisidm-ob-01-uat"
email: []

View File

@ -0,0 +1,16 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisTrustStore"
metadata:
name: "ob-auth-v1-default-tls-client-trust"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-auth-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "d00b0dcbe241793d30daf91c"
spec:
keystores:
- name: "ob-proxy-v1-ob-realm-identity"
namespace: "adn-agov-nevisidm-ob-01-uat"
- name: "ob-proxy-v1-ob-mock-me-realm-identity"
namespace: "adn-agov-nevisidm-ob-01-uat"

View File

@ -0,0 +1,18 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisKeyStore"
metadata:
name: "ob-auth-v1-ob-realm-accessapp-registration-nevisfido-tls-client"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-auth-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "d00b0dcbe241793d30daf91c"
spec:
cn: "ob-auth-v1"
usage: "<reserved for future use>"
san:
dns:
- "ob-auth-v1"
- "ob-auth-v1.adn-agov-nevisidm-ob-01-uat"
email: []

View File

@ -0,0 +1,14 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisTrustStore"
metadata:
name: "ob-auth-v1-ob-realm-accessapp-registration-nevisfido-tls-trust"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-auth-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "d00b0dcbe241793d30daf91c"
spec:
keystores:
- name: "ob-fido-uaf-v1-default-server-identity"
namespace: "adn-agov-nevisidm-ob-01-uat"

View File

@ -0,0 +1,18 @@
schemaVersion: 1.0
instance:
type: "nevisauth"
name: "default"
directory: "/var/opt/nevisauth/default"
pid: "systemctl show nevisauth@default -p MainPID | cut -d '=' -f2"
source:
url: "/nevisadmin/#/projects/DEFAULT-ADN-AGOV-WORK-OB-PROJECT/patterns/d00b0dcbe241793d30daf91c"
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "d00b0dcbe241793d30daf91c"
patternClass: "ch.nevis.admin.v4.plugin.nevisauth.patterns.NevisAuthDeployable"
resources:
ports:
- "0.0.0.0:8991"
control:
start: "systemctl restart nevisauth@default &"
stop: "systemctl stop nevisauth@default"
status: "systemctl status nevisauth@default"

View File

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICwzCCAmmgAwIBAgIRAIgdSB3tN8ZLL8RUMEGevQQwCgYIKoZIzj0EAwIwGDEW
MBQGA1UEAxMNc2VsZnNpZ25lZC1jYTAeFw0yNDA3MTcwNzI5MDFaFw0yNTA3MTcw
NzI5MDFaMFYxCzAJBgNVBAYTAkNIMQwwCgYDVQQIEwNLOFMxDDAKBgNVBAcTA0s4
UzEMMAoGA1UEChMDSzhTMQwwCgYDVQQLEwNLOFMxDzANBgNVBAMTBnNpZ25lcjCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOyJFpEW1XRq43YwOU/e9ufh
128Yct8Q3f6HoRaXpUmygAkUsyBwOLWmwNeS80SLyOVegco6kGOdoMvnZsLX3ujf
cASkbN+93xhc2MpJXvfWbLbFGrpuQki3V5Banw+UulBuTltFLmxaIRXs1y4Ny2uh
US98LjFY3YD+3d5WG7UpgRTJ+x+t+8nqnPVOJ5asfcirM8/lRB4drUAwCOv51XLR
fRbqCaXKpVaiw/vD5KpAOUH2N1cikfOTOY6rce0wgVDGS7eoCfkCN4gT1LG+134M
p0KT3FBikTGdkH6dQ52nTn7xm5byJvNYzq+2zKGdosYAGurdGGw+KLFsFKCpB40C
AwEAAaOBijCBhzAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU+2EaFiIx8JLxYnML
5NE8f8gOLlEwJwYDVR0RBCAwHoIGc2lnbmVygRRub3JlcGx5QGxvY2FsLmRvbWFp
bjAKBggqhkjOPQQDAgNIADBFAiBxCyNHGWTpj8oma8cY/rUVMZu/BSDH7zzrDhh6
Q9eJegIhAIGivTcBUZvogUDfNo7IXmmxDqZHrjpoLeu6+VgTY9Qs
-----END CERTIFICATE-----

View File

@ -0,0 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFKzBVBgkqhkiG9w0BBQ0wSDAnBgkqhkiG9w0BBQwwGgQU5G+vkuO2cctjh5w3
9UCspxzos1oCAggAMB0GCWCGSAFlAwQBKgQQk38FPw+39UGxhLjFx1ZinwSCBNBF
yCOvE7KGjMIkIEm1hm+Pi5VKUKUVh4spl3aT4BcYNtcGrQ6YSTHp5V5Y+O24GJTB
3EzH0Cg1YqFZdu/O361nVd9wQrduk35n4pTfWZrBkZ7LnUIvIfmvwowCk/sIT2R+
ei/ljQcXlzZB5He5SB4qu7OywIHArp13701sBGYyl4kUqPXx/FVC9gkiK5dzHfoi
t6PK8nbykDYhiMn7L4CuDGItCjjcdfat/Il3ycPsnvQX6z3iX9sIOxHpLRSZqkB/
Da/VLC7h+t6J5NpudpGXHhZBTq5ov6LOFsFesV8+ZkHaCqAeuZiUBFYKK9de5KUr
wxb5HDjA595l/oeiPtbeH9yocZhNf0vza4520AeuwEqmzKYfvmKz/pKTwLy1VbK5
88+bIPw3vz6VP1riP8ULVBOAV3kAKU0NRQd6lnIorDQ6MkEHO3JOyFNKYNswF8tu
s7gEzSKg8eBA/B+L8liczo89ItImyudXCHwEWcJY6uzKEaHxg2HS1DDD/pI8w8Sl
mU6OQnlL5sm2X82H75tAkni03aQueL43qE5LN5QCcXUrVO9Un737fX2/m2fZB/b9
pmy4CWjwDrXXsABf3mgiaBFbXzxRO8zDtDmNzsZnuywLNepsv1nPEV8tI7WO6c+J
Bwba8h/Vz9ulNd8u/bX3TPr/FGgAmfIwf8Hz2Rmy4Jy6Dt7nlLOYT6NSx5QNXujC
0vEnF8WQaCt+KHxOERb/5zb/OlVS+4Fech9NGmmTSfmTakGbmN6H7VpHa20q98fL
b8jLbQaDDrJ1wOumykfCAzsDpq5uGjLBu7qqTF9ZOFbNc00wAcLiZd7Oavmzocn5
PbS22IdutIhqJtREqJaZYstXQ1bzdKfPjML+SPjDb9mbqlzDFvikqDyCMpje8X7v
/bulMe/8ViEn6WemfCULrBbchFZpgRBmZFtUiNqYuv1Ib+mx83Wha8ApdvdclYn4
S8FBeZ8u+6usCz5QvaiLTyI5CTKf6u8fnaJ3mfa2yPEyq4tKVjoIliVAGMAX2v6b
Ky5Wq6UzhoRPnDdXxAsPsnypAVmfLBHea10VZd/cGH6eTKdi15PLnFqvlnFaSxVS
irR77Ze0As/+CZ3sD6vxihHGw94y4gWYYjr3NJwTR9aUQHHondh0UYE0aNarQiRz
DEVUhM6hCiQZAdp6VqgVlow4TCZ4KLAWlpXthOLml7dcZBPc+kLAhP30LFvbEDFS
/3TCHZeedFJfyY99fQOe43Qz2cftJhQzYuCxTo+bLG8rR+x3MNY9Mj20a1fVNCDr
/cc5jEu04tnr9g7UNBeGXXsTfX9oDAJeepp3w05AQKMoPBO1ow6REUDcrOoITmaj
Xdfr1uY41WQEJGURE/edArpJDsamml5qfecuW18RLGKKN2uMbTPV6+xGhpwlxFyL
pv08rFkSTuOr8EHCtA4I7YsPE8pwAcVQJX9eveP6JbebxLJcazX5BzYFcZe0fyye
EvLYNM/ppExaajWNddvluvxiJ36MOXR7Kn4jQIRmRl4nzroQ8OsrNn9GlpXmn7zn
8yHp19awVyjy5DTRq9b79Dj27bBxsB/nm85DhFUDLLNCBIA80msIg7+GwjCgy4dx
6joKO6WQzBap8NP2Y5Vk3EA89wHWhw42I1G4s/mXug==
-----END ENCRYPTED PRIVATE KEY-----

View File

@ -0,0 +1,2 @@
#!/bin/bash
echo 'yQ4X0JxsgxmmuG5j14vIdkdkqTJOEqog7Xs5UgVbo='

View File

@ -0,0 +1,48 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFKzBVBgkqhkiG9w0BBQ0wSDAnBgkqhkiG9w0BBQwwGgQU5G+vkuO2cctjh5w3
9UCspxzos1oCAggAMB0GCWCGSAFlAwQBKgQQk38FPw+39UGxhLjFx1ZinwSCBNBF
yCOvE7KGjMIkIEm1hm+Pi5VKUKUVh4spl3aT4BcYNtcGrQ6YSTHp5V5Y+O24GJTB
3EzH0Cg1YqFZdu/O361nVd9wQrduk35n4pTfWZrBkZ7LnUIvIfmvwowCk/sIT2R+
ei/ljQcXlzZB5He5SB4qu7OywIHArp13701sBGYyl4kUqPXx/FVC9gkiK5dzHfoi
t6PK8nbykDYhiMn7L4CuDGItCjjcdfat/Il3ycPsnvQX6z3iX9sIOxHpLRSZqkB/
Da/VLC7h+t6J5NpudpGXHhZBTq5ov6LOFsFesV8+ZkHaCqAeuZiUBFYKK9de5KUr
wxb5HDjA595l/oeiPtbeH9yocZhNf0vza4520AeuwEqmzKYfvmKz/pKTwLy1VbK5
88+bIPw3vz6VP1riP8ULVBOAV3kAKU0NRQd6lnIorDQ6MkEHO3JOyFNKYNswF8tu
s7gEzSKg8eBA/B+L8liczo89ItImyudXCHwEWcJY6uzKEaHxg2HS1DDD/pI8w8Sl
mU6OQnlL5sm2X82H75tAkni03aQueL43qE5LN5QCcXUrVO9Un737fX2/m2fZB/b9
pmy4CWjwDrXXsABf3mgiaBFbXzxRO8zDtDmNzsZnuywLNepsv1nPEV8tI7WO6c+J
Bwba8h/Vz9ulNd8u/bX3TPr/FGgAmfIwf8Hz2Rmy4Jy6Dt7nlLOYT6NSx5QNXujC
0vEnF8WQaCt+KHxOERb/5zb/OlVS+4Fech9NGmmTSfmTakGbmN6H7VpHa20q98fL
b8jLbQaDDrJ1wOumykfCAzsDpq5uGjLBu7qqTF9ZOFbNc00wAcLiZd7Oavmzocn5
PbS22IdutIhqJtREqJaZYstXQ1bzdKfPjML+SPjDb9mbqlzDFvikqDyCMpje8X7v
/bulMe/8ViEn6WemfCULrBbchFZpgRBmZFtUiNqYuv1Ib+mx83Wha8ApdvdclYn4
S8FBeZ8u+6usCz5QvaiLTyI5CTKf6u8fnaJ3mfa2yPEyq4tKVjoIliVAGMAX2v6b
Ky5Wq6UzhoRPnDdXxAsPsnypAVmfLBHea10VZd/cGH6eTKdi15PLnFqvlnFaSxVS
irR77Ze0As/+CZ3sD6vxihHGw94y4gWYYjr3NJwTR9aUQHHondh0UYE0aNarQiRz
DEVUhM6hCiQZAdp6VqgVlow4TCZ4KLAWlpXthOLml7dcZBPc+kLAhP30LFvbEDFS
/3TCHZeedFJfyY99fQOe43Qz2cftJhQzYuCxTo+bLG8rR+x3MNY9Mj20a1fVNCDr
/cc5jEu04tnr9g7UNBeGXXsTfX9oDAJeepp3w05AQKMoPBO1ow6REUDcrOoITmaj
Xdfr1uY41WQEJGURE/edArpJDsamml5qfecuW18RLGKKN2uMbTPV6+xGhpwlxFyL
pv08rFkSTuOr8EHCtA4I7YsPE8pwAcVQJX9eveP6JbebxLJcazX5BzYFcZe0fyye
EvLYNM/ppExaajWNddvluvxiJ36MOXR7Kn4jQIRmRl4nzroQ8OsrNn9GlpXmn7zn
8yHp19awVyjy5DTRq9b79Dj27bBxsB/nm85DhFUDLLNCBIA80msIg7+GwjCgy4dx
6joKO6WQzBap8NP2Y5Vk3EA89wHWhw42I1G4s/mXug==
-----END ENCRYPTED PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICwzCCAmmgAwIBAgIRAIgdSB3tN8ZLL8RUMEGevQQwCgYIKoZIzj0EAwIwGDEW
MBQGA1UEAxMNc2VsZnNpZ25lZC1jYTAeFw0yNDA3MTcwNzI5MDFaFw0yNTA3MTcw
NzI5MDFaMFYxCzAJBgNVBAYTAkNIMQwwCgYDVQQIEwNLOFMxDDAKBgNVBAcTA0s4
UzEMMAoGA1UEChMDSzhTMQwwCgYDVQQLEwNLOFMxDzANBgNVBAMTBnNpZ25lcjCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOyJFpEW1XRq43YwOU/e9ufh
128Yct8Q3f6HoRaXpUmygAkUsyBwOLWmwNeS80SLyOVegco6kGOdoMvnZsLX3ujf
cASkbN+93xhc2MpJXvfWbLbFGrpuQki3V5Banw+UulBuTltFLmxaIRXs1y4Ny2uh
US98LjFY3YD+3d5WG7UpgRTJ+x+t+8nqnPVOJ5asfcirM8/lRB4drUAwCOv51XLR
fRbqCaXKpVaiw/vD5KpAOUH2N1cikfOTOY6rce0wgVDGS7eoCfkCN4gT1LG+134M
p0KT3FBikTGdkH6dQ52nTn7xm5byJvNYzq+2zKGdosYAGurdGGw+KLFsFKCpB40C
AwEAAaOBijCBhzAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU+2EaFiIx8JLxYnML
5NE8f8gOLlEwJwYDVR0RBCAwHoIGc2lnbmVygRRub3JlcGx5QGxvY2FsLmRvbWFp
bjAKBggqhkjOPQQDAgNIADBFAiBxCyNHGWTpj8oma8cY/rUVMZu/BSDH7zzrDhh6
Q9eJegIhAIGivTcBUZvogUDfNo7IXmmxDqZHrjpoLeu6+VgTY9Qs
-----END CERTIFICATE-----

View File

@ -0,0 +1,101 @@
accept.button.label=Accept
button.submit=Submit
cancel.button.label=Cancel
continue.button.label=Continue
deputy.profile.label=(Deputy Profile)
error.policy.failed=The new password does not comply with the policy.
error.saml.failed=Please close your browser and try again.
error_1=Please check your input.
error_10=Please select the correct user account.
error_100=Certificate upload not possible. Certificate already exists. Please contact your helpdesk.
error_101=The entered email address is not valid.
error_11=Please use another certficate or login with another credential type.
error_2=Please select another login name.
error_3=Your account will be locked if next authentication fails.
error_4=Your new password does not comply with the security policy. Please choose a different password.
error_5=Error in password confirmation.
error_50=The new password is too short.
error_55=The new password has to differ from old passwords.
error_6=Password change required.
error_7=Change of login ID required.
error_8=Your account has been locked due to repeated authentication failures.
error_81=No access card found, access from internet denied.
error_83=Your access card is no longer valid. Please contact your advisor to get a new access card.
error_9=Session take over failed.
error_97=You are not authorized to access this resource.
error_98=Your account has been locked.
error_99=System problems. Please try later.
info.login=Please enter your authentication information.
info.logout.confirmation=Please confirm that you want to log out.
info.logout.reminder=Your session on this application has expired. Try again with a login.
info.oauth.consent=Do you want to authorise this application to access your data?
info.signup.passwordless=Log in quickly and securely next time using this device's fingerprint, face recognition, or PIN.
info.signup.passwordless.failed=Use the same method you already use on this device for login.
info.signup.passwordless.skip=<button name="cancel-bottom" type="submit" value="true" class="btn btn-link link-primary">Skip for now</button>
info.timeout.page=Your session on this application has expired. Try again with a login.
login.button.label=Login
logout.label=Logout
logout.text=You have successfully logged out.
method.certificate.label=Certificate
method.fido.label=Mobile Authentication
method.fido2.label=FIDO 2
method.mtan.label=mTAN Code
method.oath.label=OATH Authenticator App
method.otp.label=OTP (One-Time Password)
method.recovery.label=Recovery Codes
method.safeword.label=SafeWord
method.securid.label=SecurID
method.ticket.label=Ticket
outarg.lastLogin.never=Never
policyFailure.dictionary=&#9642; must not be taken from a dictionary.
policyFailure.history.History=&#9642; must be different from previously selected passwords.
policyFailure.regex.control=&#9642; cannot contain more than {0} control characters.
policyFailure.regex.lower=&#9642; must contain at least {0} lower case characters.
policyFailure.regex.maxCharacterRepetitions=&#9642; characters must not occur more than {0} time(s) consecutively.
policyFailure.regex.maxLength=&#9642; must be at most {0} characters long.
policyFailure.regex.minLength=&#9642; must be at least {0} characters long.
policyFailure.regex.nonAlnum=&#9642; must contain at least {0} non-alphanumeric characters.
policyFailure.regex.nonAscii=&#9642; cannot contain more than {0} non-ASCII characters.
policyFailure.regex.nonGraph=&#9642; cannot contain more than {0} non-printable characters.
policyFailure.regex.nonLetter=&#9642; must contain at least {0} non-letter characters.
policyFailure.regex.numeric=&#9642; must contain at least {0} numeric characters.
policyFailure.regex.upper=&#9642; must contain at least {0} upper case characters.
policyInfo.dictionary=&#9642; must not be taken from a dictionary.
policyInfo.history.History=&#9642; must be different from previously selected passwords.
policyInfo.regex.control=&#9642; cannot contain more than {0} control characters.
policyInfo.regex.lower=&#9642; must contain at least {0} lower case characters.
policyInfo.regex.maxCharacterRepetitions=&#9642; characters must not occur more than {0} time(s) consecutively.
policyInfo.regex.maxLength=&#9642; must be at most {0} characters long.
policyInfo.regex.minLength=&#9642; must be at least {0} characters long.
policyInfo.regex.nonAlnum=&#9642; must contain at least {0} non-alphanumeric characters.
policyInfo.regex.nonAscii=&#9642; cannot contain more than {0} non-ASCII characters.
policyInfo.regex.nonGraph=&#9642; cannot contain more than {0} non-printable characters.
policyInfo.regex.nonLetter=&#9642; must contain at least {0} non-letter characters.
policyInfo.regex.numeric=&#9642; must contain at least {0} numeric characters.
policyInfo.regex.upper=&#9642; must contain at least {0} upper case characters.
policyInfo.title=The password has to comply with the following password policy:
prompt.client=Client
prompt.newpassword=New Password
prompt.newpassword.confirm=Confirm Password
prompt.password=Password
prompt.userid=User-ID
pwreset.done.info=Your password was successfully changed. Please click on continue to log in.
pwreset.email.sent=If your user ID exists, an email to reset your password has been sent to you.
pwreset.info.linktext=Password forgotten
pwreset.noticket=Your password reset link is no longer valid. Please generate a new one.
reject.button.label=Deny
submit.button.label=Submit
tan.sent=Please enter the security code which has been sent to your mobile phone.
title.login=Login
title.logout=Logout
title.logout.confirmation=Logout
title.logout.reminder=Logout
title.oauth.consent=Client Authorization
title.pwchange.label=Password Change
title.pwreset=Password Forgotten
title.saml.failed=Error
title.signup.passwordless=Go passwordless
title.signup.passwordless.failed=Failed to turn on passwordless
title.timeout.page=Logout
try_again.button.label=Try again

View File

@ -0,0 +1,101 @@
accept.button.label=Akzeptieren
button.submit=Senden
cancel.button.label=Abbrechen
continue.button.label=Weiter
deputy.profile.label=(Profil Stellvertreter)
error.policy.failed=Das neue Passwort stimmt nicht mit der Richtlinie &uuml;berein.
error.saml.failed=Bitte schliessen Sie Ihren Browser und versuchen Sie es erneut.
error_1=Bitte &uuml;berpr&uuml;fen Sie Ihre Eingabe.
error_10=Bitte w&auml;hlen Sie den gew&uuml;nschten Benutzer.
error_100=Zertifikat-Upload nicht m&ouml;glich. Zertifikat bereits vorhanden. Bitte kontaktieren Sie Ihren Helpdesk.
error_101=Die angegebene E-Mail Adresse ist ung&uuml;ltig.
error_11=Bitte verwenden Sie ein anderes Zertifikat oder ein alternatives Authentisierungsmittel.
error_2=Bitte w&auml;hlen Sie einen anderen Login-Namen.
error_3=Falls Ihr n&auml;chster Login fehlschl&auml;gt, wird Ihr Konto gesperrt.
error_4=Ihr neues Passwort wurde nicht akzeptiert. Bitte w&auml;hlen Sie eines, das den Passwortvorgaben entspricht.
error_5=Die Eingabe zur Best&auml;tigung des Passwortes ist falsch.
error_50=Das neue Passwort ist zu kurz.
error_55=Das neue Passwort muss sich von alten Passw&ouml;rtern unterscheiden.
error_6=Passwortwechsel erforderlich.
error_7=Wechsel der Login-ID erforderlich.
error_8=Ihr Konto wurde infolge wiederholt fehlgeschlagener Authentisierung gesperrt.
error_81=Keine Rasterkarte gefunden, Zugang vom Internet verweigert.
error_83=Ihre Rasterkarte ist aufgebraucht. Bitte kontaktieren Sie Ihren Berater, um eine neue zu erhalten.
error_9=Die SSO-Session konnte nicht &uuml;bernommen werden.
error_97=Sie verf&uuml;gen nicht &uuml;ber die f&uuml;r den Zugriff auf diese Ressource ben&ouml;tigte Berechtigung.
error_98=Ihr Konto ist gesperrt.
error_99=Systemfehler. Bitte versuchen Sie es sp&auml;ter.
info.login=Bitte geben Sie Ihre pers&ouml;nlichen Zugangsdaten ein.
info.logout.confirmation=Bitte best&auml;tigen Sie, dass Sie sich abmelden m&ouml;chten.
info.logout.reminder=Ihre Session ist auf dieser Applikation abgelaufen. Versuchen Sie es nochmals mit einem Login.
info.oauth.consent=Wollen Sie der Anwendung den Zugriff erlauben?
info.signup.passwordless=Melden Sie sich beim nächsten Mal schnell und sicher mit dem Fingerabdruck, der Gesichtserkennung oder der PIN dieses Geräts an.
info.signup.passwordless.failed=Verwenden Sie dieselbe Methode, die Sie bereits für die Anmeldung verwenden.
info.signup.passwordless.skip=<button name="cancel-bottom" type="submit" value="true" class="btn btn-link link-primary">Vorerst überspringen</button>
info.timeout.page=Ihre Session ist auf dieser Applikation abgelaufen. Versuchen Sie es nochmals mit einem Login.
login.button.label=Login
logout.label=Logout
logout.text=Sie haben sich erfolgreich abgemeldet.
method.certificate.label=Zertifikat
method.fido.label=Mobile Authentication
method.fido2.label=FIDO 2
method.mtan.label=mTAN-Code
method.oath.label=OATH Authenticator-App
method.otp.label=OTP (One-Time Passwort)
method.recovery.label=Wiederherstellungscodes
method.safeword.label=SafeWord
method.securid.label=SecurID
method.ticket.label=Ticket
outarg.lastLogin.never=Nie
policyFailure.dictionary=&#9642; darf nicht aus einem W&ouml;rterbuch stammen.
policyFailure.history.History=&#9642; muss sich von vorhergehenden Passw&ouml;rtern unterscheiden.
policyFailure.regex.control=&#9642; darf h&ouml;chstens {0} Kontrollzeichen enthalten.
policyFailure.regex.lower=&#9642; muss {0} Kleinbuchstaben enthalten.
policyFailure.regex.maxCharacterRepetitions=&#9642; darf nicht eine Sequenz l&auml;nger als {0} des gleichen Zeichens enthalten.
policyFailure.regex.maxLength=L&auml;nge des Passwortes darf h&ouml;chstens {0} sein.
policyFailure.regex.minLength=L&auml;nge des Passwortes muss mindestens {0} sein.
policyFailure.regex.nonAlnum=&#9642; muss {0} nicht-alphanumerische Zeichen enthalten.
policyFailure.regex.nonAscii=&#9642; darf h&ouml;chstens {0} Zeichen ausserhalb des ASCII-Zeichensatzes enthalten.
policyFailure.regex.nonGraph=&#9642; darf h&ouml;chstens {0} nicht-druckende Zeichen enthalten.
policyFailure.regex.nonLetter=&#9642; muss {0} Zeichen enthalten, die keine Buchstaben sind.
policyFailure.regex.numeric=&#9642; muss {0} numerische Zeichen enthalten.
policyFailure.regex.upper=&#9642; muss {0} Grossbuchstaben enthalten.
policyInfo.dictionary=&#9642; darf nicht aus einem W&ouml;rterbuch stammen.
policyInfo.history.History=&#9642; darf keines der zuletzt verwendeten Passw&ouml;rtern sein.
policyInfo.regex.control=&#9642; darf h&ouml;chstens {0} Kontrollzeichen enthalten.
policyInfo.regex.lower=&#9642; muss mindestens {0} Kleinbuchstaben enthalten.
policyInfo.regex.maxCharacterRepetitions=&#9642; darf nicht eine Sequenz l&auml;nger als {0} des gleichen Zeichens enthalten.
policyInfo.regex.maxLength=&#9642; darf h&ouml;chstens {0} Zeichen enthalten.
policyInfo.regex.minLength=&#9642; muss mindestens {0} Zeichen enthalten.
policyInfo.regex.nonAlnum=&#9642; muss mindestens {0} Zeichen enthalten, die nicht Alphanumerisch sind.
policyInfo.regex.nonAscii=&#9642; darf h&ouml;chstens {0} Zeichen ausserhalb des ASCII-Zeichensatzes enthalten.
policyInfo.regex.nonGraph=&#9642; darf h&ouml;chstens {0} nicht-druckende Zeichen enthalten.
policyInfo.regex.nonLetter=&#9642; muss mindestens {0} Zeichen enthalten, die keine Buchstaben sind.
policyInfo.regex.numeric=&#9642; muss mindestens {0} numerische Zeichen enthalten.
policyInfo.regex.upper=&#9642; muss mindestens {0} Grossbuchstaben enthalten.
policyInfo.title=Das Passwort muss den folgenden Passwort-Richtlinien entsprechen:
prompt.client=Mandant
prompt.newpassword=Neues Passwort
prompt.newpassword.confirm=Passwort best&auml;tigen
prompt.password=Passwort
prompt.userid=Benutzer-ID
pwreset.done.info=Ihr Passwort wurde erfolgreich ge&auml;ndert. Bitte klicken Sie auf Weiter, um sich einzuloggen.
pwreset.email.sent=Wenn Ihre Benutzer-ID existiert, haben Sie eine E-Mail erhalten, um Ihr Passwort zurückzusetzen..
pwreset.info.linktext=Passwort vergessen
pwreset.noticket=Ihr Link ist nicht mehr g&uuml;ltig. Bitte generieren Sie ein Neuen.
reject.button.label=Ablehnen
submit.button.label=Senden
tan.sent=Bitte erfassen Sie den Sicherheitscode, welcher an Ihr Mobiltelefon gesendet wurde.
title.login=Login
title.logout=Logout
title.logout.confirmation=Logout
title.logout.reminder=Logout
title.oauth.consent=Client Authorisierung
title.pwchange.label=Passwort &auml;ndern
title.pwreset=Passwort Vergesssen
title.saml.failed=Error
title.signup.passwordless=Login ohne Passwort
title.signup.passwordless.failed=Login ohne Passwort konnte nicht aktiviert werden
title.timeout.page=Logout
try_again.button.label=Erneut versuchen

View File

@ -0,0 +1,101 @@
accept.button.label=Accept
button.submit=Submit
cancel.button.label=Cancel
continue.button.label=Continue
deputy.profile.label=(Deputy Profile)
error.policy.failed=The new password does not comply with the policy.
error.saml.failed=Please close your browser and try again.
error_1=Please check your input.
error_10=Please select the correct user account.
error_100=Certificate upload not possible. Certificate already exists. Please contact your helpdesk.
error_101=The entered email address is not valid.
error_11=Please use another certficate or login with another credential type.
error_2=Please select another login name.
error_3=Your account will be locked if next authentication fails.
error_4=Your new password does not comply with the security policy. Please choose a different password.
error_5=Error in password confirmation.
error_50=The new password is too short.
error_55=The new password has to differ from old passwords.
error_6=Password change required.
error_7=Change of login ID required.
error_8=Your account has been locked due to repeated authentication failures.
error_81=No access card found, access from internet denied.
error_83=Your access card is no longer valid. Please contact your advisor to get a new access card.
error_9=Session take over failed.
error_97=You are not authorized to access this resource.
error_98=Your account has been locked.
error_99=System problems. Please try later.
info.login=Please enter your authentication information.
info.logout.confirmation=Please confirm that you want to log out.
info.logout.reminder=Your session on this application has expired. Try again with a login.
info.oauth.consent=Do you want to authorise this application to access your data?
info.signup.passwordless=Log in quickly and securely next time using this device's fingerprint, face recognition, or PIN.
info.signup.passwordless.failed=Use the same method you already use on this device for login.
info.signup.passwordless.skip=<button name="cancel-bottom" type="submit" value="true" class="btn btn-link link-primary">Skip for now</button>
info.timeout.page=Your session on this application has expired. Try again with a login.
login.button.label=Login
logout.label=Logout
logout.text=You have successfully logged out.
method.certificate.label=Certificate
method.fido.label=Mobile Authentication
method.fido2.label=FIDO 2
method.mtan.label=mTAN Code
method.oath.label=OATH Authenticator App
method.otp.label=OTP (One-Time Password)
method.recovery.label=Recovery Codes
method.safeword.label=SafeWord
method.securid.label=SecurID
method.ticket.label=Ticket
outarg.lastLogin.never=Never
policyFailure.dictionary=&#9642; must not be taken from a dictionary.
policyFailure.history.History=&#9642; must be different from previously selected passwords.
policyFailure.regex.control=&#9642; cannot contain more than {0} control characters.
policyFailure.regex.lower=&#9642; must contain at least {0} lower case characters.
policyFailure.regex.maxCharacterRepetitions=&#9642; characters must not occur more than {0} time(s) consecutively.
policyFailure.regex.maxLength=&#9642; must be at most {0} characters long.
policyFailure.regex.minLength=&#9642; must be at least {0} characters long.
policyFailure.regex.nonAlnum=&#9642; must contain at least {0} non-alphanumeric characters.
policyFailure.regex.nonAscii=&#9642; cannot contain more than {0} non-ASCII characters.
policyFailure.regex.nonGraph=&#9642; cannot contain more than {0} non-printable characters.
policyFailure.regex.nonLetter=&#9642; must contain at least {0} non-letter characters.
policyFailure.regex.numeric=&#9642; must contain at least {0} numeric characters.
policyFailure.regex.upper=&#9642; must contain at least {0} upper case characters.
policyInfo.dictionary=&#9642; must not be taken from a dictionary.
policyInfo.history.History=&#9642; must be different from previously selected passwords.
policyInfo.regex.control=&#9642; cannot contain more than {0} control characters.
policyInfo.regex.lower=&#9642; must contain at least {0} lower case characters.
policyInfo.regex.maxCharacterRepetitions=&#9642; characters must not occur more than {0} time(s) consecutively.
policyInfo.regex.maxLength=&#9642; must be at most {0} characters long.
policyInfo.regex.minLength=&#9642; must be at least {0} characters long.
policyInfo.regex.nonAlnum=&#9642; must contain at least {0} non-alphanumeric characters.
policyInfo.regex.nonAscii=&#9642; cannot contain more than {0} non-ASCII characters.
policyInfo.regex.nonGraph=&#9642; cannot contain more than {0} non-printable characters.
policyInfo.regex.nonLetter=&#9642; must contain at least {0} non-letter characters.
policyInfo.regex.numeric=&#9642; must contain at least {0} numeric characters.
policyInfo.regex.upper=&#9642; must contain at least {0} upper case characters.
policyInfo.title=The password has to comply with the following password policy:
prompt.client=Client
prompt.newpassword=New Password
prompt.newpassword.confirm=Confirm Password
prompt.password=Password
prompt.userid=User-ID
pwreset.done.info=Your password was successfully changed. Please click on continue to log in.
pwreset.email.sent=If your user ID exists, an email to reset your password has been sent to you.
pwreset.info.linktext=Password forgotten
pwreset.noticket=Your password reset link is no longer valid. Please generate a new one.
reject.button.label=Deny
submit.button.label=Submit
tan.sent=Please enter the security code which has been sent to your mobile phone.
title.login=Login
title.logout=Logout
title.logout.confirmation=Logout
title.logout.reminder=Logout
title.oauth.consent=Client Authorization
title.pwchange.label=Password Change
title.pwreset=Password Forgotten
title.saml.failed=Error
title.signup.passwordless=Go passwordless
title.signup.passwordless.failed=Failed to turn on passwordless
title.timeout.page=Logout
try_again.button.label=Try again

View File

@ -0,0 +1,101 @@
accept.button.label=Accepter
button.submit=Envoyer
cancel.button.label=Abandonner
continue.button.label=Continuer
deputy.profile.label=(Profil du suppl&eacute;ant)
error.policy.failed=Votre nouveau mot de passe ne conforme pas aux mesures de s&eacute;curit&eacute;
error.saml.failed=Fermez votre navigateur et r;eacute;essayez.
error_1=Veuillez v&eacute;rifier vos donn&eacute;es, s.v.p.
error_10=Choisissez votre compte.
error_100=T&eacute;l&eacute;chargement du certificat pas possible. Certificat existe d&eacute;j&agrave;. Veuillez contacter le helpdesk s.v.p.
error_101=L&#39;adresse e-mail &eacute; n&#39;est pas valide.
error_11=Choisissez un autre certificat, s.v.p.
error_2=Choisissez un autre nom, s.v.p.
error_3=Si l&#39;authentification ne r&eacute;ussit pas au prochain essai, votre compte sera bloqu&eacute;.
error_4=Votre nouveau mot de passe ne conforme pas aux mesures de s&eacute;curit&eacute;
error_5=Votre confirmation du mot de passe ne correspond pas au mot de passe donn&eacute;.
error_50=Le nouveau mot de passe est trop court.
error_55=Le nouveau mot de passe doit diff&eacute;rer de l&#39;ancien.
error_6=Veuillez changer votre mot de passe, s.v.p.
error_7=Veuillez changer votre login ID, s.v.p.
error_8=Votre compte n&#39;est pas active.
error_81=Pas d&#39;access card trouv&eacute;, l&#39;acc&egrave;s par l&#39;internet est refus&eacute;.
error_83=Votre access card n&#39;est plus valable, veuillez contacter votre gestionnaire.
error_9=Il n&#39;est pas possible de transmettre la session.
error_97=Vous n&#39;avez pas les autorisations n&eacute;cessaires pour acc&eacute;der &agrave; cette ressource.
error_98=Votre compte a &eacute;t&eacute; bloqu&eacute;.
error_99=Probl&egrave;me technique. Veuillez essayer plus tard, s.v.p.
info.login=Veuillez entrer vos &eacute;l&eacute;ments de s&eacute;curit&eacute; ci-apr&egrave;s.
info.logout.confirmation=Veuillez confirmer que vous souhaitez vous d&eacute;connecter.
info.logout.reminder=Votre session sur cette application a expir&eacute;e. Essayez encore avec un login.
info.oauth.consent=Voulez-vous autoriser l&#39;application?
info.signup.passwordless=Connectez-vous rapidement et en toute sécurité la prochaine fois en utilisant l'empreinte digitale, la reconnaissance faciale ou le code PIN de cet appareil.
info.signup.passwordless.failed=Utilisez la même méthode que vous utilisez déjà sur cet appareil pour vous connecter.
info.signup.passwordless.skip=<button name="cancel-bottom" type="submit" value="true" class="btn btn-link link-primary">Sauter pour le moment</button>
info.timeout.page=Votre session sur cette application a expir&eacute;e. Essayez encore avec un login.
login.button.label=Login
logout.label=Logout
logout.text=Au revoir
method.certificate.label=Certificat
method.fido.label=Mobile Authentication
method.fido2.label=FIDO 2
method.mtan.label=Code mTAN
method.oath.label=Application d'authentification OATH
method.otp.label=OTP (One-Time Password)
method.recovery.label=Codes de r&eacute;cup&eacute;ration
method.safeword.label=SafeWord
method.securid.label=SecurID
method.ticket.label=Ticket
outarg.lastLogin.never=Jamais
policyFailure.dictionary=&#9642; ne peut pas &ecirc;tre pris d&#39;un dictionnaire.
policyFailure.history.History=&#9642; doit &ecirc;tre diff&eacute;rent des mots de passe pr&eacute;alablement s&eacute;lectionn&eacute;s.
policyFailure.regex.control=&#9642; ne peut contenir plus de {0} caract&egrave;res de commande.
policyFailure.regex.lower=&#9642; doit contenir au moins {0} caract&egrave;re(s) minuscule(s).
policyFailure.regex.maxCharacterRepetitions=&#9642; ne peut contenir une s&eacute;quence de plus de {0} du m&ecirc;me caract&egrave;re.
policyFailure.regex.maxLength=La longueur doit &ecirc;tre d&#39;au plus {0}.
policyFailure.regex.minLength=La longueur doit &ecirc;tre d&#39;au moins {0}.
policyFailure.regex.nonAlnum=&#9642; doit contenir au moins {0} caract&egrave;res non alphanum&eacute;riques.
policyFailure.regex.nonAscii=&#9642; ne peut contenir plus de {0} caract&egrave;res non ASCII ({1}).
policyFailure.regex.nonGraph=&#9642; ne peut contenir plus de {0} caract&egrave;res non imprimables ({1}).
policyFailure.regex.nonLetter=&#9642; doit contenir au moins {0} caract&egrave;res qui ne sont pas des lettres.
policyFailure.regex.numeric=&#9642; doit comprendre {0} caract&#232;res num&#233;riques.
policyFailure.regex.upper=&#9642; doit contenir au moins {0} caract&egrave;re(s) majuscule(s).
policyInfo.dictionary=&#9642; ne peut pas &ecirc;tre pris d&#39;un dictionnaire.
policyInfo.history.History=&#9642; ne peut pas &ecirc;tre l&#39; pr&eacute;c&eacute;demment choisis.
policyInfo.regex.control=&#9642; ne peut contenir plus de {0} caract&egrave;res de commande.
policyInfo.regex.lower=&#9642; doit contenir au moins {0} caract&egrave;re(s) minuscule(s).
policyInfo.regex.maxCharacterRepetitions=&#9642; ne peut contenir une s&eacute;quence de plus de {0} du m&ecirc;me caract&egrave;re.
policyInfo.regex.maxLength=&#9642; la longueur doit &ecirc;tre d&#39;au plus {0}.
policyInfo.regex.minLength=&#9642; la longueur doit &ecirc;tre d&#39;au moins {0}.
policyInfo.regex.nonAlnum=&#9642; doit contenir au moins {0} caract&egrave;res non alphanum&eacute;riques.
policyInfo.regex.nonAscii=&#9642; ne peut contenir plus de {0} caract&egrave;res non ASCII.
policyInfo.regex.nonGraph=&#9642; ne peut contenir plus de {0} caract&egrave;res non imprimables.
policyInfo.regex.nonLetter=&#9642; doit contenir au moins {0} caract&egrave;res qui ne sont pas des lettres.
policyInfo.regex.numeric=&#9642; doit comprendre au minimum {0} caract&#232;res num&#233;riques.
policyInfo.regex.upper=&#9642; doit contenir au moins {0} caract&egrave;re(s) majuscule(s).
policyInfo.title=Le mot de passe doit respecter les r&egrave;gles suivantes:
prompt.client=Client
prompt.newpassword=Nouveau mot de passe
prompt.newpassword.confirm=Confirmez le mot de passe
prompt.password=Mot de passe
prompt.userid=ID de l&#39;utilisateur
pwreset.done.info=Votre mot de passe a &eacute;t&eacute; chang&eacute avec succ&egrave;s. Veuillez cliquer sur continuer pour vous connecter.
pwreset.email.sent=Si votre identifiant n'existe pas, vous avez reçu un courriel pour réinitialiser votre mot de passe.
pwreset.info.linktext=Mot de passe oublié
pwreset.noticket=Votre lien n&apos;est plus valide. Veuillez en g&eacute;n&eacute;rer un nouveau.
reject.button.label=Refuser
submit.button.label=Envoyer
tan.sent=Veuillez saisir le code de s&eacute;curit&eacute; que vous avez re&ccedil;u au votre t&eacute;l&eacute;phone mobile.
title.login=Login
title.logout=Logout
title.logout.confirmation=Logout
title.logout.reminder=Logout
title.oauth.consent=Autorisation du client
title.pwchange.label=Changer mot de passe
title.pwreset=Mot de Passe Oubli&eacute;
title.saml.failed=Error
title.signup.passwordless=Aller sans mot de passe
title.signup.passwordless.failed=Impossible d'activer le sans mot de passe
title.timeout.page=Logout
try_again.button.label=Essayez à nouveau

View File

@ -0,0 +1,101 @@
accept.button.label=Accettare
button.submit=Continua
cancel.button.label=Abortire
continue.button.label=Continua
deputy.profile.label=(profilo del delegato)
error.policy.failed=La nuova password non &egrave; stata accettata. Scegliere una password che sia conforme ai criteri di password.
error.saml.failed=Chiudi il browser e riprova.
error_1=Verificare i dati immessi.
error_10=Per favore selezionare il conto utente corretto.
error_100=Impossibile caricare il certificato. Questo certificato esiste gi&agrave;. La preghiamo di contattare il Suo help desk.
error_101=L&#39;indirizzo e-mail inserito non &egrave; valido.
error_11=Scegliere un altro certificato.
error_2=Per favore scegliere un altro nome.
error_3=Il conto verr&agrave; bloccato se il prossimo login non andr&agrave; a buon fine.
error_4=La nuova password non &egrave; stata accettata. Scegliere una password che sia conforme ai criteri di password.
error_5=La conferma della password &egrave; errata.
error_50=La nuova password &egrave; troppo corta.
error_55=La nuova password deve essere diversa dalla vecchia.
error_6=&Egrave; necessario modificare la password.
error_7=Set up inizale dell&#39;account per il portale necessario.
error_8=L&#39;account &egrave; stato bloccato. Rivolgersi al servizio assistenza oppure provare con un altro strumento di autenticazione.
error_81=Nessuna carta di accesso trovata, accesso da internet rifiutato.
error_83=La sua carta di accesso non &egrave; pi&ugrave; valida. Per favore contatti il suo assistente per ricevere una nuova carta di accesso.
error_9=La sessione non pu&ograve; essere ripresa.
error_97=Non si dispone delle autorizzazioni necessarie per accedere a questa risorsa.
error_98=L&#39;account &egrave; stato bloccato.
error_99=Errore di sistema. Riprovare.
info.login=Per favore inserisca i suoi dati di accesso.
info.logout.confirmation=Si prega di confermare che si desidera disconnettersi.
info.logout.reminder=La sessione su questa applicazione &#x26;egrave; scaduta. Prova ancora con un login.
info.oauth.consent=Vuoi consentire all&#39;applicazione?
info.signup.passwordless=Accedi in modo rapido e sicuro la prossima volta utilizzando l'impronta digitale, il riconoscimento facciale o il PIN di questo dispositivo.
info.signup.passwordless.failed=Utilizza lo stesso metodo che usi già su questo dispositivo per il login.
info.signup.passwordless.skip=<button name="cancel-bottom" type="submit" value="true" class="btn btn-link link-primary">Saltare per ora</button>
info.timeout.page=La sessione su questa applicazione &#x26;egrave; scaduta. Prova ancora con un login.
login.button.label=Login
logout.label=Logout
logout.text=&Egrave; uscito con successo.
method.certificate.label=Certificato
method.fido.label=Mobile Authentication
method.fido2.label=FIDO 2
method.mtan.label=Codice mTAN
method.oath.label=App di autenticazione OATH
method.otp.label=OTP (One-Time Password)
method.recovery.label=Codici di ripristino
method.safeword.label=SafeWord
method.securid.label=SecurID
method.ticket.label=Ticket
outarg.lastLogin.never=Mai
policyFailure.dictionary=&#9642; non pu&ograve; essere presa da un dizionario.
policyFailure.history.History=&#9642; deve essere diversa da password precedenti.
policyFailure.regex.control=&#9642; non pu&ograve; contenere pi&ugrave; di {0} caratteri di controllo.
policyFailure.regex.lower=&#9642; deve conenere almeno {0} caratteri minuscoli.
policyFailure.regex.maxCharacterRepetitions=&#9642; non pu&ograve; contentere una sequenza pi&ugrave; lunga di {0} caratteri uguali.
policyFailure.regex.maxLength=&#9642; deve contenere al massimo {0} caratteri.
policyFailure.regex.minLength=&#9642; deve contenere almeno {0} caratteri.
policyFailure.regex.nonAlnum=&#9642; deve conenere almeno {0} caratteri non alfanumerici.
policyFailure.regex.nonAscii=&#9642; non pu&ograve; contenere pi&ugrave; di {0} caratteri non ASCII.
policyFailure.regex.nonGraph=&#9642; non pu&ograve; contenere pi&ugrave; di {0} caratteri non stampabili.
policyFailure.regex.nonLetter=&#9642; non pu&ograve; contenere pi&ugrave; di {0} numeri o caratteri speciali.
policyFailure.regex.numeric=&#9642; deve contenere {0} caratteri numerici.
policyFailure.regex.upper=&#9642; deve conenere almeno {0} caratteri maiuscoli.
policyInfo.dictionary=&#9642; non pu&ograve; essere presa da un dizionario.
policyInfo.history.History=&#9642; deve essere diversa dalle password precedenti.
policyInfo.regex.control=&#9642; non pu&ograve; contenere pi&ugrave; di {0} carattere/i di controllo.
policyInfo.regex.lower=&#9642; deve conenere almeno {0} carattere/i minuscolo/i.
policyInfo.regex.maxCharacterRepetitions=&#9642; non pu&ograve; contentere una sequenza pi&ugrave; lunga di {0} caratteri uguali.
policyInfo.regex.maxLength=&#9642; deve contenere al massimo {0} carattere/i.
policyInfo.regex.minLength=&#9642; deve contenere almeno {0} carattere/i.
policyInfo.regex.nonAlnum=&#9642; deve conenere almeno {0} carattere/i non alfanumerico/i.
policyInfo.regex.nonAscii=&#9642; non pu&ograve; contenere pi&ugrave; di {0} carattere/i non ASCII.
policyInfo.regex.nonGraph=&#9642; non pu&ograve; contenere pi&ugrave; di {0} carattere/i non stampabile/i.
policyInfo.regex.nonLetter=&#9642; non pu&ograve; contenere pi&ugrave; di {0} numero/i o caratere/i speciale/i.
policyInfo.regex.numeric=&#9642; deve contenere un minimo di {0} carattere/i numerico/i.
policyInfo.regex.upper=&#9642; deve conenere almeno {0} carattere/i maiuscolo/i.
policyInfo.title=La password deve rispettare le seguenti direttive:
prompt.client=Mandator
prompt.newpassword=Nuova Password
prompt.newpassword.confirm=Conferma password
prompt.password=Password
prompt.userid=Nome utente
pwreset.done.info=La password &egrave; stata modificata con successo. Fare clic su continua per accedere.
pwreset.email.sent=Se il vostro ID utente esiste, vi è stata inviata un'e-mail per reimpostare la password.
pwreset.info.linktext=Password dimenticata
pwreset.noticket=Il biglietto per la reimpostazione della password non &egrave; pi&ugrave; valido. Si prega di generarne uno nuovo.
reject.button.label=Rifiuti
submit.button.label=Continua
tan.sent=Inserisci il codice di sicurezza che &egrave; stato inviato al tuo telefono cellulare.
title.login=Login
title.logout=Logout
title.logout.confirmation=Logout
title.logout.reminder=Logout
title.oauth.consent=Autorizzazione del client
title.pwchange.label=Cambiare Password
title.pwreset=Password Dimenticata
title.saml.failed=Error
title.signup.passwordless=Vai senza password
title.signup.passwordless.failed=Impossibile attivare senza password
title.timeout.page=Logout
try_again.button.label=Riprova

View File

@ -0,0 +1 @@
bc.tracer.TraceIndentFactory=ch.nevis.bc.io.Log4jTraceIndentFactory

View File

@ -0,0 +1,20 @@
RTENV_SECURITY_CHECK=no_shell
JAVA_OPTS=(
"-XX:+UseContainerSupport"
"-Dfile.encoding=UTF-8"
"-Dotel.instrumentation.metro.enabled=false"
"-XX:MaxRAMPercentage=80.0"
"-Djava.net.preferIPv4Stack=true"
"-Djava.net.connectionTimeout=10000"
"-Djava.net.readTimeout=15000"
"-Dch.nevis.esauth.config=/var/opt/nevisauth/default/conf/esauth4.xml"
"-Djava.awt.headless=true"
"-javaagent:/opt/agent/opentelemetry-javaagent.jar"
"-Dotel.javaagent.logging=application"
"-Dotel.javaagent.configuration-file=/var/opt/nevisauth/default/conf/otel.properties"
"-Dotel.resource.attributes=service.version=8.2411.1,service.instance.id=$HOSTNAME"
"-Djavax.net.ssl.trustStore=/var/opt/keys/trust/ob-auth-v1-agov-work-internal-trust-store/truststore.p12"
"-Djavax.net.ssl.trustStorePassword=\${exec:/var/opt/keys/trust/ob-auth-v1-agov-work-internal-trust-store/keypass}"
)

View File

@ -0,0 +1,2 @@
# this file is generated by nevisAdmin 4
security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider

View File

@ -0,0 +1,733 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE esauth-server SYSTEM "/opt/nevisauth/dtd/esauth4.dtd">
<esauth-server instance="ob-auth-v1">
<!-- source: pattern://6e7b5a087711bd0ada9985fe, pattern://d00b0dcbe241793d30daf91c -->
<SessionCoordinator sessionInitialInactivityTimeout="600" sessionInactivityTimeout="28800" sessionMaxLifetime="28800" sessionIdPreGenerate="true">
<!-- source: pattern://d00b0dcbe241793d30daf91c -->
<LocalSessionStore maxSessions="100000"/>
<!-- source: pattern://d00b0dcbe241793d30daf91c -->
<TokenAssembler name="DefaultTokenAssembler">
<Selector default="true"/>
<!-- source: pattern://14b02056879c3b8991597d2b, pattern://6e7b5a087711bd0ada9985fe -->
<TokenSpec ttl="28800">
<!-- source: pattern://d00b0dcbe241793d30daf91c -->
<field src="session" key="ch.nevis.session.sessid" as="sessid"/>
<!-- source: pattern://d00b0dcbe241793d30daf91c -->
<field src="session" key="ch.nevis.session.userid" as="userid"/>
<!-- source: pattern://d00b0dcbe241793d30daf91c -->
<field src="session" key="ch.nevis.session.authlevel" as="authLevel"/>
<!-- source: pattern://d00b0dcbe241793d30daf91c -->
<field src="session" key="ch.nevis.session.esauthid" as="esauthid"/>
<!-- source: pattern://d00b0dcbe241793d30daf91c -->
<field src="session" key="ch.nevis.session.entryid" as="entryid"/>
<!-- source: pattern://d00b0dcbe241793d30daf91c -->
<field src="session" key="ch.nevis.session.loginid" as="loginId"/>
<!-- source: pattern://d00b0dcbe241793d30daf91c -->
<field src="session" key="ch.nevis.session.domain" as="domain"/>
<!-- source: pattern://d00b0dcbe241793d30daf91c -->
<field src="session" key="ch.nevis.session.secroles" as="roles"/>
</TokenSpec>
<!-- source: pattern://d00b0dcbe241793d30daf91c -->
<Signer key="DefaultSigner"/>
</TokenAssembler>
<!-- source: pattern://d00b0dcbe241793d30daf91c -->
<KeyStore name="DefaultKeyStore">
<!-- source: pattern://d00b0dcbe241793d30daf91c -->
<KeyObject name="DefaultSigner" certificate="/var/opt/keys/own/ob-auth-signer/cert.pem" privateKey="/var/opt/keys/own/ob-auth-signer/keystore.jks" passPhrase="pipe:///var/opt/keys/own/ob-auth-signer/keypass"/>
</KeyStore>
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<KeyStore name="ob-realm-accessapp-registration-nevisfido-tls-trust-store">
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<KeyObject name="ob-realm-accessapp-registration-nevisfido-tls-certificate" certificate="/var/opt/keys/trust/ob-auth-v1-ob-realm-accessapp-registration-nevisfido-tls-trust/truststore.jks" passPhrase="pipe:///var/opt/keys/trust/ob-auth-v1-ob-realm-accessapp-registration-nevisfido-tls-trust/keypass"/>
</KeyStore>
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<KeyStore name="ob-realm-accessapp-registration-nevisfido-tls-client-key-store">
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<KeyObject name="ob-realm-accessapp-registration-nevisfido-tls-client-key-object" certificate="/var/opt/keys/own/ob-auth-v1-ob-realm-accessapp-registration-nevisfido-tls-client/cert.pem" privateKey="/var/opt/keys/own/ob-auth-v1-ob-realm-accessapp-registration-nevisfido-tls-client/keystore.jks" passPhrase="pipe:///var/opt/keys/own/ob-auth-v1-ob-realm-accessapp-registration-nevisfido-tls-client/keypass"/>
</KeyStore>
</SessionCoordinator>
<!-- source: pattern://d00b0dcbe241793d30daf91c -->
<LocalOutOfContextDataStore reaperPeriod="60"/>
<!-- source: pattern://6e7b5a087711bd0ada9985fe, pattern://d00b0dcbe241793d30daf91c, pattern://d00b0dcbe241793d30daf91c, pattern://e1784eecf2db74484dd1e1bb, pattern://25bdd7e6f5b76694f6688ab8, pattern://d00b0dcbe241793d30daf91c -->
<AuthEngine useLiteralDictionary="true" literalDictionaryLanguages="en,de,fr,it" inputLanguageCookie="LANG" compatLevel="none" addAutheLevelToSecRoles="true" classPath="/opt/nevisidmcl/nevisauth/lib:/opt/nevisfidocl/nevisauth/lib:/opt/nevisauth/plugin" propagateSession="false">
<!-- source: pattern://14b02056879c3b8991597d2b -->
<Domain name="ob-mock-me-realm" default="false" inactiveInterval="7200" reauthInterval="0" resetAuthenticationCondition="${inargs:cancel}">
<Entry method="authenticate" state="ob-mock-me-realm_ob-mock-me-auth-processor"/>
<Entry method="authenticate" state="ob-mock-me-realm_ob-mock-me-auth-processor" selector="${request:currentResource:^http[s]?\u003A//[^/]+/mock-me/.*$:true}"/>
<Entry method="stepup" state="ob-mock-me-realm_Selector"/>
<Entry method="stepup" state="ob-mock-me-realm_ob-mock-me-auth-processor" selector="${request:currentResource:^http[s]?\u003A//[^/]+/mock-me/.*$:true}"/>
</Domain>
<!-- source: pattern://6e7b5a087711bd0ada9985fe -->
<Domain name="ob-realm" default="false" inactiveInterval="7200" reauthInterval="0" resetAuthenticationCondition="${inargs:cancel}">
<Entry method="authenticate" state="ob-realm_ob-realm-idm-pwd-login"/>
<Entry method="authenticate" state="ob-realm_ob-realm-idm-pwd-login-IdmTicketVerifyState" selector="${request:currentResource:/pwreset/continue:true}"/>
<Entry method="authenticate" state="ob-realm_ob-realm-idm-pwd-login-IdmUserVerifyState" selector="${request:currentResource:/pwreset/start:true}"/>
<Entry method="stepup" state="ob-realm_Selector"/>
</Domain>
<AuthState name="ob-mock-me-realm_ob-mock-me-auth-processor" class="ch.nevis.esauth.auth.states.scripting.ScriptState" final="false" resumeState="true">
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<ResultCond name="processResponse" next="ob-mock-me-realm_ob-mock-me-auth-processor_serviceProvider"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<Response value="AUTH_CONTINUE">
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<Gui name="AuthErrorDialog"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<Gui name="op_mock_me_gui" label="AGOV MOCK me">
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<GuiElem name="lasterror" type="error" label="${notes:lasterrorinfo}" value="${notes:lasterror}" optional="true"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<GuiElem name="operation" type="text" label="operation" value="${inctx|connection.actualURL|^https:\/\/[^\/]+\/mock-me\/(.+)$|$1}" optional="true"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<GuiElem name="subject" type="text" label="subject" value="${notes:saml.assertion.subject}" optional="true"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<GuiElem name="statusCode" type="text" label="statusCode" value="${notes:saml.response.statusCode}" optional="true"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<GuiElem name="authnContextClassRef" type="text" label="authnContextClassRef" value="${notes:saml.assertion.authnContextClassRef}" optional="true"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<GuiElem name="authenticatedWith" type="text" label="authenticatedWith" value="${notes|saml.attributes.http://schemas.agov.ch/ws/2023/05/identity/claims/authenticatedWith}" optional="true"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<GuiElem name="requestedRoleLevel" type="text" label="requestedRoleLevel" value="${notes|saml.attributes.http://schemas.agov.ch/ws/2023/05/identity/claims/requestedRoleLevel}" optional="true"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<GuiElem name="rpEntityId" type="text" label="rpEntityId" value="${notes|saml.attributes.http://schemas.agov.ch/ws/2023/09/identity/claim/rpEntityId}" optional="true"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<GuiElem name="allowedVerificationMethods" type="text" label="allowedVerificationMethods" value="${notes|saml.attributes.http://schemas.agov.ch/ws/2023/09/identity/claim/allowedVerificationMethods}" optional="true"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<GuiElem name="addressRequired" type="text" label="addressRequired" value="${notes|saml.attributes.http://schemas.agov.ch/ws/2023/09/identity/claims/addressRequired}" optional="true"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<GuiElem name="currentAgovAq" type="text" label="currentAgovAq" value="${notes|saml.attributes.http://schemas.agov.ch/ws/2023/11/identity/claims/currentAgovAq}" optional="true"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<GuiElem name="dateOfVerification" type="text" label="dateOfVerification" value="${notes|saml.attributes.http://schemas.agov.ch/ws/2023/05/identity/claims/qa/dateOfVerification}" optional="true"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<GuiElem name="currentIdVerification" type="text" label="currentIdVerification" value="${notes|saml.attributes.http://schemas.agov.ch/ws/2024/01/identity/claims/currentIdVerification}" optional="true"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<GuiElem name="back" type="button" label="submit.button.label" value="go"/>
</Gui>
</Response>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<property name="script" value="file:///var/opt/nevisauth/default/conf/mock-me-processing.groovy"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<property name="parameter.idp-sso-url" value="https://auth.agov-w.azure.adnovum.net/SAML2/SSO/"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<property name="parameter.idp-recovery-url" value="https://auth.agov-w.azure.adnovum.net/AUTH/RECOVERY/"/>
</AuthState>
<AuthState name="ob-mock-me-realm_ob-mock-me-auth-processor_serviceProvider" class="ch.nevis.esauth.auth.states.saml.ServiceProviderState" final="false" resumeState="false">
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<ResultCond name="default" next="ob-mock-me-realm_ob-mock-me-auth-processor"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<ResultCond name="ok" next="ob-mock-me-realm_ob-mock-me-auth-processor"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<Response value="AUTH_ERROR">
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<Gui name="AuthErrorDialog"/>
</Response>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<property name="consumerURL" value="https://ob.agov-w.azure.adnovum.net/mock-me/process"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<property name="idpURL" value="https://auth.agov-w.azure.adnovum.net/SAML2/SSO/"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<property name="in.verify" value="Response Assertion"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<property name="in.prospectVerification" value="Response Assertion"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<property name="in.binding" value="internal"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<property name="in.internalBindingSource" value="${notes:SAMLResponse}"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<property name="in.audienceRegex" value="https://ob.agov-w.azure.adnovum.net/mock-me/.+"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<property name="in.audience.checkrequired" value="false"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<property name="in.max_age" value="30"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<property name="in.keystoreref" value="DefaultKeyStore"/>
<!-- source: pattern://be8f8436b2ec70e9d601fdd3 -->
<property name="out.binding" value="none"/>
</AuthState>
<AuthState name="ob-mock-me-realm_Selector" class="ch.nevis.esauth.auth.states.standard.ConditionalDispatcherState" final="false">
<!-- source: pattern://14b02056879c3b8991597d2b -->
<ResultCond name="nomatch" next="ob-mock-me-realm_Prepare_Done"/>
<!-- source: pattern://14b02056879c3b8991597d2b -->
<Response value="AUTH_ERROR">
<!-- source: pattern://14b02056879c3b8991597d2b -->
<Arg name="ch.nevis.isiweb4.response.status" value="403"/>
</Response>
</AuthState>
<AuthState name="ob-mock-me-realm_Prepare_Done" class="ch.nevis.esauth.auth.states.scripting.ScriptState" final="false">
<!-- source: pattern://14b02056879c3b8991597d2b -->
<ResultCond name="default" next="ob-mock-me-realm_Auth_Done"/>
<!-- source: pattern://14b02056879c3b8991597d2b -->
<Response value="AUTH_DONE">
<!-- source: pattern://14b02056879c3b8991597d2b -->
<Gui name="ContinueResponse"/>
</Response>
<!-- source: pattern://14b02056879c3b8991597d2b -->
<property name="script" value="file:///var/opt/nevisauth/default/conf/prepare_done.groovy"/>
</AuthState>
<AuthState name="ob-mock-me-realm_Auth_Done" class="ch.nevis.esauth.auth.states.standard.AuthDone" final="false">
<!-- source: pattern://14b02056879c3b8991597d2b -->
<Response value="AUTH_DONE">
<!-- source: pattern://14b02056879c3b8991597d2b -->
<Gui name="ContinueResponse"/>
</Response>
</AuthState>
<AuthState name="ob-realm_ob-realm-idm-pwd-login" class="ch.nevis.esauth.auth.states.scripting.ScriptState" final="false">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="ok" next="ob-realm_ob-realm-idm-pwd-login-Login"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="redirectionPathInvalid" next="ob-realm_ob-realm-idm-pwd-loginInvalidPath"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Response value="AUTH_ERROR">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Arg name="ch.nevis.isiweb4.response.status" value="403"/>
</Response>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<property name="script" value="file:///var/opt/nevisauth/default/conf/filterRedirectionPaths.groovy"/>
</AuthState>
<AuthState name="ob-realm_ob-realm-idm-pwd-login-Login" class="ch.nevis.idm.authstate.IdmPasswordVerifyState" final="false">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="clientNotFound" next="ob-realm_ob-realm-idm-pwd-login-Login"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="disabled" next="ob-realm_ob-realm-idm-pwd-login-Login"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="failed" next="ob-realm_ob-realm-idm-pwd-login-Login"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="lockWarn" next="ob-realm_ob-realm-idm-pwd-login-Login"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="locked" next="ob-realm_ob-realm-idm-pwd-login-Login"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="nowLocked" next="ob-realm_ob-realm-idm-pwd-login-Login"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="ok" next="ob-realm_ob-realm-idm-pwd-login-IdmPostProcessing" authLevel="1"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="pwChange" next="ob-realm_ob-realm-idm-pwd-login-IdmPasswordChange"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="tmpLocked" next="ob-realm_ob-realm-idm-pwd-login-Login"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Response value="AUTH_CONTINUE">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Gui name="AuthUidPwDialog" label="title.login">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="lasterror" type="error" label="${notes:lasterrorinfo}" value="${notes:lasterror}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="info" type="info" label="info.login"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="client" type="text" label="prompt.client" value="#{notes['client'] ? notes['client'] : 'Default' }"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="isiwebuserid" type="text" label="prompt.userid" value="${notes.loginid}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="isiwebpasswd" type="pw-text" label="prompt.password"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="submit" type="button" label="continue.button.label"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="passwordforgottenlink" type="link" label="pwreset.info.linktext" value="/pwreset/start"/>
</Gui>
</Response>
<propertyRef name="nevisIDM_Connector"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<property name="user.loginType" value="EMAIL"/>
</AuthState>
<AuthState name="ob-realm_ob-realm-idm-pwd-loginInvalidPath" class="ch.nevis.esauth.auth.states.standard.AuthError" final="true">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Response value="AUTH_ERROR">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Gui name="ob-realm-idm-pwd-loginInvalidPath" label="URL Path Invalid">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="lasterror" type="error" label="${notes:lasterrorinfo}" value="${notes:lasterror}"/>
</Gui>
</Response>
</AuthState>
<AuthState name="ob-realm_ob-realm-idm-pwd-login-IdmPostProcessing" class="ch.nevis.idm.authstate.IdmGetPropertiesState" final="false">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="SOAP:showGui" next="ob-realm_ob-realm-dispatch-cred-type"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="default" next="ob-realm_ob-realm-dispatch-cred-type"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="ok" next="ob-realm_ob-realm-dispatch-cred-type" startOver="true"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="showGui" next="ob-realm_ob-realm-idm-pwd-login-IdmPostProcessing"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Response value="AUTH_CONTINUE">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Gui name="AuthProfileSelectionDialog">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="lasterror" type="error" label="${notes:lasterrorinfo}" value="${notes:lasterror}"/>
</Gui>
</Response>
<propertyRef name="nevisIDM_Connector"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<property name="chooseDefaultProfile" value="true"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<property name="user.attributes" value="extId, loginId, firstName, name, email, language"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<property name="detaillevel.default" value="EXCLUDE"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<property name="detaillevel.user" value="MEDIUM"/>
</AuthState>
<AuthState name="ob-realm_ob-realm-idm-pwd-login-IdmPasswordChange" class="ch.nevis.idm.authstate.IdmChangePasswordState" final="false">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="default" next="ob-realm_ob-realm-idm-pwd-login-IdmPasswordChange"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="ok" next="ob-realm_ob-realm-idm-pwd-login-IdmPostProcessing" authLevel="1"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="policyFailure" next="ob-realm_ob-realm-idm-pwd-login-IdmPasswordChange"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Response value="AUTH_CONTINUE">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Gui name="AuthUidPwDialog" label="title.pwchange.label">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="lasterror" type="error" label="${notes:lasterrorinfo}" value="${notes:lasterror}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.allowLoginIdPasswordViolated" type="error" label="${notes.policyFailure.allowLoginIdPasswordViolated}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.minLength" type="error" label="${notes.policyFailure.regex.minLength}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.maxLength" type="error" label="${notes.policyFailure.regex.maxLength}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.upper" type="error" label="${notes.policyFailure.regex.upper}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.lower" type="error" label="${notes.policyFailure.regex.lower}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.numeric" type="error" label="${notes.policyFailure.regex.numeric}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.nonLetter" type="error" label="${notes.policyFailure.regex.nonLetter}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.nonAlnum" type="error" label="${notes.policyFailure.regex.nonAlnum}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.control" type="error" label="${notes.policyFailure.regex.control}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.nonGraph" type="error" label="${notes.policyFailure.regex.nonGraph}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.nonAscii" type="error" label="${notes.policyFailure.regex.nonAscii}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.dictionary" type="error" label="${notes.policyFailure.dictionary}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.history.History" type="error" label="${notes.policyFailure.history.History}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.maxCharacterRepetitions" type="error" label="${notes.policyFailure.regex.maxCharacterRepetitions}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.title" type="info" label="#{!notes.containsKey('lasterror') || notes.lasterror != '4' ? 'policyInfo.title' : ''}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.minLength" type="info" label="${notes.policyInfo.regex.minLength}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.maxLength" type="info" label="${notes.policyInfo.regex.maxLength}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.upper" type="info" label="#{notes['policyInfo.regex.upper'].contains('upper[0]') ? '' : notes['policyInfo.regex.upper']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.lower" type="info" label="#{notes['policyInfo.regex.lower'].contains('lower[0]') ? '' : notes['policyInfo.regex.lower']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.numeric" type="info" label="#{notes['policyInfo.regex.numeric'].contains('numeric[0]') ? '' : notes['policyInfo.regex.numeric']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.nonLetter" type="info" label="#{notes['policyInfo.regex.nonLetter'].contains('nonLetter[0]') ? '' : notes['policyInfo.regex.nonLetter']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.nonAlnum" type="info" label="#{notes['policyInfo.regex.nonAlnum'].contains('nonAlnum[0]') ? '' : notes['policyInfo.regex.nonAlnum']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.control" type="info" label="#{notes['policyInfo.regex.control'].contains('control[0]') ? '' : notes['policyInfo.regex.control']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.nonGraph" type="info" label="#{notes['policyInfo.regex.nonGraph'].contains('nonGraph[0]') ? '' : notes['policyInfo.regex.nonGraph']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.nonAscii" type="info" label="#{notes['policyInfo.regex.nonAscii'].contains('nonAscii[0]') ? '' : notes['policyInfo.regex.nonAscii']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.dictionary" type="info" label="${notes.policyInfo.dictionary}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.history.History" type="info" label="${notes.policyInfo.history.History}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.maxCharacterRepetitions" type="info" label="${notes.policyInfo.regex.maxCharacterRepetitions}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="isiwebpasswd" type="pw-text" label="prompt.password"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="isiwebnewpw1" type="pw-text" label="prompt.newpassword"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="isiwebnewpw2" type="pw-text" label="prompt.newpassword.confirm"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="submit" type="submit" label="button.submit"/>
</Gui>
</Response>
<propertyRef name="nevisIDM_Connector"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<property name="legacyLitDictMode" value="false"/>
</AuthState>
<AuthState name="nevisIDM_Connector" class="ch.nevis.esauth.auth.states.standard.AuthGeneric" final="false">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<property name="login.service.connection.0" value="https://idm.adn-agov-nevisidm-01-uat:8989/nevisidm/services/v1/LoginService"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<property name="admin.service.connection.0" value="https://idm.adn-agov-nevisidm-01-uat:8989/nevisidm/services/v1/AdminService"/>
</AuthState>
<AuthState name="ob-realm_ob-realm-dispatch-cred-type" class="ch.nevis.esauth.auth.states.standard.AuthGeneric" final="true" resumeState="true">
<!-- source: pattern://5f192f6e91687b30b5868750 -->
<ResultCond name="accessapp" next="ob-realm_ob-realm-accessapp-registration"/>
<!-- source: pattern://5f192f6e91687b30b5868750 -->
<ResultCond name="default" next="ob-realm_ob-realm-dispatch-cred-type"/>
<!-- source: pattern://5f192f6e91687b30b5868750 -->
<ResultCond name="fido2" next="ob-realm_ob-realm-fido2-registration"/>
<!-- source: pattern://5f192f6e91687b30b5868750 -->
<Response value="AUTH_CONTINUE">
<!-- source: pattern://5f192f6e91687b30b5868750 -->
<Gui name="ChooseCredType" label="Choose Credential Type">
<!-- source: pattern://5f192f6e91687b30b5868750 -->
<GuiElem name="infotext" type="info" label="Choose the type of credential to register"/>
<!-- source: pattern://5f192f6e91687b30b5868750 -->
<GuiElem name="fido2" type="button" label="FIDO2 Key" value="fido2"/>
<!-- source: pattern://5f192f6e91687b30b5868750 -->
<GuiElem name="accessapp" type="button" label="AGOV access App" value="accessapp"/>
</Gui>
</Response>
</AuthState>
<AuthState name="ob-realm_ob-realm-accessapp-registration" class="ch.nevis.esauth.auth.states.scripting.ScriptState" final="false">
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<ResultCond name="failed" next="ob-realm_Authentication_Failed"/>
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<ResultCond name="fallback" next="ob-realm_ob-realm-idm-pwd-login"/>
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<ResultCond name="ok" next="ob-realm_Prepare_Done"/>
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<Response value="AUTH_CONTINUE">
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<Gui name="mauth_onboard">
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<GuiElem name="fallback" type="button" label="mobile_auth.cancel.button.label" value="true" optional="true"/>
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<GuiElem name="mauth_dispatcher_link" type="hidden" value="${sess:mauth_dispatcher_link}" optional="true"/>
</Gui>
</Response>
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<property name="parameter.username" value="#{session['ch.adnovum.nevisidm.user.extId'] != null ? session['ch.adnovum.nevisidm.user.extId'] : session['ch.nevis.idm.User.extId'] != null ? session['ch.nevis.idm.User.extId'] : request.getUserId() != null ? request.getUserId() : notes['userid']}"/>
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<property name="parameter.httpclient.authorization.basic.sectoken.userId" value="#{session['ch.adnovum.nevisidm.user.extId'] != null ? session['ch.adnovum.nevisidm.user.extId'] : session['ch.nevis.idm.User.extId'] != null ? session['ch.nevis.idm.User.extId'] : request.getUserId() != null ? request.getUserId() : notes['userid']}"/>
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<property name="parameter.httpclient.authorization.basic.sectoken.profileId" value="${sess:ch.adnovum.nevisidm.profileId}"/>
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<property name="parameter.httpclient.authorization.basic.sectoken.roles" value="unused"/>
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<property name="parameter.fidoUrl" value="https://ob-fido-uaf-v1:9443/nevisfido"/>
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<property name="script" value="file:///var/opt/nevisauth/default/conf/ob-realm-accessapp-registration.groovy"/>
</AuthState>
<AuthState name="ob-realm_ob-realm-fido2-registration" class="ch.nevis.esauth.auth.states.scripting.ScriptState" final="false">
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<ResultCond name="cancel" next="ob-realm_ob-realm-idm-pwd-login"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<ResultCond name="failed" next="ob-realm_ob-realm-fido2-registration_Failed"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<ResultCond name="ok" next="ob-realm_Prepare_Done"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<ResultCond name="unsupported" next="ob-realm_ob-realm-idm-pwd-login"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<Response value="AUTH_CONTINUE">
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<Gui name="fido2_onboard" label="title.signup.passwordless">
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="passwordless-icon" type="hidden" optional="true"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="info-sub-icon" type="info" label="info.signup.passwordless"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="logoName" type="hidden" label="${sess:ch.nevis.idc.logoName}" optional="true"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="brand" type="hidden" label="${sess:ch.nevis.idc.brand}" optional="true"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="primaryColor" type="hidden" label="${sess:ch.nevis.idc.config.branding.primaryColor}" optional="true"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="borderRadius" type="hidden" label="${sess:ch.nevis.idc.config.branding.borderRadius}" optional="true"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="fontFamily" type="hidden" label="${sess:ch.nevis.idc.config.branding.fontFamily}" optional="true"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="onclick" type="button" label="continue.button.label"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="cancel-bottom" type="info" label="info.signup.passwordless.skip"/>
</Gui>
</Response>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<property name="parameter.attestation" value="direct"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<property name="parameter.fido" value="ob-fido2-v1:9443"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<property name="parameter.residentKey" value="required"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<property name="parameter.requireResidentKey" value="true"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<property name="parameter.userVerification" value="required"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<property name="script" value="file:///var/opt/nevisauth/default/conf/ob-realm-fido2-registration.groovy"/>
</AuthState>
<AuthState name="ob-realm_Authentication_Failed" class="ch.nevis.esauth.auth.states.standard.AuthError" final="false">
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<Response value="AUTH_ERROR">
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<Gui name="Error">
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<GuiElem name="info" type="error" label="error_99"/>
<!-- source: pattern://25bdd7e6f5b76694f6688ab8 -->
<GuiElem name="submit" type="button" label="continue.button.label"/>
</Gui>
</Response>
</AuthState>
<AuthState name="ob-realm_Prepare_Done" class="ch.nevis.esauth.auth.states.scripting.ScriptState" final="false">
<!-- source: pattern://6e7b5a087711bd0ada9985fe -->
<ResultCond name="default" next="ob-realm_Auth_Done"/>
<!-- source: pattern://6e7b5a087711bd0ada9985fe -->
<Response value="AUTH_DONE">
<!-- source: pattern://6e7b5a087711bd0ada9985fe -->
<Gui name="ContinueResponse"/>
</Response>
<!-- source: pattern://6e7b5a087711bd0ada9985fe -->
<property name="script" value="file:///var/opt/nevisauth/default/conf/prepare_done.groovy"/>
</AuthState>
<AuthState name="ob-realm_ob-realm-fido2-registration_Failed" class="ch.nevis.esauth.auth.states.standard.AuthGeneric" final="true">
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<ResultCond name="default:${inargs:cancel-bottom:^.+$:true}" next="ob-realm_ob-realm-idm-pwd-login"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<ResultCond name="default:${inargs:o.path.v:^.+$:true}" next="ob-realm_ob-realm-fido2-registration"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<Response value="AUTH_CONTINUE">
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<Gui name="fido2_onboard" label="title.signup.passwordless.failed">
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="info-icon" type="hidden" optional="true"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="info-sub-icon" type="info" label="info.signup.passwordless.failed"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="onclick" type="button" label="try_again.button.label"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="logoName" type="hidden" label="${sess:ch.nevis.idc.logoName}" optional="true"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="brand" type="hidden" label="${sess:ch.nevis.idc.brand}" optional="true"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="primaryColor" type="hidden" label="${sess:ch.nevis.idc.config.branding.primaryColor}" optional="true"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="borderRadius" type="hidden" label="${sess:ch.nevis.idc.config.branding.borderRadius}" optional="true"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="fontFamily" type="hidden" label="${sess:ch.nevis.idc.config.branding.fontFamily}" optional="true"/>
<!-- source: pattern://3d382e0cf987535b6fa989b4 -->
<GuiElem name="cancel-bottom" type="info" label="info.signup.passwordless.skip"/>
</Gui>
</Response>
</AuthState>
<AuthState name="ob-realm_Auth_Done" class="ch.nevis.esauth.auth.states.standard.AuthDone" final="false">
<!-- source: pattern://6e7b5a087711bd0ada9985fe -->
<Response value="AUTH_DONE">
<!-- source: pattern://6e7b5a087711bd0ada9985fe -->
<Gui name="ContinueResponse"/>
</Response>
</AuthState>
<AuthState name="ob-realm_ob-realm-idm-pwd-login-IdmTicketVerifyState" class="ch.nevis.idm.authstate.IdmURLTicketVerifyState" final="false" resumeState="true">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="failed" next="ob-realm_ob-realm-idm-pwd-login-IdmTicketNotFoundState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="locked" next="ob-realm_ob-realm-idm-pwd-login-IdmTicketNotFoundState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="nowLocked" next="ob-realm_ob-realm-idm-pwd-login-IdmTicketNotFoundState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="ok" next="ob-realm_ob-realm-idm-pwd-login-IdmResetPasswordState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Response value="AUTH_ERROR">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Gui name="AuthErrorDialog" label="title.pwreset">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="lasterror" type="error" label="${notes:lasterrorinfo}" value="${notes:lasterror}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="continue" type="button" label="continue.button.label" value="true"/>
</Gui>
</Response>
<propertyRef name="nevisIDM_Connector"/>
</AuthState>
<AuthState name="ob-realm_ob-realm-idm-pwd-login-IdmTicketNotFoundState" class="ch.nevis.esauth.auth.states.standard.AuthGeneric" final="true">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="default" next="ob-realm_ob-realm-idm-pwd-login-TerminateSessionState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Response value="AUTH_CONTINUE">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Gui name="AuthDoneDialog" label="title.pwreset">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="error" type="error" label="pwreset.noticket"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="continue" type="button" label="continue.button.label" value="true"/>
</Gui>
</Response>
</AuthState>
<AuthState name="ob-realm_ob-realm-idm-pwd-login-IdmResetPasswordState" class="ch.nevis.idm.authstate.IdmPasswordResetState" final="false" resumeState="true">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="ok" next="ob-realm_ob-realm-idm-pwd-login-IdmPasswordSetState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="policyFailure" next="ob-realm_ob-realm-idm-pwd-login-IdmResetPasswordState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Response value="AUTH_CONTINUE">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Gui name="AuthInputDialog" label="title.pwreset">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="lasterror" type="error" label="${notes:lasterrorinfo}" value="${notes:lasterror}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.allowLoginIdPasswordViolated" type="error" label="${notes.policyFailure.allowLoginIdPasswordViolated}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.minLength" type="error" label="${notes.policyFailure.regex.minLength}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.maxLength" type="error" label="${notes.policyFailure.regex.maxLength}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.upper" type="error" label="${notes.policyFailure.regex.upper}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.lower" type="error" label="${notes.policyFailure.regex.lower}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.numeric" type="error" label="${notes.policyFailure.regex.numeric}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.nonLetter" type="error" label="${notes.policyFailure.regex.nonLetter}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.nonAlnum" type="error" label="${notes.policyFailure.regex.nonAlnum}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.control" type="error" label="${notes.policyFailure.regex.control}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.nonGraph" type="error" label="${notes.policyFailure.regex.nonGraph}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.nonAscii" type="error" label="${notes.policyFailure.regex.nonAscii}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.dictionary" type="error" label="${notes.policyFailure.dictionary}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.history.History" type="error" label="${notes.policyFailure.history.History}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyFailure.regex.maxCharacterRepetitions" type="error" label="${notes.policyFailure.regex.maxCharacterRepetitions}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.title" type="info" label="#{!notes.containsKey('lasterror') || notes.lasterror != '4' ? 'policyInfo.title' : ''}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.minLength" type="info" label="${notes.policyInfo.regex.minLength}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.maxLength" type="info" label="${notes.policyInfo.regex.maxLength}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.upper" type="info" label="#{notes['policyInfo.regex.upper'].contains('upper[0]') ? '' : notes['policyInfo.regex.upper']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.lower" type="info" label="#{notes['policyInfo.regex.lower'].contains('lower[0]') ? '' : notes['policyInfo.regex.lower']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.numeric" type="info" label="#{notes['policyInfo.regex.numeric'].contains('numeric[0]') ? '' : notes['policyInfo.regex.numeric']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.nonLetter" type="info" label="#{notes['policyInfo.regex.nonLetter'].contains('nonLetter[0]') ? '' : notes['policyInfo.regex.nonLetter']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.nonAlnum" type="info" label="#{notes['policyInfo.regex.nonAlnum'].contains('nonAlnum[0]') ? '' : notes['policyInfo.regex.nonAlnum']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.control" type="info" label="#{notes['policyInfo.regex.control'].contains('control[0]') ? '' : notes['policyInfo.regex.control']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.nonGraph" type="info" label="#{notes['policyInfo.regex.nonGraph'].contains('nonGraph[0]') ? '' : notes['policyInfo.regex.nonGraph']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.nonAscii" type="info" label="#{notes['policyInfo.regex.nonAscii'].contains('nonAscii[0]') ? '' : notes['policyInfo.regex.nonAscii']}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.dictionary" type="info" label="${notes.policyInfo.dictionary}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.history.History" type="info" label="${notes.policyInfo.history.History}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="policyInfo.regex.maxCharacterRepetitions" type="info" label="${notes.policyInfo.regex.maxCharacterRepetitions}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="isiwebnewpw1" type="pw-text" label="prompt.newpassword"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="isiwebnewpw2" type="pw-text" label="prompt.newpassword.confirm"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="submit" type="submit" label="submit.button.label" value="submit"/>
</Gui>
</Response>
<propertyRef name="nevisIDM_Connector"/>
</AuthState>
<AuthState name="ob-realm_ob-realm-idm-pwd-login-TerminateSessionState" class="ch.nevis.esauth.auth.states.standard.AuthGeneric" final="true">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Response value="AUTH_ERROR">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Arg name="nevis.transfer.type" value="redirect"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Arg name="nevis.transfer.destination" value="${request:currentResource:(https?.//[^/]+).*:$1}#{session.get(&quot;redirect&quot;)}"/>
</Response>
</AuthState>
<AuthState name="ob-realm_ob-realm-idm-pwd-login-IdmPasswordSetState" class="ch.nevis.esauth.auth.states.standard.AuthGeneric" final="true">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="default" next="ob-realm_ob-realm-idm-pwd-login-IdmSuccessfulChangeState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Response value="AUTH_CONTINUE">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Gui name="AuthDoneDialog" label="title.pwreset">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="info" type="info" label="pwreset.done.info"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="continue" type="button" label="continue.button.label" value="true"/>
</Gui>
</Response>
</AuthState>
<AuthState name="ob-realm_ob-realm-idm-pwd-login-IdmSuccessfulChangeState" class="ch.nevis.esauth.auth.states.standard.AuthGeneric" final="true">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Response value="AUTH_ERROR">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Arg name="nevis.transfer.type" value="redirect"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Arg name="nevis.transfer.destination" value="${request:currentResource:(https?.//[^/]+).*:$1}#{inargs.containsKey(&quot;redir&quot;) ? inargs.get(&quot;redir&quot;) : &quot;/&quot;}"/>
</Response>
</AuthState>
<AuthState name="ob-realm_ob-realm-idm-pwd-login-IdmUserVerifyState" class="ch.nevis.idm.authstate.IdmUserVerifyState" final="true" resumeState="true">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="clientNotFound" next="ob-realm_ob-realm-idm-pwd-login-AuthGenericState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="default" next="ob-realm_ob-realm-idm-pwd-login-AuthGenericState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="failed" next="ob-realm_ob-realm-idm-pwd-login-AuthGenericState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="prospect" next="ob-realm_ob-realm-idm-pwd-login-IdmCreateCredentialState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Response value="AUTH_CONTINUE">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Gui name="AuthInputDialog" label="title.pwreset">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="lasterror" type="error" label="${notes:lasterrorinfo}" value="${notes:lasterror}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="client" type="text" label="prompt.client" value="#{notes['client'] ? notes['client'] : 'Default' }"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="isiwebuserid" type="text" label="prompt.userid"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="submit" type="submit" label="submit.button.label" value="submit"/>
</Gui>
</Response>
<propertyRef name="nevisIDM_Connector"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<property name="user.loginType" value="EMAIL"/>
</AuthState>
<AuthState name="ob-realm_ob-realm-idm-pwd-login-AuthGenericState" class="ch.nevis.esauth.auth.states.standard.AuthGeneric" final="true">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="default" next="ob-realm_ob-realm-idm-pwd-login-TerminateSessionState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Response value="AUTH_CONTINUE">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Gui name="AuthDoneDialog" label="title.pwreset">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="info" type="info" label="pwreset.email.sent"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="continue" type="button" label="continue.button.label" value="true"/>
</Gui>
</Response>
</AuthState>
<AuthState name="ob-realm_ob-realm-idm-pwd-login-IdmCreateCredentialState" class="ch.nevis.idm.authstate.IdmCreateCredentialState" final="false" resumeState="true">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="clientNotFound" next="ob-realm_ob-realm-idm-pwd-login-IdmCreateCredentialState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="failed" next="ob-realm_ob-realm-idm-pwd-login-IdmCreateCredentialState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<ResultCond name="ok" next="ob-realm_ob-realm-idm-pwd-login-AuthGenericState"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Response value="AUTH_ERROR">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<Gui name="AuthErrorDialog" label="title.pwreset">
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="lasterror" type="error" label="${notes:lasterrorinfo}" value="${notes:lasterror}"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<GuiElem name="continue" type="button" label="continue.button.label" value="true"/>
</Gui>
</Response>
<propertyRef name="nevisIDM_Connector"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<property name="cred.type" value="url_ticket"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<property name="cred.urlPrefix" value="${request:currentResource:(https?.//[^/]+).*:$1}/pwreset/continue/?redir=#{session.get(&quot;redirect&quot;)}&amp;x="/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<property name="operationIfExists" value="FAIL"/>
<!-- source: pattern://e1784eecf2db74484dd1e1bb -->
<property name="recreateIfExists" value="true"/>
</AuthState>
<AuthState name="ob-realm_Selector" class="ch.nevis.esauth.auth.states.standard.ConditionalDispatcherState" final="false">
<!-- source: pattern://6e7b5a087711bd0ada9985fe -->
<ResultCond name="nomatch" next="ob-realm_Prepare_Done"/>
<!-- source: pattern://6e7b5a087711bd0ada9985fe -->
<Response value="AUTH_ERROR">
<!-- source: pattern://6e7b5a087711bd0ada9985fe -->
<Arg name="ch.nevis.isiweb4.response.status" value="403"/>
</Response>
</AuthState>
</AuthEngine>
</esauth-server>

View File

@ -0,0 +1,59 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
def getPathFromURL(url) {
def pattern = ~/https?.\/\/[^\/]+(\/[^\?]*|.*).*/
def matcher = pattern.matcher(url)
if (matcher.matches()) {
return matcher.group(1)
} else {
return null
}
}
if (request.getSession(false) == null) {
LOG.debug("No session - create new session")
session = request.getSession(true).getData()
}
def redirectionPath = getPathFromURL(request['currentResource'])
def applicationPaths = ["/register/","/pwreset/"]
def denyRegexes = [".*[\\n\\r]+.*"]
def denied = false
if (denyRegexes.size() > 0) {
for (def denyRegex : denyRegexes) {
def pattern = Pattern.compile(denyRegex)
def matcher = pattern.matcher(redirectionPath)
if (matcher.find()) {
denied = true
}
}
if (!denied) {
session.put('redirect', redirectionPath)
response.setResult('ok')
return
}
}
if (!applicationPaths.isEmpty()) {
for (String path : applicationPaths) {
if (redirectionPath.startsWith(path)) {
session.put('redirect', path)
response.setResult('ok')
return
}
}
}
if (denied) {
response.setResult('redirectionPathInvalid')
return
} else {
session.put('redirect', redirectionPath)
response.setResult('ok')
return
}

View File

@ -0,0 +1,41 @@
Configuration:
monitorInterval: 60
Appenders:
Console:
- name: "SERVER"
target: "SYSTEM_OUT"
PatternLayout:
pattern: "[esauth4sv.log] %d{ISO8601} %-15.15t %mdc{trace_id} %mdc{span_id} %-20.20c %-5.5p %m%n"
RegexFilter:
regex: ".*GET /nevisauth/liveness.*"
onMatch: "DENY"
onMismatch: "ACCEPT"
Loggers:
Logger:
- name: "ProductAnalytics"
level: "INFO"
- name: "EsAuthStart"
level: "INFO"
- name: "org.apache.catalina.loader.WebappClassLoader"
level: "FATAL"
- name: "org.apache.catalina.startup.HostConfig"
level: "ERROR"
- name: "ch.nevis.esauth.events"
level: "FATAL"
- name: "AuthEngine"
level: "INFO"
- name: "AuthPerf"
level: "INFO"
- name: "HttpClient"
level: "DEBUG"
- name: "OpTrace"
level: "INFO"
- name: "Script"
level: "DEBUG"
- name: "Vars"
level: "INFO"
Root:
level: "WARN"
additivity: "false"
AppenderRef:
- ref: "SERVER"

View File

@ -0,0 +1,23 @@
import ch.nevis.esauth.auth.engine.AuthResponse
if (inargs['SAMLResponse']) {
response.setNote('SAMLResponse', inargs['SAMLResponse'])
request.getInArgs().remove('SAMLResponse')
response.setResult('processResponse')
return
}
if (inargs['back'] && inargs['back'] == 'go') {
response.setStatus(AuthResponse.AUTH_ERROR)
if (session['ch.nevis.auth.saml.assertion.authnContextClassRef'] && session['ch.nevis.auth.saml.assertion.authnContextClassRef'] == 'urn:qa.agov.ch:names:tc:ac:classes:recovery') {
response.setTransferDestination(parameters['idp-recovery-url'])
} else {
response.setTransferDestination(parameters['idp-sso-url'])
}
response.setIsRedirectTransfer(true)
return
}
// if we reach this line, display the GUI
response.setStatus(AuthResponse.AUTH_CONTINUE)

View File

@ -0,0 +1,17 @@
server:
name: "default"
protocol: "https"
port: "8991"
host: "0.0.0.0"
max-threads: "200"
tls:
keystore: "/var/opt/keys/own/ob-auth-v1-default-identity/keystore.p12"
keystore-passphrase: "${exec:/var/opt/keys/own/ob-auth-v1-default-identity/keypass}"
client-auth: "required"
truststore: "/var/opt/keys/trust/ob-auth-v1-default-tls-client-trust/truststore.p12"
truststore-passphrase: "${exec:/var/opt/keys/trust/ob-auth-v1-default-tls-client-trust/keypass}"
management:
server:
port: "9000"
healthchecks:
enabled: "true"

View File

@ -0,0 +1,169 @@
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
import ch.nevis.esauth.auth.engine.AuthUtil
import ch.nevis.esauth.util.httpclient.configuration.HttpClientConfiguration
/**
*
* Initiate the registration process with a `POST /nevisfido/token/dispatch/registration` to nevisFIDO.
*
* @param username - required
* @param policy - default policy is used when null
*/
void dispatchRegistration(HttpClient httpClient, String baseUrl, String username, String policy) {
LOG.debug(" ==> Starting out-of-band mobile onboarding for username '{}'.", username)
String context = '{"username":"' + username + '", "policy":"' + (policy ?: 'default') + '"}'
def jsonBody = JsonOutput.toJson([
dispatcher: 'link',
getUafRequest: [
op: 'Reg',
context: context
]
])
LOG.debug("JSON body: {}", jsonBody)
def fidoRequest = Http.post().url(baseUrl + "/token/dispatch/registration")
.header('Accept', 'application/json; charset=utf-8')
.header('Content-Type', 'application/json; charset=utf-8')
.entity(Http.entity().content(jsonBody).build())
.build()
def fidoResponse = fidoRequest.send(httpClient)
def responseCode = fidoResponse.code()
if (responseCode != 200) {
LOG.error('<== Failed to enroll user with username: ' + username + '. Response: ' + responseCode + ": " + fidoResponse.bodyAsString())
response.setResult('failed')
return
}
def json = new JsonSlurper().parseText(fidoResponse.bodyAsString())
LOG.debug('JSON response: {}', json)
if (json.dispatchResult != 'dispatched') {
LOG.error('<== Failed to enroll user with username: ' + username + '. Response: ' + responseCode + ": " + fidoResponse.bodyAsString())
response.setResult('failed')
return
}
String dispatcherLink = json.dispatcherInformation.response
String sessionId = json.sessionId
// store dispatcher information and session ID as session variables
// to handle page refresh and status polling
// the session variable is rendered as a hidden field
// and picked up by the mauth_onboard.js to render a link / QR code
session.put('mauth_dispatcher_link', dispatcherLink)
// the session ID is used to handle status polling
session.put('mauth_session_id', sessionId)
}
/**
*
* Check registration status by sending a `POST /nevisfido/status` to nevisFIDO.
*
* @param sessionId - required
*/
void checkRegistrationStatus(HttpClient httpClient, String baseUrl, String sessionId) {
LOG.debug(" ==> Checking out-of-band mobile registration status for session '{}'.", sessionId)
def jsonBody = JsonOutput.toJson([
sessionId: sessionId
])
def fidoRequest = Http.post().url(baseUrl + "/status")
.header('Accept', 'application/json; charset=utf-8')
.header('Content-Type', 'application/json; charset=utf-8')
.entity(Http.entity().content(jsonBody).build())
.build()
def fidoResponse = fidoRequest.send(httpClient)
def responseCode = fidoResponse.code()
if (responseCode == 200) {
def json = new JsonSlurper().parseText(fidoResponse.bodyAsString())
LOG.debug('JSON response: {}', json)
String status = json.status
LOG.debug('status: {}', status)
def inctx = request.getLoginContext()
def contentType = request.getHttpHeader('Content-Type')
LOG.debug("incoming request has Content-Type: {}", contentType)
if (contentType ==~ /.*json.*/) {
LOG.debug("detected AJAX call")
// responding AJAX call from JS and returning only the status (nothing else)
def statusJson = JsonOutput.toJson([
status: status
])
response.setContent(statusJson)
response.setContentType('application/json')
response.setHttpStatusCode(200)
response.setIsDirectResponse(true)
}
else {
// this is a form POST and thus we have to check if we have to continue
if (status == 'succeeded') {
response.setResult('ok')
return
}
}
}
else {
LOG.error('<== Failed to check status for session ' + sessionId + '. Response: ' + responseCode + ": " + fidoResponse.bodyAsString())
response.setResult('failed')
}
}
// convert parameters to Properties
Properties properties = new Properties()
for (Map.Entry<String, String> entry : parameters.entrySet()) {
properties.setProperty(entry.getKey(), entry.getValue())
}
def httpClientConfig = HttpClientConfiguration.from(properties, request, response)
// we cannot use a cached HTTP client here as the parameters contain expressions that depend on the request
def httpClient = HttpClients.create(httpClientConfig)
def baseUrl = parameters.get('fidoUrl')
if (session.containsKey('mauth_session_id')) {
def sessionId = session['mauth_session_id']
// mauth_onboard.js sends empty AJAX calls to check for completion.
// we have to check the status by sending a `POST /nevisfido/status` to nevisFIDO respond to the AJAX call.
checkRegistrationStatus(httpClient, baseUrl, sessionId)
}
else {
def usernameSource = parameters.get('username')
if (usernameSource == null || usernameSource.isBlank()) {
LOG.error('out-of-band mobile onboarding failed. no expression to determine username.')
response.setResult('failed')
return
}
def username = AuthUtil.substituteVariables(request, response, usernameSource)
if (username == null || username.isBlank()) {
LOG.error('out-of-band mobile onboarding failed. missing username.')
response.setResult('failed')
return
}
def policy = parameters.get('policy')
dispatchRegistration(httpClient, baseUrl, username, policy)
}

View File

@ -0,0 +1,156 @@
import groovy.json.JsonBuilder
import groovy.json.JsonGenerator
import groovy.json.JsonSlurper
// we cannot use the name cancel and the -bottom is required in ID Cloud for rendering
if (inargs.containsKey('cancel-bottom')) {
response.setResult('cancel')
return
}
if (inargs.containsKey('failed')) {
response.setResult('failed')
return
}
def getUserFriendlyName(String userAgent) {
if (userAgent == null) {
return null
}
def sb = new StringBuilder()
// Check for browser
def browser = null
if (userAgent.contains('Chrome')) {
browser = 'Chrome'
}
else if (userAgent.contains('Firefox')) {
browser = 'Firefox'
}
else if (userAgent.contains('Safari')) {
browser = 'Safari'
}
else {
browser = 'Unknown browser'
}
// Check for operating system
def os = null
if (userAgent.contains('Windows')) {
os = 'Windows'
}
else if (userAgent.contains('Linux')) {
os = 'Linux'
}
else if (userAgent.contains('iOS')) {
os = 'iOS'
}
// Build the string
if (browser != null) {
sb.append(browser)
}
if (os != null) {
if (sb.length() > 0) {
sb.append(' on ')
}
sb.append(os)
}
return sb.toString()
}
def getPath() {
if (inargs.containsKey('path')) { // form POST
return inargs['path']
}
if (inargs.containsKey('o.path.v')) { // AJAX POST
return inargs['o.path.v']
}
return null
}
def post(requestBuilder, json) {
def body = json.toString()
LOG.info("==> Request: ${body}")
def entity = Http.entity().content(body).build()
def fidoRequest = requestBuilder.entity(entity).build()
def httpClient = HttpClients.create()
return fidoRequest.send(httpClient)
}
def path = getPath()
if (path == null) {
// POST from JavaScript not received
return // the AuthEngine will trigger default and thus the GUI will be rendered
}
String usernameVal = session['ch.adnovum.nevisidm.user.extId'] ?: session['ch.nevis.idm.User.extId'] ?: request.getUserId() ?: notes['userid']
if (usernameVal == null) {
LOG.error("missing username. check your authentication flow.")
}
Objects.requireNonNull(usernameVal) // fatal integration error
String displayNameVal = session['ch.nevis.idm.User.email'] ?: session['ch.nevis.session.loginid'] ?: request.getLoginId()
if (displayNameVal == null) {
LOG.error("missing displayName. check your authentication flow.")
}
Objects.requireNonNull(displayNameVal) // fatal integration error
def baseUrl = "https://" + parameters.get('fido')
def requestBuilder = Http.post().url(baseUrl + path)
.header('Accept', 'application/json')
.header('Content-Type', 'application/json;charset=utf-8')
def generator = new JsonGenerator.Options().excludeNulls().build()
def json = new JsonBuilder(generator)
if (path == '/nevisfido/fido2/attestation/options') {
def name = session['ch.nevis.idm.User.email'] ?: session['ch.nevis.session.loginid'] ?: request.getLoginId()
json {
"username" usernameVal
"displayName" displayNameVal
"authenticatorSelection" {
"authenticatorAttachment" parameters.get('authenticatorAttachment')
"requireResidentKey" parameters.get('requireResidentKey')
"residentKey" parameters.get('residentKey')
"userVerification" parameters.get('userVerification')
}
"attestation" parameters.get('attestation')
}
def fidoResponse = post(requestBuilder, json)
def responseCode = fidoResponse.code()
def responseText = fidoResponse.bodyAsString()
LOG.info("<== Response: ${responseCode} : ${responseText}")
response.setContent(responseText) // return response from nevisFIDO "as-is"
response.setContentType('application/json')
response.setHttpStatusCode(200)
response.setIsDirectResponse(true)
return
}
def userAgentVal = request.getHttpHeader('User-Agent')
def userFriendlyNameVal = getUserFriendlyName(userAgentVal)
if (path == '/nevisfido/fido2/attestation/result') {
json {
"id" inargs['id']
"type" inargs['type']
response {
"clientDataJSON" inargs['response.clientDataJSON']
"attestationObject" inargs['response.attestationObject']
}
"userFriendlyName" userFriendlyNameVal
"userAgent" userAgentVal
}
def fidoResponse = post(requestBuilder, json)
def responseCode = fidoResponse.code()
def responseText = fidoResponse.bodyAsString()
LOG.info("<== Response: ${responseCode} : ${responseText}")
if (responseCode == 200 && new JsonSlurper().parseText(responseText).status == 'ok') {
response.setResult('ok')
return
}
}
response.setError(1, "FIDO2 onboarding failed")

View File

@ -0,0 +1,4 @@
otel.service.name = ob-auth
otel.traces.exporter = none
otel.metrics.exporter = none
otel.logs.exporter = none

View File

@ -0,0 +1,23 @@
// nevisProxy replaces the entire AUTH: scope when new outargs are returned by nevisAuth.
// Thus, we have to store tokens in the session (as a String) and restore them on subsequent step-ups.
// restore tokens
session.each { key, value ->
if (key.startsWith('outarg.token.')) {
def name = key.substring(7)
if (outargs.containsKey(name)) {
LOG.debug("not restoring token (outarg: $name) from session: outarg already set")
}
else {
LOG.debug("restoring token (outarg: $name) from session")
outargs.put(name, value)
}
}
}
// store tokens
outargs.each { name, value ->
if (name.startsWith('token.')) {
session.put('outarg.' + name, value)
}
}

View File

@ -0,0 +1,79 @@
#!/bin/bash
#
# NAME
# status.sh - Checks the status of the nevisAuth instance.
#
# SYNOPSIS
# status.sh
#
# DESCRIPTION
# Performs periodic checks until the instance is up or broken or timeout is reached.
# The script terminates when the process of the instance stops running.
# There are no arguments for this script.
#
# EXIT CODES
# 0 Instance is up.
# 1 Instance process is not running.
# 2 Instance is broken.
# 3 Timeout reached.
# Defines how much we should sleep between checking if the instance is up.
interval=1
# Defines how much we should wait the instance to start up until we give up and exit.
timeout=70
((end_time=${SECONDS}+$timeout))
# Checks if the process of the instance is still running.
# Arguments:
# None
# Returns:
# In case it is running, returns 0, otherwise non-zero (exit code of systemctl).
isProcessRunning() {
systemctl is-active --quiet nevisauth@default
IS_RUNNING=$?
return $IS_RUNNING
}
# Checks if the instance is up. (Attempts connecting to the instance)
# Arguments:
# None
# Returns:
# If the connection was successful and the instance up (is not broken), returns 0.
# If the connection was not successful, returns 1.
checkInstance() {
lsof -i :8991 -sTCP:LISTEN
EXIT_CODE=$?
return $EXIT_CODE
}
# This function encapsulates the logic of checking if the process is running and if the instance is up.
# In case the process is not running, exits with exit code 1.
# Arguments:
# None
# Returns:
# If the instance process is running, returns the result of the instance check function.
check() {
if isProcessRunning
then
checkInstance
CS=$?
return $CS
else
echo "Process is not running."
exit 1
fi
}
# Check the status of the instance periodically.
while ((${SECONDS} < ${end_time}))
do
sleep ${interval}
if check
then
echo "Instance is up."
exit 0
fi
done
echo "Exceeded check timeout (70s). Instance is down."
exit 3

View File

@ -0,0 +1,63 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisComponent"
metadata:
name: "ob-fido-uaf-v1"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-fido-uaf-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "d990accd4fedae1acbc7109d"
spec:
type: "NevisFIDO"
replicas: 1
version: "8.2411.1"
gitInitVersion: "1.3.0"
runAsNonRoot: true
ports:
rest: 9443
management: 9089
resources:
limits:
cpu: "1000m"
memory: "1000Mi"
requests:
cpu: "100m"
memory: "700Mi"
livenessProbe:
management:
httpGet:
path: "/nevisfido/liveness"
periodSeconds: 5
timeoutSeconds: 6
readinessProbe:
management:
httpGet:
path: "/nevisfido/health"
periodSeconds: 5
timeoutSeconds: 6
startupProbe:
management:
httpGet:
path: "/nevisfido/health"
periodSeconds: 5
timeoutSeconds: 6
failureThreshold: 50
podDisruptionBudget:
maxUnavailable: "50%"
git:
tag: "r-ba59b3f1caf0da0e0f0589650bcae5845f2d05b1"
dir: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT/DEFAULT-DEFAULT-ADN-AGOV-OB-INV/ob-fido-uaf-v1"
credentials: "git-credentials"
database:
name: "ob-fido-uaf-v1"
requiredVersion: "8.2411.1"
keystores:
- "ob-fido-uaf-v1-default-server-identity"
truststores:
- "ob-fido-uaf-v1-default-client-trust"
- "ob-fido-uaf-v1-agov-work-internal-trust-store"
podSecurity:
policy: "baseline"
automountServiceAccountToken: false
timeZone: "Europe/Zurich"

View File

@ -0,0 +1,14 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisTrustStore"
metadata:
name: "ob-fido-uaf-v1-agov-work-internal-trust-store"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-fido-uaf-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "d990accd4fedae1acbc7109d"
spec:
keystores: []
extraCerts:
- "-----BEGIN CERTIFICATE-----\nMIIBcTCCARagAwIBAgIQWRl1eifIt8yohQYzh6yr/jAKBggqhkjOPQQDAjAYMRYw\nFAYDVQQDEw1zZWxmc2lnbmVkLWNhMB4XDTIzMDYyODE0MzI0MFoXDTQzMDYyODE0\nMzI0MFowGDEWMBQGA1UEAxMNc2VsZnNpZ25lZC1jYTBZMBMGByqGSM49AgEGCCqG\nSM49AwEHA0IABEwcjsIhSyyh0i9zP1G7ReOkFt/djzlGoUtSd5v3ZEk5QoZYjfl9\n04HdaZzrmveB2aRppbXgW7//s2Ma8wTd5uejQjBAMA4GA1UdDwEB/wQEAwICpDAP\nBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBT7YRoWIjHwkvFicwvk0Tx/yA4uUTAK\nBggqhkjOPQQDAgNJADBGAiEAgyg9t0qgb+czuscs07pNGI+12BedrD+y71psIlqx\nt2UCIQC/85UXyjYI9zg7Mg7rROTbGNCU3Jq/KIC3VzbbD+68VA==\n-----END CERTIFICATE-----\n"

View File

@ -0,0 +1,12 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisTrustStore"
metadata:
name: "ob-fido-uaf-v1-default-client-trust"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-fido-uaf-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "d990accd4fedae1acbc7109d"
spec:
keystores: []

View File

@ -0,0 +1,18 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisKeyStore"
metadata:
name: "ob-fido-uaf-v1-default-server-identity"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-fido-uaf-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "d990accd4fedae1acbc7109d"
spec:
cn: "ob-fido-uaf-v1"
usage: "<reserved for future use>"
san:
dns:
- "ob-fido-uaf-v1"
- "ob-fido-uaf-v1.adn-agov-nevisidm-ob-01-uat"
email: []

View File

@ -0,0 +1,26 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisDatabase"
metadata:
name: "ob-fido-uaf-v1"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-fido-uaf-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "e891ec2f4f924135261d22ce"
spec:
type: "NevisFIDO"
databaseType: "MariaDB"
version: "8.2411.1"
url: "mariadb-session-store-service.adn-agov-nevisidm-ob-01-uat"
port: 3306
database: "nevisfido_uaf"
bootstrap: true
migrate: true
rootCredentials:
name: "root-mariadb-session-store"
namespace: "adn-agov-nevisidm-ob-01-uat"
podSecurity:
policy: "baseline"
automountServiceAccountToken: false
timeZone: "Europe/Zurich"

View File

@ -0,0 +1,18 @@
schemaVersion: 1.0
instance:
type: "nevisfido"
name: "default"
directory: "/var/opt/nevisfido/default"
pid: "systemctl show nevisfido@default -p MainPID | cut -d '=' -f2"
source:
url: "/nevisadmin/#/projects/DEFAULT-ADN-AGOV-WORK-OB-PROJECT/patterns/d990accd4fedae1acbc7109d"
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "d990accd4fedae1acbc7109d"
patternClass: "ch.nevis.admin.v4.plugin.nevisfido.deployable.patterns.NevisFIDODeployable"
resources:
ports:
- "0.0.0.0:9443"
control:
start: "systemctl restart nevisfido@default"
stop: "systemctl stop nevisfido@default"
status: "systemctl status nevisfido@default"

View File

@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC6TCCAo+gAwIBAgIQfcfd9dgdKT/5gdDbpAiKlDAKBggqhkjOPQQDAjAYMRYw
FAYDVQQDEw1zZWxmc2lnbmVkLWNhMB4XDTI0MDUwNTE1NTAzOFoXDTI1MDUwNTE1
NTAzOFowWDELMAkGA1UEBhMCQ0gxDDAKBgNVBAgTA0s4UzEMMAoGA1UEBxMDSzhT
MQwwCgYDVQQKEwNLOFMxDDAKBgNVBAsTA0s4UzERMA8GA1UEAxMIZmlkby11YWYw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDWcQPIzUN2zbPkB3yISIGw
mDAd285YKm/ZLbE4WWw2SIHhjfh0XoYZ6QvLMENWcC8/iOX/6g6upQnYegzZKlST
Lix0zJjEbtMlK8fITiPhwziWPSOeqtuW66Rj+13G6kKYVtZ8vviu73LBDkXKHSNi
g4knNgACJpIItiDhOmtmD3Wsb8JAIQ161m7D3i2jr/kqBFKLc2DXcCHYSwxBXu3A
99iqWxoHfprL/L7RfxBo7mKbk+xjRvw6wFHBb76m6hd8fe4yg3g9zZTsZ5KeKqtA
8NT7CTG26F/MEBEmreU6NcNP62sYBkQiY+K5WweUs5qnDCAUPz+Upu0lX49ZDsvZ
AgMBAAGjga8wgawwDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMB
BggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFPthGhYiMfCS8WJz
C+TRPH/IDi5RMEwGA1UdEQRFMEOCCGZpZG8tdWFmgiFmaWRvLXVhZi5hZG4tYWdv
di1uZXZpc2lkbS0wMS11YXSBFG5vcmVwbHlAbG9jYWwuZG9tYWluMAoGCCqGSM49
BAMCA0gAMEUCIBCueTTUwnN53/dIs6W4FpbFtF/wkAhYjLZGuKgY08ZAAiEA9VFz
WoaxaINHqGPR10Sh1hqeuCHRzHxnQUt07sZf2DU=
-----END CERTIFICATE-----

View File

@ -0,0 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFKzBVBgkqhkiG9w0BBQ0wSDAnBgkqhkiG9w0BBQwwGgQUWtp2pbSNdJCf9jA9
KTzjbdorVLQCAggAMB0GCWCGSAFlAwQBKgQQb0NJGFGc8MxZaCZ71uYlEASCBND5
XhsSZKjT6CN02euPCcN5ssgXTfOlHG5hl4KcpNl/K61CH+gNH3rTzzao8utmd5ko
cWbl6o6nj2IdiU8IlaqI+VIR2nfHaqoGhJHfLbvPu/SItKTFjFTRRKddyKTIjN0o
eVbHMzt8pHvNKnNK2JmKQ+TqphGTaDIgEEqPRSniE6WHLGuCfG/VdaeRxTZldj9D
QDR41gC2kgDbsenkZZjhGEJpgM4g3mD7bc0IHMRG1wfSW8qyd+S+XxjYdgMJmffc
PCMPv3TJ0Xbxfw+BKED9WeSIaXfCFmVprNXhWhMMN8Z7o3WxigVo2oRkHWbhSff4
hFy4AQgyq8TOE1C2xeAcADEFagCHDdf0cs5LgwytpH5/0oTsm0+pFol6yEa7X1rF
Eu7NT8zLxXxqUdlCJ1A2AWbi17ER6snst4RfT7cCiI3d6q6IO2dsfuHSs17AHY2m
1KSfgVwH05o3W58ADUVuoZxtqCS0xMv2mvlTJ7xSb90R4hz5w1JBKjrYqq1Xy1Lr
pDc9kBEwJKtN9V63veUnHR5tFku9mVTEK6iykYWRNORexNEas5wsiuxrgaXtGN5G
ouhq9MCe5DI0coQOHM0Bvw1zfQ+wj8RUgrt0290WF0VtHW+zH0qbVHYZ6dKRY5YX
azzLvyu5AlH9p2MZr/+oZn6lgjmVEYq0UbsUvFoZy65qwi2XqL7FvXIVSVTgr7YY
hiODL4FBWJEevE+MujfOpOftzivdx1+/cuiQHcbqKlPQLnQXaUKI337u2o8uAEch
lP3AvI4DVi4m6IC9lo6657r8MqwMGmdEK9PRDPHUf7SP3HGX8fYArwRWILtHrcmc
/kHhKUkMxHduFb0nYQTVFnlpLEidcv6gYIVsh8Fx5pQWW+HyBD4sJuG7mLMgtmtY
vk9zayWbq0lw0Bb+E83vk9xtE0tUoFF/Wcl2nBf5PjfCqesGqr9CHElcQGfcINCg
3llXoeceN868e5DKgtQE6Fp5KukclgeeeX4kPj+UK7x4UGtdGcdghwH6EO7McQX1
67kyLDcF4p5HnrzEhP2CVcVDHXoeykMCitvHaInwmJQsR209PVa/XxXB8YoMAAV1
DB3GT024dAxFEl5r1HJm3A7BiFFuvQdUi+recFGKfmSNZ1Pwp2+8DV7UiAYLJ5Wf
o/aAwUQByITI3fBPvmEAA86FeWwtQ5BG5e+q7imH1ooOzrHQzaqwzQKU+IQCzaDF
sAqMtSD/hzIRjMKOSAL8bA2SVIXlLUnulWjPwW9zhUTv9yS1q2EsiFUJnOyq7iAI
fX72qEBvBXLFBdGhotMAXeg1YsXLUxbldqAWuPxpZMQ5S6J7GZZloXSe1Gy/ZZh4
tKD8qQTS5Rfwiqxxo3kgaB/z0qG99pTB/wWv4fwnv6lFjJRjgyGONRYIGCVCFH2X
mdV2rTUxtwB1cIr71ksA64O3YkUObyfT8gSbLjPoBDBBPQQ3crbaQdiOjGUE9zUF
8kp3/mVj/kBCNtlc4dR/lJGuM97h2OpR5sLvb/5TN9C3tcXUyRmDjqJY/eX9ui0D
pEe6juN9Wy1yZtHauTIK0dqol+DJr56mMdMzBBmDagdr17Q2XK+GKrp5Z9rPbXJv
8qjMHKVFlbQRMtOY8N/PQenRyl1XmZIPk9HWj+9+6w==
-----END ENCRYPTED PRIVATE KEY-----

View File

@ -0,0 +1,2 @@
#!/bin/bash
echo 'Hsk+IJIkp1oGu8i1S+w6p2QMDB+9WFSNjNlSYdUCfA8='

View File

@ -0,0 +1,49 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFKzBVBgkqhkiG9w0BBQ0wSDAnBgkqhkiG9w0BBQwwGgQUWtp2pbSNdJCf9jA9
KTzjbdorVLQCAggAMB0GCWCGSAFlAwQBKgQQb0NJGFGc8MxZaCZ71uYlEASCBND5
XhsSZKjT6CN02euPCcN5ssgXTfOlHG5hl4KcpNl/K61CH+gNH3rTzzao8utmd5ko
cWbl6o6nj2IdiU8IlaqI+VIR2nfHaqoGhJHfLbvPu/SItKTFjFTRRKddyKTIjN0o
eVbHMzt8pHvNKnNK2JmKQ+TqphGTaDIgEEqPRSniE6WHLGuCfG/VdaeRxTZldj9D
QDR41gC2kgDbsenkZZjhGEJpgM4g3mD7bc0IHMRG1wfSW8qyd+S+XxjYdgMJmffc
PCMPv3TJ0Xbxfw+BKED9WeSIaXfCFmVprNXhWhMMN8Z7o3WxigVo2oRkHWbhSff4
hFy4AQgyq8TOE1C2xeAcADEFagCHDdf0cs5LgwytpH5/0oTsm0+pFol6yEa7X1rF
Eu7NT8zLxXxqUdlCJ1A2AWbi17ER6snst4RfT7cCiI3d6q6IO2dsfuHSs17AHY2m
1KSfgVwH05o3W58ADUVuoZxtqCS0xMv2mvlTJ7xSb90R4hz5w1JBKjrYqq1Xy1Lr
pDc9kBEwJKtN9V63veUnHR5tFku9mVTEK6iykYWRNORexNEas5wsiuxrgaXtGN5G
ouhq9MCe5DI0coQOHM0Bvw1zfQ+wj8RUgrt0290WF0VtHW+zH0qbVHYZ6dKRY5YX
azzLvyu5AlH9p2MZr/+oZn6lgjmVEYq0UbsUvFoZy65qwi2XqL7FvXIVSVTgr7YY
hiODL4FBWJEevE+MujfOpOftzivdx1+/cuiQHcbqKlPQLnQXaUKI337u2o8uAEch
lP3AvI4DVi4m6IC9lo6657r8MqwMGmdEK9PRDPHUf7SP3HGX8fYArwRWILtHrcmc
/kHhKUkMxHduFb0nYQTVFnlpLEidcv6gYIVsh8Fx5pQWW+HyBD4sJuG7mLMgtmtY
vk9zayWbq0lw0Bb+E83vk9xtE0tUoFF/Wcl2nBf5PjfCqesGqr9CHElcQGfcINCg
3llXoeceN868e5DKgtQE6Fp5KukclgeeeX4kPj+UK7x4UGtdGcdghwH6EO7McQX1
67kyLDcF4p5HnrzEhP2CVcVDHXoeykMCitvHaInwmJQsR209PVa/XxXB8YoMAAV1
DB3GT024dAxFEl5r1HJm3A7BiFFuvQdUi+recFGKfmSNZ1Pwp2+8DV7UiAYLJ5Wf
o/aAwUQByITI3fBPvmEAA86FeWwtQ5BG5e+q7imH1ooOzrHQzaqwzQKU+IQCzaDF
sAqMtSD/hzIRjMKOSAL8bA2SVIXlLUnulWjPwW9zhUTv9yS1q2EsiFUJnOyq7iAI
fX72qEBvBXLFBdGhotMAXeg1YsXLUxbldqAWuPxpZMQ5S6J7GZZloXSe1Gy/ZZh4
tKD8qQTS5Rfwiqxxo3kgaB/z0qG99pTB/wWv4fwnv6lFjJRjgyGONRYIGCVCFH2X
mdV2rTUxtwB1cIr71ksA64O3YkUObyfT8gSbLjPoBDBBPQQ3crbaQdiOjGUE9zUF
8kp3/mVj/kBCNtlc4dR/lJGuM97h2OpR5sLvb/5TN9C3tcXUyRmDjqJY/eX9ui0D
pEe6juN9Wy1yZtHauTIK0dqol+DJr56mMdMzBBmDagdr17Q2XK+GKrp5Z9rPbXJv
8qjMHKVFlbQRMtOY8N/PQenRyl1XmZIPk9HWj+9+6w==
-----END ENCRYPTED PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIC6TCCAo+gAwIBAgIQfcfd9dgdKT/5gdDbpAiKlDAKBggqhkjOPQQDAjAYMRYw
FAYDVQQDEw1zZWxmc2lnbmVkLWNhMB4XDTI0MDUwNTE1NTAzOFoXDTI1MDUwNTE1
NTAzOFowWDELMAkGA1UEBhMCQ0gxDDAKBgNVBAgTA0s4UzEMMAoGA1UEBxMDSzhT
MQwwCgYDVQQKEwNLOFMxDDAKBgNVBAsTA0s4UzERMA8GA1UEAxMIZmlkby11YWYw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDWcQPIzUN2zbPkB3yISIGw
mDAd285YKm/ZLbE4WWw2SIHhjfh0XoYZ6QvLMENWcC8/iOX/6g6upQnYegzZKlST
Lix0zJjEbtMlK8fITiPhwziWPSOeqtuW66Rj+13G6kKYVtZ8vviu73LBDkXKHSNi
g4knNgACJpIItiDhOmtmD3Wsb8JAIQ161m7D3i2jr/kqBFKLc2DXcCHYSwxBXu3A
99iqWxoHfprL/L7RfxBo7mKbk+xjRvw6wFHBb76m6hd8fe4yg3g9zZTsZ5KeKqtA
8NT7CTG26F/MEBEmreU6NcNP62sYBkQiY+K5WweUs5qnDCAUPz+Upu0lX49ZDsvZ
AgMBAAGjga8wgawwDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMB
BggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFPthGhYiMfCS8WJz
C+TRPH/IDi5RMEwGA1UdEQRFMEOCCGZpZG8tdWFmgiFmaWRvLXVhZi5hZG4tYWdv
di1uZXZpc2lkbS0wMS11YXSBFG5vcmVwbHlAbG9jYWwuZG9tYWluMAoGCCqGSM49
BAMCA0gAMEUCIBCueTTUwnN53/dIs6W4FpbFtF/wkAhYjLZGuKgY08ZAAiEA9VFz
WoaxaINHqGPR10Sh1hqeuCHRzHxnQUt07sZf2DU=
-----END CERTIFICATE-----

View File

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICwzCCAmmgAwIBAgIRAIgdSB3tN8ZLL8RUMEGevQQwCgYIKoZIzj0EAwIwGDEW
MBQGA1UEAxMNc2VsZnNpZ25lZC1jYTAeFw0yNDA3MTcwNzI5MDFaFw0yNTA3MTcw
NzI5MDFaMFYxCzAJBgNVBAYTAkNIMQwwCgYDVQQIEwNLOFMxDDAKBgNVBAcTA0s4
UzEMMAoGA1UEChMDSzhTMQwwCgYDVQQLEwNLOFMxDzANBgNVBAMTBnNpZ25lcjCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOyJFpEW1XRq43YwOU/e9ufh
128Yct8Q3f6HoRaXpUmygAkUsyBwOLWmwNeS80SLyOVegco6kGOdoMvnZsLX3ujf
cASkbN+93xhc2MpJXvfWbLbFGrpuQki3V5Banw+UulBuTltFLmxaIRXs1y4Ny2uh
US98LjFY3YD+3d5WG7UpgRTJ+x+t+8nqnPVOJ5asfcirM8/lRB4drUAwCOv51XLR
fRbqCaXKpVaiw/vD5KpAOUH2N1cikfOTOY6rce0wgVDGS7eoCfkCN4gT1LG+134M
p0KT3FBikTGdkH6dQ52nTn7xm5byJvNYzq+2zKGdosYAGurdGGw+KLFsFKCpB40C
AwEAAaOBijCBhzAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU+2EaFiIx8JLxYnML
5NE8f8gOLlEwJwYDVR0RBCAwHoIGc2lnbmVygRRub3JlcGx5QGxvY2FsLmRvbWFp
bjAKBggqhkjOPQQDAgNIADBFAiBxCyNHGWTpj8oma8cY/rUVMZu/BSDH7zzrDhh6
Q9eJegIhAIGivTcBUZvogUDfNo7IXmmxDqZHrjpoLeu6+VgTY9Qs
-----END CERTIFICATE-----

View File

@ -0,0 +1,10 @@
RUN_ARGS="--config conf/nevisfido.yml --log-config conf/logging.yml"
JAVA_OPTS=(
"-XX:+UseContainerSupport"
"-XX:MaxRAMPercentage=80.0"
"-javaagent:/opt/agent/opentelemetry-javaagent.jar"
"-Dotel.javaagent.logging=application"
"-Dotel.javaagent.configuration-file=/var/opt/nevisfido/default/conf/otel.properties"
"-Dotel.resource.attributes=service.version=8.2411.1,service.instance.id=$HOSTNAME"
)

View File

@ -0,0 +1,27 @@
Configuration:
monitorInterval: 60
Appenders:
Console:
- name: "SERVER"
target: "SYSTEM_OUT"
PatternLayout:
pattern: "[nevisfido.log] %d{ISO8601} %-15.15t %mdc{trace_id} %mdc{span_id} %-40.40c %-5.5p %m%n"
RegexFilter:
regex: ".*GET /nevisfido/liveness.*"
onMatch: "DENY"
onMismatch: "ACCEPT"
Loggers:
Logger:
- name: "ProductAnalytics"
level: "INFO"
- name: "ch.nevis.auth.fido.application.Application"
level: "INFO"
- name: "OpTrace"
level: "INFO"
- name: "ch.nevis.auth.fido.api.uaf"
level: "DEBUG"
Root:
level: "WARN"
additivity: "false"
AppenderRef:
- ref: "SERVER"

View File

@ -0,0 +1,271 @@
[
{
"aaid" : "F1D0#0001",
"description" : "Android NEVIS Mobile Authentication PIN Authenticator",
"assertionScheme" : "UAFV1TLV",
"attestationRootCertificates" : [
"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"
],
"attestationTypes" : [ 15879, 15880 ],
"upv" : [ {
"major" : 1,
"minor" : 1
} ],
"userVerificationDetails" : [ [ {
"userVerification" : 4
} ] ],
"attachmentHint" : 1,
"authenticationAlgorithms" : [ 2, 9 ],
"authenticatorVersion" : 1,
"isSecondFactorOnly" : false,
"keyProtection" : 1,
"matcherProtection" : 1,
"publicKeyAlgAndEncodings" : [ 257, 259 ],
"tcDisplay" : 1,
"tcDisplayContentType" : "text/plain"
},
{
"aaid" : "F1D0#0002",
"description" : "Android NEVIS Mobile Authentication Fingerprint Authenticator",
"assertionScheme" : "UAFV1TLV",
"attestationRootCertificates" : [
"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"
],
"attestationTypes" : [ 15879, 15880 ],
"upv" : [ {
"major" : 1,
"minor" : 1
} ],
"userVerificationDetails" : [ [ {
"userVerification" : 2
} ] ],
"attachmentHint" : 1,
"authenticationAlgorithms" : [ 2, 9 ],
"authenticatorVersion" : 1,
"isSecondFactorOnly" : false,
"keyProtection" : 4,
"matcherProtection" : 2,
"publicKeyAlgAndEncodings" : [ 257, 259 ],
"tcDisplay" : 1,
"tcDisplayContentType" : "text/plain"
},
{
"aaid" : "F1D0#0003",
"description" : "Android NEVIS Mobile Authentication Biometric Authenticator",
"assertionScheme" : "UAFV1TLV",
"attestationRootCertificates" : [
"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"
],
"attestationTypes" : [ 15879, 15880 ],
"upv" : [ {
"major" : 1,
"minor" : 1
} ],
"userVerificationDetails" : [ [ {
"userVerification" : 346
} ] ],
"attachmentHint" : 1,
"authenticationAlgorithms" : [ 2, 9 ],
"authenticatorVersion" : 1,
"isSecondFactorOnly" : false,
"keyProtection" : 4,
"matcherProtection" : 2,
"publicKeyAlgAndEncodings" : [ 257, 259 ],
"tcDisplay" : 1,
"tcDisplayContentType" : "text/plain"
},
{
"aaid" : "F1D0#0004",
"description" : "Android NEVIS Mobile Authentication Device Passcode Authenticator",
"assertionScheme" : "UAFV1TLV",
"attestationRootCertificates" : [
"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"
],
"attestationTypes" : [ 15879, 15880 ],
"upv" : [ {
"major" : 1,
"minor" : 1
} ],
"userVerificationDetails" : [ [ {
"userVerification" : 132
} ] ],
"attachmentHint" : 1,
"authenticationAlgorithms" : [ 2, 9 ],
"authenticatorVersion" : 1,
"isSecondFactorOnly" : false,
"keyProtection" : 4,
"matcherProtection" : 2,
"publicKeyAlgAndEncodings" : [ 257, 259 ],
"tcDisplay" : 1,
"tcDisplayContentType" : "text/plain"
},
{
"aaid" : "F1D0#0005",
"description" : "Android NEVIS Mobile Authentication Password Authenticator",
"assertionScheme" : "UAFV1TLV",
"attestationRootCertificates" : [
"MIIFYDCCA0igAwIBAgIJAOj6GWMU0voYMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNVBAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMTYwNTI2MTYyODUyWhcNMjYwNTI0MTYyODUyWjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdSSxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggjnar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGqC4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQoVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+OJtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/EgsTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRiigHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+MRPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9EaDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5UmAGMCAwEAAaOBpjCBozAdBgNVHQ4EFgQUNmHhAHyIBQlRi0RsR/8aTMnqTxIwHwYDVR0jBBgwFoAUNmHhAHyIBQlRi0RsR/8aTMnqTxIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwQAYDVR0fBDkwNzA1oDOgMYYvaHR0cHM6Ly9hbmRyb2lkLmdvb2dsZWFwaXMuY29tL2F0dGVzdGF0aW9uL2NybC8wDQYJKoZIhvcNAQELBQADggIBACDIw41L3KlXG0aMiS//cqrG+EShHUGo8HNsw30W1kJtjn6UBwRM6jnmiwfBPb8VA91chb2vssAtX2zbTvqBJ9+LBPGCdw/E53Rbf86qhxKaiAHOjpvAy5Y3m00mqC0w/Zwvju1twb4vhLaJ5NkUJYsUS7rmJKHHBnETLi8GFqiEsqTWpG/6ibYCv7rYDBJDcR9W62BW9jfIoBQcxUCUJouMPH25lLNcDc1ssqvC2v7iUgI9LeoM1sNovqPmQUiG9rHli1vXxzCyaMTjwftkJLkf6724DFhuKug2jITV0QkXvaJWF4nUaHOTNA4uJU9WDvZLI1j83A+/xnAJUucIv/zGJ1AMH2boHqF8CY16LpsYgBt6tKxxWH00XcyDCdW2KlBCeqbQPcsFmWyWugxdcekhYsAWyoSf818NUsZdBWBaR/OukXrNLfkQ79IyZohZbvabO/X+MVT3rriAoKc8oE2Uws6DF+60PV7/WIPjNvXySdqspImSN78mflxDqwLqRBYkA3I75qppLGG9rp7UCdRjxMl8ZDBld+7yvHVgt1cVzJx9xnyGCC23UaicMDSXYrB4I4WHXPGjxhZuCuPBLTdOLU8YRvMYdEvYebWHMpvwGCF6bAx3JBpIeOQ1wDB5y0USicV3YgYGmi+NZfhA4URSh77Yd6uuJOJENRaNVTzk",
"MIIFHDCCAwSgAwIBAgIJANUP8luj8tazMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNVBAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMTkxMTIyMjAzNzU4WhcNMzQxMTE4MjAzNzU4WjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdSSxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggjnar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGqC4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQoVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+OJtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/EgsTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRiigHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+MRPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9EaDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5UmAGMCAwEAAaNjMGEwHQYDVR0OBBYEFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMB8GA1UdIwQYMBaAFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4ICAQBOMaBc8oumXb2voc7XCWnuXKhBBK3e2KMGz39t7lA3XXRe2ZLLAkLM5y3J7tURkf5a1SutfdOyXAmeE6SRo83Uh6WszodmMkxK5GM4JGrnt4pBisu5igXEydaW7qq2CdC6DOGjG+mEkN8/TA6p3cnoL/sPyz6evdjLlSeJ8rFBH6xWyIZCbrcpYEJzXaUOEaxxXxgYz5/cTiVKN2M1G2okQBUIYSY6bjEL4aUN5cfo7ogP3UvliEo3Eo0YgwuzR2v0KR6C1cZqZJSTnghIC/vAD32KdNQ+c3N+vl2OTsUVMC1GiWkngNx1OO1+kXW+YTnnTUOtOIswUP/Vqd5SYgAImMAfY8U9/iIgkQj6T2W6FsScy94IN9fFhE1UtzmLoBIuUFsVXJMTz+Jucth+IqoWFua9v1R93/k98p41pjtFX+H8DslVgfP097vju4KDlqN64xV1grw3ZLl4CiOe/A91oeLm2UHOq6wn3esB4r2EIQKb6jTVGu5sYCcdWpXr0AUVqcABPdgL+H7qJguBw09ojm6xNIrw2OocrDKsudk/okr/AwqEyPKw9WnMlQgLIKw1rODG2NvU9oR3GVGdMkUBZutL8VuFkERQGt6vQ2OCw0sV47VMkuYbacK/xyZFiRcrPJPb41zgbQj9XAEyLKCHex0SdDrx+tWUDqG8At2JHA==",
"MIIFHDCCAwSgAwIBAgIJAMNrfES5rhgxMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNVBAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMjExMTE3MjMxMDQyWhcNMzYxMTEzMjMxMDQyWjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdSSxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggjnar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGqC4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQoVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+OJtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/EgsTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRiigHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+MRPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9EaDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5UmAGMCAwEAAaNjMGEwHQYDVR0OBBYEFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMB8GA1UdIwQYMBaAFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4ICAQBTNNZe5cuf8oiq+jV0itTGzWVhSTjOBEk2FQvh11J3o3lna0o7rd8RFHnN00q4hi6TapFhh4qaw/iG6Xg+xOan63niLWIC5GOPFgPeYXM9+nBb3zZzC8ABypYuCusWCmt6Tn3+Pjbz3MTVhRGXuT/TQH4KGFY4PhvzAyXwdjTOCXID+aHud4RLcSySr0Fq/L+R8TWalvM1wJJPhyRjqRCJerGtfBagiALzvhnmY7U1qFcS0NCnKjoO7oFedKdWlZz0YAfu3aGCJd4KHT0MsGiLZez9WP81xYSrKMNEsDK+zK5fVzw6jA7cxmpXcARTnmAuGUeI7VVDhDzKeVOctf3a0qQLwC+d0+xrETZ4r2fRGNw2YEs2W8Qj6oDcfPvq9JySe7pJ6wcHnl5EZ0lwc4xH7Y4Dx9RA1JlfooLMw3tOdJZH0enxPXaydfAD3YifeZpFaUzicHeLzVJLt9dvGB0bHQLE4+EqKFgOZv2EoP686DQqbVS1u+9k0p2xbMA105TBIk7npraa8VM0fnrRKi7wlZKwdH+aNAyhbXRW9xsnODJ+g8eF452zvbiKKngEKirK5LGieoXBX7tZ9D1GNBH2Ob3bKOwwIWdEFle/YF/h6zWgdeoaNGDqVBrLr2+0DtWoiB1aDEjLWl9FmyIUyUm7mD/vFDkzF+wm7cyWpQpCVQ==",
"MIIFHDCCAwSgAwIBAgIJAPHBcqaZ6vUdMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNVBAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMjIwMzIwMTgwNzQ4WhcNNDIwMzE1MTgwNzQ4WjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdSSxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggjnar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGqC4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQoVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+OJtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/EgsTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRiigHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+MRPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9EaDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5UmAGMCAwEAAaNjMGEwHQYDVR0OBBYEFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMB8GA1UdIwQYMBaAFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4ICAQB8cMqTllHc8U+qCrOlg3H7174lmaCsbo/bJ0C17JEgMLb4kvrqsXZs01U3mB/qABg/1t5Pd5AORHARs1hhqGICW/nKMav574f9rZN4PC2ZlufGXb7sIdJpGiO9ctRhiLuYuly10JccUZGEHpHSYM2GtkgYbZba6lsCPYAAP83cyDV+1aOkTf1RCp/lM0PKvmxYN10RYsK631jrleGdcdkxoSK//mSQbgcWnmAEZrzHoF1/0gso1HZgIn0YLzVhLSA/iXCX4QT2h3J5z3znluKG1nv8NQdxei2DIIhASWfu804CA96cQKTTlaae2fweqXjdN1/v2nqOhngNyz1361mFmr4XmaKH/ItTwOe72NI9ZcwS1lVaCvsIkTDCEXdm9rCNPAY10iTunIHFXRh+7KPzlHGewCq/8TOohBRn0/NNfh7uRslOSZ/xKbN9tMBtw37Z8d2vvnXq/YWdsm1+JLVwn6yYD/yacNJBlwpddla8eaVMjsF6nBnIgQOf9zKSe06nSTqvgwUHosgOECZJZ1EuzbH4yswbt02tKtKEFhx+v+OTge/06V+jGsqTWLsfrOCNLuA8H++z+pUENmpqnnHovaI47gC+TNpkgYGkkBT6B/m/U01BuOBBTzhIlMEZq9qkDWuM2cA5kW5V3FJUcfHnw1IdYIg2Wxg7yHcQZemFQg==",
"MIIC8jCCAdqgAwIBAgIGAZFrLh2fMA0GCSqGSIb3DQEBCwUAMDoxDjAMBgNVBAMMBXRlc3R5MQswCQYDVQQGEwJVUzEbMBkGCSqGSIb3DQEJARYMYWJjQGFjbWUuY29tMB4XDTI0MDgxOTE1MDc1MFoXDTI1MDgxOTE1MDc1MFowOjEOMAwGA1UEAwwFdGVzdHkxCzAJBgNVBAYTAlVTMRswGQYJKoZIhvcNAQkBFgxhYmNAYWNtZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDqitlYBzaxbPF389ZT5xkSS9Le1qdIOuc+dLVpBSWP9PEJhVZROgdOHs5f666iAcBedQm73sew3rpl+02J4fSgGmPkIYm1G2vkIrpt0eB9KzSc0AiLZbrPcFZOLHcOLoqVTfoRhnmAksHDC2f8euNKhCyriK8xlJb/xPfAfCn4r58ZGsQPUS7cJL6FLYh7FjrqfYDS10VOrQvGOALrG5NUj1DdqRq0M+klgs+6oJdUZTtY62BKkWh3N+7moNvrqykpv+ydFUJltgezDcb4Br8Nkw/breSPnomRfyHIcAcfATZcOPJlI8pO0zFZDIz8r7ESMnBhAxNaZgsUhR2XbaqbAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAGw5XLY6GeFJMP350+djhcVqAw+E4HZqCJu1BMpYC0qS2D85fFi3gNuV0TnqB52abX1WBDDJK1CA0SPdyo/nX+qQzP6Dba1AVRKpRzdcsDsMDN3eMC08tajHgIIf5tNDv+HGE/MT2br4o5oducmQMOfV1NTJO1xhXYVqbsUnyrq3S6kD9WS8zRl6ruY1rT26eCQ4hTLHPaAiVsoXh5TBRXYCvGlAw7o2d9cmsbySforZ2wgdZwmu43B5eHNnt4NlDxZRyz6iEDP0nT877aB2ffsOKHAkJNuTvF5JSfnVzLmiyfa/7NI1ujfzcpA2UUXoWa7WN0wACiZQot8Zmswonjc=",
"MIIC8jCCAdqgAwIBAgIGAZFrJblQMA0GCSqGSIb3DQEBCwUAMDoxDTALBgNVBAMMBHRlc3QxCzAJBgNVBAYTAkNIMRwwGgYJKoZIhvcNAQkBFg1mYWtlQGFjbWUuY29tMB4XDTI0MDgxOTE0NTg0MFoXDTI1MDgxOTE0NTg0MFowOjENMAsGA1UEAwwEdGVzdDELMAkGA1UEBhMCQ0gxHDAaBgkqhkiG9w0BCQEWDWZha2VAYWNtZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcWDBNmdq13fYHnhsmLndAW+MfbI6PeU4OenqfbrTtQUxqpyqhP6QccPYKX2SK3JeQo5uuF1jRD/9i9vAXI9NyiMMHSItjt9LjRs7bWnY4lokYGCAcSZooR9fGZX63dBSQo73V7MC8LDFGy5rw6dGDOmh0ktKxFzaT/nav8/Mx8FyG7M9+b5OPIBo2yze5Rd5cdErGJuUYa9No93BBr5tq+JfnmR/gwgCOke97ovhNj+sMu5bt946AxC6t00wNyPNVlJHKi1os0c/pWztTQkoRAx/w0JYKS9Afl0ZnGWQQ5PNLHHecp2GzriBpQAPXq81QTbOh5H7SzvhkaFQ4oxstAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAD8GOaeMDqj2mzMmCqR6Cr3ChkbDAkdsBa5lOAikMKs7/tJyaw8iA5yH0nyobC58Jb61IATuxABPUALhP3RiNsUhnQQF/Dh+6CnCTD/2wsZmr8vUvNqyCLom+xkMT6Wayd9LYW4UONARv1qCLVI4RhiAr5kcomwqZnuj2DRF697lbSQDoz3iuKrCyBYSCBhS+k7UXpqpMyB2D6quRuPqh7JNtMjGSeMiNpMXhx5f4kl1YWb8NU93LDwHFR2kwnGmPA3M272VitcJC4dz3itGRKm9EYGd6d5D7kdC6lqpZPSIopChvXDyVrXjQgckvgtSGKscs6AvYgjthJGsR2z3Eao=",
"MIIC8jCCAdqgAwIBAgIGAZFrLh2fMA0GCSqGSIb3DQEBCwUAMDoxDjAMBgNVBAMMBXRlc3R5MQswCQYDVQQGEwJVUzEbMBkGCSqGSIb3DQEJARYMYWJjQGFjbWUuY29tMB4XDTI0MDgxOTE1MDc1MFoXDTI1MDgxOTE1MDc1MFowOjEOMAwGA1UEAwwFdGVzdHkxCzAJBgNVBAYTAlVTMRswGQYJKoZIhvcNAQkBFgxhYmNAYWNtZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDqitlYBzaxbPF389ZT5xkSS9Le1qdIOuc+dLVpBSWP9PEJhVZROgdOHs5f666iAcBedQm73sew3rpl+02J4fSgGmPkIYm1G2vkIrpt0eB9KzSc0AiLZbrPcFZOLHcOLoqVTfoRhnmAksHDC2f8euNKhCyriK8xlJb/xPfAfCn4r58ZGsQPUS7cJL6FLYh7FjrqfYDS10VOrQvGOALrG5NUj1DdqRq0M+klgs+6oJdUZTtY62BKkWh3N+7moNvrqykpv+ydFUJltgezDcb4Br8Nkw/breSPnomRfyHIcAcfATZcOPJlI8pO0zFZDIz8r7ESMnBhAxNaZgsUhR2XbaqbAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAGw5XLY6GeFJMP350+djhcVqAw+E4HZqCJu1BMpYC0qS2D85fFi3gNuV0TnqB52abX1WBDDJK1CA0SPdyo/nX+qQzP6Dba1AVRKpRzdcsDsMDN3eMC08tajHgIIf5tNDv+HGE/MT2br4o5oducmQMOfV1NTJO1xhXYVqbsUnyrq3S6kD9WS8zRl6ruY1rT26eCQ4hTLHPaAiVsoXh5TBRXYCvGlAw7o2d9cmsbySforZ2wgdZwmu43B5eHNnt4NlDxZRyz6iEDP0nT877aB2ffsOKHAkJNuTvF5JSfnVzLmiyfa/7NI1ujfzcpA2UUXoWa7WN0wACiZQot8Zmswonjc="
],
"attestationTypes" : [ 15879, 15880 ],
"upv" : [ {
"major" : 1,
"minor" : 1
} ],
"userVerificationDetails" : [ [ {
"userVerification" : 4
} ] ],
"attachmentHint" : 1,
"authenticationAlgorithms" : [ 2, 9 ],
"authenticatorVersion" : 1,
"isSecondFactorOnly" : false,
"keyProtection" : 1,
"matcherProtection" : 1,
"publicKeyAlgAndEncodings" : [ 257, 259 ],
"tcDisplay" : 1,
"tcDisplayContentType" : "text/plain"
},
{
"aaid" : "F1D0#1001",
"description" : "iOS NEVIS Mobile Authentication PIN Authenticator",
"assertionScheme" : "UAFV1TLV",
"attestationRootCertificates" : [],
"attestationTypes" : [ 15880 ],
"upv" : [ {
"major" : 1,
"minor" : 1
} ],
"userVerificationDetails" : [ [ {
"userVerification" : 4
} ] ],
"attachmentHint" : 1,
"authenticationAlgorithms" : [ 2 ],
"authenticatorVersion" : 1,
"isSecondFactorOnly" : false,
"keyProtection" : 1,
"matcherProtection" : 1,
"publicKeyAlgAndEncodings" : [ 257 ],
"tcDisplay" : 1,
"tcDisplayContentType" : "text/plain"
},
{
"aaid" : "F1D0#1002",
"description" : "iOS NEVIS Mobile Authentication Fingerprint Authenticator",
"assertionScheme" : "UAFV1TLV",
"attestationRootCertificates" : [],
"attestationTypes" : [ 15880 ],
"upv" : [ {
"major" : 1,
"minor" : 1
} ],
"userVerificationDetails" : [ [ {
"userVerification" : 2
} ] ],
"attachmentHint" : 1,
"authenticationAlgorithms" : [ 2 ],
"authenticatorVersion" : 1,
"isSecondFactorOnly" : false,
"keyProtection" : 6,
"matcherProtection" : 2,
"publicKeyAlgAndEncodings" : [ 257 ],
"tcDisplay" : 1,
"tcDisplayContentType" : "text/plain"
},
{
"aaid" : "F1D0#1003",
"description" : "iOS NEVIS Mobile Authentication Face Recognition Authenticator",
"assertionScheme" : "UAFV1TLV",
"attestationRootCertificates" : [],
"attestationTypes" : [ 15880 ],
"upv" : [ {
"major" : 1,
"minor" : 1
} ],
"userVerificationDetails" : [ [ {
"userVerification" : 16
} ] ],
"attachmentHint" : 1,
"authenticationAlgorithms" : [ 2 ],
"authenticatorVersion" : 1,
"isSecondFactorOnly" : false,
"keyProtection" : 6,
"matcherProtection" : 2,
"publicKeyAlgAndEncodings" : [ 257 ],
"tcDisplay" : 1,
"tcDisplayContentType" : "text/plain"
},
{
"aaid" : "F1D0#1004",
"description" : "iOS NEVIS Mobile Authentication Device Passcode Authenticator",
"assertionScheme" : "UAFV1TLV",
"attestationRootCertificates" : [],
"attestationTypes" : [ 15880 ],
"upv" : [ {
"major" : 1,
"minor" : 1
} ],
"userVerificationDetails" : [ [ {
"userVerification" : 4
} ] ],
"attachmentHint" : 1,
"authenticationAlgorithms" : [ 2 ],
"authenticatorVersion" : 1,
"isSecondFactorOnly" : false,
"keyProtection" : 6,
"matcherProtection" : 2,
"publicKeyAlgAndEncodings" : [ 257 ],
"tcDisplay" : 1,
"tcDisplayContentType" : "text/plain"
},
{
"aaid" : "F1D0#1005",
"description" : "iOS NEVIS Mobile Authentication Password Authenticator",
"assertionScheme" : "UAFV1TLV",
"attestationRootCertificates" : [],
"attestationTypes" : [ 15880 ],
"upv" : [ {
"major" : 1,
"minor" : 1
} ],
"userVerificationDetails" : [ [ {
"userVerification" : 4
} ] ],
"attachmentHint" : 1,
"authenticationAlgorithms" : [ 2 ],
"authenticatorVersion" : 1,
"isSecondFactorOnly" : false,
"keyProtection" : 1,
"matcherProtection" : 1,
"publicKeyAlgAndEncodings" : [ 257 ],
"tcDisplay" : 1,
"tcDisplayContentType" : "text/plain"
}]

View File

@ -0,0 +1,102 @@
server:
port: 9443
host: "0.0.0.0"
protocol: "https"
tls:
keystore: "/var/opt/keys/own/ob-fido-uaf-v1-default-server-identity/keystore.p12"
keystore-type: "pkcs12"
keystore-passphrase: "${exec:/var/opt/keys/own/ob-fido-uaf-v1-default-server-identity/keypass}"
truststore: "/var/opt/keys/trust/ob-fido-uaf-v1-default-client-trust/truststore.p12"
truststore-type: "pkcs12"
truststore-passphrase: "${exec:/var/opt/keys/trust/ob-fido-uaf-v1-default-client-trust/keypass}"
management:
server:
port: 9089
healthchecks:
enabled: true
fido-uaf:
enabled: true
app-id: "https://auth.agov-w.azure.adnovum.net/nevisfido/uaf/1.1/facets"
facets:
- "android:apk-key-hash:*"
- "ios:bundle-id:*"
policy:
path: "conf/policy/"
timeout:
registration: "300s"
authentication: "300s"
token-registration: "300s"
token-deregistration: "300s"
token-authentication: "300s"
device-request: "300s"
transaction-confirmation:
max-text-length: 2000
metadata:
path: "conf/metadata/metadata.json"
idm-connection-type: "soap"
dispatchers:
- type: "link"
registration-redeem-url: "https://auth.agov-w.azure.adnovum.net/nevisfido/token/redeem/registration"
authentication-redeem-url: "https://auth.agov-w.azure.adnovum.net/nevisfido/token/redeem/authentication"
deregistration-redeem-url: "https://auth.agov-w.azure.adnovum.net/nevisfido/token/redeem/deregistration"
base-url: "ch.agov.access-t://x-callback-url/authenticate"
basic-full-attestation:
android-verification-level: "default"
authorization:
registration:
type: "sectoken"
truststore: "/var/opt/keys/trust/ob-auth-signer-trust-store/truststore.p12"
truststore-type: "pkcs12"
truststore-passphrase: "${exec:/var/opt/keys/trust/ob-auth-signer-trust-store/keypass}"
username-attribute-names:
- "loginId"
- "userid"
authentication:
type: "none"
deregistration:
type: "sectoken"
truststore: "/var/opt/keys/trust/ob-auth-signer-trust-store/truststore.p12"
truststore-type: "pkcs12"
truststore-passphrase: "${exec:/var/opt/keys/trust/ob-auth-signer-trust-store/keypass}"
username-attribute-names:
- "loginId"
- "userid"
create-dispatch-target:
type: "sectoken"
truststore: "/var/opt/keys/trust/ob-auth-signer-trust-store/truststore.p12"
truststore-type: "pkcs12"
truststore-passphrase: "${exec:/var/opt/keys/trust/ob-auth-signer-trust-store/keypass}"
username-attribute-names:
- "loginId"
- "userid"
query-dispatch-target:
type: "none"
delete-dispatch-target:
type: "sectoken"
truststore: "/var/opt/keys/trust/ob-auth-signer-trust-store/truststore.p12"
truststore-type: "pkcs12"
truststore-passphrase: "${exec:/var/opt/keys/trust/ob-auth-signer-trust-store/keypass}"
username-attribute-names:
- "userid"
session-repository:
type: "sql"
jdbc-url: "jdbc:mariadb://mariadb-session-store-service.adn-agov-nevisidm-ob-01-uat:3306/nevisfido_uaf?sslMode=disable&autocommit=true"
max-connection-lifetime: "10m"
user: "${exec:/var/opt/nevisfido/default/conf/credentials/dbUser}"
password: "${exec:/var/opt/nevisfido/default/conf/credentials/dbPassword}"
schema-user: ""
schema-user-password: ""
automatic-db-schema-setup: false
credential-repository:
type: "nevisidm"
client-id: 100
user-attribute: "extId"
administration-url: "https://idm.adn-agov-nevisidm-01-uat:8989/nevisidm/services/v1_46/AdminService"
admin-service-version: "v1_46"
rest-url: "https://idm.adn-agov-nevisidm-01-uat:8989/nevisidm"
keystore: "/var/opt/keys/own/nevisfido-techuser-key/keystore.p12"
keystore-type: "pkcs12"
keystore-passphrase: "${exec:/var/opt/keys/own/nevisfido-techuser-key/keypass}"
truststore: "/var/opt/keys/trust/ob-fido-uaf-v1-agov-work-internal-trust-store/truststore.p12"
truststore-type: "pkcs12"
truststore-passphrase: "${exec:/var/opt/keys/trust/ob-fido-uaf-v1-agov-work-internal-trust-store/keypass}"

View File

@ -0,0 +1,4 @@
otel.service.name = ob-fido-uaf
otel.traces.exporter = none
otel.metrics.exporter = none
otel.logs.exporter = none

View File

@ -0,0 +1,24 @@
{
"accepted": [
[
{
"aaid": ["F1D0#0002"]
}
],
[
{
"aaid": ["F1D0#0003"]
}
],
[
{
"aaid": ["F1D0#1002"]
}
],
[
{
"aaid": ["F1D0#1003"]
}
]
]
}

View File

@ -0,0 +1,44 @@
{
"accepted": [
[
{
"aaid": ["F1D0#0001"]
}
],
[
{
"aaid": ["F1D0#0002"]
}
],
[
{
"aaid": ["F1D0#0003"]
}
],
[
{
"aaid": ["F1D0#0004"]
}
],
[
{
"aaid": ["F1D0#1001"]
}
],
[
{
"aaid": ["F1D0#1002"]
}
],
[
{
"aaid": ["F1D0#1003"]
}
],
[
{
"aaid": ["F1D0#1004"]
}
]
]
}

View File

@ -0,0 +1,14 @@
{
"accepted": [
[
{
"aaid": ["F1D0#0001"]
}
],
[
{
"aaid": ["F1D0#1001"]
}
]
]
}

View File

@ -0,0 +1,47 @@
import sys
import time
import urllib.request, urllib.error, urllib.parse
health_endpoint = 'http://localhost:9089/nevisfido/health'
log_file_path = '/var/opt/nevisfido/default/log/nevisfido.log'
# Calls nevisFIDO's health check endpoint repeatedly to determine whether it is up and running
# Returns True if the service is available or False otherwise
def is_nevisfido_healthy():
for timeout in [0.1, 2, 4, 8, 16, 30]:
try:
time.sleep(timeout)
response = urllib.request.urlopen(health_endpoint)
if response.getcode() == 200:
return True
except urllib.error.URLError:
continue
return False
# Parses the nevisFIDO logs for the last error registered and raises and exception about it.
def raise_last_error_in_log():
event_buffer = []
for line in reversed(open(log_file_path).readlines()):
stripped_line = line.rstrip()
event_buffer.append(stripped_line)
if '[main] ERROR' in stripped_line:
raise Exception('\n'.join(reversed(event_buffer)))
break
# Log events (by default) starts with logging the time in the following format: '2019-11-04 12:44:45,071 21512 [main]'
# but these events can be multi-lined.
# We check here whether the current line is a start of a new event - in which case we flush the buffer.
if is_year(stripped_line[:4]):
event_buffer = []
# This method returns True if the provided string can be parsed to a year (4 digit int), or False otherwise.
def is_year(str):
try:
return int(str) > 999 and int(str) < 10000
except ValueError:
return False
if is_nevisfido_healthy():
sys.exit(0)
else:
raise_last_error_in_log()
sys.exit(1)

View File

@ -0,0 +1,60 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisComponent"
metadata:
name: "ob-fido2-v1"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-fido2-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "a2d03bb46b87b90160dc83d7"
spec:
type: "NevisFIDO"
replicas: 1
version: "8.2411.1"
gitInitVersion: "1.3.0"
runAsNonRoot: true
ports:
management: 9089
https: 9443
resources:
limits:
cpu: "1000m"
memory: "1000Mi"
requests:
cpu: "100m"
memory: "700Mi"
livenessProbe:
management:
httpGet:
path: "/nevisfido/liveness"
periodSeconds: 5
timeoutSeconds: 6
readinessProbe:
management:
httpGet:
path: "/nevisfido/health"
periodSeconds: 5
timeoutSeconds: 6
startupProbe:
management:
httpGet:
path: "/nevisfido/health"
periodSeconds: 5
timeoutSeconds: 6
failureThreshold: 50
podDisruptionBudget:
maxUnavailable: "50%"
git:
tag: "r-ba59b3f1caf0da0e0f0589650bcae5845f2d05b1"
dir: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT/DEFAULT-DEFAULT-ADN-AGOV-OB-INV/ob-fido2-v1"
credentials: "git-credentials"
keystores:
- "ob-fido2-v1-default-identity"
truststores:
- "ob-fido2-v1-default-tls-client-trust"
- "ob-fido2-v1-agov-work-internal-trust-store"
podSecurity:
policy: "baseline"
automountServiceAccountToken: false
timeZone: "Europe/Zurich"

View File

@ -0,0 +1,14 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisTrustStore"
metadata:
name: "ob-fido2-v1-agov-work-internal-trust-store"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-fido2-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "a2d03bb46b87b90160dc83d7"
spec:
keystores: []
extraCerts:
- "-----BEGIN CERTIFICATE-----\nMIIBcTCCARagAwIBAgIQWRl1eifIt8yohQYzh6yr/jAKBggqhkjOPQQDAjAYMRYw\nFAYDVQQDEw1zZWxmc2lnbmVkLWNhMB4XDTIzMDYyODE0MzI0MFoXDTQzMDYyODE0\nMzI0MFowGDEWMBQGA1UEAxMNc2VsZnNpZ25lZC1jYTBZMBMGByqGSM49AgEGCCqG\nSM49AwEHA0IABEwcjsIhSyyh0i9zP1G7ReOkFt/djzlGoUtSd5v3ZEk5QoZYjfl9\n04HdaZzrmveB2aRppbXgW7//s2Ma8wTd5uejQjBAMA4GA1UdDwEB/wQEAwICpDAP\nBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBT7YRoWIjHwkvFicwvk0Tx/yA4uUTAK\nBggqhkjOPQQDAgNJADBGAiEAgyg9t0qgb+czuscs07pNGI+12BedrD+y71psIlqx\nt2UCIQC/85UXyjYI9zg7Mg7rROTbGNCU3Jq/KIC3VzbbD+68VA==\n-----END CERTIFICATE-----\n"

View File

@ -0,0 +1,18 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisKeyStore"
metadata:
name: "ob-fido2-v1-default-identity"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-fido2-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "a2d03bb46b87b90160dc83d7"
spec:
cn: "ob-fido2-v1"
usage: "<reserved for future use>"
san:
dns:
- "ob-fido2-v1"
- "ob-fido2-v1.adn-agov-nevisidm-ob-01-uat"
email: []

View File

@ -0,0 +1,12 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisTrustStore"
metadata:
name: "ob-fido2-v1-default-tls-client-trust"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-fido2-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "a2d03bb46b87b90160dc83d7"
spec:
keystores: []

View File

@ -0,0 +1,18 @@
schemaVersion: 1.0
instance:
type: "nevisfido"
name: "default"
directory: "/var/opt/nevisfido/default"
pid: "systemctl show nevisfido@default -p MainPID | cut -d '=' -f2"
source:
url: "/nevisadmin/#/projects/DEFAULT-ADN-AGOV-WORK-OB-PROJECT/patterns/a2d03bb46b87b90160dc83d7"
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "a2d03bb46b87b90160dc83d7"
patternClass: "ch.nevis.admin.v4.plugin.fido2.patterns.NevisFIDODeployable"
resources:
ports:
- "0.0.0.0:9443"
control:
start: "systemctl restart nevisfido@default"
stop: "systemctl stop nevisfido@default"
status: "systemctl status nevisfido@default"

View File

@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC6TCCAo+gAwIBAgIQfcfd9dgdKT/5gdDbpAiKlDAKBggqhkjOPQQDAjAYMRYw
FAYDVQQDEw1zZWxmc2lnbmVkLWNhMB4XDTI0MDUwNTE1NTAzOFoXDTI1MDUwNTE1
NTAzOFowWDELMAkGA1UEBhMCQ0gxDDAKBgNVBAgTA0s4UzEMMAoGA1UEBxMDSzhT
MQwwCgYDVQQKEwNLOFMxDDAKBgNVBAsTA0s4UzERMA8GA1UEAxMIZmlkby11YWYw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDWcQPIzUN2zbPkB3yISIGw
mDAd285YKm/ZLbE4WWw2SIHhjfh0XoYZ6QvLMENWcC8/iOX/6g6upQnYegzZKlST
Lix0zJjEbtMlK8fITiPhwziWPSOeqtuW66Rj+13G6kKYVtZ8vviu73LBDkXKHSNi
g4knNgACJpIItiDhOmtmD3Wsb8JAIQ161m7D3i2jr/kqBFKLc2DXcCHYSwxBXu3A
99iqWxoHfprL/L7RfxBo7mKbk+xjRvw6wFHBb76m6hd8fe4yg3g9zZTsZ5KeKqtA
8NT7CTG26F/MEBEmreU6NcNP62sYBkQiY+K5WweUs5qnDCAUPz+Upu0lX49ZDsvZ
AgMBAAGjga8wgawwDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMB
BggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFPthGhYiMfCS8WJz
C+TRPH/IDi5RMEwGA1UdEQRFMEOCCGZpZG8tdWFmgiFmaWRvLXVhZi5hZG4tYWdv
di1uZXZpc2lkbS0wMS11YXSBFG5vcmVwbHlAbG9jYWwuZG9tYWluMAoGCCqGSM49
BAMCA0gAMEUCIBCueTTUwnN53/dIs6W4FpbFtF/wkAhYjLZGuKgY08ZAAiEA9VFz
WoaxaINHqGPR10Sh1hqeuCHRzHxnQUt07sZf2DU=
-----END CERTIFICATE-----

View File

@ -0,0 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFKzBVBgkqhkiG9w0BBQ0wSDAnBgkqhkiG9w0BBQwwGgQUWtp2pbSNdJCf9jA9
KTzjbdorVLQCAggAMB0GCWCGSAFlAwQBKgQQb0NJGFGc8MxZaCZ71uYlEASCBND5
XhsSZKjT6CN02euPCcN5ssgXTfOlHG5hl4KcpNl/K61CH+gNH3rTzzao8utmd5ko
cWbl6o6nj2IdiU8IlaqI+VIR2nfHaqoGhJHfLbvPu/SItKTFjFTRRKddyKTIjN0o
eVbHMzt8pHvNKnNK2JmKQ+TqphGTaDIgEEqPRSniE6WHLGuCfG/VdaeRxTZldj9D
QDR41gC2kgDbsenkZZjhGEJpgM4g3mD7bc0IHMRG1wfSW8qyd+S+XxjYdgMJmffc
PCMPv3TJ0Xbxfw+BKED9WeSIaXfCFmVprNXhWhMMN8Z7o3WxigVo2oRkHWbhSff4
hFy4AQgyq8TOE1C2xeAcADEFagCHDdf0cs5LgwytpH5/0oTsm0+pFol6yEa7X1rF
Eu7NT8zLxXxqUdlCJ1A2AWbi17ER6snst4RfT7cCiI3d6q6IO2dsfuHSs17AHY2m
1KSfgVwH05o3W58ADUVuoZxtqCS0xMv2mvlTJ7xSb90R4hz5w1JBKjrYqq1Xy1Lr
pDc9kBEwJKtN9V63veUnHR5tFku9mVTEK6iykYWRNORexNEas5wsiuxrgaXtGN5G
ouhq9MCe5DI0coQOHM0Bvw1zfQ+wj8RUgrt0290WF0VtHW+zH0qbVHYZ6dKRY5YX
azzLvyu5AlH9p2MZr/+oZn6lgjmVEYq0UbsUvFoZy65qwi2XqL7FvXIVSVTgr7YY
hiODL4FBWJEevE+MujfOpOftzivdx1+/cuiQHcbqKlPQLnQXaUKI337u2o8uAEch
lP3AvI4DVi4m6IC9lo6657r8MqwMGmdEK9PRDPHUf7SP3HGX8fYArwRWILtHrcmc
/kHhKUkMxHduFb0nYQTVFnlpLEidcv6gYIVsh8Fx5pQWW+HyBD4sJuG7mLMgtmtY
vk9zayWbq0lw0Bb+E83vk9xtE0tUoFF/Wcl2nBf5PjfCqesGqr9CHElcQGfcINCg
3llXoeceN868e5DKgtQE6Fp5KukclgeeeX4kPj+UK7x4UGtdGcdghwH6EO7McQX1
67kyLDcF4p5HnrzEhP2CVcVDHXoeykMCitvHaInwmJQsR209PVa/XxXB8YoMAAV1
DB3GT024dAxFEl5r1HJm3A7BiFFuvQdUi+recFGKfmSNZ1Pwp2+8DV7UiAYLJ5Wf
o/aAwUQByITI3fBPvmEAA86FeWwtQ5BG5e+q7imH1ooOzrHQzaqwzQKU+IQCzaDF
sAqMtSD/hzIRjMKOSAL8bA2SVIXlLUnulWjPwW9zhUTv9yS1q2EsiFUJnOyq7iAI
fX72qEBvBXLFBdGhotMAXeg1YsXLUxbldqAWuPxpZMQ5S6J7GZZloXSe1Gy/ZZh4
tKD8qQTS5Rfwiqxxo3kgaB/z0qG99pTB/wWv4fwnv6lFjJRjgyGONRYIGCVCFH2X
mdV2rTUxtwB1cIr71ksA64O3YkUObyfT8gSbLjPoBDBBPQQ3crbaQdiOjGUE9zUF
8kp3/mVj/kBCNtlc4dR/lJGuM97h2OpR5sLvb/5TN9C3tcXUyRmDjqJY/eX9ui0D
pEe6juN9Wy1yZtHauTIK0dqol+DJr56mMdMzBBmDagdr17Q2XK+GKrp5Z9rPbXJv
8qjMHKVFlbQRMtOY8N/PQenRyl1XmZIPk9HWj+9+6w==
-----END ENCRYPTED PRIVATE KEY-----

View File

@ -0,0 +1,2 @@
#!/bin/bash
echo 'Hsk+IJIkp1oGu8i1S+w6p2QMDB+9WFSNjNlSYdUCfA8='

View File

@ -0,0 +1,49 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFKzBVBgkqhkiG9w0BBQ0wSDAnBgkqhkiG9w0BBQwwGgQUWtp2pbSNdJCf9jA9
KTzjbdorVLQCAggAMB0GCWCGSAFlAwQBKgQQb0NJGFGc8MxZaCZ71uYlEASCBND5
XhsSZKjT6CN02euPCcN5ssgXTfOlHG5hl4KcpNl/K61CH+gNH3rTzzao8utmd5ko
cWbl6o6nj2IdiU8IlaqI+VIR2nfHaqoGhJHfLbvPu/SItKTFjFTRRKddyKTIjN0o
eVbHMzt8pHvNKnNK2JmKQ+TqphGTaDIgEEqPRSniE6WHLGuCfG/VdaeRxTZldj9D
QDR41gC2kgDbsenkZZjhGEJpgM4g3mD7bc0IHMRG1wfSW8qyd+S+XxjYdgMJmffc
PCMPv3TJ0Xbxfw+BKED9WeSIaXfCFmVprNXhWhMMN8Z7o3WxigVo2oRkHWbhSff4
hFy4AQgyq8TOE1C2xeAcADEFagCHDdf0cs5LgwytpH5/0oTsm0+pFol6yEa7X1rF
Eu7NT8zLxXxqUdlCJ1A2AWbi17ER6snst4RfT7cCiI3d6q6IO2dsfuHSs17AHY2m
1KSfgVwH05o3W58ADUVuoZxtqCS0xMv2mvlTJ7xSb90R4hz5w1JBKjrYqq1Xy1Lr
pDc9kBEwJKtN9V63veUnHR5tFku9mVTEK6iykYWRNORexNEas5wsiuxrgaXtGN5G
ouhq9MCe5DI0coQOHM0Bvw1zfQ+wj8RUgrt0290WF0VtHW+zH0qbVHYZ6dKRY5YX
azzLvyu5AlH9p2MZr/+oZn6lgjmVEYq0UbsUvFoZy65qwi2XqL7FvXIVSVTgr7YY
hiODL4FBWJEevE+MujfOpOftzivdx1+/cuiQHcbqKlPQLnQXaUKI337u2o8uAEch
lP3AvI4DVi4m6IC9lo6657r8MqwMGmdEK9PRDPHUf7SP3HGX8fYArwRWILtHrcmc
/kHhKUkMxHduFb0nYQTVFnlpLEidcv6gYIVsh8Fx5pQWW+HyBD4sJuG7mLMgtmtY
vk9zayWbq0lw0Bb+E83vk9xtE0tUoFF/Wcl2nBf5PjfCqesGqr9CHElcQGfcINCg
3llXoeceN868e5DKgtQE6Fp5KukclgeeeX4kPj+UK7x4UGtdGcdghwH6EO7McQX1
67kyLDcF4p5HnrzEhP2CVcVDHXoeykMCitvHaInwmJQsR209PVa/XxXB8YoMAAV1
DB3GT024dAxFEl5r1HJm3A7BiFFuvQdUi+recFGKfmSNZ1Pwp2+8DV7UiAYLJ5Wf
o/aAwUQByITI3fBPvmEAA86FeWwtQ5BG5e+q7imH1ooOzrHQzaqwzQKU+IQCzaDF
sAqMtSD/hzIRjMKOSAL8bA2SVIXlLUnulWjPwW9zhUTv9yS1q2EsiFUJnOyq7iAI
fX72qEBvBXLFBdGhotMAXeg1YsXLUxbldqAWuPxpZMQ5S6J7GZZloXSe1Gy/ZZh4
tKD8qQTS5Rfwiqxxo3kgaB/z0qG99pTB/wWv4fwnv6lFjJRjgyGONRYIGCVCFH2X
mdV2rTUxtwB1cIr71ksA64O3YkUObyfT8gSbLjPoBDBBPQQ3crbaQdiOjGUE9zUF
8kp3/mVj/kBCNtlc4dR/lJGuM97h2OpR5sLvb/5TN9C3tcXUyRmDjqJY/eX9ui0D
pEe6juN9Wy1yZtHauTIK0dqol+DJr56mMdMzBBmDagdr17Q2XK+GKrp5Z9rPbXJv
8qjMHKVFlbQRMtOY8N/PQenRyl1XmZIPk9HWj+9+6w==
-----END ENCRYPTED PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIC6TCCAo+gAwIBAgIQfcfd9dgdKT/5gdDbpAiKlDAKBggqhkjOPQQDAjAYMRYw
FAYDVQQDEw1zZWxmc2lnbmVkLWNhMB4XDTI0MDUwNTE1NTAzOFoXDTI1MDUwNTE1
NTAzOFowWDELMAkGA1UEBhMCQ0gxDDAKBgNVBAgTA0s4UzEMMAoGA1UEBxMDSzhT
MQwwCgYDVQQKEwNLOFMxDDAKBgNVBAsTA0s4UzERMA8GA1UEAxMIZmlkby11YWYw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDWcQPIzUN2zbPkB3yISIGw
mDAd285YKm/ZLbE4WWw2SIHhjfh0XoYZ6QvLMENWcC8/iOX/6g6upQnYegzZKlST
Lix0zJjEbtMlK8fITiPhwziWPSOeqtuW66Rj+13G6kKYVtZ8vviu73LBDkXKHSNi
g4knNgACJpIItiDhOmtmD3Wsb8JAIQ161m7D3i2jr/kqBFKLc2DXcCHYSwxBXu3A
99iqWxoHfprL/L7RfxBo7mKbk+xjRvw6wFHBb76m6hd8fe4yg3g9zZTsZ5KeKqtA
8NT7CTG26F/MEBEmreU6NcNP62sYBkQiY+K5WweUs5qnDCAUPz+Upu0lX49ZDsvZ
AgMBAAGjga8wgawwDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMB
BggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFPthGhYiMfCS8WJz
C+TRPH/IDi5RMEwGA1UdEQRFMEOCCGZpZG8tdWFmgiFmaWRvLXVhZi5hZG4tYWdv
di1uZXZpc2lkbS0wMS11YXSBFG5vcmVwbHlAbG9jYWwuZG9tYWluMAoGCCqGSM49
BAMCA0gAMEUCIBCueTTUwnN53/dIs6W4FpbFtF/wkAhYjLZGuKgY08ZAAiEA9VFz
WoaxaINHqGPR10Sh1hqeuCHRzHxnQUt07sZf2DU=
-----END CERTIFICATE-----

View File

@ -0,0 +1,10 @@
RUN_ARGS="--config conf/nevisfido.yml --log-config conf/logging.yml"
JAVA_OPTS=(
"-XX:+UseContainerSupport"
"-XX:MaxRAMPercentage=80.0"
"-javaagent:/opt/agent/opentelemetry-javaagent.jar"
"-Dotel.javaagent.logging=application"
"-Dotel.javaagent.configuration-file=/var/opt/nevisfido/default/conf/otel.properties"
"-Dotel.resource.attributes=service.version=8.2411.1,service.instance.id=$HOSTNAME"
)

View File

@ -0,0 +1,23 @@
Configuration:
monitorInterval: 60
Appenders:
Console:
- name: "SERVER"
target: "SYSTEM_OUT"
PatternLayout:
pattern: "[nevisfido.log] %d{ISO8601} %-15.15t %mdc{trace_id} %mdc{span_id} %-40.40c %-5.5p %m%n"
RegexFilter:
regex: ".*GET /nevisfido/liveness.*"
onMatch: "DENY"
onMismatch: "ACCEPT"
Loggers:
Logger:
- name: "ProductAnalytics"
level: "INFO"
- name: "ch.nevis.auth.fido.application.Application"
level: "INFO"
Root:
level: "WARN"
additivity: "false"
AppenderRef:
- ref: "SERVER"

View File

@ -0,0 +1,51 @@
server:
port: 9443
protocol: "https"
tls:
keystore: "/var/opt/keys/own/ob-fido2-v1-default-identity/keystore.p12"
keystore-passphrase: "${exec:/var/opt/keys/own/ob-fido2-v1-default-identity/keypass}"
keystore-type: "pkcs12"
truststore: "/var/opt/keys/trust/ob-fido2-v1-default-tls-client-trust/truststore.p12"
truststore-passphrase: "${exec:/var/opt/keys/trust/ob-fido2-v1-default-tls-client-trust/keypass}"
truststore-type: "pkcs12"
management:
server:
port: 9089
healthchecks:
enabled: true
credential-repository:
type: "nevisidm"
client-id: "cfa9c9b9-119f-4dff-9bb8-86d7c0cf2720"
rest-url: "https://idm.adn-agov-nevisidm-01-uat:8989/nevisidm"
keystore: "/var/opt/keys/own/nevisfido-techuser-key/keystore.p12"
keystore-passphrase: "${exec:/var/opt/keys/own/nevisfido-techuser-key/keypass}"
keystore-type: "pkcs12"
truststore: "/var/opt/keys/trust/ob-fido2-v1-agov-work-internal-trust-store/truststore.p12"
truststore-passphrase: "${exec:/var/opt/keys/trust/ob-fido2-v1-agov-work-internal-trust-store/keypass}"
truststore-type: "pkcs12"
user-attribute: "extId"
fido2:
enabled: true
rp-name: "AGOV-RelPartName"
rp-id: "adnovum.net"
origins:
- "https://me.agov-w.azure.adnovum.net"
- "https://nevisidm.agov-w.azure.adnovum.net"
- "https://auth.agov-w.azure.adnovum.net"
- "https://ob.agov-w.azure.adnovum.net"
signature-algorithms:
- "RS1"
- "RS256"
- "RS384"
- "RS512"
- "ES256"
- "ES384"
- "ES512"
display-name-source: "loginId"
metadata:
allow-listing-enabled: false
timeout:
user-verification: "300s"
no-user-verification: "120s"
session-repository:
type: "in-memory"

View File

@ -0,0 +1,4 @@
otel.service.name = ob-fido2
otel.traces.exporter = none
otel.metrics.exporter = none
otel.logs.exporter = none

View File

@ -0,0 +1,47 @@
import sys
import time
import urllib.request, urllib.error, urllib.parse
health_endpoint = 'http://localhost:9089/nevisfido/health'
log_file_path = '/var/opt/nevisfido/default/log/nevisfido.log'
# Calls nevisFIDO's health check endpoint repeatedly to determine whether it is up and running
# Returns True if the service is available or False otherwise
def is_nevisfido_healthy():
for timeout in [0.1, 2, 4, 8, 16, 30]:
try:
time.sleep(timeout)
response = urllib.request.urlopen(health_endpoint)
if response.getcode() == 200:
return True
except urllib.error.URLError:
continue
return False
# Parses the nevisFIDO logs for the last error registered and raises and exception about it.
def raise_last_error_in_log():
event_buffer = []
for line in reversed(open(log_file_path).readlines()):
stripped_line = line.rstrip()
event_buffer.append(stripped_line)
if '[main] ERROR' in stripped_line:
raise Exception('\n'.join(reversed(event_buffer)))
break
# Log events (by default) starts with logging the time in the following format: '2019-11-04 12:44:45,071 21512 [main]'
# but these events can be multi-lined.
# We check here whether the current line is a start of a new event - in which case we flush the buffer.
if is_year(stripped_line[:4]):
event_buffer = []
# This method returns True if the provided string can be parsed to a year (4 digit int), or False otherwise.
def is_year(str):
try:
return int(str) > 999 and int(str) < 10000
except ValueError:
return False
if is_nevisfido_healthy():
sys.exit(0)
else:
raise_last_error_in_log()
sys.exit(1)

View File

@ -0,0 +1,53 @@
apiVersion: "operator.nevis-security.ch/v1"
kind: "NevisComponent"
metadata:
name: "ob-logrend-v1"
namespace: "adn-agov-nevisidm-ob-01-uat"
labels:
deploymentTarget: "ob-logrend-v1"
annotations:
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "bed300e1196a171ca12db431"
spec:
type: "NevisLogrend"
replicas: 1
version: "8.2411.1"
gitInitVersion: "1.3.0"
runAsNonRoot: true
ports:
server: 8988
management: 8997
resources:
limits:
cpu: "500m"
memory: "1000Mi"
requests:
cpu: "10m"
memory: "500Mi"
livenessProbe:
management:
httpGet:
path: "/nevislogrend/liveness"
periodSeconds: 5
timeoutSeconds: 6
readinessProbe:
server:
tcpSocket: true
periodSeconds: 5
timeoutSeconds: 4
startupProbe:
server:
tcpSocket: true
periodSeconds: 5
timeoutSeconds: 4
failureThreshold: 50
podDisruptionBudget:
maxUnavailable: "50%"
git:
tag: "r-ba59b3f1caf0da0e0f0589650bcae5845f2d05b1"
dir: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT/DEFAULT-DEFAULT-ADN-AGOV-OB-INV/ob-logrend-v1"
credentials: "git-credentials"
podSecurity:
policy: "baseline"
automountServiceAccountToken: false
timeZone: "Europe/Zurich"

View File

@ -0,0 +1,18 @@
schemaVersion: 1.0
instance:
type: "nevislogrend"
name: "default"
directory: "/var/opt/nevislogrend/default"
pid: "systemctl show nevislogrend@default -p MainPID | cut -d '=' -f2"
source:
url: "/nevisadmin/#/projects/DEFAULT-ADN-AGOV-WORK-OB-PROJECT/patterns/bed300e1196a171ca12db431"
projectKey: "DEFAULT-ADN-AGOV-WORK-OB-PROJECT"
patternId: "bed300e1196a171ca12db431"
patternClass: "ch.nevis.admin.v4.plugin.nevisauth.patterns.NevisLogrendDeployable"
resources:
ports:
- "0.0.0.0:8988"
control:
start: "systemctl restart nevislogrend@default"
stop: "systemctl stop nevislogrend@default"
status: "systemctl status nevislogrend@default"

View File

@ -0,0 +1,14 @@
RTENV_SECURITY_CHECK=no_shell
# only standalone deployment is supported with nevisAdmin 4
LOGREND_DEPLOY_TYPE=standalone
JAVA_OPTS=(
"-XX:+UseContainerSupport"
"-Dfile.encoding=UTF-8"
"-XX:MaxRAMPercentage=80.0"
"-javaagent:/opt/agent/opentelemetry-javaagent.jar"
"-Dotel.javaagent.logging=application"
"-Dotel.javaagent.configuration-file=/var/opt/nevislogrend/default/conf/otel.properties"
"-Dotel.resource.attributes=service.version=8.2411.1,service.instance.id=$HOSTNAME"
)

View File

@ -0,0 +1,21 @@
Configuration:
monitorInterval: 60
Appenders:
Console:
- name: "SERVER"
target: "SYSTEM_OUT"
PatternLayout:
pattern: "[nevislogrend.log] %d{ISO8601} %-15.15t %mdc{trace_id} %mdc{span_id} %-40.40c %-5.5p %m%n"
RegexFilter:
regex: ".*GET /nevislogrend/health.*"
onMatch: "DENY"
onMismatch: "ACCEPT"
Loggers:
Logger:
- name: "ProductAnalytics"
level: "INFO"
Root:
level: "WARN"
additivity: "false"
AppenderRef:
- ref: "SERVER"

View File

@ -0,0 +1,26 @@
application.accept.loginapplicationidfromuri=no
application.gui.litdict=yes
application.gui.substitution=yes
application.input.charset=UTF-8
application.inputs.htmlencode=yes
application.loginapp.current=
application.loginapp.default=ob-mock-me-realm
application.loginapp.override=header:channel
application.package.name=nevislogrend
application.render.content.type=text/html; charset=UTF-8
application.url.obfuscate=no
application.webdata.path={0}{2}{1}
application.webdata.pathparam=logrendresourcepath
application.webdata.pathparam.default=/login/resources
cache.revalidate.delay=15
cache.source=file
keytag.end=}
keytag.start=${
management.healthchecks.enabled=true
path.config=/var/opt/nevislogrend/default/conf
path.instance=/var/opt/nevislogrend/default
server.host=0.0.0.0
server.name=default
server.port=8988
server.protocol=http

View File

@ -0,0 +1,3 @@
ico=image/x-icon
woff=font/woff
woff2=font/woff2

View File

@ -0,0 +1,4 @@
otel.service.name = ob-logrend
otel.traces.exporter = none
otel.metrics.exporter = none
otel.logs.exporter = none

View File

@ -0,0 +1,26 @@
# source: pattern://14b02056879c3b8991597d2b
application.countries.default=CH
# source: pattern://14b02056879c3b8991597d2b
cache.file.exempt=
# source: pattern://14b02056879c3b8991597d2b
cache.filefolder.exempt=
# source: pattern://14b02056879c3b8991597d2b
application.language.source.1=param:language
# source: pattern://14b02056879c3b8991597d2b
application.language.source.2=cookie:LANG
# source: pattern://14b02056879c3b8991597d2b
application.language.source.3=gui
# source: pattern://14b02056879c3b8991597d2b
application.language.source.4=browser
# source: pattern://14b02056879c3b8991597d2b
application.languages=en,de,fr,it
# source: pattern://14b02056879c3b8991597d2b
application.languages.default=en
# source: pattern://bed300e1196a171ca12db431
application.language.cookie.en=LANG:en
# source: pattern://bed300e1196a171ca12db431
application.language.cookie.de=LANG:de
# source: pattern://bed300e1196a171ca12db431
application.language.cookie.fr=LANG:fr
# source: pattern://bed300e1196a171ca12db431
application.language.cookie.it=LANG:it

View File

@ -0,0 +1,27 @@
button.submit=Submit
error.policy.failed=The new password does not comply with the policy.
info.login=Please enter your authentication information.
info.signup.passwordless=Log in quickly and securely next time using this device's fingerprint, face recognition, or PIN.
info.signup.passwordless.failed=Use the same method you already use on this device for login.
info.signup.passwordless.skip=<button name="cancel-bottom" type="submit" value="true" class="btn btn-link link-primary">Skip for now</button>
language.de=Deutsch
language.en=English
language.fr=Fran&ccedil;ais
language.it=Italiano
prompt.client=Client
prompt.newpassword=New Password
prompt.newpassword.confirm=Confirm Password
prompt.password=Password
prompt.userid=User-ID
pwreset.done.info=Your password was successfully changed. Please click on continue to log in.
pwreset.email.sent=If your user ID exists, an email to reset your password has been sent to you.
pwreset.info.linktext=Password forgotten
pwreset.noticket=Your password reset link is no longer valid. Please generate a new one.
title=NEVIS SSO Portal
title.login=Login
title.pwchange.label=Password Change
title.pwreset=Password Forgotten
title.signup.passwordless=Go passwordless
title.signup.passwordless.failed=Failed to turn on passwordless
try_again.button.label=Try again

View File

@ -0,0 +1,27 @@
button.submit=Senden
error.policy.failed=Das neue Passwort stimmt nicht mit der Richtlinie &uuml;berein.
info.login=Bitte geben Sie Ihre pers&ouml;nlichen Zugangsdaten ein.
info.signup.passwordless=Melden Sie sich beim nächsten Mal schnell und sicher mit dem Fingerabdruck, der Gesichtserkennung oder der PIN dieses Geräts an.
info.signup.passwordless.failed=Verwenden Sie dieselbe Methode, die Sie bereits für die Anmeldung verwenden.
info.signup.passwordless.skip=<button name="cancel-bottom" type="submit" value="true" class="btn btn-link link-primary">Vorerst überspringen</button>
language.de=Deutsch
language.en=English
language.fr=Fran&ccedil;ais
language.it=Italiano
prompt.client=Mandant
prompt.newpassword=Neues Passwort
prompt.newpassword.confirm=Passwort best&auml;tigen
prompt.password=Passwort
prompt.userid=Benutzer-ID
pwreset.done.info=Ihr Passwort wurde erfolgreich ge&auml;ndert. Bitte klicken Sie auf Weiter, um sich einzuloggen.
pwreset.email.sent=Wenn Ihre Benutzer-ID existiert, haben Sie eine E-Mail erhalten, um Ihr Passwort zurückzusetzen..
pwreset.info.linktext=Passwort vergessen
pwreset.noticket=Ihr Link ist nicht mehr g&uuml;ltig. Bitte generieren Sie ein Neuen.
title=NEVIS SSO Portal
title.login=Login
title.pwchange.label=Passwort &auml;ndern
title.pwreset=Passwort Vergesssen
title.signup.passwordless=Login ohne Passwort
title.signup.passwordless.failed=Login ohne Passwort konnte nicht aktiviert werden
try_again.button.label=Erneut versuchen

View File

@ -0,0 +1,27 @@
button.submit=Submit
error.policy.failed=The new password does not comply with the policy.
info.login=Please enter your authentication information.
info.signup.passwordless=Log in quickly and securely next time using this device's fingerprint, face recognition, or PIN.
info.signup.passwordless.failed=Use the same method you already use on this device for login.
info.signup.passwordless.skip=<button name="cancel-bottom" type="submit" value="true" class="btn btn-link link-primary">Skip for now</button>
language.de=Deutsch
language.en=English
language.fr=Fran&ccedil;ais
language.it=Italiano
prompt.client=Client
prompt.newpassword=New Password
prompt.newpassword.confirm=Confirm Password
prompt.password=Password
prompt.userid=User-ID
pwreset.done.info=Your password was successfully changed. Please click on continue to log in.
pwreset.email.sent=If your user ID exists, an email to reset your password has been sent to you.
pwreset.info.linktext=Password forgotten
pwreset.noticket=Your password reset link is no longer valid. Please generate a new one.
title=NEVIS SSO Portal
title.login=Login
title.pwchange.label=Password Change
title.pwreset=Password Forgotten
title.signup.passwordless=Go passwordless
title.signup.passwordless.failed=Failed to turn on passwordless
try_again.button.label=Try again

View File

@ -0,0 +1,27 @@
button.submit=Envoyer
error.policy.failed=Votre nouveau mot de passe ne conforme pas aux mesures de s&eacute;curit&eacute;
info.login=Veuillez entrer vos &eacute;l&eacute;ments de s&eacute;curit&eacute; ci-apr&egrave;s.
info.signup.passwordless=Connectez-vous rapidement et en toute sécurité la prochaine fois en utilisant l'empreinte digitale, la reconnaissance faciale ou le code PIN de cet appareil.
info.signup.passwordless.failed=Utilisez la même méthode que vous utilisez déjà sur cet appareil pour vous connecter.
info.signup.passwordless.skip=<button name="cancel-bottom" type="submit" value="true" class="btn btn-link link-primary">Sauter pour le moment</button>
language.de=Deutsch
language.en=English
language.fr=Fran&ccedil;ais
language.it=Italiano
prompt.client=Client
prompt.newpassword=Nouveau mot de passe
prompt.newpassword.confirm=Confirmez le mot de passe
prompt.password=Mot de passe
prompt.userid=ID de l&#39;utilisateur
pwreset.done.info=Votre mot de passe a &eacute;t&eacute; chang&eacute avec succ&egrave;s. Veuillez cliquer sur continuer pour vous connecter.
pwreset.email.sent=Si votre identifiant n'existe pas, vous avez reçu un courriel pour réinitialiser votre mot de passe.
pwreset.info.linktext=Mot de passe oublié
pwreset.noticket=Votre lien n&apos;est plus valide. Veuillez en g&eacute;n&eacute;rer un nouveau.
title=NEVIS SSO Portal
title.login=Login
title.pwchange.label=Changer mot de passe
title.pwreset=Mot de Passe Oubli&eacute;
title.signup.passwordless=Aller sans mot de passe
title.signup.passwordless.failed=Impossible d'activer le sans mot de passe
try_again.button.label=Essayez à nouveau

View File

@ -0,0 +1,27 @@
button.submit=Continua
error.policy.failed=La nuova password non &egrave; stata accettata. Scegliere una password che sia conforme ai criteri di password.
info.login=Per favore inserisca i suoi dati di accesso.
info.signup.passwordless=Accedi in modo rapido e sicuro la prossima volta utilizzando l'impronta digitale, il riconoscimento facciale o il PIN di questo dispositivo.
info.signup.passwordless.failed=Utilizza lo stesso metodo che usi già su questo dispositivo per il login.
info.signup.passwordless.skip=<button name="cancel-bottom" type="submit" value="true" class="btn btn-link link-primary">Saltare per ora</button>
language.de=Deutsch
language.en=English
language.fr=Fran&ccedil;ais
language.it=Italiano
prompt.client=Mandator
prompt.newpassword=Nuova Password
prompt.newpassword.confirm=Conferma password
prompt.password=Password
prompt.userid=Nome utente
pwreset.done.info=La password &egrave; stata modificata con successo. Fare clic su continua per accedere.
pwreset.email.sent=Se il vostro ID utente esiste, vi è stata inviata un'e-mail per reimpostare la password.
pwreset.info.linktext=Password dimenticata
pwreset.noticket=Il biglietto per la reimpostazione della password non &egrave; pi&ugrave; valido. Si prega di generarne uno nuovo.
title=NEVIS SSO Portal
title.login=Login
title.pwchange.label=Cambiare Password
title.pwreset=Password Dimenticata
title.signup.passwordless=Vai senza password
title.signup.passwordless.failed=Impossibile attivare senza password
try_again.button.label=Riprova

View File

@ -0,0 +1,165 @@
let baseURL; // base URL
let statusToken; // used to check progress
let dispatcherElement; // to display link or QR code
let infoElement; // to display info text
let errorElement; // to display error text
function addInput(form, name, value) {
const input = document.createElement("input");
input.name = name;
input.value = value;
form.appendChild(input);
}
function submitStatus(status) {
// we have to do a form POST instead of AJAX
const form = document.createElement("form");
form.method = "POST";
form.style.display = "none";
addInput(form, "status", status);
document.body.appendChild(form);
form.submit();
}
const Status = {
_pollInterval: 2 * 1000, // Check every 2 seconds
latest: null,
startPolling: function (token, uiCallback) {
let interval = setInterval(async () => {
await this._check(token).then(function (resp) {
console.log("Polling status: %o", resp);
uiCallback && uiCallback(resp, false);
return Status.latest = resp;
})
.catch(function (err) {
console.error("Error during polling: %o", err);
return false;
});
if (Status.latest && (Status.latest.status === 'succeeded' || Status.latest.status === 'failed' || Status.latest.status === 'unknown')) {
// Done!
console.log('Latest status is: %o', this.latest);
uiCallback && uiCallback(this.latest, true);
clearInterval(interval);
}
}, this._pollInterval);
},
_check: async function (token) {
const payload = { statusToken: token };
const response = await fetch(baseURL + 'api/v1/status', {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
credentials: 'omit',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(payload),
redirect: 'follow',
referrerPolicy: 'no-referrer'
});
return await response.json();
}
};
function setDeepLinkLabel(button) {
const text = document.getElementsByName('info.deeplink')[0].value;
button.innerHTML = text;
}
function messageScanQR() {
const text = document.getElementsByName('info.qrcode')[0].value;
infoElement.innerHTML = text;
}
function messageCheckPhone() {
const text = document.getElementsByName('info.check.phone')[0].value;
infoElement.innerHTML = text;
}
const Element = {
_elem: null, // QR code or deep link depending on device
show: function (appLink) {
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
const isIphone = 'iPhone' === navigator.platform;
const isAndroid = /android/i.test(userAgent) && /mobile/i.test(userAgent);
if (isAndroid || isIphone) {
this._elem = document.createElement('a');
this._elem.setAttribute('href', appLink);
this._elem.setAttribute('class', 'btn btn-primary');
this._elem.setAttribute('target', '_blank');
dispatcherElement.appendChild(this._elem);
setDeepLinkLabel(this._elem);
}
else {
const authenticationType = document.getElementsByName('authenticationType')[0].value;
if (authenticationType == 'push') {
messageCheckPhone();
}
else {
messageScanQR();
this._elem = document.createElement('canvas');
dispatcherElement.appendChild(this._elem);
var qrcode = new QRious({
element: this._elem,
foreground: "#168CA9",
level: "M",
size: 280,
value: appLink
});
}
}
},
hide: function() {
// hide the element which was shown
if (this._elem != null) {
this._elem.style.display = "none";
}
}
};
function authenticateUser(appLink) {
Element.show(appLink);
console.log('Starting Authentication Cloud status polling...');
Status.startPolling(statusToken, (st, done) => {
if (st.status === 'succeeded') {
console.log('Authentication Cloud login done.');
submitStatus('succeeded')
}
else if (st.status === 'failed') {
// failed: The transaction failed, either by timeout or because the user did not accept.
console.warn('Authentication Cloud login failed. User abort or timeout.');
submitStatus('failed')
}
else if (st.status === 'unknown') {
console.error('Authentication Cloud login failed. Unknown status.');
submitStatus('unknown')
}
});
}
function init() {
const form = document.getElementById('authcloud_login');
baseURL = form.url.value;
statusToken = form.statusToken.value;
infoElement = document.getElementById('authcloud_info');
errorElement = document.getElementById('authcloud_error');
dispatcherElement = document.getElementById('authcloud_dispatch');
const appLink = form.appLink.value;
authenticateUser(appLink);
}
window.onload = function() {
init();
};

View File

@ -0,0 +1,154 @@
let baseURL; // base URL
let statusToken; // used to check progress
let dispatcherElement; // to display link or QR code
let infoElement; // to display info text
let errorElement; // to display error text
function addInput(form, name, value) {
const input = document.createElement("input");
input.name = name;
input.value = value;
form.appendChild(input);
}
function submitStatus(status) {
// we have to do a form POST instead of AJAX
const form = document.createElement("form");
form.method = "POST";
form.style.display = "none";
addInput(form, "status", status);
document.body.appendChild(form);
form.submit();
}
const Status = {
_pollInterval: 2 * 1000, // Check every 2 seconds
latest: null,
startPolling: function (token, uiCallback) {
let interval = setInterval(async () => {
await this._check(token).then(function (resp) {
console.log("Polling status: %o", resp);
uiCallback && uiCallback(resp, false);
return Status.latest = resp;
})
.catch(function (err) {
console.error("Error during polling: %o", err);
return false;
});
if (Status.latest && (Status.latest.status === 'succeeded' || Status.latest.status === 'failed' || Status.latest.status === 'unknown')) {
// Done!
console.log('Latest status is: %o', this.latest);
uiCallback && uiCallback(this.latest, true);
clearInterval(interval);
}
}, this._pollInterval);
},
_check: async function (token) {
const payload = { statusToken: token };
const response = await fetch(baseURL + 'api/v1/status', {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
credentials: 'omit',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(payload),
redirect: 'follow',
referrerPolicy: 'no-referrer'
});
return await response.json();
}
};
function setDeepLinkLabel(button) {
const text = document.getElementsByName('info.deeplink')[0].value;
button.innerHTML = text;
}
function messageScanQR() {
const text = document.getElementsByName('info.qrcode')[0].value;
infoElement.innerHTML = text;
}
const Element = {
_elem: null, // QR code or deep link depending on device
show: function (appLink) {
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
const isIphone = 'iPhone' === navigator.platform;
const isAndroid = /android/i.test(userAgent) && /mobile/i.test(userAgent);
if (isAndroid || isIphone) {
this._elem = document.createElement('a');
this._elem.setAttribute('href', appLink);
this._elem.setAttribute('class', 'btn btn-primary');
this._elem.setAttribute('target', '_blank');
dispatcherElement.appendChild(this._elem);
setDeepLinkLabel(this._elem);
}
else {
messageScanQR();
this._elem = document.createElement('canvas');
dispatcherElement.appendChild(this._elem);
var qrcode = new QRious({
element: this._elem,
foreground: "#168CA9",
level: "M",
size: 280,
value: appLink
});
}
},
hide: function() {
// hide the element which was shown
if (this._elem != null) {
this._elem.style.display = "none";
}
}
};
function onboardUser(appLink) {
Element.show(appLink);
console.log('Starting Authentication Cloud status polling...');
Status.startPolling(statusToken, (st, done) => {
if (st.status === 'succeeded') {
console.log('Authentication Cloud onboarding done.');
submitStatus('succeeded')
}
else if (st.status === 'failed') {
// failed: The transaction failed, either by timeout or because the user did not accept.
console.warn('Authentication Cloud onboarding failed. User abort or timeout.');
submitStatus('failed')
}
else if (st.status === 'unknown') {
console.error('Authentication Cloud onboarding failed. Unknown status.');
submitStatus('unknown')
}
});
}
function init() {
const form = document.getElementById('authcloud_onboard');
baseURL = form.url.value;
statusToken = form.statusToken.value;
infoElement = document.getElementById('authcloud_info');
errorElement = document.getElementById('authcloud_error');
dispatcherElement = document.getElementById('authcloud_dispatch');
const appLink = form.appLink.value;
onboardUser(appLink);
}
window.onload = function() {
init();
};

View File

@ -0,0 +1,87 @@
/*
* Base64URL-ArrayBuffer
* https://github.com/herrjemand/Base64URL-ArrayBuffer
*
* Copyright (c) 2017 Yuriy Ackermann <ackermann.yuriy@gmail.com>
* Copyright (c) 2012 Niklas von Hertzen
* Licensed under the MIT license.
*
*/
(function() {
"use strict";
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
// Use a lookup table to find the index.
var lookup = new Uint8Array(256);
for (var i = 0; i < chars.length; i++) {
lookup[chars.charCodeAt(i)] = i;
}
var encode = function(arraybuffer) {
var bytes = new Uint8Array(arraybuffer),
i, len = bytes.length, base64 = "";
for (i = 0; i < len; i+=3) {
base64 += chars[bytes[i] >> 2];
base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
base64 += chars[bytes[i + 2] & 63];
}
if ((len % 3) === 2) {
base64 = base64.substring(0, base64.length - 1);
} else if (len % 3 === 1) {
base64 = base64.substring(0, base64.length - 2);
}
return base64;
};
var decode = function(base64) {
var bufferLength = base64.length * 0.75,
len = base64.length, i, p = 0,
encoded1, encoded2, encoded3, encoded4;
var arraybuffer = new ArrayBuffer(bufferLength),
bytes = new Uint8Array(arraybuffer);
for (i = 0; i < len; i+=4) {
encoded1 = lookup[base64.charCodeAt(i)];
encoded2 = lookup[base64.charCodeAt(i+1)];
encoded3 = lookup[base64.charCodeAt(i+2)];
encoded4 = lookup[base64.charCodeAt(i+3)];
bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
}
return arraybuffer;
};
/**
* Exporting and stuff
*/
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
module.exports = {
'encode': encode,
'decode': decode
}
} else {
if (typeof define === 'function' && define.amd) {
define([], function() {
return {
'encode': encode,
'decode': decode
}
});
} else {
window.base64url = {
'encode': encode,
'decode': decode
}
}
}
})();

View File

@ -0,0 +1,222 @@
/********************************************************
* Layout
********************************************************/
html { /* magic to position footer */
position: relative;
min-height: 100%;
}
body {
margin-bottom: 76px; /* == footer height */
}
.container, .container-fluid {
padding-left: 36px;
padding-right: 36px;
}
nav {
min-height: 100px;
padding: 36px;
}
header {
margin-bottom: 16px; /* h1.logintitle adds 20px => 36px */
}
.container {
min-width: 260px;
max-width: 700px;
}
h1 {
margin-bottom: 50px;
}
footer {
width: 100%;
position: absolute;
bottom: 0;
padding: 0 36px;
}
img {
width: 100%;
}
/********************************************************
* Header
********************************************************/
header .logo {
/* width: 20%;*/
/*max-width: 600px;*/
max-height: 150px;
width: auto;
}
/********************************************************
* Dropdown
********************************************************/
a.dropdown-toggle {
text-decoration: none;
}
a.dropdown-toggle:hover {
color: #168CA9;
border-bottom: 3px solid #168CA9;
}
.dropdown-menu {
padding: 5px 0;
}
.dropdown-menu li > a {
padding: 6px 28px;
}
.dropdown-menu a > .prefix {
display: inline-block;
min-width: 22px;
margin-right: 28px;
text-align: right;
}
/********************************************************
* Form
********************************************************/
/* Labels should not be bold */
label {
font-weight: normal;
}
/* Make error messages bold */
.has-error .help-block {
font-weight: bold;
}
/* Change button size, by default 116px in width */
.btn {
min-width: 116px;
padding: 3px 12px;
}
/* Disable gradient in buttons, ughhhh */
.btn.btn-primary {
border-color: transparent;
background-image: none;
text-shadow: none;
box-shadow: none;
-webkit-box-shadow: none;
}
.help-block a, .help-block a:visited {
color: #168CA9;
font-weight: bold;
text-decoration: none;
}
.help-block a:hover {
color: #168CA9;
text-decoration: underline;
}
/********************************************************
* Footer
********************************************************/
footer .row {
margin: 36px 0 0 0;
height: 40px;
padding-top: 14px;
line-height: 26px; /* to center text: height - padding-top = 26px */
border-top: 1px solid #168CA9;
}
footer .row > div { /* Fix alignment between border + text on Bootstrap grid */
padding: 0;
}
footer .logo-round-container {
position: relative;
}
footer .logo-round {
position: absolute;
left: 0;
right: 0;
top: -33px; /* found visually with Chrome Dev Tools */
height: 36px;
width: 36px;
border: 1px solid #00868c;
border-radius: 18px;
background: #fff;
padding: 8px;
}
footer .logo-round > img {
display: block;
}
#dispatchTargets {
margin-top: 20px;
}
/********************************************************
* Social login
********************************************************/
.btn.line {
background-color: transparent;
display: block;
width: 100%;
padding: 0;
margin: 1.5em 0 1em;
border: 0.5px solid #ccc;
pointer-events: none;
}
.btn.socialLogin {
background-color: #fff;
border: thin solid #ccc;
color: #000;
font-weight: 600;
position: relative;
margin: 5px;
min-width: 140px;
width: 210px;
border-radius: 8px;
padding: 8px 12px;
text-align: left;
}
.socialLogin img {
width: 1.5em;
height: 108%;
margin-right: 0.5em;
}
.btn.apple img {
width: 1.2em;
}
/********************************************************
* Show password
********************************************************/
.icon-inside {
position: relative;
}
.icon-inside input {
padding-right: calc(0.75rem + 1.25rem + 0.75rem);
}
.icon-inside button {
position: absolute;
right: 0;
top: 0;
margin-top: 0.45rem;
margin-right: 0.45rem;
background: #FFFFFF;
border: #FFFFFF;
}

Some files were not shown because too many files have changed in this diff Show More