|
87 | 87 |
|
88 | 88 | // Default fallback, if any
|
89 | 89 | randomFallback = null;
|
90 |
| - |
91 | 90 | /**
|
92 | 91 | * Sets the pseudo random number generator to use as a fallback if neither node's `crypto` module nor the Web Crypto
|
93 | 92 | * API is available. Please note: It is highly important that the PRNG used is cryptographically secure and that it
|
|
132 | 131 | * @param {(number|function(Error, string=))=} rounds Number of rounds to use, defaults to 10 if omitted
|
133 | 132 | * @param {(number|function(Error, string=))=} seed_length Not supported.
|
134 | 133 | * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting salt
|
| 134 | + * @returns {!Promise} If `callback` has been omitted |
| 135 | + * @throws {Error} If the callback argument is present but not a function |
135 | 136 | * @expose
|
136 | 137 | */
|
137 | 138 | bcrypt.genSalt = function(rounds, seed_length, callback) {
|
|
141 | 142 | if (typeof rounds === 'function')
|
142 | 143 | callback = rounds,
|
143 | 144 | rounds = GENSALT_DEFAULT_LOG2_ROUNDS;
|
144 |
| - if (typeof callback !== 'function') |
145 |
| - throw Error("Illegal callback: "+typeof(callback)); |
146 |
| - if (typeof rounds !== 'number') { |
147 |
| - nextTick(callback.bind(this, Error("Illegal arguments: "+(typeof rounds)))); |
148 |
| - return; |
| 145 | + |
| 146 | + function _async(callback) { |
| 147 | + nextTick(function() { // Pretty thin, but salting is fast enough |
| 148 | + if (typeof rounds !== 'number') { |
| 149 | + callback(Error("Illegal arguments: "+(typeof rounds))); |
| 150 | + return; |
| 151 | + } |
| 152 | + try { |
| 153 | + callback(null, bcrypt.genSaltSync(rounds)); |
| 154 | + } catch (err) { |
| 155 | + callback(err); |
| 156 | + } |
| 157 | + }); |
149 | 158 | }
|
150 |
| - nextTick(function() { // Pretty thin, but salting is fast enough |
151 |
| - try { |
152 |
| - callback(null, bcrypt.genSaltSync(rounds)); |
153 |
| - } catch (err) { |
154 |
| - callback(err); |
155 |
| - } |
156 |
| - }); |
| 159 | + |
| 160 | + if (callback) { |
| 161 | + if (typeof callback !== 'function') |
| 162 | + throw Error("Illegal callback: "+typeof(callback)); |
| 163 | + _async(callback); |
| 164 | + } else |
| 165 | + return new Promise(function(resolve, reject) { |
| 166 | + _async(function(err, res) { |
| 167 | + if (err) { |
| 168 | + reject(err); |
| 169 | + return; |
| 170 | + } |
| 171 | + resolve(res); |
| 172 | + }); |
| 173 | + }); |
157 | 174 | };
|
158 | 175 |
|
159 | 176 | /**
|
|
177 | 194 | * Asynchronously generates a hash for the given string.
|
178 | 195 | * @param {string} s String to hash
|
179 | 196 | * @param {number|string} salt Salt length to generate or salt to use
|
180 |
| - * @param {function(Error, string=)} callback Callback receiving the error, if any, and the resulting hash |
| 197 | + * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting hash |
181 | 198 | * @param {function(number)=} progressCallback Callback successively called with the percentage of rounds completed
|
182 | 199 | * (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms.
|
| 200 | + * @returns {!Promise} If `callback` has been omitted |
| 201 | + * @throws {Error} If the callback argument is present but not a function |
183 | 202 | * @expose
|
184 | 203 | */
|
185 | 204 | bcrypt.hash = function(s, salt, callback, progressCallback) {
|
186 |
| - if (typeof callback !== 'function') |
187 |
| - throw Error("Illegal callback: "+typeof(callback)); |
188 |
| - if (typeof s === 'string' && typeof salt === 'number') |
189 |
| - bcrypt.genSalt(salt, function(err, salt) { |
| 205 | + |
| 206 | + function _async(callback) { |
| 207 | + if (typeof s === 'string' && typeof salt === 'number') |
| 208 | + bcrypt.genSalt(salt, function(err, salt) { |
| 209 | + _hash(s, salt, callback, progressCallback); |
| 210 | + }); |
| 211 | + else if (typeof s === 'string' && typeof salt === 'string') |
190 | 212 | _hash(s, salt, callback, progressCallback);
|
| 213 | + else |
| 214 | + nextTick(callback.bind(this, Error("Illegal arguments: "+(typeof s)+', '+(typeof salt)))); |
| 215 | + } |
| 216 | + |
| 217 | + if (callback) { |
| 218 | + if (typeof callback !== 'function') |
| 219 | + throw Error("Illegal callback: "+typeof(callback)); |
| 220 | + _async(callback); |
| 221 | + } else |
| 222 | + return new Promise(function(resolve, reject) { |
| 223 | + _async(function(err, res) { |
| 224 | + if (err) { |
| 225 | + reject(err); |
| 226 | + return; |
| 227 | + } |
| 228 | + resolve(res); |
| 229 | + }); |
191 | 230 | });
|
192 |
| - else if (typeof s === 'string' && typeof salt === 'string') |
193 |
| - _hash(s, salt, callback, progressCallback); |
194 |
| - else |
195 |
| - nextTick(callback.bind(this, Error("Illegal arguments: "+(typeof s)+', '+(typeof salt)))); |
196 | 231 | };
|
197 | 232 |
|
198 | 233 | /**
|
|
237 | 272 | * Asynchronously compares the given data against the given hash.
|
238 | 273 | * @param {string} s Data to compare
|
239 | 274 | * @param {string} hash Data to be compared to
|
240 |
| - * @param {function(Error, boolean)} callback Callback receiving the error, if any, otherwise the result |
| 275 | + * @param {function(Error, boolean)=} callback Callback receiving the error, if any, otherwise the result |
241 | 276 | * @param {function(number)=} progressCallback Callback successively called with the percentage of rounds completed
|
242 | 277 | * (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms.
|
243 |
| - * @throws {Error} If the callback argument is invalid |
| 278 | + * @returns {!Promise} If `callback` has been omitted |
| 279 | + * @throws {Error} If the callback argument is present but not a function |
244 | 280 | * @expose
|
245 | 281 | */
|
246 | 282 | bcrypt.compare = function(s, hash, callback, progressCallback) {
|
247 |
| - if (typeof callback !== 'function') |
248 |
| - throw Error("Illegal callback: "+typeof(callback)); |
249 |
| - if (typeof s !== "string" || typeof hash !== "string") { |
250 |
| - nextTick(callback.bind(this, Error("Illegal arguments: "+(typeof s)+', '+(typeof hash)))); |
251 |
| - return; |
252 |
| - } |
253 |
| - if (hash.length !== 60) { |
254 |
| - nextTick(callback.bind(this, null, false)); |
255 |
| - return; |
| 283 | + |
| 284 | + function _async(callback) { |
| 285 | + if (typeof s !== "string" || typeof hash !== "string") { |
| 286 | + nextTick(callback.bind(this, Error("Illegal arguments: "+(typeof s)+', '+(typeof hash)))); |
| 287 | + return; |
| 288 | + } |
| 289 | + if (hash.length !== 60) { |
| 290 | + nextTick(callback.bind(this, null, false)); |
| 291 | + return; |
| 292 | + } |
| 293 | + bcrypt.hash(s, hash.substr(0, 29), function(err, comp) { |
| 294 | + if (err) |
| 295 | + callback(err); |
| 296 | + else |
| 297 | + callback(null, safeStringCompare(comp, hash)); |
| 298 | + }, progressCallback); |
256 | 299 | }
|
257 |
| - bcrypt.hash(s, hash.substr(0, 29), function(err, comp) { |
258 |
| - if (err) |
259 |
| - callback(err); |
260 |
| - else |
261 |
| - callback(null, safeStringCompare(comp, hash)); |
262 |
| - }, progressCallback); |
| 300 | + |
| 301 | + if (callback) { |
| 302 | + if (typeof callback !== 'function') |
| 303 | + throw Error("Illegal callback: "+typeof(callback)); |
| 304 | + _async(callback); |
| 305 | + } else |
| 306 | + return new Promise(function(resolve, reject) { |
| 307 | + _async(function(err, res) { |
| 308 | + if (err) { |
| 309 | + reject(err); |
| 310 | + return; |
| 311 | + } |
| 312 | + resolve(res); |
| 313 | + }); |
| 314 | + }); |
263 | 315 | };
|
264 | 316 |
|
265 | 317 | /**
|
|
0 commit comments