mirror of
https://github.com/sct/overseerr.git
synced 2025-09-17 17:24:35 +02:00
feat(plex): refresh token schedule (#3875)
* feat: refresh token schedule fix #3861 * fix(i18n): add i18n message * refactor(plextv): use randomUUID crypto instead custom function
This commit is contained in:
@@ -2,6 +2,7 @@ import type { PlexDevice } from '@server/interfaces/api/plexInterfaces';
|
|||||||
import cacheManager from '@server/lib/cache';
|
import cacheManager from '@server/lib/cache';
|
||||||
import { getSettings } from '@server/lib/settings';
|
import { getSettings } from '@server/lib/settings';
|
||||||
import logger from '@server/logger';
|
import logger from '@server/logger';
|
||||||
|
import { randomUUID } from 'node:crypto';
|
||||||
import xml2js from 'xml2js';
|
import xml2js from 'xml2js';
|
||||||
import ExternalAPI from './externalapi';
|
import ExternalAPI from './externalapi';
|
||||||
|
|
||||||
@@ -363,6 +364,24 @@ class PlexTvAPI extends ExternalAPI {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async pingToken() {
|
||||||
|
try {
|
||||||
|
const response = await this.axios.get('/api/v2/ping', {
|
||||||
|
headers: {
|
||||||
|
'X-Plex-Client-Identifier': randomUUID(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!response?.data?.pong) {
|
||||||
|
throw new Error('No pong response');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('Failed to ping token', {
|
||||||
|
label: 'Plex Refresh Token',
|
||||||
|
errorMessage: e.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PlexTvAPI;
|
export default PlexTvAPI;
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import availabilitySync from '@server/lib/availabilitySync';
|
import availabilitySync from '@server/lib/availabilitySync';
|
||||||
import downloadTracker from '@server/lib/downloadtracker';
|
import downloadTracker from '@server/lib/downloadtracker';
|
||||||
import ImageProxy from '@server/lib/imageproxy';
|
import ImageProxy from '@server/lib/imageproxy';
|
||||||
|
import refreshToken from '@server/lib/refreshToken';
|
||||||
import { plexFullScanner, plexRecentScanner } from '@server/lib/scanners/plex';
|
import { plexFullScanner, plexRecentScanner } from '@server/lib/scanners/plex';
|
||||||
import { radarrScanner } from '@server/lib/scanners/radarr';
|
import { radarrScanner } from '@server/lib/scanners/radarr';
|
||||||
import { sonarrScanner } from '@server/lib/scanners/sonarr';
|
import { sonarrScanner } from '@server/lib/scanners/sonarr';
|
||||||
@@ -168,5 +169,19 @@ export const startJobs = (): void => {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
scheduledJobs.push({
|
||||||
|
id: 'plex-refresh-token',
|
||||||
|
name: 'Plex Refresh Token',
|
||||||
|
type: 'process',
|
||||||
|
interval: 'fixed',
|
||||||
|
cronSchedule: jobs['plex-refresh-token'].schedule,
|
||||||
|
job: schedule.scheduleJob(jobs['plex-refresh-token'].schedule, () => {
|
||||||
|
logger.info('Starting scheduled job: Plex Refresh Token', {
|
||||||
|
label: 'Jobs',
|
||||||
|
});
|
||||||
|
refreshToken.run();
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
logger.info('Scheduled jobs loaded', { label: 'Jobs' });
|
logger.info('Scheduled jobs loaded', { label: 'Jobs' });
|
||||||
};
|
};
|
||||||
|
37
server/lib/refreshToken.ts
Normal file
37
server/lib/refreshToken.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import PlexTvAPI from '@server/api/plextv';
|
||||||
|
import { getRepository } from '@server/datasource';
|
||||||
|
import { User } from '@server/entity/User';
|
||||||
|
import logger from '@server/logger';
|
||||||
|
|
||||||
|
class RefreshToken {
|
||||||
|
public async run() {
|
||||||
|
const userRepository = getRepository(User);
|
||||||
|
|
||||||
|
const users = await userRepository
|
||||||
|
.createQueryBuilder('user')
|
||||||
|
.addSelect('user.plexToken')
|
||||||
|
.where("user.plexToken != ''")
|
||||||
|
.getMany();
|
||||||
|
|
||||||
|
for (const user of users) {
|
||||||
|
await this.refreshUserToken(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async refreshUserToken(user: User) {
|
||||||
|
if (!user.plexToken) {
|
||||||
|
logger.warn('Skipping user refresh token for user without plex token', {
|
||||||
|
label: 'Plex Refresh Token',
|
||||||
|
user: user.displayName,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const plexTvApi = new PlexTvAPI(user.plexToken);
|
||||||
|
plexTvApi.pingToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const refreshToken = new RefreshToken();
|
||||||
|
|
||||||
|
export default refreshToken;
|
@@ -248,6 +248,7 @@ export type JobId =
|
|||||||
| 'plex-recently-added-scan'
|
| 'plex-recently-added-scan'
|
||||||
| 'plex-full-scan'
|
| 'plex-full-scan'
|
||||||
| 'plex-watchlist-sync'
|
| 'plex-watchlist-sync'
|
||||||
|
| 'plex-refresh-token'
|
||||||
| 'radarr-scan'
|
| 'radarr-scan'
|
||||||
| 'sonarr-scan'
|
| 'sonarr-scan'
|
||||||
| 'download-sync'
|
| 'download-sync'
|
||||||
@@ -409,6 +410,9 @@ class Settings {
|
|||||||
'plex-watchlist-sync': {
|
'plex-watchlist-sync': {
|
||||||
schedule: '0 */3 * * * *',
|
schedule: '0 */3 * * * *',
|
||||||
},
|
},
|
||||||
|
'plex-refresh-token': {
|
||||||
|
schedule: '0 0 5 * * *',
|
||||||
|
},
|
||||||
'radarr-scan': {
|
'radarr-scan': {
|
||||||
schedule: '0 0 4 * * *',
|
schedule: '0 0 4 * * *',
|
||||||
},
|
},
|
||||||
|
@@ -53,6 +53,7 @@ const messages: { [messageName: string]: MessageDescriptor } = defineMessages({
|
|||||||
'plex-recently-added-scan': 'Plex Recently Added Scan',
|
'plex-recently-added-scan': 'Plex Recently Added Scan',
|
||||||
'plex-full-scan': 'Plex Full Library Scan',
|
'plex-full-scan': 'Plex Full Library Scan',
|
||||||
'plex-watchlist-sync': 'Plex Watchlist Sync',
|
'plex-watchlist-sync': 'Plex Watchlist Sync',
|
||||||
|
'plex-refresh-token': 'Plex Refresh Token',
|
||||||
'availability-sync': 'Media Availability Sync',
|
'availability-sync': 'Media Availability Sync',
|
||||||
'radarr-scan': 'Radarr Scan',
|
'radarr-scan': 'Radarr Scan',
|
||||||
'sonarr-scan': 'Sonarr Scan',
|
'sonarr-scan': 'Sonarr Scan',
|
||||||
|
@@ -768,6 +768,7 @@
|
|||||||
"components.Settings.SettingsJobsCache.nextexecution": "Next Execution",
|
"components.Settings.SettingsJobsCache.nextexecution": "Next Execution",
|
||||||
"components.Settings.SettingsJobsCache.plex-full-scan": "Plex Full Library Scan",
|
"components.Settings.SettingsJobsCache.plex-full-scan": "Plex Full Library Scan",
|
||||||
"components.Settings.SettingsJobsCache.plex-recently-added-scan": "Plex Recently Added Scan",
|
"components.Settings.SettingsJobsCache.plex-recently-added-scan": "Plex Recently Added Scan",
|
||||||
|
"components.Settings.SettingsJobsCache.plex-refresh-token": "Plex Refresh Token",
|
||||||
"components.Settings.SettingsJobsCache.plex-watchlist-sync": "Plex Watchlist Sync",
|
"components.Settings.SettingsJobsCache.plex-watchlist-sync": "Plex Watchlist Sync",
|
||||||
"components.Settings.SettingsJobsCache.process": "Process",
|
"components.Settings.SettingsJobsCache.process": "Process",
|
||||||
"components.Settings.SettingsJobsCache.radarr-scan": "Radarr Scan",
|
"components.Settings.SettingsJobsCache.radarr-scan": "Radarr Scan",
|
||||||
|
Reference in New Issue
Block a user