token encryption

This commit is contained in:
Rob Walsh
2026-03-03 12:19:12 -07:00
parent 4ae68d01de
commit 8f8387abff
2 changed files with 18 additions and 40 deletions
+15 -35
View File
@@ -189,9 +189,7 @@ export class SchedulerService {
await this.unscheduleJob(job);
}
await prisma.scheduledJob.delete({ where: { id: job.id } });
logger.info(
`Removed deprecated scheduled job: ${job.name} (${job.type})`,
);
logger.info(`Removed deprecated scheduled job: ${job.name} (${job.type})`);
}
} catch (error) {
logger.error('Failed to cleanup deprecated scheduled jobs', {
@@ -224,13 +222,11 @@ export class SchedulerService {
job.type,
{ scheduledJobId: job.id },
job.schedule,
`scheduled-${job.id}`,
`scheduled-${job.id}`
);
logger.info(`Job scheduled: ${job.name} (${job.schedule})`);
} catch (error) {
logger.error(`Failed to schedule job ${job.name}`, {
error: error instanceof Error ? error.message : String(error),
});
logger.error(`Failed to schedule job ${job.name}`, { error: error instanceof Error ? error.message : String(error) });
throw error;
}
}
@@ -243,13 +239,11 @@ export class SchedulerService {
await this.jobQueue.removeRepeatableJob(
job.type,
job.schedule,
`scheduled-${job.id}`,
`scheduled-${job.id}`
);
logger.info(`Job unscheduled: ${job.name}`);
} catch (error) {
logger.error(`Failed to unschedule job ${job.name}`, {
error: error instanceof Error ? error.message : String(error),
});
logger.error(`Failed to unschedule job ${job.name}`, { error: error instanceof Error ? error.message : String(error) });
// Don't throw - job might not exist in Bull yet
}
}
@@ -301,7 +295,7 @@ export class SchedulerService {
*/
async updateScheduledJob(
id: string,
dto: UpdateScheduledJobDto,
dto: UpdateScheduledJobDto
): Promise<ScheduledJob> {
if (dto.schedule) {
this.validateCronExpression(dto.schedule);
@@ -445,8 +439,7 @@ export class SchedulerService {
throw new Error(errorMsg);
}
libraryId =
job.payload?.libraryId || absConfig['audiobookshelf.library_id'];
libraryId = job.payload?.libraryId || absConfig['audiobookshelf.library_id'];
} else {
const plexConfig = await configService.getMany([
'plex_url',
@@ -470,18 +463,15 @@ export class SchedulerService {
throw new Error(errorMsg);
}
libraryId =
job.payload?.libraryId || plexConfig.plex_audiobook_library_id;
libraryId = job.payload?.libraryId || plexConfig.plex_audiobook_library_id;
}
logger.info(
`Triggering ${backendMode} library scan for library: ${libraryId}`,
);
logger.info(`Triggering ${backendMode} library scan for library: ${libraryId}`);
return await this.jobQueue.addPlexScanJob(
libraryId || '',
job.payload?.partial,
job.payload?.path,
job.payload?.path
);
}
@@ -502,6 +492,7 @@ export class SchedulerService {
return await this.jobQueue.addAudibleRefreshJob(job.id);
}
/**
* Enable a scheduled job
*/
@@ -533,12 +524,10 @@ export class SchedulerService {
await this.triggerJobNow(job.id);
// Stagger triggers to avoid connection pool burst on startup
await new Promise((resolve) => setTimeout(resolve, 500));
await new Promise(resolve => setTimeout(resolve, 500));
}
} catch (error) {
logger.error(`Failed to trigger overdue job "${job.name}"`, {
error: error instanceof Error ? error.message : String(error),
});
logger.error(`Failed to trigger overdue job "${job.name}"`, { error: error instanceof Error ? error.message : String(error) });
}
}
}
@@ -611,22 +600,13 @@ export class SchedulerService {
if (dayOfMonth === '*' && month === '*' && dayOfWeek === '*') {
const hourNum = parseInt(hour, 10);
const minuteNum = parseInt(minute, 10);
if (
!isNaN(hourNum) &&
!isNaN(minuteNum) &&
hourNum >= 0 &&
hourNum <= 23 &&
minuteNum >= 0 &&
minuteNum <= 59
) {
if (!isNaN(hourNum) && !isNaN(minuteNum) && hourNum >= 0 && hourNum <= 23 && minuteNum >= 0 && minuteNum <= 59) {
return 24 * 60 * 60 * 1000; // 24 hours
}
}
// For other patterns, return a conservative default (24 hours)
logger.warn(
`Unknown cron pattern "${cronExpression}", defaulting to 24 hours`,
);
logger.warn(`Unknown cron pattern "${cronExpression}", defaulting to 24 hours`);
return 24 * 60 * 60 * 1000;
}
+3 -5
View File
@@ -77,8 +77,7 @@ describe('SchedulerService', () => {
])
.mockResolvedValue([]); // triggerOverdueJobs
const { SchedulerService } =
await import('@/lib/services/scheduler.service');
const { SchedulerService } = await import('@/lib/services/scheduler.service');
const service = new SchedulerService();
await service.start();
@@ -87,7 +86,7 @@ describe('SchedulerService', () => {
'audible_refresh',
{ scheduledJobId: 'job-1' },
'0 0 * * *',
'scheduled-job-1',
'scheduled-job-1'
);
});
@@ -306,8 +305,7 @@ describe('SchedulerService', () => {
(jobQueueMock as any)[queueMethod].mockResolvedValue('bull-type');
prismaMock.scheduledJob.update.mockResolvedValue({});
const { SchedulerService } =
await import('@/lib/services/scheduler.service');
const { SchedulerService } = await import('@/lib/services/scheduler.service');
const service = new SchedulerService();
const jobId = await service.triggerJobNow('job-type');