Skip to content
4 changes: 3 additions & 1 deletion src/core/Kernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export default class Kernel<Config extends IAppConfig> extends Singleton<Config>

const { appConfig } = kernel;

App.getInstance().env = appConfig.environment;

for (const provider of appConfig.providers) {
if(withoutProviders.includes(provider.constructor.name)) {
continue;
Expand All @@ -60,7 +62,7 @@ export default class Kernel<Config extends IAppConfig> extends Singleton<Config>
kernel.preparedProviders.push(provider.constructor.name);
}

App.getInstance().env = appConfig.environment;

Kernel.getInstance().readyProviders = [...kernel.preparedProviders];
}

Expand Down
8 changes: 2 additions & 6 deletions src/core/domains/express/actions/baseAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ import { Response } from 'express';
* @param {IAction} action The action function that will be called with the BaseRequest, Response, and options.
* @return {(req: BaseRequest, res: Response) => Promise<void>} A new action function that calls the given action with the given options.
*/
const ResourceAction = (options: IRouteResourceOptions, action: IAction) => {
return (req: BaseRequest, res: Response) => {
return action(req, res, options)
}
}
const baseAction = (options: IRouteResourceOptions, action: IAction) => (req: BaseRequest, res: Response) => action(req, res, options)

export default ResourceAction
export default baseAction
23 changes: 23 additions & 0 deletions src/core/domains/express/actions/resourceAll.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { IRouteResourceOptions } from '@src/core/domains/express/interfaces/IRouteResourceOptions';
import ResourceAllService from '@src/core/domains/express/services/Resources/ResourceAllService';
import ResourceErrorService from '@src/core/domains/express/services/Resources/ResourceErrorService';
import { BaseRequest } from "@src/core/domains/express/types/BaseRequest.t";
import { Response } from 'express';

/**
* Finds all records in the resource's repository
*
* @param {BaseRequest} req - The request object
* @param {Response} res - The response object
* @param {IRouteResourceOptions} options - The options object
* @returns {Promise<void>}
*/
export default async (req: BaseRequest, res: Response, options: IRouteResourceOptions): Promise<void> => {
try {
const resourceAllService = new ResourceAllService();
await resourceAllService.handler(req, res, options);
}
catch (err) {
ResourceErrorService.handleError(req, res, err)
}
}
56 changes: 5 additions & 51 deletions src/core/domains/express/actions/resourceCreate.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import UnauthorizedError from '@src/core/domains/auth/exceptions/UnauthorizedError';
import MissingSecurityError from '@src/core/domains/express/exceptions/MissingSecurityError';
import { IRouteResourceOptions } from '@src/core/domains/express/interfaces/IRouteResourceOptions';
import responseError from '@src/core/domains/express/requests/responseError';
import { RouteResourceTypes } from '@src/core/domains/express/routing/RouteResource';
import { ALWAYS } from '@src/core/domains/express/services/Security';
import SecurityReader from '@src/core/domains/express/services/SecurityReader';
import { SecurityIdentifiers } from '@src/core/domains/express/services/SecurityRules';
import ResourceCreateService from '@src/core/domains/express/services/Resources/ResourceCreateService';
import ResourceErrorService from '@src/core/domains/express/services/Resources/ResourceErrorService';
import { BaseRequest } from "@src/core/domains/express/types/BaseRequest.t";
import { App } from '@src/core/services/App';
import { Response } from 'express';


