2020-07-27 18:18:52 +00:00
|
|
|
const crypto = require('crypto');
|
|
|
|
|
|
|
|
function makeToken(secret, counter) {
|
|
|
|
const hmac = crypto.createHmac('sha256', secret);
|
|
|
|
hmac.update(String(counter));
|
|
|
|
return hmac.digest('hex');
|
|
|
|
}
|
|
|
|
|
2018-02-06 22:31:18 +00:00
|
|
|
class Metadata {
|
2020-07-27 18:18:52 +00:00
|
|
|
constructor(obj, storage) {
|
|
|
|
this.id = obj.id;
|
2018-02-06 22:31:18 +00:00
|
|
|
this.dl = +obj.dl || 0;
|
2020-07-27 18:18:52 +00:00
|
|
|
this.dlToken = +obj.dlToken || 0;
|
2018-02-06 22:31:18 +00:00
|
|
|
this.dlimit = +obj.dlimit || 1;
|
2020-07-27 18:18:52 +00:00
|
|
|
this.pwd = !!+obj.pwd;
|
2018-02-06 22:31:18 +00:00
|
|
|
this.owner = obj.owner;
|
|
|
|
this.metadata = obj.metadata;
|
|
|
|
this.auth = obj.auth;
|
|
|
|
this.nonce = obj.nonce;
|
2020-07-13 17:21:28 +00:00
|
|
|
this.flagged = !!obj.flagged;
|
|
|
|
this.dead = !!obj.dead;
|
2020-07-27 18:18:52 +00:00
|
|
|
this.fxa = !!+obj.fxa;
|
|
|
|
this.storage = storage;
|
|
|
|
}
|
|
|
|
|
|
|
|
async getDownloadToken() {
|
|
|
|
if (this.dlToken >= this.dlimit) {
|
|
|
|
throw new Error('limit');
|
|
|
|
}
|
|
|
|
this.dlToken = await this.storage.incrementField(this.id, 'dlToken');
|
|
|
|
// another request could have also incremented
|
|
|
|
if (this.dlToken > this.dlimit) {
|
|
|
|
throw new Error('limit');
|
|
|
|
}
|
|
|
|
return makeToken(this.owner, this.dlToken);
|
|
|
|
}
|
|
|
|
|
|
|
|
async verifyDownloadToken(token) {
|
|
|
|
const validTokens = Array.from({ length: this.dlToken }, (_, i) =>
|
|
|
|
makeToken(this.owner, i + 1)
|
|
|
|
);
|
|
|
|
return validTokens.includes(token);
|
2018-02-06 22:31:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = Metadata;
|