From 0d7038c4b6ffbacc4a198ba8c040f502591d3fe4 Mon Sep 17 00:00:00 2001 From: Janis Steiner Date: Tue, 18 Jun 2024 09:36:11 +0100 Subject: [PATCH] adding updated code --- sys0-code/api/queue.php | 66 ++++ sys0-code/api/sendmail.php | 102 +++++ sys0-code/api/update_settings.php | 41 ++ sys0-code/app/bugreport.php | 74 ++++ sys0-code/app/cloud.php | 199 ++++++++++ sys0-code/app/create_admin.php | 232 +++++++++++ sys0-code/app/create_key.php | 84 ++++ sys0-code/app/debug.php | 267 +++++++++++++ sys0-code/app/disclaimer.php | 87 ++++ sys0-code/app/load.php | 38 ++ sys0-code/app/overview.php | 395 +++++++++++++++++++ sys0-code/app/permission_functions.php | 50 +++ sys0-code/app/print.php | 523 +++++++++++++++++++++++++ sys0-code/app/privacy-policy.php | 212 ++++++++++ sys0-code/app/public_cloud.php | 146 +++++++ sys0-code/app/remove_user.php | 487 +++++++++++++++++++++++ sys0-code/app/reservations.php | 109 ++++++ sys0-code/app/view_apikey.php | 65 +++ sys0-code/app/view_log.php | 142 +++++++ sys0-code/app/webcam.php | 26 ++ sys0-code/assets/images/ksw_logo.png | Bin 0 -> 48551 bytes sys0-code/log/log.php | 49 +++ sys0-code/login/keepmeloggedin.php | 64 +++ sys0-code/login/login.php | 492 +++++++++++++++++++++++ sys0-code/login/logout.php | 14 + sys0-code/login/reset-password.php | 185 +++++++++ sys0-code/login/reset_pw.php | 134 +++++++ sys0-code/login/verify_account.php | 52 +++ sys0-code/waf/salt.php | 15 + 29 files changed, 4350 insertions(+) create mode 100644 sys0-code/api/queue.php create mode 100644 sys0-code/api/sendmail.php create mode 100644 sys0-code/api/update_settings.php create mode 100644 sys0-code/app/bugreport.php create mode 100644 sys0-code/app/cloud.php create mode 100644 sys0-code/app/create_admin.php create mode 100644 sys0-code/app/create_key.php create mode 100644 sys0-code/app/debug.php create mode 100644 sys0-code/app/disclaimer.php create mode 100644 sys0-code/app/load.php create mode 100644 sys0-code/app/overview.php create mode 100644 sys0-code/app/permission_functions.php create mode 100644 sys0-code/app/print.php create mode 100644 sys0-code/app/privacy-policy.php create mode 100644 sys0-code/app/public_cloud.php create mode 100644 sys0-code/app/remove_user.php create mode 100644 sys0-code/app/reservations.php create mode 100644 sys0-code/app/view_apikey.php create mode 100644 sys0-code/app/view_log.php create mode 100644 sys0-code/app/webcam.php create mode 100644 sys0-code/assets/images/ksw_logo.png create mode 100644 sys0-code/log/log.php create mode 100644 sys0-code/login/keepmeloggedin.php create mode 100644 sys0-code/login/login.php create mode 100644 sys0-code/login/logout.php create mode 100644 sys0-code/login/reset-password.php create mode 100644 sys0-code/login/reset_pw.php create mode 100644 sys0-code/login/verify_account.php create mode 100644 sys0-code/waf/salt.php diff --git a/sys0-code/api/queue.php b/sys0-code/api/queue.php new file mode 100644 index 0000000..a959a2f --- /dev/null +++ b/sys0-code/api/queue.php @@ -0,0 +1,66 @@ +$last_id and free=1 order by id"; + else + $sql="Select id,apikey,printer_url from printer where id=$print_on and free=1"; + //echo $sql; + $stmt = mysqli_prepare($link, $sql)mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $id,$papikey,$purl); + mysqli_stmt_fetch($stmt); + if($id!=0) + { + exec('curl -k -H "X-Api-Key: '.$papikey.'" -F "select=true" -F "print=true" -F "file=@'.$qfilepath.'" "'.$purl.'/api/files/local" > /var/www/html/user_files/'.$username.'/json.json'); + $fg=file_get_contents("/var/www/html/user_files/$username/json.json"); + $json=json_decode($fg,true); + if($json['effectivePrint']==true and $json["effectiveSelect"]==true) + { + $sql="update printer set free=0, printing=1,mail_sent=0, used_by_userid=$quserid where id=$id"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + + $sql="delete from queue where id=$qid"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + } + else + { + } + } + } + } + +?> + diff --git a/sys0-code/api/sendmail.php b/sys0-code/api/sendmail.php new file mode 100644 index 0000000..1d8094b --- /dev/null +++ b/sys0-code/api/sendmail.php @@ -0,0 +1,102 @@ +$last_id and printing=1 ORDER BY id"; + $cancel=0; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $is_free,$printer_id,$url,$apikey,$cancel,$used_by_userid,$mail_sent); + mysqli_stmt_fetch($stmt); + $last_id=$printer_id; + + //printer is printing + exec("curl --max-time 10 $url/api/job?apikey=$apikey > /var/www/html/user_files/$username/json.json"); + $fg=file_get_contents("/var/www/html/user_files/$username/json.json"); + $json=json_decode($fg,true); + + + $used_by_user=""; + $telegram_id=""; + $notification_telegram=0; + $notification_mail=0; + $sql="select username,telegram_id,notification_telegram,notification_mail from users where id=$used_by_userid"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $used_by_user,$telegram_id,$notification_telegram,$notification_mail); + mysqli_stmt_fetch($stmt); + $username3=explode("@",$used_by_user); + $username2=$username3[0]; + $progress=(int) $json['progress']['completion']; + if($progress<0) + $progress=-$progress; + $file=$json['job']['file']['name']; + if($progress==100){ + //print finished + //check if mail has not been sent: + + if($mail_sent==0 && $notification_telegram==1){ + //send telegram message + echo("sending telegram for printer $printer_id
"); + $text = urlencode("Hi $username2\nDein Druck auf Drucker $printer_id ist fertig\nDatei, welche du gedruckt hast: $file\n"); + exec("curl \"https://api.telegram.org/$api/sendMessage?chat_id=$telegram_id&text=$text\""); + $sql="update printer set mail_sent=1 where id=$printer_id"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + + } + + if($mail_sent==0 && $notification_mail==1) + { + + echo("sending mail for printer $printer_id
"); + $mail=<<Dein 3D-Druck auf Drucker $printer_id ist fertig.
Bitte hole diesen ab und vergiss nicht den Drucker danach freizugeben!
Deine Aufträge: https://app.ksw3d.ch/system0/html/php/login/v3/php/overview.php?private
Datei, welche du gedruckt hast: $file

Vielen dank für dein Vertrauen in uns!
Code Camp 2024
"}]}' +EOF; + $out=""; + exec($mail,$out); + $sql="update printer set mail_sent=1 where id=$printer_id"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + } + } + else if($cancel==1){ + //print cancelled + } + //else: print still running + $cnt--; + } + + +?> diff --git a/sys0-code/api/update_settings.php b/sys0-code/api/update_settings.php new file mode 100644 index 0000000..9b57547 --- /dev/null +++ b/sys0-code/api/update_settings.php @@ -0,0 +1,41 @@ + diff --git a/sys0-code/app/bugreport.php b/sys0-code/app/bugreport.php new file mode 100644 index 0000000..82d03a8 --- /dev/null +++ b/sys0-code/app/bugreport.php @@ -0,0 +1,74 @@ + + + + + + + +load_user()"; +?> + + ");?> +
+ + + Bug report + + +
+
+
+

Fehler melden

+
+
+ + +
+
+ + "> +
+ +
+ Vielen Dank, deine Fehlermeldung ist bei uns angekommen und wir kümmern uns darum.
'; + } + ?> +
+
+ + + + + diff --git a/sys0-code/app/cloud.php b/sys0-code/app/cloud.php new file mode 100644 index 0000000..38f9317 --- /dev/null +++ b/sys0-code/app/cloud.php @@ -0,0 +1,199 @@ + + + + + + + +load_user()"; + + +?> + +',':',';','?','*','"','|','%']; + $filetype = strtolower(pathinfo($_FILES['file']['name'],PATHINFO_EXTENSION)); + $path = "/var/www/html/user_files/$username/"; + $filename=basename( $_FILES['file']['name']); + $filename=str_replace($unwanted_chr,"_",$filename); + $path = $path . $filename; + if(!in_array($filetype,$ok_ft)) + { + $file_upload_err="Dieser Dateityp wird nicht unterstüzt."; + } + else + { + if(move_uploaded_file($_FILES['file']['tmp_name'], $path)) { + $file_upload_err="ok"; + } + else + { + $file_upload_err="Ein Fehler beim Uploaden der Datei ist aufgetreten! Versuche es erneut!"; + } + } + unset($_FILES['file']); + } +?> +
+ + + Eigene Dateien + + + +
+
+ + "); + else if($file_upload_err!="nan") + echo("
"); + ?> +

Eigene Dateien

+
+ +
+ + +
+
+ + + + + + + + + + + + + '; + echo ''; + echo ''; + echo ''; + echo "'; + echo "'; + echo ""; + echo ''; + } + }else{ + echo ''; + echo ''; + echo ''; + echo ''; + echo "'; + echo "'; + echo ""; + echo ''; + } + } + } else { + echo ''; + } + ?> + +
PreviewFile NamePrint FileDelete FileDownload FileMake Public
' . basename($file) . 'Drucken" . "Löschen" . '" . "Herunterladen" . 'Öffentlich verfügbar machen
' . basename($file) . 'Drucken" . "Löschen" . '" . "Herunterladen" . 'Öffentlich verfügbar machen
Directory not found
+
+
+
+
+ + + + + diff --git a/sys0-code/app/create_admin.php b/sys0-code/app/create_admin.php new file mode 100644 index 0000000..c9d675b --- /dev/null +++ b/sys0-code/app/create_admin.php @@ -0,0 +1,232 @@ + + + +Oops! Something went wrong. Please try again later."; + } + + // Close statement + mysqli_stmt_close($stmt); + } + } + + // Validate password + if(empty(trim($_POST["password"]))){ + $err = "Please enter a password."; + } elseif(strlen(trim($_POST["password"])) < 6){ + $err = "Password must have atleast 6 characters."; + } else if(strlen(trim($_POST["new_password"])) > 96) + { + $login_err = "Password cannot have more than 96 characters."; + }else{ + $password = trim($_POST["password"]); + } + + // Validate confirm password + if(empty(trim($_POST["confirm_password"]))){ + $err = "Please confirm password."; + } else{ + $confirm_password = trim($_POST["confirm_password"]); + if(empty($err) && ($password != $confirm_password)){ + $err = "Password did not match."; + } + } + + // Check input errors before inserting in database + if(empty($err)){ + + // Prepare an insert statement + $sql = "INSERT INTO users (username, password, role,notification_telegram,notification_mail) VALUES (?, ?, ?,?,?)"; + + if($stmt = mysqli_prepare($link, $sql)){ + // Bind variables to the prepared statement as parameters + $tel=0; + $mail=1; + mysqli_stmt_bind_param($stmt, "sssii", $param_username, $param_password, $role,$tel,$mail); + + // Set parameters + $tel=0; + $mail=1; + $param_username = $username; + $param_password = password_hash($password, PASSWORD_DEFAULT); // Creates a password hash + $role=get_perm_string(); + // Attempt to execute the prepared statement + if(mysqli_stmt_execute($stmt)){ + // Redirect to login page + mkdir("/var/www/html/user_files/$username"); + header("LOCATION: /app/overview.php"); + } else{ + echo "Oops! Something went wrong. Please try again later."; + } + + // Close statement + mysqli_stmt_close($stmt); + } + } + + // Close connection + mysqli_close($link); +} +?> + + + + + + Sign Up + + "); + echo("
");?> + +
+
+
+
+
+

Account erstellen

+
+
+ + +
+
+ + +
+
+ + +
+
+
Berechtigungen
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BerechtigungBerechtigung erteilen
Datei Drucken
Private Cloud
Öffentliche Cloud
Alle Drucker abbrechen / freigeben
Benutzereinstellungen ändern
Administratoren erstellen
Log ansehen
System0 APIkey ansehen
Druckschlüssel erstellen
Debug
Alle Dateien von Öffentlicher Cloud Löschen
+
+

+
+ ' . $err . '
'; + } + ?> +
+
+
+
+ + + + diff --git a/sys0-code/app/create_key.php b/sys0-code/app/create_key.php new file mode 100644 index 0000000..8771871 --- /dev/null +++ b/sys0-code/app/create_key.php @@ -0,0 +1,84 @@ + + + + + + Account Einstellungen + + + + ");?> + + + + load_user()"; + + ?> + +
+ +
+
+
+

Druckschlüssel Generieren

+
+

+ Ein Druckschlüssel ist ein Code, welcher ein Benutzer benutzen kann, um einen Druckauftrag zu starten. +

+
+ +
+
+ You key got added to the database, it can now be used to print files.
key: $key"); + } + ?> +
+
+ + + + diff --git a/sys0-code/app/debug.php b/sys0-code/app/debug.php new file mode 100644 index 0000000..91098f8 --- /dev/null +++ b/sys0-code/app/debug.php @@ -0,0 +1,267 @@ + + + + + + + +load_user()"; + + +?> + + +
+ + + Drucker Einstellungen + + + +
+
+
+

Druckerfreigabe erzwingen (falls beim freigeben Fehlermeldungen angezeigt werden)

+
"); + $last_id=0; + while($cnt!=0) + { + $userid=0; + $sql="select id,printer_url,apikey,cancel,used_by_userid from printer where free=0 and id>$last_id ORDER BY id"; + $cancel=0; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $printer_id,$url,$apikey,$cancel,$userid); + mysqli_stmt_fetch($stmt); + + + $last_id=$printer_id; + + $used_by_user=""; + $sql="select username from users where id=$userid"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $used_by_user); + mysqli_stmt_fetch($stmt); + + + echo(""); + + $cnt--; + } + echo("
DruckeridFreigeben
$printer_id
"); + ?> +

+ + + +

Rotation der Druckerkameras

+ form => action=rot&rot=180 + $cnt=0; + $url=""; + $apikey=""; + $sql="select count(*) from printer"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $cnt); + mysqli_stmt_fetch($stmt); + //echo($cnt); + echo("
"); + $last_id=0; + $rotation=0; + while($cnt!=0) + { + $userid=0; + $sql="select rotation,id from printer where id>$last_id ORDER BY id"; + $cancel=0; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $rotation,$printer_id); + mysqli_stmt_fetch($stmt); + + + $last_id=$printer_id; + + $used_by_user=""; + + echo(""); + + $cnt--; + } + echo("
DruckeridRotation
$printer_id
"); + ?> +

