metadata.js 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. const crypto = require('crypto');
  2. function makeToken(secret, counter) {
  3. const hmac = crypto.createHmac('sha256', secret);
  4. hmac.update(String(counter));
  5. return hmac.digest('hex');
  6. }
  7. class Metadata {
  8. constructor(obj, storage) {
  9. this.id = obj.id;
  10. this.dl = +obj.dl || 0;
  11. this.dlToken = +obj.dlToken || 0;
  12. this.dlimit = +obj.dlimit || 1;
  13. this.pwd = !!+obj.pwd;
  14. this.owner = obj.owner;
  15. this.metadata = obj.metadata;
  16. this.auth = obj.auth;
  17. this.nonce = obj.nonce;
  18. this.flagged = !!obj.flagged;
  19. this.dead = !!obj.dead;
  20. this.fxa = !!+obj.fxa;
  21. this.storage = storage;
  22. }
  23. async getDownloadToken() {
  24. if (this.dlToken >= this.dlimit) {
  25. throw new Error('limit');
  26. }
  27. this.dlToken = await this.storage.incrementField(this.id, 'dlToken');
  28. // another request could have also incremented
  29. if (this.dlToken > this.dlimit) {
  30. throw new Error('limit');
  31. }
  32. return makeToken(this.owner, this.dlToken);
  33. }
  34. async verifyDownloadToken(token) {
  35. const validTokens = Array.from({ length: this.dlToken }, (_, i) =>
  36. makeToken(this.owner, i + 1)
  37. );
  38. return validTokens.includes(token);
  39. }
  40. }
  41. module.exports = Metadata;