Skip to content

Commit

Permalink
feat: add rules
Browse files Browse the repository at this point in the history
  • Loading branch information
EmmanuelDemey committed Sep 20, 2024
1 parent 098bb72 commit de202e5
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 49 deletions.
7 changes: 7 additions & 0 deletions audit/apps/audit/src/checkers/async/checker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Result } from '../result';

export type Checker = (
url: string,
parsers: { name: string; result: any }[],
{ urls, page }?: { urls: Set<string>; page: Page }
) => Promise<Result | undefined>;
51 changes: 6 additions & 45 deletions audit/apps/audit/src/checkers/async/http-system-checker.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,8 @@
import puppeteer, { Page } from 'puppeteer';

type Checker = (
url: string,
parsers: { name: string; result: any }[],
{ urls, page }?: { urls: Set<string>; page: Page }
) => Promise<{ name: string; message?: string; result: any } | undefined>;

const hasValidDoctype: Checker = async (
_url: string,
parsers: { name: string; result: any }[],
{ page }: { page: Page }
): Promise<{ name: string; result: any; message: string } | undefined> => {
const doctype = await page.evaluate(() => {
const node = document.doctype;
if (node) {
return {
name: node.name,
publicId: node.publicId,
systemId: node.systemId,
};
}
return null; // Si pas de doctype
});

if (!doctype) {
return Promise.resolve({
name: 'hasValidDoctype',
result: undefined,
message: 'You do not have a doctype',
});
}

if (
doctype.name !== 'html' ||
doctype.publicId !== '' ||
doctype.systemId !== ''
) {
return Promise.resolve({
name: 'hasValidDoctype',
result: doctype,
message: 'You do not have a valide doctype',
});
}
return Promise.resolve(undefined);
};
import { Checker } from './checker';
import { hasValidDoctype } from './rules/hasValidDoctype';
import { hasValidElementInsideHead } from './rules/hasValidElementInsideHead';
import { hasBasicLayoutElement } from './rules/hasBasicLayoutElement';

const hasTitle: Checker = async (
_url: string,
Expand Down Expand Up @@ -148,6 +107,8 @@ export class HttpChecker {
hasAtLeastOneAnalyticsTools,
hasTitle,
hasValidDoctype,
hasValidElementInsideHead,
hasBasicLayoutElement,
];
constructor(private parsers: { name: string; result: any }[]) {}
async check(url: string) {
Expand Down
46 changes: 46 additions & 0 deletions audit/apps/audit/src/checkers/async/rules/hasBasicLayoutElement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Checker } from '../checker';
import { Page } from 'puppeteer';

export const hasBasicLayoutElement: Checker = async (
_url: string,
parsers: { name: string; result: any }[],
{ page }: { page: Page }
): Promise<{ name: string; result: any; message: string } | undefined> => {
const header = await page.evaluate(() => {
return document.querySelector('header');
});

if (header === null) {
return Promise.resolve({
name: 'hasBasicLayoutElement',
result: undefined,
message: 'Its looks like yo do not have any header',
});
}

const body = await page.evaluate(() => {
return document.querySelector('body');
});

if (body === null) {
return Promise.resolve({
name: 'hasBasicLayoutElement',
result: undefined,
message: 'Its looks like yo do not have any body',
});
}

const footer = await page.evaluate(() => {
return document.querySelector('header');
});

if (footer === null) {
return Promise.resolve({
name: 'hasBasicLayoutElement',
result: undefined,
message: 'Its looks like yo do not have any footer',
});
}

return Promise.resolve(undefined);
};
41 changes: 41 additions & 0 deletions audit/apps/audit/src/checkers/async/rules/hasValidDoctype.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Checker } from "../checker";
import { Page } from 'puppeteer';

export const hasValidDoctype: Checker = async (
_url: string,
parsers: { name: string; result: any }[],
{ page }: { page: Page }
): Promise<{ name: string; result: any; message: string } | undefined> => {
const doctype = await page.evaluate(() => {
const node = document.doctype;
if (node) {
return {
name: node.name,
publicId: node.publicId,
systemId: node.systemId,
};
}
return null; // Si pas de doctype
});

if (!doctype) {
return Promise.resolve({
name: 'hasValidDoctype',
result: undefined,
message: 'You do not have a doctype',
});
}

if (
doctype.name !== 'html' ||
doctype.publicId !== '' ||
doctype.systemId !== ''
) {
return Promise.resolve({
name: 'hasValidDoctype',
result: doctype,
message: 'You do not have a valide doctype',
});
}
return Promise.resolve(undefined);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Checker } from '../checker';
import { Page } from 'puppeteer';

export const hasValidElementInsideHead: Checker = async (
_url: string,
parsers: { name: string; result: any }[],
{ page }: { page: Page }
): Promise<{ name: string; result: any; message: string } | undefined> => {
const elements = await page.evaluate(() => {
return Array.from(document.querySelectorAll('head > *')).filter(
(node) =>
!['script', 'style', 'link', 'meta', 'title'].includes(
node.tagName.toLowerCase()
)
);
});

if (elements.length > 0) {
return Promise.resolve({
name: 'hasValidElementInsideHead',
result: elements,
message: 'You have invalid elements inside head',
});
}

return Promise.resolve(undefined);
};
1 change: 1 addition & 0 deletions audit/apps/audit/src/checkers/result.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type Result = { name: string; result: any; message?: string };
16 changes: 12 additions & 4 deletions audit/apps/audit/src/checkers/sync/file-system-checker.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { execSync } from 'node:child_process';
import { readFileSync } from 'node:fs';
import { Result } from '../result';

type Checker = (
parsers: { name: string; result: any }[]
) => { name: string; result: any } | undefined;
type Checker = (parsers: { name: string; result: any }[]) => Result | undefined;

const checkIfDevOrProdDependenciesPresent = (
path: string[],
Expand All @@ -30,7 +29,8 @@ const checkIfDevOrProdDependenciesPresent = (

const generateDependenciesRule = (
packageName: string,
devDependencies = false
devDependencies = false,
replacement?: string
): Checker => {
return (parsers: { name: string; result: any }[]) => {
const packageManagerConfigurationFilePath = parsers.find(
Expand All @@ -50,6 +50,13 @@ const generateDependenciesRule = (
return;
}

if (replacement) {
return {
name: `has_${packageName}_dependency`,
result,
message: `You should use ${replacement} instead of ${packageName}`,
};
}
return { name: `has_${packageName}_dependency`, result };
};
};
Expand All @@ -59,6 +66,7 @@ const dependenciesCheck = [
generateDependenciesRule('underscore'),
generateDependenciesRule('underscore'),
generateDependenciesRule('karma', true),
generateDependenciesRule('react-scripts', true, 'vite'),
];

const npmAudit = (parsers: { name: string; result: any }[]) => {
Expand Down

0 comments on commit de202e5

Please sign in to comment.