@alkocats/http-ts
TypeScript icon, indicating that this package has built-in type declarations

0.6.4 • Public • Published

http-ts

Build Status Maintainability Test Coverage npm version MIT License Known Vulnerabilities dependencies Status devDependencies Status

Installation

npm install @alkocats/http-ts

Usage

Example

All relevant imports for a minimal setup:

import { HttpGet, HttpServer, HttpForbiddenError, SimpleRepository, HttpController, HttpResponse, HTTP_STATUS } from '@alkocats/http-ts';

The user interface for the user repository:

interface User {
    name: string;
    password: string;
}

The user repository for the stored data the controller uses:

class UserRepository extends SimpleRepository<User[]> {
    public async getAsyncData(): Promise<User[]> {
        return this.data;
    }

    public async addUser(name: string, password: string): Promise<void> {
        this.data.push({
            name: name,
            password: password
        });
    }
}

The user controller, which handles the user requests, equipped with different GET-methods:

class UserController extends HttpController<UserRepository> {
    /**
     * Define a GET-method for the url /users.
     */
    @HttpGet('/users')
    public getUsers(): User[] {
        return this.repository.getData();
    }

    /**
     * Define a asynchronous GET-method for the url /async-users.
     */
    @HttpGet('/async-users')
    public async getAsyncUsers(): Promise<User[]> {
        return await this.repository.getAsyncData();
    }

    /**
     * Define a asynchronous GET-method for the url /async-users-with-http-response and a custom http code
     */
    @HttpGet('/async-users-with-http-response')
    public async getAsyncUsersWithHttpResponse(): Promise<HttpResponse> {
        const data = await this.repository.getAsyncData();

        return new HttpResponse(data, HTTP_STATUS.CODE_202_ACCEPTED);
    }

    /**
     * Define a asynchronous POST-method for the url /async-post-data which handles JSON bodies
     */
    @HttpPost('/post-data/:username')
    public async postAsyncData(options: HttpRequestOptions): Promise<User[]> {
        const name = options.request.params.username;
        const password = options.request.body.password;
    
        this.repository.addUser(name, password);

        return this.repository.getAsyncData();
    }

    /**
     * Define a GET-method for the url /faulty-users which throws a HTTP error.
     * None HTTP errors are automatically transformed to HTTP 500 error.
     */
    @HttpGet('/faulty-method')
    public faultyMethod(): HttpResponse {
        throw new HttpForbiddenError();
    }
}

Bringing it all together:

const userRepository = new UserRepository([{
    name: 'admin',
    password: 'the-cake-is-a-lie'
}]);
const userController = new UserController(userRepository);

const httpServer = new HttpServer();
httpServer.registerController(userController);
httpServer.start();

Basic JWT / bcrypt Authentication

All relevant imports for a minimal setup:

import * as bcrypt from 'bcrypt';
import { Authenticated, HttpController, HttpGet, HttpServer, JwtAuthenticator, SimpleRepository } from '@alkocats/http-ts';

The user interface for the user repository:

interface User {
    email: string;
    password: string;
}

The data interface for the data repository:

interface Data {
    foo: number;
    bar: string;
}

The data repository for the stored data the controller uses:

class DataRepository extends SimpleRepository<Data[]> {
    public getSecretData(): Data[] {
        return [{
            foo: 0,
            bar: 'top secret'
        }];
    }
}

const dataRepository = new DataRepository([{
    foo: 1,
    bar: 'no secret data'
}]);

The data controller, which handles all data requests.

class DataController extends HttpController<DataRepository> {
    /**
     * A unauthaenticated get method which can be called by everyone
     */
    @HttpGet('/data')
    public getDataUnauthenticated() {
        return this.repository.getData();
    }

    /**
     * An authenticated get method, which can only be called by authenticated
     * users who deliver a valid bearer token.
     */
    @Authenticated()
    @HttpGet('/data-authenticated')
    public getDataAuthenticated(): Data[] {
        return this.repository.getSecretData();
    }
}

const dataController = new DataController(dataRepository);

Bringing it all together:

async function main() {
    // To login with a valid password, the password needs to be hashed with bcrypt
    const hashedPassword = await bcrypt.hash('the-cake-is-a-lie', 10);

    // This repository is used by the JwtAuthenticator and contains all valid logins.
    const userRepository = new SimpleRepository<User[]>([{
        email: 'alkocats.info@gmail.com',
        password: hashedPassword
    }]);

    // The secret for JwtAuthenticator to use for encryption / decryption.
    const secret = 'some-secret';

    /**
     * The path '/auth' defines, where to make a post with email / password
     * as a json object to obtain a valid bearer token.
     * The token then can be used to access @Authenticated methods of the
     * registered controllers.
     */
    const authenticator = new JwtAuthenticator<User>('/auth', {
        // Defines the repository with all the valid logins
        repository: userRepository,
        // Defines, which field of the repository data is used for identification
        identificationKey: 'email',
        // Defines, in which field of the repository data the hashed password is stored
        passwordKey: 'password',
        // Defines the expiration time of generated tokens (still valid after restart of server)
        expiresIn: 86400,
        // Defines the secret JWT uses to encrypt / decrypt the generated tokens.
        secret: secret
    });

    const httpServer = new HttpServer(80, authenticator);

    httpServer.registerController(dataController);
    httpServer.start();
}

main();

After everything is implemented, a POST to http://localhost/auth with the JSON data

{
    "email": "alkocats.info@gmail.com",
    "password": "the-cake-is-a-lie"
}

generates a bearer token, wich can be used in future requests to access @Authenticated methods of the registered controllers.

Alternatively a custom Authenticater can be created by creating a class which extends Authenticator.

API

Supported HTTP Methods

@HttpGet(path: string)

@HttpPut(path: string)

@HttpPost(path: string)

@HttpDelete(path: string)

@HttpPatch(path: string)

@HttpHead(path: string)

@HttpTrace(path: string)

@HttpConnect(path: string)

Contributing

Feel free to create branches or pull requests.

Package Sidebar

Install

npm i @alkocats/http-ts

Weekly Downloads

1

Version

0.6.4

License

MIT

Unpacked Size

13.4 MB

Total Files

181

Last publish

Collaborators

  • alkocats