- Introduced optional JWT issuer and audience configurations in the JoseJwtService for improved token validation. - Updated CSRF middleware to streamline token validation and enhance security measures. - Added new environment variables for JWT issuer and audience, allowing for more flexible authentication setups. - Refactored CSRF controller and middleware to improve token handling and security checks. - Cleaned up and standardized cookie paths for access and refresh tokens in the AuthController. - Enhanced error handling in the TokenBlacklistService to manage Redis availability more effectively.
150 lines
4.3 KiB
Bash
Executable File
150 lines
4.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# 🔍 Dependency Validation Script
|
|
# Validates dependency integrity, checks for version drift, and security issues
|
|
|
|
set -euo pipefail
|
|
|
|
echo "🔍 Validating dependencies..."
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Check if pnpm is available
|
|
if ! command -v pnpm &> /dev/null; then
|
|
echo -e "${RED}❌ pnpm is not installed${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# 1. Validate lockfile integrity
|
|
echo "📋 Checking lockfile integrity..."
|
|
if pnpm install --frozen-lockfile --ignore-scripts; then
|
|
echo -e "${GREEN}✅ Lockfile integrity validated${NC}"
|
|
else
|
|
echo -e "${RED}❌ Lockfile integrity check failed${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# 2. Check for dependency version drift
|
|
echo "🔍 Checking for dependency version drift..."
|
|
pnpm list --recursive --depth=0 --json > /tmp/deps.json
|
|
|
|
node -e "
|
|
const fs = require('fs');
|
|
const deps = JSON.parse(fs.readFileSync('/tmp/deps.json', 'utf8'));
|
|
// depName -> Map(version -> string[])
|
|
const allDeps = new Map();
|
|
|
|
deps.forEach(pkg => {
|
|
if (pkg.dependencies) {
|
|
Object.entries(pkg.dependencies).forEach(([name, info]) => {
|
|
const version = info.version;
|
|
if (!allDeps.has(name)) allDeps.set(name, new Map());
|
|
|
|
const byVersion = allDeps.get(name);
|
|
if (!byVersion.has(version)) byVersion.set(version, []);
|
|
byVersion.get(version).push(pkg.name);
|
|
});
|
|
}
|
|
});
|
|
|
|
let hasDrift = false;
|
|
allDeps.forEach((byVersion, depName) => {
|
|
if (byVersion.size <= 1) return;
|
|
|
|
hasDrift = true;
|
|
console.log(\`❌ Version drift detected for \${depName}:\`);
|
|
for (const [version, pkgs] of [...byVersion.entries()].sort(([a], [b]) => String(a).localeCompare(String(b)))) {
|
|
console.log(\` - \${version}\`);
|
|
pkgs.sort().forEach(p => console.log(\` • \${p}\`));
|
|
}
|
|
});
|
|
|
|
if (hasDrift) {
|
|
console.log('\\n💡 Fix version drift by aligning dependency versions across workspaces.');
|
|
process.exit(1);
|
|
} else {
|
|
console.log('✅ No dependency version drift detected.');
|
|
}
|
|
"
|
|
|
|
# 2b. Ensure a single installed Zod version (lockfile-level)
|
|
echo "🧩 Checking for multiple installed Zod versions..."
|
|
node -e "
|
|
const fs = require('fs');
|
|
const lock = fs.readFileSync('pnpm-lock.yaml', 'utf8');
|
|
const versions = new Set();
|
|
const re = /\\n\\s{2}zod@([^:\\s]+):/g;
|
|
let m;
|
|
while ((m = re.exec(lock)) !== null) versions.add(m[1]);
|
|
|
|
if (versions.size === 0) {
|
|
console.log('⚠️ No zod entries found in lockfile (unexpected).');
|
|
process.exit(1);
|
|
}
|
|
|
|
if (versions.size > 1) {
|
|
console.log('❌ Multiple zod versions installed:');
|
|
[...versions].sort().forEach(v => console.log(' - zod@' + v));
|
|
console.log('\\n💡 Fix by aligning dependencies or adding a pnpm override for zod.');
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log('✅ Single zod version installed:', 'zod@' + [...versions][0]);
|
|
"
|
|
|
|
# 3. Security audit
|
|
echo "🔒 Running security audit..."
|
|
if pnpm audit --audit-level moderate; then
|
|
echo -e "${GREEN}✅ Security audit passed${NC}"
|
|
else
|
|
echo -e "${YELLOW}⚠️ Security vulnerabilities found. Review and update dependencies.${NC}"
|
|
fi
|
|
|
|
# 4. Check for outdated dependencies
|
|
echo "📅 Checking for outdated dependencies..."
|
|
pnpm outdated --recursive || echo -e "${YELLOW}⚠️ Some dependencies are outdated${NC}"
|
|
|
|
# 5. Validate workspace configuration
|
|
echo "⚙️ Validating workspace configuration..."
|
|
node -e "
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
try {
|
|
const rootPkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
console.log('✅ Root package.json is valid');
|
|
|
|
const workspaceConfig = fs.readFileSync('pnpm-workspace.yaml', 'utf8');
|
|
console.log('✅ pnpm-workspace.yaml is readable');
|
|
|
|
// Check that all workspace packages exist
|
|
const workspaces = ['apps/*', 'packages/*'];
|
|
let allValid = true;
|
|
|
|
workspaces.forEach(workspace => {
|
|
const workspacePath = workspace.replace('/*', '');
|
|
if (!fs.existsSync(workspacePath)) {
|
|
console.log(\`❌ Workspace path does not exist: \${workspacePath}\`);
|
|
allValid = false;
|
|
}
|
|
});
|
|
|
|
if (!allValid) {
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log('✅ All workspace paths are valid');
|
|
} catch (error) {
|
|
console.log(\`❌ Workspace validation failed: \${error.message}\`);
|
|
process.exit(1);
|
|
}
|
|
"
|
|
|
|
# Cleanup
|
|
rm -f /tmp/deps.json
|
|
|
|
echo -e "${GREEN}🎉 Dependency validation completed successfully!${NC}"
|