diff --git a/src/frame/middleware/index.ts b/src/frame/middleware/index.ts index 765efc32d6..a60d3a2617 100644 --- a/src/frame/middleware/index.ts +++ b/src/frame/middleware/index.ts @@ -36,7 +36,7 @@ import robots from './robots' import earlyAccessLinks from '@/early-access/middleware/early-access-links' import categoriesForSupport from './categories-for-support' import triggerError from '@/observability/middleware/trigger-error' -import secretScanning from '@/secret-scanning/middleware/secret-scanning.js' +import secretScanning from '@/secret-scanning/middleware/secret-scanning' import ghesReleaseNotes from '@/release-notes/middleware/ghes-release-notes.js' import whatsNewChangelog from './context/whats-new-changelog.js' import layout from './context/layout.js' diff --git a/src/secret-scanning/middleware/secret-scanning.js b/src/secret-scanning/middleware/secret-scanning.js deleted file mode 100644 index 33b9f0de7f..0000000000 --- a/src/secret-scanning/middleware/secret-scanning.js +++ /dev/null @@ -1,34 +0,0 @@ -import fs from 'fs' -import path from 'path' -import yaml from 'js-yaml' - -import getApplicableVersions from '#src/versions/lib/get-applicable-versions.js' -import { liquid } from '#src/content-render/index.js' - -const secretScanningPath = path.join('data/secret-scanning.yml') - -export default async function secretScanning(req, res, next) { - if (!req.pagePath.endsWith('code-security/secret-scanning/secret-scanning-patterns')) - return next() - - const secretScanningData = yaml.load(fs.readFileSync(secretScanningPath, 'utf-8')) - - const { currentVersion } = req.context - - req.context.secretScanningData = secretScanningData.filter((entry) => - getApplicableVersions(entry.versions).includes(currentVersion), - ) - - // Some entries might use Liquid syntax, so we need - // to execute that Liquid to get the actual value. - req.context.secretScanningData.forEach(async (entry, i) => { - for (const [key, value] of Object.entries(entry)) { - if (typeof value === 'string' && value.includes('{%')) { - const evaluated = yaml.load(await liquid.parseAndRender(value, req.context)) - entry[key] = evaluated - } - } - }) - - return next() -} diff --git a/src/secret-scanning/middleware/secret-scanning.ts b/src/secret-scanning/middleware/secret-scanning.ts new file mode 100644 index 0000000000..5555d5cc8c --- /dev/null +++ b/src/secret-scanning/middleware/secret-scanning.ts @@ -0,0 +1,43 @@ +import fs from 'fs' + +import yaml from 'js-yaml' +import type { NextFunction, Response } from 'express' + +import getApplicableVersions from '@/versions/lib/get-applicable-versions.js' +import { liquid } from '@/content-render/index.js' +import { ExtendedRequest, SecretScanningData } from '@/types' + +const secretScanningPath = 'data/secret-scanning.yml' + +export default async function secretScanning( + req: ExtendedRequest, + res: Response, + next: NextFunction, +) { + if (!req.pagePath!.endsWith('code-security/secret-scanning/secret-scanning-patterns')) + return next() + + const secretScanningData = yaml.load( + fs.readFileSync(secretScanningPath, 'utf-8'), + ) as SecretScanningData[] + + if (!req.context) throw new Error('request not contextualized') + const { currentVersion } = req.context + + req.context.secretScanningData = secretScanningData.filter((entry) => + getApplicableVersions(entry.versions).includes(currentVersion), + ) + + // Some entries might use Liquid syntax, so we need + // to execute that Liquid to get the actual value. + req.context.secretScanningData.forEach(async (entry) => { + for (const [key, value] of Object.entries(entry)) { + if (key === 'hasValidityCheck' && typeof value === 'string' && value.includes('{%')) { + const evaluated = yaml.load(await liquid.parseAndRender(value, req.context)) + entry[key] = evaluated as string + } + } + }) + + return next() +} diff --git a/src/types.ts b/src/types.ts index 793b83f32f..20110fed01 100644 --- a/src/types.ts +++ b/src/types.ts @@ -74,6 +74,18 @@ export type Context = { languages?: Languages redirectNotFound?: string earlyAccessPageLinks?: string + secretScanningData?: SecretScanningData[] +} + +export type SecretScanningData = { + provider: string + supportedSecret: string + secretType: string + versions: Record + isPublic: boolean + isPrivateWithGhas: boolean + hasPushProtection: boolean + hasValidityCheck: boolean | string } type Language = {