feat: provide option to limit (T)OTP checks (#7693)

* feat: provide option to limit (T)OTP checks

* fix requests in console

* update errors pkg

* cleanup

* cleanup

* improve naming of existing config
This commit is contained in:
Livio Spring
2024-04-10 11:14:55 +02:00
committed by GitHub
parent e3f10f7e23
commit 153df2e12f
58 changed files with 752 additions and 755 deletions

View File

@@ -17,17 +17,49 @@
<div class="lockout-content">
<div class="row">
<div class="length-wrapper">
<button [disabled]="(['policy.write'] | hasRole | async) === false" mat-icon-button (click)="decrementMaxAttempts()">
<button
[disabled]="(['policy.write'] | hasRole | async) === false"
mat-icon-button
(click)="decrementPasswordMaxAttempts()"
>
<mat-icon>remove</mat-icon>
</button>
<span>{{ lockoutData.maxPasswordAttempts }}</span>
<button [disabled]="(['policy.write'] | hasRole | async) === false" mat-icon-button (click)="incrementMaxAttempts()">
<button
[disabled]="(['policy.write'] | hasRole | async) === false"
mat-icon-button
(click)="incrementPasswordMaxAttempts()"
>
<mat-icon>add</mat-icon>
</button>
</div>
<div class="number-toggle-row">
<span class="left-desc">{{ 'POLICY.DATA.MAXATTEMPTS' | translate }}</span>
<span class="left-desc">{{ 'POLICY.DATA.MAXPASSWORDATTEMPTS' | translate }}</span>
<span class="fill-space"></span>
</div>
</div>
<div class="row">
<div class="length-wrapper">
<button
[disabled]="(['policy.write'] | hasRole | async) === false"
mat-icon-button
(click)="decrementOTPMaxAttempts()"
>
<mat-icon>remove</mat-icon>
</button>
<span>{{ lockoutData.maxOtpAttempts }}</span>
<button
[disabled]="(['policy.write'] | hasRole | async) === false"
mat-icon-button
(click)="incrementOTPMaxAttempts()"
>
<mat-icon>add</mat-icon>
</button>
</div>
<div class="number-toggle-row">
<span class="left-desc">{{ 'POLICY.DATA.MAXOTPATTEMPTS' | translate }}</span>
<span class="fill-space"></span>
</div>
</div>

View File

@@ -91,24 +91,36 @@ export class PasswordLockoutPolicyComponent implements OnInit {
}
}
public incrementMaxAttempts(): void {
public incrementPasswordMaxAttempts(): void {
if (this.lockoutData?.maxPasswordAttempts !== undefined) {
this.lockoutData.maxPasswordAttempts++;
}
}
public decrementMaxAttempts(): void {
public decrementPasswordMaxAttempts(): void {
if (this.lockoutData?.maxPasswordAttempts && this.lockoutData?.maxPasswordAttempts > 0) {
this.lockoutData.maxPasswordAttempts--;
}
}
public incrementOTPMaxAttempts(): void {
if (this.lockoutData?.maxOtpAttempts !== undefined) {
this.lockoutData.maxOtpAttempts++;
}
}
public decrementOTPMaxAttempts(): void {
if (this.lockoutData?.maxOtpAttempts && this.lockoutData?.maxOtpAttempts > 0) {
this.lockoutData.maxOtpAttempts--;
}
}
public savePolicy(): void {
let promise: Promise<any>;
if (this.lockoutData) {
if (this.service instanceof AdminService) {
promise = this.service
.updateLockoutPolicy(this.lockoutData.maxPasswordAttempts)
.updateLockoutPolicy(this.lockoutData.maxPasswordAttempts, this.lockoutData.maxOtpAttempts)
.then(() => {
this.toast.showInfo('POLICY.TOAST.SET', true);
this.fetchData();
@@ -119,7 +131,7 @@ export class PasswordLockoutPolicyComponent implements OnInit {
} else {
if ((this.lockoutData as LockoutPolicy.AsObject).isDefault) {
promise = (this.service as ManagementService)
.addCustomLockoutPolicy(this.lockoutData.maxPasswordAttempts)
.addCustomLockoutPolicy(this.lockoutData.maxPasswordAttempts, this.lockoutData.maxOtpAttempts)
.then(() => {
this.toast.showInfo('POLICY.TOAST.SET', true);
this.fetchData();
@@ -129,7 +141,7 @@ export class PasswordLockoutPolicyComponent implements OnInit {
});
} else {
promise = (this.service as ManagementService)
.updateCustomLockoutPolicy(this.lockoutData.maxPasswordAttempts)
.updateCustomLockoutPolicy(this.lockoutData.maxPasswordAttempts, this.lockoutData.maxOtpAttempts)
.then(() => {
this.toast.showInfo('POLICY.TOAST.SET', true);
this.fetchData();

View File

@@ -957,9 +957,13 @@ export class AdminService {
return this.grpcService.admin.getLockoutPolicy(req, null).then((resp) => resp.toObject());
}
public updateLockoutPolicy(maxAttempts: number): Promise<UpdateLockoutPolicyResponse.AsObject> {
public updateLockoutPolicy(
maxPasswordAttempts: number,
maxOTPAttempts: number,
): Promise<UpdateLockoutPolicyResponse.AsObject> {
const req = new UpdateLockoutPolicyRequest();
req.setMaxPasswordAttempts(maxAttempts);
req.setMaxPasswordAttempts(maxPasswordAttempts);
req.setMaxOtpAttempts(maxOTPAttempts);
return this.grpcService.admin.updateLockoutPolicy(req, null).then((resp) => resp.toObject());
}

View File

@@ -1587,9 +1587,13 @@ export class ManagementService {
return this.grpcService.mgmt.getLockoutPolicy(req, null).then((resp) => resp.toObject());
}
public addCustomLockoutPolicy(maxAttempts: number): Promise<AddCustomLockoutPolicyResponse.AsObject> {
public addCustomLockoutPolicy(
maxPasswordAttempts: number,
maxOTPAttempts: number,
): Promise<AddCustomLockoutPolicyResponse.AsObject> {
const req = new AddCustomLockoutPolicyRequest();
req.setMaxPasswordAttempts(maxAttempts);
req.setMaxPasswordAttempts(maxPasswordAttempts);
req.setMaxOtpAttempts(maxOTPAttempts);
return this.grpcService.mgmt.addCustomLockoutPolicy(req, null).then((resp) => resp.toObject());
}
@@ -1599,9 +1603,13 @@ export class ManagementService {
return this.grpcService.mgmt.resetLockoutPolicyToDefault(req, null).then((resp) => resp.toObject());
}
public updateCustomLockoutPolicy(maxAttempts: number): Promise<UpdateCustomLockoutPolicyResponse.AsObject> {
public updateCustomLockoutPolicy(
maxPasswordAttempts: number,
maxOTPAttempts: number,
): Promise<UpdateCustomLockoutPolicyResponse.AsObject> {
const req = new UpdateCustomLockoutPolicyRequest();
req.setMaxPasswordAttempts(maxAttempts);
req.setMaxPasswordAttempts(maxPasswordAttempts);
req.setMaxOtpAttempts(maxOTPAttempts);
return this.grpcService.mgmt.updateCustomLockoutPolicy(req, null).then((resp) => resp.toObject());
}

View File

@@ -1653,7 +1653,8 @@
"HASLOWERCASE": "има малки букви",
"HASUPPERCASE": "има главни букви",
"SHOWLOCKOUTFAILURES": "показва грешки при блокиране",
"MAXATTEMPTS": "Максимален брой опити за парола",
"MAXPASSWORDATTEMPTS": "Максимален брой опити за парола",
"MAXOTPATTEMPTS": "Максимален брой опити за OTP",
"EXPIREWARNDAYS": "Предупреждение за изтичане след ден",
"MAXAGEDAYS": "Максимална възраст в дни",
"USERLOGINMUSTBEDOMAIN": "Добавяне на домейн на организация като суфикс към имената за вход",

View File

@@ -1660,7 +1660,8 @@
"HASLOWERCASE": "obsahuje malá písmena",
"HASUPPERCASE": "obsahuje velká písmena",
"SHOWLOCKOUTFAILURES": "zobrazit neúspěšné pokusy o uzamčení",
"MAXATTEMPTS": "Maximální počet pokusů o heslo",
"MAXPASSWORDATTEMPTS": "Maximální počet pokusů o heslo",
"MAXOTPATTEMPTS": "Maximální počet pokusů o OTP",
"EXPIREWARNDAYS": "Upozornění na expiraci po dni",
"MAXAGEDAYS": "Maximální stáří v dnech",
"USERLOGINMUSTBEDOMAIN": "Přidat doménu organizace jako příponu k přihlašovacím jménům",

View File

@@ -1659,7 +1659,8 @@
"HASLOWERCASE": "erfordert Kleinbuchstaben",
"HASUPPERCASE": "erfordert Grossbuchstaben",
"SHOWLOCKOUTFAILURES": "Zeige Anzahl Anmeldeversuche",
"MAXATTEMPTS": "Maximale Anzahl an Versuchen",
"MAXPASSWORDATTEMPTS": "Maximale Anzahl an Passwort Versuchen",
"MAXOTPATTEMPTS": "Maximale Anzahl an OTP Versuchen",
"EXPIREWARNDAYS": "Ablauf Warnung nach Tagen",
"MAXAGEDAYS": "Maximale Gültigkeit in Tagen",
"USERLOGINMUSTBEDOMAIN": "Organisationsdomain dem Loginname hinzufügen",

View File

@@ -1660,7 +1660,8 @@
"HASLOWERCASE": "must include a lowercase letter",
"HASUPPERCASE": "must include an uppercase letter",
"SHOWLOCKOUTFAILURES": "show lockout failures",
"MAXATTEMPTS": "Password maximum Attempts",
"MAXPASSWORDATTEMPTS": "Password maximum attempts",
"MAXOTPATTEMPTS": "OTP maximum attempts",
"EXPIREWARNDAYS": "Expiration Warning after day",
"MAXAGEDAYS": "Max Age in days",
"USERLOGINMUSTBEDOMAIN": "Add organization domain as suffix to loginnames",

View File

@@ -1661,7 +1661,8 @@
"HASLOWERCASE": "tiene minúsculas",
"HASUPPERCASE": "tiene mayúsculas",
"SHOWLOCKOUTFAILURES": "mostrar fallos de bloqueo",
"MAXATTEMPTS": "Intentos máximos",
"MAXPASSWORDATTEMPTS": "Intentos máximos de contraseña",
"MAXOTPATTEMPTS": "Intentos máximos de OTP",
"EXPIREWARNDAYS": "Aviso de expiración después de estos días: ",
"MAXAGEDAYS": "Antigüedad máxima en días",
"USERLOGINMUSTBEDOMAIN": "Añadir el dominio de la organización como sufijo de los nombres de inicio de sesión",

View File

@@ -1659,7 +1659,8 @@
"HASLOWERCASE": "a minuscule",
"HASUPPERCASE": "a majuscule",
"SHOWLOCKOUTFAILURES": "montrer les échecs de verrouillage",
"MAXATTEMPTS": "Mot de passe maximum Tentatives",
"MAXPASSWORDATTEMPTS": "Mot de passe maximum tentatives",
"MAXOTPATTEMPTS": "Maximal de tentatives OTP",
"EXPIREWARNDAYS": "Expiration Avertissement après le jour",
"MAXAGEDAYS": "Âge maximum en jours",
"USERLOGINMUSTBEDOMAIN": "Le nom de connexion de l'utilisateur doit contenir le nom de domaine de l'organisation",

View File

@@ -1659,7 +1659,8 @@
"HASLOWERCASE": "ha la minuscola",
"HASUPPERCASE": "ha la maiuscola",
"SHOWLOCKOUTFAILURES": "mostra i fallimenti del blocco",
"MAXATTEMPTS": "Massimo numero di tentativi di password",
"MAXPASSWORDATTEMPTS": "Massimo numero di tentativi di password",
"MAXOTPATTEMPTS": "Massimo numero di tentativi di OTP",
"EXPIREWARNDAYS": "Avviso scadenza dopo il giorno",
"MAXAGEDAYS": "Lunghezza massima in giorni",
"USERLOGINMUSTBEDOMAIN": "Nome utente deve contenere il dominio dell' organizzazione",

View File

@@ -1656,7 +1656,8 @@
"HASLOWERCASE": "小文字を含める",
"HASUPPERCASE": "大文字を含める",
"SHOWLOCKOUTFAILURES": "ロックアウトの失敗を表示する",
"MAXATTEMPTS": "パスワードの最大試行",
"MAXPASSWORDATTEMPTS": "パスワードの最大試行",
"MAXOTPATTEMPTS": "最大OTP試行回数",
"EXPIREWARNDAYS": "有効期限の翌日以降の警告",
"MAXAGEDAYS": "最大有効期限",
"USERLOGINMUSTBEDOMAIN": "ログイン名の接尾辞として組織ドメインを追加する",

View File

@@ -1661,7 +1661,8 @@
"HASLOWERCASE": "има мали букви",
"HASUPPERCASE": "има големи букви",
"SHOWLOCKOUTFAILURES": "прикажи неуспешни заклучувања",
"MAXATTEMPTS": "Максимален број на обиди за лозинка",
"MAXPASSWORDATTEMPTS": "Максимален број на обиди за лозинка",
"MAXOTPATTEMPTS": "Максимални обиди за OTP",
"EXPIREWARNDAYS": "Предупредување за истекување по ден",
"MAXAGEDAYS": "Максимална возраст во денови",
"USERLOGINMUSTBEDOMAIN": "Додади организациски домен како суфикс на корисничките имиња",

View File

@@ -1660,7 +1660,8 @@
"HASLOWERCASE": "heeft kleine letters",
"HASUPPERCASE": "heeft hoofdletters",
"SHOWLOCKOUTFAILURES": "toon lockout mislukkingen",
"MAXATTEMPTS": "Maximum pogingen voor wachtwoord",
"MAXPASSWORDATTEMPTS": "Maximum pogingen voor wachtwoord",
"MAXOTPATTEMPTS": "Maximale OTP-pogingen",
"EXPIREWARNDAYS": "Vervaldatum Waarschuwing na dag",
"MAXAGEDAYS": "Maximale Leeftijd in dagen",
"USERLOGINMUSTBEDOMAIN": "Voeg organisatie domein toe als achtervoegsel aan inlognamen",

View File

@@ -1659,7 +1659,8 @@
"HASLOWERCASE": "zawiera małe litery",
"HASUPPERCASE": "zawiera duże litery",
"SHOWLOCKOUTFAILURES": "pokaż blokady nieudanych prób",
"MAXATTEMPTS": "Maksymalna liczba prób wprowadzenia hasła",
"MAXPASSWORDATTEMPTS": "Maksymalna liczba prób wprowadzenia hasła",
"MAXOTPATTEMPTS": "Maksymalna liczba prób OTP",
"EXPIREWARNDAYS": "Ostrzeżenie o wygaśnięciu po dniu",
"MAXAGEDAYS": "Maksymalny wiek w dniach",
"USERLOGINMUSTBEDOMAIN": "Dodaj domenę organizacji jako przyrostek do nazw logowania",

View File

@@ -1661,7 +1661,8 @@
"HASLOWERCASE": "tem letra minúscula",
"HASUPPERCASE": "tem letra maiúscula",
"SHOWLOCKOUTFAILURES": "mostrar falhas de bloqueio",
"MAXATTEMPTS": "Máximo de tentativas de senha",
"MAXPASSWORDATTEMPTS": "Máximo de tentativas de senha",
"MAXOTPATTEMPTS": "Máximo de tentativas de OTP",
"EXPIREWARNDAYS": "Aviso de expiração após dias",
"MAXAGEDAYS": "Idade máxima em dias",
"USERLOGINMUSTBEDOMAIN": "Adicionar domínio da organização como sufixo aos nomes de login",

View File

@@ -1729,7 +1729,8 @@
"HASLOWERCASE": "Содержит нижний регистр",
"HASUPPERCASE": "Содержит верхний регистр",
"SHOWLOCKOUTFAILURES": "Показать ошибки блокировки",
"MAXATTEMPTS": "Максимальное количество попыток пароля",
"MAXPASSWORDATTEMPTS": "Максимальное количество попыток пароля",
"MAXOTPATTEMPTS": "Максимальное количество попыток OTP",
"EXPIREWARNDAYS": "Предупреждение об истечении срока действия после дня",
"MAXAGEDAYS": "Максимальный возраст в днях",
"USERLOGINMUSTBEDOMAIN": "Добавить домен организации в качестве суффикса к именам логина",

View File

@@ -1658,7 +1658,8 @@
"HASLOWERCASE": "包含小写字母",
"HASUPPERCASE": "包含大写字母",
"SHOWLOCKOUTFAILURES": "显示锁定失败",
"MAXATTEMPTS": "密码最大尝试次数",
"MAXPASSWORDATTEMPTS": "密码最大尝试次数",
"MAXOTPATTEMPTS": "最多尝试 OTP 次数",
"EXPIREWARNDAYS": "密码过期警告",
"MAXAGEDAYS": "Max Age in days",
"USERLOGINMUSTBEDOMAIN": "用户名必须包含组织域名",

File diff suppressed because it is too large Load Diff