diff --git a/index.js b/index.js
index 031b442..072cb5a 100644
--- a/index.js
+++ b/index.js
@@ -520,9 +520,19 @@ function evaluatePendingActionTimeout(user, now = Date.now()) {
return { hadPending: false, expired: false, expiredType: null };
}
- if (!user.pendingAction.createdAt) user.pendingAction.createdAt = now;
+ const nowMs = Number(now);
+ const safeNow = Number.isFinite(nowMs) ? nowMs : Date.now();
+ const createdRaw = user.pendingAction.createdAt;
+ const createdMs = Number(createdRaw);
+ if (!Number.isFinite(createdMs)) user.pendingAction.createdAt = safeNow;
+
+ const normalizedCreatedAt = Number(user.pendingAction.createdAt);
+ if (!Number.isFinite(normalizedCreatedAt)) {
+ user.pendingAction.createdAt = safeNow;
+ return { hadPending: true, expired: false, expiredType: null };
+ }
- if ((now - Number(user.pendingAction.createdAt || 0)) <= PENDING_ACTION_TIMEOUT_MS) {
+ if ((safeNow - normalizedCreatedAt) <= PENDING_ACTION_TIMEOUT_MS) {
return { hadPending: true, expired: false, expiredType: null };
}
@@ -4651,7 +4661,7 @@ function referralShareHTML(code) {
Daily giveaways, instant rewards, drops, and a secret new-user bonus waiting inside the bot.
-Use my code ${code} when you start ā we BOTH get a 2Ć boost on all giveaways for 7 days.
+Use my code ${escapeHtml(code)} when you start ā we BOTH get a 2Ć boost on all giveaways for 7 days.
š Tap here to join Runewager
diff --git a/load_tooltips.sh b/load_tooltips.sh
index 0d3a535..edd9f78 100755
--- a/load_tooltips.sh
+++ b/load_tooltips.sh
@@ -1,4 +1,35 @@
-#!/usr/bin/env bash
+#!/bin/bash
+
+echo "=== GCZ ā TOOLTIP PIPELINE EXECUTION ==="
+
+cd /var/www/html/Runewager || exit 1
+
+echo "[1] Pulling latest from origin main..."
+git pull origin main || exit 1
+
+echo "[2] Ensuring data directory exists..."
+mkdir -p /var/www/html/Runewager/data
+
+echo "[3] Ensuring tooltips.json exists..."
+if [ ! -f /var/www/html/Runewager/data/tooltips.json ]; then
+ echo "[]" > /var/www/html/Runewager/data/tooltips.json
+ echo "Created empty tooltips.json"
+fi
+
+echo "[6] Adding data/tooltips.json to .gitignore if missing..."
+grep -qxF "data/tooltips.json" .gitignore || echo "data/tooltips.json" >> .gitignore
+
+echo "[7] Staging .gitignore only..."
+git add .gitignore
+
+echo "[8] Committing..."
+git commit -m "GCZ: ensure tooltips.json exists, ignore it, and run load_tooltips.sh"
+
+echo "[9] Pushing to origin main..."
+git push origin main
+
+echo "=== GCZ ā DONE ==="
+
set -euo pipefail
OUT="/var/www/html/Runewager/data/tooltips.json"
diff --git a/test/smoke.test.js b/test/smoke.test.js
index 5455250..4e73ff2 100644
--- a/test/smoke.test.js
+++ b/test/smoke.test.js
@@ -208,8 +208,14 @@ function extractActionRegexPatterns(source) {
* Supports `.*`, `^.*$`, and `.+` with optional grouping/anchors.
*/
function isCatchAllRegexPattern(patternSource) {
- const compact = String(patternSource || '').replace(/\s+/g, '');
- return compact === '.*' || compact === '^.*$' || compact === '.+' || compact === '^.+$';
+ let compact = String(patternSource || '').replace(/\s+/g, '');
+ compact = compact.replace(/^\^/, '').replace(/\$$/, '');
+ while (compact.startsWith('(') && compact.endsWith(')')) compact = compact.slice(1, -1);
+ compact = compact.replace(/^\?:/, '');
+
+ if (['.*', '.+', '.*?', '.+?'].includes(compact)) return true;
+ if (/^\(\?:?\.?\*\)$/.test(String(patternSource || '').replace(/\s+/g, ''))) return true;
+ return false;
}
/**
diff --git a/test/unit.test.js b/test/unit.test.js
index aa7d322..48eeec0 100644
--- a/test/unit.test.js
+++ b/test/unit.test.js
@@ -503,12 +503,21 @@ test('discord links remain external and unwrap telegram wrappers', () => {
+function escapeHtml(text) {
+ return String(text || '')
+ .replace(/&/g, '&')
+ .replace(//g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''');
+}
+
function referralShareHTML(code) {
return `šØ YO! Iām farming free SC on Runewager and you need to get in NOW.
Daily giveaways, instant rewards, drops, and a secret new-user bonus waiting inside the bot.
-Use my code ${code} when you start ā we BOTH get a 2Ć boost on all giveaways for 7 days.
+Use my code ${escapeHtml(code)} when you start ā we BOTH get a 2Ć boost on all giveaways for 7 days.
š Tap here to join Runewager
@@ -595,3 +604,10 @@ test('manual bonus policy allows requests without auto wager/API checks', () =>
assert.equal(checkBonusEligibilityLike({ status: 'bonus_sent', attempts: 1 }).ok, false);
assert.equal(checkBonusEligibilityLike({ status: 'none', attempts: 3 }).ok, false);
});
+
+
+test('referralShareHTML escapes HTML-sensitive referral codes', () => {
+ const html = referralShareHTML('
');
+ assert.ok(!html.includes('