diff --git a/app/page/Dashboard.php b/app/page/Dashboard.php
new file mode 100644
index 0000000..ab8e25d
--- /dev/null
+++ b/app/page/Dashboard.php
@@ -0,0 +1,26 @@
+config('domain')));
+ }
+
+ public function get(): void
+ {
+ $opensim = new OpenSim($this->app->db());
+ $this->app->template('dashboard-home.php')->parent('__dashboard.php')->vars([
+ 'title' => 'Dashboard',
+ 'username' => $_SESSION['DISPLAYNAME'],
+ 'global-user-count' => $opensim->getUserCount(),
+ 'global-region-count' => $opensim->getRegionCount()
+ ])->render();
+ }
+}
diff --git a/app/page/Error.php b/app/page/Error.php
new file mode 100644
index 0000000..7fe5b0c
--- /dev/null
+++ b/app/page/Error.php
@@ -0,0 +1,16 @@
+app->template('error.php')->parent('__presession.php')->vars([
+ 'title' => 'Seite nicht gefunden',
+ 'error-message' => 'Die gewünschte Seite wurde nicht gefunden.'
+ ])->render();
+ }
+}
diff --git a/app/page/ForgotPassword.php b/app/page/ForgotPassword.php
new file mode 100644
index 0000000..47e5ddc
--- /dev/null
+++ b/app/page/ForgotPassword.php
@@ -0,0 +1,89 @@
+ wir haben soeben eine Anfrage zur Zurücksetzung des Passworts für deinen 4Creative-Account erhalten. Klicke hier , um ein neues Passwort festzulegen. Dieser Link läuft in 24 Stunden ab. Falls du diese Anfrage nicht gesendet hast, ignoriere sie einfach. Bei weiteren Fragen kannst du uns unter info@4creative.net oder per Discord über @ikeytan erreichen.';
+
+ public function __construct(\Mcp\Mcp $app)
+ {
+ parent::__construct($app, new PreSessionMiddleware($app->config('domain')));
+ }
+
+ public function get(): void
+ {
+ $this->app->template('forgot.php')->parent('__presession.php')->vars([
+ 'title' => 'Passwort vergessen',
+ 'message-color' => 'red'
+ ])->render();
+ }
+
+ public function post(): void
+ {
+ $validator = new FormValidator(array(
+ 'username' => array('required' => true, 'regex' => '/^[^\\/<>\s]{1,64} [^\\/<>\s]{1,64}$/'),
+ 'email' => array('required' => true, 'regex' => '/^\S{1,64}@\S{1,250}.\S{2,64}$/')
+ ));
+ $tpl = $this->app->template('forgot.php')->parent('__presession.php')->var('title', 'Passwort vergessen');
+
+ if (!$validator->isValid($_POST)) {
+ $tpl->vars([
+ 'message' => 'Bitte gebe deinen Benutzernamen (Vor- und Nachname) und die dazugehörige E-Mail-Adresse ein',
+ 'message-color' => 'red'
+ ])->render();
+ } else {
+ $nameParts = explode(" ", $_POST['username']);
+ $email = strtolower(trim($_POST['email']));
+
+ $getAccount = $this->app->db()->prepare('SELECT Email,FirstName,LastName,PrincipalID FROM UserAccounts WHERE FirstName = ? AND LastName = ? AND Email = ?');
+ $getAccount->execute([trim($nameParts[0]), trim($nameParts[1]), $email]);
+ $validRequest = $getAccount->rowCount() == 1;
+ $uuid = null;
+ $name = null;
+ if ($res = $getAccount->fetch()) {
+ $email = $res['Email'];
+ $uuid = $res['PrincipalID'];
+ $name = $res['FirstName'].' '.$res['LastName'];
+ }
+
+ foreach ($this->app->config('reset-blocked-domains') as $domain) {
+ if (str_ends_with($email, $domain)) {
+ $validRequest = false;
+ }
+ }
+
+ $tpl->vars([
+ 'message' => 'Falls Name und E-Mail-Adresse bei uns registriert sind, erhältst du in Kürze eine E-Mail mit weiteren Informationen.',
+ 'message-color' => 'green'
+ ])->render();
+ fastcgi_finish_request();
+
+ if ($validRequest) {
+ $getReqTime = $this->app->db()->prepare('SELECT RequestTime FROM PasswordResetTokens WHERE PrincipalID=?');
+ $getReqTime->execute([$uuid]);
+ if (($res = $getReqTime->fetch()) && time() - $res['RequestTime'] < 900) {
+ return;
+ }
+
+ $token = Util::generateToken(32);
+ $setToken = $this->app->db()->prepare('REPLACE INTO PasswordResetTokens(PrincipalID,Token,RequestTime) VALUES(?,?,?)');
+ $setToken->execute([$uuid, $token, time()]);
+
+ $smtp = $this->app->config('smtp');
+ $tplMail = $this->app->template('mail.php')->vars([
+ 'title' => 'Dein Passwort zurücksetzen',
+ 'preheader' => 'So kannst du ein neues Passwort für deinen 4Creative-Account festlegen'
+ ])->unsafeVar('message', str_replace('%%NAME%%', $name, str_replace('%%RESET_LINK%%', 'https://'.$this->app->config('domain').'/index.php?page=reset-password&token='.$token, $this::MESSAGE)));
+ (new SmtpClient($smtp['host'], $smtp['port'], $smtp['address'], $smtp['password']))->sendHtml($smtp['address'], $smtp['name'], $email, 'Zurücksetzung des Passworts für '.$name, $tplMail);
+ }
+ }
+ }
+}
diff --git a/app/page/Friends.php b/app/page/Friends.php
new file mode 100644
index 0000000..9ea788a
--- /dev/null
+++ b/app/page/Friends.php
@@ -0,0 +1,66 @@
+config('domain')));
+ }
+
+ public function get(): void
+ {
+ $table = '
Name Optionen ';
+
+ $statement = $this->app->db()->prepare("SELECT PrincipalID,Friend FROM Friends WHERE PrincipalID = ? ORDER BY Friend ASC");
+ $statement->execute([$_SESSION['UUID']]);
+
+ $opensim = new OpenSim($this->app->db());
+
+ $csrf = $this->app->csrfField();
+ while ($row = $statement->fetch()) {
+ $friendData = explode(";", $row['Friend']);
+ $friend = $friendData[0];
+
+ $name = trim($opensim->getUserName($friend));
+ if (count($friendData) > 1) {
+ $friendData[1] = str_replace("http://", "", $friendData[1]);
+ $friendData[1] = str_replace("https://", "", $friendData[1]);
+ $friendData[1] = str_replace("/", "", $friendData[1]);
+ $name = $name.' @ '.strtolower($friendData[1]);
+ }
+
+ $table = $table.''.htmlspecialchars($name).' ';
+ }
+
+ $this->app->template('__dashboard.php')->vars([
+ 'title' => 'Deine Freunde',
+ 'username' => $_SESSION['DISPLAYNAME']
+ ])->unsafeVar('child-content', $table.'
')->render();
+ }
+
+ public function post(): void
+ {
+ if (isset($_POST['remove'])) {
+ $validator = new FormValidator(array(
+ 'uuid' => array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/')
+ ));
+
+ if ($validator->isValid($_POST)) {
+ $statementMembership = $this->app->db()->prepare("DELETE FROM Friends WHERE Friend = ? AND PrincipalID = ?");
+ $statementMembership->execute(array($_REQUEST['uuid'], $_SESSION['UUID']));
+
+ $statementMembership = $this->app->db()->prepare("DELETE FROM Friends WHERE PrincipalID = ? AND Friend = ?");
+ $statementMembership->execute(array($_REQUEST['uuid'], $_SESSION['UUID']));
+ }
+ }
+
+ header('Location: index.php?page=friends');
+ }
+}
diff --git a/app/page/Groups.php b/app/page/Groups.php
new file mode 100644
index 0000000..24386a1
--- /dev/null
+++ b/app/page/Groups.php
@@ -0,0 +1,52 @@
+config('domain')));
+ }
+
+ public function get(): void
+ {
+ $opensim = new OpenSim($this->app->db());
+
+ $table = 'Name Gründer Aktionen ';
+
+ $statementGroups = $this->app->db()->prepare("SELECT Name,FounderID,os_groups_membership.GroupID FROM os_groups_groups JOIN os_groups_membership ON os_groups_groups.GroupID = os_groups_membership.GroupID WHERE PrincipalID = ?");
+ $statementGroups->execute(array($_SESSION['UUID']));
+
+ $csrf = $this->app->csrfField();
+ while ($rowGroups = $statementGroups->fetch()) {
+ $table = $table.''.htmlspecialchars($rowGroups['Name']).' '.htmlspecialchars($opensim->getUserName($rowGroups['FounderID'])).' ';
+ }
+
+ $this->app->template('__dashboard.php')->vars([
+ 'title' => 'Gruppen',
+ 'username' => $_SESSION['DISPLAYNAME']
+ ])->unsafeVar('child-content', $table.'
')->render();
+ }
+
+ public function post(): void
+ {
+ if (isset($_POST['leave'])) {
+ $validator = new FormValidator(array(
+ 'group' => array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/')
+ ));
+
+ if ($validator->isValid($_POST)) {
+ $statementMembership = $this->app->db()->prepare("DELETE FROM os_groups_membership WHERE GroupID = ? AND PrincipalID = ?");
+ $statementMembership->execute(array($_REQUEST['group'], $_SESSION['UUID']));
+ }
+ }
+
+ header('Location: index.php?page=groups');
+ }
+}
diff --git a/app/page/Identities.php b/app/page/Identities.php
new file mode 100644
index 0000000..d30c7eb
--- /dev/null
+++ b/app/page/Identities.php
@@ -0,0 +1,147 @@
+config('domain')));
+ }
+
+ public function get(): void
+ {
+ $statementCheckForEntry = $this->app->db()->prepare("SELECT 1 FROM UserIdentitys WHERE PrincipalID = ? LIMIT 1");
+ $statementCheckForEntry->execute(array($_SESSION['UUID']));
+
+ if ($statementCheckForEntry->rowCount() == 0) {
+ $statement = $this->app->db()->prepare('INSERT INTO `UserIdentitys` (PrincipalID, IdentityID) VALUES (:PrincipalID, :IdentityID)');
+ $statement->execute(['PrincipalID' => $_SESSION['UUID'], 'IdentityID' => $_SESSION['UUID']]);
+ }
+
+ $table = 'Name Aktionen ';
+ $statement = $this->app->db()->prepare("SELECT IdentityID FROM UserIdentitys WHERE PrincipalID = ? ORDER BY IdentityID ASC");
+ $statement->execute(array($_SESSION['UUID']));
+
+ $opensim = new OpenSim($this->app->db());
+
+ $csrf = $this->app->csrfField();
+ while ($row = $statement->fetch()) {
+ if ($row['IdentityID'] == $_SESSION['UUID']) {
+ $entry = ''.htmlspecialchars(trim($opensim->getUserName($row['IdentityID']))).' Aktiv - ';
+ } else {
+ $entry = ''.htmlspecialchars(trim($opensim->getUserName($row['IdentityID']))).' ';
+ }
+
+ $table = $table.$entry;
+ }
+
+ $message = '';
+ if (isset($_SESSION['identities_err'])) {
+ $message = ''.$_SESSION['identities_err'].'
';
+ unset($_SESSION['identities_err']);
+ }
+
+ $this->app->template('identities.php')->parent('__dashboard.php')->vars([
+ 'title' => 'Identitäten',
+ 'username' => $_SESSION['DISPLAYNAME'],
+ 'message' => $message
+ ])->unsafeVar('ident-list', $table.'
')->render();
+ }
+
+ public function post(): void
+ {
+ if (isset($_POST['enableIdent'])) {
+ $validator = new FormValidator(array(
+ 'uuid' => array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/')
+ ));
+
+ if ($validator->isValid($_POST)) {
+ $statement = $this->app->db()->prepare("SELECT 1 FROM UserIdentitys WHERE PrincipalID = :PrincipalID AND IdentityID = :IdentityID LIMIT 1");
+ $statement->execute(['PrincipalID' => $_SESSION['UUID'], 'IdentityID' => $_POST['uuid']]);
+
+ $statementPresence = $this->app->db()->prepare("SELECT 1 FROM Presence WHERE UserID = :PrincipalID LIMIT 1");
+ $statementPresence->execute(['PrincipalID' => $_SESSION['UUID']]);
+
+ if ($statementPresence->rowCount() == 0) {
+ if ($statement->rowCount() == 1) {
+ $statementAuth = $this->app->db()->prepare('UPDATE auth SET UUID = :IdentityID WHERE UUID = :PrincipalID');
+ $statementAuth->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID']]);
+
+ $statementUserIdentitys = $this->app->db()->prepare('UPDATE UserIdentitys SET PrincipalID = :IdentityID WHERE PrincipalID = :PrincipalID');
+ $statementUserIdentitys->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID']]);
+
+ $statementFriends = $this->app->db()->prepare('UPDATE Friends SET PrincipalID = :IdentityID WHERE PrincipalID = :PrincipalID');
+ $statementFriends->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID']]);
+
+ //$statementReFriends = $this->app->db()->prepare('UPDATE Friends SET Friend = :IdentityID WHERE Friend = :PrincipalID');
+ //$statementReFriends->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID']]);
+
+ $statementInventoryFolders = $this->app->db()->prepare('UPDATE inventoryfolders SET agentID = :IdentityID WHERE agentID = :PrincipalID AND type != :InventarTyp');
+ $statementInventoryFolders->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID'], 'InventarTyp' => 46]);
+
+ $statementInventoryItems = $this->app->db()->prepare('UPDATE inventoryitems SET avatarID = :IdentityID WHERE avatarID = :PrincipalID');
+ $statementInventoryItems->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID']]);
+
+ $statementGroupMembership = $this->app->db()->prepare('UPDATE os_groups_membership SET PrincipalID = :IdentityID WHERE PrincipalID = :PrincipalID');
+ $statementGroupMembership->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID']]);
+
+ $statementGroupRoles = $this->app->db()->prepare('UPDATE os_groups_rolemembership SET PrincipalID = :IdentityID WHERE PrincipalID = :PrincipalID');
+ $statementGroupRoles->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID']]);
+
+ $statementGroupRoles = $this->app->db()->prepare('DELETE FROM Presence WHERE UserID = :PrincipalID');
+ $statementGroupRoles->execute(['PrincipalID' => $_SESSION['UUID']]);
+
+ $_SESSION['LOGIN'] = 'false';
+ session_destroy();
+ }
+ } else {
+ $_SESSION['identities_err'] = 'Du kannst die Identität nicht ändern, während du angemeldet bist. Bitte schließe den Viewer.';
+ }
+ }
+ } elseif (isset($_POST['createIdent'])) {
+ $validator = new FormValidator(array(
+ 'newName' => array('required' => true, 'regex' => '/^[^\\/<>\s]{1,64} [^\\/<>\s]{1,64}$/')
+ ));
+
+ if ($validator->isValid($_POST)) {
+ $avatarNameParts = explode(" ", trim($_POST['newName']));
+
+ if (count($avatarNameParts) == 2) {
+ $statement = $this->app->db()->prepare("SELECT 1 FROM UserAccounts WHERE FirstName = :FirstName AND LastName = :LastName LIMIT 1");
+ $statement->execute(['FirstName' => trim($avatarNameParts[0]), 'LastName' => trim($avatarNameParts[1])]);
+
+ if ($statement->rowCount() == 0) {
+ $avatarUUID = (new OpenSim($this->app->db()))->generateUuid();
+
+ $statementAccounts = $this->app->db()->prepare('INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created, UserLevel, UserFlags, UserTitle, active) VALUES (:PrincipalID, :ScopeID, :FirstName, :LastName, :Email, :ServiceURLs, :Created, :UserLevel, :UserFlags, :UserTitle, :active )');
+ $statementAccounts->execute(['PrincipalID' => $avatarUUID, 'ScopeID' => "00000000-0000-0000-0000-000000000000", 'FirstName' => $avatarNameParts[0], 'LastName' => $avatarNameParts[1], 'Email' => $_SESSION['EMAIL'], 'ServiceURLs' => "HomeURI= GatekeeperURI= InventoryServerURI= AssetServerURI= ", 'Created' => time(), 'UserLevel' => 0, 'UserFlags' => 0, 'UserTitle' => "", 'active' => 1]);
+
+ $statementUserIdentitys = $this->app->db()->prepare('INSERT INTO UserIdentitys (PrincipalID, IdentityID) VALUES (:PrincipalID, :IdentityID)');
+ $statementUserIdentitys->execute(['PrincipalID' => $_SESSION['UUID'], 'IdentityID' => $avatarUUID]);
+ } else {
+ $_SESSION['identities_err'] = 'Dieser Name ist schon in Benutzung.';
+ }
+ } else {
+ $_SESSION['identities_err'] = 'Der Name muss aus einem Vor und einem Nachnamen bestehen.';
+ }
+ }
+ }
+ elseif (isset($_POST['deleteIdent'])) {
+ $validator = new FormValidator(array(
+ 'uuid' => array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/')
+ ));
+
+ if ($validator->isValid($_POST)) {
+ (new OpenSim($this->app->db()))->deleteIdentity($_SESSION['UUID'], $_POST['uuid']);
+ }
+ }
+
+ header('Location: index.php?page=identities');
+ }
+}
diff --git a/app/page/Login.php b/app/page/Login.php
new file mode 100644
index 0000000..1f913e7
--- /dev/null
+++ b/app/page/Login.php
@@ -0,0 +1,93 @@
+config('domain')));
+ }
+
+ public function get(): void
+ {
+ $tpl = $this->app->template('login.php')->parent('__presession.php')->var('title', 'Login')->var('last-username', '');
+
+ if (isset($_SESSION) && isset($_SESSION['loginMessage'])) {
+ $tpl->vars([
+ 'message' => $_SESSION['loginMessage'],
+ 'message-color' => $_SESSION['loginMessageColor']
+ ]);
+ unset($_SESSION['loginMessage']);
+ unset($_SESSION['loginMessageColor']);
+ } else {
+ $tpl->vars([
+ 'message' => '',
+ 'message-color' => 'red'
+ ]);
+ }
+
+ $tpl->render();
+ }
+
+ public function post(): void
+ {
+ $validator = new FormValidator(array(
+ 'username' => array('required' => true, 'regex' => '/^[^\\/<>\s]{1,64} [^\\/<>\s]{1,64}$/'),
+ 'password' => array('required' => true, 'regex' => '/^.{1,1000}$/')
+ ));
+
+ $tpl = $this->app->template('login.php')->parent('__presession.php')->var('title', 'Login');
+ if (!$validator->isValid($_POST)) {
+ $tpl->vars([
+ 'message' => 'Bitte gebe Benutzername (Vor- und Nachname) und Passwort ein.',
+ 'message-color' => 'red',
+ 'last-username'=> ''
+ ])->render();
+ } else {
+ $statementUser = $this->app->db()->prepare("SELECT PrincipalID,FirstName,LastName,Email,UserLevel,passwordHash,passwordSalt FROM UserAccounts JOIN auth ON UserAccounts.PrincipalID = auth.UUID WHERE FirstName = ? AND LastName = ? LIMIT 1");
+ $statementUser->execute(explode(" ", trim($_POST['username'])));
+ $res = ['passwordHash' => '', 'passwordSalt' => ''];
+
+ if ($rowUser = $statementUser->fetch()) {
+ $res = $rowUser;
+ }
+
+ if (hash_equals(md5(md5($_POST['password']).":".$res['passwordSalt']), $res['passwordHash'])) {
+ session_abort();
+ session_set_cookie_params([
+ 'lifetime' => 86400,
+ 'path' => '/',
+ 'domain' => $this->app->config('domain'),
+ 'httponly' => true,
+ 'secure' => true,
+ 'samesite' => 'Strict'
+ ]);
+ session_start();
+ session_regenerate_id(true);
+ $_SESSION['FIRSTNAME'] = $rowUser['FirstName'];
+ $_SESSION['LASTNAME'] = $rowUser['LastName'];
+ $_SESSION['EMAIL'] = $rowUser['Email'];
+ $_SESSION['PASSWORD'] = $rowUser['passwordHash'];
+ $_SESSION['SALT'] = $rowUser['passwordSalt'];
+ $_SESSION['UUID'] = $rowUser['PrincipalID'];
+ $_SESSION['LEVEL'] = $rowUser['UserLevel'];
+ $_SESSION['DISPLAYNAME'] = strtoupper($rowUser['FirstName'].' '.$rowUser['LastName']);
+ $_SESSION['LOGIN'] = 'true';
+
+ header("Location: index.php?page=dashboard");
+ die();
+ }
+
+ $tpl->vars([
+ 'message' => 'Benutzername und/oder Passwort falsch.',
+ 'message-color' => 'red',
+ 'last-username' => $_POST['username']
+ ])->render();
+ }
+ }
+}
diff --git a/app/page/ManageUsers.php b/app/page/ManageUsers.php
new file mode 100644
index 0000000..255b534
--- /dev/null
+++ b/app/page/ManageUsers.php
@@ -0,0 +1,111 @@
+config('domain')));
+ }
+
+ public function get(): void
+ {
+ $table = 'Vorname Nachname Status Aktionen ';
+
+ // Only select current primary account
+ $statement = $this->app->db()->prepare("SELECT FirstName,LastName,UserLevel,PrincipalID FROM UserAccounts JOIN auth ON auth.UUID = UserAccounts.PrincipalID ORDER BY Created ASC");
+ $statement->execute();
+
+ $statementIdent = $this->app->db()->prepare("SELECT FirstName,LastName,UserLevel,IdentityID FROM UserIdentitys JOIN UserAccounts ON UserAccounts.PrincipalID = UserIdentitys.IdentityID WHERE UserIdentitys.PrincipalID = ? AND UserIdentitys.PrincipalID != UserIdentitys.IdentityID");
+ $csrf = $this->app->csrfField();
+ while ($row = $statement->fetch()) {
+ $entry = ''.htmlspecialchars($row['FirstName']).' '.htmlspecialchars($row['LastName']).' '.htmlspecialchars(strval($row['UserLevel'])).' ';
+ $statementIdent->execute([$row['PrincipalID']]);
+ while ($identRow = $statementIdent->fetch()) {
+ $entry = $entry.''.htmlspecialchars($identRow['FirstName']).' '.htmlspecialchars($identRow['LastName']).' '.htmlspecialchars(strval($identRow['UserLevel'])).' ';
+ }
+ $table = $table.$entry;
+ }
+
+ $tpl = $this->app->template('users.php')->parent('__dashboard.php')->var('title', 'Benutzer')->unsafeVar('user-list', $table.'
')
+ ->unsafeVar('users-message', isset($_SESSION['users-message']) ? $_SESSION['users-message'] : '')
+ ->unsafeVar('custom-css', ' ');
+
+ if (isset($_SESSION['users-message'])) {
+ $tpl->unsafeVar('users-message', $_SESSION['users-message']);
+ unset($_SESSION['users-message']);
+ }
+
+ if (isset($_SESSION['invite-id'])) {
+ $tpl->var('invite-link', 'https://'.$this->app->config('domain').'/index.php?page=register&code='.$_SESSION['invite-id']);
+ unset($_SESSION['invite-id']);
+ }
+
+ $tpl->render();
+ }
+
+ public function post(): void
+ {
+ if (isset($_POST['generateLink'])) {
+ $validator = new FormValidator(array()); // Needed only for CSRF token validation
+
+ if ($validator->isValid($_POST)) {
+ $inviteID = bin2hex(random_bytes(16));
+
+ $statement = $this->app->db()->prepare('INSERT INTO `InviteCodes` (`InviteCode`) VALUES (:InviteCode)');
+ $statement->execute(['InviteCode' => $inviteID]);
+
+ $_SESSION['invite-id'] = $inviteID;
+ }
+ } elseif (isset($_POST['delident'])) {
+ $validator = new FormValidator(array(
+ 'userid' => array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/'),
+ 'identid' => array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/')
+ ));
+
+ if ($validator->isValid($_POST)) {
+ $os = new OpenSim($this->app->db());
+ $identName = $os->getUserName($_POST['identid']);
+ $userName = $os->getUserName($_POST['userid']);
+ if ($os->deleteIdentity($_POST['userid'], $_POST['identid'])) {
+ $_SESSION['users-message'] = 'Identität '.$identName.' von '.$userName.' wurde gelöscht.';
+ } else {
+ $_SESSION['users-message'] = 'Identität '.$identName.' konnte nicht gelöscht werden.';
+ }
+ }
+ } else {
+ $validator = new FormValidator(array(
+ 'userid' => array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/')
+ ));
+
+ if ($validator->isValid($_POST)) {
+ $opensim = new OpenSim($this->app->db());
+ if (isset($_POST['genpw'])) {
+ $token = Util::generateToken(32);
+ $setToken = $this->app->db()->prepare('REPLACE INTO PasswordResetTokens(PrincipalID,Token,RequestTime) VALUES(?,?,?)');
+ $setToken->execute([$_POST['userid'], $token, time()]);
+ $resetLink = "https://".$this->app->config('domain').'/index.php?page=reset-password&token='.$token;
+
+ $_SESSION['users-message'] = 'Das Passwort für '.htmlspecialchars($opensim->getUserName($_POST['userid'])).' kann in den nächsten 24 Stunden über diesen Link zurückgesetzt werden: '.$resetLink.' ';
+ } elseif (isset($_POST['deluser'])) {
+ $name = $opensim->getUserName($_POST['userid']);
+ if ($opensim->deleteUser($_POST['userid'])) {
+ $_SESSION['users-message'] = 'Der Account '.$name.' wurde gelöscht.';
+ } else {
+ $_SESSION['users-message'] = 'Der Account '.$name.' konnte nicht gelöscht werden.';
+ }
+ }
+ }
+ }
+
+ header('Location: index.php?page=users');
+ }
+}
diff --git a/app/page/OnlineUsers.php b/app/page/OnlineUsers.php
new file mode 100644
index 0000000..7e18ef6
--- /dev/null
+++ b/app/page/OnlineUsers.php
@@ -0,0 +1,36 @@
+config('domain')));
+ }
+
+ public function get(): void
+ {
+ $opensim = new OpenSim($this->app->db());
+
+ $table = 'Benutzername Region ';
+
+ $statement = $this->app->db()->prepare("SELECT RegionID,UserID FROM Presence ORDER BY RegionID ASC");
+ $statement->execute();
+
+ while ($row = $statement->fetch()) {
+ if ($row['RegionID'] != "00000000-0000-0000-0000-000000000000") {
+ $table = $table.''.htmlspecialchars(trim($opensim->getUserName($row['UserID']))).' '.htmlspecialchars($opensim->getRegionName($row['RegionID'])).' ';
+ }
+ }
+
+ $this->app->template('__dashboard.php')->vars([
+ 'title' => 'Online Anzeige',
+ 'username' => $_SESSION['DISPLAYNAME']
+ ])->unsafeVar('child-content', $table.'
')->render();
+ }
+}
diff --git a/pages/profile.php b/app/page/Profile.php
similarity index 53%
rename from pages/profile.php
rename to app/page/Profile.php
index 97a77a2..c449e3a 100644
--- a/pages/profile.php
+++ b/app/page/Profile.php
@@ -1,38 +1,82 @@
prepare('SELECT 1 FROM UserAccounts WHERE '.$part.' = ? AND '.$otherPart.' = ?');
- $query->execute(array($value, $otherValue));
-
- if ($query->rowCount() == 0) {
- $statement = $RUNTIME['PDO']->prepare('UPDATE UserAccounts SET '.$part.' = ? WHERE PrincipalID = ?');
- $statement->execute(array($value, $_SESSION['UUID']));
- return true;
- }
-
- return false;
+ parent::__construct($app, new LoginRequiredMiddleware($app, $app->config('domain')));
}
- $statement = $RUNTIME['PDO']->prepare("CREATE TABLE IF NOT EXISTS `iarstates` (`userID` VARCHAR(36) NOT NULL COLLATE 'utf8_unicode_ci', `filesize` BIGINT(20) NOT NULL DEFAULT '0', `iarfilename` VARCHAR(64) NOT NULL COLLATE 'utf8_unicode_ci', `running` INT(1) NOT NULL DEFAULT '0', PRIMARY KEY (`userID`) USING BTREE) COLLATE='utf8_unicode_ci' ENGINE=InnoDB;");
- $statement->execute();
+ public function get(): void
+ {
+ $tpl = $this->app->template('profile.php')->parent('__dashboard.php');
- //Prüfe ob IAR grade erstellt wird.
- $statementIARCheck = $RUNTIME['PDO']->prepare('SELECT 1 FROM iarstates WHERE userID =:userID');
- $statementIARCheck->execute(['userID' => $_SESSION['UUID']]);
- $IARRUNNING = $statementIARCheck->rowCount() != 0;
- $statementIARCheck->closeCursor();
+ $statement = $this->app->db()->prepare("CREATE TABLE IF NOT EXISTS `iarstates` (`userID` VARCHAR(36) NOT NULL COLLATE 'utf8_unicode_ci', `filesize` BIGINT(20) NOT NULL DEFAULT '0', `iarfilename` VARCHAR(64) NOT NULL COLLATE 'utf8_unicode_ci', `running` INT(1) NOT NULL DEFAULT '0', PRIMARY KEY (`userID`) USING BTREE) COLLATE='utf8_unicode_ci' ENGINE=InnoDB;");
+ $statement->execute();
- if ($_SERVER['REQUEST_METHOD'] == 'POST') {
- include_once 'app/FormValidator.php';
+ //Prüfe ob IAR grade erstellt wird.
+ $statementIARCheck = $this->app->db()->prepare('SELECT 1 FROM iarstates WHERE userID =:userID');
+ $statementIARCheck->execute(['userID' => $_SESSION['UUID']]);
+ $iarRunning = $statementIARCheck->rowCount() != 0;
+ $statementIARCheck->closeCursor();
+
+ if ($iarRunning) {
+ if (isset($_SESSION['iar_created'])) {
+ $tpl->unsafeVar('iar-message', 'Deine IAR wird jetzt erstellt und der Download Link wird dir per PM zugesendet.
');
+ } else {
+ $tpl->unsafeVar('iar-message', 'Aktuell wird eine IAR erstellt. Warte bitte bis du eine PM bekommst.
');
+ }
+ $tpl->var('iar-button-state', 'disabled');
+ }
+ else {
+ $tpl->vars([
+ 'iar-message' => ' ',
+ 'iar-state' => ''
+ ]);
+ }
+
+ $opensim = new OpenSim($this->app->db());
+
+ $partnerUUID = $opensim->getPartner($_SESSION['UUID']);
+ $partnerName = "";
+
+ if ($partnerUUID != null) {
+ $partnerName = $opensim->getUserName($partnerUUID);
+ }
+
+ $profileInfo = '';
+ if (isset($_SESSION['profile_info'])) {
+ $profileInfo = $_SESSION['profile_info'];
+ unset($_SESSION['profile_info']);
+ }
+ $tpl->vars([
+ 'title' => 'Dein Profil',
+ 'offline-im-state' => $opensim->allowOfflineIM($_SESSION['UUID']) == "TRUE" ? ' checked' : ' ',
+ 'firstname' => $_SESSION['FIRSTNAME'],
+ 'lastname' => $_SESSION['LASTNAME'],
+ 'partner' => $partnerName,
+ 'email' => $opensim->getUserMail($_SESSION['UUID']),
+ 'residents-js-array' => '',
+ 'message' => $profileInfo
+ ])->render();
+ }
+
+ public function post(): void
+ {
if (isset($_POST['createIAR'])) {
$validator = new FormValidator(array()); // CSRF validation only
- if($validator->isValid($_POST) && !$IARRUNNING) {
+ if($validator->isValid($_POST)) {
$iarname = md5(time().$_SESSION['UUID'] . rand()).".iar";
- $statementIARSTART = $RUNTIME['PDO']->prepare('INSERT INTO iarstates (userID, filesize, iarfilename) VALUES (:userID, :filesize, :iarfilename)');
+ $statementIARSTART = $this->app->db()->prepare('INSERT INTO iarstates (userID, filesize, iarfilename) VALUES (:userID, :filesize, :iarfilename)');
$statementIARSTART->execute(['userID' => $_SESSION['UUID'], 'filesize' => 0, 'iarfilename' => $iarname]);
$_SESSION['iar_created'] = true;
@@ -49,11 +93,11 @@
if ($validator->isValid($_POST)) {
if(isset($_POST['formInputFeldVorname'])) {
- $NewFirstName = trim($_POST['formInputFeldVorname']);
+ $newFirstName = trim($_POST['formInputFeldVorname']);
- if($NewFirstName != "" && $_SESSION['FIRSTNAME'] != $NewFirstName) {
- if(setNamePart('FirstName', $NewFirstName, 'LastName', isset($_POST['formInputFeldNachname']) && strlen(trim($_POST['formInputFeldNachname'])) > 0 ? $_POST['formInputFeldNachname'] : $_SESSION['LASTNAME'])) {
- $_SESSION['FIRSTNAME'] = $NewFirstName;
+ if($newFirstName != "" && $_SESSION['FIRSTNAME'] != $newFirstName) {
+ if($this->setNamePart('FirstName', $newFirstName, 'LastName', isset($_POST['formInputFeldNachname']) && strlen(trim($_POST['formInputFeldNachname'])) > 0 ? $_POST['formInputFeldNachname'] : $_SESSION['LASTNAME'])) {
+ $_SESSION['FIRSTNAME'] = $newFirstName;
$_SESSION['USERNAME'] = $_SESSION['FIRSTNAME']." ".$_SESSION['LASTNAME'];
$_SESSION['DISPLAYNAME'] = strtoupper($_SESSION['USERNAME']);
}
@@ -64,11 +108,11 @@
}
if (isset($_POST['formInputFeldNachname'])) {
- $NewLastName = trim($_POST['formInputFeldNachname']);
+ $newLastName = trim($_POST['formInputFeldNachname']);
- if ($NewLastName != "" && $_SESSION['LASTNAME'] != $NewLastName) {
- if (setNamePart('LastName', $NewLastName, 'FirstName', isset($_POST['formInputFeldVorname']) && strlen(trim($_POST['formInputFeldVorname'])) > 0 ? $_POST['formInputFeldVorname'] : $_SESSION['FIRSTNAME'])) {
- $_SESSION['LASTNAME'] = $NewLastName;
+ if ($newLastName != "" && $_SESSION['LASTNAME'] != $newLastName) {
+ if ($this->setNamePart('LastName', $newLastName, 'FirstName', isset($_POST['formInputFeldVorname']) && strlen(trim($_POST['formInputFeldVorname'])) > 0 ? $_POST['formInputFeldVorname'] : $_SESSION['FIRSTNAME'])) {
+ $_SESSION['LASTNAME'] = $newLastName;
$_SESSION['USERNAME'] = $_SESSION['FIRSTNAME']." ".$_SESSION['LASTNAME'];
$_SESSION['DISPLAYNAME'] = strtoupper($_SESSION['USERNAME']);
} else {
@@ -78,47 +122,46 @@
}
if (isset($_POST['formInputFeldEMail'])) {
- $NewEMail = trim($_POST['formInputFeldEMail']);
+ $newEmail = trim($_POST['formInputFeldEMail']);
- if ($NewEMail != "" && $_SESSION['EMAIL'] != $NewEMail) {
- $statement = $RUNTIME['PDO']->prepare('UPDATE UserAccounts SET Email = :Email WHERE PrincipalID = :PrincipalID');
- $statement->execute(['Email' => $NewEMail, 'PrincipalID' => $_SESSION['UUID']]);
+ if ($newEmail != "" && $_SESSION['EMAIL'] != $newEmail) {
+ $statement = $this->app->db()->prepare('UPDATE UserAccounts SET Email = :Email WHERE PrincipalID = :PrincipalID');
+ $statement->execute(['Email' => $newEmail, 'PrincipalID' => $_SESSION['UUID']]);
- $statement = $RUNTIME['PDO']->prepare('UPDATE usersettings SET email = :Email WHERE useruuid = :PrincipalID');
- $statement->execute(['Email' => $NewEMail, 'PrincipalID' => $_SESSION['UUID']]);
+ $statement = $this->app->db()->prepare('UPDATE usersettings SET email = :Email WHERE useruuid = :PrincipalID');
+ $statement->execute(['Email' => $newEmail, 'PrincipalID' => $_SESSION['UUID']]);
- $_SESSION['EMAIL'] = $NewEMail;
+ $_SESSION['EMAIL'] = $newEmail;
}
}
if (isset($_POST['formInputFeldOfflineIM']) && $_POST['formInputFeldOfflineIM'] == "on") {
- $statement = $RUNTIME['PDO']->prepare('UPDATE usersettings SET imviaemail = :IMState WHERE useruuid = :PrincipalID');
+ $statement = $this->app->db()->prepare('UPDATE usersettings SET imviaemail = :IMState WHERE useruuid = :PrincipalID');
$statement->execute(['IMState' => 'true', 'PrincipalID' => $_SESSION['UUID']]);
} else {
- $statement = $RUNTIME['PDO']->prepare('UPDATE usersettings SET imviaemail = :IMState WHERE useruuid = :PrincipalID');
+ $statement = $this->app->db()->prepare('UPDATE usersettings SET imviaemail = :IMState WHERE useruuid = :PrincipalID');
$statement->execute(['IMState' => 'false', 'PrincipalID' => $_SESSION['UUID']]);
}
if (isset($_POST['formInputFeldPartnerName']) && $_POST['formInputFeldPartnerName'] != "") {
- include_once 'app/OpenSim.php';
- $opensim = new OpenSim();
+ $opensim = new OpenSim($this->app->db());
- $NewPartner = trim($_POST['formInputFeldPartnerName']);
- $CurrentPartner = $opensim->getPartner($_SESSION['UUID']);
+ $newPartner = trim($_POST['formInputFeldPartnerName']);
+ $currentPartner = $opensim->getPartner($_SESSION['UUID']);
- if ($CurrentPartner != "") {
- $CurrentPartner = $opensim->getUserName($CurrentPartner);
+ if ($currentPartner != "") {
+ $currentPartner = $opensim->getUserName($currentPartner);
}
- if ($NewPartner != "" && $CurrentPartner != $NewPartner) {
- $newPartnerUUID = $opensim->getUserUUID($NewPartner);
+ if ($newPartner != "" && $currentPartner != $newPartner) {
+ $newPartnerUUID = $opensim->getUserUUID($newPartner);
if ($newPartnerUUID != null) {
- $statement = $RUNTIME['PDO']->prepare('UPDATE userprofile SET profilePartner = :profilePartner WHERE useruuid = :PrincipalID');
+ $statement = $this->app->db()->prepare('UPDATE userprofile SET profilePartner = :profilePartner WHERE useruuid = :PrincipalID');
$statement->execute(['profilePartner' => $newPartnerUUID, 'PrincipalID' => $_SESSION['UUID']]);
}
} else {
- $statement = $RUNTIME['PDO']->prepare('UPDATE userprofile SET profilePartner = :profilePartner WHERE useruuid = :PrincipalID');
+ $statement = $this->app->db()->prepare('UPDATE userprofile SET profilePartner = :profilePartner WHERE useruuid = :PrincipalID');
$statement->execute(['profilePartner' => '00000000-0000-0000-0000-000000000000', 'PrincipalID' => $_SESSION['UUID']]);
}
}
@@ -132,11 +175,11 @@
if ($validator->isValid($_POST)) {
if ($_POST['newPasswordRepeat'] == $_POST['newPassword']) {
- if (strlen(trim($_POST['newPassword'])) >= $RUNTIME['PASSWORD_MIN_LENGTH']) {
+ if (strlen(trim($_POST['newPassword'])) >= $this->app->config('password-min-length')) {
if (md5(md5($_POST['oldPassword']).':'.$_SESSION['SALT']) == $_SESSION['PASSWORD']) {
$salt = bin2hex(random_bytes(16));
$hash = md5(md5(trim($_POST['newPassword'])).':'.$salt);
- $statement = $RUNTIME['PDO']->prepare('UPDATE auth SET passwordHash = :PasswordHash, passwordSalt = :PasswordSalt WHERE UUID = :PrincipalID');
+ $statement = $this->app->db()->prepare('UPDATE auth SET passwordHash = :PasswordHash, passwordSalt = :PasswordSalt WHERE UUID = :PrincipalID');
$statement->execute(['PasswordHash' => $hash, 'PasswordSalt' => $salt, 'PrincipalID' => $_SESSION['UUID']]);
$_SESSION['PASSWORD'] = $hash;
$_SESSION['SALT'] = $salt;
@@ -145,7 +188,7 @@
$_SESSION['profile_info'] = 'Das alte Passwort ist nicht richtig!';
}
} else {
- $_SESSION['profile_info'] = 'Das neue Passwort muss mindestens '.$RUNTIME['PASSWORD_MIN_LENGTH'].' Zeichen lang sein.';
+ $_SESSION['profile_info'] = 'Das neue Passwort muss mindestens '.$this->app->config('password-min-length').' Zeichen lang sein.';
}
} else {
$_SESSION['profile_info'] = 'Die neuen Passwörter stimmen nicht überein!';
@@ -161,9 +204,7 @@
if ($validator->isValid($_POST)) {
if (hash_equals(md5(md5($_POST['delete-confirm-password']).':'.$_SESSION['SALT']), $_SESSION['PASSWORD'])) {
- $uuid = $_SESSION['UUID'];
- include_once 'app/OpenSim.php';
- $os = new OpenSim();
+ $os = new OpenSim($this->app->db());
if ($os->deleteUser($_SESSION['UUID'])) {
$_SESSION['LOGIN'] = false;
session_destroy();
@@ -183,52 +224,21 @@
}
header('Location: index.php?page=profile');
- die();
}
- $HTML->setHTMLTitle("Dein Profile");
- $HTML->importSeitenInhalt("profile.html");
+ private function setNamePart(string $part, string $value, string $otherPart, string $otherValue): bool
+ {
+ global $RUNTIME;
- if ($IARRUNNING) {
- if (isset($_SESSION['iar_created'])) {
- $HTML->ReplaceSeitenInhalt("%%IARINFOMESSAGE%%", 'Deine IAR wird jetzt erstellt und der Download Link wird dir per PM zugesendet.'.$APIResult.'
');
- unset($_SESSION['iar_created']);
- } else {
- $HTML->ReplaceSeitenInhalt("%%IARINFOMESSAGE%%", 'Aktuell wird eine IAR erstellt. Warte bitte bis du eine PM bekommst.
');
+ $query = $RUNTIME['PDO']->prepare('SELECT 1 FROM UserAccounts WHERE '.$part.' = ? AND '.$otherPart.' = ?');
+ $query->execute(array($value, $otherValue));
+
+ if ($query->rowCount() == 0) {
+ $statement = $RUNTIME['PDO']->prepare('UPDATE UserAccounts SET '.$part.' = ? WHERE PrincipalID = ?');
+ $statement->execute(array($value, $_SESSION['UUID']));
+ return true;
}
- $HTML->ReplaceSeitenInhalt("%%IARBUTTONSTATE%%", 'disabled');
+
+ return false;
}
-
- include_once 'app/OpenSim.php';
- $opensim = new OpenSim();
-
- $PartnerUUID = $opensim->getPartner($_SESSION['UUID']);
- $PartnerName = "";
-
- if ($PartnerUUID != null) {
- $PartnerName = $opensim->getUserName($PartnerUUID);
- }
-
- if ($opensim->allowOfflineIM($_SESSION['UUID']) == "TRUE") {
- $HTML->ReplaceSeitenInhalt("%%offlineIMSTATE%%", ' checked');
- }
-
- $HTML->ReplaceSeitenInhalt("%%offlineIMSTATE%%", ' ');
- $HTML->ReplaceSeitenInhalt("%%firstname%%", htmlspecialchars($_SESSION['FIRSTNAME']));
- $HTML->ReplaceSeitenInhalt("%%lastname%%", htmlspecialchars($_SESSION['LASTNAME']));
- $HTML->ReplaceSeitenInhalt("%%partner%%", htmlspecialchars($PartnerName));
- $HTML->ReplaceSeitenInhalt("%%email%%", htmlspecialchars($opensim->getUserMail($_SESSION['UUID'])));
- $HTML->ReplaceSeitenInhalt("%%listAllResidentsAsJSArray%%", "");
-
- $profileInfo = '';
- if (isset($_SESSION['profile_info'])) {
- $profileInfo = $_SESSION['profile_info'];
- unset($_SESSION['profile_info']);
- }
- $HTML->ReplaceSeitenInhalt("%%INFOMESSAGE%%", $profileInfo);
-
- $HTML->ReplaceSeitenInhalt("%%IARINFOMESSAGE%%", ' ');
- $HTML->ReplaceSeitenInhalt("%%IARBUTTONSTATE%%", '');
-
- $HTML->build();
- echo $HTML->ausgabe();
+}
diff --git a/app/page/Regions.php b/app/page/Regions.php
new file mode 100644
index 0000000..25447c1
--- /dev/null
+++ b/app/page/Regions.php
@@ -0,0 +1,93 @@
+config('domain')) : new LoginRequiredMiddleware($app, $app->config('domain')));
+ }
+
+ public function get(): void
+ {
+ $table = 'Region Name Eigentümer Position Aktionen ';
+
+ $showAll = isset($_GET['SHOWALL']) && $_GET['SHOWALL'] == "1";
+ $statement = $this->app->db()->prepare("SELECT uuid,regionName,owner_uuid,locX,locY FROM regions ".($showAll ? "ORDER BY owner_uuid ASC" : "WHERE owner_uuid = ? ORDER BY uuid ASC"));
+ $statement->execute($showAll ? array() : array($_SESSION['UUID']));
+
+ $opensim = new OpenSim($this->app->db());
+
+ $csrf = $this->app->csrfField();
+ while ($row = $statement->fetch()) {
+ $stats = $this->getRegionStatsData($row['uuid']);
+ $table = $table.''.htmlspecialchars($row['regionName']).' '.htmlspecialchars($opensim->getUserName($row['owner_uuid'])).' '.Util::fillString(($row['locX'] / 256), 4).' / '.Util::fillString(($row['locY'] / 256), 4).' ';
+ }
+
+ $this->app->template('__dashboard.php')->vars([
+ 'title' => isset($_GET["SHOWALL"]) ? 'Regionen verwalten' : 'Deine Regionen',
+ 'username' => $_SESSION['DISPLAYNAME']
+ ])->unsafeVar('child-content', $table.'
')->render();
+ }
+
+ public function post(): void
+ {
+ $validator = new FormValidator(array(
+ 'remove' => array('required' => true),
+ 'region' => array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/')
+ ));
+
+ if ($validator->isValid($_POST)) {
+ if (isset($_GET['SHOWALL'])) {
+ $statementMembership = $this->app->db()->prepare("DELETE FROM regions WHERE uuid = ?");
+ $statementMembership->execute(array($_POST['region']));
+ } else {
+ $statementMembership = $this->app->db()->prepare("DELETE FROM regions WHERE uuid = ? AND owner_uuid = ?");
+ $statementMembership->execute(array($_POST['region'], $_SESSION['UUID']));
+ }
+ }
+
+ header('Location: index.php?page=regions');
+ }
+
+ private function cleanSize($bytes)
+ {
+ if ($bytes > 0) {
+ $unit = intval(log($bytes, 1024));
+ $units = array('B', 'KB', 'MB', 'GB');
+
+ if (array_key_exists($unit, $units) === true) {
+ return sprintf('%d %s', $bytes / pow(1024, $unit), $units[$unit]);
+ }
+ }
+
+ return $bytes;
+ }
+
+ private function getRegionStatsData($regionID)
+ {
+ $statement = $this->app->db()->prepare("SELECT Prims,SimFPS,PhyFPS,ProcMem,RegionVersion FROM regions_info WHERE regionID = ?");
+ $statement->execute([$regionID]);
+
+ if ($row = $statement->fetch()) {
+ $return = array();
+ $return['Prims'] = $row['Prims'];
+ $return['SimFPS'] = $row['SimFPS'];
+ $return['PhyFPS'] = $row['PhyFPS'];
+ $return['ProcMem'] = $this->cleanSize(str_replace(".", "", str_replace(",", ".", $row['ProcMem']))."000");
+ $return['RegionVersion'] = trim($row['RegionVersion']);
+
+ return $return;
+ }
+
+ return array();
+ }
+}
diff --git a/app/page/Register.php b/app/page/Register.php
new file mode 100644
index 0000000..d0986b6
--- /dev/null
+++ b/app/page/Register.php
@@ -0,0 +1,182 @@
+config('domain')));
+ }
+
+ public function get(): void
+ {
+ if ($this->checkInvite()) {
+ $this->displayPage();
+ }
+ }
+
+ public function post(): void
+ {
+ $validator = new FormValidator(array(
+ 'tos' => array('required' => true, 'equals' => 'on'),
+ 'username' => array('required' => true, 'regex' => '/^[^\\/<>\s]{1,64}( [^\\/<>\s]{1,64})?$/'),
+ 'password' => array('required' => true, 'regex' => '/^.{1,1000}$/'),
+ 'email' => array('required' => true, 'regex' => '/^\S{1,64}@\S{1,250}.\S{2,64}$/'),
+ 'avatar' => array('required' => true)
+ ));
+
+ if (!$validator->isValid($_POST)) {
+ if (!isset($_POST['tos']) || $_POST['tos'] !== true) {
+ $this->displayPage("Du musst die Nutzungsbedingungen lesen und Akzeptieren.");
+ } else {
+ $this->displayPage("Ups da stimmt was nicht. Versuche es bitte noch mal.");
+ }
+
+ return;
+ }
+
+ $name = trim($_POST['username']);
+ $nameParts = explode(" ", $name);
+ if ($name != "") {
+ if (count($nameParts) == 1) {
+ $name .= " Resident";
+ $nameParts = explode(" ", $name);
+ }
+
+ $statementAvatarName = $this->app->db()->prepare("SELECT 1 FROM UserAccounts WHERE FirstName = :FirstName AND LastName = :LastName LIMIT 1");
+ $statementAvatarName->execute(['FirstName' => $nameParts[0], 'LastName' => $nameParts[1]]);
+ if ($statementAvatarName->rowCount() > 0) {
+ $this->displayPage("Der gewählte Name ist bereits vergeben.");
+ }
+ }
+
+ $pass = trim($_POST['password']);
+ if (strlen($pass) < $this->app->config('password-min-length')) {
+ $this->displayPage('Dein Passwort muss mindestens '.$this->app->config('password-min-length').' Zeichen lang sein.');
+ }
+
+ $email = trim($_POST['email']);
+
+ $avatar = null;
+ if (isset($this->app->config('default-avatar')[$_POST['avatar']]['UUID'])) {
+ $avatar = trim($_POST['avatar']);
+ } else {
+ $this->displayPage("Der gewählte Standardavatar existiert nicht.");
+ }
+
+ $opensim = new OpenSim($this->app->db());
+
+ $avatarUUID = $opensim->generateUuid();
+ $salt = bin2hex(random_bytes(16));
+ $passwordHash = md5(md5($pass).':'.$salt);
+
+ $statementInviteDeleter = $this->app->db()->prepare('DELETE FROM InviteCodes WHERE InviteCode = :code');
+ $statementInviteDeleter->execute(['code' => $_REQUEST['code']]);
+ if ($statementInviteDeleter->rowCount() == 0) {
+ $this->displayError("Der angegebene Einladungscode ist nicht mehr gültig.");
+ }
+
+ try {
+ $this->app->db()->beginTransaction();
+
+ $statementAuth = $this->app->db()->prepare('INSERT INTO `auth` (`UUID`, `passwordHash`, `passwordSalt`, `webLoginKey`, `accountType`) VALUES (:UUID, :HASHVALUE, :SALT, :WEBKEY, :ACCTYPE)');
+ $statementAuth->execute(['UUID' => $avatarUUID, 'HASHVALUE' => $passwordHash, 'SALT' => $salt, 'WEBKEY' => "00000000-0000-0000-0000-000000000000", 'ACCTYPE' => "UserAccount"]);
+
+ $statementAccounts = $this->app->db()->prepare('INSERT INTO `UserAccounts` (`PrincipalID`, `ScopeID`, `FirstName`, `LastName`, `Email`, `ServiceURLs`, `Created`, `UserLevel`, `UserFlags`, `UserTitle`, `active`) VALUES (:PrincipalID, :ScopeID, :FirstName, :LastName, :Email, :ServiceURLs, :Created, :UserLevel, :UserFlags, :UserTitle, :active )');
+ $statementAccounts->execute(['PrincipalID' => $avatarUUID, 'ScopeID' => "00000000-0000-0000-0000-000000000000", 'FirstName' => $nameParts[0], 'LastName' => $nameParts[1], 'Email' => $email, 'ServiceURLs' => "HomeURI= GatekeeperURI= InventoryServerURI= AssetServerURI= ", 'Created' => time(), 'UserLevel' => 0, 'UserFlags' => 0, 'UserTitle' => "", 'active' => 1]);
+
+ $statementProfile = $this->app->db()->prepare('INSERT INTO `userprofile` (`useruuid`, `profilePartner`, `profileImage`, `profileURL`, `profileFirstImage`, `profileAllowPublish`, `profileMaturePublish`, `profileWantToMask`, `profileWantToText`, `profileSkillsMask`, `profileSkillsText`, `profileLanguages`, `profileAboutText`, `profileFirstText`) VALUES (:useruuid, :profilePartner, :profileImage, :profileURL, :profileFirstImage, :profileAllowPublish, :profileMaturePublish, :profileWantToMask, :profileWantToText, :profileSkillsMask, :profileSkillsText, :profileLanguages, :profileAboutText, :profileFirstText)');
+ $statementProfile->execute(['useruuid' => $avatarUUID, 'profilePartner' => "00000000-0000-0000-0000-000000000000", 'profileImage' => "00000000-0000-0000-0000-000000000000", 'profileURL' => '', 'profileFirstImage' => "00000000-0000-0000-0000-000000000000", "profileAllowPublish" => "0", "profileMaturePublish" => "0", "profileWantToMask" => "0", "profileWantToText" => "", "profileSkillsMask" => "0", "profileSkillsText" => "", "profileLanguages" => "", "profileAboutText" => "", "profileFirstText" => ""]);
+
+ $statementInventoryFolder = $this->app->db()->prepare('INSERT INTO `inventoryfolders` (`folderName`, `type`, `version`, `folderID`, `agentID`, `parentFolderID`) VALUES (:folderName, :folderTyp, :folderVersion, :folderID, :agentID, :parentFolderID)');
+ $inventory = array('Calling Cards' => 2, 'Objects' => 6, 'Landmarks' => 3, 'Clothing' => 5, 'Gestures' => 21, 'Body Parts' => 13, 'Textures' => 0, 'Scripts' => 10, 'Photo Album' => 15, 'Lost And Found' => 16, 'Trash' => 14, 'Notecards' => 7, 'My Inventory' => 8, 'Sounds' => 1, 'Animations' => 20);
+ $inventoryRootFolder = $opensim->generateUuid();
+ foreach ($inventory as $folderName => $inventoryType) {
+ $folderUUID = $opensim->generateUuid();
+ if ($inventoryType == 8) {
+ $folderUUID = $inventoryRootFolder;
+ $folderParent = "00000000-0000-0000-0000-000000000000";
+ } else {
+ $folderParent = $inventoryRootFolder;
+ }
+ $statementInventoryFolder->execute(['agentID' => $avatarUUID, 'folderName' => $folderName, 'folderTyp' => $inventoryType, 'folderVersion' => 1, 'folderID' => $folderUUID, 'parentFolderID' => $folderParent]);
+ }
+
+ $this->app->db()->commit();
+ } catch (Exception $pdoException) {
+ $this->app->db()->rollBack();
+ error_log('Could not create Account: '.$pdoException->getMessage());
+ $this->displayPage('Fehler bei der Erstellung deines Accounts. Bitte versuche es später erneut.');
+ }
+
+ session_abort();
+ session_set_cookie_params([
+ 'lifetime' => 86400,
+ 'path' => '/',
+ 'domain' => $this->app->config('domain'),
+ 'httponly' => true,
+ 'secure' => true,
+ 'samesite' => 'Strict'
+ ]);
+ session_start();
+ session_regenerate_id(true);
+ $_SESSION['FIRSTNAME'] = trim($nameParts[0]);
+ $_SESSION['LASTNAME'] = trim($nameParts[1]);
+ $_SESSION['EMAIL'] = $email;
+ $_SESSION['PASSWORD'] = $passwordHash;
+ $_SESSION['SALT'] = $salt;
+ $_SESSION['UUID'] = $avatarUUID;
+ $_SESSION['LEVEL'] = 0;
+ $_SESSION['DISPLAYNAME'] = strtoupper($name);
+ $_SESSION['LOGIN'] = 'true';
+
+ header('Location: index.php?page=dashboard');
+ }
+
+ private function displayPage(string $message = ''): void
+ {
+ $this->app->template('register.php')->parent('__presession.php')->vars([
+ 'title' => 'Registrieren',
+ 'message' => $message,
+ 'tos-url' => $this->app->config('tos-url'),
+ 'invcode' => $_REQUEST['code']
+ ])->render();
+ }
+
+ private function displayError(string $message): void
+ {
+ $this->app->template('error.php')->parent('__presession.php')->vars([
+ 'error-message' => $message,
+ 'title' => 'Fehler'
+ ])->render();
+ }
+
+ private function checkInvite(): bool
+ {
+ if (!isset($_REQUEST['code'])) {
+ $this->displayError("Du benötigst einen Einladungscode, um dich bei 4Creative zu registrieren.");
+ } elseif (strlen($_REQUEST['code']) != 32 || !preg_match('/^[a-f0-9]+$/', $_REQUEST['code'])) {
+ $this->displayError("Der angegebene Einladungscode ist nicht gültig. Nutze genau den Link, der dir zugeschickt wurde.");
+ } else {
+ $statementInviteCode = $this->app->db()->prepare("SELECT 1 FROM InviteCodes WHERE InviteCode = ? LIMIT 1");
+ $statementInviteCode->execute([$_REQUEST['code']]);
+
+ if ($statementInviteCode->rowCount() == 0) {
+ $this->displayError("Der angegebene Einladungscode ist nicht gültig. Nutze genau den Link, der dir zugeschickt wurde.");
+ return false;
+ }
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/app/page/ResetPassword.php b/app/page/ResetPassword.php
new file mode 100644
index 0000000..c7aa0f2
--- /dev/null
+++ b/app/page/ResetPassword.php
@@ -0,0 +1,110 @@
+ das Passwort für deinen 4Creative-Account wurde soeben über die Funktion "Passwort vergessen" geändert. Solltest du diese Änderung nicht selbst durchgeführt haben, wende dich bitte umgehend per E-Mail (info@4creative.net) oder Discord (@ikeytan) an uns.';
+ private const TOKEN_INVALID = 'Dieser Link zur Passwortzurücksetzung ist nicht gültig. Bitte klicke oder kopiere den Link aus der E-Mail, die du erhalten hast.';
+ private const TOKEN_EXPIRED = 'Dein Link zur Passwortzurücksetzung ist abgelaufen. Klicke hier , um eine neue Anfrage zu senden.';
+
+ public function __construct(\Mcp\Mcp $app)
+ {
+ parent::__construct($app, new PreSessionMiddleware($app->config('domain')));
+ }
+
+ public function get(): void
+ {
+ $this->displayPage();
+ }
+
+ public function post(): void
+ {
+ $validator = new FormValidator(array(
+ 'password' => array('required' => true, 'regex' => '/^.{1,1000}$/'),
+ 'passwordRepeat' => array('required' => true, 'regex' => '/^.{1,1000}$/'),
+ 'resetToken' => array('required' => true, 'regex' => '/^[a-zA-Z0-9]{32}$/')
+ ));
+
+ if ($validator->isValid($_POST)) {
+ if ($_POST['password'] !== $_POST['passwordRepeat']) {
+ $this->displayPage('Du musst in beiden Feldern das gleiche Passwort eingeben');
+ return;
+ }
+
+ if (strlen($_POST['password']) < $this->app->config('password-min-length')) {
+ $this->displayPage('Dein Passwort muss mindestens '.$this->app->config('password-min-length').' Zeichen lang sein.');
+ return;
+ }
+
+ $getReq = $this->app->db()->prepare('SELECT UserAccounts.PrincipalID AS UUID,FirstName,LastName,Email,Token,RequestTime FROM PasswordResetTokens JOIN UserAccounts ON UserAccounts.PrincipalID = PasswordResetTokens.PrincipalID WHERE Token = ?');
+ $getReq->execute([$_POST['resetToken']]);
+ $res = $getReq->fetch();
+
+ if (!$res || !hash_equals($res['Token'], $_POST['resetToken'])) {
+ $this->displayTokenError($this::TOKEN_INVALID);
+ return;
+ }
+
+ $uuid = $res['UUID'];
+ $name = $res['FirstName'].' '.$res['LastName'];
+ $getToken = $this->app->db()->prepare('DELETE FROM PasswordResetTokens WHERE PrincipalID = ? AND Token = ?');
+ $getToken->execute([$uuid, $_POST['resetToken']]);
+ if ($getToken->rowCount() == 0) {
+ $this->displayTokenError($this::TOKEN_INVALID);
+ return;
+ }
+
+ if (time() - $res['RequestTime'] > 86400) {
+ $this->displayTokenError($this::TOKEN_EXPIRED);
+ return;
+ }
+
+ $salt = bin2hex(random_bytes(16));
+ $hash = md5(md5(trim($_POST['password'])).':'.$salt);
+ $statement = $this->app->db()->prepare('UPDATE auth SET passwordHash = :PasswordHash, passwordSalt = :PasswordSalt WHERE UUID = :PrincipalID');
+ $statement->execute(['PasswordHash' => $hash, 'PasswordSalt' => $salt, 'PrincipalID' => $uuid]);
+
+ session_unset();
+ $_SESSION['loginMessage'] = 'Du kannst dich jetzt mit deinem neuen Passwort einloggen!';
+ $_SESSION['loginMessageColor'] = 'darkgreen';
+
+ $smtp = $this->app->config('smtp');
+ $tplMail = $this->app->template('mail.php')->vars([
+ 'title' => 'Passwort geändert',
+ 'preheader' => 'Das Passwort für deinen 4Creative-Account wurde soeben zurückgesetzt'
+ ])->unsafeVar('message', str_replace('%%NAME%%', $name, $this::MESSAGE));
+ (new SmtpClient($smtp['host'], $smtp['port'], $smtp['address'], $smtp['password']))->sendHtml($smtp['address'], $smtp['name'], $res['Email'], 'Passwort für '.$name.' zurückgesetzt', $tplMail);
+
+ header('Location: index.php?page=login');
+ }
+ }
+
+ private function displayTokenError(string $message): void
+ {
+ $this->app->template('error.php')->parent('__presession.php')->vars([
+ 'title' => 'Fehler',
+ 'message' => $message
+ ])->render();
+ }
+
+ private function displayPage(string $message = ''): void
+ {
+ if (!isset($_GET['token']) || !preg_match('/^[a-z0-9A-Z]{32}$/', $_GET['token'])) {
+ displayTokenError(TOKEN_INVALID);
+ }
+
+ $this->app->template('reset-password.php')->parent('__presession.php')->vars([
+ 'title' => 'Neues Passwort festlegen',
+ 'message' => $message,
+ 'reset-token' => $_GET['token']
+ ])->render();
+ }
+}
diff --git a/pages/.htaccess b/pages/.htaccess
deleted file mode 100644
index 14249c5..0000000
--- a/pages/.htaccess
+++ /dev/null
@@ -1 +0,0 @@
-Deny from all
\ No newline at end of file
diff --git a/pages/dashboard.php b/pages/dashboard.php
deleted file mode 100644
index 2585503..0000000
--- a/pages/dashboard.php
+++ /dev/null
@@ -1,14 +0,0 @@
-setHTMLTitle("Dashboard");
- $HTML->importSeitenInhalt("dashboard-home.html");
-
- $HTML->ReplaceSeitenInhalt("%%GLOBAL-USER-COUNT%%", $opensim->getUserCount());
- $HTML->ReplaceSeitenInhalt("%%GLOBAL-REGION-COUNT%%", $opensim->getRegionCount());
-
- $HTML->ReplaceLayoutInhalt("%%USERNAME%%", htmlspecialchars($_SESSION['DISPLAYNAME']));
-
- $HTML->build();
- echo $HTML->ausgabe();
diff --git a/pages/error.php b/pages/error.php
deleted file mode 100644
index 18c1acd..0000000
--- a/pages/error.php
+++ /dev/null
@@ -1,6 +0,0 @@
-setHTMLTitle("Seite nicht gefunden");
-
- $HTML->build();
- http_response_code(404);
- echo $HTML->ausgabe();
diff --git a/pages/forgot.php b/pages/forgot.php
deleted file mode 100644
index f923676..0000000
--- a/pages/forgot.php
+++ /dev/null
@@ -1,67 +0,0 @@
- wir haben soeben eine Anfrage zur Zurücksetzung des Passworts für deinen 4Creative-Account erhalten. Klicke hier , um ein neues Passwort festzulegen. Dieser Link läuft in 24 Stunden ab. Falls du diese Anfrage nicht gesendet hast, ignoriere sie einfach. Bei weiteren Fragen kannst du uns unter info@4creative.net oder per Discord über @ikeytan erreichen.';
-
- $HTML = new HTML();
- $HTML->setHTMLTitle("Passwort vergessen");
- $HTML->importHTML("forgot.html");
-
- if ($_SERVER['REQUEST_METHOD'] == 'POST') {
- include_once 'app/FormValidator.php';
- $validator = new FormValidator(array(
- 'username' => array('required' => true, 'regex' => '/^[^\\/<>\s]{1,64} [^\\/<>\s]{1,64}$/'),
- 'email' => array('required' => true, 'regex' => '/^\S{1,64}@\S{1,250}.\S{2,64}$/')
- ));
-
- if (!$validator->isValid($_POST)) {
- $HTML->ReplaceLayoutInhalt('%%MESSAGE%%', 'Bitte gebe deinen Benutzernamen (Vor- und Nachname) und die dazugehörige E-Mail-Adresse ein');
- $HTML->ReplaceLayoutInhalt('%%MESSAGECOLOR%%', 'red');
- $HTML->build();
- echo $HTML->ausgabe();
- } else {
- $nameParts = explode(" ", $_POST['username']);
- $email = strtolower(trim($_POST['email']));
-
- $getAccount = $RUNTIME['PDO']->prepare('SELECT Email,FirstName,LastName,PrincipalID FROM UserAccounts WHERE FirstName = ? AND LastName = ? AND Email = ?');
- $getAccount->execute([trim($nameParts[0]), trim($nameParts[1]), $email]);
- $validRequest = $getAccount->rowCount() == 1;
- $uuid;
- $name;
- if ($res = $getAccount->fetch()) {
- $email = $res['Email'];
- $uuid = $res['PrincipalID'];
- $name = $res['FirstName'].' '.$res['LastName'];
- }
-
- foreach ($RUNTIME['RESET_BLOCKED_DOMAINS'] as $domain) {
- if (str_ends_with($email, $domain)) {
- $validRequest = false;
- }
- }
-
- $HTML->ReplaceLayoutInhalt('%%MESSAGE%%', 'Falls Name und E-Mail-Adresse bei uns registriert sind, erhältst du in Kürze eine E-Mail mit weiteren Informationen.');
- $HTML->ReplaceLayoutInhalt('%%MESSAGECOLOR%%', 'green');
- $HTML->build();
- echo $HTML->ausgabe();
- fastcgi_finish_request();
-
- if ($validRequest) {
- $getReqTime = $RUNTIME['PDO']->prepare('SELECT RequestTime FROM PasswordResetTokens WHERE PrincipalID=?');
- $getReqTime->execute([$uuid]);
- if (($res = $getReqTime->fetch()) && time() - $res['RequestTime'] < 900) {
- return;
- }
-
- require_once 'app/utils.php';
- $token = generateToken(32);
- $setToken = $RUNTIME['PDO']->prepare('REPLACE INTO PasswordResetTokens(PrincipalID,Token,RequestTime) VALUES(?,?,?)');
- $setToken->execute([$uuid, $token, time()]);
-
- sendMail($email, str_replace('%%NAME%%', $name, str_replace('%%RESET_LINK%%', 'https://'.$RUNTIME['DOMAIN'].'/index.php?page=reset-password&token='.$token, MESSAGE)), "Zurücksetzung des Passworts für ".$name, 'Dein Passwort zurücksetzen', 'Folge diesen Anweisungen, um ein neues Passwort für deinen 4Creative-Account festzulegen');
- }
- }
- } else {
- $HTML->ReplaceLayoutInhalt('%%MESSAGE%%', '');
- $HTML->ReplaceLayoutInhalt('%%MESSAGECOLOR%%', 'red');
- $HTML->build();
- echo $HTML->ausgabe();
- }
diff --git a/pages/friends.php b/pages/friends.php
deleted file mode 100644
index 16002f3..0000000
--- a/pages/friends.php
+++ /dev/null
@@ -1,55 +0,0 @@
- array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/')
- ));
-
- if ($validator->isValid($_POST)) {
- $statementMembership = $RUNTIME['PDO']->prepare("DELETE FROM Friends WHERE Friend = ? AND PrincipalID = ?");
- $statementMembership->execute(array($_REQUEST['uuid'], $_SESSION['UUID']));
-
- $statementMembership = $RUNTIME['PDO']->prepare("DELETE FROM Friends WHERE PrincipalID = ? AND Friend = ?");
- $statementMembership->execute(array($_REQUEST['uuid'], $_SESSION['UUID']));
- }
- }
-
- header('Location: index.php?page=friends');
- die();
- }
-
- $HTML->setHTMLTitle("Deine Freunde");
- $HTML->importSeitenInhalt("online-anzeige.html");
-
- $table = '';
-
- $statement = $RUNTIME['PDO']->prepare("SELECT PrincipalID,Friend FROM Friends WHERE PrincipalID = ? ORDER BY Friend ASC");
- $statement->execute([$_SESSION['UUID']]);
-
- include_once 'app/OpenSim.php';
- $opensim = new OpenSim();
-
- while ($row = $statement->fetch()) {
- $PrincipalID = explode(";", $row['PrincipalID'])[0];
- $FriendData = explode(";", $row['Friend']);
- $Friend = $FriendData[0];
-
- $name = trim($opensim->getUserName($Friend));
- if (count($FriendData) > 1) {
- $FriendData[1] = str_replace("http://", "", $FriendData[1]);
- $FriendData[1] = str_replace("https://", "", $FriendData[1]);
- $FriendData[1] = str_replace("/", "", $FriendData[1]);
- $name = $name.' @ '.strtolower($FriendData[1]);
- }
-
- $entry = ''.htmlspecialchars($name).' ';
-
- $table = str_replace("%%ENTRY%%", $entry."%%ENTRY%%", $table);
- }
-
- $table = str_replace("%%ENTRY%%", "", $table);
- $HTML->ReplaceSeitenInhalt("%%ONLINE-LIST%%", $table);
-
- $HTML->build();
- echo $HTML->ausgabe();
diff --git a/pages/groups.php b/pages/groups.php
deleted file mode 100644
index 92c9b68..0000000
--- a/pages/groups.php
+++ /dev/null
@@ -1,39 +0,0 @@
- array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/')
- ));
-
- if ($validator->isValid($_POST)) {
- $statementMembership = $RUNTIME['PDO']->prepare("DELETE FROM os_groups_membership WHERE GroupID = ? AND PrincipalID = ?");
- $statementMembership->execute(array($_REQUEST['group'], $_SESSION['UUID']));
- }
- }
-
- header('Location: index.php?page=groups');
- die();
- }
-
- include_once 'app/OpenSim.php';
- $opensim = new OpenSim();
-
- $HTML->setHTMLTitle("Gruppen");
- $HTML->importSeitenInhalt("deine-regionen.html");
-
- $table = 'Name Gründer Aktionen %%ENTRY%%
';
-
- $statementGroups = $RUNTIME['PDO']->prepare("SELECT Name,FounderID,os_groups_membership.GroupID FROM os_groups_groups JOIN os_groups_membership ON os_groups_groups.GroupID = os_groups_membership.GroupID WHERE PrincipalID = ?");
- $statementGroups->execute(array($_SESSION['UUID']));
-
- while ($rowGroups = $statementGroups->fetch()) {
- $entry = ''.htmlspecialchars($rowGroups['Name']).' '.htmlspecialchars($opensim->getUserName($rowGroups['FounderID'])).' ';
- $table = str_replace("%%ENTRY%%", $entry."%%ENTRY%%", $table);
- }
-
- $table = str_replace("%%ENTRY%%", "", $table);
- $HTML->ReplaceSeitenInhalt("%%REGION-LIST%%", $table);
-
- $HTML->build();
- echo $HTML->ausgabe();
diff --git a/pages/identities.php b/pages/identities.php
deleted file mode 100644
index c2d6f7f..0000000
--- a/pages/identities.php
+++ /dev/null
@@ -1,141 +0,0 @@
-prepare("CREATE TABLE IF NOT EXISTS `UserIdentitys` (`PrincipalID` CHAR(36) NOT NULL, `IdentityID` CHAR(36) NOT NULL, PRIMARY KEY (`PrincipalID`, `IdentityID`)) ENGINE=MyISAM CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci");
- $statementCreateTable->execute();
- $statementCreateTrigger = $RUNTIME['PDO']->prepare("CREATE TRIGGER IF NOT EXISTS del_id_trig AFTER DELETE ON UserAccounts FOR EACH ROW DELETE FROM UserIdentitys WHERE UserIdentitys.PrincipalID = OLD.PrincipalID OR UserIdentitys.IdentityID = OLD.PrincipalID");
- $statementCreateTrigger->execute();
-
- if ($_SERVER['REQUEST_METHOD'] == 'POST') {
- include_once 'app/FormValidator.php';
- if (isset($_POST['enableIdent'])) {
- $validator = new FormValidator(array(
- 'uuid' => array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/')
- ));
-
- if ($validator->isValid($_POST)) {
- $statement = $RUNTIME['PDO']->prepare("SELECT 1 FROM UserIdentitys WHERE PrincipalID = :PrincipalID AND IdentityID = :IdentityID LIMIT 1");
- $statement->execute(['PrincipalID' => $_SESSION['UUID'], 'IdentityID' => $_POST['uuid']]);
-
- $statementPresence = $RUNTIME['PDO']->prepare("SELECT 1 FROM Presence WHERE UserID = :PrincipalID LIMIT 1");
- $statementPresence->execute(['PrincipalID' => $_SESSION['UUID']]);
-
- if ($statementPresence->rowCount() == 0) {
- if ($statement->rowCount() == 1) {
- $statementAuth = $RUNTIME['PDO']->prepare('UPDATE auth SET UUID = :IdentityID WHERE UUID = :PrincipalID');
- $statementAuth->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID']]);
-
- $statementUserIdentitys = $RUNTIME['PDO']->prepare('UPDATE UserIdentitys SET PrincipalID = :IdentityID WHERE PrincipalID = :PrincipalID');
- $statementUserIdentitys->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID']]);
-
- $statementFriends = $RUNTIME['PDO']->prepare('UPDATE Friends SET PrincipalID = :IdentityID WHERE PrincipalID = :PrincipalID');
- $statementFriends->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID']]);
-
- //$statementReFriends = $RUNTIME['PDO']->prepare('UPDATE Friends SET Friend = :IdentityID WHERE Friend = :PrincipalID');
- //$statementReFriends->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID']]);
-
- $statementInventoryFolders = $RUNTIME['PDO']->prepare('UPDATE inventoryfolders SET agentID = :IdentityID WHERE agentID = :PrincipalID AND type != :InventarTyp');
- $statementInventoryFolders->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID'], 'InventarTyp' => 46]);
-
- $statementInventoryItems = $RUNTIME['PDO']->prepare('UPDATE inventoryitems SET avatarID = :IdentityID WHERE avatarID = :PrincipalID');
- $statementInventoryItems->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID']]);
-
- $statementGroupMembership = $RUNTIME['PDO']->prepare('UPDATE os_groups_membership SET PrincipalID = :IdentityID WHERE PrincipalID = :PrincipalID');
- $statementGroupMembership->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID']]);
-
- $statementGroupRoles = $RUNTIME['PDO']->prepare('UPDATE os_groups_rolemembership SET PrincipalID = :IdentityID WHERE PrincipalID = :PrincipalID');
- $statementGroupRoles->execute(['IdentityID' => $_POST['uuid'], 'PrincipalID' => $_SESSION['UUID']]);
-
- $statementGroupRoles = $RUNTIME['PDO']->prepare('DELETE FROM Presence WHERE UserID = :PrincipalID');
- $statementGroupRoles->execute(['PrincipalID' => $_SESSION['UUID']]);
-
- $_SESSION['LOGIN'] = 'false';
- session_destroy();
- }
- } else {
- $_SESSION['identities_err'] = 'Du kannst die Identität nicht ändern, während du angemeldet bist. Bitte schließe den Viewer.';
- }
- }
- } elseif (isset($_POST['createIdent'])) {
- $validator = new FormValidator(array(
- 'newName' => array('required' => true, 'regex' => '/^[^\\/<>\s]{1,64} [^\\/<>\s]{1,64}$/')
- ));
-
- if ($validator->isValid($_POST)) {
- $avatarNameParts = explode(" ", trim($_POST['newName']));
-
- if (count($avatarNameParts) == 2) {
- $statement = $RUNTIME['PDO']->prepare("SELECT 1 FROM UserAccounts WHERE FirstName = :FirstName AND LastName = :LastName LIMIT 1");
- $statement->execute(['FirstName' => trim($avatarNameParts[0]), 'LastName' => trim($avatarNameParts[1])]);
-
- if ($statement->rowCount() == 0) {
- include_once 'app/OpenSim.php';
- $avatarUUID = (new OpenSim())->gen_uuid();
-
- $statementAccounts = $RUNTIME['PDO']->prepare('INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created, UserLevel, UserFlags, UserTitle, active) VALUES (:PrincipalID, :ScopeID, :FirstName, :LastName, :Email, :ServiceURLs, :Created, :UserLevel, :UserFlags, :UserTitle, :active )');
- $statementAccounts->execute(['PrincipalID' => $avatarUUID, 'ScopeID' => "00000000-0000-0000-0000-000000000000", 'FirstName' => $avatarNameParts[0], 'LastName' => $avatarNameParts[1], 'Email' => $_SESSION['EMAIL'], 'ServiceURLs' => "HomeURI= GatekeeperURI= InventoryServerURI= AssetServerURI= ", 'Created' => time(), 'UserLevel' => 0, 'UserFlags' => 0, 'UserTitle' => "", 'active' => 1]);
-
- $statementUserIdentitys = $RUNTIME['PDO']->prepare('INSERT INTO UserIdentitys (PrincipalID, IdentityID) VALUES (:PrincipalID, :IdentityID)');
- $statementUserIdentitys->execute(['PrincipalID' => $_SESSION['UUID'], 'IdentityID' => $avatarUUID]);
- } else {
- $_SESSION['identities_err'] = 'Dieser Name ist schon in Benutzung.';
- }
- } else {
- $_SESSION['identities_err'] = 'Der Name muss aus einem Vor und einem Nachnamen bestehen.';
- }
- }
- }
- elseif (isset($_POST['deleteIdent'])) {
- $validator = new FormValidator(array(
- 'uuid' => array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/')
- ));
-
- if ($validator->isValid($_POST)) {
- include_once 'app/OpenSim.php';
- (new OpenSim())->deleteIdentity($_SESSION['UUID'], $_POST['uuid']);
- }
- }
-
- header('Location: index.php?page=identities');
- die();
- }
-
- $HTML->setHTMLTitle("Identitäten");
- $HTML->importSeitenInhalt("identities.html");
-
- $statementCheckForEntry = $RUNTIME['PDO']->prepare("SELECT 1 FROM UserIdentitys WHERE PrincipalID = ? LIMIT 1");
- $statementCheckForEntry->execute(array($_SESSION['UUID']));
-
- if ($statementCheckForEntry->rowCount() == 0) {
- $statement = $RUNTIME['PDO']->prepare('INSERT INTO `UserIdentitys` (PrincipalID, IdentityID) VALUES (:PrincipalID, :IdentityID)');
- $statement->execute(['PrincipalID' => $_SESSION['UUID'], 'IdentityID' => $_SESSION['UUID']]);
- }
-
- $table = '';
- $statement = $RUNTIME['PDO']->prepare("SELECT IdentityID FROM UserIdentitys WHERE PrincipalID = ? ORDER BY IdentityID ASC");
- $statement->execute(array($_SESSION['UUID']));
-
- include_once 'app/OpenSim.php';
- $opensim = new OpenSim();
-
- while ($row = $statement->fetch()) {
- if ($row['IdentityID'] == $_SESSION['UUID']) {
- $entry = ''.htmlspecialchars(trim($opensim->getUserName($row['IdentityID']))).' Aktiv - ';
- } else {
- $entry = ''.htmlspecialchars(trim($opensim->getUserName($row['IdentityID']))).' ';
- }
-
- $table = str_replace("%%ENTRY%%", $entry."%%ENTRY%%", $table);
- }
-
- $table = str_replace("%%ENTRY%%", "", $table);
- $HTML->ReplaceSeitenInhalt("%%IDENT-LIST%%", $table);
- $HTML->ReplaceSeitenInhalt("%%link%%", ' ');
-
- $message = '';
- if (isset($_SESSION['identities_err'])) {
- $message = ''.$_SESSION['identities_err'].'
';
- unset($_SESSION['identities_err']);
- }
- $HTML->ReplaceSeitenInhalt("%%MESSAGE%%", $message);
-
- $HTML->build();
- echo $HTML->ausgabe();
diff --git a/pages/invite.php b/pages/invite.php
deleted file mode 100644
index d0c8cd7..0000000
--- a/pages/invite.php
+++ /dev/null
@@ -1,17 +0,0 @@
-setHTMLTitle("Kein Zugriff");
- $HTML->SetSeitenInhalt("Dazu hast du keine Rechte!");
- $HTML->build();
- echo $HTML->ausgabe();
- die();
- }
-
- $HTML->setHTMLTitle("Benutzer");
- $HTML->importSeitenInhalt("users.html");
-
-
- $HTML->ReplaceSeitenInhalt("%%link%%", ' ');
-
- $HTML->build();
- echo $HTML->ausgabe();
diff --git a/pages/login.php b/pages/login.php
deleted file mode 100644
index 70d8a34..0000000
--- a/pages/login.php
+++ /dev/null
@@ -1,55 +0,0 @@
-setHTMLTitle("Login");
- $HTML->importHTML("login.html");
-
- if ($_SERVER['REQUEST_METHOD'] == 'POST') {
- include_once 'app/FormValidator.php';
- $validator = new FormValidator(array(
- 'username' => array('required' => true, 'regex' => '/^[^\\/<>\s]{1,64} [^\\/<>\s]{1,64}$/'),
- 'password' => array('required' => true, 'regex' => '/^.{1,1000}$/')
- ));
-
- if (!$validator->isValid($_POST)) {
- $HTML->ReplaceLayoutInhalt("%%LOGINMESSAGE%%", "Bitte gebe Benutzername (Vor- und Nachname) und Passwort ein.");
- } else {
- $statementUser = $RUNTIME['PDO']->prepare("SELECT PrincipalID,FirstName,LastName,Email,UserLevel,passwordHash,passwordSalt FROM UserAccounts JOIN auth ON UserAccounts.PrincipalID = auth.UUID WHERE FirstName = ? AND LastName = ? LIMIT 1");
- $statementUser->execute(explode(" ", trim($_POST['username'])));
- $res = ['passwordHash' => '', 'passwordSalt' => ''];
-
- if ($rowUser = $statementUser->fetch()) {
- $res = $rowUser;
- }
-
- if (hash_equals(md5(md5($_POST['password']).":".$res['passwordSalt']), $res['passwordHash'])) {
- session_unset(); // Unset pre-session variables, next request will generate a new CSRF token
- $_SESSION['FIRSTNAME'] = $rowUser['FirstName'];
- $_SESSION['LASTNAME'] = $rowUser['LastName'];
- $_SESSION['EMAIL'] = $rowUser['Email'];
- $_SESSION['PASSWORD'] = $rowUser['passwordHash'];
- $_SESSION['SALT'] = $rowUser['passwordSalt'];
- $_SESSION['UUID'] = $rowUser['PrincipalID'];
- $_SESSION['LEVEL'] = $rowUser['UserLevel'];
- $_SESSION['DISPLAYNAME'] = strtoupper($rowUser['FirstName'].' '.$rowUser['LastName']);
- $_SESSION['LOGIN'] = 'true';
-
- header("Location: index.php?page=dashboard");
- die();
- }
-
- $HTML->ReplaceLayoutInhalt("%%LOGINMESSAGE%%", "Benutzername und/oder Passwort falsch.");
- $HTML->ReplaceLayoutInhalt("%%LASTUSERNAME%%", htmlspecialchars($_POST['username']));
- }
- } elseif (isset($_SESSION) && isset($_SESSION['loginMessage'])) {
- $HTML->ReplaceLayoutInhalt('%%LOGINMESSAGE%%', $_SESSION['loginMessage']);
- $HTML->ReplaceLayoutInhalt('%%MESSAGECOLOR%%', $_SESSION['loginMessageColor']);
- unset($_SESSION['loginMessage']);
- unset($_SESSION['loginMessageColor']);
- }
-
- $HTML->ReplaceLayoutInhalt("%%LOGINMESSAGE%%", "");
- $HTML->ReplaceLayoutInhalt("%%MESSAGECOLOR%%", "red");
- $HTML->ReplaceLayoutInhalt("%%LASTUSERNAME%%", "");
-
- $HTML->build();
- echo $HTML->ausgabe();
diff --git a/pages/regions.php b/pages/regions.php
deleted file mode 100644
index 4b85a9e..0000000
--- a/pages/regions.php
+++ /dev/null
@@ -1,80 +0,0 @@
-setHTMLTitle("Deine Regionen");
- $HTML->importSeitenInhalt("deine-regionen.html");
-
- function cleanSize($bytes)
- {
- if ($bytes > 0) {
- $unit = intval(log($bytes, 1024));
- $units = array('B', 'KB', 'MB', 'GB');
-
- if (array_key_exists($unit, $units) === true) {
- return sprintf('%d %s', $bytes / pow(1024, $unit), $units[$unit]);
- }
- }
-
- return $bytes;
- }
-
- function getRegionStatsData($regionID)
- {
- global $RUNTIME;
-
- $statement = $RUNTIME['PDO']->prepare("SELECT Prims,SimFPS,PhyFPS,ProcMem,RegionVersion FROM regions_info WHERE regionID = ?");
- $statement->execute([$regionID]);
-
- if ($row = $statement->fetch()) {
- $return = array();
- $return['Prims'] = $row['Prims'];
- $return['SimFPS'] = $row['SimFPS'];
- $return['PhyFPS'] = $row['PhyFPS'];
- $return['ProcMem'] = cleanSize(str_replace(".", "", str_replace(",", ".", $row['ProcMem']))."000");
- $return['RegionVersion'] = trim($row['RegionVersion']);
-
- return $return;
- }
-
- return array();
- }
-
- if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_REQUEST['remove'])) {
- include_once 'app/FormValidator.php';
- $validator = new FormValidator(array(
- 'region' => array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/')
- ));
-
- if ($validator->isValid($_POST)) {
- if (isset($_SESSION['LEVEL']) && $_SESSION['LEVEL'] >= 100) {
- $statementMembership = $RUNTIME['PDO']->prepare("DELETE FROM regions WHERE uuid = ?");
- $statementMembership->execute(array($_POST['region']));
- } else {
- $statementMembership = $RUNTIME['PDO']->prepare("DELETE FROM regions WHERE uuid = ? AND owner_uuid = ?");
- $statementMembership->execute(array($_POST['region'], $_SESSION['UUID']));
- }
- }
-
- header('Location: index.php?page=regions');
- die();
- }
-
- $table = 'Region Name Eigentümer Position Aktionen %%ENTRY%%
';
-
- $showAll = isset($_SESSION['LEVEL']) && $_SESSION['LEVEL'] >= 100 && isset($_REQUEST['SHOWALL']) && $_REQUEST['SHOWALL'] == "1";
- $statement = $RUNTIME['PDO']->prepare("SELECT uuid,regionName,owner_uuid,locX,locY FROM regions ".($showAll ? "ORDER BY owner_uuid ASC" : "WHERE owner_uuid = ? ORDER BY uuid ASC"));
- $statement->execute($showAll ? array() : array($_SESSION['UUID']));
-
- include_once 'app/OpenSim.php';
- $opensim = new OpenSim();
-
- while ($row = $statement->fetch()) {
- $stats = getRegionStatsData($row['uuid']);
-
- $entry = ''.htmlspecialchars($row['regionName']).' '.htmlspecialchars($opensim->getUserName($row['owner_uuid'])).' '.fillString(($row['locX'] / 256), 4).' / '.fillString(($row['locY'] / 256), 4).' ';
- $table = str_replace("%%ENTRY%%", $entry."%%ENTRY%%", $table);
- }
-
- $table = str_replace("%%ENTRY%%", "", $table);
- $HTML->ReplaceSeitenInhalt("%%REGION-LIST%%", $table);
-
- $HTML->build();
- echo $HTML->ausgabe();
diff --git a/pages/register.php b/pages/register.php
deleted file mode 100644
index 2951246..0000000
--- a/pages/register.php
+++ /dev/null
@@ -1,154 +0,0 @@
-setHTMLTitle("Registrieren");
- $HTML->importHTML("register.html");
-
- $HTML->ReplaceLayoutInhalt("%%MESSAGE%%", $message);
- $HTML->ReplaceLayoutInhalt("%%tosURL%%", $RUNTIME['TOOLS']['TOS'] );
- $HTML->ReplaceLayoutInhalt("%%INVCODE%%", htmlspecialchars($_REQUEST['code']));
-
- $HTML->build();
- echo $HTML->ausgabe();
- die();
- }
-
- function displayError(string $message)
- {
- $HTML = new HTML();
- $HTML->importHTML("error.html");
- $HTML->ReplaceLayoutInhalt("%%MESSAGE%%", $message);
- $HTML->build();
- echo $HTML->ausgabe();
- die();
- }
-
- if (!isset($_REQUEST['code'])) {
- displayError("Du benötigst einen Einladungscode, um dich bei 4Creative zu registrieren.");
- }
-
- if (strlen($_REQUEST['code']) != 32 || !preg_match('/^[a-f0-9]+$/', $_REQUEST['code'])) {
- displayError("Der angegebene Einladungscode ist nicht gültig. Nutze genau den Link, der dir zugeschickt wurde.");
- }
-
- $statementInviteCode = $RUNTIME['PDO']->prepare("SELECT 1 FROM InviteCodes WHERE InviteCode = ? LIMIT 1");
- $statementInviteCode->execute([$_REQUEST['code']]);
-
- if ($statementInviteCode->rowCount() == 0) {
- displayError("Der angegebene Einladungscode ist nicht gültig. Nutze genau den Link, der dir zugeschickt wurde.");
- }
-
- if ($_SERVER['REQUEST_METHOD'] != 'POST') {
- displayPage("");
- }
-
- include_once 'app/FormValidator.php';
- $validator = new FormValidator(array(
- 'tos' => array('required' => true, 'equals' => 'on'),
- 'username' => array('required' => true, 'regex' => '/^[^\\/<>\s]{1,64}( [^\\/<>\s]{1,64})?$/'),
- 'password' => array('required' => true, 'regex' => '/^.{1,1000}$/'),
- 'email' => array('required' => true, 'regex' => '/^\S{1,64}@\S{1,250}.\S{2,64}$/'),
- 'avatar' => array('required' => true)
- ));
-
- if (!$validator->isValid($_POST)) {
- if (!isset($_POST['tos']) || $_POST['tos'] !== true) {
- displayPage("Du musst die Nutzungsbedingungen lesen und Akzeptieren.");
- } else {
- displayPage("Ups da stimmt was nicht. Versuche es bitte noch mal.");
- }
-
- die();
- }
-
- $name = trim($_POST['username']);
- $nameParts;
- if ($name != "") {
- $nameParts = explode(" ", $name);
- if (count($nameParts) == 1) {
- $name .= " Resident";
- $nameParts = explode(" ", $name);
- }
-
- $statementAvatarName = $RUNTIME['PDO']->prepare("SELECT 1 FROM UserAccounts WHERE FirstName = :FirstName AND LastName = :LastName LIMIT 1");
- $statementAvatarName->execute(['FirstName' => $nameParts[0], 'LastName' => $nameParts[1]]);
- if ($statementAvatarName->rowCount() > 0) {
- displayPage("Der gewählte Name ist bereits vergeben.");
- }
- }
-
- $pass = trim($_POST['password']);
- if (strlen($pass) < $RUNTIME['PASSWORD_MIN_LENGTH']) {
- displayPage('Dein Passwort muss mindestens '.$RUNTIME['PASSWORD_MIN_LENGTH'].' Zeichen lang sein.');
- }
-
- $email = trim($_POST['email']);
-
- $avatar;
- if (isset($RUNTIME['DEFAULTAVATAR'][$_POST['avatar']]['UUID'])) {
- $avatar = trim($_POST['avatar']);
- } else {
- displayPage("Der gewählte Standardavatar existiert nicht.");
- }
-
- include_once 'app/OpenSim.php';
- $opensim = new OpenSim();
-
- $avatarUUID = $opensim->gen_uuid();
- $salt = bin2hex(random_bytes(16));
- $passwordHash = md5(md5($pass).':'.$salt);
-
- $statementInviteDeleter = $RUNTIME['PDO']->prepare('DELETE FROM InviteCodes WHERE InviteCode = :code');
- $statementInviteDeleter->execute(['code' => $_REQUEST['code']]);
- if ($statementInviteDeleter->rowCount() == 0) {
- displayError("Der angegebene Einladungscode ist nicht mehr gültig.");
- }
-
- try {
- $RUNTIME['PDO']->beginTransaction();
-
- $statementAuth = $RUNTIME['PDO']->prepare('INSERT INTO `auth` (`UUID`, `passwordHash`, `passwordSalt`, `webLoginKey`, `accountType`) VALUES (:UUID, :HASHVALUE, :SALT, :WEBKEY, :ACCTYPE)');
- $statementAuth->execute(['UUID' => $avatarUUID, 'HASHVALUE' => $passwordHash, 'SALT' => $salt, 'WEBKEY' => "00000000-0000-0000-0000-000000000000", 'ACCTYPE' => "UserAccount"]);
-
- $statementAccounts = $RUNTIME['PDO']->prepare('INSERT INTO `UserAccounts` (`PrincipalID`, `ScopeID`, `FirstName`, `LastName`, `Email`, `ServiceURLs`, `Created`, `UserLevel`, `UserFlags`, `UserTitle`, `active`) VALUES (:PrincipalID, :ScopeID, :FirstName, :LastName, :Email, :ServiceURLs, :Created, :UserLevel, :UserFlags, :UserTitle, :active )');
- $statementAccounts->execute(['PrincipalID' => $avatarUUID, 'ScopeID' => "00000000-0000-0000-0000-000000000000", 'FirstName' => $nameParts[0], 'LastName' => $nameParts[1], 'Email' => $email, 'ServiceURLs' => "HomeURI= GatekeeperURI= InventoryServerURI= AssetServerURI= ", 'Created' => time(), 'UserLevel' => 0, 'UserFlags' => 0, 'UserTitle' => "", 'active' => 1]);
-
- $statementProfile = $RUNTIME['PDO']->prepare('INSERT INTO `userprofile` (`useruuid`, `profilePartner`, `profileImage`, `profileURL`, `profileFirstImage`, `profileAllowPublish`, `profileMaturePublish`, `profileWantToMask`, `profileWantToText`, `profileSkillsMask`, `profileSkillsText`, `profileLanguages`, `profileAboutText`, `profileFirstText`) VALUES (:useruuid, :profilePartner, :profileImage, :profileURL, :profileFirstImage, :profileAllowPublish, :profileMaturePublish, :profileWantToMask, :profileWantToText, :profileSkillsMask, :profileSkillsText, :profileLanguages, :profileAboutText, :profileFirstText)');
- $statementProfile->execute(['useruuid' => $avatarUUID, 'profilePartner' => "00000000-0000-0000-0000-000000000000", 'profileImage' => "00000000-0000-0000-0000-000000000000", 'profileURL' => '', 'profileFirstImage' => "00000000-0000-0000-0000-000000000000", "profileAllowPublish" => "0", "profileMaturePublish" => "0", "profileWantToMask" => "0", "profileWantToText" => "", "profileSkillsMask" => "0", "profileSkillsText" => "", "profileLanguages" => "", "profileAboutText" => "", "profileFirstText" => ""]);
-
- $statementInventoryFolder = $RUNTIME['PDO']->prepare('INSERT INTO `inventoryfolders` (`folderName`, `type`, `version`, `folderID`, `agentID`, `parentFolderID`) VALUES (:folderName, :folderTyp, :folderVersion, :folderID, :agentID, :parentFolderID)');
- $Inventory = array('Calling Cards' => 2, 'Objects' => 6, 'Landmarks' => 3, 'Clothing' => 5, 'Gestures' => 21, 'Body Parts' => 13, 'Textures' => 0, 'Scripts' => 10, 'Photo Album' => 15, 'Lost And Found' => 16, 'Trash' => 14, 'Notecards' => 7, 'My Inventory' => 8, 'Sounds' => 1, 'Animations' => 20);
- $InventoryRootFolder = $opensim->gen_uuid();
- foreach ($Inventory as $FolderName => $InventoryType) {
- $FolderUUID = $opensim->gen_uuid();
- if ($InventoryType == 8) {
- $FolderUUID = $InventoryRootFolder;
- $FolderParent = "00000000-0000-0000-0000-000000000000";
- } else {
- $FolderParent = $InventoryRootFolder;
- }
- $statementInventoryFolder->execute(['agentID' => $avatarUUID, 'folderName' => $FolderName, 'folderTyp' => $InventoryType, 'folderVersion' => 1, 'folderID' => $FolderUUID, 'parentFolderID' => $FolderParent]);
- }
-
- $RUNTIME['PDO']->commit();
- } catch (Exception $pdoException) {
- $RUNTIME['PDO']->rollBack();
- error_log('Could not create Account: '.$pdoException->getMessage());
- displayPage('Fehler bei der Erstellung deines Accounts. Bitte versuche es später erneut.');
- }
-
- session_unset(); // Unset pre-session variables, next request will generate a new CSRF token
- $_SESSION['FIRSTNAME'] = trim($nameParts[0]);
- $_SESSION['LASTNAME'] = trim($nameParts[1]);
- $_SESSION['EMAIL'] = $email;
- $_SESSION['PASSWORD'] = $passwordHash;
- $_SESSION['SALT'] = $salt;
- $_SESSION['UUID'] = $avatarUUID;
- $_SESSION['LEVEL'] = 0;
- $_SESSION['DISPLAYNAME'] = strtoupper($name);
- $_SESSION['LOGIN'] = 'true';
-
- header('Location: index.php?page=dashboard');
- die();
diff --git a/pages/reset-password.php b/pages/reset-password.php
deleted file mode 100644
index c36f29e..0000000
--- a/pages/reset-password.php
+++ /dev/null
@@ -1,90 +0,0 @@
- das Passwort für deinen 4Creative-Account wurde soeben über die Funktion "Passwort vergessen" geändert. Solltest du diese Änderung nicht selbst durchgeführt haben, wende dich bitte umgehend per E-Mail (info@4creative.net) oder Discord (@ikeytan) an uns.';
- const TOKEN_INVALID = 'Dieser Link zur Passwortzurücksetzung ist nicht gültig. Bitte klicke oder kopiere den Link aus der E-Mail, die du erhalten hast.';
- const TOKEN_EXPIRED = 'Dein Link zur Passwortzurücksetzung ist abgelaufen. Klicke hier , um eine neue Anfrage zu senden.';
-
- function displayTokenError($message)
- {
- $HTML = new HTML();
- $HTML->importHTML("error.html");
- $HTML->ReplaceLayoutInhalt('%%MESSAGE%%', $message);
- $HTML->build();
- echo $HTML->ausgabe();
- exit();
- }
-
- function displayPage($err)
- {
- if (!isset($_GET['token']) || !preg_match('/^[a-z0-9A-Z]{32}$/', $_GET['token'])) {
- displayTokenError(TOKEN_INVALID);
- }
-
- $HTML = new HTML();
- $HTML->setHTMLTitle("");
- $HTML->importHTML("reset-password.html");
- $HTML->ReplaceLayoutInhalt('%%MESSAGE%%', $err);
- $HTML->ReplaceLayoutInhalt('%%RESET_TOKEN%%', htmlspecialchars($_GET['token']));
- $HTML->build();
- echo $HTML->ausgabe();
- exit();
- }
-
- if ($_SERVER['REQUEST_METHOD'] == 'POST') {
- include_once 'app/FormValidator.php';
- $validator = new FormValidator(array(
- 'password' => array('required' => true, 'regex' => '/^.{1,1000}$/'),
- 'passwordRepeat' => array('required' => true, 'regex' => '/^.{1,1000}$/'),
- 'resetToken' => array('required' => true, 'regex' => '/^[a-zA-Z0-9]{32}$/')
- ));
-
- if ($validator->isValid($_POST)) {
- if ($_POST['password'] !== $_POST['passwordRepeat']) {
- displayPage('Du musst in beiden Feldern das gleiche Passwort eingeben');
- }
-
- if (strlen($_POST['password']) < $RUNTIME['PASSWORD_MIN_LENGTH']) {
- displayPage('Dein Passwort muss mindestens '.$RUNTIME['PASSWORD_MIN_LENGTH'].' Zeichen lang sein.');
- }
-
- $getReq = $RUNTIME['PDO']->prepare('SELECT UserAccounts.PrincipalID AS UUID,FirstName,LastName,Email,Token,RequestTime FROM PasswordResetTokens JOIN UserAccounts ON UserAccounts.PrincipalID = PasswordResetTokens.PrincipalID WHERE Token = ?');
- $getReq->execute([$_POST['resetToken']]);
- if ($getReq->rowCount() == 0) {
- displayTokenError(TOKEN_INVALID);
- }
-
- $res = $getReq->fetch();
-
- if (!hash_equals($res['Token'], $_POST['resetToken'])) {
- displayTokenError(TOKEN_INVALID);
- }
-
- $uuid = $res['UUID'];
- $name = $res['FirstName'].' '.$res['LastName'];
- $getToken = $RUNTIME['PDO']->prepare('DELETE FROM PasswordResetTokens WHERE PrincipalID = ? AND Token = ?');
- $getToken->execute([$uuid, $_POST['resetToken']]);
- if ($getToken->rowCount() == 0) {
- displayTokenError(TOKEN_INVALID);
- }
-
- if (time() - $res['RequestTime'] > 86400) {
- displayTokenError(TOKEN_EXPIRED);
- }
-
- $salt = bin2hex(random_bytes(16));
- $hash = md5(md5(trim($_POST['password'])).':'.$salt);
- $statement = $RUNTIME['PDO']->prepare('UPDATE auth SET passwordHash = :PasswordHash, passwordSalt = :PasswordSalt WHERE UUID = :PrincipalID');
- $statement->execute(['PasswordHash' => $hash, 'PasswordSalt' => $salt, 'PrincipalID' => $uuid]);
-
- session_unset();
- $_SESSION['loginMessage'] = 'Du kannst dich jetzt mit deinem neuen Passwort einloggen!';
- $_SESSION['loginMessageColor'] = 'darkgreen';
-
- require_once 'app/utils.php';
- sendMail($res['Email'], str_replace('%%NAME%%', $name, MESSAGE), 'Passwort für '.$name.' zurückgesetzt', 'Passwort geändert', 'Das Passwort für deinen 4Creative-Account wurde soeben zurückgesetzt');
-
- header('Location: index.php?page=login');
- exit();
- }
- }
-
- displayPage('');
diff --git a/pages/user-online-state.php b/pages/user-online-state.php
deleted file mode 100644
index b65fc77..0000000
--- a/pages/user-online-state.php
+++ /dev/null
@@ -1,24 +0,0 @@
-setHTMLTitle("Online Anzeige");
- $HTML->importSeitenInhalt("online-anzeige.html");
-
- $table = 'Benutzername Region %%ENTRY%%
';
-
- $statement = $RUNTIME['PDO']->prepare("SELECT RegionID,UserID FROM Presence ORDER BY RegionID ASC");
- $statement->execute();
-
- while ($row = $statement->fetch()) {
- if ($row['RegionID'] != "00000000-0000-0000-0000-000000000000") {
- $entry = ''.htmlspecialchars(trim($opensim->getUserName($row['UserID']))).' '.htmlspecialchars($opensim->getRegionName($row['RegionID'])).' ';
- $table = str_replace("%%ENTRY%%", $entry."%%ENTRY%%", $table);
- }
- }
-
- $table = str_replace("%%ENTRY%%", "", $table);
- $HTML->ReplaceSeitenInhalt("%%ONLINE-LIST%%", $table);
-
- $HTML->build();
- echo $HTML->ausgabe();
diff --git a/pages/users.php b/pages/users.php
deleted file mode 100644
index 0ae2cca..0000000
--- a/pages/users.php
+++ /dev/null
@@ -1,99 +0,0 @@
-setHTMLTitle("Benutzer");
- $HTML->importSeitenInhalt("users.html");
- $HTML->addHTMLHeader(' ');
-
- if (!isset($_SESSION['LOGIN']) || !isset($_SESSION['LEVEL']) || $_SESSION['LEVEL'] < 100) {
- $HTML->setHTMLTitle("Kein Zugriff");
- $HTML->SetSeitenInhalt("Dazu hast du keine Rechte!");
- $HTML->build();
- echo $HTML->ausgabe();
- die();
- }
-
- include_once 'app/OpenSim.php';
- $opensim = new OpenSim();
-
- if ($_SERVER['REQUEST_METHOD'] == 'POST') {
- include_once 'app/FormValidator.php';
- if (isset($_POST['generateLink'])) {
- $validator = new FormValidator(array()); // Needed only for CSRF token validation
-
- if ($validator->isValid($_POST)) {
- $inviteID = bin2hex(random_bytes(16));
- $link = "https://".$_SERVER['SERVER_NAME']."/index.php?page=register&code=".$inviteID;
-
- $statement = $RUNTIME['PDO']->prepare('INSERT INTO `InviteCodes` (`InviteCode`) VALUES (:InviteCode)');
- $statement->execute(['InviteCode' => $inviteID]);
-
- $HTML->ReplaceSeitenInhalt("%%link%%", $link);
- }
- } elseif (isset($_POST['delident'])) {
- $validator = new FormValidator(array(
- 'userid' => array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/'),
- 'identid' => array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/')
- ));
-
- if ($validator->isValid($_POST)) {
- include_once 'app/OpenSim.php';
- $os = new OpenSim();
- $identName = $os->getUserName($_POST['identid']);
- $userName = $os->getUserName($_POST['userid']);
- if($os->deleteIdentity($_POST['userid'], $_POST['identid'])) {
- $HTML->ReplaceSeitenInhalt("%%MESSAGE%%", 'Identität '.$identName.' von '.$userName.' wurde gelöscht.
');
- } else {
- $HTML->ReplaceSeitenInhalt("%%MESSAGE%%", 'Identität '.$identName.' konnte nicht gelöscht werden.
');
- }
- }
- } else {
- $validator = new FormValidator(array(
- 'userid' => array('required' => true, 'regex' => '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/')
- ));
-
- if ($validator->isValid($_POST)) {
- if (isset($_POST['genpw'])) {
- require_once 'app/utils.php';
- $token = generateToken(32);
- $setToken = $RUNTIME['PDO']->prepare('REPLACE INTO PasswordResetTokens(PrincipalID,Token,RequestTime) VALUES(?,?,?)');
- $setToken->execute([$_POST['userid'], $token, time()]);
- $resetLink = "https://".$RUNTIME['DOMAIN'].'/index.php?page=reset-password&token='.$token;
-
- $HTML->ReplaceSeitenInhalt("%%MESSAGE%%", 'Das Passwort für '.htmlspecialchars($opensim->getUserName($_POST['userid'])).' kann in den nächsten 24 Stunden über diesen Link zurückgesetzt werden: '.$resetLink.'
');
- } elseif (isset($_POST['deluser'])) {
- $name = $opensim->getUserName($_POST['userid']);
- if ($opensim->deleteUser($_POST['userid'])) {
- $HTML->ReplaceSeitenInhalt("%%MESSAGE%%", 'Der Account '.$name.' wurde gelöscht.
');
- } else {
- $HTML->ReplaceSeitenInhalt("%%MESSAGE%%", 'Der Account '.$name.' konnte nicht gelöscht werden.
');
- }
- }
- }
- }
- }
-
- $statement = $RUNTIME['PDO']->prepare("CREATE TABLE IF NOT EXISTS `InviteCodes` (`InviteCode` VARCHAR(64) NOT NULL, PRIMARY KEY (`InviteCode`))");
- $statement->execute();
-
- $table = 'Vorname Nachname Status Aktionen %%ENTRY%%
';
-
- // Only select current primary account
- $statement = $RUNTIME['PDO']->prepare("SELECT FirstName,LastName,UserLevel,PrincipalID FROM UserAccounts JOIN auth ON auth.UUID = UserAccounts.PrincipalID ORDER BY Created ASC");
- $statement->execute();
-
- $statementIdent = $RUNTIME['PDO']->prepare("SELECT FirstName,LastName,UserLevel,IdentityID FROM UserIdentitys JOIN UserAccounts ON UserAccounts.PrincipalID = UserIdentitys.IdentityID WHERE UserIdentitys.PrincipalID = ? AND UserIdentitys.PrincipalID != UserIdentitys.IdentityID");
- while ($row = $statement->fetch()) {
- $entry = ''.htmlspecialchars($row['FirstName']).' '.htmlspecialchars($row['LastName']).' '.htmlspecialchars($row['UserLevel']).' ';
- $statementIdent->execute([$row['PrincipalID']]);
- while ($identRow = $statementIdent->fetch()) {
- $entry = $entry.''.htmlspecialchars($identRow['FirstName']).' '.htmlspecialchars($identRow['LastName']).' '.htmlspecialchars($identRow['UserLevel']).' ';
- }
- $table = str_replace("%%ENTRY%%", $entry."%%ENTRY%%", $table);
- }
-
- $table = str_replace("%%ENTRY%%", "", $table);
- $HTML->ReplaceSeitenInhalt("%%USER-LIST%%", $table);
- $HTML->ReplaceSeitenInhalt("%%link%%", ' ');
- $HTML->ReplaceSeitenInhalt("%%MESSAGE%%", ' ');
-
- $HTML->build();
- echo $HTML->ausgabe();
diff --git a/plugins/default-html.php b/plugins/default-html.php
deleted file mode 100644
index f9873ae..0000000
--- a/plugins/default-html.php
+++ /dev/null
@@ -1,11 +0,0 @@
-importHTML("dashboard.html");
-
- if(isset($_SESSION['LEVEL']) && $_SESSION['LEVEL'] > 100) {
- $HTML->importHTML("dashboard-admin.html");
- }
-
- $HTML->ReplaceLayoutInhalt("%%USERNAME%%", isset($_SESSION['DISPLAYNAME']) ? htmlspecialchars($_SESSION['DISPLAYNAME']) : '');
- }