Skip to content

Fix/security recommendations #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/trivy-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ on:
jobs:
trivy-scan:
runs-on: 'ubuntu-latest'
permissions:
security-events: write
contents: read

steps:
- uses: actions/checkout@v4
with:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ node_modules
node_modules/**
gen/src/icons/**
dist.web.zip
node_modules
gen/src/GraphQL/**
gen/src/GraphQL
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
node_modules/**
*.hbs
*.hbs
CHANGELOG.md
1 change: 1 addition & 0 deletions gen/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
.env
src/icons/**
src/GraphQL/**
84 changes: 61 additions & 23 deletions gen/src/generateImages.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// generate.ts
import chalk from 'chalk'
import { execSync } from 'child_process'
import { execFileSync } from 'child_process'
import dotenv from 'dotenv'
import fs from 'fs-extra'
import path from 'path'
import { FigmaDocument, IconFontData, IconMapper } from './interfaces'


// Load environment variables
dotenv.config()
//Retrieve Figma Access Token and Canvas from .env file
Expand Down Expand Up @@ -37,7 +38,7 @@ filesToDelete.push(svgImagesUrlsPath)
const iconMapper: IconMapper = {}

try {
;(async () => {
; (async () => {
try {
console.log(chalk.blueBright('1. Using curl to fetch data from Figma API...'))

Expand All @@ -57,10 +58,26 @@ try {
// console.log(chalk.blue(' Command:'), curlCommand);

// Execute curl with inherit stdio to show real-time progress
execSync(curlCommand, {
timeout: 120000,
env: execEnvironment
})
try {
execFileSync(
'curl',
[
'-s',
'-o',
tempFilePath,
'-H',
`X-Figma-Token: ${FIGMA_API_TOKEN}`,
FIGMA_CANVAS_URL
],
{
timeout: 120000,
env: execEnvironment
}
)
} catch (error) {
console.error(chalk.red(' Error fetching data from Figma API:'), error)
throw error
}

// Read from file
console.log(chalk.blueBright('2. Reading response from file...'))
Expand Down Expand Up @@ -199,8 +216,7 @@ async function getImageUrls(

console.log(
chalk.gray(
` Processing ${imageType} batch ${i + 1}/${batches.length} (${
batch.length
` Processing ${imageType} batch ${i + 1}/${batches.length} (${batch.length
} icons)`
)
)
Expand All @@ -214,10 +230,21 @@ async function getImageUrls(
console.log(chalk.yellow(` Downloading URLs for ${imageType} batch ${i + 1}`))
// Execute curl with inherit stdio to show real-time progress
try {
execSync(curlImagesURLCommand, {
timeout: 120000,
env: execEnvironment
})
execFileSync(
'curl',
[
'-s',
'-o',
batchFilePath,
'-H',
`X-Figma-Token: ${FIGMA_API_TOKEN}`,
`https://api.figma.com/v1/images/${figmaFileKey}?ids=${batchKeysString}&format=${imageType}`
],
{
timeout: 120000,
env: execEnvironment
}
)

// Read and process the batch response
const batchData = JSON.parse(fs.readFileSync(batchFilePath, 'utf-8'))
Expand Down Expand Up @@ -269,30 +296,41 @@ async function downloadImages(
) {
const totalIcons = Object.keys(allImageUrls).length
let currentIcon = 0
Object.entries(allImageUrls).forEach(([ImageID, ImageUrl]) => {

for (const [ImageID, ImageUrl] of Object.entries(allImageUrls) as [string, string][]) {
const ImageFileName = iconMapper[ImageID].name + '.' + imageType || null
const variant = iconMapper[ImageID].variant || null

if (ImageFileName !== null && variant !== null) {
const folder = path.resolve(__dirname, 'icons', `${imageType}s`, variant)
console.log(
chalk.gray(
` Downloading Image: ${ImageFileName} ${variant} (${
currentIcon + 1
` Downloading Image: ${ImageFileName} ${variant} (${currentIcon + 1
}/${totalIcons})`
)
)

// Create Image directory if it doesn't exist
fs.ensureDirSync(folder)

// Download Image data
const curlImageCommand = `curl -s -o "${folder}/${ImageFileName}" "${ImageUrl}"`

execSync(curlImageCommand, {
timeout: 30000,
env: execEnvironment
})
const outputFilePath = path.join(folder, ImageFileName)
try {
execFileSync(
'curl',
[
'-s',
'-o',
outputFilePath,
ImageUrl.toString()
],
{
timeout: 30000,
env: execEnvironment
}
)
} catch (error) {
console.error(chalk.red(` Error downloading ${ImageFileName}:`), error)
}
} else {
console.error(
chalk.underline.yellow(
Expand All @@ -302,6 +340,6 @@ async function downloadImages(
}

currentIcon++
})
}
console.log(chalk.green(` All ${currentIcon} ${imageType} images were downloaded`))
}