+

Filamentfarbe

+ form => color + $cnt=0; + $url=""; + $apikey=""; + $sql="select count(*) from printer"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $cnt); + mysqli_stmt_fetch($stmt); + //echo($cnt); + echo("
"); + $last_id=0; + $color=""; + while($cnt!=0) + { + $userid=0; + $sql="select color,id from printer where id>$last_id ORDER BY id"; + $cancel=0; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $color,$printer_id); + mysqli_stmt_fetch($stmt); + + + $last_id=$printer_id; + + $used_by_user=""; + + echo(""); + + $cnt--; + } + echo("
DruckeridRotation
$printer_id
"); + echo("
"); + + ?> +

Filamente

+ form => color + $cnt=0; + $url=""; + $apikey=""; + $sql="select count(*) from filament"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $cnt); + mysqli_stmt_fetch($stmt); + //echo($cnt); + echo("
"); + + //form to add a color + echo(""); + echo(""); + echo(""); + echo(""); + echo(""); + + $last_id=0; + $color=""; + $id=0; + $row=1; + while($cnt!=0) + { + $userid=0; + $sql="select id,name,internal_id from filament where id>$last_id ORDER BY id"; + $cancel=0; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt,$id, $color,$printer_id); + mysqli_stmt_fetch($stmt); + + + $last_id=$id; + + $used_by_user=""; + $row++; + echo(""); + $cnt--; + } + echo("
FilamenteFarbeHinzufügen/Löschen
$printer_id
"); + echo("
"); + + ?> + +
+
+
+ + + + + diff --git a/sys0-code/app/disclaimer.php b/sys0-code/app/disclaimer.php new file mode 100644 index 0000000..1600b12 --- /dev/null +++ b/sys0-code/app/disclaimer.php @@ -0,0 +1,87 @@ + + + Privacy Policy + + + + ");?> + + + load_user()"; + + ?> + +
+ +
+

Disclaimer

+

Last updated: December 18, 2023

+

Interpretation and Definitions

+

Interpretation

+

The words of which the initial letter is capitalized have meanings defined under the following conditions. + The following definitions shall have the same meaning regardless of whether they appear in singular or in plural.

+

Definitions

+

For the purposes of this Disclaimer:

+
    +
  • Company (referred to as either "the Company", "We", "Us" or "Our" in this Disclaimer) refers to jakach.
  • +
  • Service refers to the Website.
  • +
  • You means the individual accessing the Service, or the company, or other legal entity on behalf of which such individual is accessing or using the Service, as applicable.
  • +
  • Website refers to system0, accessible from app.ksw3d.ch
  • +
+

Disclaimer

+

The information contained on the Service is for general information purposes only.

+

The Company assumes no responsibility for errors or omissions in the contents of the Service.

+

In no event shall the Company be liable for any special, direct, indirect, consequential, or incidental damages or any damages whatsoever, whether in an action of contract, negligence or other tort, arising out of or in connection with the use of the Service or the contents of the Service. The Company reserves the right to make additions, deletions, or modifications to the contents on the Service at any time without prior notice. This Disclaimer has been created with the help of the Disclaimer Generator.

+

The Company does not warrant that the Service is free of viruses or other harmful components.

+

External Links Disclaimer

+

The Service may contain links to external websites that are not provided or maintained by or in any way affiliated with the Company.

+

Please note that the Company does not guarantee the accuracy, relevance, timeliness, or completeness of any information on these external websites.

+

Errors and Omissions Disclaimer

+

The information given by the Service is for general guidance on matters of interest only. Even if the Company takes every precaution to insure that the content of the Service is both current and accurate, errors can occur. Plus, given the changing nature of laws, rules and regulations, there may be delays, omissions or inaccuracies in the information contained on the Service.

+

The Company is not responsible for any errors or omissions, or for the results obtained from the use of this information.

+

Fair Use Disclaimer

+

The Company may use copyrighted material which has not always been specifically authorized by the copyright owner. The Company is making such material available for criticism, comment, news reporting, teaching, scholarship, or research.

+

The Company believes this constitutes a "fair use" of any such copyrighted material as provided for in section 107 of the United States Copyright law.

+

If You wish to use copyrighted material from the Service for your own purposes that go beyond fair use, You must obtain permission from the copyright owner.

+

Views Expressed Disclaimer

+

The Service may contain views and opinions which are those of the authors and do not necessarily reflect the official policy or position of any other author, agency, organization, employer or company, including the Company.

+

Comments published by users are their sole responsibility and the users will take full responsibility, liability and blame for any libel or litigation that results from something written in or as a direct result of something written in a comment. The Company is not liable for any comment published by users and reserves the right to delete any comment for any reason whatsoever.

