Initial commit

ZnoteX / Commit #5

Commit Initial commit

Alex Alex committed 01/10/2026 09:20 main Full upload
481 files +128,311 -0
A twofa.php +106-0 View file
@@ -0,0 +1,106 @@
1+<?php require_once 'engine/init.php';
2+znote_csrf_protect_public_post();
3+protect_page();
4+theme_open();
5+
6+$twofa2Enabled = znote2fa_v2_enabled();
7+
8+if ($config['twoFactorAuthenticator'] === false && !$twofa2Enabled) {
9+ die("Two-factor authentication is disabled in config.php");
10+}
11+
12+// When only 2FA v2 is enabled, this whole legacy-TFS section has nothing to
13+// offer - skip straight past it.
14+if ($config['twoFactorAuthenticator'] !== false) {
15+ if ($config['ServerEngine'] !== 'TFS_10') {
16+ view('twofa_legacy_incompatible', ['twofa2Enabled' => $twofa2Enabled]);
17+ } else {
18+ // If user wishes to disable Two-Factor Authentication
19+ if (isset($_POST['disable_2fa'])) {
20+ db()->execute("UPDATE `accounts` SET `secret` = NULL WHERE `id` = ? LIMIT 1;", [(int)$session_user_id]);
21+ db()->execute("UPDATE `znote_accounts` SET `secret` = NULL WHERE `account_id` = ? LIMIT 1;", [(int)$session_user_id]);
22+ }
23+
24+ // General init
25+ require_once("engine/function/rfc6238.php");
26+
27+ // Fetch the secret data from accounts and znote_accounts table
28+ $query = db()->fetchOne("SELECT `a`.`secret` AS `secret`, `za`.`secret` AS `znote_secret` FROM `accounts` AS `a` INNER JOIN `znote_accounts` AS `za` ON `a`.`id` = `za`.`account_id` WHERE `a`.`id` = ? LIMIT 1;", [(int)$session_user_id]);
29+
30+ // If secret column returns NULL on the regular accounts table, then it means the system is not active.
31+ $status = ($query['secret'] === NULL) ? false : true;
32+
33+ // If secret column returns NULL on the znote_accounts table, then it means we havent generated a secret for it yet.
34+ if ($query['znote_secret'] === NULL) {
35+ $scrtString = ($query['secret'] === NULL) ? generateRandomString(16) : $query['secret'];
36+ // Add secret to znote_accounts table
37+ db()->execute("UPDATE `znote_accounts` SET `secret` = ? WHERE `account_id` = ?;", [$scrtString, (int)$session_user_id]);
38+ $query['znote_secret'] = $scrtString;
39+ }
40+
41+ view('twofa_legacy', ['status' => $status, 'query' => $query]);
42+ }
43+}
44+
45+// ---------------------------------------------------------------------------
46+// 2FA v2 - independent of the game engine.
47+// ---------------------------------------------------------------------------
48+if ($twofa2Enabled) {
49+
50+ $accountId = (int)$session_user_id;
51+ $revealedRecoveryCodes = array();
52+ $successes = array();
53+
54+ if (empty($_POST) === false) {
55+ if (isset($_POST['tfa2_totp_start'])) {
56+ $secret = znote2fa_totp_start($accountId);
57+
58+ } else if (isset($_POST['tfa2_totp_confirm'])) {
59+ $code = getValue($_POST['tfa2_totp_code'] ?? null);
60+ if ($code !== false && znote2fa_totp_confirm($accountId, $code)) {
61+ $successes[] = t_default('twofa2.totp_confirmed', 'Authenticator app enabled.');
62+ } else {
63+ $errors[] = t_default('twofa2.totp_confirm_failed', 'That code did not match. Scan the QR code again and try once more.');
64+ }
65+
66+ } else if (isset($_POST['tfa2_totp_disable'])) {
67+ znote2fa_totp_disable($accountId);
68+
69+ } else if (isset($_POST['tfa2_email_toggle'])) {
70+ $enableEmailOtp = !empty($_POST['tfa2_email_enabled']);
71+ $email = trim((string)($user_data['email'] ?? ''));
72+ if ($enableEmailOtp && !znote2fa_v2_config()['email_otp_enabled']) {
73+ $errors[] = t_default('twofa2.email_unavailable', 'E-mail codes are disabled by the site administrator.');
74+ } else if ($enableEmailOtp && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
75+ $errors[] = t_default('twofa2.email_invalid', 'Add a valid e-mail address to your account before enabling e-mail codes.');
76+ } else {
77+ znote2fa_email_otp_set($accountId, $enableEmailOtp);
78+ }
79+
80+ } else if (isset($_POST['tfa2_recovery_generate'])) {
81+ $revealedRecoveryCodes = znote2fa_recovery_generate($accountId);
82+
83+ } else if (isset($_POST['tfa2_device_revoke'])) {
84+ znote2fa_trusted_device_revoke($accountId, (int)$_POST['tfa2_device_revoke']);
85+
86+ } else if (isset($_POST['tfa2_logout_all'])) {
87+ znote2fa_logout_all_devices($accountId);
88+ $_SESSION['tfa2_sv'] = znote2fa_session_version($accountId); // keep this session, the one that asked, alive
89+ znote2fa_trusted_cookie_clear();
90+ $successes[] = t_default('twofa2.logged_out_all', 'Every other session and trusted device has been signed out.');
91+ }
92+ }
93+
94+ $status = znote2fa_status($accountId);
95+ $devices = znote2fa_trusted_devices_list($accountId);
96+
97+ view('twofa2', [
98+ 'status' => $status,
99+ 'devices' => $devices,
100+ 'revealedRecoveryCodes' => $revealedRecoveryCodes,
101+ 'accountId' => $accountId,
102+ 'successes' => $successes,
103+ ]);
104+}
105+
106+theme_close(); ?>
A twtrNews.php +10-0 View file
@@ -0,0 +1,10 @@
1+<a class="twitter-timeline" href="https://twitter.com/ZnoteAAC" data-widget-id="353297614114021376"><?= t('twtr.tweets_from') ?> @ZnoteAAC</a>
2+<script>
3+!function(d,s,id){
4+ var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';
5+ if(!d.getElementById(id)){
6+ js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";
7+ fjs.parentNode.insertBefore(js,fjs);
8+ }
9+}(document,"script","twitter-wjs");
10+</script>
A voting.php +75-0 View file
@@ -0,0 +1,75 @@
1+<?php
2+require_once 'engine/init.php';
3+theme_open();
4+
5+$otservers_eu_voting = $config['otservers_eu_voting'];
6+$votingMessage = '';
7+
8+if ($otservers_eu_voting['enabled']) {
9+ if (user_logged_in()) {
10+ $isRewardRequest = isset($_GET['action']) && $_GET['action'] === 'reward';
11+ if (!$isRewardRequest) {
12+ $result = vote($user_data['id'], $otservers_eu_voting);
13+ if ($result === false) {
14+ $votingMessage = t('voting.request_failed');
15+ } else {
16+ header('Location: ' . $result['voteLink']);
17+ die;
18+ }
19+ } else {
20+ $result = checkHasVoted($user_data['id'], $otservers_eu_voting);
21+ if ($result !== false) {
22+ if ($result['voted'] === true) {
23+ $points = $otservers_eu_voting['points'];
24+ $pointsText = $points === '1' ? t('voting.point_singular') : t('voting.point_plural');
25+ db()->execute("UPDATE `znote_accounts` SET `points` = `points` + ? WHERE `account_id` = ?", [(int)$points, (int)$user_data['id']]);
26+ $votingMessage = t('voting.rewarded', ['points' => $points, 'unit' => $pointsText]);
27+ } else {
28+ $votingMessage = t('voting.not_voted');
29+ }
30+ } else {
31+ $votingMessage = t('voting.cannot_verify');
32+ }
33+ }
34+ } else {
35+ header('Location: ' . $otservers_eu_voting['simpleVoteUrl']);
36+ die;
37+ }
38+} else {
39+ $votingMessage = t('voting.disabled');
40+}
41+
42+view('voting');
43+theme_close();
44+
45+function vote($otUserId, $otservers_eu_voting) {
46+ $context = stream_context_create([
47+ 'http' => [
48+ 'header' => "Content-type: application/json",
49+ 'method' => 'POST',
50+ 'content' => json_encode([
51+ 'otUserId' => $otUserId,
52+ 'secretToken' => $otservers_eu_voting['secretToken'],
53+ 'landingPage' => $otservers_eu_voting['landingPage']
54+ ])
55+ ]
56+ ]);
57+ $result = file_get_contents($otservers_eu_voting['voteUrl'], false, $context);
58+ return $result !== false ? json_decode($result, true) : false;
59+}
60+
61+function checkHasVoted($otUserId, $otservers_eu_voting) {
62+ $context = stream_context_create([
63+ 'http' => [
64+ 'header' => "Content-type: application/json",
65+ 'method' => 'POST',
66+ 'content' => json_encode([
67+ 'otUserId' => $otUserId,
68+ 'secretToken' => $otservers_eu_voting['secretToken'],
69+ 'consume' => true
70+ ])
71+ ]
72+ ]);
73+ $result = file_get_contents($otservers_eu_voting['voteCheckUrl'], false, $context);
74+ return $result !== false ? json_decode($result, true) : false;
75+}
Top