mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 00:11:37 -06:00
fix: patch Trivy CRITICAL/HIGH findings in container image
- apk upgrade in runtime stage to fix OpenSSL CVEs (CVE-2025-15467 CRITICAL, CVE-2025-69419 HIGH) - remove npm from runtime image to eliminate npm-bundled CVEs - update fastify to 5.8.5 and force via pnpm override (CVE-2026-33806 HIGH) - switch vitest pool to threads to fix flaky audio extractor tests - simplify unit test setup with direct instantiation
This commit is contained in:
@@ -37,6 +37,9 @@ RUN mkdir -p /deploy/migrations && cp -r /app/server/src/db/migrations/. /deploy
|
||||
FROM ${NODE_IMAGE} AS runtime
|
||||
WORKDIR /app
|
||||
|
||||
RUN apk upgrade --no-cache && \
|
||||
rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV PORT=3000
|
||||
|
||||
|
||||
@@ -62,6 +62,9 @@
|
||||
]
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"fastify": "^5.8.5"
|
||||
},
|
||||
"onlyBuiltDependencies": [
|
||||
"@nestjs/core",
|
||||
"@parcel/watcher",
|
||||
|
||||
+3
-3
@@ -39,7 +39,7 @@
|
||||
"@fastify/helmet": "^13.0.2",
|
||||
"@fastify/multipart": "^9.4.0",
|
||||
"@fastify/rate-limit": "^10.3.0",
|
||||
"@fastify/static": "^9.0.0",
|
||||
"@fastify/static": "^9.1.0",
|
||||
"@nestjs/common": "^11.1.18",
|
||||
"@nestjs/config": "^4.0.3",
|
||||
"@nestjs/core": "^11.1.18",
|
||||
@@ -89,11 +89,11 @@
|
||||
"@nestjs/schematics": "^11.0.10",
|
||||
"@nestjs/testing": "^11.1.18",
|
||||
"@swc/cli": "^0.8.1",
|
||||
"@swc/core": "^1.15.21",
|
||||
"@swc/core": "^1.15.24",
|
||||
"@types/bcrypt": "^6.0.0",
|
||||
"@types/express": "^5.0.6",
|
||||
"@types/node": "^25.5.2",
|
||||
"@types/nodemailer": "^6.4.23",
|
||||
"@types/nodemailer": "^8.0.0",
|
||||
"@types/passport-jwt": "^4.0.1",
|
||||
"@types/pg": "^8.18.0",
|
||||
"@types/supertest": "^7.2.0",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { ConflictException, ForbiddenException, NotFoundException } from '@nestjs/common';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { EmailProviderService } from './email-provider.service';
|
||||
import { EmailProviderRepository } from './email-provider.repository';
|
||||
import { EmailEncryptionService } from './email-encryption.service';
|
||||
@@ -46,38 +45,29 @@ describe('EmailProviderService', () => {
|
||||
startTls: true,
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
EmailProviderService,
|
||||
{
|
||||
provide: EmailProviderRepository,
|
||||
useValue: {
|
||||
findAllForUser: vi.fn().mockResolvedValue([mockProvider]),
|
||||
findById: vi.fn().mockResolvedValue([mockProvider]),
|
||||
insert: vi.fn().mockResolvedValue([mockProvider]),
|
||||
update: vi.fn().mockResolvedValue([mockProvider]),
|
||||
delete: vi.fn(),
|
||||
clearDefault: vi.fn(),
|
||||
setDefault: vi.fn().mockResolvedValue([mockProvider]),
|
||||
setSharedByOwner: vi.fn().mockResolvedValue([{ ...mockProvider, isShared: true }]),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: EmailEncryptionService,
|
||||
useValue: { encrypt: vi.fn().mockReturnValue('encrypted'), decrypt: vi.fn().mockReturnValue('decrypted') },
|
||||
},
|
||||
{
|
||||
provide: EmailTransportService,
|
||||
useValue: { buildTransporter: vi.fn(), verifyTransporter: vi.fn() },
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
beforeEach(() => {
|
||||
repo = {
|
||||
findAllForUser: vi.fn().mockResolvedValue([mockProvider]),
|
||||
findById: vi.fn().mockResolvedValue([mockProvider]),
|
||||
insert: vi.fn().mockResolvedValue([mockProvider]),
|
||||
update: vi.fn().mockResolvedValue([mockProvider]),
|
||||
delete: vi.fn(),
|
||||
clearDefault: vi.fn(),
|
||||
setDefault: vi.fn().mockResolvedValue([mockProvider]),
|
||||
setSharedByOwner: vi.fn().mockResolvedValue([{ ...mockProvider, isShared: true }]),
|
||||
} as unknown as EmailProviderRepository;
|
||||
|
||||
service = module.get<EmailProviderService>(EmailProviderService);
|
||||
repo = module.get<EmailProviderRepository>(EmailProviderRepository);
|
||||
encryption = module.get<EmailEncryptionService>(EmailEncryptionService);
|
||||
transport = module.get<EmailTransportService>(EmailTransportService);
|
||||
encryption = {
|
||||
encrypt: vi.fn().mockReturnValue('encrypted'),
|
||||
decrypt: vi.fn().mockReturnValue('decrypted'),
|
||||
} as unknown as EmailEncryptionService;
|
||||
|
||||
transport = {
|
||||
buildTransporter: vi.fn(),
|
||||
verifyTransporter: vi.fn(),
|
||||
} as unknown as EmailTransportService;
|
||||
|
||||
service = new EmailProviderService(repo, encryption, transport);
|
||||
});
|
||||
|
||||
describe('findAll', () => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import * as nodemailer from 'nodemailer';
|
||||
import { EmailTransportService } from './email-transport.service';
|
||||
|
||||
@@ -7,12 +6,9 @@ vi.mock('nodemailer');
|
||||
describe('EmailTransportService', () => {
|
||||
let service: EmailTransportService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [EmailTransportService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<EmailTransportService>(EmailTransportService);
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
service = new EmailTransportService();
|
||||
});
|
||||
|
||||
it('should build transporter with correct config (Port 587)', () => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { ProviderConfigurations } from '@projectx/types';
|
||||
|
||||
import { ProviderConfigService } from '../../../metadata-preferences/provider-config.service';
|
||||
@@ -21,21 +20,11 @@ describe('GoodreadsProvider', () => {
|
||||
comicvine: { enabled: false, apiKey: '' },
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
GoodreadsProvider,
|
||||
{
|
||||
provide: ProviderConfigService,
|
||||
useValue: {
|
||||
getConfig: vi.fn().mockResolvedValue(mockConfig),
|
||||
},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
provider = module.get<GoodreadsProvider>(GoodreadsProvider);
|
||||
providerConfig = module.get<ProviderConfigService>(ProviderConfigService);
|
||||
beforeEach(() => {
|
||||
providerConfig = {
|
||||
getConfig: vi.fn().mockResolvedValue(mockConfig),
|
||||
} as unknown as ProviderConfigService;
|
||||
provider = new GoodreadsProvider(providerConfig);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
+5
-16
@@ -1,4 +1,3 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { ProviderConfigurations } from '@projectx/types';
|
||||
|
||||
import { ProviderConfigService } from '../../../metadata-preferences/provider-config.service';
|
||||
@@ -20,21 +19,11 @@ describe('OpenLibraryProvider', () => {
|
||||
comicvine: { enabled: false, apiKey: '' },
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
OpenLibraryProvider,
|
||||
{
|
||||
provide: ProviderConfigService,
|
||||
useValue: {
|
||||
getConfig: vi.fn().mockResolvedValue(mockConfig),
|
||||
},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
provider = module.get<OpenLibraryProvider>(OpenLibraryProvider);
|
||||
providerConfig = module.get<ProviderConfigService>(ProviderConfigService);
|
||||
beforeEach(() => {
|
||||
providerConfig = {
|
||||
getConfig: vi.fn().mockResolvedValue(mockConfig),
|
||||
} as unknown as ProviderConfigService;
|
||||
provider = new OpenLibraryProvider(providerConfig);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -11,7 +11,7 @@ export default defineConfig({
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'node',
|
||||
pool: 'forks',
|
||||
pool: 'threads',
|
||||
include: ['src/**/*.test.ts', 'test/**/*.test.ts'],
|
||||
passWithNoTests: true,
|
||||
reporters: process.env.CI ? ['default', 'github-actions'] : ['default'],
|
||||
|
||||
Reference in New Issue
Block a user