Skip to content

Commit

Permalink
Enhancements: CLI interface updates and column reordering (#362)
Browse files Browse the repository at this point in the history
* chore:reorder table coloums in cli dashboard

* feat: add flag to omit prompts

* feat:add flag to skip technology assesment

* feat: Dont show tech table if no data available

* fix: Show frames horizontal count component

* Revert "feat: Dont show tech table if no data available"

This reverts commit 79b3ca7.

* feat: Move tech table to bottom and don't show if no data available

* feat: add argument to pass no of urls to be analyzed

* fix: url limit

* fix:ignore creating technologies csv file

---------

Co-authored-by: Mayank Rana <mayankranax1@gmail.com>
  • Loading branch information
ayushnirwal and mayan-000 committed Dec 26, 2023
1 parent 9b6dea3 commit 6d1ba86
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import {
Sidebar,
useSidebar,
type SidebarItems,
SiteBoundariesIcon,
SiteBoundariesIconWhite,
} from '@ps-analysis-tool/design-system';

/**
Expand All @@ -42,8 +44,9 @@ interface LayoutProps {

const Layout = ({ selectedSite }: LayoutProps) => {
const [data, setData] = useState<SidebarItems>(TABS);
const { tabCookies } = useContentStore(({ state }) => ({
const { tabCookies, technologies } = useContentStore(({ state }) => ({
tabCookies: state.tabCookies,
technologies: state.technologies,
}));

const frameUrls = useMemo(
Expand Down Expand Up @@ -113,13 +116,21 @@ const Layout = ({ selectedSite }: LayoutProps) => {
<SiteAffectedCookies selectedSite={selectedSite} />
);

_data['technologies'].panel = (
<Technologies selectedSite={selectedSite} />
);
if (technologies && technologies.length > 0) {
_data['technologies'] = {
title: 'Technologies',
children: {},
icon: <SiteBoundariesIcon />,
selectedIcon: <SiteBoundariesIconWhite />,
panel: <Technologies selectedSite={selectedSite} />,
};
} else {
delete _data['technologies'];
}

return _data;
});
}, [frameUrls, selectedItemKey, selectedSite]);
}, [frameUrls, selectedItemKey, selectedSite, technologies]);

useEffect(() => {
if (selectedItemKey === null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const CookiesLandingContainer = ({
showInfoIcon={false}
associatedCookiesCount={Object.values(tabFrames).length}
showMessageBoxBody={false}
showHorizontalMatrix
>
<div className="flex flex-col">
<h3 className="text-xs font-bold text-darkest-gray dark:text-bright-gray uppercase">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,24 +61,33 @@ const CookiesListing = ({
enableHiding: false,
},
{
header: 'Value',
accessorKey: 'parsedCookie.value',
cell: (info: InfoType) => info,
header: 'Scope',
accessorKey: 'isFirstParty',
cell: (info: InfoType) => (
<p className="truncate w-full">
{!info ? 'Third Party' : 'First Party'}
</p>
),
},
{
header: 'Domain',
accessorKey: 'parsedCookie.domain',
cell: (info: InfoType) => info,
},
{
header: 'Path',
accessorKey: 'parsedCookie.path',
header: 'SameSite',
accessorKey: 'parsedCookie.samesite',
cell: (info: InfoType) => <span className="capitalize">{info}</span>,
},
{
header: 'Category',
accessorKey: 'analytics.category',
cell: (info: InfoType) => info,
},
{
header: 'Expires / Max-Age',
accessorKey: 'parsedCookie.expires',
cell: (info: InfoType) => (info ? info : 'Session'),
header: 'Platform',
accessorKey: 'analytics.platform',
cell: (info: InfoType) => info,
},
{
header: 'HttpOnly',
Expand All @@ -89,11 +98,6 @@ const CookiesListing = ({
</p>
),
},
{
header: 'SameSite',
accessorKey: 'parsedCookie.samesite',
cell: (info: InfoType) => <span className="capitalize">{info}</span>,
},
{
header: 'Secure',
accessorKey: 'parsedCookie.secure',
Expand All @@ -104,23 +108,19 @@ const CookiesListing = ({
),
},
{
header: 'Category',
accessorKey: 'analytics.category',
header: 'Value',
accessorKey: 'parsedCookie.value',
cell: (info: InfoType) => info,
},
{
header: 'Platform',
accessorKey: 'analytics.platform',
header: 'Path',
accessorKey: 'parsedCookie.path',
cell: (info: InfoType) => info,
},
{
header: 'Scope',
accessorKey: 'isFirstParty',
cell: (info: InfoType) => (
<p className="truncate w-full">
{!info ? 'Third Party' : 'First Party'}
</p>
),
header: 'Expires / Max-Age',
accessorKey: 'parsedCookie.expires',
cell: (info: InfoType) => (info ? info : 'Session'),
},
],
[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import React from 'react';
import {
CookieIcon,
CookieIconWhite,
SiteBoundariesIcon,
SiteBoundariesIconWhite,
type SidebarItems,
} from '@ps-analysis-tool/design-system';

Expand All @@ -32,12 +30,6 @@ const Tabs: SidebarItems = {
icon: <CookieIcon />,
selectedIcon: <CookieIconWhite />,
},
technologies: {
title: 'Technologies',
children: {},
icon: <SiteBoundariesIcon />,
selectedIcon: <SiteBoundariesIconWhite />,
},
'affected-cookies': {
title: 'Affected Cookies',
children: {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,18 @@ export const genereateAndDownloadCSVReports = (
}

const allCookiesCSV = generateAllCookiesCSV(siteAnalysisData);
const technologyDataCSV = generateTechnologyCSV(siteAnalysisData);
let technologyDataCSV = null;
if (siteAnalysisData.technologyData.length > 0) {
technologyDataCSV = generateTechnologyCSV(siteAnalysisData);
}
const affectedCookiesDataCSV = generateAffectedCookiesCSV(siteAnalysisData);
const summaryDataCSV = generateSummaryDataCSV(siteAnalysisData);

const zip = new JSZip();
zip.file('cookies.csv', allCookiesCSV);
zip.file('technologies.csv', technologyDataCSV);
if (technologyDataCSV) {
zip.file('technologies.csv', technologyDataCSV);
}
zip.file('affected-cookies.csv', affectedCookiesDataCSV);
zip.file('report.csv', summaryDataCSV);
zip.file('report.json', JSON.stringify(JSONReport, null, 4));
Expand Down
90 changes: 61 additions & 29 deletions packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import { checkPortInUse } from './utils/checkPortInUse';
events.EventEmitter.defaultMaxListeners = 15;

const DELAY_TIME = 20000;

const program = new Command();

program
Expand All @@ -52,10 +51,16 @@ program
'-p, --sitemap-path <value>',
'Path to a sitmap saved in the file system'
)
.option('-ul, --url-limit <value>', 'No of Urls to analyze')
.option(
'-nh, --no-headless ',
'Flag for running puppeteer in non headless mode'
);
)
.option(
'-np, --no-prompts',
'Flags for skipping all prompts. Default options will be used'
)
.option('-nt, --no-technology', 'Flags for skipping technology analysis.');

program.parse();

Expand All @@ -77,7 +82,8 @@ const validateArgs = async (
url: string,
sitemapUrl: string,
csvPath: string,
sitemapPath: string
sitemapPath: string,
numberOfUrls: string
) => {
if (!url && !sitemapUrl && !csvPath && !sitemapPath) {
console.log(
Expand Down Expand Up @@ -132,6 +138,13 @@ const validateArgs = async (
process.exit(1);
}
}

if (numberOfUrls) {
if (isNaN(parseInt(numberOfUrls))) {
console.log(`${numberOfUrls} is not valid numeric value`);
process.exit(1);
}
}
};

const getUrlListFromArgs = async (
Expand Down Expand Up @@ -262,16 +275,20 @@ const getUrlListFromArgs = async (
return urls;
};

// eslint-disable-next-line complexity
(async () => {
await initialize();

const url = program.opts().url;
const sitemapUrl = program.opts().sitemapUrl;
const csvPath = program.opts().csvPath;
const sitemapPath = program.opts().sitemapPath;
const numberOfUrlsInput = program.opts().urlLimit;
const isHeadless = Boolean(program.opts().headless);
const shouldSkipPrompts = !program.opts().prompts;
const shouldSkipTechnologyAnalysis = !program.opts().technology;

validateArgs(url, sitemapUrl, csvPath, sitemapPath);
validateArgs(url, sitemapUrl, csvPath, sitemapPath, numberOfUrlsInput);

const prefix =
url || sitemapUrl
Expand All @@ -292,19 +309,29 @@ const getUrlListFromArgs = async (
let urlsToProcess: string[] = [];

if (sitemapUrl || csvPath || sitemapPath) {
const userInput = await Utility.askUserInput(
`Provided ${sitemapUrl || sitemapPath ? 'Sitemap' : 'CSV file'} has ${
urls.length
} pages. Please enter the number of pages you want to analyze (Default ${
urls.length
}):`,
{ default: urls.length.toString() }
);
let numberOfUrls: number = isNaN(userInput)
? urls.length
: parseInt(userInput);

numberOfUrls = numberOfUrls < urls.length ? numberOfUrls : urls.length;
let numberOfUrls: number | null = null;
let userInput: string | null = null;

if (!shouldSkipPrompts && !numberOfUrlsInput) {
userInput = await Utility.askUserInput(
`Provided ${sitemapUrl || sitemapPath ? 'Sitemap' : 'CSV file'} has ${
urls.length
} pages. Please enter the number of pages you want to analyze (Default ${
urls.length
}):`,
{ default: urls.length.toString() }
);
numberOfUrls =
userInput && isNaN(parseInt(userInput))
? urls.length
: parseInt(userInput);
} else if (numberOfUrlsInput) {
console.log(`Analysing ${numberOfUrlsInput} urls.`);
numberOfUrls = parseInt(numberOfUrlsInput);
} else {
console.log(`Analysing all ${urls.length} urls.`);
numberOfUrls = urls.length;
}

urlsToProcess = urlsToProcess.concat(urls.splice(0, numberOfUrls));
} else if (url) {
Expand All @@ -329,24 +356,29 @@ const getUrlListFromArgs = async (
spinnies.succeed('cookie-spinner', {
text: 'Done analyzing cookies.',
});
spinnies.add('technology-spinner', {
text: 'Analysing technologies',
});

const technologyAnalysisData = await analyzeTechnologiesUrlsInBatches(
urlsToProcess,
3,
urlsToProcess.length !== 1 ? spinnies : undefined
);
let technologyAnalysisData: any = null;

Check warning on line 360 in packages/cli/src/index.ts

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type

spinnies.succeed('technology-spinner', {
text: 'Done analyzing technologies.',
});
if (!shouldSkipTechnologyAnalysis) {
spinnies.add('technology-spinner', {
text: 'Analysing technologies',
});

technologyAnalysisData = await analyzeTechnologiesUrlsInBatches(
urlsToProcess,
3,
urlsToProcess.length !== 1 ? spinnies : undefined
);

spinnies.succeed('technology-spinner', {
text: 'Done analyzing technologies.',
});
}

const result = urlsToProcess.map((_url, ind) => {
return {
pageUrl: _url,
technologyData: technologyAnalysisData[ind],
technologyData: technologyAnalysisData ? technologyAnalysisData[ind] : [],
cookieData: cookieAnalysisData[ind].cookieData,
};
});
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/utils/utility/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ export default class Utility {
public static async askUserInput(
message: string,
options: object = {}
): Promise<any> {
const userInput: any = await promptly.prompt(message, options);
): Promise<string> {
const userInput: string = await promptly.prompt(message, options);
return userInput;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/common/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
"esModuleInterop": true,
"moduleResolution": "node"
},
"exclude": ["**/tests/**/*.ts"]
"exclude": ["**/tests/**/*.ts", "dist/**", "dist-types/**"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const CookiesLanding = ({
associatedCookiesCount = null,
showMessageBoxBody = true,
showBlockedCookiesSection = false,
showHorizontalMatrix = false,
}: CookiesLandingProps) => {
const cookieStats = prepareCookiesCount(tabCookies);
const cookiesStatsComponents = prepareCookieStatsComponents(cookieStats);
Expand Down Expand Up @@ -104,7 +105,7 @@ const CookiesLanding = ({
componentData={cookiesStatsComponents.legend}
tabFrames={tabFrames}
showInfoIcon={showInfoIcon}
showHorizontalMatrix={false}
showHorizontalMatrix={showHorizontalMatrix}
associatedCookiesCount={associatedCookiesCount}
/>
{children && <div className="mt-8">{children}</div>}
Expand Down

0 comments on commit 6d1ba86

Please sign in to comment.