Compare commits

...

5 Commits

Author SHA1 Message Date
gronod ae9e877445 Merge branch 'main' of https://git.i3omb.com/Gandalf/sofarr
Create Release / release (push) Successful in 30s
CI / Security audit (push) Successful in 1m38s
CI / Tests & coverage (push) Successful in 1m52s
2026-05-19 09:07:59 +01:00
gronod 853b205c46 Merge develop: Add MIT copyright headers 2026-05-19 09:07:51 +01:00
gronod 8c4cc20551 Add MIT copyright headers to all source files
Build and Push Docker Image / build (push) Successful in 48s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m21s
CI / Security audit (push) Successful in 1m47s
CI / Tests & coverage (push) Successful in 2m1s
2026-05-19 09:07:42 +01:00
Gandalf da77f083fe Merge pull request 'Update .gitea/workflows/licence-check.yml' (#17) from develop-workflow into develop
Build and Push Docker Image / build (push) Successful in 40s
Licence Check / Licence compatibility and copyright header verification (push) Failing after 54s
CI / Security audit (push) Successful in 1m25s
CI / Tests & coverage (push) Successful in 1m39s
Reviewed-on: #17
2026-05-18 13:45:03 +01:00
Gandalf 71feaf0175 Update .gitea/workflows/licence-check.yml
Licence Check / Licence compatibility and copyright header verification (push) Failing after 56s
CI / Security audit (push) Successful in 1m7s
CI / Tests & coverage (push) Successful in 1m18s
Licence Check / Licence compatibility and copyright header verification (pull_request) Failing after 39s
CI / Security audit (pull_request) Successful in 1m13s
CI / Tests & coverage (pull_request) Successful in 1m23s
2026-05-18 13:39:59 +01:00
37 changed files with 82 additions and 6 deletions
+46 -1
View File
@@ -7,16 +7,24 @@ on:
- "package.json"
- "package-lock.json"
- ".gitea/workflows/licence-check.yml"
- "**/*.js"
- "**/*.ts"
- "**/*.jsx"
- "**/*.tsx"
pull_request:
branches: ["**", "!main", "!release/**"]
paths:
- "package.json"
- "package-lock.json"
- ".gitea/workflows/licence-check.yml"
- "**/*.js"
- "**/*.ts"
- "**/*.jsx"
- "**/*.tsx"
jobs:
licence-check:
name: Dependency licence compatibility
name: Licence compatibility and copyright header verification
runs-on: ubuntu-latest
continue-on-error: true
steps:
@@ -36,3 +44,40 @@ jobs:
--onlyAllow "MIT;ISC;MIT-0;BSD-2-Clause;BSD-3-Clause;Apache-2.0;CC0-1.0;BlueOak-1.0.0" \
--excludePrivatePackages \
&& echo "All production dependency licences are compatible with MIT."
- name: Check copyright headers in source files
run: |
#!/bin/bash
set -e
# Find all source files, excluding build artifacts and node_modules
SOURCE_FILES=$(find . -type f \( -name "*.js" -o -name "*.ts" -o -name "*.jsx" -o -name "*.tsx" \) \
! -path "./node_modules/*" \
! -path "./.git/*" \
! -path "./dist/*" \
! -path "./build/*" \
! -path "./.gitea/*")
MISSING_HEADER=0
# Check each file for MIT-compliant copyright header
while IFS= read -r file; do
if [ -z "$file" ]; then
continue
fi
# Check if file starts with a copyright header containing: Copyright, year (4 digits), name, and MIT License
if ! head -n 5 "$file" | grep -qiE "Copyright.*[0-9]{4}.*MIT"; then
echo "❌ Missing MIT-compliant copyright header in: $file"
echo " Required format: // Copyright (c) YYYY Name. MIT License."
MISSING_HEADER=$((MISSING_HEADER + 1))
fi
done <<< "$SOURCE_FILES"
if [ $MISSING_HEADER -gt 0 ]; then
echo ""
echo "⚠️ Found $MISSING_HEADER file(s) with missing or non-compliant copyright headers."
exit 1
else
echo "✅ All source files have MIT-compliant copyright headers."
fi
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
import { useState, useEffect } from 'react';
import axios from 'axios';
import './App.css';
+1
View File
@@ -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'
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
let currentUser = null;
let downloads = [];
let isAdmin = false;
+1
View File
@@ -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
+1 -1
View File
@@ -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');
+1
View File
@@ -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;
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
/**
* CSRF protection using the double-submit cookie pattern.
*
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
const express = require('express');
const axios = require('axios');
const crypto = require('crypto');
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
const express = require('express');
const router = express.Router();
const requireAuth = require('../middleware/requireAuth');
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
const express = require('express');
const axios = require('axios');
const router = express.Router();
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
const express = require('express');
const router = express.Router();
const axios = require('axios');
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
const express = require('express');
const axios = require('axios');
const router = express.Router();
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
const express = require('express');
const axios = require('axios');
const router = express.Router();
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
const express = require('express');
const axios = require('axios');
const router = express.Router();
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
const { logToFile } = require('./logger');
class MemoryCache {
+1 -1
View File
@@ -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).
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
const axios = require('axios');
const cache = require('./cache');
const { getSonarrInstances, getRadarrInstances } = require('./config');
+1 -1
View File
@@ -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.
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
const fs = require('fs');
const path = require('path');
+1 -1
View File
@@ -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');
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
const axios = require('axios');
const { logToFile } = require('./logger');
const { getQbittorrentInstances } = require('./config');
+1 -1
View File
@@ -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)
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
/**
* Persistent token store backed by a JSON file.
*
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
/**
* Integration tests for authentication routes.
*
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
/**
* Integration tests for health and readiness endpoints.
*
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
/**
* Integration tests for GET /api/history/recent
*
+1
View File
@@ -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';
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
/**
* Tests for server/utils/config.js
*
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
/**
* Unit tests for server/utils/historyFetcher.js
*
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
/**
* Tests for server/utils/qbittorrent.js pure utility functions.
*
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
/**
* Tests for server/middleware/requireAuth.js
*
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
/**
* Tests for server/utils/sanitizeError.js
*
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
/**
* Tests for server/utils/tokenStore.js
*
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
/**
* Tests for server/middleware/verifyCsrf.js
*
+1
View File
@@ -1,3 +1,4 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
import { defineConfig } from 'vitest/config';
export default defineConfig({