Merge branch 'master' into release

This commit is contained in:
Dan Brown 2021-09-02 21:12:06 +01:00
commit c6773a8c9f
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
15 changed files with 63 additions and 35 deletions

View File

@ -183,3 +183,4 @@ A Ibnu Hibban (abd.ibnuhibban) :: Indonesian
Frost-ZX :: Chinese Simplified Frost-ZX :: Chinese Simplified
Kuzma Simonov (ovmach) :: Russian Kuzma Simonov (ovmach) :: Russian
Vojtěch Krystek (acantophis) :: Czech Vojtěch Krystek (acantophis) :: Czech
Michał Lipok (mLipok) :: Polish

View File

@ -25,8 +25,8 @@ use Permissions;
*/ */
class Page extends BookChild class Page extends BookChild
{ {
public static $listAttributes = ['name', 'id', 'slug', 'book_id', 'chapter_id', 'draft', 'template', 'text', 'created_at', 'updated_at']; public static $listAttributes = ['name', 'id', 'slug', 'book_id', 'chapter_id', 'draft', 'template', 'text', 'created_at', 'updated_at', 'priority'];
public static $contentAttributes = ['name', 'id', 'slug', 'book_id', 'chapter_id', 'draft', 'template', 'html', 'text', 'created_at', 'updated_at']; public static $contentAttributes = ['name', 'id', 'slug', 'book_id', 'chapter_id', 'draft', 'template', 'html', 'text', 'created_at', 'updated_at', 'priority'];
protected $fillable = ['name', 'priority', 'markdown']; protected $fillable = ['name', 'priority', 'markdown'];

View File

@ -35,7 +35,7 @@ class MfaTotpController extends Controller
$svg = $totp->generateQrCodeSvg($qrCodeUrl); $svg = $totp->generateQrCodeSvg($qrCodeUrl);
return view('mfa.totp-generate', [ return view('mfa.totp-generate', [
'secret' => $totpSecret, 'url' => $qrCodeUrl,
'svg' => $svg, 'svg' => $svg,
]); ]);
} }

View File

