Skip to content

Commit 537b4d4

Browse files
committed
Implement error handling during Profile Removal
Caught errors that occur when extension fails to contact server when "Remove Profile" Pressed. Updated placeholders for input boxes in `options.html` Updated manifest version. Preparing release of patch. Added **commented** code to verify the main server's identity through magic packet verification (using checksum SHA-256).
1 parent b7a48db commit 537b4d4

5 files changed

Lines changed: 60 additions & 11 deletions

File tree

README.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Project Ignite is a new Device Manager Application (DMA) for schools developed a
33
<br>
44
Project Ignite focuses on ensuring the **Security** and **Privacy** of students as well as being as **Fail-Proof** as possible. The chrome extension for students is **designed to work even if the server goes offline** after it has been properly set up. Moreover, the chrome extension does not collect any data from students' devices (as of version 0.1.0).
55
<br>
6-
The first version unstable of this application was made in less than 3 days.
6+
The first unstable version of this application was made in less than 3 days.
77
<br><br>
88
I believe that Singapore needs our own solution for a DMA to accommodate for the various needs of students and teachers. In the future, Project Ignite be more than just a DMA. It will be an all in one software to help teachers facilitate learning through various tools and features that will keep students intrigued to conducted lessons. These features will be synced to the complex timetable schools in Singapore have. It will also come with software to help schools create these complex timetables.
99
<br>
@@ -25,7 +25,6 @@ This full stack application does not collect any personal data nor does it have
2525
## Feature Timeline
2626
- **End of October 2024**
2727
- Multiple profile Support
28-
<br><br>
2928
- **End of November 2024**
3029
- Ability to handle more than 5,000 blocked sites
3130
- "Live class" feature, which includes the following features:
@@ -34,13 +33,10 @@ This full stack application does not collect any personal data nor does it have
3433
- "Live Management". Allows teachers, during a live class session, to see the sites students are visiting, push sites for students to visit, and, enforce a custom set of rules for which sites students are allowed to visit.
3534
- "Q&A". Allows students to post questions to the teacher without disrupting the entire lesson.
3635
- "Live Polls". Allows teachers to create multiple choice or open ended polls. This is useful when teachers show questions in their slides and ask students to answer.
37-
<br><br>
3836
- **By 3rd quarter of December 2024**
3937
- Documentation for Ignite DMA
40-
<br><br>
4138
- **End of June 2025**
4239
- Ability to manage the installation, enabling, disabling and removal of extensions from the chrome web store on students' devices.
43-
<br><br>
4440
- **Future Goals**
4541
- Timetable generation and ability to sync with "Live class" system
4642
- iPad and Windows Client for students using these devices
@@ -78,8 +74,8 @@ Even if you cannot enforce this setting, it will by default have access to all s
7874
- [ ] Server: Code cleanup
7975
- [ ] App Icon
8076
- [ ] Server: Create reset profile password feature?
81-
- [ ] Extension (`background.js`): Implement Error Handling.
77+
- [ ] Extension (`background.js`): Implement Logging.
8278
- [ ] Extension: Detect use of [pillow](https://github.com/S1monlol/pillow)
83-
- [ ] Extension: Implement End-to-End Encryption to prevent server impersonation. (Students might fork server and bypass through DNS hijack)
79+
- [ ] Extension: Implement Verify Magic Packet to prevent server impersonation. (Students might fork server and bypass through DNS hijack)
8480
- [ ] Extension: Find a way around `declarativeNetRequest` 5000 rule limit
8581
- [ ] Extension: Support for multiple profiles

extension/background.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,24 @@ export function syncNow(){
451451
return syncProfiles();
452452
}
453453

454+
//The function below is used to verify the main server's identity
455+
//How it works is that when the main server receives the correct PIN
456+
//to remove the enrollment. A secret file is sent to the client and
457+
//the checksum of the file is measured to verify that the server
458+
//contacted is indeed the real server.
459+
//Function has not been Implemented yet
460+
/*export function verifyMagicPacket(blob){
461+
return blob.arrayBuffer().then((dataBuffer) => {
462+
return crypto.subtle.digest('SHA-256', dataBuffer).then((hashBuffer) => {
463+
const hashArray = Array.from(new Uint8Array(hashBuffer));
464+
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
465+
const expectedChecksum = "139531df1cac2ff1b2be3fa5afde6a904cef6583de35efe07f1ddfe6f3228da5";
466+
return hashHex === expectedChecksum;
467+
});
468+
});
469+
}
470+
*/
471+
454472
if (typeof window == 'undefined') { //The javascript equivilant of `if __name__ == '__main__':` in python
455473
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
456474
if (request === 'getBlockedSites') {

extension/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifest_version": 3,
33
"name": "Ignite DMA",
4-
"version": "0.1",
4+
"version": "0.1.1",
55
"author": "AzlanCoding",
66
"description": "A Device Manager Application (DMA) for students under MOE",
77
"homepage_url": "https://ignitedma.mooo.com/",

extension/options.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
<div class="field">
7373
<label class="label">Profile Code</label>
7474
<div class="control">
75-
<input class="input" type="text" maxLength="8" placeholder="ABC123" id="classCode" style="text-transform:uppercase"/>
75+
<input class="input" type="text" maxLength="8" placeholder="ABCDEFGH" id="classCode" style="text-transform:uppercase"/>
7676
</div>
7777
</div>
7878
<button class="button is-primary" id="addProfileBtn">Add Profile</button>
@@ -88,7 +88,7 @@
8888
<div class="field">
8989
<label class="label">Master PIN</label>
9090
<div class="control">
91-
<input class="input" type="password" id="maserPinInput"/>
91+
<input class="input" type="password" id="maserPinInput" placeholder="Enter Master Pin"/>
9292
</div>
9393
</div>
9494
<button class="button is-danger" id="removeProfileBtn">Remove Profile</button>

extension/scripts.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,41 @@ function masterPin(){
5959
alert("Wrong PIN");
6060
}
6161
document.getElementById("removeProfileBtn").classList.remove("is-loading");
62+
}).catch((err) => {
63+
alert("FAILED TO CONTACT SERVER!\n"+err);
64+
document.getElementById("removeProfileBtn").classList.remove("is-loading");
6265
});
6366
}
6467

