+ /**
+ *
+ * @param {Object} state
+ * @param {String} state.key
+ * @param {Number} state.attempt
+ * @param {Number} state.epochMs
+ * @param {String} otp
+ * @returns {String} Enum.OTPResult
+ */
+ checkOTP(state, otp) {
+ const totp = new this.TOTP({
+ ...this.options?.authenticator?.otpOptions,
+ ...state,
+ });
+ const isValid = totp.validate(otp);
+ if (isValid) {
+ return Enum.OTPResult.Valid;
+ }
+ const otpAttemptsRemain = state.attempt <= (this.options?.authenticator?.otpAttemptsAllowed ?? 3);
+ const otpWithinWindow = state.epochMs + (this.options?.authenticator?.otpWindowMs ?? 600000) > Date.now();
+ if (otpAttemptsRemain && otpWithinWindow) {
+ return Enum.OTPResult.InvalidSoftFail;
+ }
+ return Enum.OTPResult.InvalidHardFail;
+ }
+
+