+

No Responsibility Disclaimer

+

The information on the Service is provided with the understanding that the Company is not herein engaged in rendering legal, accounting, tax, or other professional advice and services. As such, it should not be used as a substitute for consultation with professional accounting, tax, legal or other competent advisers.

+

In no event shall the Company or its suppliers be liable for any special, incidental, indirect, or consequential damages whatsoever arising out of or in connection with your access or use or inability to access or use the Service.

+

"Use at Your Own Risk" Disclaimer

+

All information in the Service is provided "as is", with no guarantee of completeness, accuracy, timeliness or of the results obtained from the use of this information, and without warranty of any kind, express or implied, including, but not limited to warranties of performance, merchantability and fitness for a particular purpose.

+

The Company will not be liable to You or anyone else for any decision made or action taken in reliance on the information given by the Service or for any consequential, special or similar damages, even if advised of the possibility of such damages.

+

Contact Us

+

If you have any questions about this Disclaimer, You can contact Us:

+
    +
  • By email: info.jakach@gmail.com
  • +
+
+ + + diff --git a/sys0-code/app/load.php b/sys0-code/app/load.php new file mode 100644 index 0000000..0663971 --- /dev/null +++ b/sys0-code/app/load.php @@ -0,0 +1,38 @@ + + + + + +Server Stats + + +
+ +"; +echo "CPU Usage: " . $cpu_usage . "
"; +echo "RAM Usage: " . $ram_usage . "
"; + +?> + + + diff --git a/sys0-code/app/overview.php b/sys0-code/app/overview.php new file mode 100644 index 0000000..cf712cb --- /dev/null +++ b/sys0-code/app/overview.php @@ -0,0 +1,395 @@ + + + + + + + + +load_user()"; +?> + +=$firstCharsCount+$lastCharsCount+3){ + $firstChars = substr($filePath, 0, $firstCharsCount); + + // Get the last few characters of the path + $lastChars = substr($filePath, -$lastCharsCount); + + // Return the shortened path + return $firstChars . "..." . $lastChars; + } + else{ + return $filePath; + } + } + $color=$_SESSION["color"]; + include "../assets/components.php"; + if(!isset($_SESSION["rid"])) + $_SESSION["rid"]=0; + $_SESSION["rid"]++; +?> + + Alle Drucker + + + +
+
+
+
+ /var/www/html/user_files/$username/json.json"); + $fg=file_get_contents("/var/www/html/user_files/$username/json.json"); + $json=json_decode($fg,true); + if($json["error"]!="") + { + echo(""); + } + else + { + $sql="update printer set cancel=1 where id=$printer_id"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + } + + } + + $cnt=0; + $url=""; + $apikey=""; + if(isset($_GET["private"])) + $sql="select count(*) from printer where used_by_userid=".$_SESSION["id"]; + else + $sql="select count(*) from printer"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $cnt); + mysqli_stmt_fetch($stmt); + //echo($cnt); + $is_free=0; + echo("
"); + echo("
"); + echo("
"); + if(isset($_GET["private"])) + echo("
Alle Drucker anzeigen"); + else + echo("
Nur eigene Aufträge anzeigen"); + echo("
"); + $last_id=0; + $system_status=0; + $rotation=0; + while($cnt!=0) + { + $userid=0; + if(isset($_GET["private"])) + $sql="select rotation,free,id,printer_url,apikey,cancel,used_by_userid,system_status,color from printer where id>$last_id and used_by_userid=".$_SESSION["id"]." ORDER BY id"; + else + $sql="select rotation,free,id,printer_url,apikey,cancel,used_by_userid,system_status,color from printer where id>$last_id ORDER BY id"; + $cancel=0; + $filament_color=""; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $rotation,$is_free,$printer_id,$url,$apikey,$cancel,$userid,$system_status,$filament_color); + mysqli_stmt_fetch($stmt); + $last_id=$printer_id; + $filament_color=intval($filament_color); + //get the real color + $sql="select name from filament where internal_id=$filament_color"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt,$filament_color); + mysqli_stmt_fetch($stmt); + + if($is_free==0){ + //printer is printing + exec("curl --max-time 10 $url/api/job?apikey=$apikey > /var/www/html/user_files/$username/json.json"); + $fg=file_get_contents("/var/www/html/user_files/$username/json.json"); + $json=json_decode($fg,true); + + $used_by_user=""; + $sql="select username from users where id=$userid"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $used_by_user); + mysqli_stmt_fetch($stmt); + $username2=explode("@",$used_by_user); + + $progress=(int) $json['progress']['completion']; + if($progress<0) + $progress=-$progress; + $file=$json['job']['file']['name']; + if($progress==100){ + $print_time=seconds_to_time(intval($json["progress"]["printTime"])); + $print_time_left=seconds_to_time(intval($json["progress"]["printTimeLeft"])); + $print_time_total=seconds_to_time(intval($json["job"]["estimatedPrintTime"])); + echo("
"); + echo("
"); + echo("
Drucker $printer_id
"); + echo("
"); + echo("
"); + echo(""); + echo("
"); + echo("
$progress%
"); + echo("
"); + echo(""); + echo(""); + echo(""); + echo(""); + if(!empty($filament_color) && $filament_color!=NULL) + echo(""); + echo(""); + echo(""); + echo(""); + echo(""); + echo(""); + if($userid==$_SESSION["id"] or $role[3]==="1"){ + echo(""); + } + echo(""); + echo("
StatusFertig
Genutzt von".$username2[0]."
Filamentfarbe$filament_color
Erwartete Druckzeit$print_time_total
Verbleibende Druckzeit$print_time_left
Vergangene Druckzeit$print_time
Datei
".short_path($json["job"]["file"]["name"],10,10)."
".$json["job"]["file"]["name"]."
Freigeben
"); + echo("
"); + echo("
"); + } + else if($cancel==1){ + $print_time=seconds_to_time(intval($json["progress"]["printTime"])); + $print_time_left=seconds_to_time(intval($json["progress"]["printTimeLeft"])); + $print_time_total=seconds_to_time(intval($json["job"]["estimatedPrintTime"])); + echo("
"); + echo("
"); + echo("
Drucker $printer_id
"); + echo("
"); + echo("
"); + echo(""); + echo("
"); + echo("
$progress%
"); + echo("
"); + echo(""); + echo(""); + echo(""); + echo(""); + if(!empty($filament_color) && $filament_color!=NULL) + echo(""); + echo(""); + echo(""); + echo(""); + echo(""); + if($userid==$_SESSION["id"] or $role[3]=="1"){ + echo(""); + } + echo(""); + echo("
StatusDruck Abgebrochen
Genutzt von".$username2[0]."
Filamentfarbe$filament_color
Erwartete Druckzeit$print_time_total
Verbleibende Druckzeit$print_time_left
Vergangene Druckzeit$print_time
Datei
".short_path($json["job"]["file"]["name"],10,10)."
".$json["job"]["file"]["name"]."
Freigeben
"); + echo("
"); + echo("
"); + } + else{ + $print_time=seconds_to_time(intval($json["progress"]["printTime"])); + $print_time_left=seconds_to_time(intval($json["progress"]["printTimeLeft"])); + $print_time_total=seconds_to_time(intval($json["job"]["estimatedPrintTime"])); + echo("
"); + echo("
"); + echo("
Drucker $printer_id
"); + echo("
"); + echo("
"); + echo(""); + echo("
"); + echo("
$progress%
"); + echo("
"); + echo(""); + echo(""); + echo(""); + echo(""); + if(!empty($filament_color) && $filament_color!=NULL) + echo(""); + echo(""); + echo(""); + echo(""); + echo(""); + if($userid==$_SESSION["id"] or $role[3]==="1"){ + echo(""); + } + echo(""); + echo("
StatusDrucken
Genutzt von".$username2[0]."
Filamentfarbe$filament_color
Erwartete Druckzeit$print_time_total
Verbleibende Druckzeit$print_time_left
Vergangene Druckzeit$print_time
Datei
".short_path($json["job"]["file"]["name"],10,10)."
".$json["job"]["file"]["name"]."
Abbrechen
"); + echo("
"); + echo("
"); + } + }else{ + //printer is free + echo("
"); + echo("
"); + echo("
Drucker $printer_id
"); + echo("
"); + echo("
"); + echo(""); + echo(""); + echo(""); + echo(""); + if(!empty($filament_color) && $filament_color!=NULL) + echo(""); + echo(""); + echo(""); + echo("
StatusBereit
Filamentfarbe$filament_color
Drucken
"); + echo("
"); + echo("
"); + + } + $cnt--; + } + echo("
"); + + ?> +

+ +
+
+
+
+ +
+

Warteschlange

+
"); + $last_id=0; + $form_userid=0; + $print_on=0; + while($cnt!=0) + { + $sql="select id,filepath,from_userid,print_on from queue where id>$last_id order by id"; + $cancel=0; + $stmt = mysqli_prepare($link, $sql); + echo mysqli_error($link); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $queue_id,$filepath,$from_userid,$print_on); + mysqli_stmt_fetch($stmt); + $filepath=basename($filepath); + $last_id=$queue_id; + echo(""); + if($print_on==-1) + echo(""); + else + echo(""); + if($_SESSION["role"][3]==="1" or $_SESSION["id"]==$from_userid) + echo(""); + + $cnt--; + } + echo("
DateiDrucken auf Druckeraus der Warteschlange entfernen
$filepathErster verfügbarer Drucker$print_on
"); + ?> +

+ + + + + diff --git a/sys0-code/app/permission_functions.php b/sys0-code/app/permission_functions.php new file mode 100644 index 0000000..4ca0b6b --- /dev/null +++ b/sys0-code/app/permission_functions.php @@ -0,0 +1,50 @@ + diff --git a/sys0-code/app/print.php b/sys0-code/app/print.php new file mode 100644 index 0000000..77e1e36 --- /dev/null +++ b/sys0-code/app/print.php @@ -0,0 +1,523 @@ +75 or $ex_temp>225){ + return 0; + }else{ + return 1; + } +} + +function is_time_between($startTime, $endTime, $checkTime) { + // Convert times to timestamps + $startTimestamp = strtotime($startTime); + $endTimestamp = strtotime($endTime); + $checkTimestamp = strtotime($checkTime); + + // If end time is less than start time, it means the range crosses midnight + if ($endTimestamp < $startTimestamp) { + // Check if the time is between start time and midnight or between midnight and end time + return ($checkTimestamp >= $startTimestamp || $checkTimestamp <= $endTimestamp); + } else { + // Normal case: check if the time is between start and end time + return ($checkTimestamp >= $startTimestamp && $checkTimestamp <= $endTimestamp); + } +} + +?> + + + + + + + + load_user()"; + test_queue($link); + ?> + + + ");?> +
+ + + Datei drucken + + + + +

+ ',':',';','?','*','"','|','%']; + $filetype = strtolower(pathinfo($_FILES['file_upload']['name'],PATHINFO_EXTENSION)); + $path = "/var/www/html/user_files/$username/"; + $print_on=$_POST["queue_printer"]; + $filename=basename( $_FILES['file_upload']['name']); + $filename=str_replace($unwanted_chr,"_",$filename); + $path = $path . $filename; + if(!in_array($filetype,$ok_ft)) + { + echo("
"); + sys0_log("Could not upload file for ".$_SESSION["username"]." because of unknown file extension",$_SESSION["username"],"PRINT::UPLOAD::FILE::FAILED");//notes,username,type + } + else + { + if(move_uploaded_file($_FILES['file_upload']['tmp_name'], $path)) { + $sql="INSERT INTO queue (from_userid,filepath,print_on) VALUES (?,?,?)"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_bind_param($stmt, "isi", $userid,$path,$print_on); + mysqli_stmt_execute($stmt); + + echo("
"); + sys0_log("user ".$_SESSION["username"]." uploaded ".basename($path)." to the queue",$_SESSION["username"],"PRINT::UPLOAD::QUEUE");//notes,username,type + } + else + { + echo("
"); + } + } + unset($_FILES['file']); + } + if(isset($_GET["cloudprint"])){ + $print_on=$_POST["queue_printer"]; + if(!isset($_GET["pc"])) + $path = "/var/www/html/user_files/$username/".$_GET["cloudprint"]; + else + $path = "/var/www/html/user_files/public/".$_GET["cloudprint"]; + $sql="INSERT INTO queue (from_userid,filepath,print_on) VALUES (?,?,?)"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_bind_param($stmt, "isi", $userid,$path,$print_on); + mysqli_stmt_execute($stmt); + + + echo("
"); + sys0_log("user ".$_SESSION["username"]." uploaded ".basename($path)." to the queue",$_SESSION["username"],"PRINT::UPLOAD::QUEUE"); + + } + } + else + { + $sql="select printer_url, free, system_status,apikey,printer_url from printer where id=$printer_id"; + //echo $sql; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $url,$free,$status,$apikey,$printer_url); + mysqli_stmt_fetch($stmt); + if($free!=1 or $status!=0) + { + + echo("
"); + sys0_log("Could not start job for ".$_SESSION["username"]." with file ".basename($path)."",$_SESSION["username"],"PRINT::JOB::START::FAILED");//notes,username,type + exit; + } + if(!empty($_FILES['file_upload'])) + { + $ok_ft=array("gcode",""); + $unwanted_chr=[' ','(',')','/','\\','<','>',':',';','?','*','"','|','%']; + $filetype = strtolower(pathinfo($_FILES['file_upload']['name'],PATHINFO_EXTENSION)); + $path = "/var/www/html/user_files/$username/"; + $filename=basename( $_FILES['file_upload']['name']); + $filename=str_replace($unwanted_chr,"_",$filename); + $path = $path . $filename; + + //if(in_array($filetype,$unwanted_ft)) + if(!in_array($filetype,$ok_ft)) + { + echo("
"); + sys0_log("Could not upload file for ".$_SESSION["username"]." because of unknown file extension",$_SESSION["username"],"PRINT::UPLOAD::FILE::FAILED");//notes,username,type + } + else + { + //check if print key is valid: + $print_key=htmlspecialchars($_POST["print_key"]); + $sql="SELECT id from print_key where print_key='$print_key'"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + + //if(mysqli_stmt_num_rows($stmt) == 1){ turned off because user does not need to have a printer key + if(true){ + mysqli_stmt_close($stmt); + if(move_uploaded_file($_FILES['file_upload']['tmp_name'], $path)) { + echo("
"); + echo("
"); + if(check_file($path) or isset($_POST["ignore_unsafe"])){ + exec('curl -k -H "X-Api-Key: '.$apikey.'" -F "select=true" -F "print=true" -F "file=@'.$path.'" "'.$printer_url.'/api/files/local" > /var/www/html/user_files/'.$username.'/json.json'); + //file is on printer and ready to be printed + $userid=$_SESSION["id"]; + echo("
"); + sys0_log("user ".$_SESSION["username"]." uploaded ".basename($path)." to printer ".$_POST["printer"]."",$_SESSION["username"],"PRINT::UPLOAD::PRINTER");//notes,username,type + $fg=file_get_contents("/var/www/html/user_files/$username/json.json"); + $json=json_decode($fg,true); + if($json['effectivePrint']==false or $json["effectiveSelect"]==false) + { + echo("
"); + sys0_log("Could not start job for ".$_SESSION["username"]."with file ".basename($path)."",$_SESSION["username"],"PRINT::JOB::START::FAILED");//notes,username,type + } + else + { + $sql="update printer set free=0, printing=1,mail_sent=0, used_by_userid=$userid where id=$printer_id"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + //delete printer key: + $sql="DELETE from print_key where print_key='$print_key'"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + } + }else{ + $warning=true; + echo("
"); + } + } + else + { + echo("
"); + } + } + else{ + echo("
"); + } + } + unset($_FILES['file']); + } + if(isset($_GET["cloudprint"])){ + if(!isset($_GET["pc"])) + $path = "/var/www/html/user_files/$username/".$_GET["cloudprint"]; + else + $path = "/var/www/html/user_files/public/".$_GET["cloudprint"]; + //check if print key is valid: + $print_key=htmlspecialchars($_POST["print_key"]); + $sql="SELECT id from print_key where print_key='$print_key'"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + + //if(mysqli_stmt_num_rows($stmt) == 1){ turned off because user does not need to have a printer key + if(true){ + mysqli_stmt_close($stmt); + + echo("
"); + if(check_file($path) or isset($_POST["ignore_unsafe"])){ + exec('curl -k -H "X-Api-Key: '.$apikey.'" -F "select=true" -F "print=true" -F "file=@'.$path.'" "'.$printer_url.'/api/files/local" > /var/www/html/user_files/'.$username.'/json.json'); + //file is on printer and ready to be printed + $userid=$_SESSION["id"]; + echo("
"); + sys0_log("user ".$_SESSION["username"]." uploaded ".basename($path)." to printer ".$_POST["printer"]."",$_SESSION["username"],"PRINT::UPLOAD::PRINTER");//notes,username,type + $fg=file_get_contents("/var/www/html/user_files/$username/json.json"); + $json=json_decode($fg,true); + //echo('curl -k -H "X-Api-Key: '.$apikey.'" -F "select=true" -F "print=true" -F "file=@'.$path.'" "'.$printer_url.'/api/files/local" > /var/www/html/system0/html/user_files/'.$username.'/json.json'); + //echo("


"); + //var_dump($json); + if($json['effectivePrint']==false or $json["effectiveSelect"]==false) + { + echo("
"); + sys0_log("Could not start job for ".$_SESSION["username"]."with file ".basename($path)."",$_SESSION["username"],"PRINT::JOB::START::FAILED");//notes,username,type + } + else + { + $sql="update printer set free=0, printing=1,mail_sent=0, used_by_userid=$userid where id=$printer_id"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + //delete printer key: + $sql="DELETE from print_key where print_key='$print_key'"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + } + }else{ + $warning=true; + echo("
"); + } + } + else{ + echo("
"); + } + } + } + } + + ?> + +
+

Datei drucken

+ + prepare($sql); + $stmt->execute(); + $result = $stmt->get_result(); + //$row = $result->fetch_assoc(); + $time_now=date("H:i"); + while ($row = $result->fetch_assoc()) { + if (is_time_between($row["time_from"], $row["time_to"], $time_now)) { + $reservation_conflict = true; + break; + } + } + + if ($reservation_conflict) { + echo "
"; + } + + ?> +
+ + +
+ '); + echo('
'); + + echo(''); + echo(' '); + echo('
'); + echo('
'); + } + else{ + echo ('
'); + echo('
'); + + echo("

Cloudfile: ".$_GET["cloudprint"]."

"); + echo('
'); + echo('
'); + } + ?> +

+
+ + +
+ + '); + echo(''); + echo(''); + echo('
'); + } + ?> + + +

+ + "); + echo("
"); + } + + ?> + + + + + + +
+ + + + + diff --git a/sys0-code/app/privacy-policy.php b/sys0-code/app/privacy-policy.php new file mode 100644 index 0000000..74f6029 --- /dev/null +++ b/sys0-code/app/privacy-policy.php @@ -0,0 +1,212 @@ + + + Privacy Policy + + + + ");?> + + + load_user()"; + ?> + +
+ +
+

Privacy Policy

+

Last updated: December 18, 2023

+

This Privacy Policy describes Our policies and procedures on the collection, use and disclosure of Your information when You use the Service and tells You about Your privacy rights and how the law protects You.

+

We use Your Personal data to provide and improve the Service. By using the Service, You agree to the collection and use of information in accordance with this Privacy Policy. This Privacy Policy has been created with the help of the Privacy Policy Generator.

+

Interpretation and Definitions

+

Interpretation

+

The words of which the initial letter is capitalized have meanings defined under the following conditions. The following definitions shall have the same meaning regardless of whether they appear in singular or in plural.

+

Definitions

+

For the purposes of this Privacy Policy:

+
    +
  • +

    Account means a unique account created for You to access our Service or parts of our Service.

    +
  • +
  • +

    Affiliate means an entity that controls, is controlled by or is under common control with a party, where "control" means ownership of 50% or more of the shares, equity interest or other securities entitled to vote for election of directors or other managing authority.

    +
  • +
  • +

    Company (referred to as either "the Company", "We", "Us" or "Our" in this Agreement) refers to Jakach.

    +
  • +
  • +

    Cookies are small files that are placed on Your computer, mobile device or any other device by a website, containing the details of Your browsing history on that website among its many uses.

    +
  • +
  • +

    Country refers to: Switzerland

    +
  • +
  • +

    Device means any device that can access the Service such as a computer, a cellphone or a digital tablet.

    +
  • +
  • +

    Personal Data is any information that relates to an identified or identifiable individual.

    +
  • +
  • +

    Service refers to the Website.

    +
  • +
  • +

    Service Provider means any natural or legal person who processes the data on behalf of the Company. It refers to third-party companies or individuals employed by the Company to facilitate the Service, to provide the Service on behalf of the Company, to perform services related to the Service or to assist the Company in analyzing how the Service is used.

    +
  • +
  • +

    Usage Data refers to data collected automatically, either generated by the use of the Service or from the Service infrastructure itself (for example, the duration of a page visit).

    +
  • +
  • +

    Website refers to system0, accessible from app.ksw3d.ch

    +
  • +
  • +

    You means the individual accessing or using the Service, or the company, or other legal entity on behalf of which such individual is accessing or using the Service, as applicable.

    +
  • +
+

Collecting and Using Your Personal Data

+

Types of Data Collected

+

Personal Data

+

While using Our Service, We may ask You to provide Us with certain personally identifiable information that can be used to contact or identify You. Personally identifiable information may include, but is not limited to:

+
    +
  • Usage Data
  • +
+

Usage Data

+

Usage Data is collected automatically when using the Service.

+

Usage Data may include information such as Your Device's Internet Protocol address (e.g. IP address), browser type, browser version, the pages of our Service that You visit, the time and date of Your visit, the time spent on those pages, unique device identifiers and other diagnostic data.

+

When You access the Service by or through a mobile device, We may collect certain information automatically, including, but not limited to, the type of mobile device You use, Your mobile device unique ID, the IP address of Your mobile device, Your mobile operating system, the type of mobile Internet browser You use, unique device identifiers and other diagnostic data.

+

We may also collect information that Your browser sends whenever You visit our Service or when You access the Service by or through a mobile device.

+

Tracking Technologies and Cookies

+

We use Cookies and similar tracking technologies to track the activity on Our Service and store certain information. Tracking technologies used are beacons, tags, and scripts to collect and track information and to improve and analyze Our Service. The technologies We use may include:

+
    +
  • Cookies or Browser Cookies. A cookie is a small file placed on Your Device. You can instruct Your browser to refuse all Cookies or to indicate when a Cookie is being sent. However, if You do not accept Cookies, You may not be able to use some parts of our Service. Unless you have adjusted Your browser setting so that it will refuse Cookies, our Service may use Cookies.
  • +
  • Web Beacons. Certain sections of our Service and our emails may contain small electronic files known as web beacons (also referred to as clear gifs, pixel tags, and single-pixel gifs) that permit the Company, for example, to count users who have visited those pages or opened an email and for other related website statistics (for example, recording the popularity of a certain section and verifying system and server integrity).
  • +
+

Cookies can be "Persistent" or "Session" Cookies. Persistent Cookies remain on Your personal computer or mobile device when You go offline, while Session Cookies are deleted as soon as You close Your web browser. Learn more about cookies on the Privacy Policies website article.

+

We use both Session and Persistent Cookies for the purposes set out below:

+
    +
  • +

    Necessary / Essential Cookies

    +

    Type: Session Cookies

    +

    Administered by: Us

    +

    Purpose: These Cookies are essential to provide You with services available through the Website and to enable You to use some of its features. They help to authenticate users and prevent fraudulent use of user accounts. Without these Cookies, the services that You have asked for cannot be provided, and We only use these Cookies to provide You with those services.

    +
  • +
  • +

    Cookies Policy / Notice Acceptance Cookies

    +

    Type: Persistent Cookies

    +

    Administered by: Us

    +

    Purpose: These Cookies identify if users have accepted the use of cookies on the Website.

    +
  • +
  • +

    Functionality Cookies

    +

    Type: Persistent Cookies

    +

    Administered by: Us

    +

    Purpose: These Cookies allow us to remember choices You make when You use the Website, such as remembering your login details or language preference. The purpose of these Cookies is to provide You with a more personal experience and to avoid You having to re-enter your preferences every time You use the Website.

    +
  • +
+

For more information about the cookies we use and your choices regarding cookies, please visit our Cookies Policy or the Cookies section of our Privacy Policy.

+

Use of Your Personal Data

+

The Company may use Personal Data for the following purposes:

+
    +
  • +

    To provide and maintain our Service, including to monitor the usage of our Service.

    +
  • +
  • +

    To manage Your Account: to manage Your registration as a user of the Service. The Personal Data You provide can give You access to different functionalities of the Service that are available to You as a registered user.

    +
  • +
  • +

    For the performance of a contract: the development, compliance and undertaking of the purchase contract for the products, items or services You have purchased or of any other contract with Us through the Service.

    +
  • +
  • +

    To contact You: To contact You by email, telephone calls, SMS, or other equivalent forms of electronic communication, such as a mobile application's push notifications regarding updates or informative communications related to the functionalities, products or contracted services, including the security updates, when necessary or reasonable for their implementation.

    +
  • +
  • +

    To provide You with news, special offers and general information about other goods, services and events which we offer that are similar to those that you have already purchased or enquired about unless You have opted not to receive such information.

    +
  • +
  • +

    To manage Your requests: To attend and manage Your requests to Us.

    +
  • +
  • +

    For business transfers: We may use Your information to evaluate or conduct a merger, divestiture, restructuring, reorganization, dissolution, or other sale or transfer of some or all of Our assets, whether as a going concern or as part of bankruptcy, liquidation, or similar proceeding, in which Personal Data held by Us about our Service users is among the assets transferred.

    +
  • +
  • +

    For other purposes: We may use Your information for other purposes, such as data analysis, identifying usage trends, determining the effectiveness of our promotional campaigns and to evaluate and improve our Service, products, services, marketing and your experience.

    +
  • +
+

We may share Your personal information in the following situations:

+
    +
  • With Service Providers: We may share Your personal information with Service Providers to monitor and analyze the use of our Service, to contact You.
  • +
  • For business transfers: We may share or transfer Your personal information in connection with, or during negotiations of, any merger, sale of Company assets, financing, or acquisition of all or a portion of Our business to another company.
  • +
  • With Affiliates: We may share Your information with Our affiliates, in which case we will require those affiliates to honor this Privacy Policy. Affiliates include Our parent company and any other subsidiaries, joint venture partners or other companies that We control or that are under common control with Us.
  • +
  • With business partners: We may share Your information with Our business partners to offer You certain products, services or promotions.
  • +
  • With other users: when You share personal information or otherwise interact in the public areas with other users, such information may be viewed by all users and may be publicly distributed outside.
  • +
  • With Your consent: We may disclose Your personal information for any other purpose with Your consent.
  • +
+

Retention of Your Personal Data

+

The Company will retain Your Personal Data only for as long as is necessary for the purposes set out in this Privacy Policy. We will retain and use Your Personal Data to the extent necessary to comply with our legal obligations (for example, if we are required to retain your data to comply with applicable laws), resolve disputes, and enforce our legal agreements and policies.

+

The Company will also retain Usage Data for internal analysis purposes. Usage Data is generally retained for a shorter period of time, except when this data is used to strengthen the security or to improve the functionality of Our Service, or We are legally obligated to retain this data for longer time periods.

+

Transfer of Your Personal Data

+

Your information, including Personal Data, is processed at the Company's operating offices and in any other places where the parties involved in the processing are located. It means that this information may be transferred to — and maintained on — computers located outside of Your state, province, country or other governmental jurisdiction where the data protection laws may differ than those from Your jurisdiction.

+

Your consent to this Privacy Policy followed by Your submission of such information represents Your agreement to that transfer.

+

The Company will take all steps reasonably necessary to ensure that Your data is treated securely and in accordance with this Privacy Policy and no transfer of Your Personal Data will take place to an organization or a country unless there are adequate controls in place including the security of Your data and other personal information.

+

Delete Your Personal Data

+

You have the right to delete or request that We assist in deleting the Personal Data that We have collected about You.

+

Our Service may give You the ability to delete certain information about You from within the Service.

+

You may update, amend, or delete Your information at any time by signing in to Your Account, if you have one, and visiting the account settings section that allows you to manage Your personal information. You may also contact Us to request access to, correct, or delete any personal information that You have provided to Us.

+

Please note, however, that We may need to retain certain information when we have a legal obligation or lawful basis to do so.

+

Disclosure of Your Personal Data

+

Business Transactions

+

If the Company is involved in a merger, acquisition or asset sale, Your Personal Data may be transferred. We will provide notice before Your Personal Data is transferred and becomes subject to a different Privacy Policy.

+

Law enforcement

+

Under certain circumstances, the Company may be required to disclose Your Personal Data if required to do so by law or in response to valid requests by public authorities (e.g. a court or a government agency).

+

Other legal requirements

+

The Company may disclose Your Personal Data in the good faith belief that such action is necessary to:

+
    +
  • Comply with a legal obligation
  • +
  • Protect and defend the rights or property of the Company
  • +
  • Prevent or investigate possible wrongdoing in connection with the Service
  • +
  • Protect the personal safety of Users of the Service or the public
  • +
  • Protect against legal liability
  • +
+

Security of Your Personal Data

+

The security of Your Personal Data is important to Us, but remember that no method of transmission over the Internet, or method of electronic storage is 100% secure. While We strive to use commercially acceptable means to protect Your Personal Data, We cannot guarantee its absolute security.

+

Children's Privacy

+

Our Service does not address anyone under the age of 13. We do not knowingly collect personally identifiable information from anyone under the age of 13. If You are a parent or guardian and You are aware that Your child has provided Us with Personal Data, please contact Us. If We become aware that We have collected Personal Data from anyone under the age of 13 without verification of parental consent, We take steps to remove that information from Our servers.

+

If We need to rely on consent as a legal basis for processing Your information and Your country requires consent from a parent, We may require Your parent's consent before We collect and use that information.

+

Links to Other Websites

+

Our Service may contain links to other websites that are not operated by Us. If You click on a third party link, You will be directed to that third party's site. We strongly advise You to review the Privacy Policy of every site You visit.

+

We have no control over and assume no responsibility for the content, privacy policies or practices of any third party sites or services.

+

Changes to this Privacy Policy

+

We may update Our Privacy Policy from time to time. We will notify You of any changes by posting the new Privacy Policy on this page.

+

We will let You know via email and/or a prominent notice on Our Service, prior to the change becoming effective and update the "Last updated" date at the top of this Privacy Policy.

+

You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when they are posted on this page.

+

Contact Us

+

If you have any questions about this Privacy Policy, You can contact us:

+ + +
+ +



+div> diff --git a/sys0-code/app/public_cloud.php b/sys0-code/app/public_cloud.php new file mode 100644 index 0000000..4128306 --- /dev/null +++ b/sys0-code/app/public_cloud.php @@ -0,0 +1,146 @@ + + + + + + + +load_user()"; + + + +?> + + +
+ + + Alle öffentlichen Dateien + + + +
+
+ + +

Öffentliche Dateien

+
+
+ + +
+
+ + + + + + + + + + + + '; + echo ''; + echo ''; + echo ''; + if($role[10]=="1"){ + echo "'; + }else{ + echo ""; + } + echo "'; + echo ''; + } + }else{ + echo ''; + echo ''; + echo ''; + echo ''; + if($role[10]=="1"){ + echo "'; + }else{ + echo ""; + } + echo "'; + + echo ''; + + } + } + } else { + echo ''; + } + ?> + +
PreviewFile NamePrint FileDelete FileDownload File
' . basename($file) . 'Drucken" . "Löschen" . '" . "Herunterladen" . '
' . basename($file) . 'Drucken" . "Löschen" . '" . "Herunterladen" . '
Directory not found
+
+
+
+
+ + + + diff --git a/sys0-code/app/remove_user.php b/sys0-code/app/remove_user.php new file mode 100644 index 0000000..0bb8fa6 --- /dev/null +++ b/sys0-code/app/remove_user.php @@ -0,0 +1,487 @@ + + + + + + + + + ");?> +
+load_user()"); + require_once "../config/config.php"; + if(isset($_GET["update_id"]) && $_GET["rid"]==$_SESSION["rid"]-1){ + $tid=$_GET["update_id"]; + $perms=get_perm_string(); + $sql="UPDATE users SET role = '$perms' WHERE id=$tid"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + } + if(isset($_POST['username'])) + { + $username_td=$_POST['username']; + $username_td=htmlspecialchars($username_td); + $sql="DELETE FROM users WHERE username = '$username_td';"; + //echo($sql); + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + deleteDirectory("/var/www/html/user_files/$username_td/"); + log_("Deleted $username_td","BAN:DELETION"); + } + else if(isset($_POST["ban"])) + { + $username_td=htmlspecialchars($_POST["ban"]); + $reason=htmlspecialchars($_POST["reason"]); + $sql="UPDATE users SET banned = 1, banned_reason='$reason' WHERE username='$username_td'"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + log_("Banned $username_td","BAN:BAN"); + } + else if(isset($_POST["unban"])) + { + $username_td=htmlspecialchars($_POST["unban"]); + $sql="UPDATE users SET banned = 0 WHERE username='$username_td'"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + log_("Unanned $username_td","BAN:UNBAN"); + } + + + //how many users do we have? + $cnt=0; + $sql="SELECT COUNT(*) FROM users"; + if($stmt = mysqli_prepare($link, $sql)){ + // Bind variables to the prepared statement as parameters + + // Attempt to execute the prepared statement + if(mysqli_stmt_execute($stmt)){ + // Store result + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $cnt); + if(mysqli_stmt_fetch($stmt)){ + + } + } else{ + echo ""; + } + + // Close statement + mysqli_stmt_close($stmt); + } + echo('
'); + echo('
+
+

