2023-10-17 19:04:15 +02:00
|
|
|
"use strict;"
|
2023-10-14 16:28:19 +02:00
|
|
|
function luhnValidate(cardNumber) {
|
|
|
|
cardNumber = String(cardNumber).replace(/[\s]/g, "");
|
|
|
|
let odd = false;
|
|
|
|
let total = 0;
|
|
|
|
let position, doubledPos;
|
|
|
|
|
|
|
|
if (!/^[0-9]+$/.test(cardNumber)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = cardNumber.length; i > 0; i--) {
|
|
|
|
position = parseInt(cardNumber[i - 1]);
|
|
|
|
if (!odd) {
|
|
|
|
total += position;
|
|
|
|
} else {
|
|
|
|
doubledPos = position * 2;
|
|
|
|
|
|
|
|
if (doubledPos > 9) {
|
|
|
|
doubledPos -= 9;
|
|
|
|
}
|
|
|
|
total += doubledPos;
|
|
|
|
}
|
|
|
|
odd = !odd;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (total !== 0 && (total % 10) === 0);
|
|
|
|
}
|
2023-11-13 22:06:21 +01:00
|
|
|
function ibanLatinCharId(chr) {
|
2023-11-13 20:28:02 +01:00
|
|
|
c = chr.charCodeAt(0);
|
|
|
|
if (c > 0x40 && c <= 0x5a) {
|
|
|
|
return chr.charCodeAt(0) - 0x40 + 9;
|
|
|
|
} else if (c > 0x60 && c <= 0x7a) {
|
|
|
|
return chr.charCodeAt(0) - 0x60 + 9;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2023-11-13 22:06:21 +01:00
|
|
|
function ibanValidate(iban) {
|
2023-11-13 20:28:02 +01:00
|
|
|
iban = iban.toUpperCase();
|
|
|
|
countryId = iban.slice(0, 2);
|
|
|
|
checksum = iban.slice(2, 4);
|
|
|
|
countryDigits = countryId.split('').map(ibanLatinCharId).join('');
|
|
|
|
body = iban.substring(4);
|
|
|
|
processing = `${body}${countryDigits}${checksum}`;
|
|
|
|
resultingNumber = BigInt(processing, 10);
|
|
|
|
mod = resultingNumber % 97n;
|
|
|
|
return mod == 1;
|
2023-11-13 22:06:21 +01:00
|
|
|
|
2023-11-13 20:28:02 +01:00
|
|
|
}
|
2023-10-14 16:28:19 +02:00
|
|
|
|
2023-11-13 22:06:21 +01:00
|
|
|
function putError(s) {
|
2023-10-14 16:28:19 +02:00
|
|
|
document.querySelector('#errors').textContent += s;
|
|
|
|
}
|
2023-11-13 22:06:21 +01:00
|
|
|
function clearError() {
|
2023-10-14 16:28:19 +02:00
|
|
|
document.querySelector('#errors').textContent = "";
|
|
|
|
}
|
|
|
|
|
2023-11-13 22:06:21 +01:00
|
|
|
async function saveValueIfNotEmpty(k, v) {
|
|
|
|
if (v !== "") {
|
|
|
|
return browser.storage.sync.set({ k: v })
|
2023-11-13 20:28:02 +01:00
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2023-10-14 16:28:19 +02:00
|
|
|
async function saveOptions(ev) {
|
|
|
|
clearError();
|
|
|
|
ev.preventDefault();
|
|
|
|
let bcNum = this.querySelector("#bcnum").value;
|
2023-10-17 19:04:15 +02:00
|
|
|
if (bcNum.length !== 16 || !bcNum.startsWith("70814") || !luhnValidate(bcNum)) {
|
2023-10-14 16:28:19 +02:00
|
|
|
putError("Your BahnCard number is not valid. Please make sure you haven't made any typos.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let bDay = this.querySelector('#birthday').value;
|
2023-11-13 22:06:21 +01:00
|
|
|
if (bDay == "") {
|
2023-10-14 16:28:19 +02:00
|
|
|
putError("Please enter a birthday.");
|
|
|
|
return;
|
|
|
|
}
|
2023-10-17 18:56:19 +02:00
|
|
|
let enable = this.querySelector('#enable').checked;
|
2024-05-01 14:53:27 +02:00
|
|
|
let defaultAction = this.querySelector('#default_action').value;
|
2023-11-13 20:28:02 +01:00
|
|
|
let title = this.querySelector('#title').value;
|
2024-02-15 19:14:55 +01:00
|
|
|
let title_addl = this.querySelector('#title_addl').value;
|
2023-11-13 20:28:02 +01:00
|
|
|
let firstName = this.querySelector('#firstname').value;
|
|
|
|
let surName = this.querySelector('#surname').value;
|
|
|
|
let emailAddress = this.querySelector('#email').value;
|
|
|
|
let streetAddr = this.querySelector('#addr1').value;
|
|
|
|
let postCode = this.querySelector('#postcode').value;
|
|
|
|
let placeName = this.querySelector('#placename').value;
|
2024-04-08 14:23:59 +02:00
|
|
|
let iban = this.querySelector('#iban').value.replaceAll(" ", "");
|
2024-04-10 18:47:00 +02:00
|
|
|
let country = this.querySelector("#country").value;
|
2024-05-29 13:47:08 +02:00
|
|
|
let allowChangelogMessages = this.querySelector("#showChangelog").checked;
|
2023-11-13 22:06:21 +01:00
|
|
|
if (iban != "" && !ibanValidate(iban)) {
|
2023-11-13 20:28:02 +01:00
|
|
|
putError("Please check your IBAN for typing errors.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let bic = this.querySelector('#bic').value;
|
2023-10-13 20:48:11 +02:00
|
|
|
let options = {
|
|
|
|
bcnum: bcNum,
|
|
|
|
bday: bDay,
|
2023-11-13 20:28:02 +01:00
|
|
|
enable: enable,
|
2024-05-01 14:53:27 +02:00
|
|
|
defaultAction: defaultAction,
|
2023-11-13 20:28:02 +01:00
|
|
|
addr__appellation: title,
|
2024-02-15 19:14:55 +01:00
|
|
|
addr__title: title_addl,
|
2023-11-13 20:28:02 +01:00
|
|
|
addr__firstName: firstName,
|
|
|
|
addr__surName: surName,
|
|
|
|
addr__email: emailAddress,
|
|
|
|
addr__street: streetAddr,
|
|
|
|
addr__postcode: postCode,
|
|
|
|
addr__placename: placeName,
|
2024-04-10 18:47:00 +02:00
|
|
|
addr__country: country,
|
2023-11-13 20:28:02 +01:00
|
|
|
pymt__iban: iban,
|
2024-05-29 13:47:08 +02:00
|
|
|
pymt__bic: bic,
|
|
|
|
showChangelog: allowChangelogMessages,
|
2023-10-13 20:48:11 +02:00
|
|
|
};
|
2024-05-29 13:53:03 +02:00
|
|
|
// list of options that may be explicitly empty
|
|
|
|
const EMPTYABLE_OPTIONS = ["defaultAction"];
|
|
|
|
options = Object.fromEntries(Object.entries(options).filter(([k, v]) => v !== "" || EMPTYABLE_OPTIONS.includes(k)))
|
2024-05-07 17:46:34 +02:00
|
|
|
console.info("saving", options);
|
2023-11-13 20:28:02 +01:00
|
|
|
|
2023-10-14 16:28:19 +02:00
|
|
|
browser.storage.sync.set(options).then(() => {
|
|
|
|
document.querySelector('#success').textContent = "✔";
|
|
|
|
setTimeout(() => {
|
|
|
|
document.querySelector('#success').textContent = '';
|
|
|
|
}, 5000);
|
|
|
|
})
|
2023-11-13 20:28:02 +01:00
|
|
|
|
2023-10-13 20:48:11 +02:00
|
|
|
}
|
|
|
|
|
2024-05-29 13:47:08 +02:00
|
|
|
function boolDefaultTrue(dict, key){
|
|
|
|
if (key in dict){
|
|
|
|
return dict[key];
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-10-13 20:48:11 +02:00
|
|
|
async function restoreOptions() {
|
|
|
|
// We do not save user data in managed storage.
|
|
|
|
// let res = await browser.storage.managed.get('colour');
|
|
|
|
// document.querySelector("#managed-colour").innerText = res.colour;
|
|
|
|
|
2023-10-14 16:28:19 +02:00
|
|
|
let settings = await browser.storage.sync.get();
|
2024-05-07 17:46:34 +02:00
|
|
|
console.info("restoring", settings);
|
2024-05-29 13:47:08 +02:00
|
|
|
|
|
|
|
document.querySelector('#enable').checked = boolDefaultTrue(settings, "enable");
|
2023-10-13 20:48:11 +02:00
|
|
|
document.querySelector("#bcnum").value = settings.bcnum || "";
|
|
|
|
document.querySelector("#birthday").value = settings.bday || "";
|
2024-05-01 14:53:27 +02:00
|
|
|
document.querySelector("#default_action").value = settings.defaultAction || "";
|
2023-11-13 22:42:42 +01:00
|
|
|
document.querySelector('#title').value = settings.addr__appellation || "";
|
2024-02-15 19:14:55 +01:00
|
|
|
document.querySelector('#title_addl').value = settings.addr__title || "";
|
2023-11-13 22:42:42 +01:00
|
|
|
document.querySelector('#firstname').value = settings.addr__firstName || "";
|
|
|
|
document.querySelector('#surname').value = settings.addr__surName || "";
|
|
|
|
document.querySelector('#email').value = settings.addr__email || "";
|
|
|
|
document.querySelector('#addr1').value = settings.addr__street || "";
|
|
|
|
document.querySelector('#postcode').value = settings.addr__postcode || "";
|
|
|
|
document.querySelector('#placename').value = settings.addr__placename || "";
|
2024-04-10 18:47:00 +02:00
|
|
|
document.querySelector('#country').value = settings.addr__country || "";
|
2023-11-13 22:42:42 +01:00
|
|
|
document.querySelector('#iban').value = settings.pymt__iban || "";
|
|
|
|
document.querySelector('#bic').value = settings.pymt__bic || "";
|
2024-05-29 13:47:08 +02:00
|
|
|
document.querySelector('#showChangelog').checked = boolDefaultTrue(settings, "showChangelog");
|
2023-10-13 20:48:11 +02:00
|
|
|
}
|
|
|
|
|
2023-11-13 22:42:42 +01:00
|
|
|
let bahncardWindow;
|
|
|
|
|
2023-10-17 19:04:15 +02:00
|
|
|
function startBcnumAcquisition(ev) {
|
2023-11-13 22:42:42 +01:00
|
|
|
browser.storage.sync.set({ "acquireBahncard": true }).then(() => {
|
|
|
|
browser.storage.sync.onChanged.addListener(changes => {
|
2024-05-07 17:46:34 +02:00
|
|
|
console.debug(changes);
|
2023-11-13 22:42:42 +01:00
|
|
|
for (const [key, changeSet] of Object.entries(changes)) {
|
|
|
|
if (key === "bcnum") {
|
|
|
|
browser.storage.sync.onChanged.removeListener(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
bahncardWindow = window.open("https://www.bahn.de/buchung/kundenkonto/bahncard", "_blank", "popup")
|
|
|
|
if (bahncardWindow instanceof Window) {
|
|
|
|
bahncardWindow.postMessage("__WINDOW_OPENED_FOR_BC_ACQUISITION__");
|
2023-10-17 19:04:15 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2024-02-15 19:14:55 +01:00
|
|
|
function startAllAcquisition(ev) {
|
2024-05-29 13:53:23 +02:00
|
|
|
browser.storage.sync.set({ "acquireAll": true }).then(() => {
|
2024-02-15 19:14:55 +01:00
|
|
|
browser.storage.sync.onChanged.addListener(changes => {
|
2024-05-07 17:46:34 +02:00
|
|
|
console.debug(changes);
|
2024-05-29 13:53:23 +02:00
|
|
|
if ("acquireAll" in changes) {
|
|
|
|
document.location.reload();
|
2024-02-15 19:14:55 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
bahncardWindow = window.open("https://www.bahn.de/buchung/kundenkonto/bahncard", "_blank", "popup")
|
|
|
|
if (bahncardWindow instanceof Window) {
|
|
|
|
bahncardWindow.postMessage("__WINDOW_OPENED_FOR_BC_ACQUISITION__");
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2023-10-17 19:04:15 +02:00
|
|
|
|
2023-10-13 20:48:11 +02:00
|
|
|
document.addEventListener('DOMContentLoaded', restoreOptions);
|
2023-10-17 19:04:15 +02:00
|
|
|
document.querySelector("form").addEventListener("submit", saveOptions);
|
2024-02-15 19:14:55 +01:00
|
|
|
document.querySelector("#bcnum-get-from-profile").addEventListener("click", startBcnumAcquisition)
|
|
|
|
document.querySelector("#all-get-from-profile").addEventListener("click", startAllAcquisition)
|