Expand All @@ -21,50 +15,10 @@ import { Response } from 'express';
*/
export default async (req: BaseRequest, res: Response, options: IRouteResourceOptions): Promise<void> => {
try {
const resourceOwnerSecurity = SecurityReader.findFromRouteResourceOptions(options, SecurityIdentifiers.RESOURCE_OWNER, [RouteResourceTypes.CREATE]);
const authorizationSecurity = SecurityReader.findFromRouteResourceOptions(options, SecurityIdentifiers.AUTHORIZED, [RouteResourceTypes.CREATE, ALWAYS]);

if(authorizationSecurity && !authorizationSecurity.callback(req)) {
responseError(req, res, new UnauthorizedError(), 401)
return;
}

const modelInstance = new options.resource(req.body);

/**
* When a resourceOwnerSecurity is defined, we need to set the record that is owned by the user
*/
if(resourceOwnerSecurity) {

if(!authorizationSecurity) {
responseError(req, res, new MissingSecurityError('Expected authorized security for this route, recieved: ' + typeof authorizationSecurity), 401);
}

const propertyKey = resourceOwnerSecurity.arguements?.key;
const userId = App.container('requestContext').getByRequest<string>(req, 'userId');

if(typeof propertyKey !== 'string') {
throw new Error('Malformed resourceOwner security. Expected parameter \'key\' to be a string but received ' + typeof propertyKey);
}

if(!userId) {
responseError(req, res, new UnauthorizedError(), 401)
return;
}

modelInstance.setAttribute(propertyKey, userId)
}

await modelInstance.save();

res.status(201).send(modelInstance.getData({ excludeGuarded: true }) as IRouteResourceOptions['resource'])
const resourceCreateService = new ResourceCreateService();
await resourceCreateService.handler(req, res, options);
}
catch (err) {
if (err instanceof Error) {
responseError(req, res, err)
return;
}

res.status(500).send({ error: 'Something went wrong' })
ResourceErrorService.handleError(req, res, err)
}
}
47 changes: 5 additions & 42 deletions src/core/domains/express/actions/resourceDelete.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import Repository from '@src/core/base/Repository';
import ForbiddenResourceError from '@src/core/domains/auth/exceptions/ForbiddenResourceError';
import UnauthorizedError from '@src/core/domains/auth/exceptions/UnauthorizedError';
import { IRouteResourceOptions } from '@src/core/domains/express/interfaces/IRouteResourceOptions';
import responseError from '@src/core/domains/express/requests/responseError';
import { RouteResourceTypes } from '@src/core/domains/express/routing/RouteResource';
import { ALWAYS } from '@src/core/domains/express/services/Security';
import SecurityReader from '@src/core/domains/express/services/SecurityReader';
import { SecurityIdentifiers } from '@src/core/domains/express/services/SecurityRules';
import ResourceDeleteService from '@src/core/domains/express/services/Resources/ResourceDeleteService';
import ResourceErrorService from '@src/core/domains/express/services/Resources/ResourceErrorService';
import { BaseRequest } from "@src/core/domains/express/types/BaseRequest.t";
import ModelNotFound from '@src/core/exceptions/ModelNotFound';
import { Response } from 'express';

/**
Expand All @@ -21,40 +14,10 @@ import { Response } from 'express';
*/
export default async (req: BaseRequest, res: Response, options: IRouteResourceOptions): Promise<void> => {
try {
const resourceOwnerSecurity = SecurityReader.findFromRouteResourceOptions(options, SecurityIdentifiers.RESOURCE_OWNER, [RouteResourceTypes.DESTROY]);
const authorizationSecurity = SecurityReader.findFromRouteResourceOptions(options, SecurityIdentifiers.AUTHORIZED, [RouteResourceTypes.DESTROY, ALWAYS]);

if(authorizationSecurity && !authorizationSecurity.callback(req)) {
responseError(req, res, new UnauthorizedError(), 401)
return;
}
const repository = new Repository(options.resource);

const result = await repository.findById(req.params?.id);

if (!result) {
throw new ModelNotFound('Resource not found');
}

if(resourceOwnerSecurity && !resourceOwnerSecurity.callback(req, result)) {
responseError(req, res, new ForbiddenResourceError(), 403)
return;
}

await result.delete();

res.send({ success: true })
const resourceDeleteService = new ResourceDeleteService();
await resourceDeleteService.handler(req, res, options);
}
catch (err) {
if(err instanceof ModelNotFound) {
responseError(req, res, err, 404)
return;
}
if (err instanceof Error) {
responseError(req, res, err)
return;
}

res.status(500).send({ error: 'Something went wrong' })
ResourceErrorService.handleError(req, res, err)
}
}
106 changes: 0 additions & 106 deletions src/core/domains/express/actions/resourceIndex.ts