Benutzer zum löschen auswählen:

+
+ + +
+
+
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+
'); + echo('

+
+
+

User zum Bannen auswählen:

+
+ + +
+
+
+
+ +
+
+ '); + //echo('
'); + echo(' +
+
+
+ +
+
+
+
+
+
'); + + echo("

"); + echo('
+
+

Please select a user to unban:

+
+ + +
+
+
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+
+
'); + ?> + + +
+
+
+ + "); + echo(""); + echo(""); + echo("Nutzer"); + echo("Drucken"); + echo("Cloud"); + echo("Öffentliche Cloud"); + echo("Alle Drucker abbrechen / freigeben"); + echo("Benutzereinstellungen ändern"); + echo("Administratoren erstellen"); + echo("Log ansehen"); + echo("APIkey ansehen"); + echo("Druckschlüssel erstellen"); + echo("Debug"); + echo("Alle Dateien von Öffentlicher Cloud löschen"); + echo("Aktualisieren"); + echo("Benutzer löschen"); + echo(""); + echo(""); + echo(""); + echo(""); + //how many users do we have? + $cnt=0; + $sql="SELECT COUNT(*) FROM users"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + // Store result + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $cnt); + mysqli_stmt_fetch($stmt); + mysqli_stmt_close($stmt); + //now we know how many users we have. + $last_id=0; + while($cnt!=0){ + $tusername=""; + $trole=""; + $tid=0; + $sql="select id,username,role from users where id>$last_id ORDER BY id"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + // Store result + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $tid,$tusername,$trole); + mysqli_stmt_fetch($stmt); + mysqli_stmt_close($stmt); + echo("
"); + echo("$tusername"); + if($trole[0]==="1") + echo(''); + else + echo(''); + if($trole[1]==="1") + echo(''); + else + echo(''); + if($trole[2]==="1") + echo(''); + else + echo(''); + if($trole[3]==="1") + echo(''); + else + echo(''); + if($trole[4]==="1") + echo(''); + else + echo(''); + if($trole[5]==="1") + echo(''); + else + echo(''); + if($trole[6]==="1") + echo(''); + else + echo(''); + if($trole[7]==="1") + echo(''); + else + echo(''); + if($trole[8]==="1") + echo(''); + else + echo(''); + if($trole[9]==="1") + echo(''); + else + echo(''); + if($trole[10]==="1") + echo(''); + else + echo(''); + echo(''); + echo(''); + echo("
"); + $last_id=$tid; + $cnt--; + } + echo(""); + echo(""); + echo(""); + mysqli_close($link); + ?> +
+
+ +
+ + + + + diff --git a/sys0-code/app/reservations.php b/sys0-code/app/reservations.php new file mode 100644 index 0000000..92e475d --- /dev/null +++ b/sys0-code/app/reservations.php @@ -0,0 +1,109 @@ + + + + + + + +load_user()"; +?> + +format('Y-m-d'); + +$sql = "DELETE FROM reservations WHERE day <= ?"; +$stmt = $link->prepare($sql); +if ($stmt) { + $stmt->bind_param("s", $formattedYesterday); + $stmt->execute(); + $stmt->close(); +} + +if(isset($_POST["res"])){ + $time_from=htmlspecialchars($_POST["time_from"]); + $time_to=htmlspecialchars($_POST["time_to"]); + $day=htmlspecialchars($_POST["date"]); + $sql="INSERT INTO reservations (time_from,time_to,day,set_by_userid) VALUES (?, ?, ?, ?);"; + $stmt = $link->prepare($sql); + $stmt->bind_param("sssi",$time_from, $time_to, $day,$userid); + $stmt->execute(); +} +if(isset($_GET["del"])){ + $id=htmlspecialchars($_GET["del"]); + $sql="delete from reservations where id=$id"; + $stmt = $link->prepare($sql); + $stmt->execute(); +} + +?> + ");?> +
+ + + Drucker Reservationen + + +
+
+
+ +

