Add support for global 2FA enforcement #349

This commit is contained in:
the-djmaze 2022-04-25 16:21:16 +02:00
parent 375f715b78
commit 8b3cfc7a67
15 changed files with 85 additions and 54 deletions

View file

@ -7,9 +7,9 @@ class TwoFactorAuthPlugin extends \RainLoop\Plugins\AbstractPlugin
{
const
NAME = 'Two Factor Authentication',
VERSION = '2.13.3',
RELEASE = '2022-03-04',
REQUIRED = '2.13.2',
VERSION = '2.15.0',
RELEASE = '2022-04-25',
REQUIRED = '2.15.0',
CATEGORY = 'Login',
DESCRIPTION = 'Provides support for TOTP 2FA';
@ -21,6 +21,7 @@ class TwoFactorAuthPlugin extends \RainLoop\Plugins\AbstractPlugin
$this->addJs('js/TwoFactorAuthSettings.js');
$this->addHook('login.success', 'DoLogin');
$this->addHook('filter.app-data', 'FilterAppData');
$this->addJsonHook('GetTwoFactorInfo', 'DoGetTwoFactorInfo');
$this->addJsonHook('CreateTwoFactorSecret', 'DoCreateTwoFactorSecret');
@ -33,6 +34,23 @@ class TwoFactorAuthPlugin extends \RainLoop\Plugins\AbstractPlugin
$this->addTemplate('templates/PopupsTwoFactorAuthTest.html');
}
public function configMapping() : array
{
return [
\RainLoop\Plugins\Property::NewInstance("force_two_factor_auth")
// ->SetLabel('PLUGIN_TWO_FACTOR/LABEL_FORCE')
->SetLabel('Enforce 2-Step Verification')
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL),
];
}
public function FilterAppData($bAdmin, &$aResult)
{
if (!$bAdmin && \is_array($aResult)/* && isset($aResult['Auth']) && !$aResult['Auth']*/) {
$aResult['RequireTwoFactor'] = $this->Config()->Get('plugin', 'force_two_factor_auth', false);
}
}
public function DoLogin(MainAccount $oAccount)
{
if ($this->TwoFactorAuthProvider($oAccount)) {

View file

@ -1,10 +1,10 @@
(rl => {
rl && addEventListener('rl-view-model', e => {
addEventListener('rl-view-model', e => {
if (e.detail && 'Login' === e.detail.viewModelTemplateID) {
const container = e.detail.viewModelDom.querySelector('#plugin-Login-BottomControlGroup'),
placeholder = 'LOGIN/LABEL_TWO_FACTOR_CODE';
placeholder = 'PLUGIN_2FA/LABEL_TWO_FACTOR_CODE';
if (container) {
container.prepend(Element.fromHTML('<div class="controls">'
+ '<span class="fontastic">⏱</span>'
@ -18,4 +18,15 @@
}
});
// https://github.com/the-djmaze/snappymail/issues/349
let code;
addEventListener('sm-user-login', e => {
code = e.detail.get('totp_code');
});
addEventListener('sm-user-login-response', e => {
if (e.detail && !e.detail.error && rl.settings.get('RequireTwoFactor') && !code) {
document.location.hash = '#/settings/two-factor-auth';
}
});
})(window.rl);

View file

@ -70,12 +70,12 @@ class TwoFactorAuthSettings
// translatorTrigger();
return this.twoFactorTested() || this.viewEnable_()
? ''
: rl.i18n('POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_SECRET_TEST_BEFORE_DESC');
: rl.i18n('PLUGIN_2FA/TWO_FACTOR_SECRET_TEST_BEFORE_DESC');
},
viewTwoFactorStatus: () => {
// translatorTrigger();
return rl.i18n('POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_SECRET_'
return rl.i18n('PLUGIN_2FA/TWO_FACTOR_SECRET_'
+ (this.twoFactorStatus() ? '' : 'NOT_')
+ 'CONFIGURED_DESC'
);
@ -202,7 +202,7 @@ class TwoFactorAuthTestPopupView extends rl.pluginPopupView {
rl.addSettingsViewModel(
TwoFactorAuthSettings,
'TwoFactorAuthSettings',
'POPUPS_TWO_FACTOR_CFG/LEGEND_TWO_FACTOR_AUTH',
'PLUGIN_2FA/LEGEND_TWO_FACTOR_AUTH',
'two-factor-auth'
);

View file

@ -0,0 +1,20 @@
[PLUGIN_2FA]
LEGEND_TWO_FACTOR_AUTH = "Dvoufázové ověření"
LABEL_ENABLE_TWO_FACTOR = "Povolit dvoufázové ověření"
LABEL_TWO_FACTOR_USER = "Uživatel"
LABEL_TWO_FACTOR_STATUS = "Stav"
LABEL_TWO_FACTOR_SECRET = "Tajný klíč"
LABEL_TWO_FACTOR_BACKUP_CODES = "Backup codes"
BUTTON_CREATE = "Create a secret"
BUTTON_ACTIVATE = "Activate"
LINK_TEST = "test"
BUTTON_SHOW_SECRET = "Show Secret"
BUTTON_HIDE_SECRET = "Hide Secret"
TWO_FACTOR_SECRET_CONFIGURED_DESC = "Configured"
TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC = "Not configured"
TWO_FACTOR_SECRET_DESC = "Import this info into your Google Authenticator client (or other TOTP client) using the provided QR code below or by entering the code manually.\n"
TWO_FACTOR_BACKUP_CODES_DESC = "If you can't receive codes via Google Authenticator (or other TOTP client), you can use backup codes to sign in. After youve used a backup code to sign in, it will become inactive.\n"
TWO_FACTOR_SECRET_TEST_BEFORE_DESC = "You can't change this setting before test."
TITLE_TEST_CODE = "2-Step verification test"
LABEL_CODE = "Code"
LABEL_TWO_FACTOR_CODE = "Verification Code"

View file

@ -1,4 +1,4 @@
[POPUPS_TWO_FACTOR_CFG]
[PLUGIN_2FA]
LEGEND_TWO_FACTOR_AUTH = "Zwei-Faktor-Authentifizierung"
LABEL_ENABLE_TWO_FACTOR = "Zwei-Faktor-Authentifizierung aktivieren"
LABEL_TWO_FACTOR_USER = "Benutzer"
@ -15,8 +15,6 @@ TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC = "Nicht konfiguriert"
TWO_FACTOR_SECRET_DESC = "Importieren Sie diese Information in Ihre Google-Authenticator-Anwendung (oder andere TOTP-Anwendung), indem Sie den unten bereitgestellten QR-Code verwenden oder den Code manuell eingeben."
TWO_FACTOR_BACKUP_CODES_DESC = "Sollten Sie keine Codes über den Google Authenticator erhalten, können Sie einen Sicherungscode zur Anmeldung verwenden. Der Sicherungscode wird inaktiv, sobald Sie ihn zur Anmeldung verwendet haben."
TWO_FACTOR_SECRET_TEST_BEFORE_DESC = "Sie können diese Einstellung nicht ohne vorherigen Test verändern."
[POPUPS_TWO_FACTOR_TEST]
TITLE_TEST_CODE = "Zwei-Faktor-Authentifizierung"
LABEL_CODE = "Code"
[LOGIN]
LABEL_TWO_FACTOR_CODE = "Verifizierungscode"

View file

@ -1,7 +1,4 @@
[POPUPS_TWO_FACTOR_TEST]
TITLE_TEST_CODE = "2-Step verification test"
LABEL_CODE = "Code"
[POPUPS_TWO_FACTOR_CFG]
[PLUGIN_2FA]
LEGEND_TWO_FACTOR_AUTH = "2-Step Verification (TOTP)"
LABEL_ENABLE_TWO_FACTOR = "Enable 2-Step verification"
LABEL_TWO_FACTOR_USER = "User"
@ -18,5 +15,6 @@ TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC = "Not configured"
TWO_FACTOR_SECRET_DESC = "Import this info into your Google Authenticator client (or other TOTP client) using the provided QR code below or by entering the code manually.\n"
TWO_FACTOR_BACKUP_CODES_DESC = "If you can't receive codes via Google Authenticator (or other TOTP client), you can use backup codes to sign in. After youve used a backup code to sign in, it will become inactive.\n"
TWO_FACTOR_SECRET_TEST_BEFORE_DESC = "You can't change this setting before test."
[LOGIN]
TITLE_TEST_CODE = "2-Step verification test"
LABEL_CODE = "Code"
LABEL_TWO_FACTOR_CODE = "Verification Code"

View file

@ -1,7 +1,4 @@
[POPUPS_TWO_FACTOR_TEST]
TITLE_TEST_CODE = "Prueba de verificación de 2 pasos"
LABEL_CODE = "Código"
[POPUPS_TWO_FACTOR_CFG]
[PLUGIN_2FA]
LEGEND_TWO_FACTOR_AUTH = "Verificación de 2 Pasos"
LABEL_ENABLE_TWO_FACTOR = "Activar la verificación de 2 pasos"
LABEL_TWO_FACTOR_USER = "Usuario"
@ -18,5 +15,6 @@ TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC = "No configurado"
TWO_FACTOR_SECRET_DESC = "Importar esta información en su cliente Google Authenticator (u otro cliente TOTP) utilizando el código QR se indica debajo o introduciendo el código manualmente."
TWO_FACTOR_BACKUP_CODES_DESC = "Si usted no puede recibir los códigos a través de Google Authenticator, puede utilizar códigos de copia de seguridad para firmar pulg Después de que usted ha utilizado un código de copia de seguridad para iniciar sesión, se convertirá en inactiva."
TWO_FACTOR_SECRET_TEST_BEFORE_DESC = "You can't change this setting before test."
[LOGIN]
TITLE_TEST_CODE = "Prueba de verificación de 2 pasos"
LABEL_CODE = "Código"
LABEL_TWO_FACTOR_CODE = "Código de verificación"

View file

@ -1,4 +1,4 @@
[POPUPS_TWO_FACTOR_CFG]
[PLUGIN_2FA]
LEGEND_TWO_FACTOR_AUTH = "Authentification en deux étapes"
LABEL_ENABLE_TWO_FACTOR = "Activer l'authentification en deux étapes"
LABEL_TWO_FACTOR_USER = "Utilisateur"
@ -15,8 +15,6 @@ TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC = "Non configuré"
TWO_FACTOR_SECRET_DESC = "Importez ces informations dans votre client Google Authenticator (ou un autre client TOTP) en utilisant le code QR fourni ci-dessous ou en entrant les valeurs manuellement."
TWO_FACTOR_BACKUP_CODES_DESC = "Si vous ne pouvez pas recevoir les codes par Google Authenticator, vous pouvez utiliser les codes de sauvegarde pour vous connecter. Après avoir fait cela, il deviendra inactif."
TWO_FACTOR_SECRET_TEST_BEFORE_DESC = "Vous ne pouvez pas modifier ce paramètre avant de l'avoir essayé."
[POPUPS_TWO_FACTOR_TEST]
TITLE_TEST_CODE = "Test d'authentification en deux étapes"
LABEL_CODE = "Code"
[LOGIN]
LABEL_TWO_FACTOR_CODE = "Code de vérification"

View file

@ -1,4 +1,4 @@
[POPUPS_TWO_FACTOR_CFG]
[PLUGIN_2FA]
LEGEND_TWO_FACTOR_AUTH = "2 lépcsős hitelesítés"
LABEL_ENABLE_TWO_FACTOR = "2 lépcsős hitelesítés engedélyezése"
LABEL_TWO_FACTOR_USER = "Felhasználó"
@ -15,8 +15,6 @@ TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC = "Nincs beállítva"
TWO_FACTOR_SECRET_DESC = "Importáld ezt az infót a Google Authenticator kliensedbe (vagy más TOTP kliensbe) az alábbi QR kód használatával vagy a kód manuális megadatásával.\n"
TWO_FACTOR_BACKUP_CODES_DESC = "Ha nem kapod meg a kódokat a Google Authenticator kliensből (vagy más TOTP kliensből), akkor a bejelentkezéshez használhatod a biztonsági kódot. A biztonsági kód használata után inaktívvá válik.\n"
TWO_FACTOR_SECRET_TEST_BEFORE_DESC = "Tesztelés nélkül nem lehet megváltoztatni ezt a beállítást."
[POPUPS_TWO_FACTOR_TEST]
TITLE_TEST_CODE = "2-lépéses hitelesítés teszt"
LABEL_CODE = "Kód"
[LOGIN]
LABEL_TWO_FACTOR_CODE = "Megerősítő kód"

View file

@ -1,7 +1,4 @@
[POPUPS_TWO_FACTOR_TEST]
TITLE_TEST_CODE = "Test di verifica a 2 fattori"
LABEL_CODE = "Codice"
[POPUPS_TWO_FACTOR_CFG]
[PLUGIN_2FA]
LEGEND_TWO_FACTOR_AUTH = "Verifica a 2 Fattori"
LABEL_ENABLE_TWO_FACTOR = "Abilita la verifica a 2 fattori"
LABEL_TWO_FACTOR_USER = "Utente"
@ -18,5 +15,6 @@ TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC = "Non configurato"
TWO_FACTOR_SECRET_DESC = "Importa queste informazioni nella tua app Google Authenticator (o un altro programma per l'autenticazione a due fattori) utilizzando il codice QR fornito qui sotto o inserendo il codice manualmente.\n"
TWO_FACTOR_BACKUP_CODES_DESC = "Se non riesci a ricevere i codici tramite Google Authenticator (o un altro programma per l'autenticazione a due fattori), puoi utilizzare i codici di backup per accedere. Dopo che hai utilizzato un codice di backup per accedere, diventerà inattivo.\n"
TWO_FACTOR_SECRET_TEST_BEFORE_DESC = "Non puoi modificare questa impostazione prima del test."
[LOGIN]
TITLE_TEST_CODE = "Test di verifica a 2 fattori"
LABEL_CODE = "Codice"
LABEL_TWO_FACTOR_CODE = "Codice di Verifica"

View file

@ -1,4 +1,4 @@
[POPUPS_TWO_FACTOR_CFG]
[PLUGIN_2FA]
LEGEND_TWO_FACTOR_AUTH = "2-Stap verificatie"
LABEL_ENABLE_TWO_FACTOR = "Gebruik 2-Stap verificatie"
LABEL_TWO_FACTOR_USER = "Gebruikersnaam"
@ -15,8 +15,6 @@ TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC = "Niet geconfigureerd"
TWO_FACTOR_SECRET_DESC = "Importeer deze informatie in uw Google Authenticator-client (of andere TOTP-client) door gebruik te maken van de QR code hier beneden of door de code handmatig in te voeren."
TWO_FACTOR_BACKUP_CODES_DESC = "Als u geen codes ontvangt via de Google Authenticator kunt u de backup codes gebruiken om in te loggen. Na gebruik van de backup code wordt deze inactief."
TWO_FACTOR_SECRET_TEST_BEFORE_DESC = "U kunt 2-stap verificatie niet activeren voordat u het succesvol getest heeft."
[POPUPS_TWO_FACTOR_TEST]
TITLE_TEST_CODE = "2-Stap verificatie test"
LABEL_CODE = "Code"
[LOGIN]
LABEL_TWO_FACTOR_CODE = "Verificatie Code"

View file

@ -1,4 +1,4 @@
[POPUPS_TWO_FACTOR_CFG]
[PLUGIN_2FA]
LEGEND_TWO_FACTOR_AUTH = "Tvåstegsverifiering (TOTP)"
LABEL_ENABLE_TWO_FACTOR = "Aktivera tvåstegsverifiering"
LABEL_TWO_FACTOR_USER = "Användare"
@ -15,8 +15,6 @@ TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC = "Inte konfigurarad"
TWO_FACTOR_SECRET_DESC = "Importera denna information till din Google Authenticator klient (eller annan TOTP klient) med denna QR kod eller manuellt med koden här nedan."
TWO_FACTOR_BACKUP_CODES_DESC = "Om du inte kan ta emot koderna med Google Authenticator, så använd backupkoderna för att logga in. När du använt backupkoderna för att logga in så blir dom inaktiva."
TWO_FACTOR_SECRET_TEST_BEFORE_DESC = "Du kan inte ändra denna inställning innan test."
[POPUPS_TWO_FACTOR_TEST]
TITLE_TEST_CODE = "Tvåstegsverifieringstest"
LABEL_CODE = "Kod"
[LOGIN]
LABEL_TWO_FACTOR_CODE = "Verifikationskod"

View file

@ -1,4 +1,4 @@
[POPUPS_TWO_FACTOR_CFG]
[PLUGIN_2FA]
LEGEND_TWO_FACTOR_AUTH = "两步验证 (TOTP)"
LABEL_ENABLE_TWO_FACTOR = "启用两步验证"
LABEL_TWO_FACTOR_USER = "用户"
@ -15,8 +15,6 @@ TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC = "未设置"
TWO_FACTOR_SECRET_DESC = "将下面的信息导入 Google Authenticator (或其他 TOTP 客户端)。 扫描下面的二维码或手动输入密钥。\n"
TWO_FACTOR_BACKUP_CODES_DESC = "如果你无法从验证器获取验证码,你可以使用备用代码登录。 当你使用过某一个备用代码后,它将会失效。\n"
TWO_FACTOR_SECRET_TEST_BEFORE_DESC = "完成测试前你无法更改此设置。"
[POPUPS_TWO_FACTOR_TEST]
TITLE_TEST_CODE = "两步验证测试"
LABEL_CODE = "代码"
[LOGIN]
LABEL_TWO_FACTOR_CODE = "验证码"

View file

@ -1,10 +1,10 @@
<header>
<a class="close" href="#" data-bind="click: close">×</a>
<h3 data-i18n="POPUPS_TWO_FACTOR_TEST/TITLE_TEST_CODE"></h3>
<h3 data-i18n="PLUGIN_2FA/TITLE_TEST_CODE"></h3>
</header>
<div class="modal-body form-horizontal">
<div class="control-group">
<label data-i18n="POPUPS_TWO_FACTOR_TEST/LABEL_CODE"></label>
<label data-i18n="PLUGIN_2FA/LABEL_CODE"></label>
<input type="text" class="uiInput inputName"
autofocus="" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
data-bind="textInput: code, onEnter: testCodeCommand" />

View file

@ -1,5 +1,5 @@
<div class="b-settings-two-factor form-horizontal">
<div class="legend" data-i18n="POPUPS_TWO_FACTOR_CFG/LEGEND_TWO_FACTOR_AUTH"></div>
<div class="legend" data-i18n="PLUGIN_2FA/LEGEND_TWO_FACTOR_AUTH"></div>
<div class="form-horizontal">
<div class="control-group" data-bind="visible: twoFactorStatus">
<div class="controls">
@ -7,7 +7,7 @@
<div data-bind="component: {
name: 'Checkbox',
params: {
label: 'POPUPS_TWO_FACTOR_CFG/LABEL_ENABLE_TWO_FACTOR',
label: 'PLUGIN_2FA/LABEL_ENABLE_TWO_FACTOR',
enable: twoFactorAllowedEnable,
value: viewEnable,
inline: true
@ -16,12 +16,12 @@
</div>
&nbsp;&nbsp;&nbsp;
<span class="g-ui-link" data-bind="click: testTwoFactor, visible: twoFactorStatus"
data-i18n="POPUPS_TWO_FACTOR_CFG/LINK_TEST"></span>
data-i18n="PLUGIN_2FA/LINK_TEST"></span>
</div>
</div>
<div class="control-group">
<label class="control-label">
<span data-i18n="POPUPS_TWO_FACTOR_CFG/LABEL_TWO_FACTOR_USER"></span>
<span data-i18n="PLUGIN_2FA/LABEL_TWO_FACTOR_USER"></span>
</label>
<div class="controls" style="padding-top: 5px;">
<strong data-bind="text: viewUser"></strong>
@ -31,34 +31,34 @@
<div class="controls" style="padding-top: 5px;">
<strong data-bind="visible: secreting">...</strong>
<span class="g-ui-link" data-bind="click: showSecret, visible: !secreting()"
data-i18n="POPUPS_TWO_FACTOR_CFG/BUTTON_SHOW_SECRET"></span>
data-i18n="PLUGIN_2FA/BUTTON_SHOW_SECRET"></span>
</div>
</div>
<div class="control-group" data-bind="visible: '' !== viewSecret()">
<label class="control-label">
<span data-i18n="POPUPS_TWO_FACTOR_CFG/LABEL_TWO_FACTOR_SECRET"></span>
<span data-i18n="PLUGIN_2FA/LABEL_TWO_FACTOR_SECRET"></span>
</label>
<div class="controls" style="padding-top: 5px;">
<strong data-bind="text: viewSecret" style="user-select:text"></strong>
&nbsp;&nbsp;
<span class="g-ui-link" data-bind="click: hideSecret" data-i18n="POPUPS_TWO_FACTOR_CFG/BUTTON_HIDE_SECRET"></span>
<span class="g-ui-link" data-bind="click: hideSecret" data-i18n="PLUGIN_2FA/BUTTON_HIDE_SECRET"></span>
<br />
<br />
<blockquote>
<p class="muted width100-on-mobile" style="width: 550px" data-i18n="POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_SECRET_DESC"></p>
<p class="muted width100-on-mobile" style="width: 550px" data-i18n="PLUGIN_2FA/TWO_FACTOR_SECRET_DESC"></p>
</blockquote>
<pre data-bind="text: viewQRCode" style="line-height:1;letter-spacing:-1px"></pre>
</div>
</div>
<div class="control-group" data-bind="visible: '' !== viewBackupCodes()">
<label class="control-label">
<span data-i18n="POPUPS_TWO_FACTOR_CFG/LABEL_TWO_FACTOR_BACKUP_CODES"></span>
<span data-i18n="PLUGIN_2FA/LABEL_TWO_FACTOR_BACKUP_CODES"></span>
</label>
<div class="controls" style="padding-top: 5px;">
<pre data-bind="text: viewBackupCodes" style="user-select: text; width: 230px; word-break: break-word;"></pre>
<br />
<blockquote>
<p class="muted width100-on-mobile" style="width: 550px" data-i18n="POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_BACKUP_CODES_DESC"></p>
<p class="muted width100-on-mobile" style="width: 550px" data-i18n="PLUGIN_2FA/TWO_FACTOR_BACKUP_CODES_DESC"></p>
</blockquote>
</div>
</div>
@ -70,7 +70,7 @@
</a>
<a class="btn" data-bind="click: createTwoFactor, visible: !twoFactorStatus()">
<i class="fontastic" data-bind="css: {'icon-spinner': processing()}"></i>
<span data-i18n="POPUPS_TWO_FACTOR_CFG/BUTTON_ACTIVATE"></span>
<span data-i18n="PLUGIN_2FA/BUTTON_ACTIVATE"></span>
</a>
<!--
<a class="btn" data-bind="click: close, visible: viewEnable()">