1.0.3 • Published 3 years ago

aeolus.js v1.0.3

Weekly downloads
-
License
MIT
Repository
github
Last release
3 years ago

Aeolus

Request rules manager in order to block/allow request. Can be in use in interceptors/middlewares.

Overview

The Operation class allows one to execute a sequence of commands (rules) as a whole. Each Rule returns a boolean result as indication of the check method.

API

Instantiation

To create an operation

const operation = new Operation<T>(rulesContainer)

where

  • <T> is the request class
  • rulesContainer is an instance of RulesContainer<T>

RulesContainer<T>

addAllowRules(callback: (req: T) => Promise<boolean>, name: string): void

Receives a function reference and adds it to the operation execution allowed rules plan. If the result is true, the request will be mark as allowed

addBlockRule(callback: (req: T) => Promise<boolean>, name: string): void

Receives a function reference and adds it to the operation execution blocked rules plan. If the result is true, the request will be mark as blocked.

run

Run on all the rules that defined in this order: 1) allowed rules
1) blocked rules
2) throttled rules

Should return a OperationResult in order to understand the request status.


NOTE

If no rules have been defined, the OperationResult status will be REGULAR.


Examples

Using NestJS as a framework for the examples but could be used with any other framework that allows to create interceptors/middlewares.

Definition

interface AeulosApiRequest extends Request {
    userAgent: string;
}
@Injectable()
export class AeulosRedis implements StoreCache {

    async read(key: string): Promise<string | null> {
        // implement logic to fetch by key
    }

    write(key: string, value: string, expiresIn: number): Promise<void> {
        // implement logic to store by key, value and expiration
    }

    increment(key: string, amount: number, expiresIn: number): number {
        // implement logic to increment by key, amount and expiration
    }

    delete(key: string): void {
        // implement logic to delete the key
    }
}
@Injectable()
export class ExampleRulesContainer extends RulesContainer<AeulosApiRequest> {

    private static readonly BLOCKLIST_UA = ['BAD_UA, BAD_UA2'];
    private static readonly ALLOWLIST_UA = ['GOOD_UA'];
    private static readonly TTL = 30 * 60;

    constructor() {
        super();
        this.addAllowRules(this.allowedUa, 'allowedUa');
        this.addBlockRule(this.isBadUa, 'badUA');
    }

    allowedUa(request: AeulosApiRequest): Promise<boolean> {
        const allow: boolean = ExampleRulesContainer.ALLOWLIST_UA.some(element => request.userAgent === element);
        return Promise.resolve(allow);
    }

    isBadUa(request: AeulosApiRequest): Promise<boolean> {
        const block: boolean = ExampleRulesContainer.BLOCKLIST_UA.some(element => request.userAgent.includes(element));
        return Promise.resolve(block);
    }
}

Execution

@Injectable()
export class AeulosMiddleware implements NestMiddleware {
    constructor (
        private readonly rulesContainer: ExampleRulesContainer,
        private readonly aeulosRedis: AeulosRedis
    ) {}

    async use(request: AeulosApiRequest, response: Response, next: () => void) {
        const operation = new Operation<AeulosApiRequest>(this.rulesContainer);
        AeolusCache.setStoreCache(this.aeulosRedis);
        const result = await operation.run(request);
        switch (result) {
            case OperationResult.ALLOWED: {
                next();
                break;
            }
            case OperationResult.BLOCKED: {
                // blocked logic
            }
            default: {
                next();
                break;
            }
        }
    }
}
1.0.3

3 years ago

1.0.2-3

3 years ago

1.0.2-2

3 years ago

1.0.2-1

3 years ago

1.0.2-0

3 years ago

1.0.1-0

3 years ago

1.0.0

3 years ago