Reservation hinzufügen

+
+ + + + +
+

+ +

Reservationen (Alte Reservationen werden automatisch gelöscht)

+ prepare($sql); + $stmt->execute(); + $result = $stmt->get_result(); + echo(""); + echo(""); + while($row = $result->fetch_assoc()) { + echo(""); + } + echo("
Zeit vonZeit bisDatumReservation löschen
".$row["time_from"]."".$row["time_to"]."".$row["day"]."Löschen
"); + + ?> +
+
+
+ + + + diff --git a/sys0-code/app/view_apikey.php b/sys0-code/app/view_apikey.php new file mode 100644 index 0000000..434ab9e --- /dev/null +++ b/sys0-code/app/view_apikey.php @@ -0,0 +1,65 @@ + + + + + + + +load_user()"; +?> + + ");?> +
+ + + Api viewer + + + + +
+
+
+

Dein system0 APIkey:

+ ".$apikey_fromdb.""); + echo("

Behandle diesen Schlüssel wie ein Passwort.
Es ist wichtig, dass niemand diesen Schlüssel erfährt!"); + ?> +
+
+
+ + + + + diff --git a/sys0-code/app/view_log.php b/sys0-code/app/view_log.php new file mode 100644 index 0000000..5878b69 --- /dev/null +++ b/sys0-code/app/view_log.php @@ -0,0 +1,142 @@ + + + + + + + +load_user()"; +?> + + ");?> +
+ + + Log viewer + + + +
+
+
+

