diff --git a/client/src/App.jsx b/client/src/App.jsx index 6a06d22..17eaaf7 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. import { useState, useEffect } from 'react'; import axios from 'axios'; import './App.css'; diff --git a/client/src/main.jsx b/client/src/main.jsx index 6aee80b..93ce542 100644 --- a/client/src/main.jsx +++ b/client/src/main.jsx @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.jsx' diff --git a/client/vite.config.js b/client/vite.config.js index 0f5e78c..bf237b5 100644 --- a/client/vite.config.js +++ b/client/vite.config.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' diff --git a/public/app.js b/public/app.js index 0016d07..ddd4f99 100644 --- a/public/app.js +++ b/public/app.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. let currentUser = null; let downloads = []; let isAdmin = false; diff --git a/server/app.js b/server/app.js index 6f15371..da9d319 100644 --- a/server/app.js +++ b/server/app.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. /** * Express application factory — imported by both server/index.js (production) * and the test suite. Keeping app creation separate from app.listen() means diff --git a/server/index.js b/server/index.js index 3e40136..9de9820 100644 --- a/server/index.js +++ b/server/index.js @@ -1,4 +1,4 @@ -// Copyright (c) 2025 Gordon Bolton. MIT License. +// Copyright (c) 2026 Gordon Bolton. MIT License. const express = require('express'); const path = require('path'); const cookieParser = require('cookie-parser'); diff --git a/server/middleware/requireAuth.js b/server/middleware/requireAuth.js index 2504fcb..454614c 100644 --- a/server/middleware/requireAuth.js +++ b/server/middleware/requireAuth.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. function requireAuth(req, res, next) { const signed = !!process.env.COOKIE_SECRET; const raw = signed ? req.signedCookies.emby_user : req.cookies.emby_user; diff --git a/server/middleware/verifyCsrf.js b/server/middleware/verifyCsrf.js index 6026870..6eca0ad 100644 --- a/server/middleware/verifyCsrf.js +++ b/server/middleware/verifyCsrf.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. /** * CSRF protection using the double-submit cookie pattern. * diff --git a/server/routes/auth.js b/server/routes/auth.js index caab701..6b2b913 100644 --- a/server/routes/auth.js +++ b/server/routes/auth.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. const express = require('express'); const axios = require('axios'); const crypto = require('crypto'); diff --git a/server/routes/dashboard.js b/server/routes/dashboard.js index 290b42c..c6b389e 100644 --- a/server/routes/dashboard.js +++ b/server/routes/dashboard.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. const express = require('express'); const router = express.Router(); const requireAuth = require('../middleware/requireAuth'); diff --git a/server/routes/emby.js b/server/routes/emby.js index f349e7f..0aa37ea 100644 --- a/server/routes/emby.js +++ b/server/routes/emby.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. const express = require('express'); const axios = require('axios'); const router = express.Router(); diff --git a/server/routes/history.js b/server/routes/history.js index a468574..e91e745 100644 --- a/server/routes/history.js +++ b/server/routes/history.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. const express = require('express'); const router = express.Router(); const axios = require('axios'); diff --git a/server/routes/radarr.js b/server/routes/radarr.js index e9f348b..6d74211 100644 --- a/server/routes/radarr.js +++ b/server/routes/radarr.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. const express = require('express'); const axios = require('axios'); const router = express.Router(); diff --git a/server/routes/sabnzbd.js b/server/routes/sabnzbd.js index 19ff152..fc8a54b 100644 --- a/server/routes/sabnzbd.js +++ b/server/routes/sabnzbd.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. const express = require('express'); const axios = require('axios'); const router = express.Router(); diff --git a/server/routes/sonarr.js b/server/routes/sonarr.js index 889b9ab..aba4bdc 100644 --- a/server/routes/sonarr.js +++ b/server/routes/sonarr.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. const express = require('express'); const axios = require('axios'); const router = express.Router(); diff --git a/server/utils/cache.js b/server/utils/cache.js index daf4253..30640cf 100644 --- a/server/utils/cache.js +++ b/server/utils/cache.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. const { logToFile } = require('./logger'); class MemoryCache { diff --git a/server/utils/config.js b/server/utils/config.js index c71f8cd..ca989f5 100644 --- a/server/utils/config.js +++ b/server/utils/config.js @@ -1,4 +1,4 @@ -// Copyright (c) 2025 Gordon Bolton. MIT License. +// Copyright (c) 2026 Gordon Bolton. MIT License. const { logToFile } = require('./logger'); // Validate that a configured service URL is well-formed and uses http(s). diff --git a/server/utils/historyFetcher.js b/server/utils/historyFetcher.js index 3e0707f..8f5066d 100644 --- a/server/utils/historyFetcher.js +++ b/server/utils/historyFetcher.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. const axios = require('axios'); const cache = require('./cache'); const { getSonarrInstances, getRadarrInstances } = require('./config'); diff --git a/server/utils/loadSecrets.js b/server/utils/loadSecrets.js index e50058c..e028623 100644 --- a/server/utils/loadSecrets.js +++ b/server/utils/loadSecrets.js @@ -1,4 +1,4 @@ -// Copyright (c) 2025 Gordon Bolton. MIT License. +// Copyright (c) 2026 Gordon Bolton. MIT License. // // Docker secrets support: if an environment variable named FOO_FILE is set, // read its contents from the file at that path and expose it as FOO. diff --git a/server/utils/logger.js b/server/utils/logger.js index 3160d2e..00c6df9 100644 --- a/server/utils/logger.js +++ b/server/utils/logger.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. const fs = require('fs'); const path = require('path'); diff --git a/server/utils/poller.js b/server/utils/poller.js index a631ca5..91df51c 100644 --- a/server/utils/poller.js +++ b/server/utils/poller.js @@ -1,4 +1,4 @@ -// Copyright (c) 2025 Gordon Bolton. MIT License. +// Copyright (c) 2026 Gordon Bolton. MIT License. const axios = require('axios'); const cache = require('./cache'); const { getTorrents } = require('./qbittorrent'); diff --git a/server/utils/qbittorrent.js b/server/utils/qbittorrent.js index 7c218ce..0915037 100644 --- a/server/utils/qbittorrent.js +++ b/server/utils/qbittorrent.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. const axios = require('axios'); const { logToFile } = require('./logger'); const { getQbittorrentInstances } = require('./config'); diff --git a/server/utils/sanitizeError.js b/server/utils/sanitizeError.js index 2a9a60c..7e6a9ba 100644 --- a/server/utils/sanitizeError.js +++ b/server/utils/sanitizeError.js @@ -1,4 +1,4 @@ -// Copyright (c) 2025 Gordon Bolton. MIT License. +// Copyright (c) 2026 Gordon Bolton. MIT License. // Query-param secrets (SABnzbd apikey, generic token/password params) const QUERY_SECRET_PATTERN = /([?&](?:apikey|token|password|api_key|key|secret)=)[^&\s#]*/gi; // HTTP auth header values (X-Api-Key, X-MediaBrowser-Token, Authorization, X-Emby-Authorization) diff --git a/server/utils/tokenStore.js b/server/utils/tokenStore.js index 9a66000..551f88a 100644 --- a/server/utils/tokenStore.js +++ b/server/utils/tokenStore.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. /** * Persistent token store backed by a JSON file. * diff --git a/tests/integration/auth.test.js b/tests/integration/auth.test.js index ca98d33..bca64f2 100644 --- a/tests/integration/auth.test.js +++ b/tests/integration/auth.test.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. /** * Integration tests for authentication routes. * diff --git a/tests/integration/health.test.js b/tests/integration/health.test.js index fbe806b..a6530f0 100644 --- a/tests/integration/health.test.js +++ b/tests/integration/health.test.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. /** * Integration tests for health and readiness endpoints. * diff --git a/tests/integration/history.test.js b/tests/integration/history.test.js index d6f924d..4257cda 100644 --- a/tests/integration/history.test.js +++ b/tests/integration/history.test.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. /** * Integration tests for GET /api/history/recent * diff --git a/tests/setup.js b/tests/setup.js index 83ec3d4..8f652d0 100644 --- a/tests/setup.js +++ b/tests/setup.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. import { vi, beforeEach, afterEach } from 'vitest'; import os from 'os'; import path from 'path'; diff --git a/tests/unit/config.test.js b/tests/unit/config.test.js index 544e5de..80a74b2 100644 --- a/tests/unit/config.test.js +++ b/tests/unit/config.test.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. /** * Tests for server/utils/config.js * diff --git a/tests/unit/historyFetcher.test.js b/tests/unit/historyFetcher.test.js index 040a358..9231607 100644 --- a/tests/unit/historyFetcher.test.js +++ b/tests/unit/historyFetcher.test.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. /** * Unit tests for server/utils/historyFetcher.js * diff --git a/tests/unit/qbittorrent.test.js b/tests/unit/qbittorrent.test.js index 72cc467..ddf149d 100644 --- a/tests/unit/qbittorrent.test.js +++ b/tests/unit/qbittorrent.test.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. /** * Tests for server/utils/qbittorrent.js pure utility functions. * diff --git a/tests/unit/requireAuth.test.js b/tests/unit/requireAuth.test.js index 87cefb4..f7f6533 100644 --- a/tests/unit/requireAuth.test.js +++ b/tests/unit/requireAuth.test.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. /** * Tests for server/middleware/requireAuth.js * diff --git a/tests/unit/sanitizeError.test.js b/tests/unit/sanitizeError.test.js index a6f3266..3f5c375 100644 --- a/tests/unit/sanitizeError.test.js +++ b/tests/unit/sanitizeError.test.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. /** * Tests for server/utils/sanitizeError.js * diff --git a/tests/unit/tokenStore.test.js b/tests/unit/tokenStore.test.js index 53e0c3c..910704f 100644 --- a/tests/unit/tokenStore.test.js +++ b/tests/unit/tokenStore.test.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. /** * Tests for server/utils/tokenStore.js * diff --git a/tests/unit/verifyCsrf.test.js b/tests/unit/verifyCsrf.test.js index 3f0e631..97d52af 100644 --- a/tests/unit/verifyCsrf.test.js +++ b/tests/unit/verifyCsrf.test.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. /** * Tests for server/middleware/verifyCsrf.js * diff --git a/vitest.config.js b/vitest.config.js index 5df0b1e..a314db6 100644 --- a/vitest.config.js +++ b/vitest.config.js @@ -1,3 +1,4 @@ +// Copyright (c) 2026 Gordon Bolton. MIT License. import { defineConfig } from 'vitest/config'; export default defineConfig({