UNPKG

5.6 kBJavaScriptView Raw
1"use strict";
2
3function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
4
5function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
6
7function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
8
9const {
10 Microfleet,
11 ConnectorsTypes
12} = require('@microfleet/core');
13
14const Mailer = require('ms-mailer-client');
15
16const merge = require('lodash/merge');
17
18const assert = require('assert');
19
20const fsort = require('redis-filtered-sort');
21
22const TokenManager = require('ms-token');
23
24const LockManager = require('dlock');
25
26const Flakeless = require('ms-flakeless');
27
28const conf = require('./config');
29
30const get = require('./utils/get-value');
31
32const attachPasswordKeyword = require('./utils/password-validator');
33/**
34 * @namespace Users
35 */
36
37
38class Users extends Microfleet {
39 /**
40 * @namespace Users
41 * @param {Object} opts
42 * @return {Users}
43 */
44 constructor(opts = {}) {
45 super(merge({}, Users.defaultOpts, opts));
46 /**
47 * Initializes Admin accounts
48 * @returns {Promise}
49 */
50
51 this.initAdminAccounts = require('./accounts/init-admin');
52 /**
53 * Initializes fake account for dev purposes
54 * @returns {Promise}
55 */
56
57 this.initFakeAccounts = require('./accounts/init-dev'); // cached ref
58
59 const {
60 config
61 } = this;
62 const {
63 prefix
64 } = config.router.routes;
65 /**
66 * Setup data for bearer token authentication
67 * @type {Object}
68 */
69
70 config.users = {
71 audience: config.jwt.defaultAudience,
72 verify: `${prefix}.verify`,
73 timeouts: {
74 verify: 5000
75 }
76 }; // 2 different plugin types
77
78 if (config.plugins.includes('redisCluster')) {
79 this.redisType = 'redisCluster';
80 } else if (config.plugins.includes('redisSentinel')) {
81 this.redisType = 'redisSentinel';
82 } else {
83 throw new Error('must include redis family plugins');
84 } // id generator
85
86
87 this.flake = new Flakeless(config.flake);
88 this.on('plugin:connect:amqp', amqp => {
89 this.mailer = new Mailer(amqp, config.mailer);
90 }, 'mailer');
91 this.on('plugin:close:amqp', () => {
92 this.mailer = null;
93 });
94 this.on(`plugin:connect:${this.redisType}`, redis => {
95 fsort.attach(redis, 'fsort'); // init token manager
96
97 const tokenManagerOpts = {
98 backend: {
99 connection: redis
100 }
101 };
102 const tmOpts = merge({}, config.tokenManager, tokenManagerOpts);
103 this.tokenManager = new TokenManager(tmOpts);
104 });
105 this.on('plugin:start:http', server => {
106 // if oAuth is enabled - initiate the strategy
107 if (get(config, 'oauth.enabled', {
108 default: false
109 }) === true) {
110 assert.equal(config.http.server.handler, 'hapi', 'oAuth must be used with hapi.js webserver');
111
112 const OAuthStrategyHandler = require('./auth/oauth/hapi');
113
114 this.oauth = new OAuthStrategyHandler(server, config);
115 }
116 });
117 this.on('plugin:stop:http', () => {
118 this.oauth = null;
119 }); // cleanup connections
120
121 this.on(`plugin:close:${this.redisType}`, () => {
122 this.dlock = null;
123 this.tokenManager = null;
124 }); // add migration connector
125
126 if (config.migrations.enabled === true) {
127 this.addConnector(ConnectorsTypes.migration, () => this.migrate('redis', `${__dirname}/migrations`), 'redis-migration');
128 } // ensure we close connection when needed
129
130
131 this.addDestructor(ConnectorsTypes.database, () => this.pubsub.quit(), 'pubsub-dlock'); // add lock manager
132
133 this.addConnector(ConnectorsTypes.migration, async () => {
134 this.pubsub = this.redis.duplicate({
135 lazyConnect: true
136 });
137 await this.pubsub.connect();
138 this.dlock = new LockManager(_objectSpread(_objectSpread({}, config.lockManager), {}, {
139 client: this.redis,
140 pubsub: this.pubsub,
141 log: this.log
142 }));
143 return this.dlock;
144 }, 'pubsub-dlock');
145 this.addConnector(ConnectorsTypes.essential, () => {
146 attachPasswordKeyword(this);
147 });
148
149 if (this.config.tbits.enabled) {
150 this.addConnector(ConnectorsTypes.essential, () => {
151 const TbitsRelay = require('./utils/tbits');
152
153 this.tbits = new TbitsRelay(this);
154 }, 'tbits');
155 } // init account seed
156
157
158 this.addConnector(ConnectorsTypes.application, () => this.initAdminAccounts(), 'admins'); // fake accounts for development
159
160 if (process.env.NODE_ENV === 'development') {
161 this.addConnector(ConnectorsTypes.application, () => this.initFakeAccounts(), 'dev accounts');
162 }
163 }
164
165}
166/**
167 * Configuration options for the service
168 * @type {Object}
169 */
170
171
172Users.defaultOpts = conf.get('/', {
173 env: process.env.NODE_ENV
174});
175module.exports = Users;
\No newline at end of file