Alle Einträge

+
+ + + + + + + + + + + + + + + + + "); + } + } + + } + fclose($fp); + ?> + +
Datum & ZeitIP AdresseTypBenutzernameInfo
------ + + + '); + echo(''); + //now get those users + $cnt2=1; + $id=0; + $last_id=0; + while($cnt2!==$cnt+1) + { + $sql = "SELECT id, username FROM users WHERE id > $last_id ORDER BY id;"; + $stmt = mysqli_prepare($link, $sql); + + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + mysqli_stmt_bind_result($stmt, $id,$username); + mysqli_stmt_fetch($stmt); + $last_id=$id; + echo(''); + mysqli_stmt_close($stmt); + $cnt2++; + } + + + + + ?> + +
".$data[0]."".$data[1]."".$data[2]."".$data[3]."".$data[4]."
+
+
+
+
+ + + diff --git a/sys0-code/app/webcam.php b/sys0-code/app/webcam.php new file mode 100644 index 0000000..70b7511 --- /dev/null +++ b/sys0-code/app/webcam.php @@ -0,0 +1,26 @@ + + + + + Webcam + + + + "); + ?> + + + + diff --git a/sys0-code/assets/images/ksw_logo.png b/sys0-code/assets/images/ksw_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..a3a1cd1da9e17be8cb601d9cf25444f64c35f440 GIT binary patch literal 48551 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 diff --git a/sys0-code/login/keepmeloggedin.php b/sys0-code/login/keepmeloggedin.php new file mode 100644 index 0000000..4694897 --- /dev/null +++ b/sys0-code/login/keepmeloggedin.php @@ -0,0 +1,64 @@ + diff --git a/sys0-code/login/login.php b/sys0-code/login/login.php new file mode 100644 index 0000000..ff8ed65 --- /dev/null +++ b/sys0-code/login/login.php @@ -0,0 +1,492 @@ +Hier ist dein System0 Account verifikations Link. Bitte klicke drauf. Sollte dies nicht funktionieren, kopiere bitte den Link und öffne Ihn in deinem Browser.
https://app.ksw3d.ch/login/verify_account.php?token=$token
Achtung: der Link funktioniert nur in dem gleichen Browser und Gerät, auf dem du deinen Account erstellt hast.

