333 lines
12 KiB
Plaintext
333 lines
12 KiB
Plaintext
@namespace Oqtane.Installer
|
|
@using Oqtane.Interfaces
|
|
@inject NavigationManager NavigationManager
|
|
@inject IInstallationService InstallationService
|
|
@inject ISiteService SiteService
|
|
@inject IUserService UserService
|
|
@inject IDatabaseService DatabaseService
|
|
@inject ISiteTemplateService SiteTemplateService
|
|
@inject IJSRuntime JSRuntime
|
|
@inject IStringLocalizer<Installer> Localizer
|
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
|
@inject SiteState SiteState
|
|
|
|
<div class="container">
|
|
<div class="row">
|
|
<div class="mx-auto text-center">
|
|
<img src="oqtane-black.png" />
|
|
<div style="font-weight: bold">@SharedLocalizer["Version"] @Constants.Version (.NET 8)</div>
|
|
</div>
|
|
</div>
|
|
<hr class="app-rule" />
|
|
<div class="row justify-content-center">
|
|
<div class="col text-center">
|
|
<h2>@Localizer["DatabaseConfig"]</h2><br />
|
|
<div class="container">
|
|
<div class="row mb-1 align-items-center">
|
|
<Label Class="col-sm-3" For="databasetype" HelpText="Select the type of database you wish to use" ResourceKey="DatabaseType">Database:</Label>
|
|
<div class="col-sm-9">
|
|
@if (_databases != null)
|
|
{
|
|
<div class="input-group">
|
|
<select id="databaseType" class="form-select" value="@_databaseName" @onchange="(e => DatabaseChanged(e))" required>
|
|
@foreach (var database in _databases)
|
|
{
|
|
<option value="@database.Name">@Localizer[@database.Name]</option>
|
|
}
|
|
</select>
|
|
@if (!_showConnectionString)
|
|
{
|
|
<button type="button" class="btn btn-secondary" @onclick="ToggleConnectionString">@Localizer["EnterConnectionString"]</button>
|
|
}
|
|
else
|
|
{
|
|
<button type="button" class="btn btn-secondary" @onclick="ToggleConnectionString">@Localizer["EnterConnectionParameters"]</button>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
@if (!_showConnectionString)
|
|
{
|
|
if (_databaseConfigType != null)
|
|
{
|
|
@DatabaseConfigComponent
|
|
}
|
|
}
|
|
else
|
|
{
|
|
<div class="row mb-1 align-items-center">
|
|
<Label Class="col-sm-3" For="connectionstring" HelpText="Enter a complete connection string including all parameters and delimiters" ResourceKey="ConnectionString">Settings:</Label>
|
|
<div class="col-sm-9">
|
|
<textarea id="connectionstring" class="form-control" @bind="@_connectionString" rows="3"></textarea>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
<div class="col text-center">
|
|
<h2>@Localizer["ApplicationAdmin"]</h2><br />
|
|
<div class="container">
|
|
<div class="row mb-1 align-items-center">
|
|
<Label Class="col-sm-3" For="username" HelpText="Provide a username for the primary user account" ResourceKey="Username">Username:</Label>
|
|
<div class="col-sm-9">
|
|
<input id="username" type="text" class="form-control" @bind="@_hostUsername" />
|
|
</div>
|
|
</div>
|
|
<div class="row mb-1 align-items-center">
|
|
<Label Class="col-sm-3" For="password" HelpText="Provide a password for the primary user account" ResourceKey="Password">Password:</Label>
|
|
<div class="col-sm-9">
|
|
<div class="input-group">
|
|
<input id="password" type="@_passwordType" class="form-control" @bind="@_hostPassword" autocomplete="new-password" />
|
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglePassword</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row mb-1 align-items-center">
|
|
<Label Class="col-sm-3" For="confirm" HelpText="Please confirm the password entered above by entering it again" ResourceKey="Confirm">Confirm:</Label>
|
|
<div class="col-sm-9">
|
|
<div class="input-group">
|
|
<input id="confirm" type="@_confirmPasswordType" class="form-control" @bind="@_confirmPassword" autocomplete="new-password" />
|
|
<button type="button" class="btn btn-secondary" @onclick="@ToggleConfirmPassword" tabindex="-1">@_toggleConfirmPassword</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row mb-1 align-items-center">
|
|
<Label Class="col-sm-3" For="email" HelpText="Provide the email address for the host user account" ResourceKey="Email">Email:</Label>
|
|
<div class="col-sm-9">
|
|
<input type="text" class="form-control" @bind="@_hostEmail" />
|
|
</div>
|
|
</div>
|
|
<div class="row mb-1 align-items-center">
|
|
<Label Class="col-sm-3" For="template" HelpText="Select a site template" ResourceKey="Template">Template:</Label>
|
|
<div class="col-sm-9">
|
|
@if (_templates != null)
|
|
{
|
|
<select id="template" class="form-select" @bind="@_template" required>
|
|
@foreach (var template in _templates)
|
|
{
|
|
<option value="@template.TypeName">@template.Name</option>
|
|
}
|
|
</select>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<hr class="app-rule" />
|
|
<div class="row">
|
|
<div class="mx-auto text-center">
|
|
<button type="button" class="btn btn-success" @onclick="Install">@Localizer["InstallNow"]</button><br /><br />
|
|
@if (!string.IsNullOrEmpty(_message))
|
|
{
|
|
<div class="alert alert-danger alert-dismissible fade show mb-3" role="alert">
|
|
@((MarkupString)_message)
|
|
<button type="button" class="btn-close" aria-label="Close" @onclick="DismissModal"></button>
|
|
</div>
|
|
}
|
|
</div>
|
|
<div class="app-progress-indicator" style="@_loadingDisplay"></div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="mx-auto text-center">
|
|
<input type="checkbox" @bind="@_register" /> @Localizer["Register"]
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@code {
|
|
private List<Database> _databases;
|
|
private string _databaseName;
|
|
private Type _databaseConfigType;
|
|
private object _databaseConfig;
|
|
private RenderFragment DatabaseConfigComponent { get; set; }
|
|
private bool _showConnectionString = false;
|
|
private string _connectionString = string.Empty;
|
|
|
|
private string _hostUsername = string.Empty;
|
|
private string _hostPassword = string.Empty;
|
|
private string _passwordType = "password";
|
|
private string _confirmPasswordType = "password";
|
|
private string _togglePassword = string.Empty;
|
|
private string _toggleConfirmPassword = string.Empty;
|
|
private string _confirmPassword = string.Empty;
|
|
private string _hostEmail = string.Empty;
|
|
private List<SiteTemplate> _templates;
|
|
private string _template = Constants.DefaultSiteTemplate;
|
|
private bool _register = true;
|
|
private string _message = string.Empty;
|
|
private string _loadingDisplay = "display: none;";
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
// include CSS
|
|
var content = $"<link rel=\"stylesheet\" href=\"{Constants.BootstrapStylesheetUrl}\" integrity=\"{Constants.BootstrapStylesheetIntegrity}\" crossorigin=\"anonymous\" type=\"text/css\"/>";
|
|
SiteState.AppendHeadContent(content);
|
|
|
|
_togglePassword = SharedLocalizer["ShowPassword"];
|
|
_toggleConfirmPassword = SharedLocalizer["ShowPassword"];
|
|
|
|
_databases = await DatabaseService.GetDatabasesAsync();
|
|
if (_databases.Exists(item => item.IsDefault))
|
|
{
|
|
_databaseName = _databases.Find(item => item.IsDefault).Name;
|
|
}
|
|
else
|
|
{
|
|
_databaseName = "LocalDB";
|
|
}
|
|
LoadDatabaseConfigComponent();
|
|
|
|
_templates = await SiteTemplateService.GetSiteTemplatesAsync();
|
|
}
|
|
|
|
private void DatabaseChanged(ChangeEventArgs eventArgs)
|
|
{
|
|
try
|
|
{
|
|
_databaseName = (string)eventArgs.Value;
|
|
_showConnectionString = false;
|
|
LoadDatabaseConfigComponent();
|
|
}
|
|
catch
|
|
{
|
|
_message = Localizer["Error.DbConfig.Load"];
|
|
}
|
|
}
|
|
|
|
private void LoadDatabaseConfigComponent()
|
|
{
|
|
var database = _databases.SingleOrDefault(d => d.Name == _databaseName);
|
|
if (database != null)
|
|
{
|
|
_databaseConfigType = Type.GetType(database.ControlType);
|
|
DatabaseConfigComponent = builder =>
|
|
{
|
|
builder.OpenComponent(0, _databaseConfigType);
|
|
builder.AddComponentReferenceCapture(1, inst => { _databaseConfig = Convert.ChangeType(inst, _databaseConfigType); });
|
|
builder.CloseComponent();
|
|
};
|
|
}
|
|
}
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
if (firstRender)
|
|
{
|
|
// include JavaScript
|
|
var interop = new Interop(JSRuntime);
|
|
await interop.IncludeScript("", Constants.BootstrapScriptUrl, Constants.BootstrapScriptIntegrity, "anonymous", "", "head");
|
|
}
|
|
}
|
|
|
|
private async Task Install()
|
|
{
|
|
var connectionString = String.Empty;
|
|
if (_showConnectionString)
|
|
{
|
|
connectionString = _connectionString;
|
|
}
|
|
else
|
|
{
|
|
if (_databaseConfig is IDatabaseConfigControl databaseConfigControl)
|
|
{
|
|
connectionString = databaseConfigControl.GetConnectionString();
|
|
}
|
|
}
|
|
|
|
if (connectionString != "" && !string.IsNullOrEmpty(_hostUsername) && !string.IsNullOrEmpty(_hostPassword) && _hostPassword == _confirmPassword && !string.IsNullOrEmpty(_hostEmail) && _hostEmail.Contains("@"))
|
|
{
|
|
if (await UserService.ValidatePasswordAsync(_hostPassword))
|
|
{
|
|
_loadingDisplay = "";
|
|
StateHasChanged();
|
|
|
|
Uri uri = new Uri(NavigationManager.Uri);
|
|
|
|
var database = _databases.SingleOrDefault(d => d.Name == _databaseName);
|
|
|
|
var config = new InstallConfig
|
|
{
|
|
DatabaseType = database.DBType,
|
|
ConnectionString = connectionString,
|
|
Aliases = uri.Authority,
|
|
HostUsername = _hostUsername,
|
|
HostPassword = _hostPassword,
|
|
HostEmail = _hostEmail,
|
|
HostName = _hostUsername,
|
|
TenantName = TenantNames.Master,
|
|
IsNewTenant = true,
|
|
SiteName = Constants.DefaultSite,
|
|
Register = _register,
|
|
SiteTemplate = _template,
|
|
RenderMode = RenderModes.Static,
|
|
Runtime = Runtimes.Server
|
|
};
|
|
|
|
var installation = await InstallationService.Install(config);
|
|
if (installation.Success)
|
|
{
|
|
NavigationManager.NavigateTo(uri.Scheme + "://" + uri.Authority, true);
|
|
}
|
|
else
|
|
{
|
|
_message = installation.Message;
|
|
_loadingDisplay = "display: none;";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_message = Localizer["Message.Password.Invalid"];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_message = Localizer["Message.Require.DbInfo"];
|
|
}
|
|
}
|
|
|
|
private void TogglePassword()
|
|
{
|
|
if (_passwordType == "password")
|
|
{
|
|
_passwordType = "text";
|
|
_togglePassword = SharedLocalizer["HidePassword"];
|
|
}
|
|
else
|
|
{
|
|
_passwordType = "password";
|
|
_togglePassword = SharedLocalizer["ShowPassword"];
|
|
}
|
|
}
|
|
|
|
private void ToggleConfirmPassword()
|
|
{
|
|
if (_confirmPasswordType == "password")
|
|
{
|
|
_confirmPasswordType = "text";
|
|
_toggleConfirmPassword = SharedLocalizer["HidePassword"];
|
|
}
|
|
else
|
|
{
|
|
_confirmPasswordType = "password";
|
|
_toggleConfirmPassword = SharedLocalizer["ShowPassword"];
|
|
}
|
|
}
|
|
|
|
private void ToggleConnectionString()
|
|
{
|
|
if (_databaseConfig is IDatabaseConfigControl databaseConfigControl)
|
|
{
|
|
_connectionString = databaseConfigControl.GetConnectionString();
|
|
}
|
|
_showConnectionString = !_showConnectionString;
|
|
}
|
|
|
|
private void DismissModal()
|
|
{
|
|
_message = "";
|
|
StateHasChanged();
|
|
}
|
|
}
|