diff options
Diffstat (limited to 'server/helpers')
-rw-r--r-- | server/helpers/core-utils.ts | 89 | ||||
-rw-r--r-- | server/helpers/database-utils.ts | 69 | ||||
-rw-r--r-- | server/helpers/peertube-crypto.ts | 111 | ||||
-rw-r--r-- | server/helpers/requests.ts | 81 | ||||
-rw-r--r-- | server/helpers/utils.ts | 24 |
5 files changed, 209 insertions, 165 deletions
diff --git a/server/helpers/core-utils.ts b/server/helpers/core-utils.ts index 32b89b6dd..1e92049f1 100644 --- a/server/helpers/core-utils.ts +++ b/server/helpers/core-utils.ts | |||
@@ -4,6 +4,20 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | import { join } from 'path' | 6 | import { join } from 'path' |
7 | import { pseudoRandomBytes } from 'crypto' | ||
8 | import { | ||
9 | readdir, | ||
10 | readFile, | ||
11 | rename, | ||
12 | unlink, | ||
13 | writeFile, | ||
14 | access | ||
15 | } from 'fs' | ||
16 | import * as mkdirp from 'mkdirp' | ||
17 | import * as bcrypt from 'bcrypt' | ||
18 | import * as createTorrent from 'create-torrent' | ||
19 | import * as openssl from 'openssl-wrapper' | ||
20 | import * as Promise from 'bluebird' | ||
7 | 21 | ||
8 | function isTestInstance () { | 22 | function isTestInstance () { |
9 | return process.env.NODE_ENV === 'test' | 23 | return process.env.NODE_ENV === 'test' |
@@ -14,9 +28,82 @@ function root () { | |||
14 | return join(__dirname, '..', '..', '..') | 28 | return join(__dirname, '..', '..', '..') |
15 | } | 29 | } |
16 | 30 | ||
31 | function promisify0<A> (func: (cb: (err: any, result: A) => void) => void): () => Promise<A> { | ||
32 | return function promisified (): Promise<A> { | ||
33 | return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => { | ||
34 | func.apply(null, [ (err: any, res: A) => err ? reject(err) : resolve(res) ]) | ||
35 | }) | ||
36 | } | ||
37 | } | ||
38 | |||
39 | // Thanks to https://gist.github.com/kumasento/617daa7e46f13ecdd9b2 | ||
40 | function promisify1<T, A> (func: (arg: T, cb: (err: any, result: A) => void) => void): (arg: T) => Promise<A> { | ||
41 | return function promisified (arg: T): Promise<A> { | ||
42 | return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => { | ||
43 | func.apply(null, [ arg, (err: any, res: A) => err ? reject(err) : resolve(res) ]) | ||
44 | }) | ||
45 | } | ||
46 | } | ||
47 | |||
48 | function promisify1WithVoid<T> (func: (arg: T, cb: (err: any) => void) => void): (arg: T) => Promise<void> { | ||
49 | return function promisified (arg: T): Promise<void> { | ||
50 | return new Promise<void>((resolve: () => void, reject: (err: any) => void) => { | ||
51 | func.apply(null, [ arg, (err: any) => err ? reject(err) : resolve() ]) | ||
52 | }) | ||
53 | } | ||
54 | } | ||
55 | |||
56 | function promisify2<T, U, A> (func: (arg1: T, arg2: U, cb: (err: any, result: A) => void) => void): (arg1: T, arg2: U) => Promise<A> { | ||
57 | return function promisified (arg1: T, arg2: U): Promise<A> { | ||
58 | return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => { | ||
59 | func.apply(null, [ arg1, arg2, (err: any, res: A) => err ? reject(err) : resolve(res) ]) | ||
60 | }) | ||
61 | } | ||
62 | } | ||
63 | |||
64 | function promisify2WithVoid<T, U> (func: (arg1: T, arg2: U, cb: (err: any) => void) => void): (arg1: T, arg2: U) => Promise<void> { | ||
65 | return function promisified (arg1: T, arg2: U): Promise<void> { | ||
66 | return new Promise<void>((resolve: () => void, reject: (err: any) => void) => { | ||
67 | func.apply(null, [ arg1, arg2, (err: any) => err ? reject(err) : resolve() ]) | ||
68 | }) | ||
69 | } | ||
70 | } | ||
71 | |||
72 | const readFilePromise = promisify2<string, string, string>(readFile) | ||
73 | const readFileBufferPromise = promisify1<string, Buffer>(readFile) | ||
74 | const unlinkPromise = promisify1WithVoid<string>(unlink) | ||
75 | const renamePromise = promisify2WithVoid<string, string>(rename) | ||
76 | const writeFilePromise = promisify2<string, any, void>(writeFile) | ||
77 | const readdirPromise = promisify1<string, string[]>(readdir) | ||
78 | const mkdirpPromise = promisify1<string, string>(mkdirp) | ||
79 | const pseudoRandomBytesPromise = promisify1<number, Buffer>(pseudoRandomBytes) | ||
80 | const accessPromise = promisify1WithVoid<string|Buffer>(access) | ||
81 | const opensslExecPromise = promisify2WithVoid<string, any>(openssl.exec) | ||
82 | const bcryptComparePromise = promisify2<any, string, boolean>(bcrypt.compare) | ||
83 | const bcryptGenSaltPromise = promisify1<number, string>(bcrypt.genSalt) | ||
84 | const bcryptHashPromise = promisify2<any, string|number, string>(bcrypt.hash) | ||
85 | const createTorrentPromise = promisify2<string, any, any>(createTorrent) | ||
86 | |||
17 | // --------------------------------------------------------------------------- | 87 | // --------------------------------------------------------------------------- |
18 | 88 | ||
19 | export { | 89 | export { |
20 | isTestInstance, | 90 | isTestInstance, |
21 | root | 91 | root, |
92 | |||
93 | promisify0, | ||
94 | promisify1, | ||
95 | readdirPromise, | ||
96 | readFilePromise, | ||
97 | readFileBufferPromise, | ||
98 | unlinkPromise, | ||
99 | renamePromise, | ||
100 | writeFilePromise, | ||
101 | mkdirpPromise, | ||
102 | pseudoRandomBytesPromise, | ||
103 | accessPromise, | ||
104 | opensslExecPromise, | ||
105 | bcryptComparePromise, | ||
106 | bcryptGenSaltPromise, | ||
107 | bcryptHashPromise, | ||
108 | createTorrentPromise | ||
22 | } | 109 | } |
diff --git a/server/helpers/database-utils.ts b/server/helpers/database-utils.ts index f8ee9a454..f761cfb89 100644 --- a/server/helpers/database-utils.ts +++ b/server/helpers/database-utils.ts | |||
@@ -1,70 +1,45 @@ | |||
1 | import * as Sequelize from 'sequelize' | ||
2 | // TODO: import from ES6 when retry typing file will include errorFilter function | 1 | // TODO: import from ES6 when retry typing file will include errorFilter function |
3 | import * as retry from 'async/retry' | 2 | import * as retry from 'async/retry' |
3 | import * as Promise from 'bluebird' | ||
4 | 4 | ||
5 | import { database as db } from '../initializers/database' | ||
6 | import { logger } from './logger' | 5 | import { logger } from './logger' |
7 | 6 | ||
8 | function commitTransaction (t: Sequelize.Transaction, callback: (err: Error) => void) { | ||
9 | return t.commit().asCallback(callback) | ||
10 | } | ||
11 | |||
12 | function rollbackTransaction (err: Error, t: Sequelize.Transaction, callback: (err: Error) => void) { | ||
13 | // Try to rollback transaction | ||
14 | if (t) { | ||
15 | // Do not catch err, report the original one | ||
16 | t.rollback().asCallback(function () { | ||
17 | return callback(err) | ||
18 | }) | ||
19 | } else { | ||
20 | return callback(err) | ||
21 | } | ||
22 | } | ||
23 | |||
24 | type RetryTransactionWrapperOptions = { errorMessage: string, arguments?: any[] } | 7 | type RetryTransactionWrapperOptions = { errorMessage: string, arguments?: any[] } |
25 | function retryTransactionWrapper (functionToRetry: Function, options: RetryTransactionWrapperOptions, finalCallback: Function) { | 8 | function retryTransactionWrapper (functionToRetry: (... args) => Promise<any>, options: RetryTransactionWrapperOptions) { |
26 | const args = options.arguments ? options.arguments : [] | 9 | const args = options.arguments ? options.arguments : [] |
27 | 10 | ||
28 | transactionRetryer( | 11 | return transactionRetryer( |
29 | function (callback) { | 12 | function (callback) { |
30 | return functionToRetry.apply(this, args.concat([ callback ])) | 13 | functionToRetry.apply(this, args) |
31 | }, | 14 | .then(result => callback(null, result)) |
32 | function (err) { | 15 | .catch(err => callback(err)) |
33 | if (err) { | ||
34 | logger.error(options.errorMessage, { error: err }) | ||
35 | } | ||
36 | |||
37 | // Do not return the error, continue the process | ||
38 | return finalCallback(null) | ||
39 | } | 16 | } |
40 | ) | 17 | ) |
18 | .catch(err => { | ||
19 | // Do not throw the error, continue the process | ||
20 | logger.error(options.errorMessage, { error: err }) | ||
21 | }) | ||
41 | } | 22 | } |
42 | 23 | ||
43 | function transactionRetryer (func: Function, callback: (err: Error) => void) { | 24 | function transactionRetryer (func: Function) { |
44 | retry({ | 25 | return new Promise((res, rej) => { |
45 | times: 5, | 26 | retry({ |
46 | 27 | times: 5, | |
47 | errorFilter: function (err) { | ||
48 | const willRetry = (err.name === 'SequelizeDatabaseError') | ||
49 | logger.debug('Maybe retrying the transaction function.', { willRetry }) | ||
50 | return willRetry | ||
51 | } | ||
52 | }, func, callback) | ||
53 | } | ||
54 | 28 | ||
55 | function startSerializableTransaction (callback: (err: Error, t: Sequelize.Transaction) => void) { | 29 | errorFilter: function (err) { |
56 | db.sequelize.transaction(/* { isolationLevel: 'SERIALIZABLE' } */).asCallback(function (err, t) { | 30 | const willRetry = (err.name === 'SequelizeDatabaseError') |
57 | // We force to return only two parameters | 31 | logger.debug('Maybe retrying the transaction function.', { willRetry }) |
58 | return callback(err, t) | 32 | return willRetry |
33 | } | ||
34 | }, func, function (err) { | ||
35 | err ? rej(err) : res() | ||
36 | }) | ||
59 | }) | 37 | }) |
60 | } | 38 | } |
61 | 39 | ||
62 | // --------------------------------------------------------------------------- | 40 | // --------------------------------------------------------------------------- |
63 | 41 | ||
64 | export { | 42 | export { |
65 | commitTransaction, | ||
66 | retryTransactionWrapper, | 43 | retryTransactionWrapper, |
67 | rollbackTransaction, | ||
68 | startSerializableTransaction, | ||
69 | transactionRetryer | 44 | transactionRetryer |
70 | } | 45 | } |
diff --git a/server/helpers/peertube-crypto.ts b/server/helpers/peertube-crypto.ts index 0ac875127..8e8001cd6 100644 --- a/server/helpers/peertube-crypto.ts +++ b/server/helpers/peertube-crypto.ts | |||
@@ -1,7 +1,5 @@ | |||
1 | import * as crypto from 'crypto' | 1 | import * as crypto from 'crypto' |
2 | import * as bcrypt from 'bcrypt' | ||
3 | import * as fs from 'fs' | 2 | import * as fs from 'fs' |
4 | import * as openssl from 'openssl-wrapper' | ||
5 | import { join } from 'path' | 3 | import { join } from 'path' |
6 | 4 | ||
7 | import { | 5 | import { |
@@ -12,6 +10,14 @@ import { | |||
12 | BCRYPT_SALT_SIZE, | 10 | BCRYPT_SALT_SIZE, |
13 | PUBLIC_CERT_NAME | 11 | PUBLIC_CERT_NAME |
14 | } from '../initializers' | 12 | } from '../initializers' |
13 | import { | ||
14 | readFilePromise, | ||
15 | bcryptComparePromise, | ||
16 | bcryptGenSaltPromise, | ||
17 | bcryptHashPromise, | ||
18 | accessPromise, | ||
19 | opensslExecPromise | ||
20 | } from './core-utils' | ||
15 | import { logger } from './logger' | 21 | import { logger } from './logger' |
16 | 22 | ||
17 | function checkSignature (publicKey: string, data: string, hexSignature: string) { | 23 | function checkSignature (publicKey: string, data: string, hexSignature: string) { |
@@ -60,46 +66,32 @@ function sign (data: string|Object) { | |||
60 | return signature | 66 | return signature |
61 | } | 67 | } |
62 | 68 | ||
63 | function comparePassword (plainPassword: string, hashPassword: string, callback: (err: Error, match?: boolean) => void) { | 69 | function comparePassword (plainPassword: string, hashPassword: string) { |
64 | bcrypt.compare(plainPassword, hashPassword, function (err, isPasswordMatch) { | 70 | return bcryptComparePromise(plainPassword, hashPassword) |
65 | if (err) return callback(err) | ||
66 | |||
67 | return callback(null, isPasswordMatch) | ||
68 | }) | ||
69 | } | 71 | } |
70 | 72 | ||
71 | function createCertsIfNotExist (callback: (err: Error) => void) { | 73 | function createCertsIfNotExist () { |
72 | certsExist(function (err, exist) { | 74 | return certsExist().then(exist => { |
73 | if (err) return callback(err) | ||
74 | |||
75 | if (exist === true) { | 75 | if (exist === true) { |
76 | return callback(null) | 76 | return undefined |
77 | } | 77 | } |
78 | 78 | ||
79 | createCerts(function (err) { | 79 | return createCerts() |
80 | return callback(err) | ||
81 | }) | ||
82 | }) | 80 | }) |
83 | } | 81 | } |
84 | 82 | ||
85 | function cryptPassword (password: string, callback: (err: Error, hash?: string) => void) { | 83 | function cryptPassword (password: string) { |
86 | bcrypt.genSalt(BCRYPT_SALT_SIZE, function (err, salt) { | 84 | return bcryptGenSaltPromise(BCRYPT_SALT_SIZE).then(salt => bcryptHashPromise(password, salt)) |
87 | if (err) return callback(err) | ||
88 | |||
89 | bcrypt.hash(password, salt, function (err, hash) { | ||
90 | return callback(err, hash) | ||
91 | }) | ||
92 | }) | ||
93 | } | 85 | } |
94 | 86 | ||
95 | function getMyPrivateCert (callback: (err: Error, privateCert: string) => void) { | 87 | function getMyPrivateCert () { |
96 | const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME) | 88 | const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME) |
97 | fs.readFile(certPath, 'utf8', callback) | 89 | return readFilePromise(certPath, 'utf8') |
98 | } | 90 | } |
99 | 91 | ||
100 | function getMyPublicCert (callback: (err: Error, publicCert: string) => void) { | 92 | function getMyPublicCert () { |
101 | const certPath = join(CONFIG.STORAGE.CERT_DIR, PUBLIC_CERT_NAME) | 93 | const certPath = join(CONFIG.STORAGE.CERT_DIR, PUBLIC_CERT_NAME) |
102 | fs.readFile(certPath, 'utf8', callback) | 94 | return readFilePromise(certPath, 'utf8') |
103 | } | 95 | } |
104 | 96 | ||
105 | // --------------------------------------------------------------------------- | 97 | // --------------------------------------------------------------------------- |
@@ -116,23 +108,21 @@ export { | |||
116 | 108 | ||
117 | // --------------------------------------------------------------------------- | 109 | // --------------------------------------------------------------------------- |
118 | 110 | ||
119 | function certsExist (callback: (err: Error, certsExist: boolean) => void) { | 111 | function certsExist () { |
120 | const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME) | 112 | const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME) |
121 | fs.access(certPath, function (err) { | ||
122 | // If there is an error the certificates do not exist | ||
123 | const exists = !err | ||
124 | return callback(null, exists) | ||
125 | }) | ||
126 | } | ||
127 | 113 | ||
128 | function createCerts (callback: (err: Error) => void) { | 114 | // If there is an error the certificates do not exist |
129 | certsExist(function (err, exist) { | 115 | return accessPromise(certPath) |
130 | if (err) return callback(err) | 116 | .then(() => true) |
117 | .catch(() => false) | ||
118 | } | ||
131 | 119 | ||
120 | function createCerts () { | ||
121 | return certsExist().then(exist => { | ||
132 | if (exist === true) { | 122 | if (exist === true) { |
133 | const errorMessage = 'Certs already exist.' | 123 | const errorMessage = 'Certs already exist.' |
134 | logger.warning(errorMessage) | 124 | logger.warning(errorMessage) |
135 | return callback(new Error(errorMessage)) | 125 | throw new Error(errorMessage) |
136 | } | 126 | } |
137 | 127 | ||
138 | logger.info('Generating a RSA key...') | 128 | logger.info('Generating a RSA key...') |
@@ -142,30 +132,27 @@ function createCerts (callback: (err: Error) => void) { | |||
142 | 'out': privateCertPath, | 132 | 'out': privateCertPath, |
143 | '2048': false | 133 | '2048': false |
144 | } | 134 | } |
145 | openssl.exec('genrsa', genRsaOptions, function (err) { | 135 | return opensslExecPromise('genrsa', genRsaOptions) |
146 | if (err) { | 136 | .then(() => { |
147 | logger.error('Cannot create private key on this pod.') | 137 | logger.info('RSA key generated.') |
148 | return callback(err) | 138 | logger.info('Managing public key...') |
149 | } | 139 | |
150 | 140 | const publicCertPath = join(CONFIG.STORAGE.CERT_DIR, 'peertube.pub') | |
151 | logger.info('RSA key generated.') | 141 | const rsaOptions = { |
152 | logger.info('Managing public key...') | 142 | 'in': privateCertPath, |
153 | 143 | 'pubout': true, | |
154 | const publicCertPath = join(CONFIG.STORAGE.CERT_DIR, 'peertube.pub') | 144 | 'out': publicCertPath |
155 | const rsaOptions = { | ||
156 | 'in': privateCertPath, | ||
157 | 'pubout': true, | ||
158 | 'out': publicCertPath | ||
159 | } | ||
160 | openssl.exec('rsa', rsaOptions, function (err) { | ||
161 | if (err) { | ||
162 | logger.error('Cannot create public key on this pod.') | ||
163 | return callback(err) | ||
164 | } | 145 | } |
165 | 146 | return opensslExecPromise('rsa', rsaOptions) | |
166 | logger.info('Public key managed.') | 147 | .then(() => logger.info('Public key managed.')) |
167 | return callback(null) | 148 | .catch(err => { |
149 | logger.error('Cannot create public key on this pod.') | ||
150 | throw err | ||
151 | }) | ||
152 | }) | ||
153 | .catch(err => { | ||
154 | logger.error('Cannot create private key on this pod.') | ||
155 | throw err | ||
168 | }) | 156 | }) |
169 | }) | ||
170 | }) | 157 | }) |
171 | } | 158 | } |
diff --git a/server/helpers/requests.ts b/server/helpers/requests.ts index b40fc8e39..b31074373 100644 --- a/server/helpers/requests.ts +++ b/server/helpers/requests.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import * as replay from 'request-replay' | 1 | import * as replay from 'request-replay' |
2 | import * as request from 'request' | 2 | import * as request from 'request' |
3 | import * as Promise from 'bluebird' | ||
3 | 4 | ||
4 | import { | 5 | import { |
5 | RETRY_REQUESTS, | 6 | RETRY_REQUESTS, |
@@ -14,16 +15,18 @@ type MakeRetryRequestParams = { | |||
14 | method: 'GET'|'POST', | 15 | method: 'GET'|'POST', |
15 | json: Object | 16 | json: Object |
16 | } | 17 | } |
17 | function makeRetryRequest (params: MakeRetryRequestParams, callback: request.RequestCallback) { | 18 | function makeRetryRequest (params: MakeRetryRequestParams) { |
18 | replay( | 19 | return new Promise<{ response: request.RequestResponse, body: any }>((res, rej) => { |
19 | request(params, callback), | 20 | replay( |
20 | { | 21 | request(params, (err, response, body) => err ? rej(err) : res({ response, body })), |
21 | retries: RETRY_REQUESTS, | 22 | { |
22 | factor: 3, | 23 | retries: RETRY_REQUESTS, |
23 | maxTimeout: Infinity, | 24 | factor: 3, |
24 | errorCodes: [ 'EADDRINFO', 'ETIMEDOUT', 'ECONNRESET', 'ESOCKETTIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED' ] | 25 | maxTimeout: Infinity, |
25 | } | 26 | errorCodes: [ 'EADDRINFO', 'ETIMEDOUT', 'ECONNRESET', 'ESOCKETTIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED' ] |
26 | ) | 27 | } |
28 | ) | ||
29 | }) | ||
27 | } | 30 | } |
28 | 31 | ||
29 | type MakeSecureRequestParams = { | 32 | type MakeSecureRequestParams = { |
@@ -33,41 +36,43 @@ type MakeSecureRequestParams = { | |||
33 | sign: boolean | 36 | sign: boolean |
34 | data?: Object | 37 | data?: Object |
35 | } | 38 | } |
36 | function makeSecureRequest (params: MakeSecureRequestParams, callback: request.RequestCallback) { | 39 | function makeSecureRequest (params: MakeSecureRequestParams) { |
37 | const requestParams = { | 40 | return new Promise<{ response: request.RequestResponse, body: any }>((res, rej) => { |
38 | url: REMOTE_SCHEME.HTTP + '://' + params.toPod.host + params.path, | 41 | const requestParams = { |
39 | json: {} | 42 | url: REMOTE_SCHEME.HTTP + '://' + params.toPod.host + params.path, |
40 | } | 43 | json: {} |
44 | } | ||
41 | 45 | ||
42 | if (params.method !== 'POST') { | 46 | if (params.method !== 'POST') { |
43 | return callback(new Error('Cannot make a secure request with a non POST method.'), null, null) | 47 | return rej(new Error('Cannot make a secure request with a non POST method.')) |
44 | } | 48 | } |
45 | 49 | ||
46 | // Add signature if it is specified in the params | 50 | // Add signature if it is specified in the params |
47 | if (params.sign === true) { | 51 | if (params.sign === true) { |
48 | const host = CONFIG.WEBSERVER.HOST | 52 | const host = CONFIG.WEBSERVER.HOST |
49 | 53 | ||
50 | let dataToSign | 54 | let dataToSign |
51 | if (params.data) { | 55 | if (params.data) { |
52 | dataToSign = params.data | 56 | dataToSign = params.data |
53 | } else { | 57 | } else { |
54 | // We do not have data to sign so we just take our host | 58 | // We do not have data to sign so we just take our host |
55 | // It is not ideal but the connection should be in HTTPS | 59 | // It is not ideal but the connection should be in HTTPS |
56 | dataToSign = host | 60 | dataToSign = host |
57 | } | 61 | } |
58 | 62 | ||
59 | requestParams.json['signature'] = { | 63 | requestParams.json['signature'] = { |
60 | host, // Which host we pretend to be | 64 | host, // Which host we pretend to be |
61 | signature: sign(dataToSign) | 65 | signature: sign(dataToSign) |
66 | } | ||
62 | } | 67 | } |
63 | } | ||
64 | 68 | ||
65 | // If there are data informations | 69 | // If there are data informations |
66 | if (params.data) { | 70 | if (params.data) { |
67 | requestParams.json['data'] = params.data | 71 | requestParams.json['data'] = params.data |
68 | } | 72 | } |
69 | 73 | ||
70 | request.post(requestParams, callback) | 74 | request.post(requestParams, (err, response, body) => err ? rej(err) : res({ response, body })) |
75 | }) | ||
71 | } | 76 | } |
72 | 77 | ||
73 | // --------------------------------------------------------------------------- | 78 | // --------------------------------------------------------------------------- |
diff --git a/server/helpers/utils.ts b/server/helpers/utils.ts index bbf135fa1..e99a48393 100644 --- a/server/helpers/utils.ts +++ b/server/helpers/utils.ts | |||
@@ -1,25 +1,14 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | 2 | ||
3 | import { pseudoRandomBytes } from 'crypto' | 3 | import { pseudoRandomBytesPromise } from './core-utils' |
4 | 4 | import { ResultList } from '../../shared' | |
5 | import { logger } from './logger' | ||
6 | 5 | ||
7 | function badRequest (req: express.Request, res: express.Response, next: express.NextFunction) { | 6 | function badRequest (req: express.Request, res: express.Response, next: express.NextFunction) { |
8 | res.type('json').status(400).end() | 7 | res.type('json').status(400).end() |
9 | } | 8 | } |
10 | 9 | ||
11 | function generateRandomString (size: number, callback: (err: Error, randomString?: string) => void) { | 10 | function generateRandomString (size: number) { |
12 | pseudoRandomBytes(size, function (err, raw) { | 11 | return pseudoRandomBytesPromise(size).then(raw => raw.toString('hex')) |
13 | if (err) return callback(err) | ||
14 | |||
15 | callback(null, raw.toString('hex')) | ||
16 | }) | ||
17 | } | ||
18 | |||
19 | function createEmptyCallback () { | ||
20 | return function (err) { | ||
21 | if (err) logger.error('Error in empty callback.', { error: err }) | ||
22 | } | ||
23 | } | 12 | } |
24 | 13 | ||
25 | interface FormatableToJSON { | 14 | interface FormatableToJSON { |
@@ -33,17 +22,18 @@ function getFormatedObjects<U, T extends FormatableToJSON> (objects: T[], object | |||
33 | formatedObjects.push(object.toFormatedJSON()) | 22 | formatedObjects.push(object.toFormatedJSON()) |
34 | }) | 23 | }) |
35 | 24 | ||
36 | return { | 25 | const res: ResultList<U> = { |
37 | total: objectsTotal, | 26 | total: objectsTotal, |
38 | data: formatedObjects | 27 | data: formatedObjects |
39 | } | 28 | } |
29 | |||
30 | return res | ||
40 | } | 31 | } |
41 | 32 | ||
42 | // --------------------------------------------------------------------------- | 33 | // --------------------------------------------------------------------------- |
43 | 34 | ||
44 | export { | 35 | export { |
45 | badRequest, | 36 | badRequest, |
46 | createEmptyCallback, | ||
47 | generateRandomString, | 37 | generateRandomString, |
48 | getFormatedObjects | 38 | getFormatedObjects |
49 | } | 39 | } |