Base Url Support (#642)

* Added base url config

* UI side is not working

* Working base url more

* Attempt to get UI to work with base url

* Implemented the ability to set the Base URL for the app

* Hooked in Base URL as a managed setting

* Ensure we always start with / for base url

* Removed default base href from debug builds. Cleaned up an issue with base url migration.

* Fixed an issue with our BaseURL migration
This commit is contained in:
Joseph Milazzo 2021-10-06 05:42:02 -07:00 committed by GitHub
parent 56239ee0a7
commit 27aaa040c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 126 additions and 10 deletions

View file

@ -7,4 +7,5 @@ export interface ServerSettings {
allowStatCollection: boolean;
enableOpds: boolean;
enableAuthentication: boolean;
baseUrl: string;
}

View file

@ -2,7 +2,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { ToastrService } from 'ngx-toastr';
import { Subject } from 'rxjs';
import { take, takeUntil, takeWhile } from 'rxjs/operators';
import { take, takeUntil } from 'rxjs/operators';
import { ConfirmService } from 'src/app/shared/confirm.service';
import { ScanLibraryProgressEvent } from 'src/app/_models/events/scan-library-progress-event';
import { Library, LibraryType } from 'src/app/_models/library';

View file

@ -1,6 +1,6 @@
<div class="container-fluid">
<form [formGroup]="settingsForm" *ngIf="serverSettings !== undefined">
<p class="text-warning pt-2">Port and Logging Level require a manual restart of Kavita to take effect.</p>
<p class="text-warning pt-2">Port, Base Url, and Logging Level require a manual restart of Kavita to take effect.</p>
<div class="form-group">
<label for="settings-cachedir">Cache Directory</label>&nbsp;<i class="fa fa-info-circle" placement="right" [ngbTooltip]="cacheDirectoryTooltip" role="button" tabindex="0"></i>
<ng-template #cacheDirectoryTooltip>Where the server place temporary files when reading. This will be cleaned up on a regular basis.</ng-template>
@ -8,6 +8,13 @@
<input readonly id="settings-cachedir" aria-describedby="settings-cachedir-help" class="form-control" formControlName="cacheDirectory" type="text">
</div>
<div class="form-group">
<label for="settings-baseurl">Base Url</label>&nbsp;<i class="fa fa-info-circle" placement="right" [ngbTooltip]="baseUrlTooltip" role="button" tabindex="0"></i>
<ng-template #baseUrlTooltip>Use this if you want to host Kavita on a base url ie) yourdomain.com/kavita</ng-template>
<span class="sr-only" id="settings-baseurl-help">Use this if you want to host Kavita on a base url ie) yourdomain.com/kavita</span>
<input id="settings-baseurl" aria-describedby="settings-baseurl-help" class="form-control" formControlName="baseUrl" type="text">
</div>
<div class="form-group">
<label for="settings-port">Port</label>&nbsp;<i class="fa fa-info-circle" placement="right" [ngbTooltip]="portTooltip" role="button" tabindex="0"></i>
<ng-template #portTooltip>Port the server listens on. This is fixed if you are running on Docker. Requires restart to take effect.</ng-template>

View file

@ -37,6 +37,7 @@ export class ManageSettingsComponent implements OnInit {
this.settingsForm.addControl('allowStatCollection', new FormControl(this.serverSettings.allowStatCollection, [Validators.required]));
this.settingsForm.addControl('enableOpds', new FormControl(this.serverSettings.enableOpds, [Validators.required]));
this.settingsForm.addControl('enableAuthentication', new FormControl(this.serverSettings.enableAuthentication, [Validators.required]));
this.settingsForm.addControl('baseUrl', new FormControl(this.serverSettings.baseUrl, [Validators.required]));
});
}
@ -49,6 +50,7 @@ export class ManageSettingsComponent implements OnInit {
this.settingsForm.get('allowStatCollection')?.setValue(this.serverSettings.allowStatCollection);
this.settingsForm.get('enableOpds')?.setValue(this.serverSettings.enableOpds);
this.settingsForm.get('enableAuthentication')?.setValue(this.serverSettings.enableAuthentication);
this.settingsForm.get('baseUrl')?.setValue(this.serverSettings.baseUrl);
}
async saveSettings() {

View file

@ -1,11 +1,12 @@
import { BrowserModule, Title } from '@angular/platform-browser';
import { APP_INITIALIZER, ErrorHandler, NgModule } from '@angular/core';
import { APP_BASE_HREF } from '@angular/common';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpClient, HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { NgbCollapseModule, NgbDropdownModule, NgbNavModule, NgbPaginationModule, NgbRatingModule } from '@ng-bootstrap/ng-bootstrap';
import { NavHeaderComponent } from './nav-header/nav-header.component';
import { JwtInterceptor } from './_interceptors/jwt.interceptor';
@ -24,12 +25,12 @@ import { CarouselModule } from './carousel/carousel.module';
import { PersonBadgeComponent } from './person-badge/person-badge.component';
import { TypeaheadModule } from './typeahead/typeahead.module';
import { RecentlyAddedComponent } from './recently-added/recently-added.component';
import { InProgressComponent } from './in-progress/in-progress.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { CardsModule } from './cards/cards.module';
import { CollectionsModule } from './collections/collections.module';
import { InProgressComponent } from './in-progress/in-progress.component';
import { SAVER, getSaver } from './shared/_providers/saver.provider';
import { ReadingListModule } from './reading-list/reading-list.module';
import { DashboardComponent } from './dashboard/dashboard.component';
import { SAVER, getSaver } from './shared/_providers/saver.provider';
@NgModule({
declarations: [
@ -81,7 +82,8 @@ import { DashboardComponent } from './dashboard/dashboard.component';
{provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true},
Title,
{provide: SAVER, useFactory: getSaver}
{provide: SAVER, useFactory: getSaver},
{ provide: APP_BASE_HREF, useValue: window['_app_base' as keyof Window] || '/' },
],
entryComponents: [],
bootstrap: [AppComponent]

View file

@ -40,4 +40,9 @@
<app-root></app-root>
<noscript>Please enable JavaScript to continue using this application.</noscript>
</body>
<script>
(function() {
window['_app_base'] = '/' + window.location.pathname.split('/')[1];
})();
</script>
</html>