68+
//Not implemented yet
69+
/*
70+
function masterPin(){
71+
document.getElementById("removeProfileBtn").classList.add("is-loading");
72+
let enrollCode = "";
73+
return fetch(updateHost+"/api/v1/masterPin",{cache: "no-cache", method:"post", headers: {'enrollCode': enrollCode, 'PIN': document.getElementById('maserPinInput').value}}).then((response) => {
74+
if (response.ok) {
75+
response.blob().then((data) => {
76+
verifyMagicPacket(data).then((outcome) => {
77+
if (outcome){
78+
removeClass().then(()=>{
79+
alert("REMOVAL PROCESS SUCCESS!");
80+
window.location.reload();
81+
});
82+
}
83+
else{
84+
alert("Wrong PIN");
85+
document.getElementById("removeProfileBtn").classList.remove("is-loading");
86+
}
87+
});
88+
});
89+
}
90+
else {
91+
alert("Wrong PIN");
92+
document.getElementById("removeProfileBtn").classList.remove("is-loading");
93+
}
94+
});
95+
}
96+
*/
6597

6698
function createBlockedSiteData(value){
6799
const container = document.getElementById('profileBlockedSites');
@@ -158,10 +190,13 @@ document.getElementById("refreshProfileBtn").addEventListener("click", () => {
158190
alert("STOP SPAMMING `REFRESH PROFILE` YOU'RE BREAKING THE APP\n"+err+"\nREFRESHING PAGE...");
159191
canContinue = false;
160192
window.location.reload();
161-
// BUG: Uncaught (in promise) Error: This request exceeds the MAX_WRITE_OPERATIONS_PER_MINUTE quota.
193+
// NOTE: Uncaught (in promise) Error: This request exceeds the MAX_WRITE_OPERATIONS_PER_MINUTE quota.
162194
// Caused when `Refresh Profile` is spammed
163195
}
164196
else{
197+
// I know this looks a bit stupid but it is needed.
198+
// Even after window.location.reload() is called this function
199+
// may still execute as the button may have been spammed too many times.
165200
if (canContinue){
166201
alert("FAILED TO CONTACT SERVER!\n"+err);
167202
}

0 commit comments

Comments
 (0)