credential.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. define([
  2. '/customize/application_config.js',
  3. '/bower_components/scrypt-async/scrypt-async.min.js',
  4. ], function (AppConfig) {
  5. var Cred = {};
  6. var Scrypt = window.scrypt;
  7. Cred.MINIMUM_PASSWORD_LENGTH = typeof(AppConfig.minimumPasswordLength) === 'number'?
  8. AppConfig.minimumPasswordLength: 8;
  9. Cred.isLongEnoughPassword = function (passwd) {
  10. return passwd.length >= Cred.MINIMUM_PASSWORD_LENGTH;
  11. };
  12. var isString = Cred.isString = function (x) {
  13. return typeof(x) === 'string';
  14. };
  15. Cred.isValidUsername = function (name) {
  16. return !!(name && isString(name));
  17. };
  18. Cred.isValidPassword = function (passwd) {
  19. return !!(passwd && isString(passwd));
  20. };
  21. Cred.passwordsMatch = function (a, b) {
  22. return isString(a) && isString(b) && a === b;
  23. };
  24. Cred.customSalt = function () {
  25. return typeof(AppConfig.loginSalt) === 'string'?
  26. AppConfig.loginSalt: '';
  27. };
  28. Cred.deriveFromPassphrase = function (username, password, len, cb) {
  29. Scrypt(password,
  30. username + Cred.customSalt(), // salt
  31. 8, // memoryCost (n)
  32. 1024, // block size parameter (r)
  33. len || 128, // dkLen
  34. 200, // interruptStep
  35. cb,
  36. undefined); // format, could be 'base64'
  37. };
  38. Cred.dispenser = function (bytes) {
  39. var entropy = {
  40. used: 0,
  41. };
  42. // crypto hygeine
  43. var consume = function (n) {
  44. // explode if you run out of bytes
  45. if (entropy.used + n > bytes.length) {
  46. throw new Error('exceeded available entropy');
  47. }
  48. if (typeof(n) !== 'number') { throw new Error('expected a number'); }
  49. if (n <= 0) {
  50. throw new Error('expected to consume a positive number of bytes');
  51. }
  52. // grab an unused slice of the entropy
  53. // Note: Internet Explorer doesn't support .slice on Uint8Array
  54. var A;
  55. if (bytes.slice) {
  56. A = bytes.slice(entropy.used, entropy.used + n);
  57. } else {
  58. A = bytes.subarray(entropy.used, entropy.used + n);
  59. }
  60. // account for the bytes you used so you don't reuse bytes
  61. entropy.used += n;
  62. //console.info("%s bytes of entropy remaining", bytes.length - entropy.used);
  63. return A;
  64. };
  65. return consume;
  66. };
  67. return Cred;
  68. });