POF for retrying extension
This commit is contained in:
1 parent
1b955f06ed
commit
b5b6ca363d
11 files changed
+256
-50
No files matched your search
-45
@@ -1,45 +0,0 @@
|
|||||||
// Function to send POST request
|
|
||||||
function sendPostRequest(data) {
|
|
||||||
fetch('https://ntfy.sh/snegov', {
|
|
||||||
method: 'POST', // PUT works too
|
|
||||||
body: `US visa: ${data}`
|
|
||||||
})
|
|
||||||
.then(response => {
|
|
||||||
console.log('POST request sent successfully:', data);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error('Error sending POST request:', error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkDate() {
|
|
||||||
const targetElement = document.querySelector('.swal2-html-container');
|
|
||||||
// Get current time
|
|
||||||
const currentTime = new Date();
|
|
||||||
const formattedTime = currentTime.toISOString();
|
|
||||||
|
|
||||||
if (targetElement) {
|
|
||||||
const availabilitySpan = targetElement.querySelector('span[style="color: lightgreen;"]');
|
|
||||||
const appointmentSpan = targetElement.querySelector('span[style="color: orange"]');
|
|
||||||
|
|
||||||
const date_avail = availabilitySpan ? availabilitySpan.textContent.match(/Latest availability: (.*)\./)[1].trim() : null;
|
|
||||||
const date_booked = appointmentSpan ? appointmentSpan.textContent.match(/Your current appointment is on (.*)/)[1].trim() : null;
|
|
||||||
|
|
||||||
if (date_avail && date_booked) {
|
|
||||||
const date_avail_date = new Date(date_avail);
|
|
||||||
const date_booked_date = new Date(date_booked);
|
|
||||||
console.log(`${formattedTime}: available date ${date_avail}; booked on ${date_booked}`);
|
|
||||||
|
|
||||||
// Compare the dates
|
|
||||||
if (date_avail_date < date_booked_date) {
|
|
||||||
const message = `available date ${date_avail}; booked on ${date_booked}`;
|
|
||||||
sendPostRequest(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('Element with class "swal2-html-container" not found');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set an interval to check the date every 10 seconds
|
|
||||||
setInterval(checkDate, 20000);
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 309 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
+18
-5
@@ -1,12 +1,25 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "Page Change Detector",
|
"name": "not-a-rescheduler",
|
||||||
"version": "1.0",
|
"version": "0.0.1",
|
||||||
"permissions": ["activeTab"],
|
"permissions": [ "storage", "tabs", "activeTab", "notifications", "declarativeContent" ],
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
"matches": ["https://ais.usvisa-info.com/*"],
|
"matches": ["https://ais.usvisa-info.com/*"],
|
||||||
"js": ["content.js"]
|
"js": ["scripts/content.js"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"action": {
|
||||||
|
"default_popup": "popup/popup.html",
|
||||||
|
"default_icon": "images/icon_passport_48.png"
|
||||||
|
},
|
||||||
|
"background": {
|
||||||
|
"service_worker": "background.js"
|
||||||
|
},
|
||||||
|
"icons": {
|
||||||
|
"16": "images/icon_passport_16.png",
|
||||||
|
"48": "images/icon_passport_48.png",
|
||||||
|
"128": "images/icon_passport_128.png",
|
||||||
|
"512": "images/icon_passport_512.png"
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
}
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
@charset "UTF-8";/*!
|
||||||
|
* Bootstrap v5.3.3 (https://getbootstrap.com/)
|
||||||
|
* Copyright 2011-2024 The Bootstrap Authors
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
|
*/:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherLine truncated
|
||||||
|
/*# sourceMappingURL=bootstrap.min.css.map */
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#saveStatus {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.5s;
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
#saveStatus.show {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>not-a-rescheduler popup</title>
|
||||||
|
<link rel="stylesheet" href="bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="popup.css">
|
||||||
|
<style>
|
||||||
|
/* Set a minimum width for the body */
|
||||||
|
body {
|
||||||
|
min-width: 300px; /* Adjust the value as desired */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h3 style="white-space: nowrap;">not-a-rescheduler<br><span id="version"></span></h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="form-check form-switch" style="text-align: left;">
|
||||||
|
<input class="form-check-input" type="checkbox" role="switch" id="activate">
|
||||||
|
<label class="form-check-label" for="activate">Activate the script</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="form-group mb-2">
|
||||||
|
<label for="username">Username</label>
|
||||||
|
<input type="text" class="form-control" id="username" placeholder="Username">
|
||||||
|
</div>
|
||||||
|
<div class="form-group mb-2">
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input type="password" class="form-control" id="password" placeholder="Password">
|
||||||
|
<button type="button" id="showPassword" class="btn btn-link btn-sm">Show password</button>
|
||||||
|
</div>
|
||||||
|
<div class="mb-2">
|
||||||
|
<button type="button mb-2" class="btn btn-primary" id="saveButton">Save credentials</button>
|
||||||
|
<span id="saveStatus">Saved!</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="mb-2">
|
||||||
|
<input type="range" id="frequency" name="frequency" min="1" max="10" step="0.5">
|
||||||
|
<label for="frequency">Frequency of checks<br>(every <span id="frequency_info">1</span> minutes)</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="popup.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
(async function() {
|
||||||
|
|
||||||
|
const $version = await new Promise(r => chrome.management.getSelf(self => r(self.version)));
|
||||||
|
document.getElementById("version").innerText = `v${$version}`;
|
||||||
|
|
||||||
|
await chrome.storage.local.get().then(items => {
|
||||||
|
document.getElementById("activate").checked = items["__activate"] || false;
|
||||||
|
document.getElementById("username").value = items["__username"] || "";
|
||||||
|
document.getElementById("password").value = items["__password"] || "";
|
||||||
|
document.getElementById("frequency").value = items["__frequency"] || 1;
|
||||||
|
document.getElementById("frequency_info").innerText = items["__frequency"] || 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
chrome.storage.onChanged.addListener((changes, area) => {
|
||||||
|
if (changes.__frequency)
|
||||||
|
document.getElementById("frequency_info").innerText = changes.__frequency.newValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
// activate checkbox
|
||||||
|
document.getElementById("activate").addEventListener("change", async e => {
|
||||||
|
await chrome.storage.local.set({ "__activate": e.target.checked });
|
||||||
|
});
|
||||||
|
|
||||||
|
// credentials
|
||||||
|
let usernameField = document.getElementById("username");
|
||||||
|
let passwordField = document.getElementById("password");
|
||||||
|
let showPasswordButton = document.getElementById("showPassword");
|
||||||
|
let saveCredsButton = document.getElementById("saveButton");
|
||||||
|
let saveStatusElement = document.getElementById("saveStatus");
|
||||||
|
|
||||||
|
async function save_credentials() {
|
||||||
|
await chrome.storage.local.set({
|
||||||
|
"__username": usernameField.value,
|
||||||
|
"__password": passwordField.value
|
||||||
|
});
|
||||||
|
saveStatusElement.classList.add("show");
|
||||||
|
setTimeout(() => {
|
||||||
|
saveStatusElement.classList.remove("show");
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
usernameField.addEventListener("keypress", async e => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
await save_credentials();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
passwordField.addEventListener("keypress", async e => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
await save_credentials();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
saveCredsButton.addEventListener("click", async () => {
|
||||||
|
await save_credentials();
|
||||||
|
});
|
||||||
|
|
||||||
|
showPasswordButton.addEventListener("mousedown", function() {
|
||||||
|
passwordField.type = "text";
|
||||||
|
});
|
||||||
|
showPasswordButton.addEventListener("mouseup", function() {
|
||||||
|
passwordField.type = "password";
|
||||||
|
});
|
||||||
|
|
||||||
|
// frequency range slider
|
||||||
|
document.getElementById("frequency").addEventListener("change", function() {
|
||||||
|
chrome.storage.local.set({ __frequency: this.value });
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
function log_ts(message) {
|
||||||
|
console.log(new Date().toISOString() + " " + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function checkDates() {
|
||||||
|
log_ts('checkDates start');
|
||||||
|
config.countdown = config.frequency * minute;
|
||||||
|
await chrome.storage.local.set({ "__countdown": config.countdown });
|
||||||
|
log_ts('checkDates done');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function runner() {
|
||||||
|
// log_ts('runner start');
|
||||||
|
let prev_config = Object.assign({}, config);
|
||||||
|
|
||||||
|
let result = await new Promise(resolve => chrome.storage.local.get(null, resolve));
|
||||||
|
config.activate = result['__activate'] || false;
|
||||||
|
config.username = result['__username'] || "";
|
||||||
|
config.password = result['__password'] || "";
|
||||||
|
config.frequency = result['__frequency'] || 1;
|
||||||
|
config.countdown = result['__countdown'] || 0;
|
||||||
|
|
||||||
|
if (prev_config.activate === null) {
|
||||||
|
log_ts('Reading config: ' + JSON.stringify(config));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let configChanged = false;
|
||||||
|
for (let key in config) {
|
||||||
|
if (config.hasOwnProperty(key) && config[key] !== prev_config[key]) {
|
||||||
|
log_ts(`Config change: ${key}, ${prev_config[key]} => ${config[key]}`);
|
||||||
|
configChanged = true;
|
||||||
|
// reduce countdown if frequency is reduced
|
||||||
|
if (key === 'frequency') {
|
||||||
|
let max_countdown = config[key] * minute;
|
||||||
|
if (config.countdown > max_countdown) {
|
||||||
|
config.countdown = max_countdown;
|
||||||
|
await chrome.storage.local.set({ "__countdown": config.countdown });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (configChanged) {
|
||||||
|
// print whole config
|
||||||
|
log_ts(JSON.stringify(config));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.activate && !prev_config.activate) {
|
||||||
|
log_ts('Activating extension');
|
||||||
|
config.countdown = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config.activate) {
|
||||||
|
// reset countdown when deactivating the extension
|
||||||
|
if (prev_config.activate) {
|
||||||
|
log_ts('Deactivating extension');
|
||||||
|
config.countdown = 0;
|
||||||
|
await chrome.storage.local.set({ "__countdown": config.countdown });
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.username === "" || config.password === "") {
|
||||||
|
log_ts('Username or password is empty');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.frequency <= 0) {
|
||||||
|
log_ts('Frequency is 0');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.countdown > 0) {
|
||||||
|
config.countdown -= 1;
|
||||||
|
log_ts(`Countdown: ${config.countdown}`);
|
||||||
|
await chrome.storage.local.set({ "__countdown": config.countdown });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkDates();
|
||||||
|
|
||||||
|
|
||||||
|
// log_ts('runner done');
|
||||||
|
}
|
||||||
|
|
||||||
|
let config = {
|
||||||
|
activate: null,
|
||||||
|
username: null,
|
||||||
|
password: null,
|
||||||
|
frequency: null,
|
||||||
|
countdown: null,
|
||||||
|
};
|
||||||
|
let minute = 60;
|
||||||
|
|
||||||
|
setInterval(runner, 1000);
|
||||||
Reference in new issue
Block a user