2022-01-08 09:31:58 +00:00
|
|
|
'use strict'
|
|
|
|
|
2022-12-17 06:47:27 +00:00
|
|
|
// Attempt to download GitLab job artifact and failover to GitHub if unsuccessful.
|
|
|
|
// In GitLab Pages, the latest job status will be marked as unknown/failed if the repo has newer commit.
|
|
|
|
// The link to download the latest job artifact will also be unavailable when that happens,
|
|
|
|
// unless manually queried through API.
|
|
|
|
// Instead of using the API, I find it easier to failover to GitHub.
|
|
|
|
// ref: https://gitlab.com/gitlab-org/gitlab/-/issues/29257
|
|
|
|
|
2023-10-01 09:46:12 +00:00
|
|
|
import unzip from 'extract-zip'
|
|
|
|
import { basename, dirname, join } from 'node:path'
|
|
|
|
import { mkdir, readdir, rm } from 'node:fs/promises'
|
|
|
|
import { createWriteStream } from 'node:fs'
|
|
|
|
import { pipeline } from 'node:stream/promises'
|
|
|
|
import { fileURLToPath } from 'node:url'
|
2024-04-06 22:49:24 +00:00
|
|
|
import { Readable } from 'node:stream'
|
2022-01-08 09:31:58 +00:00
|
|
|
|
2023-10-01 09:46:12 +00:00
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
2022-01-08 09:31:58 +00:00
|
|
|
const rootPath = join(__dirname, '..')
|
|
|
|
const tmpPath = join(rootPath, 'tmp')
|
2022-01-25 09:10:43 +00:00
|
|
|
const publicPath = join(rootPath, 'public')
|
2022-03-19 05:33:26 +00:00
|
|
|
const projects = [
|
|
|
|
'urlhaus-filter',
|
|
|
|
'phishing-filter',
|
2022-03-20 06:51:12 +00:00
|
|
|
'tracking-filter',
|
2023-01-01 00:09:47 +00:00
|
|
|
'vn-badsite-filter',
|
2023-06-13 08:42:10 +00:00
|
|
|
'botnet-filter',
|
|
|
|
// 'pup-filter'
|
2022-03-19 05:33:26 +00:00
|
|
|
]
|
2022-01-08 09:31:58 +00:00
|
|
|
|
2022-03-19 05:33:26 +00:00
|
|
|
const pipelineStatus = async (url) => {
|
2024-04-06 22:49:24 +00:00
|
|
|
console.log(`Checking pipeline from "${url}"`)
|
2022-03-19 05:33:26 +00:00
|
|
|
try {
|
2024-04-06 22:49:24 +00:00
|
|
|
const svg = await (await fetch(url)).text()
|
2023-08-06 11:20:20 +00:00
|
|
|
if (svg.includes('failed')) throw new Error('last gitlab pipeline failed')
|
2022-03-19 05:33:26 +00:00
|
|
|
} catch ({ message }) {
|
|
|
|
throw new Error(message)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const dl = async (project) => {
|
|
|
|
const filename = project + '.zip'
|
2022-05-21 02:51:52 +00:00
|
|
|
const link = `https://gitlab.com/malware-filter/${project}/-/jobs/artifacts/main/download?job=pages`
|
2023-08-06 11:16:26 +00:00
|
|
|
const zipPath = join(tmpPath, filename)
|
2022-05-21 02:51:52 +00:00
|
|
|
const pipelineUrl = `https://gitlab.com/malware-filter/${project}/badges/main/pipeline.svg`
|
2023-08-06 11:16:02 +00:00
|
|
|
let isMirror = false
|
2022-01-25 09:10:43 +00:00
|
|
|
|
2022-01-11 06:23:08 +00:00
|
|
|
console.log(`Downloading ${filename} from "${link}"`)
|
|
|
|
try {
|
|
|
|
await pipeline(
|
2024-04-06 22:49:24 +00:00
|
|
|
Readable.fromWeb((await fetch(link)).body),
|
2023-08-06 11:16:26 +00:00
|
|
|
createWriteStream(zipPath)
|
2022-01-11 06:23:08 +00:00
|
|
|
)
|
2022-03-19 05:33:26 +00:00
|
|
|
await pipelineStatus(pipelineUrl)
|
2022-01-11 06:23:08 +00:00
|
|
|
} catch ({ message }) {
|
2022-01-25 09:10:43 +00:00
|
|
|
console.error(JSON.stringify({
|
2022-01-11 06:23:08 +00:00
|
|
|
error: message,
|
|
|
|
link,
|
|
|
|
filename
|
|
|
|
}))
|
2022-01-25 09:10:43 +00:00
|
|
|
|
2022-03-19 05:33:26 +00:00
|
|
|
const mirrorLink = `https://nightly.link/curbengh/${project}/workflows/pages/main/public.zip`
|
2022-01-25 09:10:43 +00:00
|
|
|
console.log(`Downloading ${filename} from "${mirrorLink}"`)
|
2023-08-06 11:16:02 +00:00
|
|
|
isMirror = true
|
2022-01-25 09:10:43 +00:00
|
|
|
|
|
|
|
try {
|
|
|
|
await pipeline(
|
2024-04-06 22:49:24 +00:00
|
|
|
Readable.fromWeb((await fetch(mirrorLink)).body),
|
2023-08-06 11:16:26 +00:00
|
|
|
createWriteStream(zipPath)
|
2022-01-25 09:10:43 +00:00
|
|
|
)
|
|
|
|
} catch ({ message }) {
|
|
|
|
throw new Error(JSON.stringify({
|
|
|
|
error: message,
|
|
|
|
link: mirrorLink,
|
|
|
|
filename
|
|
|
|
}))
|
|
|
|
}
|
2022-01-11 06:23:08 +00:00
|
|
|
}
|
2023-08-06 11:16:26 +00:00
|
|
|
|
|
|
|
console.log(`Extracting ${basename(zipPath)}...`)
|
|
|
|
if (isMirror === false) {
|
|
|
|
await unzip(zipPath, { dir: rootPath })
|
|
|
|
} else {
|
|
|
|
await unzip(zipPath, { dir: publicPath })
|
|
|
|
}
|
2022-01-25 09:10:43 +00:00
|
|
|
}
|
|
|
|
|
2022-01-11 06:23:08 +00:00
|
|
|
const f = async () => {
|
|
|
|
await mkdir(tmpPath, { recursive: true })
|
2022-01-25 09:10:43 +00:00
|
|
|
await mkdir(publicPath, { recursive: true })
|
2022-03-19 05:33:26 +00:00
|
|
|
await Promise.all(projects.map((project) => { return dl(project) }))
|
2023-08-22 12:47:06 +00:00
|
|
|
|
|
|
|
const files = await readdir(publicPath)
|
|
|
|
await Promise.all(files.map(async (file) => {
|
|
|
|
// cf pages limits file size to 26.2MB
|
|
|
|
// compressed (br/gz) files are excluded
|
|
|
|
if (file.startsWith('phishing-filter') && file.endsWith('.rules')) {
|
|
|
|
await rm(join(publicPath, file))
|
|
|
|
}
|
|
|
|
}))
|
2022-01-08 09:31:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
f()
|