Skip to content

Commit a4921e8

Browse files
committed
1.2.2
1 parent 2755655 commit a4921e8

File tree

8 files changed

+199
-47
lines changed

8 files changed

+199
-47
lines changed

background.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ function appendReferer(e) {
1212
let appendReferer_extraInfoSpec = ["blocking", "requestHeaders"];
1313
if (chrome.webRequest.OnBeforeSendHeadersOptions.hasOwnProperty('EXTRA_HEADERS')) appendReferer_extraInfoSpec.push('extraHeaders'); // Chrome needs this apparently...
1414
browser.webRequest.onBeforeSendHeaders.addListener(appendReferer,
15-
{urls: ["https://portal.librus.pl/rodzina/synergia/loguj", "https://portal.librus.pl/szkola/synergia/loguj"]},
15+
{urls: [
16+
"https://portal.librus.pl/rodzina/synergia/loguj", "https://portal.librus.pl/szkola/synergia/loguj",
17+
"https://portal.librus.pl/rodzina/synergia/loguj#*", "https://portal.librus.pl/szkola/synergia/loguj#*"
18+
]},
1619
appendReferer_extraInfoSpec
1720
);
1821

@@ -27,7 +30,22 @@ browser.webRequest.onBeforeRequest.addListener(e => {
2730

2831
// this login link would redirect user to the main page, so catch it and redirect directly to the actual login page instead
2932
browser.webRequest.onBeforeRequest.addListener(e => {
30-
return {redirectUrl: 'https://portal.librus.pl/rodzina/synergia/loguj'};
33+
let appendee = '';
34+
let moveToUri = '';
35+
if (e.url === 'https://synergia.librus.pl/loguj' && e.originUrl && e.originUrl.startsWith('https://synergia.librus.pl/')) {
36+
// this will only work in Firefox
37+
moveToUri = e.originUrl.replace('https://synergia.librus.pl', '');
38+
}
39+
else if (e.url && e.url.startsWith('https://synergia.librus.pl/loguj/przenies/')) {
40+
moveToUri = e.url.replace('https://synergia.librus.pl/loguj/przenies', '');
41+
}
42+
moveToUri = moveToUri.replace(/\\\//g, '/');
43+
if (moveToUri
44+
&& moveToUri !== '/rodzic/index' && moveToUri !== '/uczen/index' // we don't care about main page redirect, especially that mixing up "rodzic" and "uczen" would log us out again
45+
&& moveToUri !== '/loguj' && !moveToUri.startsWith('/loguj')
46+
)
47+
appendee = '#' + moveToUri;
48+
return {redirectUrl: 'https://portal.librus.pl/rodzina/synergia/loguj' + appendee};
3149
},
3250
{urls: ["https://synergia.librus.pl/loguj", "https://synergia.librus.pl/loguj/przenies*"]},
3351
["blocking"]

browser-polyfill.min.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

browser-polyfill.min.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contentscript.js

Lines changed: 154 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
const isChrome = typeof browser === "undefined" || Object.getPrototypeOf(browser) !== Object.prototype;
44
const isFirefox = !isChrome && !!browser;
5-
const debug = false;
5+
const debug = true;
66
let url = document.location.toString().split('#')[0].split('?')[0];
77
let didInjectCssAlready = false;
88

@@ -25,6 +25,7 @@ if (document.readyState === 'complete') onDocumentReady();
2525

2626
setTimeout(() => modifyStuff(), 500); // just to make sure and catch the late loaded stuff
2727
setTimeout(() => modifyStuff(), 1500); // apparently the one above was not enough...
28+
setTimeout(() => modifyStuff(), 2500); // apparently the one above was not enough...
2829

2930
// run on document ready once
3031
function onDocumentReady() {}
@@ -60,6 +61,25 @@ function modifyStuff() {
6061
if (url === 'https://portal.librus.pl/rodzina/synergia/loguj' || url === 'https://portal.librus.pl/szkola/synergia/loguj') {
6162
$("#synergiaLogin").next().remove(); // some ad
6263
$('section#app-download').remove(); // mobile app ad (only on mobile screens)
64+
65+
// they send: window.parent.postMessage({"command":"open_synergia_window","commandPayload":{"url":"https:\/\/synergia.librus.pl\/uczen\/index"}}, 'https://portal.librus.pl/rodzina');
66+
let redirectUrl = window.location.hash && window.location.hash.substr(1);
67+
if (redirectUrl && !window.didSetUpOpenSynergiaWindowListenerAlready) {
68+
console.log("[Librus Enhancer] Setting up window message event listener to change redirect destination after login (as hash url is provided)");
69+
window.addEventListener("message", (event) => {
70+
if (debug) console.log("[Librus Enhancer] message event", event);
71+
if (event.data && event.data.command && event.data.command === 'open_synergia_window') {
72+
console.log("[Librus Enhancer] intercepted open_synergia_window");
73+
event.stopImmediatePropagation();
74+
event.stopPropagation();
75+
//let url = event.data && event.data.commandPayload && event.data.commandPayload.url;
76+
let url = window.location.hash && window.location.hash.substr(1);
77+
if (!url) url = '/uczen/index';
78+
document.location.assign('https://synergia.librus.pl/' + url.replace(/^\/+/, ''));
79+
}
80+
}, true);
81+
window.didSetUpOpenSynergiaWindowListenerAlready = true;
82+
}
6383
}
6484

6585
if (url === 'https://portal.librus.pl/rodzina' || url === 'https://portal.librus.pl/rodzina/login' || url === 'https://portal.librus.pl/szkola') {
@@ -128,61 +148,163 @@ function modifyStuff() {
128148
const PAGE_REFRESH_INTERVAL = 3 * 60 * 1000;
129149
if (url.startsWith('https://synergia.librus.pl/')) {
130150

131-
let isLoggedIn = !!$('#user-section').length;
151+
let isLoggedIn = !!$('#user-section').length; // we are catching only full pages, not popups
132152
let div = $('#page .container .inside');
133153
let isLoggedOut = div && !!div.length && div.text() === 'Brak dostępu';
134154

135155
if (isLoggedIn && !isLoggedOut) {
136-
let regex = /jesteś zalogowany jako\:.*(uczeń|rodzic).*/gsi.exec($('#user-section').text());
137-
let isParent = regex && regex[1] && regex[1] === 'rodzic';
156+
let regex = /(jesteś zalogowan[ya\-\(\)\/]+ jako\:).*(uczeń|rodzic).*/gsi.exec($('#user-section').text());
157+
158+
let isPupil = regex && regex[1] && regex[2] && regex[2] === 'uczeń';
159+
let isParent = regex && regex[1] && regex[2] && regex[2] === 'rodzic';
160+
let isTeacher = regex && regex[1] && !isPupil && !isParent;
161+
162+
// fallback detections
163+
//if (!isPupil && (!!$("a[href='/przegladaj_oceny/uczen']").length || !!$("a[href='/przegladaj_nb/uczen']").length)) isPupil = true;
164+
//if (!isParent && (!!$("a[href='/przegladaj_oceny/rodzic']").length || !!$("a[href='/przegladaj_nb/rodzic']").length)) isParent = true; // both pupil and parent turn out to have "uczen" in these links!!!
165+
if (!isTeacher && !!$("a[href='/interfejs_lekcyjny']").length) isTeacher = true;
166+
167+
let accountType = -1;
168+
let accountTypeStr = "unknown";
169+
switch (true) {
170+
case isPupil && !isParent && !isTeacher: accountType = ACCOUNT_TYPE_PUPIL; accountTypeStr = "pupil"; break;
171+
case isParent && !isPupil && !isTeacher: accountType = ACCOUNT_TYPE_PARENT; accountTypeStr = "parent"; break;
172+
case isTeacher && !isPupil && !isParent: accountType = ACCOUNT_TYPE_TEACHER; accountTypeStr = "teacher"; break;
173+
}
138174

139-
console.log("[Librus Enhancer] Detected that you are logged in!" + (isParent ? " (as parent)":""));
175+
console.log("[Librus Enhancer] Detected that you are logged in! (as "+accountTypeStr+")");
176+
177+
$("a[href='/wyloguj']").on('click', () => storage.set({
178+
//['lastLogin'+(isTeacher?'School':'')]: null,
179+
lastLogin: null,
180+
lastLoginSchool: null,
181+
pupilNumber: -1
182+
}));
183+
revealLiblinks();
184+
185+
if (!regex || !regex[1] || accountType == -1)
186+
console.warn("[Librus Enhancer] Could not detect account type!");
140187

141188
// the difference between these two is documented above these functions' definitions
142189
if (isFirefox) {
143-
setInterval(() => firefox_refreshPageInBackground(isParent), PAGE_REFRESH_INTERVAL);
144-
//setTimeout(() => firefox_refreshPageInBackground(isParent), 3000); // testing
190+
setInterval(() => firefox_refreshPageInBackground(accountType), PAGE_REFRESH_INTERVAL);
191+
//setTimeout(() => firefox_refreshPageInBackground(accountType), 3000); // testing
145192
} else {
146-
chrome_refreshPageInBackground_setupIntervalInPageContext(isParent);
193+
chrome_refreshPageInBackground_setupIntervalInPageContext(accountType);
147194
}
148195

149-
$("a[href='/wyloguj']").on('click', () => storage.set({lastLogin: null}));
150-
revealLiblinks();
196+
if (accountType == ACCOUNT_TYPE_PUPIL || accountType == ACCOUNT_TYPE_PARENT)
197+
grabPupilNumber();
151198

152-
} else {
153-
console.log("[Librus Enhancer] Detected that you are logged out!");
154-
if (isLoggedOut) {
155-
// make the login button move us to the login page, and not main page
156-
let button = $("input[value='Loguj']");
157-
if (button && !!button.length) {
158-
button.attr('onclick', '');
159-
button.on('click', ev => {
160-
ev.preventDefault();
161-
ev.stopImmediatePropagation();
162-
// below doesn't support the school version currently, as I have no account to test it with; I assume most users will be family users anyways
163-
window.location.replace('https://portal.librus.pl/rodzina/synergia/loguj'); // take us to the login page directly...
164-
});
165-
}
199+
} else if (isLoggedOut) {
200+
console.log("[Librus Enhancer] Detected that you were logged out!");
201+
let isFamily = (document.body.innerHTML+'').includes('https:\\/\\/synergia.librus.pl\\/loguj\\/przenies\\/rodzic\\/index');
202+
if (isFamily) {
203+
let pathname = window.location.pathname;
204+
if (pathname !== 'https://synergia.librus.pl/rodzic/index' && pathname !== 'https://synergia.librus.pl/uczen/index')
205+
window.location.replace('https://portal.librus.pl/rodzina/synergia/loguj#' + pathname);
206+
}
207+
208+
// make the login button move us to the login page, and not main page
209+
let button = $("input[value='Loguj']");
210+
if (button && !!button.length) {
211+
button.attr('onclick', '');
212+
button.on('click', ev => {
213+
ev.preventDefault();
214+
ev.stopImmediatePropagation();
215+
window.location.replace(`https://portal.librus.pl/${isFamily?'rodzina':'szkola'}/synergia/loguj`); // take us to the login page directly...
216+
});
166217
}
218+
} else {
219+
console.log("[Librus Enhancer] Detected that you are neither logged in or out (popup or another page)");
167220
}
168221

169222
}
170223

224+
async function grabPupilNumber() {
225+
let data = await storage.get(['pupilNumber']);
226+
let pupilNumber = +data.pupilNumber;
227+
if (!pupilNumber || pupilNumber == -1) {
228+
229+
if (debug) console.log('[Librus Enhancer] Pupil number was not in storage, gonna fetch it.');
230+
// fetch it
231+
let url = 'https://synergia.librus.pl/informacja';
232+
let regex = /<th class="big">Nr w dzienniku\s*<\/th>\s*<td>\s*([0-9]+)\s*<\/td>/gs;
233+
234+
let code = `${debug ? "console.log('[Librus Enhancer] Fetching number in page context...');":""}
235+
fetch('${url}', {
236+
cache: 'no-cache',
237+
credentials: 'include'
238+
}).then(response => response.text()).then(text => {
239+
let regex = /<th class="big">Nr w dzienniku\\s*<\\/th>\\s*<td>\\s*([0-9]+)\\s*<\\/td>/gs;
240+
let data = regex.exec(text);
241+
let number = data && data[1] && +data[1];
242+
if (!number) return console.warn('[Librus Enhancer] Failed to fetch pupil number!', data);
243+
${debug ? "console.log('[Librus Enhancer] Fetched number in page context:', number);":""}
244+
const event = new CustomEvent('PupilNumberEvent', {detail: {number}});
245+
window.dispatchEvent(event);
246+
});`;
247+
248+
window.addEventListener('PupilNumberEvent', e => {
249+
let number = +(e.detail && e.detail.number);
250+
if (!number) return console.warn('[Librus Enhancer] Received invalid pupil number in event listener!', e);
251+
storage.set({pupilNumber: number});
252+
processPupilNumber(number);
253+
});
254+
255+
if (isFirefox) {
256+
window.eval(code);
257+
} else {
258+
let script = document.createElement('script');
259+
script.type = 'text/javascript';
260+
script.async = true;
261+
script.innerHTML = code;
262+
document.head.appendChild(script);
263+
}
264+
265+
} else processPupilNumber(pupilNumber);
266+
}
267+
268+
function processPupilNumber(number) {
269+
console.log("[Librus Enhancer] Determined your number:", number);
270+
let currentLuckyNumber = +($('.luckyNumber').text()+'').trim();
271+
if (currentLuckyNumber === number) {
272+
console.log("[Librus Enhancer] Your number is lucky today!");
273+
$('.luckyNumber').css('border', '15px solid red'); // dashed
274+
$('.luckyNumber').css('font-size', '20px');
275+
$('.luckyNumber').css('background-color', 'lime');
276+
}
277+
}
278+
279+
function getLinkToFetchForBackgroundSessionRefresh(accountType) {
280+
let linkToFetch;
281+
switch (accountType) {
282+
case ACCOUNT_TYPE_PUPIL: linkToFetch = 'https://synergia.librus.pl/uczen/index'; break;
283+
case ACCOUNT_TYPE_PARENT: linkToFetch = 'https://synergia.librus.pl/rodzic/index'; break;
284+
case ACCOUNT_TYPE_TEACHER: linkToFetch = 'https://synergia.librus.pl/interfejs_lekcyjny'; break;
285+
default: linkToFetch = 'https://synergia.librus.pl/ustawienia'; break;
286+
}
287+
return linkToFetch;
288+
}
289+
171290
// the difference between below functions:
172291
// firefox one sets interval in content script (in code block above), and uses window.eval to then execute the request in page context
173292
// chrome one sets both the interval and request in page context (with script tag workaround, as window.eval is not available there)
174293

175294
// prevent session expiration, so we don't get logged out...
176-
function firefox_refreshPageInBackground(isParent) { // this function only gets executed in Firefox
295+
function firefox_refreshPageInBackground(accountType) { // this function only gets executed in Firefox
177296
console.log("[Librus Enhancer] Running firefox_refreshPageInBackground in page context...");
297+
298+
let linkToFetch = getLinkToFetchForBackgroundSessionRefresh(accountType);
299+
178300
/*fetch('https://synergia.librus.pl/uczen/index', { // content.fetch crashes tab lol
179301
//mode: 'same-origin',
180302
cache: 'no-cache',
181303
credentials: 'include'
182304
}).then(response => console.log("[Librus Enhancer] Refreshed page in background to preserve the session (response status: " + response.status + ", length: " + response.headers.get("content-length") + ")"));
183305
*/
184306

185-
let code = `fetch('https://synergia.librus.pl/${isParent?'rodzic':'uczen'}/index', {
307+
let code = `fetch('${linkToFetch}', {
186308
cache: 'no-cache',
187309
credentials: 'include'
188310
}).then(response => console.log("[Librus Enhancer] Refreshed page in background to preserve the session (response status: " + response.status + ", length: " + response.headers.get("content-length") + ")"));`;
@@ -193,8 +315,11 @@ function firefox_refreshPageInBackground(isParent) { // this function only gets
193315

194316
// workaround for chrome
195317
// the modern-age Internet Explorer
196-
function chrome_refreshPageInBackground_setupIntervalInPageContext(isParent) { // this function only gets executed in Chrome, and not in Firefox
197-
let fetchcode = `fetch('https://synergia.librus.pl/${isParent?'rodzic':'uczen'}/index', {
318+
function chrome_refreshPageInBackground_setupIntervalInPageContext(accountType) { // this function only gets executed in Chrome, and not in Firefox
319+
320+
let linkToFetch = getLinkToFetchForBackgroundSessionRefresh(accountType);
321+
322+
let fetchcode = `fetch('${linkToFetch}', {
198323
cache: 'no-cache',
199324
credentials: 'include'
200325
}).then(response => console.log("[Librus Enhancer] Refreshed page in background to preserve the session (response status: " + response.status + ", length: " + response.headers.get("content-length") + ")"));`;
@@ -371,4 +496,4 @@ if (url === 'https://portal.librus.pl//vendor/widget-librus/index.html' || url =
371496

372497
const observer = new MutationObserver(callback);
373498
observer.observe(document.body, {childList: true, subtree: true});
374-
}
499+
}

contentscript_common.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
const ACCOUNT_TYPE_PUPIL = 0;
2+
const ACCOUNT_TYPE_PARENT = 1;
3+
const ACCOUNT_TYPE_TEACHER = 2;
4+
15
//#region ENCRYPTION
26

37
// better to encrypt with a statically embedded key than to store in storage in plaintext
@@ -46,5 +50,5 @@ async function decryptPassword(passEncrypted) {
4650
//#endregion ENCRYPTION
4751

4852
/** @type {browser.storage.StorageArea} */
49-
//let storage = browser.storage.sync; // production?
50-
let storage = browser.storage.local; // development
53+
//let storage = browser.storage.sync;
54+
let storage = browser.storage.local;

contentscript_login_iframe.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ let loadingSavedLoginsPromise = (async () => {
3232
3333
$("#Login").val(savedLogin.login);
3434
$("#Pass").val(await decryptPassword(savedLogin.passEncrypted));
35-
$("#LoginBtn").click();
35+
$("#LoginBtn").trigger('click');
3636
}
3737
})();*/
3838

@@ -49,15 +49,15 @@ function insertSavedLoginsButtons() {
4949

5050
let loginPart = $('<div class="loginPart">');
5151
loginPart.text(savedLogin.login);
52-
loginPart.click(async () => {
52+
loginPart.on('click', async () => {
5353
$("#Login").val(savedLogin.login);
5454
$("#Pass").val(await decryptPassword(savedLogin.passEncrypted));
55-
$("#LoginBtn").click();
55+
$("#LoginBtn").trigger('click');
5656
});
5757

5858
let deletePart = $('<div class="deletePart">');
5959
deletePart.text('×');
60-
deletePart.click(async () => {
60+
deletePart.on('click', async () => {
6161
savedLogins = savedLogins.filter(sl => sl !== savedLogin);
6262
await storage.set({savedLogins});
6363
insertSavedLoginsButtons();
@@ -71,7 +71,7 @@ function insertSavedLoginsButtons() {
7171
$('.LoginBox').prepend(container);
7272
}
7373

74-
$("#LoginBtn").click(async (ev) => {
74+
$("#LoginBtn").on('click', async (ev) => {
7575
let remember = $("input#remember").is(':checked'); // credentials will only be saved in storage if user has explicitly pressed the checkbox to "remember for quick login"
7676

7777
let login = $("#Login").val();
@@ -86,7 +86,7 @@ $("#LoginBtn").click(async (ev) => {
8686
await loadingSavedLoginsPromise;
8787

8888
// remove users that match login, but don't match the password, if user is updating one right now
89-
savedLogins = savedLogins.filter(savedLogin => savedLogin.login === login && savedLogin.passEncrypted !== passEncrypted);
89+
savedLogins = savedLogins.filter(savedLogin => !(savedLogin.login === login && savedLogin.passEncrypted !== passEncrypted));
9090

9191
// if the entry doesn't exist on our list
9292
if (!savedLogins.some(savedLogin => savedLogin.login === login && savedLogin.passEncrypted === passEncrypted)) {
@@ -96,11 +96,14 @@ $("#LoginBtn").click(async (ev) => {
9696
}
9797

9898
// if the user is saved, we will save their name for auto re-login, in case their session expired despite having this addon (interval was throttled or user had disconnected from the internet)
99+
// currently not implemented
99100
// that feature will not affect manual sign-out
100101
if (login && pass && savedLogins.some(savedLogin => savedLogin.login === login && savedLogin.passEncrypted === passEncrypted)) {
101-
storage.set({lastLogin: login});
102+
storage.set({['lastLogin'+(isSchool?'School':'')]: login});
102103
}
104+
103105
});
104106

105107
$("input#remember").parent().remove(); // if we're hot-reloading the script
106-
$("#passwordRow").append(rememberLoginCode);
108+
$("#passwordRow").append(rememberLoginCode);
109+
storage.set({'pupilNumber': -1});

login_iframe.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
border-color: #975b83;
1010

1111
box-sizing: border-box;
12-
padding: 0;
12+
padding: 0 !important;
1313
margin-top: .3em;
14+
margin-right: .3em;
1415
}
1516

1617
.btn-savedlogin > div:hover {

0 commit comments

Comments
 (0)