backend-tools
TypeScript icon, indicating that this package has built-in type declarations

2.0.0 • Public • Published

Overview

This is a collection of node tools to make express server development quicker and cleaner. Contains tools for jwt generation, SQL utilities, file management, error handling and others.

SimpleToken

import { SimpleToken } from 'backend-tools';

const simpleToken = new SimpleToken('SECRET KEY STRING');
const payload = {
    user: 265,
    permissions: 'af8',
};

/**
 * Create a token that expires in 300 seconds (5 minutes)
 */
const token = simpleToken.sign(payload, 300);

simpleToken
    .verify(token)
    .then(payloadIntoToken => {
        /**
         * Must be:
         * {
         *  user: 265,
         *  permissions: 'af8'
         * }
         */
        console.log(payloadIntoToken);
    })
    .catch(err => {
        // Invalid token
    });

Bcrypt algorithm is used to have better security, set the saltRound or cost factor (10 by default) into the instance of a SimpleToken object.

const simpleToken = new SimpleToken('SECRET KEY STRING', 15);

PermissionsManager

import { PermissionsManager } from 'backend-tools';

const permissionsManager = new PermissionsManager([
    'products_create',
    'products_update',
    'products_delete',
    'clients_create',
    'clients_update',
    'clients_delete',
    'providers_create',
    'providers_update',
    'providers_delete',
    'admin_users',
]);

Decode and encode permissions object into a short string of a base 32 number (each digit can be between 0 and v).

const permissions = {
    clients_create: true,
    clients_update: true,
    providers_create: true,
    providers_update: true,
};

/**
 * Must be equal to '6o'
 */
const encoded = permissionsManager.encode(permissions);

/*
 * Must match to permissions object previously declared
 */
const decodedPermissions = permissionsManager.decode(encoded);

Build and verify payloads according to a list of permissions declared.

const permissions = {
    products_delete: true,
    clients_delete: true,
    providers_delete: true,
    admin_users: true,
};

/**
 * Payload must be
 * {
 *  user: 'admin',
 *  _pp: 'p4',
 * }
 */
const payload = permissionsManager.buildPayload(
    {
        user: 'admin',
    },
    permissions
);

/**
 * Return the permissions object
 */
const canDeleteClients = permissionsManager.verifyPayload(
    payload,
    'clients_delete'
);

/**
 * Must be false
 */
const canUpdateClients = permissionsManager.verifyPayload(
    payload,
    'clients_update'
);

Verify the permissions by other methods too.

const adminUsersVerifier = permissionsManager.getVerifier('admin_users');

const canAdminUsers = adminUsersVerifier(payload);
const {
    products_create,
    products_update,
    products_delete,
} = permissionsManager.verifyPayload(payload);

Session manager

import express from 'express';
import { sessionManager, verifySession } from 'backend-tools';

let expressApp = express();
expressApp.use(express.json());

expressApp.use(sessionManager('SECRET KEY STRING'));

expressApp.post('/login', (req, res, next) => {
    let { username, password } = req.body;

    // ...

    // Success login

    /*
        Expires on 1800 seconds (30 min).
    */
    req.setSession({ user: username, canReadPrivate: true }, 1800, {
        // Only accepted on https request.
        secure: true,
    });

    res.sendStatus(200);
});

expressApp.get(
    '/private-resource',
    verifySession(session_data => session_data.canReadPrivate),
    (req, res, next) => {
        res.send('This is a private data');
    }
);

Configuration

sessionManager(secret, defaultOptions);
  • secret: Password to sign sessions.
  • defaultOptions: Options to configure sessions by default.
    • lifetime: Seconds of lifetime before expires.
    • authorizationHeader: Set if the manager accept authorization header (Default: true).
    • cookie: Cookie configuration.
    • errorHandler: Function that handle if a token verify is unsuccessful.

Usage

req.setSession

