mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
fix validation harder
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
d050d6c0ea
commit
1c17420e6c
@ -4,23 +4,18 @@ import tar, { ExtractOptions, FileStat } from "tar";
|
||||
import path from "path";
|
||||
|
||||
export interface ReadFileFromTarOpts {
|
||||
fileName?: string;
|
||||
fileMatcher?(path: string, entry: FileStat): boolean;
|
||||
notFoundMessage?: string;
|
||||
tarPath: string;
|
||||
filePath: string;
|
||||
parseJson?: boolean;
|
||||
}
|
||||
|
||||
export function readFileFromTar(tarFilePath: string, opts: ReadFileFromTarOpts): Promise<Buffer> {
|
||||
export function readFileFromTar<R = Buffer>({tarPath, filePath, parseJson}: ReadFileFromTarOpts): Promise<R> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const fileChunks: Buffer[] = [];
|
||||
const {
|
||||
fileName,
|
||||
fileMatcher = (path: string) => path === fileName,
|
||||
notFoundMessage = "File not found",
|
||||
} = opts;
|
||||
|
||||
await tar.list({
|
||||
file: tarFilePath,
|
||||
filter: fileMatcher,
|
||||
file: tarPath,
|
||||
filter: path => path === filePath,
|
||||
onentry(entry: FileStat) {
|
||||
entry.on("data", chunk => {
|
||||
fileChunks.push(chunk);
|
||||
@ -29,17 +24,28 @@ export function readFileFromTar(tarFilePath: string, opts: ReadFileFromTarOpts):
|
||||
reject(`Reading ${entry.path} error: ${err}`);
|
||||
});
|
||||
entry.once("end", () => {
|
||||
resolve(Buffer.concat(fileChunks));
|
||||
const data = Buffer.concat(fileChunks);
|
||||
const result = parseJson ? JSON.parse(data.toString("utf8")) : data;
|
||||
resolve(result);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
if (!fileChunks.length) {
|
||||
reject(notFoundMessage);
|
||||
reject(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function listTarEntries(filePath: string): Promise<string[]> {
|
||||
const entries: string[] = [];
|
||||
await tar.list({
|
||||
file: filePath,
|
||||
onentry: (entry: FileStat) => entries.push(entry.path as any as string),
|
||||
});
|
||||
return entries;
|
||||
}
|
||||
|
||||
export function extractTar(filePath: string, opts: ExtractOptions & { sync?: boolean } = {}) {
|
||||
return tar.extract({
|
||||
file: filePath,
|
||||
|
||||
@ -20,8 +20,8 @@ import { extensionLoader } from "../../../extensions/extension-loader";
|
||||
import { extensionDiscovery, manifestFilename } from "../../../extensions/extension-discovery";
|
||||
import { LensExtensionManifest, sanitizeExtensionName } from "../../../extensions/lens-extension";
|
||||
import { Notifications } from "../notifications";
|
||||
import { downloadFile, escapeRegExp } from "../../../common/utils";
|
||||
import { extractTar, readFileFromTar } from "../../../common/utils/tar";
|
||||
import { downloadFile } from "../../../common/utils";
|
||||
import { extractTar, listTarEntries, readFileFromTar } from "../../../common/utils/tar";
|
||||
import { docsUrl } from "../../../common/vars";
|
||||
|
||||
interface InstallRequest {
|
||||
@ -142,14 +142,20 @@ export class Extensions extends React.Component {
|
||||
}
|
||||
|
||||
async validatePackage(filePath: string): Promise<LensExtensionManifest> {
|
||||
const manifestMatcher = RegExp(String.raw`^(\w+\/)?${escapeRegExp(manifestFilename)}$`);
|
||||
const tarFiles = await listTarEntries(filePath);
|
||||
|
||||
const packageJson: Buffer = await readFileFromTar(filePath, {
|
||||
notFoundMessage: `Invalid extension package, ${manifestFilename} not found`,
|
||||
// tarball from npm contains single root folder "package/*"
|
||||
fileMatcher: (path: string) => !!path.match(manifestMatcher),
|
||||
// tarball from npm contains single root folder "package/*"
|
||||
const hasSingleRootFolder = tarFiles.every(entry => entry.startsWith(tarFiles[0]));
|
||||
const manifestLocation = hasSingleRootFolder ? path.join(tarFiles[0], manifestFilename) : manifestFilename;
|
||||
|
||||
if(!tarFiles.includes(manifestLocation)) {
|
||||
throw `invalid package, ${manifestFilename} not found`;
|
||||
}
|
||||
const manifest = await readFileFromTar<LensExtensionManifest>({
|
||||
tarPath: filePath,
|
||||
filePath: manifestLocation,
|
||||
parseJson: true,
|
||||
});
|
||||
const manifest: LensExtensionManifest = JSON.parse(packageJson.toString("utf8"));
|
||||
if (!manifest.lens && !manifest.renderer) {
|
||||
throw `${manifestFilename} must specify "main" and/or "renderer" fields`;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user