1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

fix validation

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman 2020-11-24 17:04:39 +02:00
parent 12c3422c28
commit d050d6c0ea
4 changed files with 14 additions and 6 deletions

View File

@ -0,0 +1,5 @@
// Helper to sanitize / escape special chars for passing to RegExp-constructor
export function escapeRegExp(str: string) {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

View File

@ -16,3 +16,4 @@ export * from "./singleton";
export * from "./openExternal"; export * from "./openExternal";
export * from "./rectify-array"; export * from "./rectify-array";
export * from "./downloadFile"; export * from "./downloadFile";
export * from "./escapeRegExp";

View File

@ -16,7 +16,7 @@ export interface InstalledExtension {
} }
const logModule = "[EXTENSION-DISCOVERY]"; const logModule = "[EXTENSION-DISCOVERY]";
const manifestFilename = "package.json"; export const manifestFilename = "package.json";
/** /**
* Returns true if the lstat is for a directory-like file (e.g. isDirectory or symbolic link) * Returns true if the lstat is for a directory-like file (e.g. isDirectory or symbolic link)

View File

@ -17,10 +17,10 @@ import { PageLayout } from "../layout/page-layout";
import { Clipboard } from "../clipboard"; import { Clipboard } from "../clipboard";
import logger from "../../../main/logger"; import logger from "../../../main/logger";
import { extensionLoader } from "../../../extensions/extension-loader"; import { extensionLoader } from "../../../extensions/extension-loader";
import { extensionDiscovery } from "../../../extensions/extension-discovery"; import { extensionDiscovery, manifestFilename } from "../../../extensions/extension-discovery";
import { LensExtensionManifest, sanitizeExtensionName } from "../../../extensions/lens-extension"; import { LensExtensionManifest, sanitizeExtensionName } from "../../../extensions/lens-extension";
import { Notifications } from "../notifications"; import { Notifications } from "../notifications";
import { downloadFile } from "../../../common/utils"; import { downloadFile, escapeRegExp } from "../../../common/utils";
import { extractTar, readFileFromTar } from "../../../common/utils/tar"; import { extractTar, readFileFromTar } from "../../../common/utils/tar";
import { docsUrl } from "../../../common/vars"; import { docsUrl } from "../../../common/vars";
@ -142,14 +142,16 @@ export class Extensions extends React.Component {
} }
async validatePackage(filePath: string): Promise<LensExtensionManifest> { async validatePackage(filePath: string): Promise<LensExtensionManifest> {
const manifestMatcher = RegExp(String.raw`^(\w+\/)?${escapeRegExp(manifestFilename)}$`);
const packageJson: Buffer = await readFileFromTar(filePath, { const packageJson: Buffer = await readFileFromTar(filePath, {
notFoundMessage: `Invalid extension package, ${manifestFilename} not found`,
// tarball from npm contains single root folder "package/*" // tarball from npm contains single root folder "package/*"
fileMatcher: (path: string) => !!path.match(/(\w+\/)?package\.json$/), fileMatcher: (path: string) => !!path.match(manifestMatcher),
notFoundMessage: "Invalid extension, package.json not found",
}); });
const manifest: LensExtensionManifest = JSON.parse(packageJson.toString("utf8")); const manifest: LensExtensionManifest = JSON.parse(packageJson.toString("utf8"));
if (!manifest.lens && !manifest.renderer) { if (!manifest.lens && !manifest.renderer) {
throw `package.json must specify "main" and/or "renderer" fields`; throw `${manifestFilename} must specify "main" and/or "renderer" fields`;
} }
return manifest; return manifest;
} }