aboutsummaryrefslogtreecommitdiff
path: root/lib/dasein.js
blob: 5b8486a09806a132be9ae8d262b39c331a677313 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
'use strict';

const Koa = require('koa');
const KoaBodyParser = require('koa-bodyparser');
const KoaJwt = require('koa-jwt');
const KoaRoute = require('koa-route');
const KoaSend = require('koa-send');
const KoaStatic = require('koa-static');
const Path = require('path');

const AuthHandler = require('./handlers/auth');
const PostsHandler = require('./handlers/posts');
const CommentsHandler = require('./handlers/comments');

const internals = {};

internals.k401Location = '/401.html';
internals.kMainLocation = '/';

/**
 * The Dasein class is the main entry point for the application.
 *
 * @class Dasein
 * @param {Dasein.tConfiguration} config the initialization options to
 * extend the instance
 */
module.exports = internals.Dasein = class Dasein {

  constructor(config) {

    Object.assign(this, config);
  }

  /**
   * Initializes the application and starts listening. Also prints a
   * nice robotic banner with information.
   *
   * @function run
   * @memberof Dasein
   * @instance
   */
  run() {

    this._initializeServer();
    this._startServer();
    this._printBanner();

    return Promise.resolve();
  }

  // Initializes the Koa application and all the handlers.

  _initializeServer() {

    const self = this;

    this._app = Koa();

    this._app.use(KoaStatic(this.staticDirectory));
    this._app.use(KoaBodyParser());

    // Error handler

    this._app.use(function * (next) {

      try {
        yield next;
      }
      catch (err) {
        this.status = err.status || 500;

        const response = {
          error: err.message,
          status: this.status
        };

        if (response.status === 401) {
          response.error === 'Protected resource, use Authorization header to get access';
        }

        this.body = response;

        this.app.emit('error', err, this);
      }
    });

    this._app.use(KoaJwt({
      secret: this.jwt.secret,
      passthrough: true
    }));

    this._initializeAuthRoutes();
    this._initializePostsRoutes();
    this._initializeCommentsRoutes();

    this._app.use(function * () {

      yield KoaSend(this, Path.join(self.staticDirectory, 'index.html'));
    });

  }

  // Initialize routes for auth

  _initializeAuthRoutes() {

    const authHandler = new AuthHandler({
      jwt: this.jwt,
      twitter: this.twitter
    });
    this._app.use(KoaRoute.get('/api/auth/login', authHandler.login()));
    this._app.use(KoaRoute.post('/api/auth/callback', authHandler.callback()));
  }

  // Initialize routes for posts

  _initializePostsRoutes() {

    const postsHandler = new PostsHandler({
      ttl: this.ttl,
      redis: this.redis
    });
    this._app.use(KoaRoute.get('/api/posts', postsHandler.findAll()));
    this._app.use(KoaRoute.get('/api/posts/:id', postsHandler.find()));
    this._app.use(KoaRoute.post('/api/posts', postsHandler.create()));
    this._app.use(KoaRoute.delete('/api/posts/:id', postsHandler.delete()));

  }

  // Initialize routes for comments

  _initializeCommentsRoutes() {

    const commentsHandler = new CommentsHandler({
      ttl: this.ttl,
      redis: this.redis
    });
    this._app.use(KoaRoute.get('/api/posts/:postId/comments', commentsHandler.findAll()));
    this._app.use(KoaRoute.post('/api/posts/:postId/comments', commentsHandler.create()));
  }

  // Starts listening

  _startServer() {

    this._app.listen(this.port);
  }

  // Prints the banner.

  _printBanner() {

    console.log('        .');
    console.log('       /');
    console.log('    +-----+');
    console.log(`    | o o |  - Listening Gladly, Try me on port: ${this.port}`);
    console.log('    +-----+');
    console.log('  +---------+');
    console.log(' /|    [][] |\\');
    console.log(' ||         | |');
    console.log(' ||         |  \\c');
    console.log(' ^+---------+');
    console.log('      (.) ');
  }
};