mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-07-09 03:04:19 -04:00
Polish Round 2 (#2845)
This commit is contained in:
parent
c47fec4648
commit
5195f08c2f
31
API.Tests/Services/TokenServiceTests.cs
Normal file
31
API.Tests/Services/TokenServiceTests.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using API.Services;
|
||||
using Xunit;
|
||||
|
||||
namespace API.Tests.Services;
|
||||
|
||||
public class TokenServiceTests
|
||||
{
|
||||
[Fact]
|
||||
public void HasTokenExpired_OldToken()
|
||||
{
|
||||
// ValidTo: 1/1/1990
|
||||
var result = TokenService.HasTokenExpired("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjYzMzgzMDM5OX0.KM_cUKSaCJL3ts0Qim3ZHUeJT7yf-wKoLdKb0rx0VbU");
|
||||
|
||||
Assert.True(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasTokenExpired_ValidInFuture()
|
||||
{
|
||||
// ValidTo: 4/11/2200
|
||||
var result = TokenService.HasTokenExpired("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjcyNjg0ODYzOTl9.nZrN5USbUmMYDKwkPoMtEAhTeYTeaikgAeSzDPj5kZQ");
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasTokenExpired_NoToken()
|
||||
{
|
||||
var result = TokenService.HasTokenExpired("");
|
||||
Assert.True(result);
|
||||
}
|
||||
}
|
@ -30,9 +30,9 @@ public enum LibraryType
|
||||
[Description("Light Novel")]
|
||||
LightNovel = 4,
|
||||
/// <summary>
|
||||
/// Uses Comic regex for filename parsing, uses ComicVine type of Parsing. Will replace Comic type in future
|
||||
/// Uses Comic regex for filename parsing, uses Comic Vine type of Parsing. Will replace Comic type in future
|
||||
/// </summary>
|
||||
[Description("Comic (ComicVine)")]
|
||||
[Description("Comic (Comic Vine)")]
|
||||
ComicVine = 5,
|
||||
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ public class DeviceService : IDeviceService
|
||||
public async Task<bool> SendTo(IReadOnlyList<int> chapterIds, int deviceId)
|
||||
{
|
||||
var settings = await _unitOfWork.SettingsRepository.GetSettingsDtoAsync();
|
||||
if (!settings.IsEmailSetup())
|
||||
if (!settings.IsEmailSetupForSendToDevice())
|
||||
throw new KavitaException("send-to-kavita-email");
|
||||
|
||||
var device = await _unitOfWork.DeviceRepository.GetDeviceById(deviceId);
|
||||
@ -123,9 +123,16 @@ public class DeviceService : IDeviceService
|
||||
throw new KavitaException("send-to-size-limit");
|
||||
|
||||
|
||||
device.UpdateLastUsed();
|
||||
_unitOfWork.DeviceRepository.Update(device);
|
||||
await _unitOfWork.CommitAsync();
|
||||
try
|
||||
{
|
||||
device.UpdateLastUsed();
|
||||
_unitOfWork.DeviceRepository.Update(device);
|
||||
await _unitOfWork.CommitAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "There was an issue updating device last used time");
|
||||
}
|
||||
|
||||
var success = await _emailService.SendFilesToEmail(new SendToDto()
|
||||
{
|
||||
|
@ -126,7 +126,7 @@ public class ScrobblingService : IScrobblingService
|
||||
var users = await _unitOfWork.UserRepository.GetAllUsersAsync();
|
||||
foreach (var user in users)
|
||||
{
|
||||
if (string.IsNullOrEmpty(user.AniListAccessToken) || !_tokenService.HasTokenExpired(user.AniListAccessToken)) continue;
|
||||
if (string.IsNullOrEmpty(user.AniListAccessToken) || !TokenService.HasTokenExpired(user.AniListAccessToken)) continue;
|
||||
_logger.LogInformation("User {UserName}'s AniList token has expired! They need to regenerate it for scrobbling to work", user.UserName);
|
||||
await _eventHub.SendMessageToAsync(MessageFactory.ScrobblingKeyExpired,
|
||||
MessageFactory.ScrobblingKeyExpiredEvent(ScrobbleProvider.AniList), user.Id);
|
||||
@ -151,7 +151,7 @@ public class ScrobblingService : IScrobblingService
|
||||
private async Task<bool> HasTokenExpired(string token, ScrobbleProvider provider)
|
||||
{
|
||||
if (string.IsNullOrEmpty(token) ||
|
||||
!_tokenService.HasTokenExpired(token)) return false;
|
||||
!TokenService.HasTokenExpired(token)) return false;
|
||||
|
||||
var license = await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.LicenseKey);
|
||||
if (string.IsNullOrEmpty(license.Value)) return true;
|
||||
@ -778,7 +778,7 @@ public class ScrobblingService : IScrobblingService
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_tokenService.HasTokenExpired(evt.AppUser.AniListAccessToken))
|
||||
if (TokenService.HasTokenExpired(evt.AppUser.AniListAccessToken))
|
||||
{
|
||||
_unitOfWork.ScrobbleRepository.Attach(new ScrobbleError()
|
||||
{
|
||||
|
@ -561,7 +561,7 @@ public class ReadingListService : IReadingListService
|
||||
// How can we match properly with ComicVine library when year is part of the series unless we do this in 2 passes and see which has a better match
|
||||
|
||||
|
||||
if (!userSeries.Any())
|
||||
if (userSeries.Count == 0)
|
||||
{
|
||||
// Report that no series exist in the reading list
|
||||
importSummary.Results.Add(new CblBookResult
|
||||
|
@ -24,8 +24,7 @@ public interface ITokenService
|
||||
Task<string> CreateToken(AppUser user);
|
||||
Task<TokenRequestDto?> ValidateRefreshToken(TokenRequestDto request);
|
||||
Task<string> CreateRefreshToken(AppUser user);
|
||||
Task<string> GetJwtFromUser(AppUser user);
|
||||
bool HasTokenExpired(string token);
|
||||
Task<string?> GetJwtFromUser(AppUser user);
|
||||
}
|
||||
|
||||
|
||||
@ -135,18 +134,21 @@ public class TokenService : ITokenService
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> GetJwtFromUser(AppUser user)
|
||||
public async Task<string?> GetJwtFromUser(AppUser user)
|
||||
{
|
||||
var userClaims = await _userManager.GetClaimsAsync(user);
|
||||
var jwtClaim = userClaims.FirstOrDefault(claim => claim.Type == "jwt");
|
||||
return jwtClaim?.Value;
|
||||
}
|
||||
|
||||
public bool HasTokenExpired(string? token)
|
||||
public static bool HasTokenExpired(string? token)
|
||||
{
|
||||
if (string.IsNullOrEmpty(token)) return true;
|
||||
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
var tokenContent = tokenHandler.ReadJwtToken(token);
|
||||
return tokenContent.ValidTo >= DateTime.UtcNow;
|
||||
var validToUtc = tokenContent.ValidTo.ToUniversalTime();
|
||||
|
||||
return validToUtc < DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +70,7 @@ export class ManageEmailSettingsComponent implements OnInit {
|
||||
this.settingsForm.get('port')?.setValue(587);
|
||||
this.settingsForm.get('sizeLimit')?.setValue(26214400);
|
||||
this.settingsForm.get('enableSsl')?.setValue(true);
|
||||
this.settingsForm.markAsDirty();
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
|
||||
@ -78,6 +79,7 @@ export class ManageEmailSettingsComponent implements OnInit {
|
||||
this.settingsForm.get('port')?.setValue(587 );
|
||||
this.settingsForm.get('sizeLimit')?.setValue(1048576);
|
||||
this.settingsForm.get('enableSsl')?.setValue(true);
|
||||
this.settingsForm.markAsDirty();
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
<virtual-scroller [ngClass]="{'empty': items.length === 0 && !isLoading}" #scroll [items]="items" [bufferAmount]="bufferAmount" [parentScroll]="parentScroll">
|
||||
<div class="grid row g-0" #container>
|
||||
<!-- TODO: @for (item of scroll.viewPortItems; track trackByIdentity; let i = $index;) { works -->
|
||||
<div class="card col-auto mt-2 mb-2"
|
||||
(click)="tryToSaveJumpKey(item)"
|
||||
*ngFor="let item of scroll.viewPortItems; trackBy:trackByIdentity; index as i" id="jumpbar-index--{{i}}"
|
||||
|
@ -76,7 +76,7 @@ export class AllCollectionsComponent implements OnInit {
|
||||
jumpbarKeys: Array<JumpKey> = [];
|
||||
isAdmin$: Observable<boolean> = of(false);
|
||||
filterOpen: EventEmitter<boolean> = new EventEmitter();
|
||||
trackByIdentity = (index: number, item: UserCollection) => `${item.id}_${item.title}`;
|
||||
trackByIdentity = (index: number, item: UserCollection) => `${item.id}_${item.title}_${item.owner}_${item.promoted}`;
|
||||
user!: User;
|
||||
|
||||
@HostListener('document:keydown.shift', ['$event'])
|
||||
@ -146,13 +146,14 @@ export class AllCollectionsComponent implements OnInit {
|
||||
|
||||
switch (action.action) {
|
||||
case Action.Promote:
|
||||
this.collectionService.promoteMultipleCollections([collectionTag.id], true).subscribe();
|
||||
this.collectionService.promoteMultipleCollections([collectionTag.id], true).subscribe(_ => this.loadPage());
|
||||
break;
|
||||
case Action.UnPromote:
|
||||
this.collectionService.promoteMultipleCollections([collectionTag.id], false).subscribe();
|
||||
this.collectionService.promoteMultipleCollections([collectionTag.id], false).subscribe(_ => this.loadPage());
|
||||
break;
|
||||
case(Action.Delete):
|
||||
this.collectionService.deleteTag(collectionTag.id).subscribe(res => {
|
||||
this.loadPage();
|
||||
this.toastr.success(res);
|
||||
});
|
||||
break;
|
||||
|
@ -114,9 +114,6 @@ export class SeriesMetadataDetailComponent implements OnChanges, OnInit {
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
|
||||
|
||||
|
||||
this.hasExtendedProperties = this.seriesMetadata.colorists.length > 0 ||
|
||||
this.seriesMetadata.editors.length > 0 ||
|
||||
this.seriesMetadata.coverArtists.length > 0 ||
|
||||
|
@ -7,7 +7,7 @@
|
||||
"name": "GPL-3.0",
|
||||
"url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE"
|
||||
},
|
||||
"version": "0.7.14.14"
|
||||
"version": "0.7.14.15"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user