Vielen dank für dein Vertrauen in uns!
Code Camp 2024
"}]}' + +EOF; + exec($mail); + header("location: /login/login.php?mail_sent1"); + } + else{ + header("location: /login/login.php?mail_sent3"); + } + } +// Processing form data when form is submitted +if($_SERVER["REQUEST_METHOD"] == "POST" and $_GET["action"]=="login"){ + + // Check if username is empty + if(empty(trim($_POST["username"]))){ + $username_err = "Please enter username."; + } else{ + $username = trim($_POST["username"]); + } + + // Check if password is empty + if(empty(trim($_POST["password"]))){ + $password_err = "Please enter your password."; + } else{ + $password = trim($_POST["password"]); + } + + // Validate credentials + if(empty($username_err) && empty($password_err)){ + // Prepare a select statement + $sql = "SELECT id, username, password, role, color,banned,banned_reason ,telegram_id,notification_telegram,notification_mail FROM users WHERE username = ?"; + + if($stmt = mysqli_prepare($link, $sql)){ + // Bind variables to the prepared statement as parameters + mysqli_stmt_bind_param($stmt, "s", $param_username); + + // Set parameters + $param_username = htmlspecialchars($username); + + // Attempt to execute the prepared statement + if(mysqli_stmt_execute($stmt)){ + // Store result + mysqli_stmt_store_result($stmt); + + // Check if username exists, if yes then verify password + if(mysqli_stmt_num_rows($stmt) == 1){ + // Bind result variables + mysqli_stmt_bind_result($stmt, $id, $username, $hashed_password, $role,$color,$banned,$banned_reason,$telegram_id,$notification_telegram,$notification_mail); + if(mysqli_stmt_fetch($stmt)){ + if(password_verify($password, $hashed_password)){ + if($banned!=1) + { + // Password is correct, so start a new session + mysqli_stmt_close($stmt); + if(isset($_POST["keepmeloggedin"])) + { + $token=getSalt(); + $sql="UPDATE users SET keepmeloggedin=? WHERE username=?"; + if($stmt = mysqli_prepare($link, $sql)){ + $ptoken=""; + $pusername=""; + mysqli_stmt_bind_param($stmt, "ss", $ptoken,$pusername); + $ptoken=$token; + $pusername=$username; + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + } + else + echo("Error while setting 'keepmeloggedin'"); + + $cookie=$username.':'.$token; + $mac=hash("sha256",$cookie); + $cookie.=':'.$mac; + setcookie('keepmeloggedin',$cookie,time()+(3600*24*31)); + log_("Added keepmeloggedin token for $username","LOGIN:AUTOLOGIN"); + } + session_start(); + + // Store data in session variables + $_SESSION["loggedin"] = true; + $_SESSION["id"] = $id; + $_SESSION["username"] = $username; + $_SESSION["role"] = $role; + $_SESSION["token"]=bin2hex(random_bytes(32)); + $_SESSION["color"]=$color; + $_SESSION["creation_token"]= urlencode(bin2hex(random_bytes(24/2))); + $_SESSION["telegram_id"]=$telegram_id; + $_SESSION["notification_telegram"]=$notification_telegram; + $_SESSION["notification_mail"]=$notification_mail; + // Redirect user to welcome page + log_("$username logged in","LOGIN:SUCCESS"); + header("location:/app/overview.php"); + } + else + { + $_SESSION["verify"]=$username; + $login_err = "Dein Account wurde noch nicht aktiviert. Neuen aktivierungslink anfordern"; + } + } else{ + // Password is not valid, display a generic error message + $login_err = "Invalid username or password."; + log_("$username tried to log in with wrong Password","LOGIN:FAILURE"); + } + } + } else{ + // Username doesn't exist, display a generic error message + $login_err = "Invalid username or password."; + log_("$username tried to log in with non existant username","LOGIN:FAILURE"); + } + } else{ + echo "Oops! Something went wrong. Please try again later."; + log_("$username tried to log. Undefind failure","LOGIN:FAILURE"); + } + + // Close statement + mysqli_stmt_close($stmt); + } + } + + // Close connection + mysqli_close($link); +} +// Processing form data when form is submitted and user wants to create new user +if($_SERVER["REQUEST_METHOD"] == "POST" and $_GET["action"]=="create_user"){ + + // Validate username + if(empty(trim($_POST["username"]))){ + $err = "Please enter a username."; + } elseif(!preg_match('/^[a-zA-Z0-9_@.\-]+$/', trim($_POST["username"]))){ + $err = "Username can only contain letters, numbers, and underscores."; + } else{ + // Prepare a select statement + $sql = "SELECT id FROM users WHERE username = ?"; + + if($stmt = mysqli_prepare($link, $sql)){ + // Bind variables to the prepared statement as parameters + mysqli_stmt_bind_param($stmt, "s", $param_username); + + // Set parameters + $param_username = trim($_POST["username"]); + + // Attempt to execute the prepared statement + if(mysqli_stmt_execute($stmt)){ + /* store result */ + mysqli_stmt_store_result($stmt); + + if(mysqli_stmt_num_rows($stmt) == 1){ + $err = "This username is already taken."; + } else{ + $username = trim($_POST["username"]); + } + } else{ + echo "Oops! Something went wrong. Please try again later."; + } + + // Close statement + mysqli_stmt_close($stmt); + } + } + + // Validate password + if(empty(trim($_POST["password"]))){ + $err = "Please enter a password."; + } elseif(strlen(trim($_POST["password"])) < 6){ + $err = "Password must have atleast 6 characters."; + } + else if(strlen(trim($_POST["new_password"])) > 96) + { + $login_err = "Password cannot have more than 96 characters."; + } else{ + $password = trim($_POST["password"]); + } + + // Validate confirm password + if(empty(trim($_POST["confirm_password"]))){ + $err = "Please confirm password."; + } else{ + $confirm_password = trim($_POST["confirm_password"]); + if(empty($err) && ($password != $confirm_password)){ + $err = "Password did not match."; + } + } + // Validate kantimail + if(strpos($_POST["username"],"@kantiwattwil.ch")===false){ + $err = "Only members of KSW can access this site. (prename.name@kantiwattwil.ch)."; + } + // Check input errors before inserting in database + if(empty($err)){ + + // Prepare an insert statement + $sql = "INSERT INTO users (username, password, role,banned,banned_reason,notification_telegram,notification_mail) VALUES (?, ?, ?,?,?,?,?)"; + + if($stmt = mysqli_prepare($link, $sql)){ + // Bind variables to the prepared statement as parameters + $banned=1; + $banned_reason="Account muss zuerst verifiziert werden (Link in Mail)"; + $tel=0; + $mail=1; + mysqli_stmt_bind_param($stmt, "sssisii", $param_username, $param_password, $role,$banned,$banned_reason,$tel,$mail); + + // Set parameters + $param_username = $username; + $param_password = password_hash($password, PASSWORD_DEFAULT); // Creates a password hash + $role="11100000000"; + $banned=1; + $tel=0; + $mail=1; + $banned_reason="Account muss zuerst verifiziert werden (Link in Mail)"; + // Attempt to execute the prepared statement + if(mysqli_stmt_execute($stmt)){ + // Redirect to login page + if(!is_dir("../user_files/$username")) + mkdir("/var/www/html/user_files/$username"); + //create session token, which has account creation token inisde it. + $_SESSION["creation_token"]= urlencode(bin2hex(random_bytes(24/2))); + $token=$_SESSION["creation_token"]; + $_SESSION["verify"]=$username; + $_SESSION["email"]=$username; + //send the mail: + $mail=<<Hier ist dein System0 Account verifikations Link. Bitte klicke drauf. Sollte dies nicht funktionieren, kopiere bitte den Link und öffne Ihn in deinem Browser.
https://app.ksw3d.ch/login/verify_account.php?token=$token
Achtung: der Link funktioniert nur in dem gleichen Browser und Gerät, auf dem du deinen Account erstellt hast.

