This commit is contained in:
“xHuPo” 2025-06-09 13:35:15 +08:00
commit 2b8870a40e
51 changed files with 5845 additions and 0 deletions

132
utils/totp.test.js Normal file
View file

@ -0,0 +1,132 @@
const totp = require('./totp');
console.log('=== TOTP Implementation Test Suite ===\n');
function runTests() {
// 1. Basic Functionality Tests
console.log('1. Basic Functionality Tests:');
const testSecret = 'JBSWY3DPEHPK3PXP';
const testTime = 1623456789000; // Fixed timestamp for consistent testing
try {
const code = totp.generate(testTime, testSecret);
console.log('Generate TOTP code:');
console.log(` Secret: ${testSecret}`);
console.log(` Time: ${new Date(testTime).toISOString()}`);
console.log(` Code: ${code}`);
console.log(` Length: ${code.length} digits`);
console.log(' Result: ✓ (Generated successfully)\n');
} catch (error) {
console.log(` Result: ✗ (${error.message})\n`);
}
// 2. Verification Tests
console.log('2. Verification Tests:');
const currentCode = totp.now(testSecret);
const verifyResults = [
totp.verify(currentCode, testSecret),
totp.verify('000000', testSecret),
totp.verify(currentCode, 'WRONGSECRET')
];
console.log('Verify current code:');
console.log(` Code: ${currentCode}`);
console.log(` Valid code: ${verifyResults[0] ? '✓' : '✗'}`);
console.log(` Invalid code: ${!verifyResults[1] ? '✓' : '✗'}`);
console.log(` Wrong secret: ${!verifyResults[2] ? '✓' : '✗'}\n`);
// 3. Configuration Tests
console.log('3. Configuration Tests:');
const configs = [
{ digits: 8 },
{ interval: 60 },
{ algorithm: 'SHA-256' }
];
configs.forEach(config => {
try {
const code = totp.generate(testTime, testSecret, config);
console.log(`Custom config (${Object.keys(config)[0]}=${Object.values(config)[0]}):`);
console.log(` Code: ${code}`);
console.log(' Result: ✓\n');
} catch (error) {
console.log(`Custom config (${Object.keys(config)[0]}=${Object.values(config)[0]}):`);
console.log(` Result: ✗ (${error.message})\n`);
}
});
// 4. Error Handling Tests
console.log('4. Error Handling Tests:');
const errorTests = [
['Invalid secret', () => totp.generate(testTime, '')],
['Invalid digits', () => totp.generate(testTime, testSecret, { digits: 4 })],
['Invalid interval', () => totp.generate(testTime, testSecret, { interval: -1 })],
['Invalid algorithm', () => totp.generate(testTime, testSecret, { algorithm: 'INVALID' })]
];
errorTests.forEach(([name, test]) => {
try {
test();
console.log(`${name}: ✗ (Should have thrown)`);
} catch (error) {
console.log(`${name}: ✓ (${error.type})`);
}
});
console.log('');
// 5. URI Generation Test
console.log('5. URI Generation Test:');
try {
const uri = totp.generateUri(
testSecret,
'test@example.com',
'TestApp',
{ digits: 8, interval: 60 }
);
console.log('Generated URI:');
console.log(` ${uri}`);
console.log(' Result: ✓\n');
} catch (error) {
console.log(` Result: ✗ (${error.message})\n`);
}
// 6. Time Window Tests
console.log('6. Time Window Tests:');
const remaining = totp.timeRemaining();
console.log(`Time until next code: ${remaining} seconds`);
// Test window verification
const currentTime = Date.now();
const pastCode = totp.generate(currentTime - 30000, testSecret);
const futureCode = totp.generate(currentTime + 30000, testSecret);
console.log('Time window verification:');
console.log(` Past code valid: ${totp.verify(pastCode, testSecret, { window: 1 }) ? '✓' : '✗'}`);
console.log(` Future code valid: ${totp.verify(futureCode, testSecret, { window: 1 }) ? '✓' : '✗'}`);
console.log(` Outside window invalid: ${!totp.verify(pastCode, testSecret, { window: 0 }) ? '✓' : '✗'}\n`);
// 7. Security Tests
console.log('7. Security Tests:');
// Test timing attack resistance
const start = Date.now();
for (let i = 0; i < 1000; i++) {
totp.verify('000000', testSecret);
totp.verify('999999', testSecret);
}
const end = Date.now();
const timeDiff = Math.abs((end - start) / 2000);
console.log('Timing attack resistance:');
console.log(` Average verification time: ${timeDiff.toFixed(3)}ms`);
console.log(` Time consistency: ${timeDiff < 1 ? '✓' : '✗'}`);
}
// Run all tests
runTests();