Skip to content

Commit

Permalink
test that challenges expire
Browse files Browse the repository at this point in the history
  • Loading branch information
finn-block committed Nov 17, 2023
1 parent 1a4a612 commit 367a7aa
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
17 changes: 16 additions & 1 deletion src/tenant-gate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,29 @@ export class TenantGate {
response: string;
} = req.body;

const challengeIssued = recentChallenges[body.challenge];
if (
challengeIssued == undefined ||
Date.now() - challengeIssued > CHALLENGE_TIMEOUT
) {
res
.status(401)
.json({ success: false, reason: 'challenge invalid or expired' });
return;
}

const hash = createHash('sha256');
hash.update(body.challenge);
hash.update(body.response);

const complexity = await this.getComplexity();
const digest = hash.digest('hex');
if (!digest.startsWith('0'.repeat(complexity))) {
res.status(401).json({ success: false });
res.status(401).json({
success: false,
reason: 'insufficiently complex',
requiredComplexity: complexity,
});
return;
}

Expand Down
42 changes: 42 additions & 0 deletions tests/http-api.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { expect } from 'chai';
import type { Server } from 'http';
import fetch from 'node-fetch';
import { webcrypto } from 'node:crypto';
import { useFakeTimers } from 'sinon';
import request from 'supertest';
import { v4 as uuidv4 } from 'uuid';

Expand Down Expand Up @@ -47,8 +48,11 @@ describe('http api', function () {
let profile: Profile;
let tenantGate: TenantGate;
let dwn: Dwn;
let clock;

before(async function () {
clock = useFakeTimers({ shouldAdvanceTime: true });

config.registrationRequirementPow = true;
const testdwn = await getTestDwn(true);
dwn = testdwn.dwn;
Expand All @@ -67,6 +71,10 @@ describe('http api', function () {
server.closeAllConnections();
});

after(function () {
clock.restore();
});

describe('/register/pow', function () {
it('returns a register challenge', async function () {
const response = await fetch('http://localhost:3000/register/pow');
Expand Down Expand Up @@ -110,6 +118,40 @@ describe('http api', function () {
expect(submitResponse.status).to.equal(200);
}).timeout(30000);

it('rejects a registration challenge 5 minutes after it was issued', async function () {
const challengeResponse = await fetch(
'http://localhost:3000/register/pow',
);
expect(challengeResponse.status).to.equal(200);
const body = (await challengeResponse.json()) as {
challenge: string;
complexity: number;
};
expect(body.challenge.length).to.equal(16);
expect(body.complexity).to.equal(5);

clock.tick(5 * 60 * 1000);
clock.runToLast();

// solve the challenge
let response = '';
while (!checkNonce(body.challenge, response, body.complexity)) {
response = generateNonce(5);
}

const submitResponse = await fetch('http://localhost:3000/register/pow', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
challenge: body.challenge,
response: response,
did: profile.did,
}),
});

expect(submitResponse.status).to.equal(401);
}).timeout(30000);

it('increase complexity as more challenges are completed', async function () {
for (let i = 1; i <= 60; i++) {
const p = await createProfile();
Expand Down

0 comments on commit 367a7aa

Please sign in to comment.