diff --git a/src/BootstrapBlazor.Server/Components/Layout/MainLayout.razor b/src/BootstrapBlazor.Server/Components/Layout/MainLayout.razor index e0484b03943..3dfc8f120db 100644 --- a/src/BootstrapBlazor.Server/Components/Layout/MainLayout.razor +++ b/src/BootstrapBlazor.Server/Components/Layout/MainLayout.razor @@ -21,7 +21,7 @@
- +
diff --git a/src/BootstrapBlazor.Server/Components/Layout/TutorialsNavMenu.razor.cs b/src/BootstrapBlazor.Server/Components/Layout/TutorialsNavMenu.razor.cs index 3235e718788..5f28ad92fa0 100644 --- a/src/BootstrapBlazor.Server/Components/Layout/TutorialsNavMenu.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Layout/TutorialsNavMenu.razor.cs @@ -115,6 +115,11 @@ protected override async Task OnInitializedAsync() { Text = Localizer["MemorialMode"], Url = "tutorials/memorial", + }, + new() + { + Text = Localizer["MFA"], + Url = "tutorials/mfa", } ]); } diff --git a/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/Login.razor b/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/Login.razor new file mode 100644 index 00000000000..fd8ed1f04ae --- /dev/null +++ b/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/Login.razor @@ -0,0 +1,37 @@ +@page "/tutorials/mfa" +@inject IOptionsMonitor WebsiteOption + +
+
+ +

Sign in to Blazor