req.setSession(payload, expiresIn, options);
  • payload: Object with session information.

  • expiresIn: (Optional) Seconds of lifetime before expires (By default defaultOption.lifetime), if it's 0 or undefined never expires.

  • options: (Optional) Set session url (By default defaultOption.cookie).

    • secure: If only used on HTTPS protocol.
    • domain
    • path

Returns a object that can be used on OAuth2.

  • access_token.
  • token_type: Bearer.
  • expires_in.
  • expires_at.

verifySession

verifySession(verifyPayload?: (payload) => boolean)

Returns a middleware that checks if the request has a session and checks its payload (if verifyPayload has setted).

PermissionsManager Verifiers can be used

canCreateVerify = permissionsManager.getVerifier('products_create');

expressApp.post(
    '/products',
    verifySession(canCreateVerify),
    createProductsHandler
);

req.removeSession

req.removeSession(path?: string)

Delete the session associated with the path.

EasySQL

import { EasySQL } from 'backend-tools';

const testDBConnection = new EasySQL.Connection({
    username: 'tester',
    database: 'test',
});

/**
 Table object implements CRUD operation like Find, FindOne, Create, Update, Delete
 */
const usersTable = testDBConnection.table('users');

/**
  Equals to "SELECT * FROM users WHERE team IN ('A','Y','E','X','B') AND (email LIKE '%@gmail.com' OR email LIKE '%@outlook.com') ORDER BY team ASC ;" query
 */
usersTable
    .find({
        _sort: 'team:ASC',
        team_in: 'A,Y,E,X,B',
        email_like: ['%@gmail.com', '%@outlook.com'],
    })
    .then(users => {
        console.log(users);
    });

More details on docs/EasySQL.md file in the repository.

AdminFile

import { AdminFile } from 'backend-tools';

const adminFile = new AdminFile(AdminFile.path.resolve(__dirname, 'adminfile'));

adminFile.makeDir('logs');

adminFile.appendFile(
    'logs',
    'access.log',
    `
    <-------------------------------------------->
    Start at ${new Date().toLocaleString()}
    `
);

ErrorHandler

import express from 'express';
import path from 'path';

import { ErrorHandler } from 'backend-tools';

import mainRouter from './routes';

let expressApp = express();
const errorHandler = new ErrorHandler(
    path.resolve(__dirname, 'logs', 'error.log')
);
expressApp.use('/', mainRouter);
expressApp.use(errorHandler.handler);

ApiREST

import express from 'express';
import { ApiREST, EasySQL } from 'backend-tools';

const connectionStore = new EasySQL.Connection({
    user: 'seller',
    database: 'store',
});
const products = connectionStore.table('products', { id_name: 'id' });
const simpleToken = new SimpleToken('Secret store key');

/**
 * Set Securit middlewares
 */
const getSecurityMiddleware = ApiREST.defaultSecurity(simpleToken.verify);
/**
 *  Require valid token
 */
const authNeeded = getSecurityMiddleware(payload => true);
/**
 * Payload of the token must have { canModify: true }
 */
const canModifyPermission = getSecurityMiddleware(payload => payload.canModify);

/**
 * Enable
 *  - Find: Get /
 *  - FindOne: Get /:id
 *  - Create: Post /
 *  - Modify: Patch /:id
 *
 * The token is passed into header Authorization.
 *
 */
const productsAPI = ApiREST.createApiREST({
    find: [authNeeded, ApiREST.defaultFind(products)],
    findOne: [
      authNeeded,
      ApiREST.defaultFindOne(products)
    ]
    create: [
      canModifyPermission,
      ApiREST.defaultCreate(products)
    ],
    modify: [
      canModifyPermission,
      ApiREST.defaultModify(products)
    ]
}, 'id')

const app = express();
app.use(express.json());
app.use('/products', productsAPI);

More details on docs/ApiREST.md file in the repository.

Package Sidebar

Install

npm i backend-tools

Weekly Downloads

2

Version

2.0.0

License

MIT

Unpacked Size

1.02 MB

Total Files

52

Last publish

Collaborators

  • galezy25