Skip to content

Commit

Permalink
Merge branch 'dev' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
The-breakbar committed Oct 24, 2023
2 parents d8e336f + 9a0be7c commit 168c81b
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 21 deletions.
25 changes: 21 additions & 4 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,25 @@ Hopefully this was an interesting read, even if you're not planning to implement

# API Docs

> [!IMPORTANT]
> This documentation has been updated and is valid as of October 7th, 2023. Any future changes will be updated as soon as possible. See the [API Changelog](#api-changelog) for a detailed list of changes.
> [!NOTE]
> While this documentation tries to be as complete as possible, certain things have not been thoroughly tested and are unknown. It is sufficient for this extension, however that might not be the case for every use case. If you find any mistakes or have additional information, please open an issue or a pull request.
## Table of contents

- [General notes](#general-notes)
- [LVA endpoint](#lva-endpoint---educationcoursecourseregistrationxhtml-post)
- [Group endpoint](#group-endpoint---educationcoursegrouplistxhtml-post)
- [Exam endpoint](#exam-endpoint---educationcourseexamdatelistxhtml-post)
- [Confirm endpoint](#confirm-endpoint---educationcourseregisterxhtml-post)
- [Example curl commands](#example-curl-commands)
- [API Changelog](#api-changelog)

## General notes

- First either the LVA, group or exam endpoint has to be called, depending on what you want to register for. After that, the response has to be used to call the confirm endpoint, which is the same for all 3.
- Either the LVA, group or exam endpoint has to be called first, depending on what you want to register for. After that, the response has to be used to call the confirm endpoint, which is the same for all three.
- All requests need the following 3 cookies: `_tiss_session`, `TISS_AUTH`, `JSESSIONID`. These are present after logging in to TISS and should be passed along with every request.
- To mimic the site, POST requests should have the `Content-Type` header set to `application/x-www-form-urlencoded` (and the body should be encoded as such).
- An error is generally indicated by a 302, or a redirect. Make sure you detect and don't follow any redirects, as they will lead to an error page or redirect back to the original page, making it seem like nothing happened.
Expand All @@ -212,7 +225,7 @@ The request body needs to contain the following key-value pairs:

| Key name | Value | Notes |
| -------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `registrationForm:j_id_6t` | `"Register"` | Key name is the HTML id of the register button<br />Value is the text of the button<br />`"Anmelden"` is also valid as the value |
| `registrationForm:j_id_6z` | `"Register"` | Key name is the HTML id of the register button<br />Value is the text of the button<br />`"Anmelden"` is also valid as the value |
| `registrationForm_SUBMIT` | `1` |
| `dspwid` | A window id | The id is found in the url as the "dswid" parameter |
| `javax.faces.ClientWindow` | Same value as `dspwid` |
Expand Down Expand Up @@ -270,15 +283,15 @@ These are some example curl commands that show how to perform the requests. Make
- Window id (`dspwid`, `javax.faces.ClientWindow`)
- Group/Exam option id (`groupContentForm:<id>:j_id_a1` / `examDateListForm:<id>:j_id_9u`)

Also note that the [--data-urlencode](https://everything.curl.dev/http/post/url-encode) flag is used (for the `application/x-www-form-urlencoded` content type), however that requires the key of the key-value pairs to be already encoded. For example, the key `registrationForm:j_id_6t` is encoded as `registrationForm%3Aj_id_6t`.
Also note that the [--data-urlencode](https://everything.curl.dev/http/post/url-encode) flag is used (for the `application/x-www-form-urlencoded` content type), however that requires the key of the key-value pairs to be already encoded. For example, the key `registrationForm:j_id_6z` is encoded as `registrationForm%3Aj_id_6z`.

### LVA endpoint

```bash
curl --location 'https://tiss.tuwien.ac.at/education/course/courseRegistration.xhtml' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cookie: JSESSIONID=d7~CC38E402394034D90A28E8D77D9E0022; TISS_AUTH=fe21d3192f3bc581ce4ed9c9ghd6cd5f80707441837c4dc15b9481368fb5d0c8; _tiss_session=50d4bfd6423157d995a18e7ef6150772' \
--data-urlencode 'registrationForm%3Aj_id_6t=Register' \
--data-urlencode 'registrationForm%3Aj_id_6z=Register' \
--data-urlencode 'registrationForm_SUBMIT=1' \
--data-urlencode 'dspwid=8359' \
--data-urlencode 'javax.faces.ClientWindow=8359' \
Expand Down Expand Up @@ -323,3 +336,7 @@ curl --location 'https://tiss.tuwien.ac.at/education/course/register.xhtml' \
--data-urlencode 'javax.faces.ClientWindow=8358' \
--data-urlencode 'javax.faces.ViewState=RUVBN0FTEUZEMUI3QjQzNTAwMDAwMDQw'
```

## API Changelog

- 2023-10-07: LVA button id changed from `registrationForm:j_id_6t` to `registrationForm:j_id_6z`
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# TISS Lightning Registrator

![Screenshot of the extension being shown in two different browsers](images/Screenshots.png)
![Screenshot of the extension being shown in three different browsers](images/Screenshots.png)

TISS Lightning Registrator is a browser extension that automatically registers you for an LVA, group or exam in TISS as soon as it opens. Start the extension a few minutes in advance, and once the registration begins, experience lightning-fast registration that's often completed in less than a second.

The extension streamlines registrations, working quietly in the background. You can multitask and browse other tabs while it handles the registration process efficiently. As registrations don't open regularly, to try the extension out, it can also be used to register for an LVA, group or exam which has already opened.
Introducing TISS Lightning Registrator, a handy browser extension that takes the hassle out of TISS registrations by automatically signing you up for LVAs, groups, or exams as soon as they open. Start the extension before a registration begins, and once it does, experience lightning-fast registration that is often completed in less than a second. Additionally this streamlined process works quietly in the background, allowing you to multitask and browse other tabs, while the extension handles the registration process efficiently.

## Installing

Expand Down
2 changes: 1 addition & 1 deletion content-scripts/infoMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ chrome.storage.onChanged.addListener((changes, area) => {
} else if (task.status == "success") {
message.textContent = `Refresh the page to see`;
} else if (task.status == "failure") {
message.textContent = `${task.error.charAt(0).toUpperCase()}${task.error.slice(1)}`;
message.textContent = task.error;
} else if (task.status == "running") {
message.textContent = `Sending registration`;
}
Expand Down
8 changes: 4 additions & 4 deletions content-scripts/resultHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ let handleResult = async (message) => {
status: "failure",
expiry: Date.now() + TASK_EXPIRY,
time,
error: `registration attempted ${attempts} times`
error: `Registration attempted ${attempts} times`
};
updateTask(tabId, update);

Expand All @@ -47,13 +47,13 @@ let handleResult = async (message) => {
// At this point we still assume that the registration was not successful, as we have to check the response message
let success = false;
let preregistration = false;
let errorMessage = "unable to register for this option";
let errorMessage = "Unable to register for this option";
let responseDocument = new DOMParser().parseFromString(response, "text/html");
let responseInfoText = responseDocument.querySelector("#confirmForm .staticInfoMessage").innerText;

// Check if the registration wasn't fast enough and ended up on the waiting list
if (/(warteliste|waiting list)/i.test(responseInfoText)) {
errorMessage = "on waiting list";
errorMessage = "On waiting list";
}

// Check if the response message contains the success message
Expand Down Expand Up @@ -99,7 +99,7 @@ let handleRefreshTimeout = async (tabId) => {
let update = {
status: "failure",
expiry: Date.now() + TASK_EXPIRY,
error: "registration did not open"
error: "Registration did not open"
};

updateTask(tabId, update);
Expand Down
4 changes: 2 additions & 2 deletions content-scripts/sendRegistration.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ let refreshLoop = async (optionId, slot) => {
let options = pageDocument.querySelectorAll("#contentInner .groupWrapper");

let button;
if (pageType == "lva") button = options[0].querySelector("#registrationForm\\:j_id_6t");
if (pageType == "lva") button = options[0].querySelector("#registrationForm\\:j_id_6z");
else button = Array.from(options).find((option) => option.querySelector(`input[id*="${optionId}"]`));

// If the button was found, extract the ViewState
Expand Down Expand Up @@ -219,7 +219,7 @@ const CONFIRM_DATA = {
regForm_SUBMIT: "1"
};
const LVA_DATA = {
"registrationForm:j_id_6t": "Register",
"registrationForm:j_id_6z": "Register",
registrationForm_SUBMIT: "1"
};
// The group and exam data needs the id of the option to be inserted
Expand Down
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ initTaskRemovalTimeouts();
chrome.tabs.query({ active: true, currentWindow: true }, async (tabs) => {
tabId = tabs[0].id;
let tabUrl = tabs[0].url;
if (!/https:\/\/.*tiss.tuwien.ac.at\/education\/course\/(courseRegistration|groupList|examDateList)/.test(tabUrl)) return;
if (!/https:\/\/tiss.tuwien.ac.at\/education\/course\/(courseRegistration|groupList|examDateList)/.test(tabUrl)) return;

// Determine type of registration
if (/courseRegistration/.test(tabUrl)) pageType = "lva";
Expand Down
8 changes: 4 additions & 4 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"name": "TISS Lightning Registrator",
"description": "Automatically register in TISS",
"version": "1.0.0",
"version": "1.1.0",
"manifest_version": 3,
"action": {
"default_popup": "./popup.html"
},
"content_scripts": [
{
"matches": [
"https://*.tiss.tuwien.ac.at/education/course/courseRegistration*",
"https://*.tiss.tuwien.ac.at/education/course/groupList*",
"https://*.tiss.tuwien.ac.at/education/course/examDateList*"
"https://tiss.tuwien.ac.at/education/course/courseRegistration*",
"https://tiss.tuwien.ac.at/education/course/groupList*",
"https://tiss.tuwien.ac.at/education/course/examDateList*"
],
"js": [
"./content-scripts/getPageInfo.js",
Expand Down
2 changes: 1 addition & 1 deletion popup-scripts/registerButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ registerButton.addEventListener("click", async () => {
// This is not a perfect solution, if the request fails, then the time is not checked
// However this should only happen very rarely, as most system clocks don't deviate that much
let timeOverride;
const timeResponse = await fetch("http://worldtimeapi.org/api/timezone/Europe/Vienna");
const timeResponse = await fetch("https://worldtimeapi.org/api/timezone/Europe/Vienna");
if (timeResponse.ok) {
// If response is fine, extract the timestamp
const data = await timeResponse.json();
Expand Down
1 change: 1 addition & 0 deletions styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ section[name="tasks"] .failure h3 {

/* Task header infotext */
.task h3 span {
margin-left: 3px;
font-size: 10px;
font-weight: normal;
}
Expand Down

0 comments on commit 168c81b

Please sign in to comment.