@ -48,8 +48,8 @@ return [
'favourite_remove_notification' => '":name" ir izņemts no jūsu favorītiem', 'favourite_remove_notification' => '":name" ir izņemts no jūsu favorītiem',
// MFA // MFA
'mfa_setup_method_notification' => 'Multi-factor method successfully configured', 'mfa_setup_method_notification' => '2FA funkcija aktivizēta',
'mfa_remove_method_notification' => 'Multi-factor method successfully removed', 'mfa_remove_method_notification' => '2FA funkcija noņemta',
// Other // Other
'commented_on' => 'komentēts', 'commented_on' => 'komentēts',

View File

@ -76,11 +76,11 @@ return [
'user_invite_success' => 'Parole iestatīta, tagad varat piekļūt :appName!', 'user_invite_success' => 'Parole iestatīta, tagad varat piekļūt :appName!',
// Multi-factor Authentication // Multi-factor Authentication
'mfa_setup' => 'Setup Multi-Factor Authentication', 'mfa_setup' => 'Iestati divfaktoru autentifikāciju (2FA)',
'mfa_setup_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.', 'mfa_setup_desc' => 'Iestati divfaktoru autentifikāciju kā papildus drošību tavam lietotāja kontam.',
'mfa_setup_configured' => 'Already configured', 'mfa_setup_configured' => 'Divfaktoru autentifikācija jau ir nokonfigurēta',
'mfa_setup_reconfigure' => 'Reconfigure', 'mfa_setup_reconfigure' => 'Mainīt 2FA konfigurāciju',
'mfa_setup_remove_confirmation' => 'Are you sure you want to remove this multi-factor authentication method?', 'mfa_setup_remove_confirmation' => 'Vai esi drošs, ka vēlies noņemt divfaktoru autentifikāciju?',
'mfa_setup_action' => 'Setup', 'mfa_setup_action' => 'Setup',
'mfa_backup_codes_usage_limit_warning' => 'You have less than 5 backup codes remaining, Please generate and store a new set before you run out of codes to prevent being locked out of your account.', 'mfa_backup_codes_usage_limit_warning' => 'You have less than 5 backup codes remaining, Please generate and store a new set before you run out of codes to prevent being locked out of your account.',
'mfa_option_totp_title' => 'Mobile App', 'mfa_option_totp_title' => 'Mobile App',

View File

@ -39,7 +39,7 @@ return [
'reset' => 'Atiestatīt', 'reset' => 'Atiestatīt',
'remove' => 'Noņemt', 'remove' => 'Noņemt',
'add' => 'Pievienot', 'add' => 'Pievienot',
'configure' => 'Configure', 'configure' => 'Mainīt konfigurāciju',
'fullscreen' => 'Pilnekrāns', 'fullscreen' => 'Pilnekrāns',
'favourite' => 'Pievienot favorītiem', 'favourite' => 'Pievienot favorītiem',
'unfavourite' => 'Noņemt no favorītiem', 'unfavourite' => 'Noņemt no favorītiem',

View File

@ -99,7 +99,7 @@ return [
'shelves_permissions' => 'Grāmatplaukta atļaujas', 'shelves_permissions' => 'Grāmatplaukta atļaujas',
'shelves_permissions_updated' => 'Grāmatplaukta atļaujas atjauninātas', 'shelves_permissions_updated' => 'Grāmatplaukta atļaujas atjauninātas',
'shelves_permissions_active' => 'Grāmatplaukta atļaujas ir aktīvas', 'shelves_permissions_active' => 'Grāmatplaukta atļaujas ir aktīvas',
'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_permissions_cascade_warning' => 'Grāmatu plauktu atļaujas netiek automātiski pārvietotas uz grāmatām. Tas ir tāpēc, ka grāmata var atrasties vairākos plauktos. Tomēr atļaujas var nokopēt uz plauktam pievienotajām grāmatām, izmantojot zemāk norādīto opciju.',
'shelves_copy_permissions_to_books' => 'Kopēt grāmatplaukta atļaujas uz grāmatām', 'shelves_copy_permissions_to_books' => 'Kopēt grāmatplaukta atļaujas uz grāmatām',
'shelves_copy_permissions' => 'Kopēt atļaujas', 'shelves_copy_permissions' => 'Kopēt atļaujas',
'shelves_copy_permissions_explain' => 'Šis piemēros pašreizējās grāmatplaukta piekļuves tiesības visām tajā esošajām grāmatām. Pirms ieslēgšanas pārliecinieties, ka ir saglabātas izmaiņas grāmatplaukta piekļuves tiesībām.', 'shelves_copy_permissions_explain' => 'Šis piemēros pašreizējās grāmatplaukta piekļuves tiesības visām tajā esošajām grāmatām. Pirms ieslēgšanas pārliecinieties, ka ir saglabātas izmaiņas grāmatplaukta piekļuves tiesībām.',

View File

@ -15,7 +15,7 @@ return [
'alpha_dash' => ':attribute var saturēt tikai burtus, ciparus, domuzīmes un apakš svītras.', 'alpha_dash' => ':attribute var saturēt tikai burtus, ciparus, domuzīmes un apakš svītras.',
'alpha_num' => ':attribute var saturēt tikai burtus un ciparus.', 'alpha_num' => ':attribute var saturēt tikai burtus un ciparus.',
'array' => ':attribute ir jābūt masīvam.', 'array' => ':attribute ir jābūt masīvam.',
'backup_codes' => 'The provided code is not valid or has already been used.', 'backup_codes' => 'Ievadītais kods nav derīgs vai arī jau ir izmantots.',
'before' => ':attribute jābūt datumam pirms :date.', 'before' => ':attribute jābūt datumam pirms :date.',
'between' => [ 'between' => [
'numeric' => ':attribute jābūt starp :min un :max.', 'numeric' => ':attribute jābūt starp :min un :max.',
@ -99,7 +99,7 @@ return [
], ],
'string' => ':attribute jābūt teksta virknei.', 'string' => ':attribute jābūt teksta virknei.',
'timezone' => ':attribute jābūt derīgai zonai.', 'timezone' => ':attribute jābūt derīgai zonai.',
'totp' => 'The provided code is not valid or has expired.', 'totp' => 'Ievadītais kods nav derīgs.',
'unique' => ':attribute jau ir aizņemts.', 'unique' => ':attribute jau ir aizņemts.',
'url' => ':attribute formāts nav derīgs.', 'url' => ':attribute formāts nav derīgs.',
'uploaded' => 'Fails netika ielādēts. Serveris nevar pieņemt šāda izmēra failus.', 'uploaded' => 'Fails netika ielādēts. Serveris nevar pieņemt šāda izmēra failus.',

View File

@ -48,8 +48,8 @@ return [
'favourite_remove_notification' => '":name" został usunięty z ulubionych', 'favourite_remove_notification' => '":name" został usunięty z ulubionych',
// MFA // MFA
'mfa_setup_method_notification' => 'Multi-factor method successfully configured', 'mfa_setup_method_notification' => 'Metoda wieloskładnikowa została pomyślnie skonfigurowana',
'mfa_remove_method_notification' => 'Multi-factor method successfully removed', 'mfa_remove_method_notification' => 'Metoda wieloskładnikowa pomyślnie usunięta',
// Other // Other
'commented_on' => 'skomentował', 'commented_on' => 'skomentował',

View File

@ -26,7 +26,7 @@ return [
'remember_me' => '记住我', 'remember_me' => '记住我',
'ldap_email_hint' => '请输入用于此帐户的电子邮件。', 'ldap_email_hint' => '请输入用于此帐户的电子邮件。',
'create_account' => '创建账户', 'create_account' => '创建账户',
'already_have_account' => '已经有账号?', 'already_have_account' => '已经有账号',
'dont_have_account' => '您还没有账号吗?', 'dont_have_account' => '您还没有账号吗?',
'social_login' => 'SNS登录', 'social_login' => 'SNS登录',
'social_registration' => '使用社交网站账号注册', 'social_registration' => '使用社交网站账号注册',
@ -82,31 +82,31 @@ return [
'mfa_setup_reconfigure' => '重新配置', 'mfa_setup_reconfigure' => '重新配置',
'mfa_setup_remove_confirmation' => '您确定想要移除多重身份认证吗?', 'mfa_setup_remove_confirmation' => '您确定想要移除多重身份认证吗?',
'mfa_setup_action' => '设置', 'mfa_setup_action' => '设置',
'mfa_backup_codes_usage_limit_warning' => '您剩余的备用验证码少于 5 个,请在用完验证码之前生成并保存新的验证码,以防止您的帐户被锁定。', 'mfa_backup_codes_usage_limit_warning' => '您剩余的备用认证码少于 5 个,请在用完认证码之前生成并保存新的认证码,以防止您的帐户被锁定。',
'mfa_option_totp_title' => '移动设备 App', 'mfa_option_totp_title' => '移动设备 App',
'mfa_option_totp_desc' => '要使用多重身份认证功能,您需要一个支持 TOTP基于时间的一次性密码算法 的移动设备 App如谷歌身份验证器Google Authenticator、Authy 或微软身份验证器Microsoft Authenticator。', 'mfa_option_totp_desc' => '要使用多重身份认证功能,您需要一个支持 TOTP基于时间的一次性密码算法 的移动设备 App如谷歌身份验证器Google Authenticator、Authy 或微软身份验证器Microsoft Authenticator。',
'mfa_option_backup_codes_title' => '备用证码', 'mfa_option_backup_codes_title' => '备用证码',
'mfa_option_backup_codes_desc' => '安全地保存一组一次性使用的备用验证码,您可以输入这些验证码来验证您的身份。', 'mfa_option_backup_codes_desc' => '请安全地保存这些一次性使用的备用认证码,您可以输入这些认证码来验证您的身份。',
'mfa_gen_confirm_and_enable' => '确认并启用', 'mfa_gen_confirm_and_enable' => '确认并启用',
'mfa_gen_backup_codes_title' => '备用证码设置', 'mfa_gen_backup_codes_title' => '备用证码设置',
'mfa_gen_backup_codes_desc' => '将下面的证码存放在一个安全的地方。访问系统时,您可以使用其中的一个验证码进行二次认证。', 'mfa_gen_backup_codes_desc' => '将下面的证码存放在一个安全的地方。访问系统时,您可以使用其中的一个验证码进行二次认证。',
'mfa_gen_backup_codes_download' => '下载证码', 'mfa_gen_backup_codes_download' => '下载证码',
'mfa_gen_backup_codes_usage_warning' => '每个证码只能使用一次', 'mfa_gen_backup_codes_usage_warning' => '每个证码只能使用一次',
'mfa_gen_totp_title' => '移动设备 App', 'mfa_gen_totp_title' => '移动设备 App',
'mfa_gen_totp_desc' => '要使用多重身份认证功能,您需要一个支持 TOTP基于时间的一次性密码算法 的移动设备 App如谷歌身份验证器Google Authenticator、Authy 或微软身份验证器Microsoft Authenticator。', 'mfa_gen_totp_desc' => '要使用多重身份认证功能,您需要一个支持 TOTP基于时间的一次性密码算法 的移动设备 App如谷歌身份验证器Google Authenticator、Authy 或微软身份验证器Microsoft Authenticator。',
'mfa_gen_totp_scan' => '要开始操作,请使用你的身份验证 App 扫描下面的二维码。', 'mfa_gen_totp_scan' => '要开始操作,请使用你的身份验证 App 扫描下面的二维码。',
'mfa_gen_totp_verify_setup' => '验证设置', 'mfa_gen_totp_verify_setup' => '验证设置',
'mfa_gen_totp_verify_setup_desc' => '请在下面的框中输入您在身份验证 App 中生成的证码来验证一切是否正常:', 'mfa_gen_totp_verify_setup_desc' => '请在下面的框中输入您在身份验证 App 中生成的证码来验证一切是否正常:',
'mfa_gen_totp_provide_code_here' => '再此输入您的 App 生成的验证码', 'mfa_gen_totp_provide_code_here' => '在此输入您的 App 生成的认证码',
'mfa_verify_access' => '认证访问', 'mfa_verify_access' => '认证访问',
'mfa_verify_access_desc' => '您的账户要求您在访问前通过额外的验证确认您的身份。使用您设置的认证方法认证以继续。', 'mfa_verify_access_desc' => '您的账户要求您在访问前通过额外的验证确认您的身份。使用您设置的认证方法认证以继续。',
'mfa_verify_no_methods' => '没有设置认证方法', 'mfa_verify_no_methods' => '没有设置认证方法',
'mfa_verify_no_methods_desc' => '您的账户没有设置多重身份认证。您需要至少设置一种才能访问。', 'mfa_verify_no_methods_desc' => '您的账户没有设置多重身份认证。您需要至少设置一种才能访问。',
'mfa_verify_use_totp' => '使用移动设备 App 进行认证', 'mfa_verify_use_totp' => '使用移动设备 App 进行认证',
'mfa_verify_use_backup_codes' => '使用备用证码进行认证', 'mfa_verify_use_backup_codes' => '使用备用证码进行认证',
'mfa_verify_backup_code' => '备用证码', 'mfa_verify_backup_code' => '备用证码',
'mfa_verify_backup_code_desc' => '在下面输入你的其中一个备用证码:', 'mfa_verify_backup_code_desc' => '在下面输入你的其中一个备用证码:',
'mfa_verify_backup_code_enter_here' => '在这里输入备用证码', 'mfa_verify_backup_code_enter_here' => '在这里输入备用证码',
'mfa_verify_totp_desc' => '在下面输入您的移动 App 生成的证码:', 'mfa_verify_totp_desc' => '在下面输入您的移动 App 生成的证码:',
'mfa_setup_login_notification' => '多重身份认证已设置,请使用新配置的方法重新登录。', 'mfa_setup_login_notification' => '多重身份认证已设置,请使用新配置的方法重新登录。',
]; ];

View File

@ -15,7 +15,7 @@ return [
'alpha_dash' => ':attribute 只能包含字母、数字和短横线。', 'alpha_dash' => ':attribute 只能包含字母、数字和短横线。',
'alpha_num' => ':attribute 只能包含字母和数字。', 'alpha_num' => ':attribute 只能包含字母和数字。',
'array' => ':attribute 必须是一个数组。', 'array' => ':attribute 必须是一个数组。',
'backup_codes' => '您输入的证码无效或已被使用。', 'backup_codes' => '您输入的证码无效或已被使用。',
'before' => ':attribute 必须是在 :date 前的日期。', 'before' => ':attribute 必须是在 :date 前的日期。',
'between' => [ 'between' => [
'numeric' => ':attribute 必须在:min到:max之间。', 'numeric' => ':attribute 必须在:min到:max之间。',
@ -99,7 +99,7 @@ return [
], ],
'string' => ':attribute 必须是字符串。', 'string' => ':attribute 必须是字符串。',
'timezone' => ':attribute 必须是有效的区域。', 'timezone' => ':attribute 必须是有效的区域。',
'totp' => '您输入的证码无效或已过期。', 'totp' => '您输入的证码无效或已过期。',
'unique' => ':attribute 已经被使用。', 'unique' => ':attribute 已经被使用。',
'url' => ':attribute 格式无效。', 'url' => ':attribute 格式无效。',
'uploaded' => '无法上传文件。 服务器可能不接受此大小的文件。', 'uploaded' => '无法上传文件。 服务器可能不接受此大小的文件。',

View File

@ -145,6 +145,7 @@ body.flexbox {
.flex { .flex {
min-height: 0; min-height: 0;
flex: 1; flex: 1;
max-width: 100%;
&.fit-content { &.fit-content {
flex-basis: auto; flex-basis: auto;
flex-grow: 0; flex-grow: 0;

View File

@ -12,6 +12,9 @@
<div class="block inline"> <div class="block inline">
{!! $svg !!} {!! $svg !!}
</div> </div>
<div class="code-base small text-muted px-s py-xs my-xs" style="overflow-x: scroll; white-space: nowrap;">
{{ $url }}
</div>
</div> </div>
<h2 class="list-heading">{{ trans('auth.mfa_gen_totp_verify_setup') }}</h2> <h2 class="list-heading">{{ trans('auth.mfa_gen_totp_verify_setup') }}</h2>

View File

@ -36,10 +36,12 @@ class MfaConfigurationTest extends TestCase
$resp->assertSee('The provided code is not valid or has expired.'); $resp->assertSee('The provided code is not valid or has expired.');
$revisitSvg = $resp->getElementHtml('#main-content .card svg'); $revisitSvg = $resp->getElementHtml('#main-content .card svg');
$this->assertTrue($svg === $revisitSvg); $this->assertTrue($svg === $revisitSvg);
$secret = decrypt(session()->get('mfa-setup-totp-secret'));
$resp->assertSee(htmlentities("?secret={$secret}&issuer=BookStack&algorithm=SHA1&digits=6&period=30"));
// Successful confirmation // Successful confirmation
$google2fa = new Google2FA(); $google2fa = new Google2FA();
$secret = decrypt(session()->get('mfa-setup-totp-secret'));
$otp = $google2fa->getCurrentOtp($secret); $otp = $google2fa->getCurrentOtp($secret);
$resp = $this->post('/mfa/totp/confirm', [ $resp = $this->post('/mfa/totp/confirm', [
'code' => $otp, 'code' => $otp,

View File

@ -258,4 +258,25 @@ class SortTest extends TestCase
$checkResp = $this->get(Page::find($checkPage->id)->getUrl()); $checkResp = $this->get(Page::find($checkPage->id)->getUrl());
$checkResp->assertSee($newBook->name); $checkResp->assertSee($newBook->name);
} }
public function test_pages_in_book_show_sorted_by_priority()
{
/** @var Book $book */
$book = Book::query()->whereHas('pages')->first();
$book->chapters()->forceDelete();
/** @var Page[] $pages */
$pages = $book->pages()->where('chapter_id', '=', 0)->take(2)->get();
$book->pages()->whereNotIn('id', $pages->pluck('id'))->delete();
$resp = $this->asEditor()->get($book->getUrl());
$resp->assertElementContains('.content-wrap a.page:nth-child(1)', $pages[0]->name);
$resp->assertElementContains('.content-wrap a.page:nth-child(2)', $pages[1]->name);
$pages[0]->forceFill(['priority' => 10])->save();
$pages[1]->forceFill(['priority' => 5])->save();
$resp = $this->asEditor()->get($book->getUrl());
$resp->assertElementContains('.content-wrap a.page:nth-child(1)', $pages[1]->name);
$resp->assertElementContains('.content-wrap a.page:nth-child(2)', $pages[0]->name);
}
} }