Browse Source

Added signer with ttl

main
bitnix 4 months ago
parent
commit
ad36a60b28
  1. 49
      src/expiring-signer.ts
  2. 4
      src/index.ts
  3. 28
      test/expiring-signer.test.ts

49
src/expiring-signer.ts

@ -0,0 +1,49 @@
import crypto from 'crypto';
import { Signer } from './signer.js';
function time() : number {
return Math.floor(Date.now() / 1000);
}
export class ExpiringSigner implements Signer {
ttl: number;
algo: string;
constructor(ttl: number = 10, algo: string = 'sha256') {
this.ttl = ttl;
this.algo = algo;
}
sign(secret: string, payload: string) : string {
const now = time();
return now
+ '.'
+ crypto
.createHmac(this.algo, secret)
.update(now + payload).digest('hex');
}
verify(secret: string, signature: string, payload: string) : boolean {
const dot = signature.indexOf('.');
if (-1 === dot) {
return false;
}
const stamp = parseInt(signature.substring(0, dot));
const hash = signature.substring(dot + 1);
try {
const computed = crypto.createHmac(this.algo, secret).update(stamp + payload).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(computed), Buffer.from(hash))) {
return false;
}
} catch (x) {
return false;
}
return time() <= stamp + this.ttl;
}
}

4
src/index.ts

@ -1,5 +1,7 @@
import { BasicSigner } from './basic-signer.js';
import { ExpiringSigner } from './expiring-signer.js';
export {
BasicSigner
BasicSigner,
ExpiringSigner
};

28
test/expiring-signer.test.ts

@ -0,0 +1,28 @@
import { expect } from 'chai';
import { ExpiringSigner } from '../src/expiring-signer';
describe('ExpiringSigner', function() {
it('signed payloads should validate when given the correct input', function() {
const signer = new ExpiringSigner();
const signature = signer.sign('foo', 'bar');
expect(signer.verify('foo', signature, 'bar')).to.be.true;
});
it('signed payloads should not validate when given incorrect input', function() {
const signer = new ExpiringSigner();
const signature = signer.sign('foo', 'bar');
// bad signature
expect(signer.verify('foo', 'bad-signature', 'bar')).to.be.false;
// bad payload
expect(signer.verify('foo', signature, 'baz')).to.be.false;
});
it('signed payloads should not validate when given expired input', function() {
const signer = new ExpiringSigner(-10); // expired 10 seconds ago...
const signature = signer.sign('foo', 'bar');
expect(signer.verify('foo', signature, 'bar')).to.be.false;
});
});
Loading…
Cancel
Save