Vielen dank für dein Vertrauen in uns!
Code Camp 2024
"}]}' + +EOF; + + exec($mail); + + header("location: login.php?mail_sent1"); + } else{ + echo "Oops! Something went wrong. Please try again later."; + } + + // Close statement + mysqli_stmt_close($stmt); + + + + } + } + + // Close connection + mysqli_close($link); +} +if($_SERVER["REQUEST_METHOD"] == "POST" and $_GET["action"]=="reset_pw"){ + $email=htmlspecialchars($_POST["username"]); + $_SESSION["email"]=$email; + $_SESSION["pw_reset_token"]= urlencode(bin2hex(random_bytes(24 / 2))); + $token=$_SESSION["pw_reset_token"]; + $_SESSION["verify"]=$email; + $mail=<<Hier ist dein System0 Passwort Zurücksetzungs Link. Bitte klicke drauf. Sollte dies nicht funktionieren, kopiere bitte den Link und öffne Ihn in deinem Browser.
https://app.ksw3d.ch/login/reset_pw.php?token=$token
Achtung: der Link funktioniert nur in dem gleichen Browser und Gerät, auf dem du deinen Account erstellt hast.

Vielen dank für dein Vertrauen in uns!
Code Camp 2024
"}]}' +EOF; + + exec($mail); + header("location: login.php?mail_sent2"); +} +?> + + + + + + + + + Login + + + + + + + + +
+ Logo +
+
+
+
+
+

Login

+
+
+ + +
+
+ + +
+
+ + +
+ +
+
+ + +
+ ' . $login_err . '
'; + } + if(isset($_GET["mail_sent1"])) + echo '
Eine Mail mit einem Aktivierungslink wurde an deine Mailadresse gesendet.
'; + if(isset($_GET["mail_sent2"])) + echo '
Eine Mail mit einem Passwort zurücksetzungslink wurde an deine Mailadresse gesendet.
'; + if(isset($_GET["acc_verify_ok"])) + echo '
Email erfolgreich Verifiziert.
'; + if(isset($_GET["mail_sent3"])) + echo '
Eine Mail mit einem Passwort zurücksetzungslink konnte nich gesendet werden. Bitte melde dich beim Support hier.
'; + ?> +
+
+
+ + + + + + +"); + echo('const a=document.getElementById("lnk_1");'); + echo('a.click();'); + echo(""); + } + if(isset($_GET["resend_pw_reset"])){ + echo(""); + } + + ?> + + + + + diff --git a/sys0-code/login/logout.php b/sys0-code/login/logout.php new file mode 100644 index 0000000..cce0014 --- /dev/null +++ b/sys0-code/login/logout.php @@ -0,0 +1,14 @@ + diff --git a/sys0-code/login/reset-password.php b/sys0-code/login/reset-password.php new file mode 100644 index 0000000..3faffdf --- /dev/null +++ b/sys0-code/login/reset-password.php @@ -0,0 +1,185 @@ + 96) + { + $login_err = "Password cannot have more than 96 characters."; + } + else{ + $new_password = trim($_POST["new_password"]); + } + + // Validate confirm password + if(empty(trim($_POST["confirm_password"]))){ + $login_err = "Please confirm the password."; + } else{ + $confirm_password = trim($_POST["confirm_password"]); + if(empty($new_password_err) && ($new_password != $confirm_password)){ + $login_err = "Password did not match."; + } + } + + // Check input errors before updating the database + if(empty($login_err) ){ + // Prepare an update statement + $sql = "UPDATE users SET password = ? WHERE id = ?"; + + if($stmt = mysqli_prepare($link, $sql)){ + // Bind variables to the prepared statement as parameters + mysqli_stmt_bind_param($stmt, "si", $param_password, $param_id); + + // Set parameters + $param_password = password_hash($new_password, PASSWORD_DEFAULT); + $param_id = $_SESSION["id"]; + + // Attempt to execute the prepared statement + if(mysqli_stmt_execute($stmt)){ + // Password updated successfully. Destroy the session, and redirect to login page + session_destroy(); + header("location: login.php"); + exit(); + } else{ + echo "Oops! Something went wrong. Please try again later."; + } + + // Close statement + mysqli_stmt_close($stmt); + } + } + } + // Close connection + mysqli_close($link); +?> + + + + + + Passwort zurücksetzen + + + + "); ?> + + + +load_user()"; + + +echo("
");?> +
+
+

Passwort zurücksetzen

+
+
+
+ + + +
+
+ + +
+
+ + +
+ +
+
+ ' . $login_err . '
'; + } + ?> +
+ + + + diff --git a/sys0-code/login/reset_pw.php b/sys0-code/login/reset_pw.php new file mode 100644 index 0000000..b191eb2 --- /dev/null +++ b/sys0-code/login/reset_pw.php @@ -0,0 +1,134 @@ +"); +if($_GET["token"]!=$_SESSION["pw_reset_token"]){ + $login_err = "Dein Link ist entweder abgelaufen oder ungültig. Erzeuge einen neuen, in dem du auf diesen Link klickst."; + echo '
' . $login_err . '
'; + + //die(); +} + +// Processing form data when form is submitted +if($_SERVER["REQUEST_METHOD"] == "POST"){ + $login_err=""; + //first: validate old password + if(isset($_GET["token"])&&isset($_SESSION["pw_reset_token"])){ + if($_GET["token"]==$_SESSION["pw_reset_token"]){ + $auth=true; + } + else{ + $auth=false; + } + } + else{ $auth=false; } + if($auth===true) + { + //end of old_password validation + // Validate new password + if(empty(trim($_POST["new_password"]))){ + $login_err = "Please enter the new password."; + } elseif(strlen(trim($_POST["new_password"])) < 6){ + $login_err = "Password must have atleast 6 characters."; + }else if(strlen(trim($_POST["new_password"])) > 96) + { + $login_err = "Password cannot have more than 96 characters."; + } + else{ + $new_password = trim($_POST["new_password"]); + } + + // Validate confirm password + if(empty(trim($_POST["confirm_password"]))){ + $login_err = "Please confirm the password."; + } else{ + $confirm_password = trim($_POST["confirm_password"]); + if(empty($new_password_err) && ($new_password != $confirm_password)){ + $login_err = "Password did not match."; + } + } + + // Check input errors before updating the database + if(empty($login_err) ){ + // Prepare an update statement + $sql = "UPDATE users SET password = ? WHERE username = ?"; + + if($stmt = mysqli_prepare($link, $sql)){ + // Bind variables to the prepared statement as parameters + mysqli_stmt_bind_param($stmt, "ss", $param_password, $username); + + // Set parameters + $param_password = password_hash($new_password, PASSWORD_DEFAULT); + $username=$_SESSION["verify"]; + + // Attempt to execute the prepared statement + if(mysqli_stmt_execute($stmt)){ + // Password updated successfully. Destroy the session, and redirect to login page + $_SESSION["pw_reset_token"]=urlencode(bin2hex(random_bytes(24))); + session_destroy(); + header("location: login.php"); + exit(); + } else{ + echo "Oops! Something went wrong. Please try again later."; + } + + // Close statement + mysqli_stmt_close($stmt); + } + } + } + else{ + $login_err = "Dein Link ist entweder abgelaufen oder ungültig. Erzeuge einen neuen, in dem du auf diesen Link klickst."; + } + // Close connection + mysqli_close($link); +} +?> + + + + + + Passwort zurücksetzen + + + + ");?> + +
+
+

Passwort zurücksetzen

+
+
+
+ + +
+
+ + +
+ +
+
+ ' . $login_err . '
'; + } + ?> +
+ + + + diff --git a/sys0-code/login/verify_account.php b/sys0-code/login/verify_account.php new file mode 100644 index 0000000..66c7a08 --- /dev/null +++ b/sys0-code/login/verify_account.php @@ -0,0 +1,52 @@ +"); + include "../assets/components.php"; + ?> + + + "); + echo("
"); + session_start(); + include "../config/config.php"; + if(isset($_GET["token"])){ + if($_GET["token"]==$_SESSION["creation_token"]){ + $username=$_SESSION["verify"]; + $sql="update users set banned=0 where username='$username'"; + $stmt = mysqli_prepare($link, $sql); + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + header("LOCATION: /login/login.php?acc_verify_ok"); + }else{ + $login_err = "Dein Link ist entweder abgelaufen oder ungültig. Erzeuge einen neuen, in dem du auf diesen Link klickst."; + echo '
' . $login_err . '
'; + } + }else{ + $login_err = "Dein Link ist entweder abgelaufen oder ungültig. Erzeuge einen neuen, in dem du auf diesen Link klickst."; + echo '
' . $login_err . '
'; + } +?> diff --git a/sys0-code/waf/salt.php b/sys0-code/waf/salt.php new file mode 100644 index 0000000..9c8120b --- /dev/null +++ b/sys0-code/waf/salt.php @@ -0,0 +1,15 @@ +