This file was deleted.

84 changes: 5 additions & 79 deletions src/core/domains/express/actions/resourceShow.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
import Repository from '@src/core/base/Repository';
import ForbiddenResourceError from '@src/core/domains/auth/exceptions/ForbiddenResourceError';
import UnauthorizedError from '@src/core/domains/auth/exceptions/UnauthorizedError';
import { IRouteResourceOptions } from '@src/core/domains/express/interfaces/IRouteResourceOptions';
import responseError from '@src/core/domains/express/requests/responseError';
import { RouteResourceTypes } from '@src/core/domains/express/routing/RouteResource';
import { ALWAYS } from '@src/core/domains/express/services/Security';
import SecurityReader from '@src/core/domains/express/services/SecurityReader';
import { SecurityIdentifiers } from '@src/core/domains/express/services/SecurityRules';
import ResourceErrorService from '@src/core/domains/express/services/Resources/ResourceErrorService';
import ResourceShowService from '@src/core/domains/express/services/Resources/ResourceShowService';
import { BaseRequest } from "@src/core/domains/express/types/BaseRequest.t";
import ModelNotFound from '@src/core/exceptions/ModelNotFound';
import { IModel } from '@src/core/interfaces/IModel';
import { App } from '@src/core/services/App';
import { Response } from 'express';

/**
Expand All @@ -23,75 +14,10 @@ import { Response } from 'express';
*/
export default async (req: BaseRequest, res: Response, options: IRouteResourceOptions): Promise<void> => {
try {
const resourceOwnerSecurity = SecurityReader.findFromRouteResourceOptions(options, SecurityIdentifiers.RESOURCE_OWNER, [RouteResourceTypes.SHOW]);
const authorizationSecurity = SecurityReader.findFromRouteResourceOptions(options, SecurityIdentifiers.AUTHORIZED, [RouteResourceTypes.SHOW, ALWAYS]);

if(authorizationSecurity && !authorizationSecurity.callback(req)) {
responseError(req, res, new UnauthorizedError(), 401)
return;
}
const repository = new Repository(options.resource);

let result: IModel | null = null;

// Define our query filters
const filters: object = {
...(options.showFilters ?? {}),
id: req.params?.id
};

/**
* When a resourceOwnerSecurity is defined, we need to find the record that is owned by the user
*/
if(resourceOwnerSecurity && authorizationSecurity) {

const propertyKey = resourceOwnerSecurity.arguements?.key;
const userId = App.container('requestContext').getByRequest<string>(req, 'userId');

if(!userId) {
responseError(req, res, new ForbiddenResourceError(), 403);
return;
}

if(typeof propertyKey !== 'string') {
throw new Error('Malformed resourceOwner security. Expected parameter \'key\' to be a string but received ' + typeof propertyKey);
}

result = await repository.findOne({
...filters,
[propertyKey]: userId
})

if (!result) {
throw new ModelNotFound('Resource not found');
}

res.send(result?.getData({ excludeGuarded: true }) as IModel);

return;
}

/**
* Find resource without restrictions
*/
result = await repository.findOne(filters);

if (!result) {
throw new ModelNotFound('Resource not found');
}

res.send(result?.getData({ excludeGuarded: true }) as IModel);
const resourceShowService = new ResourceShowService()
await resourceShowService.handler(req, res, options)
}
catch (err) {
if(err instanceof ModelNotFound) {
responseError(req, res, err, 404)
return;
}
if (err instanceof Error) {
responseError(req, res, err)
return;
}

res.status(500).send({ error: 'Something went wrong' })
ResourceErrorService.handleError(req, res, err)
}
}
Loading