mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-07-31 14:33:50 -04:00
Moved BaseUrl from appsettings.json to Database and fixed an issue in UI for setting base url based on a hack, rather than asking backend for it. (#644)
This commit is contained in:
parent
e8e838d125
commit
977e364d5a
@ -33,6 +33,14 @@ namespace API.Controllers
|
|||||||
_accountService = accountService;
|
_accountService = accountService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpGet("base-url")]
|
||||||
|
public async Task<ActionResult<string>> GetBaseUrl()
|
||||||
|
{
|
||||||
|
var settingsDto = await _unitOfWork.SettingsRepository.GetSettingsDtoAsync();
|
||||||
|
return Ok(settingsDto.BaseUrl);
|
||||||
|
}
|
||||||
|
|
||||||
[Authorize(Policy = "RequireAdminRole")]
|
[Authorize(Policy = "RequireAdminRole")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<ActionResult<ServerSettingDto>> GetSettings()
|
public async Task<ActionResult<ServerSettingDto>> GetSettings()
|
||||||
@ -91,8 +99,6 @@ namespace API.Controllers
|
|||||||
? $"/{updateSettingsDto.BaseUrl}"
|
? $"/{updateSettingsDto.BaseUrl}"
|
||||||
: updateSettingsDto.BaseUrl;
|
: updateSettingsDto.BaseUrl;
|
||||||
setting.Value = path;
|
setting.Value = path;
|
||||||
// BaseUrl is managed in appSetting.json
|
|
||||||
Configuration.BaseUrl = updateSettingsDto.BaseUrl;
|
|
||||||
_unitOfWork.SettingsRepository.Update(setting);
|
_unitOfWork.SettingsRepository.Update(setting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool EnableAuthentication { get; set; }
|
public bool EnableAuthentication { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base Url for the kavita. Defaults to "/". Managed in appsettings.json.Requires restart to take effect.
|
/// Base Url for the kavita. Requires restart to take effect.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string BaseUrl { get; set; } = "/";
|
public string BaseUrl { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,15 @@ namespace API.Data.Repositories
|
|||||||
return _mapper.Map<ServerSettingDto>(settings);
|
return _mapper.Map<ServerSettingDto>(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServerSettingDto GetSettingsDto()
|
||||||
|
{
|
||||||
|
var settings = _context.ServerSetting
|
||||||
|
.Select(x => x)
|
||||||
|
.AsNoTracking()
|
||||||
|
.ToList();
|
||||||
|
return _mapper.Map<ServerSettingDto>(settings);
|
||||||
|
}
|
||||||
|
|
||||||
public Task<ServerSetting> GetSettingAsync(ServerSettingKey key)
|
public Task<ServerSetting> GetSettingAsync(ServerSettingKey key)
|
||||||
{
|
{
|
||||||
return _context.ServerSetting.SingleOrDefaultAsync(x => x.Key == key);
|
return _context.ServerSetting.SingleOrDefaultAsync(x => x.Key == key);
|
||||||
|
@ -50,7 +50,7 @@ namespace API.Data
|
|||||||
new () {Key = ServerSettingKey.AllowStatCollection, Value = "true"},
|
new () {Key = ServerSettingKey.AllowStatCollection, Value = "true"},
|
||||||
new () {Key = ServerSettingKey.EnableOpds, Value = "false"},
|
new () {Key = ServerSettingKey.EnableOpds, Value = "false"},
|
||||||
new () {Key = ServerSettingKey.EnableAuthentication, Value = "true"},
|
new () {Key = ServerSettingKey.EnableAuthentication, Value = "true"},
|
||||||
new () {Key = ServerSettingKey.BaseUrl, Value = ""},// Not used from DB, but DB is sync with appSettings.json
|
new () {Key = ServerSettingKey.BaseUrl, Value = "/"},
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var defaultSetting in defaultSettings)
|
foreach (var defaultSetting in defaultSettings)
|
||||||
@ -64,20 +64,11 @@ namespace API.Data
|
|||||||
|
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(Configuration.BaseUrl))
|
|
||||||
{
|
|
||||||
Configuration.BaseUrl = "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Port and LoggingLevel are managed in appSettings.json. Update the DB values to match
|
// Port and LoggingLevel are managed in appSettings.json. Update the DB values to match
|
||||||
context.ServerSetting.First(s => s.Key == ServerSettingKey.Port).Value =
|
context.ServerSetting.First(s => s.Key == ServerSettingKey.Port).Value =
|
||||||
Configuration.Port + string.Empty;
|
Configuration.Port + string.Empty;
|
||||||
context.ServerSetting.First(s => s.Key == ServerSettingKey.LoggingLevel).Value =
|
context.ServerSetting.First(s => s.Key == ServerSettingKey.LoggingLevel).Value =
|
||||||
Configuration.LogLevel + string.Empty;
|
Configuration.LogLevel + string.Empty;
|
||||||
context.ServerSetting.First(s => s.Key == ServerSettingKey.BaseUrl).Value =
|
|
||||||
Configuration.BaseUrl;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ namespace API.Interfaces.Repositories
|
|||||||
{
|
{
|
||||||
void Update(ServerSetting settings);
|
void Update(ServerSetting settings);
|
||||||
Task<ServerSettingDto> GetSettingsDtoAsync();
|
Task<ServerSettingDto> GetSettingsDtoAsync();
|
||||||
|
ServerSettingDto GetSettingsDto();
|
||||||
Task<ServerSetting> GetSettingAsync(ServerSettingKey key);
|
Task<ServerSetting> GetSettingAsync(ServerSettingKey key);
|
||||||
Task<IEnumerable<ServerSetting>> GetSettingsAsync();
|
Task<IEnumerable<ServerSetting>> GetSettingsAsync();
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ using System.Linq;
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using API.Extensions;
|
using API.Extensions;
|
||||||
|
using API.Interfaces;
|
||||||
|
using API.Interfaces.Repositories;
|
||||||
using API.Middleware;
|
using API.Middleware;
|
||||||
using API.Services;
|
using API.Services;
|
||||||
using API.Services.HostedServices;
|
using API.Services.HostedServices;
|
||||||
@ -121,7 +123,7 @@ namespace API
|
|||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
public void Configure(IApplicationBuilder app, IBackgroundJobClient backgroundJobs, IWebHostEnvironment env,
|
public void Configure(IApplicationBuilder app, IBackgroundJobClient backgroundJobs, IWebHostEnvironment env,
|
||||||
IHostApplicationLifetime applicationLifetime)
|
IHostApplicationLifetime applicationLifetime, IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
app.UseMiddleware<ExceptionMiddleware>();
|
app.UseMiddleware<ExceptionMiddleware>();
|
||||||
|
|
||||||
@ -160,7 +162,9 @@ namespace API
|
|||||||
|
|
||||||
app.UseDefaultFiles();
|
app.UseDefaultFiles();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Configuration.BaseUrl))
|
var service = serviceProvider.GetRequiredService<IUnitOfWork>();
|
||||||
|
var settings = service.SettingsRepository.GetSettingsDto();
|
||||||
|
if (!string.IsNullOrEmpty(settings.BaseUrl) && !settings.BaseUrl.Equals("/"))
|
||||||
{
|
{
|
||||||
var path = !Configuration.BaseUrl.StartsWith("/")
|
var path = !Configuration.BaseUrl.StartsWith("/")
|
||||||
? $"/{Configuration.BaseUrl}"
|
? $"/{Configuration.BaseUrl}"
|
||||||
|
10
UI/Web/src/app/_models/config-data.ts
Normal file
10
UI/Web/src/app/_models/config-data.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* This is for base url only. Not to be used my applicaiton, only loading and bootstrapping app
|
||||||
|
*/
|
||||||
|
export class ConfigData {
|
||||||
|
baseUrl: string = '/';
|
||||||
|
|
||||||
|
constructor(baseUrl: string) {
|
||||||
|
this.baseUrl = baseUrl;
|
||||||
|
}
|
||||||
|
}
|
@ -31,6 +31,8 @@ import { CardsModule } from './cards/cards.module';
|
|||||||
import { CollectionsModule } from './collections/collections.module';
|
import { CollectionsModule } from './collections/collections.module';
|
||||||
import { ReadingListModule } from './reading-list/reading-list.module';
|
import { ReadingListModule } from './reading-list/reading-list.module';
|
||||||
import { SAVER, getSaver } from './shared/_providers/saver.provider';
|
import { SAVER, getSaver } from './shared/_providers/saver.provider';
|
||||||
|
import { ConfigData } from './_models/config-data';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -83,7 +85,7 @@ import { SAVER, getSaver } from './shared/_providers/saver.provider';
|
|||||||
{provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true},
|
{provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true},
|
||||||
Title,
|
Title,
|
||||||
{provide: SAVER, useFactory: getSaver},
|
{provide: SAVER, useFactory: getSaver},
|
||||||
{ provide: APP_BASE_HREF, useValue: window['_app_base' as keyof Window] || '/' },
|
{ provide: APP_BASE_HREF, useFactory: (config: ConfigData) => config.baseUrl, deps: [ConfigData] },
|
||||||
],
|
],
|
||||||
entryComponents: [],
|
entryComponents: [],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
|
@ -40,9 +40,4 @@
|
|||||||
<app-root></app-root>
|
<app-root></app-root>
|
||||||
<noscript>Please enable JavaScript to continue using this application.</noscript>
|
<noscript>Please enable JavaScript to continue using this application.</noscript>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
|
||||||
(function() {
|
|
||||||
window['_app_base'] = '/' + window.location.pathname.split('/')[1];
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -2,13 +2,21 @@ import { enableProdMode } from '@angular/core';
|
|||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
import { AppModule } from './app/app.module';
|
import { AppModule } from './app/app.module';
|
||||||
|
import { ConfigData } from './app/_models/config-data';
|
||||||
import { environment } from './environments/environment';
|
import { environment } from './environments/environment';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (environment.production) {
|
if (environment.production) {
|
||||||
enableProdMode();
|
enableProdMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
function fetchConfig(): Promise<ConfigData> {
|
||||||
.catch(err => console.error(err));
|
return fetch(environment.apiUrl + 'settings/base-url')
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(response => new ConfigData(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchConfig().then(config => {
|
||||||
|
platformBrowserDynamic([ { provide: ConfigData, useValue: config } ])
|
||||||
|
.bootstrapModule(AppModule)
|
||||||
|
.catch(err => console.error(err));
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user