New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@plumier/core

Package Overview
Dependencies
Maintainers
1
Versions
645
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@plumier/core - npm Package Compare versions

Comparing version 1.0.2-canary.kp2a4t.0 to 1.0.2

17

CHANGELOG.md

@@ -6,4 +6,21 @@ # Change Log

## [1.0.2](https://github.com/plumier/plumier/compare/v1.0.0...v1.0.2) (2021-06-06)
### Bug Fixes
* Fix array relation should not accessible (read/write) on first class entity ([#956](https://github.com/plumier/plumier/issues/956)) ([58058a5](https://github.com/plumier/plumier/commit/58058a54861447d04cedfd585d60687eb3d4e1d4))
* Fix authorization evaluation issue on undefined value should be skipped ([#945](https://github.com/plumier/plumier/issues/945)) ([7e9acd3](https://github.com/plumier/plumier/commit/7e9acd330032f7f829ef738668768daf4c379566))
* Fix response authorization error when no ID provided on response ([#948](https://github.com/plumier/plumier/issues/948)) ([2b5429e](https://github.com/plumier/plumier/commit/2b5429ef30f9cfb3843fb07c5af271dd3223b14c))
* Fix Swagger urls not visible on route analysis ([#935](https://github.com/plumier/plumier/issues/935)) ([e858197](https://github.com/plumier/plumier/commit/e8581971087ddde0d3642aaa930ac36eafc9bc26))
* Give proper error message when action return type array, but got non array ([#934](https://github.com/plumier/plumier/issues/934)) ([05cd377](https://github.com/plumier/plumier/commit/05cd377823e789e1c18c3902cad69798f196549e))
* Give proper error message when found cross reference entity issue ([#933](https://github.com/plumier/plumier/issues/933)) ([0d09d22](https://github.com/plumier/plumier/commit/0d09d22589b751f54c0c4bd03de9f0581334b2ff))
* Unable to apply write authorization on relation property ([#941](https://github.com/plumier/plumier/issues/941)) ([39ff2b6](https://github.com/plumier/plumier/commit/39ff2b638d9cc5895b1368ef5e419e28c142b359))
## 1.0.1 (2021-05-18)
**Note:** Version bump only for package @plumier/core

48

lib/authorization.js

@@ -86,2 +86,3 @@ "use strict";

async authorize(ctx) {
var _a, _b;
for (const Auth of this.policies.reverse()) {

@@ -92,3 +93,3 @@ const authPolicy = new Auth();

const authorize = await authPolicy.authorize(ctx);
log.debug("%s by %s", authorize ? "AUTHORIZED" : "FORBIDDEN", authPolicy.friendlyName());
log.debug("%s -> %s.%s by %s", authorize ? "AUTHORIZED" : "FORBIDDEN", (_b = (_a = ctx.metadata.current.parent) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : "", ctx.metadata.current.name, authPolicy.friendlyName());
if (authorize)

@@ -185,4 +186,3 @@ return true;

const entity = ctx.metadata.current.parent;
const meta = reflect_1.reflect(entity);
const prop = meta.properties.find(p => p.decorators.some((x) => x.kind === "plumier-meta:entity-id"));
const prop = common_1.entityHelper.getIdProp(entity);
if (!prop)

@@ -328,3 +328,18 @@ throw new Error(`Entity ${entity.name} doesn't have primary ID information required for entity policy`);

return [];
else if (Array.isArray(meta.type)) {
// skip check on GET method
if (ctx.info.ctx.method === "GET")
return [];
const decorators = meta.decorators.filter(createDecoratorFilter(x => x.access === "write"));
if (decorators.length > 0) {
const info = createContext(ctx, value, meta);
const allowed = await executeAuthorizer(decorators, info);
if (!allowed)
return [ctx.path.join(".")];
}
// if the property is a relation property just skip checking, since we allow set relation using ID
const isRelation = meta.decorators.some((x) => x.kind === "plumier-meta:relation");
if (isRelation)
return [];
// loop through property of type array
if (Array.isArray(meta.type)) {
const newMeta = Object.assign(Object.assign({}, meta), { type: meta.type[0] });

@@ -338,3 +353,4 @@ const result = [];

}
else if (common_1.isCustomClass(meta.type)) {
// loop through custom class properties
if (common_1.isCustomClass(meta.type)) {
const classMeta = reflect_1.reflect(meta.type);

@@ -344,14 +360,4 @@ const values = classMeta.properties.map(x => value[x.name]);

}
else {
// skip check on GET method
if (ctx.info.ctx.method === "GET")
return [];
const decorators = meta.decorators.filter(createDecoratorFilter(x => x.access === "write"));
// if no decorator then just allow, follow route authorization
if (decorators.length === 0)
return [];
const info = createContext(ctx, value, meta);
const allowed = await executeAuthorizer(decorators, info);
return allowed ? [] : [ctx.path.join(".")];
}
// everything when fine then just return []
return [];
}

@@ -362,6 +368,2 @@ async function checkParameters(meta, value, ctx) {

const prop = meta[i];
// if the property is a relation property just skip checking, since we allow set relation using ID
const isRelation = prop.decorators.some((x) => x.kind === "plumier-meta:relation");
if (isRelation)
continue;
const issues = await checkParameter(prop, value[i], Object.assign(Object.assign({}, ctx), { path: ctx.path.concat(prop.name) }));

@@ -415,4 +417,2 @@ result.push(...issues);

var _a;
if (raw === undefined || raw === null)
return undefined;
if (node.kind === "Array") {

@@ -433,2 +433,4 @@ const result = [];

const value = raw[prop.name];
if (value === null || value === undefined)
continue;
const authorized = await getAuthorize(prop.authorizer, Object.assign(Object.assign({}, ctx), { value, parentValue: raw, metadata: Object.assign(Object.assign({}, ctx.metadata), { current: prop.meta }) }));

@@ -435,0 +437,0 @@ if (authorized) {

import glob from "glob";
declare type Class<T = any> = new (...args: any[]) => T;
interface ClassWithRoot {
root: string;
type: Class;
}
declare global {

@@ -19,2 +23,7 @@ interface String {

declare function findFilesRecursive(path: string): Promise<string[]>;
declare function appendRoute(...args: string[]): string;
declare function findClassRecursive(path: string | string[] | Class | Class[], option?: {
directoryAsPath?: boolean;
rootDir?: string;
}): Promise<ClassWithRoot[]>;
interface ColumnMeta {

@@ -57,2 +66,2 @@ align?: "left" | "right";

}
export { ellipsis, toBoolean, getChildValue, Class, hasKeyOf, isCustomClass, entityHelper, findFilesRecursive, memoize, printTable, analyzeModel, AnalysisMessage, globAsync, EntityRelationInfo, OneToManyRelationInfo, ManyToOneRelationInfo };
export { ellipsis, toBoolean, getChildValue, Class, hasKeyOf, isCustomClass, entityHelper, findFilesRecursive, memoize, printTable, analyzeModel, AnalysisMessage, globAsync, EntityRelationInfo, OneToManyRelationInfo, ManyToOneRelationInfo, appendRoute, findClassRecursive, ClassWithRoot };
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.globAsync = exports.analyzeModel = exports.printTable = exports.memoize = exports.findFilesRecursive = exports.entityHelper = exports.isCustomClass = exports.hasKeyOf = exports.getChildValue = exports.toBoolean = exports.ellipsis = void 0;
exports.findClassRecursive = exports.appendRoute = exports.globAsync = exports.analyzeModel = exports.printTable = exports.memoize = exports.findFilesRecursive = exports.entityHelper = exports.isCustomClass = exports.hasKeyOf = exports.getChildValue = exports.toBoolean = exports.ellipsis = void 0;
const tslib_1 = require("tslib");

@@ -10,2 +10,3 @@ const fs_1 = require("fs");

const types_1 = require("./types");
const path_1 = require("path");
const lstatAsync = util_1.promisify(fs_1.lstat);

@@ -99,2 +100,48 @@ const existsAsync = util_1.promisify(fs_1.exists);

exports.findFilesRecursive = findFilesRecursive;
function appendRoute(...args) {
return "/" + args
.filter(x => !!x)
.map(x => x.toLowerCase())
.map(x => x.startsWith("/") ? x.slice(1) : x)
.map(x => x.endsWith("/") ? x.slice(0, -1) : x)
.filter(x => !!x)
.join("/");
}
exports.appendRoute = appendRoute;
function getRoot(rootPath, path) {
// directoryAsPath should not working with glob
if (rootPath.indexOf("*") >= 0)
return;
const part = path.slice(rootPath.length).split("/").filter(x => !!x)
.slice(0, -1);
return (part.length === 0) ? undefined : appendRoute(...part);
}
async function findClassRecursive(path, option) {
var _a;
const opt = Object.assign({ rootDir: "", directoryAsPath: false }, option);
if (Array.isArray(path)) {
const result = [];
for (const p of path) {
result.push(...await findClassRecursive(p, opt));
}
return result;
}
if (typeof path === "string") {
const absPath = path_1.isAbsolute(path) ? path : path_1.join(opt.rootDir, path);
//read all files and get module reflection
const files = await findFilesRecursive(absPath);
const result = [];
for (const file of files) {
const root = !!opt.directoryAsPath ? ((_a = getRoot(absPath, file)) !== null && _a !== void 0 ? _a : "") : "";
for (const member of reflect_1.default(file).members) {
if (member.kind === "Class")
result.push({ root, type: member.type });
}
}
return result;
}
else
return [{ root: "", type: path }];
}
exports.findClassRecursive = findClassRecursive;
function printTable(meta, data, option) {

@@ -101,0 +148,0 @@ const getText = (col, row) => {

@@ -9,6 +9,6 @@ import { val } from "@plumier/validator";

export { response } from "./response";
export { generateRoutes, findClassRecursive, appendRoute, IgnoreDecorator, RouteDecorator, transformController, ControllerTransformOption } from "./route-generator";
export { generateRoutes, IgnoreDecorator, RouteDecorator, transformController, ControllerTransformOption } from "./route-generator";
export { analyzeRoutes, printAnalysis } from "./route-analyzer";
export { router } from "./router";
export { Class, findFilesRecursive, getChildValue, hasKeyOf, isCustomClass, printTable, toBoolean, ellipsis, analyzeModel, AnalysisMessage, entityHelper, globAsync, EntityRelationInfo, OneToManyRelationInfo, ManyToOneRelationInfo } from "./common";
export { Class, findFilesRecursive, getChildValue, hasKeyOf, isCustomClass, printTable, toBoolean, ellipsis, analyzeModel, AnalysisMessage, entityHelper, globAsync, EntityRelationInfo, OneToManyRelationInfo, ManyToOneRelationInfo, findClassRecursive, appendRoute, ClassWithRoot } from "./common";
export { AuthDecoratorImpl, authorize } from "./decorator/authorize";

@@ -15,0 +15,0 @@ export { ApiDescriptionDecorator, ApiEnumDecorator, ApiFieldNameDecorator, ApiRequiredDecorator, ApiResponseDecorator, ApiTagDecorator, api, ApiReadOnlyDecorator, ApiWriteOnlyDecorator, ApiHideRelationDecorator } from "./decorator/api";

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.entityProvider = exports.middleware = exports.domain = exports.bind = exports.api = exports.authorize = exports.AuthDecoratorImpl = exports.globAsync = exports.entityHelper = exports.analyzeModel = exports.ellipsis = exports.toBoolean = exports.printTable = exports.isCustomClass = exports.hasKeyOf = exports.getChildValue = exports.findFilesRecursive = exports.router = exports.printAnalysis = exports.analyzeRoutes = exports.transformController = exports.appendRoute = exports.findClassRecursive = exports.generateRoutes = exports.response = exports.invoke = exports.ParameterBinderMiddleware = exports.binder = exports.getPolicyInfo = exports.createAuthorizationAnalyzer = exports.analyzeAuthPolicyNameConflict = exports.updateRouteAuthorizationAccess = exports.getRouteAuthorizeDecorators = exports.throwAuthError = exports.createAuthContext = exports.executeAuthorizer = exports.WriteonlyAuthPolicy = exports.ReadonlyAuthPolicy = exports.AuthenticatedAuthPolicy = exports.PublicAuthPolicy = exports.globalPolicies = exports.EntityAuthPolicy = exports.CustomAuthPolicy = exports.Authenticated = exports.Public = exports.PolicyAuthorizer = exports.entityPolicy = exports.authPolicy = exports.checkAuthorize = exports.val = void 0;
exports.entityProvider = exports.middleware = exports.domain = exports.bind = exports.api = exports.authorize = exports.AuthDecoratorImpl = exports.appendRoute = exports.findClassRecursive = exports.globAsync = exports.entityHelper = exports.analyzeModel = exports.ellipsis = exports.toBoolean = exports.printTable = exports.isCustomClass = exports.hasKeyOf = exports.getChildValue = exports.findFilesRecursive = exports.router = exports.printAnalysis = exports.analyzeRoutes = exports.transformController = exports.generateRoutes = exports.response = exports.invoke = exports.ParameterBinderMiddleware = exports.binder = exports.getPolicyInfo = exports.createAuthorizationAnalyzer = exports.analyzeAuthPolicyNameConflict = exports.updateRouteAuthorizationAccess = exports.getRouteAuthorizeDecorators = exports.throwAuthError = exports.createAuthContext = exports.executeAuthorizer = exports.WriteonlyAuthPolicy = exports.ReadonlyAuthPolicy = exports.AuthenticatedAuthPolicy = exports.PublicAuthPolicy = exports.globalPolicies = exports.EntityAuthPolicy = exports.CustomAuthPolicy = exports.Authenticated = exports.Public = exports.PolicyAuthorizer = exports.entityPolicy = exports.authPolicy = exports.checkAuthorize = exports.val = void 0;
exports.MetadataImpl = exports.NestedControllerGeneric = exports.ControllerGeneric = exports.FormFile = exports.DefaultDependencyResolver = exports.errorMessage = exports.ValidationError = exports.RedirectActionResult = exports.MiddlewareUtil = exports.HttpStatusError = exports.DefaultFacility = exports.ActionResult = exports.ValidatorMiddleware = exports.validate = exports.HttpStatus = exports.meta = exports.postSave = exports.preSave = exports.entity = exports.RouteDecoratorImpl = exports.route = exports.responseType = void 0;

@@ -41,4 +41,2 @@ // TypeScript bug https://github.com/microsoft/TypeScript/issues/18877

Object.defineProperty(exports, "generateRoutes", { enumerable: true, get: function () { return route_generator_1.generateRoutes; } });
Object.defineProperty(exports, "findClassRecursive", { enumerable: true, get: function () { return route_generator_1.findClassRecursive; } });
Object.defineProperty(exports, "appendRoute", { enumerable: true, get: function () { return route_generator_1.appendRoute; } });
Object.defineProperty(exports, "transformController", { enumerable: true, get: function () { return route_generator_1.transformController; } });

@@ -61,2 +59,4 @@ var route_analyzer_1 = require("./route-analyzer");

Object.defineProperty(exports, "globAsync", { enumerable: true, get: function () { return common_1.globAsync; } });
Object.defineProperty(exports, "findClassRecursive", { enumerable: true, get: function () { return common_1.findClassRecursive; } });
Object.defineProperty(exports, "appendRoute", { enumerable: true, get: function () { return common_1.appendRoute; } });
var authorize_1 = require("./decorator/authorize");

@@ -63,0 +63,0 @@ Object.defineProperty(exports, "AuthDecoratorImpl", { enumerable: true, get: function () { return authorize_1.AuthDecoratorImpl; } });

@@ -25,10 +25,4 @@ import { Class } from "./common";

}
interface ClassWithRoot {
root: string;
type: Class;
}
declare function appendRoute(...args: string[]): string;
declare function findClassRecursive(path: string): Promise<ClassWithRoot[]>;
declare function transformController(object: Class, opt: ControllerTransformOption): RouteInfo[];
declare function generateRoutes(controller: string | string[] | Class[] | Class, option?: Partial<ControllerTransformOption>): Promise<RouteMetadata[]>;
export { generateRoutes, transformController, RouteDecorator, IgnoreDecorator, RootDecorator, appendRoute, findClassRecursive, ControllerTransformOption };
export { generateRoutes, transformController, RouteDecorator, IgnoreDecorator, RootDecorator, ControllerTransformOption };
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.findClassRecursive = exports.appendRoute = exports.transformController = exports.generateRoutes = void 0;
exports.transformController = exports.generateRoutes = void 0;
const reflect_1 = require("@plumier/reflect");
const path_1 = require("path");
const common_1 = require("./common");

@@ -10,12 +9,2 @@ /* ------------------------------------------------------------------------------- */

/* ------------------------------------------------------------------------------- */
function appendRoute(...args) {
return "/" + args
.filter(x => !!x)
.map(x => x.toLowerCase())
.map(x => x.startsWith("/") ? x.slice(1) : x)
.map(x => x.endsWith("/") ? x.slice(0, -1) : x)
.filter(x => !!x)
.join("/");
}
exports.appendRoute = appendRoute;
function striveController(name) {

@@ -36,28 +25,5 @@ return name.replace(/controller$/i, "");

else {
return [{ root: appendRoute(root, striveController(controller.name)), map: {} }];
return [{ root: common_1.appendRoute(root, striveController(controller.name)), map: {} }];
}
}
function getRoot(rootPath, path) {
// directoryAsPath should not working with glob
if (rootPath.indexOf("*") >= 0)
return;
const part = path.slice(rootPath.length).split("/").filter(x => !!x)
.slice(0, -1);
return (part.length === 0) ? undefined : appendRoute(...part);
}
async function findClassRecursive(path) {
var _a;
//read all files and get module reflection
const files = await common_1.findFilesRecursive(path);
const result = [];
for (const file of files) {
const root = (_a = getRoot(path, file)) !== null && _a !== void 0 ? _a : "";
for (const member of reflect_1.reflect(file).members) {
if (member.kind === "Class")
result.push({ root, type: member.type });
}
}
return result;
}
exports.findClassRecursive = findClassRecursive;
class ParamMapper {

@@ -89,3 +55,3 @@ constructor(map) {

else {
return appendRoute(root, actionDecorator.url || actionName.toLowerCase());
return common_1.appendRoute(root, actionDecorator.url || actionName.toLowerCase());
}

@@ -110,3 +76,3 @@ }

group, method: "get",
url: appendRoute(root.root, method.name),
url: common_1.appendRoute(root.root, method.name),
controller,

@@ -142,25 +108,4 @@ action: method,

async function extractController(controller, option) {
if (typeof controller === "string") {
const ctl = path_1.isAbsolute(controller) ? controller : path_1.join(option.rootDir, controller);
const types = await findClassRecursive(ctl);
const result = [];
for (const type of types) {
const ctl = await extractController(type.type, option);
result.push(...ctl.map(x => ({
root: option.directoryAsPath ? type.root : "",
type: x.type
})));
}
return result;
}
else if (Array.isArray(controller)) {
const raw = controller;
const controllers = await Promise.all(raw.map(x => extractController(x, option)));
return controllers.flatten();
}
// common controller
if (isController(controller)) {
return [{ root: "", type: controller }];
}
return [];
const classes = await common_1.findClassRecursive(controller, option);
return classes.filter(x => isController(x.type));
}

@@ -172,3 +117,3 @@ async function generateRoutes(controller, option) {

for (const controller of controllers) {
routes.push(...transformController(controller.type, Object.assign(Object.assign({}, opt), { rootPath: appendRoute(controller.root, opt.rootPath) })));
routes.push(...transformController(controller.type, Object.assign(Object.assign({}, opt), { rootPath: common_1.appendRoute(controller.root, opt.rootPath) })));
}

@@ -175,0 +120,0 @@ return routes;

@@ -80,3 +80,3 @@ /// <reference types="node" />

export interface Facility {
generateRoutes(app: Readonly<PlumierApplication>): Promise<RouteMetadata[]>;
generateRoutes(app: Readonly<PlumierApplication>, routes: RouteMetadata[]): Promise<RouteMetadata[]>;
setup(app: Readonly<PlumierApplication>): void;

@@ -87,3 +87,3 @@ preInitialize(app: Readonly<PlumierApplication>): Promise<void>;

export declare class DefaultFacility implements Facility {
generateRoutes(app: Readonly<PlumierApplication>): Promise<RouteMetadata[]>;
generateRoutes(app: Readonly<PlumierApplication>, routes: RouteMetadata[]): Promise<RouteMetadata[]>;
setup(app: Readonly<PlumierApplication>): void;

@@ -273,2 +273,3 @@ preInitialize(app: Readonly<PlumierApplication>): Promise<void>;

export interface SelectQuery {
includeId?: true;
columns?: any;

@@ -275,0 +276,0 @@ relations?: any;

@@ -67,3 +67,3 @@ "use strict";

class DefaultFacility {
async generateRoutes(app) { return []; }
async generateRoutes(app, routes) { return []; }
setup(app) { }

@@ -70,0 +70,0 @@ async preInitialize(app) { }

{
"name": "@plumier/core",
"version": "1.0.2-canary.kp2a4t.0+05cd377",
"version": "1.0.2",
"description": "Delightful Node.js Rest Framework",

@@ -23,8 +23,8 @@ "main": "lib/index.js",

"dependencies": {
"@plumier/reflect": "1.0.2-canary.kp2a4t.0+05cd377",
"@plumier/validator": "1.0.2-canary.kp2a4t.0+05cd377",
"@plumier/reflect": "^1.0.2",
"@plumier/validator": "^1.0.2",
"@types/debug": "^4.1.5",
"@types/glob": "^7.1.3",
"chalk": "^4.1.1",
"debug": "^4.3.1",
"debug": "^4.3.2",
"glob": "^7.1.7",

@@ -50,3 +50,3 @@ "path-to-regexp": "^6.2.0",

},
"gitHead": "05cd377823e789e1c18c3902cad69798f196549e"
"gitHead": "21a5ddc95244c15fc218146daee6a4e521ce3c0f"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc