Skip to content

Commit

Permalink
Added a UI to see which users on the server have anilist/mal tokens s…
Browse files Browse the repository at this point in the history
…et, which anilist are expired (mal doesn't do JWTs).

Added a new email which will inform users that their (anilist) token has expired and to renew it. Runs every night.
  • Loading branch information
majora2007 committed Jan 8, 2025
1 parent 0186391 commit ae4b239
Show file tree
Hide file tree
Showing 5 changed files with 9 additions and 25 deletions.
1 change: 0 additions & 1 deletion API/Data/Repositories/ExternalSeriesMetadataRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,6 @@ public async Task<IList<ManageMatchSeriesDto>> GetAllSeries(ManageMatchFilterDto
{
return await _context.Series
.Where(s => !ExternalMetadataService.NonEligibleLibraryTypes.Contains(s.Library.Type))
//.Where(s => s.ExternalSeriesMetadata == null || s.ExternalSeriesMetadata.ValidUntilUtc < DateTime.UtcNow)
.FilterMatchState(filter.MatchStateOption)
//.WhereNameLike(filter.SearchTerm)
.OrderBy(s => s.NormalizedName)
Expand Down
9 changes: 8 additions & 1 deletion API/Services/Plus/ScrobblingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public class ScrobblingService : IScrobblingService
private readonly ILogger<ScrobblingService> _logger;
private readonly ILicenseService _licenseService;
private readonly ILocalizationService _localizationService;
private readonly IEmailService _emailService;

public const string AniListWeblinkWebsite = "https://anilist.co/manga/";
public const string MalWeblinkWebsite = "https://myanimelist.net/manga/";
Expand Down Expand Up @@ -100,13 +101,14 @@ public class ScrobblingService : IScrobblingService


public ScrobblingService(IUnitOfWork unitOfWork, IEventHub eventHub, ILogger<ScrobblingService> logger,
ILicenseService licenseService, ILocalizationService localizationService)
ILicenseService licenseService, ILocalizationService localizationService, IEmailService emailService)
{
_unitOfWork = unitOfWork;
_eventHub = eventHub;
_logger = logger;
_licenseService = licenseService;
_localizationService = localizationService;
_emailService = emailService;

FlurlConfiguration.ConfigureClientForUrl(Configuration.KavitaPlusApiUrl);
}
Expand All @@ -125,8 +127,13 @@ public async Task CheckExternalAccessTokens()
{
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);

// Send a event to them
await _eventHub.SendMessageToAsync(MessageFactory.ScrobblingKeyExpired,
MessageFactory.ScrobblingKeyExpiredEvent(ScrobbleProvider.AniList), user.Id);

// Send an email to remind them
await _emailService.SendTokenExpiredEmail(user.Id, JwtHelper.GetTokenExpiry(user.AniListAccessToken), ScrobbleProvider.AniList);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
<th scope="col">
{{t('mal-header')}}
</th>
<!-- Actions header -->
<th scope="col">{{t('actions-header')}}</th>
</tr>
</thead>
<tbody #container>
Expand All @@ -37,12 +35,6 @@
{{null | defaultValue}}
}
</td>
<td>
<button class="btn btn-secondary" [disabled]="!isEmailSetup" (click)="sendEmail(item)">
<i class="fa fa-share-from-square" aria-hidden="true"></i>
<span class="visually-hidden">{{t('actions-header')}}</span>
</button>
</td>
</tr>
} @empty {
@if (isLoading) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,11 @@ export class ManageUserTokensComponent implements OnInit {

private readonly cdRef = inject(ChangeDetectorRef);
private readonly memberService = inject(MemberService);
private readonly settingService = inject(SettingsService);
private readonly confirmService = inject(ConfirmService);

isLoading = true;
isEmailSetup = false;
users: UserTokenInfo[] = [];

ngOnInit() {

this.settingService.isEmailSetup().subscribe(isEmailSetup => {
this.isEmailSetup = isEmailSetup;
this.cdRef.markForCheck();
});
this.loadData();
}

Expand All @@ -55,9 +47,4 @@ export class ManageUserTokensComponent implements OnInit {
this.cdRef.markForCheck();
});
}

sendEmail(item: UserTokenInfo) {

}

}
3 changes: 1 addition & 2 deletions UI/Web/src/assets/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -748,11 +748,10 @@
},

"manage-user-tokens": {
"description": "Users that have access tokens may need resetting occasionally. Send them a nudge if their token is expired. Requires Email to be setup.",
"description": "Users that have scrobbling tokens may need renewing occasionally. Kavita will automatically email them if email is setup and they have a valid email.",
"username-header": "Username",
"anilist-header": "AniList",
"mal-header": "MAL",
"actions-header": "Send Expiration Email",
"token-set-label": "Token Set",
"no-data": "{{common.no-data}}"
},
Expand Down

0 comments on commit ae4b239

Please sign in to comment.