+
+
+
Username or email address
+ +
+
Password
+
Forgot password?
+
+ + +
Or
+ +
+
+
New to Blazor? Create an account
+
+
+ +@code { + [Inject, NotNull] + private NavigationManager? NavigationManager { get; set; } + + private void OnSubmit() + { + NavigationManager.NavigateTo("/tutorials/mfa/two-factor"); + } +} diff --git a/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/Login.razor.css b/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/Login.razor.css new file mode 100644 index 00000000000..0b3e6c11f74 --- /dev/null +++ b/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/Login.razor.css @@ -0,0 +1,50 @@ +.bb-sign { + margin: 0 auto; + width: 320px; + padding: 0 1rem; +} + + .bb-sign img { + background-color: var(--bb-primary-color); + border-radius: 50%; + margin-block: 2rem; + } + +.bb-sign-body { + background-color: #f6f8fa; + border: 1px solid var(--bs-border-color); + border-radius: var(--bs-border-radius); + padding: 1rem; +} + +.bb-sign-divider { + display: flex; + flex-basis: 100%; + align-items: center; +} + + .bb-sign-divider::before, + .bb-sign-divider::after { + content: ""; + position: relative; + display: inline-block; + width: 50%; + height: 1px; + vertical-align: middle; + background-color: #d1d9e0; + } + + .bb-sign-divider::before { + right: 0.5rem; + } + + .bb-sign-divider::after { + left: 0.5rem; + } + +.bb-sign-callout { + padding: 1rem; + border: 1px solid var(--bs-border-color); + border-radius: var(--bs-border-radius); + text-align: center; +} diff --git a/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/TwoFactor.razor b/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/TwoFactor.razor new file mode 100644 index 00000000000..4cdeb2598ce --- /dev/null +++ b/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/TwoFactor.razor @@ -0,0 +1,21 @@ +@page "/tutorials/mfa/two-factor" +@inject IOptionsMonitor WebsiteOption + +
+
+ +

Two-factor authentication

+
+
+
+ +

Blazor Mobile

+
+
We sent you a sign-in request on your Blazor Mobile app. Approve the request to verify your identity.
+
+ +
diff --git a/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/TwoFactor.razor.css b/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/TwoFactor.razor.css new file mode 100644 index 00000000000..40abf62731e --- /dev/null +++ b/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/TwoFactor.razor.css @@ -0,0 +1,44 @@ +.bb-sign { + margin: 0 auto; + width: 320px; + padding: 0 1rem; +} + + .bb-sign img { + background-color: var(--bb-primary-color); + border-radius: 50%; + margin-block: 2rem; + } + + .bb-sign h1 { + font-size: 24px; + font-weight: 300; + letter-spacing: -0.5px; + margin-block-end: 1rem; + } + +.bb-sign-body { + background-color: #f6f8fa; + border: 1px solid var(--bs-border-color); + border-radius: var(--bs-border-radius); + padding: 1rem; +} + + .bb-sign-body img { + width: 32px; + height: auto; + margin: 0; + margin-block-end: 1rem; + } + + .bb-sign-body h3 { + font-size: 20px; + font-weight: 400; + } + +.bb-sign-callout { + padding: 1rem; + border: 1px solid var(--bs-border-color); + border-radius: var(--bs-border-radius); + text-align: center; +} diff --git a/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/TwoFactorApp.razor b/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/TwoFactorApp.razor new file mode 100644 index 00000000000..ad5c3b06175 --- /dev/null +++ b/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/TwoFactorApp.razor @@ -0,0 +1,48 @@ +@page "/tutorials/mfa/two-factor/app" +@inject IOptionsMonitor WebsiteOption + +
+
+ +

Two-factor authentication

+
+
+
+ +

Authentication code

+
+
+ +
+ +
+ Open your two-factor authenticator (TOTP) app or browser extension to view your authentication code. +
+
+
+ +@code { + [Inject, NotNull] + private ITotpService? TotpService { get; set; } + + [Inject, NotNull] + private ToastService? ToastService { get; set; } + + private string _code = ""; + + private async Task OnVerify() + { + if (string.IsNullOrEmpty(_code)) + { + return; + } + if (TotpService.Verify(_code)) + { + await ToastService.Success("Sign In", "Login success. redirect home Url"); + } + else + { + await ToastService.Error("Sign In", "Login failed."); + } + } +} diff --git a/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/TwoFactorApp.razor.css b/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/TwoFactorApp.razor.css new file mode 100644 index 00000000000..19bf25fc0f6 --- /dev/null +++ b/src/BootstrapBlazor.Server/Components/Samples/Tutorials/MFA/TwoFactorApp.razor.css @@ -0,0 +1,42 @@ +.bb-sign { + margin: 0 auto; + width: 406px; + padding: 0 1rem; +} + + .bb-sign img { + background-color: var(--bb-primary-color); + border-radius: 50%; + margin-block: 2rem; + } + + .bb-sign h1 { + font-size: 24px; + font-weight: 300; + letter-spacing: -0.5px; + margin-block-end: 1rem; + } + +.bb-sign-body { + background-color: #f6f8fa; + border: 1px solid var(--bs-border-color); + border-radius: var(--bs-border-radius); + padding: 1rem; +} + + .bb-sign-body img { + width: 32px; + height: auto; + margin: 0; + margin-block-end: 1rem; + } + + .bb-sign-body h3 { + font-size: 20px; + font-weight: 400; + } + +::deep .bb-opt-input .bb-opt-item { + --bb-opt-item-width: 50px; + --bb-opt-font-size: 2em; +} diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index a3aed59c1b9..8e78d65fdcc 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -23,7 +23,8 @@ "DrawingSummary": "Drawing", "AdminSummary": "Admin", "OnlineSheet": "UniverSheet", - "MemorialMode": "Memorial" + "MemorialMode": "Memorial", + "MFA": "MFA" }, "BootstrapBlazor.Server.Components.Components.Pre": { "LoadingText": "Loading ...", diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index a8881f92588..ae2eac1a317 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -23,7 +23,8 @@ "DrawingSummary": "画图 Drawing", "AdminSummary": "中台 Admin", "OnlineSheet": "在线表格 UniverSheet", - "MemorialMode": "追悼模式" + "MemorialMode": "追悼模式", + "MFA": "多因子认证 MFA" }, "BootstrapBlazor.Server.Components.Components.Pre": { "LoadingText": "正在加载 ...",