|
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