diff --git a/booklore-api/src/main/java/com/adityachandel/booklore/config/security/SecurityConfig.java b/booklore-api/src/main/java/com/adityachandel/booklore/config/security/SecurityConfig.java
index 2a32ad0e7..1bfae4a50 100644
--- a/booklore-api/src/main/java/com/adityachandel/booklore/config/security/SecurityConfig.java
+++ b/booklore-api/src/main/java/com/adityachandel/booklore/config/security/SecurityConfig.java
@@ -5,7 +5,7 @@ import com.adityachandel.booklore.config.security.filter.CoverJwtFilter;
import com.adityachandel.booklore.config.security.filter.DualJwtAuthenticationFilter;
import com.adityachandel.booklore.config.security.filter.KoboAuthFilter;
import com.adityachandel.booklore.config.security.filter.KoreaderAuthFilter;
-import com.adityachandel.booklore.config.security.service.CustomOpdsUserDetailsService;
+import com.adityachandel.booklore.config.security.service.OpdsUserDetailsService;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -37,7 +37,7 @@ import jakarta.servlet.http.HttpServletResponse;
@Configuration
public class SecurityConfig {
- private final CustomOpdsUserDetailsService customOpdsUserDetailsService;
+ private final OpdsUserDetailsService opdsUserDetailsService;
private final DualJwtAuthenticationFilter dualJwtAuthenticationFilter;
private final AppProperties appProperties;
@@ -157,7 +157,7 @@ public class SecurityConfig {
@Bean
public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
- provider.setUserDetailsService(customOpdsUserDetailsService);
+ provider.setUserDetailsService(opdsUserDetailsService);
provider.setPasswordEncoder(passwordEncoder());
return provider;
}
diff --git a/booklore-api/src/main/java/com/adityachandel/booklore/config/security/SecurityUtil.java b/booklore-api/src/main/java/com/adityachandel/booklore/config/security/SecurityUtil.java
index 697aa9639..85d0a6793 100644
--- a/booklore-api/src/main/java/com/adityachandel/booklore/config/security/SecurityUtil.java
+++ b/booklore-api/src/main/java/com/adityachandel/booklore/config/security/SecurityUtil.java
@@ -69,6 +69,11 @@ public class SecurityUtil {
var user = getCurrentUser();
return user != null && user.getPermissions().isCanDeleteBook();
}
+ public boolean canAccessOpds() {
+ var user = getCurrentUser();
+ return user != null && user.getPermissions().isCanAccessOpds();
+ }
+
public boolean canViewUserProfile(Long userId) {
var user = getCurrentUser();
diff --git a/booklore-api/src/main/java/com/adityachandel/booklore/config/security/service/AuthenticationService.java b/booklore-api/src/main/java/com/adityachandel/booklore/config/security/service/AuthenticationService.java
index c17c9264b..9989b0a39 100644
--- a/booklore-api/src/main/java/com/adityachandel/booklore/config/security/service/AuthenticationService.java
+++ b/booklore-api/src/main/java/com/adityachandel/booklore/config/security/service/AuthenticationService.java
@@ -2,11 +2,14 @@ package com.adityachandel.booklore.config.security.service;
import com.adityachandel.booklore.config.AppProperties;
import com.adityachandel.booklore.config.security.JwtUtils;
+import com.adityachandel.booklore.config.security.userdetails.OpdsUserDetails;
import com.adityachandel.booklore.exception.ApiError;
import com.adityachandel.booklore.model.dto.BookLoreUser;
import com.adityachandel.booklore.model.dto.request.UserLoginRequest;
import com.adityachandel.booklore.model.entity.BookLoreUserEntity;
+import com.adityachandel.booklore.model.entity.OpdsUserEntity;
import com.adityachandel.booklore.model.entity.RefreshTokenEntity;
+import com.adityachandel.booklore.repository.OpdsUserRepository;
import com.adityachandel.booklore.repository.RefreshTokenRepository;
import com.adityachandel.booklore.repository.UserRepository;
import com.adityachandel.booklore.service.user.DefaultSettingInitializer;
@@ -16,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@@ -35,6 +39,7 @@ public class AuthenticationService {
private final PasswordEncoder passwordEncoder;
private final JwtUtils jwtUtils;
private final DefaultSettingInitializer defaultSettingInitializer;
+ private final OpdsUserRepository opdsUserRepository;
public BookLoreUser getAuthenticatedUser() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
@@ -46,6 +51,15 @@ public class AuthenticationService {
throw new IllegalStateException("Authenticated principal is not of type BookLoreUser");
}
+
+ public OpdsUserDetails getOpdsUser() {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ if (authentication != null && authentication.getPrincipal() instanceof OpdsUserDetails opdsUser) {
+ return opdsUser;
+ }
+ throw new IllegalStateException("No OPDS user authenticated");
+ }
+
public ResponseEntity
+
+
+
+
+
+ Deprecated: OPDS (v1) support will be removed in a future release.
+ Please migrate to OPDS v2 for continued support and improvements.
+
+
+
+
@@ -53,7 +64,7 @@
-
+
| Username |
diff --git a/booklore-ui/src/app/settings/global-preferences/opds-settings/opds-settings.component.scss b/booklore-ui/src/app/settings/opds-settings/opds-settings.component.scss
similarity index 100%
rename from booklore-ui/src/app/settings/global-preferences/opds-settings/opds-settings.component.scss
rename to booklore-ui/src/app/settings/opds-settings/opds-settings.component.scss
diff --git a/booklore-ui/src/app/settings/global-preferences/opds-settings/opds-settings.component.ts b/booklore-ui/src/app/settings/opds-settings/opds-settings.component.ts
similarity index 96%
rename from booklore-ui/src/app/settings/global-preferences/opds-settings/opds-settings.component.ts
rename to booklore-ui/src/app/settings/opds-settings/opds-settings.component.ts
index 67c1bb445..9031e2ce8 100644
--- a/booklore-ui/src/app/settings/global-preferences/opds-settings/opds-settings.component.ts
+++ b/booklore-ui/src/app/settings/opds-settings/opds-settings.component.ts
@@ -10,10 +10,10 @@ import {MessageService} from 'primeng/api';
import {filter, take} from 'rxjs/operators';
import {OpdsUser, OpdsUserService} from './opds-user.service';
-import {AppSettingsService} from '../../../core/service/app-settings.service';
-import {AppSettingKey, AppSettings} from '../../../core/model/app-settings.model';
+import {AppSettingsService} from '../../core/service/app-settings.service';
+import {AppSettingKey, AppSettings} from '../../core/model/app-settings.model';
import {Password} from 'primeng/password';
-import {API_CONFIG} from '../../../config/api-config';
+import {API_CONFIG} from '../../config/api-config';
import {ToggleSwitch} from 'primeng/toggleswitch';
@Component({
diff --git a/booklore-ui/src/app/settings/global-preferences/opds-settings/opds-user.service.ts b/booklore-ui/src/app/settings/opds-settings/opds-user.service.ts
similarity index 94%
rename from booklore-ui/src/app/settings/global-preferences/opds-settings/opds-user.service.ts
rename to booklore-ui/src/app/settings/opds-settings/opds-user.service.ts
index d66cdb8c5..83a52eba2 100644
--- a/booklore-ui/src/app/settings/global-preferences/opds-settings/opds-user.service.ts
+++ b/booklore-ui/src/app/settings/opds-settings/opds-user.service.ts
@@ -1,5 +1,5 @@
import {inject, Injectable} from '@angular/core';
-import {API_CONFIG} from '../../../config/api-config';
+import {API_CONFIG} from '../../config/api-config';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs';
diff --git a/booklore-ui/src/app/settings/settings.component.html b/booklore-ui/src/app/settings/settings.component.html
index e49c1da1c..b8520f465 100644
--- a/booklore-ui/src/app/settings/settings.component.html
+++ b/booklore-ui/src/app/settings/settings.component.html
@@ -29,9 +29,12 @@
Authentication
- OPDS
+ OPDS (Deprecated)
}
+
+ OPDS V2
+
Devices
@@ -66,6 +69,9 @@
}
+
+
+
diff --git a/booklore-ui/src/app/settings/settings.component.ts b/booklore-ui/src/app/settings/settings.component.ts
index 491d0a4e2..4201814ff 100644
--- a/booklore-ui/src/app/settings/settings.component.ts
+++ b/booklore-ui/src/app/settings/settings.component.ts
@@ -11,9 +11,10 @@ import {AuthenticationSettingsComponent} from '../core/security/oauth2-managemen
import {ViewPreferencesParentComponent} from './view-preferences-parent/view-preferences-parent.component';
import {ReaderPreferences} from './reader-preferences/reader-preferences.component';
import {MetadataSettingsComponent} from './metadata-settings-component/metadata-settings-component';
-import {OpdsSettingsComponent} from './global-preferences/opds-settings/opds-settings.component';
+import {OpdsSettingsComponent} from './opds-settings/opds-settings.component';
import {DeviceSettingsComponent} from './device-settings-component/device-settings-component';
import {FileNamingPatternComponent} from './file-naming-pattern/file-naming-pattern.component';
+import {OpdsSettingsV2} from './opds-settings-v2/opds-settings-v2';
export enum SettingsTab {
ReaderSettings = 'reader',
@@ -25,6 +26,7 @@ export enum SettingsTab {
MetadataSettings = 'metadata',
ApplicationSettings = 'application',
AuthenticationSettings = 'authentication',
+ OpdsV2 = 'opds-v2',
Opds = 'opds'
}
@@ -46,7 +48,8 @@ export enum SettingsTab {
MetadataSettingsComponent,
OpdsSettingsComponent,
DeviceSettingsComponent,
- FileNamingPatternComponent
+ FileNamingPatternComponent,
+ OpdsSettingsV2
],
templateUrl: './settings.component.html',
styleUrl: './settings.component.scss'
diff --git a/booklore-ui/src/app/settings/user-management/create-user-dialog/create-user-dialog.component.html b/booklore-ui/src/app/settings/user-management/create-user-dialog/create-user-dialog.component.html
index 989e40250..4e03fd730 100644
--- a/booklore-ui/src/app/settings/user-management/create-user-dialog/create-user-dialog.component.html
+++ b/booklore-ui/src/app/settings/user-management/create-user-dialog/create-user-dialog.component.html
@@ -91,6 +91,11 @@
+
+
diff --git a/booklore-ui/src/app/settings/user-management/create-user-dialog/create-user-dialog.component.ts b/booklore-ui/src/app/settings/user-management/create-user-dialog/create-user-dialog.component.ts
index 9ebcb84a6..1fb297f62 100644
--- a/booklore-ui/src/app/settings/user-management/create-user-dialog/create-user-dialog.component.ts
+++ b/booklore-ui/src/app/settings/user-management/create-user-dialog/create-user-dialog.component.ts
@@ -50,6 +50,7 @@ export class CreateUserDialogComponent implements OnInit {
permissionManipulateLibrary: [false],
permissionEmailBook: [false],
permissionDeleteBook: [false],
+ permissionAccessOpds: [false],
permissionSyncKoreader: [false],
permissionSyncKobo: [false],
permissionAdmin: [false],
diff --git a/booklore-ui/src/app/settings/user-management/user-management.component.html b/booklore-ui/src/app/settings/user-management/user-management.component.html
index 7ff6a4d49..cfdf054ed 100644
--- a/booklore-ui/src/app/settings/user-management/user-management.component.html
+++ b/booklore-ui/src/app/settings/user-management/user-management.component.html
@@ -22,6 +22,7 @@
Manage Library |
Email Books |
Delete Books |
+
Access OPDS |
KOReader Sync |
Kobo Sync |
Edit |
@@ -127,6 +128,14 @@
}
+
+ @if (user.isEditing) {
+
+ }
+ @if (!user.isEditing) {
+
+ }
+ |
@if (user.isEditing) {
diff --git a/booklore-ui/src/app/settings/user-management/user.service.ts b/booklore-ui/src/app/settings/user-management/user.service.ts
index 9fa06f960..e3c276f2b 100644
--- a/booklore-ui/src/app/settings/user-management/user.service.ts
+++ b/booklore-ui/src/app/settings/user-management/user.service.ts
@@ -107,6 +107,7 @@ export interface User {
canManipulateLibrary: boolean;
canSyncKoReader: boolean;
canSyncKobo: boolean;
+ canAccessOpds: boolean;
};
userSettings: UserSettings;
provisioningMethod?: 'LOCAL' | 'OIDC' | 'REMOTE';
diff --git a/booklore-ui/src/app/settings/global-preferences/user-profile-dialog/user-profile-dialog.component.html b/booklore-ui/src/app/settings/user-profile-dialog/user-profile-dialog.component.html
similarity index 100%
rename from booklore-ui/src/app/settings/global-preferences/user-profile-dialog/user-profile-dialog.component.html
rename to booklore-ui/src/app/settings/user-profile-dialog/user-profile-dialog.component.html
diff --git a/booklore-ui/src/app/settings/global-preferences/user-profile-dialog/user-profile-dialog.component.scss b/booklore-ui/src/app/settings/user-profile-dialog/user-profile-dialog.component.scss
similarity index 100%
rename from booklore-ui/src/app/settings/global-preferences/user-profile-dialog/user-profile-dialog.component.scss
rename to booklore-ui/src/app/settings/user-profile-dialog/user-profile-dialog.component.scss
diff --git a/booklore-ui/src/app/settings/global-preferences/user-profile-dialog/user-profile-dialog.component.ts b/booklore-ui/src/app/settings/user-profile-dialog/user-profile-dialog.component.ts
similarity index 98%
rename from booklore-ui/src/app/settings/global-preferences/user-profile-dialog/user-profile-dialog.component.ts
rename to booklore-ui/src/app/settings/user-profile-dialog/user-profile-dialog.component.ts
index 074ec4809..c7c594ef0 100644
--- a/booklore-ui/src/app/settings/global-preferences/user-profile-dialog/user-profile-dialog.component.ts
+++ b/booklore-ui/src/app/settings/user-profile-dialog/user-profile-dialog.component.ts
@@ -5,7 +5,7 @@ import {FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators} fr
import {InputText} from 'primeng/inputtext';
import {Password} from 'primeng/password';
-import {User, UserService} from '../../user-management/user.service';
+import {User, UserService} from '../user-management/user.service';
import {MessageService} from 'primeng/api';
import {Subject} from 'rxjs';
import {Message} from 'primeng/message';
|