memory_randomstore.ts
1 import { RandomStore, RandomStoreOptions } from "./index"; 2 import dayjs, { Dayjs } from "dayjs"; 3 import * as util from "node:util"; 4 5 type RandomStoreEntry = { 6 string: string; 7 valid: boolean; 8 added: Dayjs; 9 } 10 11 const logger = util.debuglog('captchajs:randomstore:memory'); 12 13 const defaultOptions: RandomStoreOptions = { 14 expiryTimeSeconds: 60 * 60 * 24 15 } 16 17 export class MemoryRandomStore implements RandomStore { 18 private opts: RandomStoreOptions; 19 private validStrings: RandomStoreEntry[] = []; 20 21 constructor(opts?: RandomStoreOptions) { 22 logger("Constructing with options", opts); 23 this.opts = Object.assign({}, defaultOptions, opts); 24 logger("this.opts", this.opts); 25 } 26 27 addRandom(rs: string): boolean { 28 this.expire(); 29 30 // Don't care if it's valid. 31 logger("Checking if", rs, "is already recorded") 32 const index = this.validStrings.findIndex((entry) => entry.string === rs); 33 if (index >= 0) { 34 logger("It is, reject.") 35 return false; 36 } 37 38 this.validStrings.push({ string: rs, valid: true, added: dayjs() }); 39 logger("Accepted string"); 40 return true; 41 } 42 43 validateRandom(rs: string, invalidate= true): boolean { 44 this.expire(); 45 46 logger("Validating random string", rs, "- invalidate after?", invalidate); 47 const index = this.validStrings.findIndex((entry) => entry.string === rs && entry.valid) 48 if (index < 0) { 49 logger("String not found"); 50 return false; 51 } else { 52 logger("Found at position", index); 53 } 54 55 if (invalidate) { 56 logger("Marking no longer valid"); 57 this.validStrings[index].valid = false; 58 } 59 60 return true; 61 } 62 63 expire(): void { 64 const now = dayjs(); 65 logger("Running expiry"); 66 this.validStrings.forEach((entry) => { 67 if (entry.valid) { 68 // expiryTimeSeconds will exist, it comes from defaultOptions if they don't provide one. 69 if (now.isAfter(entry.added.add(this.opts.expiryTimeSeconds!, "seconds"))) { 70 logger("Expiring entry", entry); 71 entry.valid = false; 72 } 73 } 74 }) 75 } 76 }