1
0
mirror of https://github.com/Daichimarukana/uwuzu.git synced 2026-06-04 19:14:41 +00:00

uwuzu v1.6.8 Hapuego

This commit is contained in:
だいちまる
2025-12-30 03:21:39 +09:00
parent 0666b6b2c4
commit b0b7b305eb
23 changed files with 1685 additions and 210 deletions
+141
View File
@@ -0,0 +1,141 @@
<?php
$domain = $_SERVER['HTTP_HOST'];
require(__DIR__ . '/../../../db.php');
require(__DIR__ . "/../../../function/function.php");
blockedIP($_SERVER['REMOTE_ADDR']);
header("Content-Type: application/json; charset=utf-8");
header("Access-Control-Allow-Origin: *");
//----------------------------------------------------------------
//--------------------------管理者向けAPI---------------------------
//----------------------------------------------------------------
$pdo = null;
try {
$option = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_MULTI_STATEMENTS => false
);
$pdo = new PDO('mysql:charset=utf8mb4;dbname=' . DB_NAME . ';host=' . DB_HOST, DB_USER, DB_PASS, $option);
} catch (PDOException $e) {
// 接続エラーのときエラー内容を取得する
$error_message[] = $e->getMessage();
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode([
'error_code' => 'method_not_allowed',
'success' => false
]);
exit;
}
$Get_Post_Json = file_get_contents("php://input");
if ((!(empty($Get_Post_Json)))) {
//トークン取得
$post_json = json_decode($Get_Post_Json, true);
if (isset($post_json["token"])) {
$token = safetext($post_json["token"]);
} else {
$err = "input_not_found";
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
if ($token == "") {
$err = "input_not_found";
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
if(!(empty($post_json["limit"]))){
$limit = (int)$post_json["limit"];
}else{
$limit = 50;
}
if($limit > 500){
$limit = 500;
}
if(!(empty($post_json["page"]))){
$page = (int)$post_json["page"];
}else{
$page = 1;
}
$offset = ($page - 1) * $limit;
session_start();
if (!empty($pdo)) {
$AuthData = APIAuth($pdo, $token, "read:admin:reports");
if ($AuthData[0] === true && $AuthData[2]["admin"] == "yes") {
$sql = "SELECT * FROM report WHERE admin_chk = 'none' ORDER BY datetime DESC LIMIT :offset, :itemsPerPage";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->bindValue(':itemsPerPage', $limit, PDO::PARAM_INT);
$stmt->execute();
$allreport = $stmt;
while ($row = $allreport->fetch(PDO::FETCH_ASSOC)) {
$reports[] = $row;
}
$groupedReports = [];
if (!empty($reports)) {
foreach ($reports as $row) {
$reportedUserId = $row['userid'];
if (!isset($groupedReports[$reportedUserId])) {
$groupedReports[$reportedUserId] = [
'reported_userid' => $reportedUserId,
'total_count' => 0,
'details' => []
];
}
$groupedReports[$reportedUserId]['details'][] = [
'uniqid' => $row['uniqid'],
'reporter_userid' => $row['report_userid'],
'message' => $row['msg'],
'datetime' => $row['datetime']
];
$groupedReports[$reportedUserId]['total_count']++;
}
}
echo json_encode([
'success' => true,
'data' => array_values($groupedReports)
], JSON_UNESCAPED_UNICODE);
} else {
$err = $AuthData[1];
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
}
}
} else {
$err = "input_not_found";
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
}
+167
View File
@@ -0,0 +1,167 @@
<?php
$domain = $_SERVER['HTTP_HOST'];
require(__DIR__ . '/../../../db.php');
require(__DIR__ . "/../../../function/function.php");
blockedIP($_SERVER['REMOTE_ADDR']);
header("Content-Type: application/json; charset=utf-8");
header("Access-Control-Allow-Origin: *");
//----------------------------------------------------------------
//--------------------------管理者向けAPI---------------------------
//----------------------------------------------------------------
$pdo = null;
try {
$option = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_MULTI_STATEMENTS => false
);
$pdo = new PDO('mysql:charset=utf8mb4;dbname=' . DB_NAME . ';host=' . DB_HOST, DB_USER, DB_PASS, $option);
} catch (PDOException $e) {
// 接続エラーのときエラー内容を取得する
$error_message[] = $e->getMessage();
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode([
'error_code' => 'method_not_allowed',
'success' => false
]);
exit;
}
$Get_Post_Json = file_get_contents("php://input");
if ((!(empty($Get_Post_Json)))) {
//トークン取得
$post_json = json_decode($Get_Post_Json, true);
if (isset($post_json["token"])) {
$token = safetext($post_json["token"]);
} else {
$err = "input_not_found";
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
if ($token == "") {
$err = "input_not_found";
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
if(!(empty($post_json["uniqid"]))){
$uniqid = safetext($post_json["uniqid"]);
}else{
$uniqid = null;
}
if(!(empty($post_json["reported_userid"]))){
$reported_userid = safetext($post_json["reported_userid"]);
}else{
$reported_userid = null;
}
session_start();
if (!empty($pdo)) {
$AuthData = APIAuth($pdo, $token, "write:admin:reports");
if ($AuthData[0] === true && $AuthData[2]["admin"] == "yes") {
if(!(empty($uniqid))){
$newchk = "done";
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare("UPDATE report SET admin_chk = :adchk WHERE uniqid = :uniqid");
$stmt->bindValue(':adchk', $newchk, PDO::PARAM_STR);
$stmt->bindValue(':uniqid', $uniqid, PDO::PARAM_STR);
$res = $stmt->execute();
if ($res) {
$pdo->commit();
$response = array(
'success' => true,
'uniqid' => $uniqid
);
} else {
$response = array(
'error_code' => 'could_not_complete',
'success' => false
);
$pdo->rollBack();
actionLog($AuthData[2]["userid"], "error", "admin-reports-resolve-api", null, "通報の解決に失敗しました", 3);
}
} catch (Exception $e) {
$response = array(
'error_code' => 'db_error_update',
'success' => false
);
$pdo->rollBack();
actionLog($AuthData[2]["userid"], "error", "admin-reports-resolve-api", null, $e, 4);
}
}elseif(!(empty($reported_userid))){
$newchk = "done";
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare("UPDATE report SET admin_chk = :adchk WHERE userid = :userid");
$stmt->bindValue(':adchk', $newchk, PDO::PARAM_STR);
$stmt->bindValue(':userid', $reported_userid, PDO::PARAM_STR);
$res = $stmt->execute();
if ($res) {
$pdo->commit();
$response = array(
'success' => true,
'reported_userid' => $reported_userid
);
} else {
$response = array(
'error_code' => 'could_not_complete',
'success' => false
);
$pdo->rollBack();
actionLog($AuthData[2]["userid"], "error", "admin-reports-resolve-api", null, "通報の解決に失敗しました", 3);
}
} catch (Exception $e) {
$response = array(
'error_code' => 'db_error_update',
'success' => false
);
$pdo->rollBack();
actionLog($AuthData[2]["userid"], "error", "admin-reports-resolve-api", null, $e, 4);
}
}else{
$response = array(
'error_code' => 'input_not_found',
'success' => false
);
}
echo json_encode($response, JSON_UNESCAPED_UNICODE);
} else {
$err = $AuthData[1];
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
}
}
} else {
$err = "input_not_found";
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
}
+265
View File
@@ -0,0 +1,265 @@
<?php
$domain = $_SERVER['HTTP_HOST'];
require(__DIR__ . '/../../../db.php');
require(__DIR__ . "/../../../function/function.php");
blockedIP($_SERVER['REMOTE_ADDR']);
header("Content-Type: application/json; charset=utf-8");
header("Access-Control-Allow-Origin: *");
//----------------------------------------------------------------
//--------------------------管理者向けAPI---------------------------
//----------------------------------------------------------------
$pdo = null;
try {
$option = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_MULTI_STATEMENTS => false
);
$pdo = new PDO('mysql:charset=utf8mb4;dbname=' . DB_NAME . ';host=' . DB_HOST, DB_USER, DB_PASS, $option);
} catch (PDOException $e) {
// 接続エラーのときエラー内容を取得する
$error_message[] = $e->getMessage();
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode([
'error_code' => 'method_not_allowed',
'success' => false
]);
exit;
}
$Get_Post_Json = file_get_contents("php://input");
if ((!(empty($Get_Post_Json)))) {
//トークン取得
$post_json = json_decode($Get_Post_Json, true);
if (isset($post_json["token"])) {
$token = safetext($post_json["token"]);
} else {
$err = "input_not_found";
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
if ($token == "") {
$err = "input_not_found";
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
if(!(empty($post_json["userid"]))) {
$userid = safetext($post_json["userid"]);
} else {
$err = "input_not_found";
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
session_start();
if (!empty($pdo)) {
$AuthData = APIAuth($pdo, $token, "read:admin:users");
if ($AuthData[0] === true && $AuthData[2]["admin"] == "yes") {
$userdata = getUserData($pdo, $userid);
if (empty($userdata)) {
$response = array(
'error_code' => "critical_error_userdata_not_found",
);
} else {
$roles = explode(',', $userdata["role"]);
if (!(empty($roles))) {
foreach ($roles as $roleId) {
$Getrole = $pdo->prepare("SELECT roleidname, rolename, roleauth, rolecolor, roleeffect FROM role WHERE roleidname = :role");
$Getrole->bindValue(':role', $roleId);
$Getrole->execute();
$roleData[$roleId] = $Getrole->fetch();
if ($roleData[$roleId]['roleeffect'] == '' || $roleData[$roleId]['roleeffect'] == 'none') {
$role_view_effect = "none";
} elseif ($roleData[$roleId]['roleeffect'] == 'shine') {
$role_view_effect = "shine";
} elseif ($roleData[$roleId]['roleeffect'] == 'rainbow') {
$role_view_effect = "rainbow";
} else {
$role_view_effect = "none";
}
$roleinfo = array(
"name" => decode_yajirushi(htmlspecialchars_decode($roleData[$roleId]['rolename'])),
"color" => decode_yajirushi(htmlspecialchars_decode($roleData[$roleId]['rolecolor'])),
"effect" => decode_yajirushi(htmlspecialchars_decode($role_view_effect)),
"id" => decode_yajirushi(htmlspecialchars_decode($roleData[$roleId]['roleidname'])),
);
$role[] = $roleinfo;
}
} else {
$role[] = "";
}
if (!(empty($userdata["sacinfo"]))) {
if ($userdata["sacinfo"] == "bot") {
$isBot = true;
} else {
$isBot = false;
}
} else {
$isBot = false;
}
if (!(empty($userdata["admin"]))) {
if ($userdata["admin"] == "yes") {
$isAdmin = true;
} else {
$isAdmin = false;
}
} else {
$isAdmin = false;
}
$isPublicOnlineStatus = val_OtherSettings("isPublicOnlineStatus", $userdata["other_settings"]);
if ($isPublicOnlineStatus === true) {
if (!(empty($userdata["last_login_datetime"]))) {
$lastLogin = new DateTime($userdata["last_login_datetime"]);
$now = new DateTime();
$interval = $now->diff($lastLogin);
$minutesPast = ($interval->days * 24 * 60) + ($interval->h * 60) + $interval->i;
$status_datetime = $userdata["last_login_datetime"];
if ($minutesPast <= 5) {
$online_status = "Online";
$real_online_status = "Online";
} elseif ($minutesPast <= 15) {
$online_status = "Away";
$real_online_status = "Away";
} else {
$online_status = "Offline";
$real_online_status = "Offline";
}
} else {
$online_status = "Offline";
$real_online_status = "Offline";
}
} else {
$online_status = null;
if (!(empty($userdata["last_login_datetime"]))) {
$lastLogin = new DateTime($userdata["last_login_datetime"]);
$now = new DateTime();
$interval = $now->diff($lastLogin);
$minutesPast = ($interval->days * 24 * 60) + ($interval->h * 60) + $interval->i;
$status_datetime = $userdata["last_login_datetime"];
if ($minutesPast <= 5) {
$real_online_status = "Online";
} elseif ($minutesPast <= 15) {
$real_online_status = "Away";
} else {
$real_online_status = "Offline";
}
} else {
$real_online_status = "Offline";
}
}
$followee = getFolloweeList($pdo, $userdata["userid"]);
if ($followee === false) {
$followee = array();
}
$follower = getFollowerList($pdo, $userdata["userid"]);
if ($follower === false) {
$follower = array();
}
$userdata["follow_cnt"] = (int)count($followee);
$userdata["follower_cnt"] = (int)count($follower);
$allueuse = $pdo->prepare("SELECT account FROM ueuse WHERE account = :userid");
$allueuse->bindValue(':userid', $userdata["userid"]);
$allueuse->execute();
$All_ueuse = $allueuse->rowCount();
if (!(empty($userdata["encryption_ivkey"]))) {
$view_mailadds = DecryptionUseEncrKey($userdata["mailadds"], GenUserEnckey($userdata["datetime"]), $userdata["encryption_ivkey"]);
$view_ip_addr = DecryptionUseEncrKey($userdata["last_ip"], GenUserEnckey($userdata["datetime"]), $userdata["encryption_ivkey"]);
} else {
$view_mailadds = $userdata["mailadds"];
$view_ip_addr = $userdata["last_ip"];
}
if (!empty($userdata["authcode"])) {
$is_2fa_configured = true;
} else {
$is_2fa_configured = false;
}
$response = array(
'success' => true,
'username' => decode_yajirushi(htmlspecialchars_decode($userdata["username"])),
'userid' => decode_yajirushi(htmlspecialchars_decode($userdata["userid"])),
'profile' => decode_yajirushi(htmlspecialchars_decode($userdata["profile"])),
'user_icon' => decode_yajirushi(htmlspecialchars_decode(localcloudURLtoAPI(localcloudURL($userdata["iconname"])))),
'user_header' => decode_yajirushi(htmlspecialchars_decode(localcloudURLtoAPI(localcloudURL($userdata["headname"])))),
'registered_date' => decode_yajirushi(htmlspecialchars_decode($userdata["datetime"])),
'followee' => $followee,
'followee_cnt' => $userdata["follow_cnt"],
'follower' => $follower,
'follower_cnt' => $userdata["follower_cnt"],
'ueuse_cnt' => $All_ueuse,
'isBot' => $isBot,
'isAdmin' => $isAdmin,
'role' => $role,
'online_status' => $online_status,
'real_online_status' => $real_online_status,
'last_login_datetime' => $userdata["last_login_datetime"],
'last_login_ipaddress' => $view_ip_addr,
'mailaddress' => $view_mailadds,
'is_2fa_configured' => $is_2fa_configured,
'language' => "ja-JP",
);
}
echo json_encode($response, JSON_UNESCAPED_UNICODE);
} else {
$err = $AuthData[1];
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
}
}
} else {
$err = "input_not_found";
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
}
+409
View File
@@ -0,0 +1,409 @@
<?php
$domain = $_SERVER['HTTP_HOST'];
require_once(__DIR__ . '/../../../db.php');
require_once(__DIR__ . "/../../../function/function.php");
blockedIP($_SERVER['REMOTE_ADDR']);
header("Content-Type: application/json; charset=utf-8");
header("Access-Control-Allow-Origin: *");
//----------------------------------------------------------------
//--------------------------管理者向けAPI---------------------------
//----------------------------------------------------------------
$serversettings_file = __DIR__ . "/../../../server/serversettings.ini";
$serversettings = parse_ini_file($serversettings_file, true);
//phpmailer--------------------------------------------
require_once(__DIR__ . '/../../../settings_admin/plugin_settings/phpmailer_settings.php');
require_once(__DIR__ . '/../../../settings_admin/plugin_settings/phpmailer_sender.php');
//------------------------------------------------------
//2fa---------------------------------------------------
require_once(__DIR__ . '/../../../authcode/GoogleAuthenticator.php');
//------------------------------------------------------
$pdo = null;
try {
$option = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_MULTI_STATEMENTS => false
);
$pdo = new PDO('mysql:charset=utf8mb4;dbname=' . DB_NAME . ';host=' . DB_HOST, DB_USER, DB_PASS, $option);
} catch (PDOException $e) {
// 接続エラーのときエラー内容を取得する
$error_message[] = $e->getMessage();
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode([
'error_code' => 'method_not_allowed',
'success' => false
]);
exit;
}
$Get_Post_Json = file_get_contents("php://input");
if ((!(empty($Get_Post_Json)))) {
//トークン取得
$post_json = json_decode($Get_Post_Json, true);
if (isset($post_json["token"])) {
$token = safetext($post_json["token"]);
} else {
$err = "input_not_found";
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
if ($token == "") {
$err = "input_not_found";
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
if (!(empty($post_json["userid"]))) {
$userid = safetext($post_json["userid"]);
} else {
$err = "input_not_found";
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
if (!(empty($post_json["type"]))) {
$type = safetext($post_json["type"]);
} else {
$err = "input_not_found";
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
session_start();
if (!empty($pdo)) {
$AuthData = APIAuth($pdo, $token, "write:admin:user-sanction");
if ($AuthData[0] === true && $AuthData[2]["admin"] == "yes") {
$userdata = getUserData($pdo, $userid);
if (empty($userdata)) {
$response = array(
'error_code' => "critical_error_userdata_not_found",
);
} else {
if (!(empty($userdata["encryption_ivkey"]))) {
$view_mailadds = DecryptionUseEncrKey($userdata["mailadds"], GenUserEnckey($userdata["datetime"]), $userdata["encryption_ivkey"]);
$view_ip_addr = DecryptionUseEncrKey($userdata["last_ip"], GenUserEnckey($userdata["datetime"]), $userdata["encryption_ivkey"]);
} else {
$view_mailadds = $userdata["mailadds"];
$view_ip_addr = $userdata["last_ip"];
}
if ($type == "notification") {
if (!(empty($post_json["notification_title"]))) {
$notice_title = safetext($post_json["notification_title"]);
} else {
$err = "input_not_found";
}
if (!(empty($post_json["notification_message"]))) {
$notice_msg = safetext($post_json["notification_message"]);
} else {
$err = "input_not_found";
}
if (empty($notice_title)) {
$err = "input_not_found";
} elseif (mb_strlen($notice_title) > 512) {
$err = "content_to_512_characters";
}
if (empty($notice_msg)) {
$err = "input_not_found";
} elseif (mb_strlen($notice_msg) > 16777216) {
$err = "content_to_16777216_characters";
}
if (empty($err)) {
$url = safetext("/rule/serverabout");
$response = send_notification($userdata['userid'], "uwuzu-fromsys", $notice_title, $notice_msg, $url, "system");
if ($response == true) {
actionLog($AuthData[2]["userid"], "info", "admin-user-sanction-api-send_notification", $userdata['userid'], $userdata['userid'] . "さんに" . $AuthData[2]["userid"] . "さんが通知を送信しました。\n" . $notice_msg, 0);
$response = array(
'success' => true,
'userid' => $userdata['userid']
);
} else {
actionLog($AuthData[2]["userid"], "error", "admin-user-sanction-api-send_notification", $userdata['userid'], $userdata['userid'] . "さんに" . $AuthData[2]["userid"] . "さんが通知を送信できませんでした。\n" . $notice_msg, 4);
$response = array(
'error_code' => "could_not_complete",
'success' => false
);
}
} else {
$response = array(
'error_code' => $err,
'success' => false
);
}
} elseif ($type == "frozen") {
if(!($userdata["role"] === "ice")){
if (!(empty($post_json["notification_message"]))) {
$notice_msg = safetext($post_json["notification_message"]);
} else {
$err = "input_not_found";
}
// --- バリデーション ---
if (empty($notice_msg)) {
$err = "input_not_found";
} elseif (mb_strlen($notice_msg) > 16777216) {
$err = "content_to_16777216_characters";
}
if (empty($err)) {
$touserid = $userdata['userid'];
$newrole = "ice";
$newtoken = "ice";
$newadmin = "none";
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare("UPDATE account SET role = :role, token = :newtoken, admin = :newadmin WHERE userid = :userid");
$stmt->bindValue(':role', $newrole, PDO::PARAM_STR);
$stmt->bindValue(':newtoken', $newtoken, PDO::PARAM_STR);
$stmt->bindValue(':newadmin', $newadmin, PDO::PARAM_STR);
$stmt->bindValue(':userid', $touserid, PDO::PARAM_STR);
$stmt->execute();
$pdo->commit();
$account_updated = true;
} catch (Exception $e) {
$pdo->rollBack();
$account_updated = false;
$err_msg = $e->getMessage();
}
if ($account_updated) {
$notice_title = "🧊お使いのアカウントは凍結されました。🧊";
$full_msg = "サービス管理者からのメッセージは以下のものです。\n" . $notice_msg . "\n異議申し立てする場合は連絡用メールに異議申し立てをする旨を記載し送信をしてください。";
$url = safetext("/rule/serverabout");
$notif_res = send_notification($touserid, "uwuzu-fromsys", $notice_title, $full_msg, $url, "system");
if (false !== strpos($userdata["mail_settings"], 'important')) {
if (!empty(MAIL_CHKS) && MAIL_CHKS == "true") {
if (!empty($view_mailadds) && filter_var($view_mailadds, FILTER_VALIDATE_EMAIL)) {
$mail_title = "お使いの" . safetext($serversettings["serverinfo"]["server_name"]) . "アカウントは凍結されました";
$mail_text = "".$userdata["username"]."(".$userdata["userid"].")さん いつもuwuzuをご利用いただきありがとうございます。 ご利用のアカウント(".$userdata["userid"].")が".safetext($serversettings["serverinfo"]["server_name"])."管理者により凍結されたためお知らせいたします。 サービス管理者からのメッセージは以下のものです。 ". safetext($notice_msg) ." 異議申し立てする場合は[".safetext($serversettings["serverinfo"]["server_admin_mailadds"])."]まで異議申し立てをする旨を記載し送信をしてください。";
$sendmail_error_message[] = send_html_mail($view_mailadds, $mail_title, $mail_text, "../../../");
if(!(empty($sendmail_error_message))){
actionLog($AuthData[2]["userid"], "error", "admin-user-sanction-api-frozen", $userdata['userid'], $sendmail_error_message, 3);
}
}
}
}
actionLog($AuthData[2]["userid"], "info", "admin-user-sanction-api-frozen", $touserid, $touserid . "さんを" . $AuthData[2]["userid"] . "さんが凍結しました。\n理由: " . $notice_msg, 0);
$response = array(
'success' => true,
'userid' => $touserid
);
} else {
actionLog($AuthData[2]["userid"], "error", "admin-user-sanction-api-frozen", $touserid, $err_msg, 4);
$response = array(
'error_code' => "could_not_complete",
'success' => false
);
}
} else {
$response = array(
'error_code' => $err,
'success' => false
);
}
}else{
$response = array(
'error_code' => "already_been_completed",
'success' => false
);
}
} elseif ($type == "unfrozen") {
if($userdata["role"] === "ice"){
$touserid = $userdata['userid'];
$newrole = "user";
$newtoken = "";
$newadmin = "none";
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare("UPDATE account SET role = :role, token = :newtoken, admin = :newadmin WHERE userid = :userid");
$stmt->bindValue(':role', $newrole, PDO::PARAM_STR);
$stmt->bindValue(':newtoken', $newtoken, PDO::PARAM_STR);
$stmt->bindValue(':newadmin', $newadmin, PDO::PARAM_STR);
$stmt->bindValue(':userid', $touserid, PDO::PARAM_STR);
$stmt->execute();
$pdo->commit();
$account_updated = true;
} catch (Exception $e) {
$pdo->rollBack();
$account_updated = false;
$err_msg = $e->getMessage();
}
if ($account_updated) {
$notice_title = "🫗お使いのアカウントが解凍されました!🫗";
$full_msg = "サービス管理者によりお使いのアカウントは解凍されました!\n今まで通りご利用いただけます。";
$url = safetext("/home");
$notif_res = send_notification($touserid, "uwuzu-fromsys", $notice_title, $full_msg, $url, "system");
if (false !== strpos($userdata["mail_settings"], 'important')) {
if (!empty(MAIL_CHKS) && MAIL_CHKS == "true") {
if (!empty($view_mailadds) && filter_var($view_mailadds, FILTER_VALIDATE_EMAIL)) {
$mail_title = "お使いの" . safetext($serversettings["serverinfo"]["server_name"]) . "アカウントは解凍されました!";
$mail_text = "".$userdata["username"]."(".$userdata["userid"].")さん いつもuwuzuをご利用いただきありがとうございます。 ご利用のアカウント(".$userdata["userid"].")が解凍されたためお知らせいたします。 今後、ご利用のuwuzuアカウントは今まで通りご利用いただけます。";
$sendmail_error_message[] = send_html_mail($view_mailadds, $mail_title, $mail_text, "../../../");
if(!(empty($sendmail_error_message))){
actionLog($AuthData[2]["userid"], "error", "admin-user-sanction-api-unfrozen", $userdata['userid'], $sendmail_error_message, 3);
}
}
}
}
actionLog($AuthData[2]["userid"], "info", "admin-user-sanction-api-unfrozen", $touserid, $touserid . "さんを" . $AuthData[2]["userid"] . "さんが解凍しました", 0);
$response = array(
'success' => true,
'userid' => $touserid
);
} else {
actionLog($AuthData[2]["userid"], "error", "admin-user-sanction-api-unfrozen", $touserid, $err_msg, 4);
$response = array(
'error_code' => "could_not_complete",
'success' => false
);
}
}else{
$response = array(
'error_code' => "already_been_completed",
'success' => false
);
}
} elseif ($type == "ban") {
if($userdata["role"] === "ice"){
if (!(empty($post_json["really"]))) {
$really = safetext($post_json["really"]);
} else {
$err = "input_not_found";
}
if (empty($really)) {
$err = "input_not_found";
}else{
if(!(empty($AuthData[2]["authcode"]))){
if(!(empty($AuthData[2]["encryption_ivkey"])) && (!(mb_strlen($AuthData[2]["authcode"]) === 16))){
$private_authcode = DecryptionUseEncrKey($AuthData[2]["authcode"], GenUserEnckey($AuthData[2]["datetime"]), $AuthData[2]["encryption_ivkey"]);
}else{
$private_authcode = $AuthData[2]["authcode"];
}
$chkauthcode = new PHPGangsta_GoogleAuthenticator();
$checkResult = $chkauthcode->verifyCode($private_authcode, $really, 2);
if ($checkResult == false) {
$err = "input_not_found";
}
}else{
if(!($really === "yes_i_will_delete_".safetext($userdata["userid"]))){
$err = "input_not_found";
}
}
}
if (empty($err)) {
try{
$res = addJob($pdo, $userdata['userid'], "deleteUser", "stop_account");
if ($res) {
actionLog($AuthData[2]["userid"], "info", "admin-user-sanction-api-ban", $userdata['userid'], $AuthData[2]["userid"]."さんが".$userdata['userid']."さんをBANしました", 4);
$response = array(
'success' => true,
'userid' => $userdata['userid']
);
//BAN通知メール
if(false !== strpos($userdata["mail_settings"], 'important')) {
if(!empty(MAIL_CHKS)){
if(MAIL_CHKS == "true"){
if( !empty($view_mailadds) ){
if(filter_var($view_mailadds, FILTER_VALIDATE_EMAIL)){
$mail_title = "お使いの".safetext($serversettings["serverinfo"]["server_name"])."アカウントはBANされました";
$mail_text = "".$userdata["username"]."(".$userdata["userid"].")さん いつもuwuzuをご利用いただきありがとうございます。 この度、ご利用のアカウント(".$userdata["userid"].")が".safetext($serversettings["serverinfo"]["server_name"])."管理者によりBAN(削除)されたためお知らせいたします。 今後は今までご利用いただいた".safetext($serversettings["serverinfo"]["server_name"])."アカウントは利用できません。 ".safetext($serversettings["serverinfo"]["server_name"])."サーバー上から今までご利用いただいていたアカウントの情報は削除されたためログインなどもできません。 ご理解とご協力のほどよろしくお願いします。";
$error_message[] = send_html_mail($view_mailadds,$mail_title,$mail_text,"../../../");
}
}
}
}
}
//------------
} else {
$error_message[] = 'アカウント削除に失敗しました。(ACCOUNT_DELETE_DAME)';
actionLog($AuthData[2]["userid"], "error", "admin-user-sanction-api-ban", $userdata['userid'], $error_message[], 4);
}
} catch (Exception $e) {
$pdo->rollBack();
actionLog($AuthData[2]["userid"], "error", "admin-user-sanction-api-ban", $userdata['userid'], $e, 4);
}
}else{
$response = array(
'error_code' => $err,
'success' => false
);
}
}else{
$response = array(
'error_code' => "user_not_frozen_cant_be_banned",
'success' => false
);
}
} else {
$response = array(
'error_code' => "input_not_found",
'success' => false
);
}
}
echo json_encode($response, JSON_UNESCAPED_UNICODE);
} else {
$err = $AuthData[1];
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
}
}
} else {
$err = "input_not_found";
$response = array(
'error_code' => $err,
'success' => false
);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
}
+14 -3
View File
@@ -96,6 +96,13 @@ $is_trueclient = false;
if(!(empty($_GET["session"])) && !(empty($_GET["client"])) && !(empty($_GET["scope"]))){
$is_trueclient = true;
$session_code = safetext($_GET["session"]);
if($is_Admin == "yes"){
$admin_permission = true;
}else{
$admin_permission = false;
}
if(strlen($session_code) > 512){
$is_trueclient = false;
}
@@ -114,8 +121,8 @@ if(!(empty($_GET["session"])) && !(empty($_GET["client"])) && !(empty($_GET["sco
$securityScopesView = false;
foreach ($client_scope_base as $scope) {
if (GetAPIScopes($scope)) {
$client_scope[] = GetAPIScopes($scope);
if (GetAPIScopes($scope, $admin_permission)) {
$client_scope[] = GetAPIScopes($scope, $admin_permission);
if($securityScopesView === false && in_array($scope, $securityScopes)){
$securityScopesView = true;
}
@@ -156,7 +163,7 @@ if($is_trueclient === true){
}
foreach ($client_scope_base as $scope) {
if (GetAPIScopes($scope)) {
if (GetAPIScopes($scope, $admin_permission)) {
$client_scope_done[] = $scope;
}else{
$client_scope_done = array();
@@ -196,6 +203,10 @@ if($is_trueclient === true){
$pdo->rollBack();
}
if($res) {
if($admin_permission === true){
actionLog($userid, "info", "api/auth", $client_name, "管理者のアカウントでAPIトークンが発行されました。\n".$client_scope_done, 4);
}
if(!(empty($client_callback))){
header("Location: ".$client_callback."");
exit;
+1
View File
@@ -206,6 +206,7 @@ $pdo = null;
<div id="Big_ImageModal" class="Image_modal">
<div class="modal-content">
<img id="Big_ImageMain" href="">
<div id="NoAI_Footer" class="warning-footer"><span>No AI</span>機械学習への利用を一切拒否します。</div>
</div>
</div>
+284 -37
View File
@@ -16,12 +16,12 @@
background: var(--main-color);
}
.flexbox{
.flexbox {
display: flex;
}
.btnbox{
.btnbox {
width: auto;
margin: 0px auto;
}
@@ -176,7 +176,8 @@ textarea {
line-height: 20px;
border: 1px solid var(--error);
}
.justfit{
.justfit {
margin: 16px 0px;
}
@@ -588,7 +589,6 @@ main h1 {
width: 148px;
height: 148px;
border-radius: 50%;
box-shadow: 0 0px 48px 0 rgba(0, 0, 0, .05);
}
.userheader .icon h2 img {
@@ -602,6 +602,29 @@ main h1 {
border-radius: 0px;
}
.userheader .icon .status {
position: relative;
left: calc(-24px + -8px);
top: calc(32px - 4px);
width: 24px;
height: 24px;
border-radius: 50%;
background-color: #CCC;
border: solid 4px var(--tl-color);
}
.userheader .icon .green {
background-color: #00cc4e;
}
.userheader .icon .yellow {
background-color: #ffc400;
}
.userheader .icon .gray {
background-color: #CCC;
}
.userheader h2 {
word-wrap: break-word;
margin-left: 12px;
@@ -1257,6 +1280,7 @@ main h1 {
transition: 0.5s;
opacity: 0;
}
.ueuse .blur:hover * {
opacity: 1;
}
@@ -2436,7 +2460,7 @@ main h1 {
margin-top: auto;
margin-bottom: auto;
margin-left: 6px;
border-radius: 6px;
border-radius: 16px;
background-color: var(--background-color);
border: 1px solid var(--border-color);
}
@@ -2444,8 +2468,8 @@ main h1 {
.ueuse .reuse_box .reuse_flebox .idbox a {
margin-top: 3px;
margin-bottom: 3px;
margin-left: 4px;
margin-right: 4px;
margin-left: 8px;
margin-right: 8px;
text-align: center;
font-size: 12px;
text-decoration: none;
@@ -2852,6 +2876,85 @@ main h1 {
font-weight: normal;
}
/*
.sendbox #preview_container {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 10px;
}
.sendbox .preview-item {
background: linear-gradient(45deg, #CCC 25%, transparent 25%, transparent 75%, #CCC 75%),
linear-gradient(45deg, #CCC 25%, transparent 25%, transparent 75%, #CCC 75%);
background-color: #FFF;
background-size: 20px 20px;
background-position: 0 0, 10px 10px;
border: 1px solid #ccc;
position: relative;
border-radius: 10px;
overflow: hidden;
}
.sendbox .img-preview img {
width: 96px;
height: 96px;
object-fit: cover;
display: block;
}
.sendbox .video-preview {
width: 128px;
height: 96px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: white;
}
.sendbox .video-preview img {
width: 100%;
height: 100%;
object-fit: cover;
}
.sendbox .video-preview.simple {
background: #333;
}
.sendbox .video-preview.simple .video-label {
font-size: 16px;
margin-bottom: 4px;
}
.sendbox .video-preview.simple .video-size {
font-size: 12px;
color: #aaa;
}
.sendbox .remove-preview {
opacity: 0.5;
position: absolute;
top: 4px;
right: 4px;
background-color: #000;
color: #FFF;
border-radius: 50%;
width: 24px;
height: 24px;
line-height: 22px;
text-align: center;
cursor: pointer;
font-weight: bold;
z-index: 10;
transition: all ease-out 250ms;
border: solid 1px transparent;
}
.sendbox .remove-preview:hover {
opacity: 1;
background-color: var(--error);
border: solid 1px #FFF;
}
*/
.ueusebtn {
cursor: pointer;
border: none;
@@ -3535,7 +3638,7 @@ label>input {
animation: SlideDown .15s ease-in-out forwards;
}
.modal-content .scope_desc{
.modal-content .scope_desc {
margin-left: 8px;
line-height: 24px;
overflow-wrap: break-word;
@@ -3579,6 +3682,18 @@ label>input {
margin-bottom: 16px;
}
.Image_modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.25);
backdrop-filter: blur(5px);
z-index: 9999;
transition: all 250ms ease-out;
}
.Image_modal {
display: none;
position: fixed;
@@ -3608,21 +3723,45 @@ label>input {
box-shadow: 0 0px 48px 0 rgba(0, 0, 0, .15);
overflow: hidden;
cursor: zoom-out;
background-color: #fff;
display: flex;
flex-direction: column;
}
.Image_modal .modal-content img {
background: linear-gradient(45deg, #CCC 25%, transparent 25%, transparent 75%, #CCC 75%),
linear-gradient(45deg, #CCC 25%, transparent 25%, transparent 75%, #CCC 75%);
background: linear-gradient(45deg, #CCC 25%, transparent 25%, transparent 75%, #CCC 75%), linear-gradient(45deg, #CCC 25%, transparent 25%, transparent 75%, #CCC 75%);
background-color: #FFF;
background-size: 20px 20px;
background-position: 0 0, 10px 10px;
width: 100%;
height: 80dvh;
max-height: 80dvh;
margin: 0px;
vertical-align: top;
object-fit: contain;
}
.warning-footer {
padding: 4px 20px;
background-color: var(--error);
color: var(--dark-text-color);
line-height: 22px;
font-size: 16px;
font-family: var(--Text-fonts);
font-weight: bold;
text-align: center;
border-top: 1px solid #FFFFFF;
font-weight: bold;
display: none;
}
.warning-footer span{
margin-right: 16px;
color: var(--dark-text-color);
font-size: 18px;
font-family: var(--Mono-fonts);
font-weight: bold;
}
.topbox {
position: fixed;
@@ -4550,10 +4689,12 @@ label>input {
background-color: var(--notification-color);
color: var(--text-color);
}
.notification .blur * {
transition: 0.5s;
opacity: 0;
}
.notification .blur:hover * {
opacity: 1;
}
@@ -4992,6 +5133,45 @@ hr {
margin-bottom: 6px;
}
.hny .done_button {
cursor: pointer;
border: none;
display: block;
width: 20%;
padding: 8px auto;
margin-left: auto;
margin-right: 0px;
padding-top: 6px;
padding-bottom: 6px;
background-color: var(--main-color);
border-radius: 50px;
color: var(--sub-color);
font-size: 16px;
font-family: var(--Head-fonts), sans-serif;
font-weight: normal;
text-decoration: none;
text-align: center;
transition: box-shadow 250ms ease-in-out;
transition: width 250ms ease-out;
transition: all 250ms ease-out;
}
.hny .done_button:hover {
background-color: var(--main-color);
color: var(--sub-color);
box-shadow: 0 0px 48px 0 rgba(0, 0, 0, .2);
width: 21%;
}
.hny .done_button:active {
box-shadow: 0 0px 48px 0 rgba(0, 0, 0, .0);
width: 19%;
}
.switch_input {
position: absolute;
width: 50px;
@@ -5146,14 +5326,14 @@ summary {
list-style: none;
}
.report_summary{
display:flex;
justify-content:space-between;
align-items:center;
width:100%;
.report_summary {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
.report_summary .count{
.report_summary .count {
font-size: 16px;
color: var(--subtext-color);
padding: 2px 8px;
@@ -5170,7 +5350,8 @@ summary {
padding-bottom: 0px;
border-radius: 8px;
}
.report-entry .p2{
.report-entry .p2 {
margin: 0px;
}
@@ -5388,6 +5569,44 @@ summary {
font-weight: 900;
}
.admin_userinfo .icon .tatext .status {
display: flex;
vertical-align: top;
margin-left: 12px;
margin-right: auto;
margin-top: auto;
margin-bottom: 0px;
}
.admin_userinfo .icon .tatext .status p {
margin: 2px 0px 0px 8px;
vertical-align: middle;
line-height: 14px;
color: var(--subtext-color);
font-size: 14px;
font-family: var(--Mono-fonts), sans-serif;
}
.admin_userinfo .icon .tatext .circle {
width: 16px;
height: 16px;
border-radius: 50%;
background-color: #CCC;
}
.admin_userinfo .icon .tatext .green {
background-color: #00cc4e;
}
.admin_userinfo .icon .tatext .yellow {
background-color: #ffc400;
}
.admin_userinfo .icon .tatext .gray {
background-color: #CCC;
}
.admin_userinfo .profile p {
text-align: left;
margin-top: 12px;
@@ -6387,26 +6606,29 @@ noscript .noscript_modal .inner .center_text p {
font-weight: normal;
}
.auth_clientbox{
.auth_clientbox {
width: 100%;
height: fit-content;
background-color: var(--background-color);
border: solid 1px var(--border-color);
border-radius: 10px;
}
.auth_clientbox .flexbox{
.auth_clientbox .flexbox {
margin: 16px;
display: flex;
width: 100%;
height: fit-content;
}
.auth_clientbox .flexbox img{
.auth_clientbox .flexbox img {
width: 64px;
height: 64px;
object-fit: cover;
border-radius: 8px;
}
.auth_clientbox .flexbox p{
.auth_clientbox .flexbox p {
width: calc(100% - 24px);
margin: auto auto auto 16px;
font-weight: bold;
@@ -6414,35 +6636,41 @@ noscript .noscript_modal .inner .center_text p {
line-height: 24px;
color: var(--text-color);
}
.auth_clientbox .about{
.auth_clientbox .about {
margin: 16px;
width: calc(100% - 32px);
}
.auth_clientbox .about .scopebox{
.auth_clientbox .about .scopebox {
width: calc(100% - 32px);
border: solid 1px var(--border-color);
background-color: var(--tl-color);
border-radius: 8px;
padding: 2px 16px;
}
.auth_clientbox .accountbox{
.auth_clientbox .accountbox {
width: calc(100% - 32px);
height: fit-content;
margin: 16px;
}
.auth_clientbox .accountbox .flexbox{
.auth_clientbox .accountbox .flexbox {
margin: 0px;
display: flex;
width: 100%;
height: fit-content;
}
.auth_clientbox .accountbox .flexbox img{
.auth_clientbox .accountbox .flexbox img {
width: 32px;
height: 32px;
object-fit: cover;
border-radius: 16px;
}
.auth_clientbox .accountbox .flexbox p{
.auth_clientbox .accountbox .flexbox p {
width: calc(100% - 8px);
margin: auto auto auto 8px;
font-weight: normal;
@@ -6450,12 +6678,14 @@ noscript .noscript_modal .inner .center_text p {
line-height: 16px;
color: var(--text-color);
}
.auth_clientbox .callbackbox{
.auth_clientbox .callbackbox {
width: calc(100% - 32px);
height: fit-content;
margin: 16px;
}
.auth_clientbox .callbackbox p{
.auth_clientbox .callbackbox p {
font-family: var(--Mono-fonts), sans-serif;
font-weight: normal;
font-size: 14px;
@@ -6535,6 +6765,15 @@ noscript .noscript_modal .inner .center_text p {
flex-wrap: wrap;
}
.userheader .icon .status {
position: relative;
left: calc(148px - (24px + 8px));
top: -37px;
width: 24px;
height: 24px;
border-radius: 50%;
}
.userheader .profile p {
margin-left: 12px;
margin-right: 12px;
@@ -8478,6 +8717,10 @@ noscript .noscript_modal .inner .center_text p {
border: 1px solid var(--main-color);
}
.userheader .icon .status {
border: solid 4px var(--dark-sub-color);
}
.fzone .follow .fbtn {
background-color: var(--main-color);
color: var(--sub-color);
@@ -8785,7 +9028,7 @@ noscript .noscript_modal .inner .center_text p {
color: var(--dark-subtext-color);
}
.modal-content .scope_desc{
.modal-content .scope_desc {
color: var(--dark-text-color);
}
@@ -8845,7 +9088,7 @@ noscript .noscript_modal .inner .center_text p {
color: var(--dark-subtext-color);
}
.report_summary .count{
.report_summary .count {
color: var(--subtext-color);
background-color: var(--dark-sub-color);
border: solid 1px var(--dark-border-color);
@@ -9347,21 +9590,25 @@ noscript .noscript_modal .inner .center_text p {
border: solid 1px var(--dark-border-color);
}
.auth_clientbox{
.auth_clientbox {
background-color: var(--dark-background-color);
border: solid 1px var(--dark-border-color);
}
.auth_clientbox .flexbox p{
.auth_clientbox .flexbox p {
color: var(--dark-text-color);
}
.auth_clientbox .about .scopebox{
.auth_clientbox .about .scopebox {
border: solid 1px var(--dark-border-color);
background-color: var(--dark-sub-color);
}
.auth_clientbox .accountbox .flexbox p{
.auth_clientbox .accountbox .flexbox p {
color: var(--dark-text-color);
}
.auth_clientbox .callbackbox p{
.auth_clientbox .callbackbox p {
color: var(--dark-text-color);
}
}
+79 -8
View File
@@ -243,6 +243,28 @@ function uwuzuUserLogin($session, $cookie, $ip_addr, $operation_permission = "us
}
}
//ログイン日時を記録---------------------------------------------------------
$last_login_datetime = date("Y-m-d H:i:s", time());
$pdo->beginTransaction();
try {
$updateQuery = $pdo->prepare("UPDATE account SET last_login_datetime = :last_login_datetime WHERE userid = :userid");
$updateQuery->bindValue(':last_login_datetime', $last_login_datetime, PDO::PARAM_STR);
$updateQuery->bindValue(':userid', $userid, PDO::PARAM_STR);
$res = $updateQuery->execute();
if($res){
$pdo->commit();
}else{
// ロールバック
$pdo->rollBack();
actionLog($userid, "error", "uwuzuUserLogin", null, "最終ログイン日時を記録できませんでした!", 3);
}
} catch (Exception $e) {
// ロールバック
$pdo->rollBack();
actionLog($userid, "error", "uwuzuUserLogin", null, $e, 4);
}
//JobがあればJobを実行する---------------------------------------------------
$job = getJob($pdo, $userid);
if(!(empty($job))){
@@ -3746,6 +3768,12 @@ function FormatUeuseItem(array $value, string $myblocklist, string $mybookmark,
? $value['iconname']
: "../" . $value['iconname'];
if(isset($value["other_settings"])) {
$value["isAIBlock"] = val_OtherSettings("isAIBlock", $value["other_settings"]);
} else {
$value["isAIBlock"] = false;
}
$value = to_null($value);
$value = to_array_safetext($value);
$value["role"] = explode(',', $value["role"]);
@@ -3772,6 +3800,12 @@ function FormatUeuseItem(array $value, string $myblocklist, string $mybookmark,
$reusedUserData = getUserData($pdo, $reused['account']);
$reusedUserData["role"] = explode(',', $reusedUserData["role"]);
if(isset($reusedUserData["other_settings"])) {
$reusedUserData["isAIBlock"] = val_OtherSettings("isAIBlock", $reusedUserData["other_settings"]);
} else {
$reusedUserData["isAIBlock"] = false;
}
$reused = to_null($reused);
$reused = to_array_safetext($reused);
@@ -3794,6 +3828,7 @@ function FormatUeuseItem(array $value, string $myblocklist, string $mybookmark,
: "../" . $reusedUserData['iconname'],
"role" => $reusedUserData["role"],
"is_bot" => $reusedUserData["is_bot"],
"is_aiblock" => (bool)$reusedUserData["isAIBlock"],
],
"ueuse" => $reused["ueuse"],
"photo1" => $reused["photo1"],
@@ -3833,6 +3868,7 @@ function FormatUeuseItem(array $value, string $myblocklist, string $mybookmark,
"iconurl" => $value['iconname'],
"role" => $value["role"],
"is_bot" => $value["is_bot"],
"is_aiblock" => (bool)$value["isAIBlock"],
],
"ueuse" => $value["ueuse"],
"photo1" => $value["photo1"],
@@ -3862,7 +3898,7 @@ function FormatUeuseItem(array $value, string $myblocklist, string $mybookmark,
return $ueuse;
}
function GetAPIScopes($scope){
function GetAPIScopes($scope, $is_admin = false){
$scopelist = [
"read:me" => "重要な情報以外の自分のアカウントの情報を見る",
"write:me" => "重要な情報以外の自分のアカウントの情報を変更する",
@@ -3876,15 +3912,37 @@ function GetAPIScopes($scope){
"write:bookmark" => "ブックマークにユーズを追加・削除する",
"read:bookmark" => "ブックマークを見る"
];
if(empty($scope)){
return $scopelist;
}else{
if(array_key_exists($scope, $scopelist)){
return $scopelist[$scope];
$admin_scopelist = [
'read:admin:users' => '[Admin] 重要な情報を含めたユーザーのアカウント情報を見る',
'write:admin:user-sanction' => '[Admin] ユーザーに通知・凍結/凍結解除・BANする',
'read:admin:reports' => '[Admin] 通報を取得する',
'write:admin:reports' => '[Admin] 通報を解決する'
];
if($is_admin === false){
if(empty($scope)){
return $scopelist;
}else{
return false;
if(array_key_exists($scope, $scopelist)){
return $scopelist[$scope];
}else{
return false;
}
}
}else{
$admin_all_scopes = array_merge($scopelist, $admin_scopelist);
if(empty($scope)){
return $admin_all_scopes;
}else{
if(array_key_exists($scope, $admin_all_scopes)){
return $admin_all_scopes[$scope];
}else{
return false;
}
}
}
}
function MinimumHash($text) {
@@ -4021,7 +4079,19 @@ function APIAuth($pdo, $token, $scope){
$allow_scope = array_unique(array_map('trim', explode(",", $tokenData["scope"])));
if(in_array($scope, $allow_scope)){
$userdata = getUserData($pdo, $tokenData["userid"]);
if(!(empty($userdata))){
if($userdata["admin"] == "yes"){
$admin_permission = true;
}else{
$admin_permission = false;
}
foreach ($allow_scope as $scope) {
$description = GetAPIScopes($scope, $admin_permission);
if ($description === false) {
return [false, "token_invalid_scope", null];
}
}
if($userdata["role"] === "ice"){
return [false, "this_account_has_been_frozen", null];
}else{
@@ -4059,7 +4129,7 @@ function getDatasUeuse(PDO $pdo, array $messages): array {
$users = [];
if (!empty($userIds)) {
$placeholders = implode(',', array_fill(0, count($userIds), '?'));
$stmt = $pdo->prepare("SELECT userid, username, profile, role, iconname, headname, sacinfo FROM account WHERE userid IN ($placeholders)");
$stmt = $pdo->prepare("SELECT userid, username, profile, role, iconname, headname, sacinfo, other_settings FROM account WHERE userid IN ($placeholders)");
$stmt->execute($userIds);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$users[$row['userid']] = $row;
@@ -4096,6 +4166,7 @@ function getDatasUeuse(PDO $pdo, array $messages): array {
$message['iconname'] = $userRow['iconname'] ?? ($message['iconname'] ?? null);
$message['headname'] = $userRow['headname'] ?? ($message['headname'] ?? null);
$message['sacinfo'] = $userRow['sacinfo'] ?? ($message['sacinfo'] ?? null);
$message['other_settings'] = $userRow['other_settings'] ?? ($message['other_settings'] ?? null);
}
// reply / reuse
+2 -3
View File
@@ -290,6 +290,7 @@ if ("serviceWorker" in navigator) {
<div id="Big_ImageModal" class="Image_modal">
<div class="modal-content">
<img id="Big_ImageMain" href="">
<div id="NoAI_Footer" class="warning-footer"><span>No AI</span>機械学習への利用を一切拒否します。</div>
</div>
</div>
@@ -638,12 +639,11 @@ $(document).ready(function() {
dataType: 'json',
success: function(response) {
if (response.success) {
// いいね成功時の処理
if (isLiked) {
$this.removeClass('bookmark_after'); // クラスを削除していいねを取り消す
view_notify("ブックマークを解除しました");
} else {
$this.addClass('bookmark_after'); // クラスを追加していいねを追加する
view_notify("ユーズをブックマークしました!");
}
} else {
// いいね失敗時の処理
@@ -687,7 +687,6 @@ $(document).ready(function() {
success: function (response) {
if (response.success) {
postElement.remove();
view_notify("ユーズを削除しました!");
} else {
view_notify("ユーズの削除に失敗しました");
}
+7
View File
@@ -12,6 +12,7 @@ $(document).on('click', '.mini_irobtn', function (event) {
$(document).on('click', '#ueuse_image', function (event) {
var imgLink = $(this).attr('src');
var imgAIBlock = $(this).attr('data-aiblock');
var modal = $('#Big_ImageModal');
var modalMain = $('.modal-content');
@@ -19,6 +20,12 @@ $(document).on('click', '#ueuse_image', function (event) {
$(modalimg_zone).attr('src',imgLink);
if(imgAIBlock == "true"){
$("#NoAI_Footer").show();
}else{
$("#NoAI_Footer").hide();
}
modal.show();
modalMain.addClass("slideUp");
modalMain.removeClass("slideDown");
+27 -10
View File
@@ -312,6 +312,8 @@ function formatMarkdown(text) {
return key;
}
text = text.replaceAll('&#039;', "'");
// 複数行コードブロック (```)
text = text.replace(/```([\s\S]+?)```/g, (match, code) => {
// 先頭の改行のみ削除
@@ -518,10 +520,19 @@ function getBotIcon(userdata) {
return "";
}
function getAIBlockFlag(userdata) {
if (userdata["is_aiblock"] && userdata["is_aiblock"] == true) {
return `data-aiblock = "true"`;
}else{
return `data-aiblock = "false"`;
}
}
async function createUeuseHtml(ueuse, selectedUniqid = null) {
let html = "";
let check = "";
let bot = "";
let AIBlock = "";
var reuse = "";
let contentHtml = "";
@@ -557,6 +568,7 @@ async function createUeuseHtml(ueuse, selectedUniqid = null) {
if (ueuse["reuse"]) {
check = getCheckIcon(ueuse["userdata"]);
bot = getBotIcon(ueuse["userdata"]);
AIBlock = getAIBlockFlag(ueuse["userdata"]);
}
if (ueuse["ueuse"].length > 0) {
@@ -621,6 +633,9 @@ async function createUeuseHtml(ueuse, selectedUniqid = null) {
abi_date = ueuse["abi"]["abi_date"];
} else {
if (!(ueuse["reuse"] == null)) {
check = getCheckIcon(ueuse["reuse"]["userdata"]);
bot = getBotIcon(ueuse["reuse"]["userdata"]);
AIBlock = getAIBlockFlag(ueuse["reuse"]["userdata"]);
reuse = `<div class="ru">
<a href="/@`+ ueuse["userdata"]["userid"] + `">
<img src="`+ ueuse["userdata"]["iconurl"] + `" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/icon_404.png'">
@@ -693,6 +708,7 @@ async function createUeuseHtml(ueuse, selectedUniqid = null) {
} else if (ueuse["type"] == "Reply") {
check = getCheckIcon(ueuse["userdata"]);
bot = getBotIcon(ueuse["userdata"]);
AIBlock = getAIBlockFlag(ueuse["userdata"]);
if (selectedUniqid != null && selectedUniqid == ueuse["uniqid"]) {
reuse = `<div class="rp"><div class="here"></div><div class="totop"></div><p>一番上のユーズに返信</p></div>`;
@@ -757,6 +773,7 @@ async function createUeuseHtml(ueuse, selectedUniqid = null) {
} else {
check = getCheckIcon(ueuse["userdata"]);
bot = getBotIcon(ueuse["userdata"]);
AIBlock = getAIBlockFlag(ueuse["userdata"]);
reuse = ``;
inyo = ``;
@@ -858,29 +875,29 @@ async function createUeuseHtml(ueuse, selectedUniqid = null) {
if (img4.length > 0) {
img_html = `<div class="photo4">
<a>
<img src="`+ img1 + `" alt="画像1" title="画像1" data-id="1" id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
<img src="`+ img1 + `" alt="画像1" title="画像1" data-id="1" `+ AIBlock + ` id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
</a>
<a>
<img src="`+ img2 + `" alt="画像2" title="画像2" data-id="2" id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
<img src="`+ img2 + `" alt="画像2" title="画像2" data-id="2" `+ AIBlock + ` id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
</a>
<a>
<img src="`+ img3 + `" alt="画像3" title="画像3" data-id="3" id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
<img src="`+ img3 + `" alt="画像3" title="画像3" data-id="3" `+ AIBlock + ` id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
</a>
<a>
<img src="`+ img4 + `" alt="画像4" title="画像4" data-id="4" id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
<img src="`+ img4 + `" alt="画像4" title="画像4" data-id="4" `+ AIBlock + ` id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
</a>
</div>`;
} else {
img_html = `<div class="photo3">
<a>
<img src="`+ img1 + `" alt="画像1" title="画像1" data-id="1" id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
<img src="`+ img1 + `" alt="画像1" title="画像1" data-id="1" `+ AIBlock + ` id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
</a>
<a>
<img src="`+ img2 + `" alt="画像2" title="画像2" data-id="2" id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
<img src="`+ img2 + `" alt="画像2" title="画像2" data-id="2" `+ AIBlock + ` id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
</a>
<div class="photo3_btm">
<a>
<img src="`+ img3 + `" alt="画像3" title="画像3" data-id="3" id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
<img src="`+ img3 + `" alt="画像3" title="画像3" data-id="3" `+ AIBlock + ` id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
</a>
</div>
</div>`;
@@ -888,17 +905,17 @@ async function createUeuseHtml(ueuse, selectedUniqid = null) {
} else {
img_html = `<div class="photo2">
<a>
<img src="`+ img1 + `" alt="画像1" title="画像1" data-id="1" id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
<img src="`+ img1 + `" alt="画像1" title="画像1" data-id="1" `+ AIBlock + ` id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
</a>
<a>
<img src="`+ img2 + `" alt="画像2" title="画像2" data-id="2" id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
<img src="`+ img2 + `" alt="画像2" title="画像2" data-id="2" `+ AIBlock + ` id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
</a>
</div>`;
}
} else {
img_html = `<div class="photo1">
<a>
<img src="`+ img1 + `" alt="画像1" title="画像1" data-id="1" id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
<img src="`+ img1 + `" alt="画像1" title="画像1" data-id="1" `+ AIBlock + ` id="ueuse_image" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/image_404.png'">
</a>
</div>`;
}
+8 -3
View File
@@ -68,6 +68,11 @@ $notificationcount = $notiData['notification_count'];
if (!empty($pdo)) {
$userData = getUserData($pdo, $userid);
if($is_Admin == "yes"){
$admin_permission = true;
}else{
$admin_permission = false;
}
$apitokenQuery = $pdo->prepare("SELECT * FROM api WHERE userid = :userid ORDER BY datetime DESC");
$apitokenQuery->bindValue(':userid', $userid);
@@ -309,8 +314,8 @@ require('../logout/logout.php');
$client_scope_base = array_unique(array_map('trim', explode(",", $value["scope"])));
$client_scope = [];
foreach ($client_scope_base as $scope) {
if (GetAPIScopes($scope)) {
$client_scope[] = GetAPIScopes($scope);
if (GetAPIScopes($scope, $admin_permission)) {
$client_scope[] = GetAPIScopes($scope, $admin_permission);
} else {
$client_scope[] = "未知のスコープ ($scope)";
}
@@ -372,7 +377,7 @@ require('../logout/logout.php');
<input type="text" id="client_name" class="inbox" placeholder="appname" value="">
<div class="p2">許可する権限</div>
<?php
$scopes = GetAPIScopes(null);
$scopes = GetAPIScopes(null, $admin_permission);
foreach ($scopes as $key => $label) { ?>
<div class="flexbox">
<div class="scope-item">
+3
View File
@@ -204,6 +204,7 @@ $pdo = null;
<div id="Big_ImageModal" class="Image_modal">
<div class="modal-content">
<img id="Big_ImageMain" href="">
<div id="NoAI_Footer" class="warning-footer"><span>No AI</span>機械学習への利用を一切拒否します。</div>
</div>
</div>
@@ -367,8 +368,10 @@ $(document).ready(function() {
// いいね成功時の処理
if (isLiked) {
$this.removeClass('bookmark_after'); // クラスを削除していいねを取り消す
view_notify("ブックマークを解除しました");
} else {
$this.addClass('bookmark_after'); // クラスを追加していいねを追加する
view_notify("ユーズをブックマークしました!");
}
} else {
// いいね失敗時の処理
+2 -2
View File
@@ -1,4 +1,4 @@
uwuzu
1.6.7
2025/12/26
1.6.8
2025/12/30
daichimarukana,putonfps
+31
View File
@@ -1,6 +1,37 @@
## リリースノートだぜぇぇぇぇぇぇい!!!!!!!
ここにはuwuzuの更新情報を載せてくぜぇ~!(いやまてテンションおかしいだろ...)
## Version 1.6.8 (Hapuego)
2025/12/26
fix: 不要なコードを削除しました!
fix: 一部UIの崩れを修正しました!
fix: アポストロフィーが正しく表示されない問題を修正しました!
fix: 管理者からユーザーに通知を送信する際に、通知のタイトルが128文字までしか入力できない問題を修正しました!
fix: サーバーの環境次第で、管理者ページより概要ページで発生するおそれのあるゼロ除算エラーを修正しました!
fix: 公式マークを持つユーザーもしくはBotユーザーのユーズをリユーズすると、チェックマークおよびBotラベルが表示されなくなる問題を修正しました!
fix: 一部ページでブックマーク追加時に画面上からお知らせが出ない問題を修正しました!
chg: APIスコープに関する整合性とセキュリティを向上させました!
chg: 一部UIを変更しました!
new: 管理者向け機能でアクティブユーザー数の統計情報とユーザーのオンラインステータスを確認できる機能を追加しました!
この機能を使用するにはデータベースの更新が必要となります。
データベースのaccountテーブルにlast_login_datetime(datetime)というカラムを追加してください。
new: オンラインステータス公開機能を追加しました!
メニューより、「設定」→「プロフィール」内のオンラインステータスを公開するをオンにするとオンラインステータスがユーザーのプロフィールページに公開されます。
ステータスは以下の種類があります。
- 🟢: オンライン - 過去5分間以内にuwuzuを利用した
- 🟡: 離席中 - 過去15分から過去5分までの間にuwuzuを利用した
- ⚪: オフライン - 最後にuwuzuを利用してから15分間以上経過している
- 表示なし: オンラインステータスの表示をオンにしていない
new: 管理者向けAPIを追加しました!
これにより以下の操作がAPI経由で行えるようになります。
APIの使用方法はdocs.uwuzu.comをご確認ください!
- 重要な情報を含めたユーザーのアカウント情報を見る
- ユーザーに通知・凍結/凍結解除・BANする
- 通報を取得する
- 通報を解決する
new: AIによる学習を拒否する機能を強化しました!
これにより、AIによる学習を拒否する設定がオンの場合に、uwuzu上で画像を表示すると画像の下に「No AI 機械学習への利用を一切拒否します。」と表示されるようになります。
## Version 1.6.7 (Hapuego)
2025/12/26
fix: 通知ページにてユーザー名に含まれるカスタム絵文字が横にぎゅっと表示されてしまう問題を修正しました!
+23 -23
View File
@@ -88,6 +88,7 @@ if( !empty($pdo) ) {
$isAIBlock = val_OtherSettings("isAIBlock", $userData["other_settings"]);
$isAIBWM = val_OtherSettings("isAIBlockWaterMark", $userData["other_settings"]);
$isPublicOnlineStatus = val_OtherSettings("isPublicOnlineStatus", $userData["other_settings"]);
if(!(empty($userData["encryption_ivkey"]))){
$view_mailadds = DecryptionUseEncrKey($userData["mailadds"], GenUserEnckey($userData["datetime"]), $userData["encryption_ivkey"]);
@@ -146,31 +147,17 @@ if( !empty($_POST['btn_submit']) ) {
$mailadds = safetext($_POST['mailadds']);
if( !empty($_POST['isAIBlock']) ) {
$new_isAIBlock = safetext($_POST['isAIBlock']);
}else{
$new_isAIBlock = "false";
$targets = [
'isAIBlock' => 'isAIBlock',
'isAIBMW' => 'isAIBlockWaterMark',
'isPublicOnlineStatus' => 'isPublicOnlineStatus'
];
$other_settings_json = $userData["other_settings"];
foreach ($targets as $post_key => $save_key) {
$is_true = (!empty($_POST[$post_key]) && safetext($_POST[$post_key]) === "true");
$other_settings_json = val_AddOtherSettings($save_key, $is_true, $other_settings_json);
}
if($new_isAIBlock === "true"){
$save_isAIBlock = true;
}else{
$save_isAIBlock = false;
}
$other_settings_json = val_AddOtherSettings("isAIBlock", $save_isAIBlock, $userData["other_settings"]);
if( !empty($_POST['isAIBMW']) ) {
$new_isAIBMW = safetext($_POST['isAIBMW']);
}else{
$new_isAIBMW = "false";
}
if($new_isAIBMW === "true"){
$save_isAIBMW = true;
}else{
$save_isAIBMW = false;
}
$other_settings_json = val_AddOtherSettings("isAIBlockWaterMark", $save_isAIBMW, $other_settings_json);
if( !empty($_POST['mail_important']) ) {
$mail_important = safetext($_POST['mail_important']);
}else{
@@ -613,6 +600,19 @@ $pdo = null;
</div>
<?php }?>
<p>オンラインステータスを公開する</p>
<div class="p2">プロフィール画面にあなたのオンラインステータスを表示するかを選択できます。<br>
この設定はAPIにも反映されます。</div>
<div class="switch_button">
<?php if($isPublicOnlineStatus == true){?>
<input id="isPublicOnlineStatus" class="switch_input" type='checkbox' name="isPublicOnlineStatus" value="true" checked/>
<label for="isPublicOnlineStatus" class="switch_label"></label>
<?php }else{?>
<input id="isPublicOnlineStatus" class="switch_input" type='checkbox' name="isPublicOnlineStatus" value="true" />
<label for="isPublicOnlineStatus" class="switch_label"></label>
<?php }?>
</div>
<input type="submit" class = "irobutton" name="btn_submit" value="保存">
<?php }?>
+84 -54
View File
@@ -84,21 +84,29 @@ $notiData = $notiQuery->fetch(PDO::FETCH_ASSOC);
$notificationcount = $notiData['notification_count'];
if(!empty($pdo)){
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
//User
$result = $mysqli->query("SELECT userid FROM account");
$count1 = $result->num_rows;
//ueuse
$result2 = $mysqli->query("SELECT uniqid FROM ueuse");
$count2 = $result2->num_rows;
//emoji
$result3 = $mysqli->query("SELECT sysid FROM emoji");
$count3 = $result3->num_rows;
//bot
$result4 = $mysqli->query("SELECT userid FROM account WHERE sacinfo = 'bot'");
$count4 = $result4->num_rows;
try {
//User
$count1 = $pdo->query("SELECT userid FROM account")->rowCount();
//Ueuse
$count2 = $pdo->query("SELECT uniqid FROM ueuse")->rowCount();
//Emoji
$count3 = $pdo->query("SELECT sysid FROM emoji")->rowCount();
// bot
$count4 = $pdo->query("SELECT userid FROM account WHERE sacinfo = 'bot'")->rowCount();
// ActiveUsers
$count5 = $pdo->query("SELECT userid FROM account WHERE last_login_datetime > NOW() - INTERVAL 5 MINUTE")->rowCount();
// AwayUsers
$count6 = $pdo->query("SELECT userid FROM account WHERE last_login_datetime < NOW() - INTERVAL 5 MINUTE AND last_login_datetime >= NOW() - INTERVAL 15 MINUTE")->rowCount();
} catch (PDOException $e) {
$count1 = 0;
$count2 = 0;
$count3 = 0;
$count4 = 0;
$count5 = 0;
$count6 = 0;
$error_message[] = $e->getMessage();
actionLog($userid, "error", "overview_admin", null, "統計情報の取得に失敗しました!", 4);
}
$migrationUserFollow = checkFollowMigrationProgress($pdo);
@@ -162,45 +170,50 @@ if(!empty($pdo)){
if(function_exists("disk_free_space")){
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$disk = true;
$diskFree = (int) disk_free_space('C:') / 1024 / 1024;
$diskTotal = (int) disk_total_space('C:') / 1024 / 1024;
$diskUmari = $diskTotal - $diskFree;
if ($diskFree / $diskTotal < 0.1) {
$disk_over90p = true;
}else{
$disk_over90p = false;
}
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$disk = true;
$totalRaw = disk_total_space('C:');
$diskTotal = ($totalRaw > 0) ? (int)$totalRaw / 1024 / 1024 : 0;
$diskFree = (int)disk_free_space('C:') / 1024 / 1024;
$diskUmari = $diskTotal - $diskFree;
$loadAve = null;
} else {
$disk = true;
$diskFree = (int) disk_free_space('/') / 1024 / 1024;
$diskTotal = (int) disk_total_space('/') / 1024 / 1024;
$diskUmari = $diskTotal - $diskFree;
if ($diskFree / $diskTotal < 0.1) {
$disk_over90p = true;
}else{
$disk_over90p = false;
}
if(function_exists("sys_getloadavg")){
$loadAve = sys_getloadavg()[0];
}else{
$loadAve = null;
}
}
}else{
$disk = false;
$diskFree = 5000;
$diskUmari = 5000;
$diskTotal = 10000;
$disk_over90p = false;
if(function_exists("sys_getloadavg")){
$loadAve = sys_getloadavg()[0];
}else{
$loadAve = null;
}
if ($diskTotal > 0 && ($diskFree / $diskTotal < 0.1)) {
$disk_over90p = true;
} else {
$disk_over90p = false;
}
$loadAve = null;
} else {
$disk = true;
$totalRaw = disk_total_space('/');
$diskTotal = ($totalRaw > 0) ? (int)$totalRaw / 1024 / 1024 : 0;
$diskFree = (int)disk_free_space('/') / 1024 / 1024;
$diskUmari = $diskTotal - $diskFree;
if ($diskTotal > 0 && ($diskFree / $diskTotal < 0.1)) {
$disk_over90p = true;
} else {
$disk_over90p = false;
}
if(function_exists("sys_getloadavg")){
$loadAve = sys_getloadavg()[0];
} else {
$loadAve = null;
}
}
} else {
$disk = false;
$diskFree = 5000;
$diskUmari = 5000;
$diskTotal = 10000;
$disk_over90p = false;
if(function_exists("sys_getloadavg")){
$loadAve = sys_getloadavg()[0];
}else{
$loadAve = null;
}
}
@@ -289,6 +302,16 @@ require('../logout/logout.php');
<p><?php echo safetext($count4);?></p>
</div>
</div>
<div class="overview">
<div class="overview_cnt_l">
<div class="p2">アクティブユーザー数<br>(過去5分間)</div>
<p><?php echo safetext($count5);?></p>
</div>
<div class="overview_cnt_r">
<div class="p2">離席中のユーザー数<br>(過去5分~15分間)</div>
<p><?php echo safetext($count6);?></p>
</div>
</div>
<hr>
<p>ディスク空き容量</p>
<?php if($disk == true){?>
@@ -297,10 +320,17 @@ require('../logout/logout.php');
<?php }else{?>
<p>ディスク空き容量には余裕があります。</p>
<?php };?>
<div class="graph">
<div class="per" style="width:calc(<?php echo round((int)mb_to_gb($diskUmari) / (int)mb_to_gb($diskTotal) * 100, 1);?>% - 8px);">
<?php
$totalGB = (int)mb_to_gb($diskTotal);
$usedGB = (int)mb_to_gb($diskUmari);
$percent = ($totalGB > 0) ? round($usedGB / $totalGB * 100, 1) : 0;
?>
<div class="per" style="width:calc(<?php echo $percent; ?>% - 8px);">
</div>
</div>
<p>使用済み : <?php echo mb_to_gb($diskUmari)."GB/".mb_to_gb($diskTotal);?>GB<br>
空き容量 : <?php echo mb_to_gb($diskFree);?>GB</p>
<?php }else{?>
+33 -3
View File
@@ -95,6 +95,31 @@ if (!empty($pdo)) {
$view_ip_addr = $userdata["last_ip"];
}
if (!(empty($userdata["last_login_datetime"]))) {
$lastLogin = new DateTime($userdata["last_login_datetime"]);
$now = new DateTime();
$interval = $now->diff($lastLogin);
$minutesPast = ($interval->days * 24 * 60) + ($interval->h * 60) + $interval->i;
$status_datetime = $userdata["last_login_datetime"];
if ($minutesPast <= 5) {
$status_color = "green";
$status = "Online";
} elseif ($minutesPast <= 15) {
$status_color = "yellow";
$status = "Away";
} else {
$status_color = "gray";
$status = "Offline";
}
} else {
$status_color = "gray";
$status = "Offline";
}
$roles = array_filter(explode(',', $userdata["role"]));
$roleDataArray = array();
@@ -123,7 +148,7 @@ if( !empty($_POST['send_notification_submit']) ) {
$notice_msg = safetext($_POST['notice_msg']);
if(empty($notice_title)){
$error_message[] = "通知のタイトルを空欄にすることはできません。(INPUT_PLEASE)";
}elseif(mb_strlen($notice_title) > 128){
}elseif(mb_strlen($notice_title) > 512){
$error_message[] = "通知のタイトルを512文字以上にすることはできません。(INPUT_OVER_MAX_COUNT)";
}
if(empty($notice_msg)){
@@ -283,7 +308,7 @@ if( !empty($_POST['send_water_submit']) ) {
if( !empty($view_mailadds) ){
if(filter_var($view_mailadds, FILTER_VALIDATE_EMAIL)){
$mail_title = "お使いの".safetext($serversettings["serverinfo"]["server_name"])."アカウントは解凍されました!";
$mail_text = "".$userdata["username"]."(".$userdata["userid"].")さん いつもuwuzuをご利用いただきありがとうございます。 ご利用のアカウント(".$userdata["userid"].")が解凍されたためお知らせいたします。 今後、ご利用のuwuzuアカウントは今まで通りご利用いただけます。 また、APIを使用している方はAPIのトークンがリセットされているため再度トークンを発行してご利用ください。";
$mail_text = "".$userdata["username"]."(".$userdata["userid"].")さん いつもuwuzuをご利用いただきありがとうございます。 ご利用のアカウント(".$userdata["userid"].")が解凍されたためお知らせいたします。 今後、ご利用のuwuzuアカウントは今まで通りご利用いただけます。";
$error_message[] = send_html_mail($view_mailadds,$mail_title,$mail_text,"../");
}
@@ -298,7 +323,7 @@ if( !empty($_POST['send_water_submit']) ) {
try {
$touserid = safetext($userdata['userid']);
$datetime = safetext(date("Y-m-d H:i:s"));
$msg = safetext("サービス管理者によりお使いのアカウントは解凍されました!\n今まで通りご利用いただけます。\nなお、APIを使用している方はAPIのトークンがリセットされているため再度トークンを発行してご利用ください。");
$msg = safetext("サービス管理者によりお使いのアカウントは解凍されました!\n今まで通りご利用いただけます。");
$title = safetext("🫗お使いのアカウントが解凍されました!🫗");
$url = safetext("/home");
$userchk = 'none';
@@ -420,6 +445,11 @@ require('../logout/logout.php');
<div class="tatext">
<h2><?php echo safetext($userdata['username']); ?></h2>
<p>@<?php echo safetext($userdata['userid']); ?></p>
<div class="status">
<div class="circle <?php echo safetext($status_color);?>"></div>
<p><?php echo safetext($status);?></p>
<p><?php echo safetext($status_datetime);?></p>
</div>
</div>
</div>
+1
View File
@@ -294,6 +294,7 @@ $pdo = null;
<div id="Big_ImageModal" class="Image_modal">
<div class="modal-content">
<img id="Big_ImageMain" href="">
<div id="NoAI_Footer" class="warning-footer"><span>No AI</span>機械学習への利用を一切拒否します。</div>
</div>
</div>
+18 -20
View File
@@ -1,33 +1,31 @@
{
"software": "uwuzu",
"version": "1.6.7",
"release_date": "2025/12/26",
"release_notes": "このアップデートには、パスワードの復元に関する脆弱性の修正が含まれます。\nまた、パレットイメージが投稿できない問題など、いくつかのバグ修正が含まれます!\n詳細はリリースノートをご確認ください。",
"notices": "アップデート前にデータのバックアップを行うことをおすすめします!",
"version": "1.6.8",
"release_date": "2025/12/30",
"release_notes": "このアップデートには、アポストロフィーが正しく表示されない問題の修正や、一部ページでブックマーク追加時に画面上からお知らせが出ない問題の修正など、いくつかのバグ修正が含まれます!\nまた、新機能でオンラインステータス機能と管理者向けAPIが含まれます!\n詳細はリリースノートをご確認ください。",
"notices": "アップデートの前にデータベース構造の更新が必要です。リリースノートの案内に沿って更新をしてからアップデートをしてください。\nアップデート前にデータのバックアップを行うことをおすすめします!",
"files": {
"overwrite": [
"/admin/addadmin.php",
"/admin/index.php",
"/admin/setup_db_php.php",
"/admin/setup_uwuzu_db.php",
"/admin/success.php",
"/css/home.css",
"/js/view_function.js",
"/settings_admin/api/update_query.php",
"/uwuzu_error_code.txt",
"/function/function.php",
"/nextpage/notification.php",
"/bookmark/bookmark.php",
"/api/auth.php",
"/api/admin/reports/index.php",
"/api/admin/reports/resolve.php",
"/api/admin/users/index.php",
"/api/admin/users/sanction.php",
"/api/users/index.php",
"/bookmark/index.php",
"/css/home.css",
"/function/function.php",
"/home/index.php",
"/js/nsfw_event.js",
"/js/view_function.js",
"/others/index.php",
"/search/index.php",
"/settings/index.php",
"/settings_admin/overview_admin.php",
"/settings_admin/userinfo.php",
"/ueuse/index.php",
"/user/index.php",
"/img/sysimage/errorimage/icon_404.png",
"/passrecovery/badrecovery.php",
"/passrecovery/donerecovery.php",
"/passrecovery/index.php",
"/passrecovery/startrecovery.php",
"/server/uwuzuabout.txt",
"/server/uwuzuinfo.txt",
"/server/uwuzurelease.txt"
+78 -40
View File
@@ -110,7 +110,7 @@ if (!empty($pdo)) {
if($is_local == true){
$roles = array_filter(explode(',', $userData["role"])); // カンマで区切られたロールを配列に分割
$rerole = $pdo->prepare("SELECT follow, follower,blocklist, username, userid, password, mailadds, profile, iconname, headname, role, datetime, other_settings FROM account WHERE userid = :userid");
$rerole = $pdo->prepare("SELECT follow, follower,blocklist, username, userid, password, mailadds, profile, iconname, headname, role, datetime, other_settings, last_login_datetime FROM account WHERE userid = :userid");
$rerole->bindValue(':userid', $userData["userid"]);
// SQL実行
@@ -129,6 +129,37 @@ if (!empty($pdo)) {
$isAIBlock = val_OtherSettings("isAIBlock", $userdata["other_settings"]);
$isPublicOnlineStatus = val_OtherSettings("isPublicOnlineStatus", $userdata["other_settings"]);
if($isPublicOnlineStatus === true){
if (!(empty($userdata["last_login_datetime"]))) {
$lastLogin = new DateTime($userdata["last_login_datetime"]);
$now = new DateTime();
$interval = $now->diff($lastLogin);
$minutesPast = ($interval->days * 24 * 60) + ($interval->h * 60) + $interval->i;
$status_datetime = $userdata["last_login_datetime"];
if ($minutesPast <= 5) {
$status_color = "green";
$status = "オンライン";
} elseif ($minutesPast <= 15) {
$status_color = "yellow";
$status = "離席中";
} else {
$status_color = "gray";
$status = "オフライン";
}
} else {
$status_color = "gray";
$status = "オフライン";
}
}else{
$status = null;
}
//-------フォロー数---------
$follow = getFolloweeList($pdo, $userData["userid"]); // コンマで区切られたユーザーIDを含む変数
$followCount = count($follow);
@@ -203,6 +234,8 @@ if (!empty($pdo)) {
$ueuse_cnt = "zero";
$followCount = "zero";
$followerCount = "zero";
$status = null;
}
} else {
@@ -213,59 +246,60 @@ if (!empty($pdo)) {
$ueuse_cnt = "zero";
$followCount = "zero";
$followerCount = "zero";
$status = null;
}
}
if (!empty($_POST['follow'])) {
$res_follow = follow_user($pdo, $userData['userid'], $userid);
if($res_follow === false){
$error_message[] = '更新に失敗しました。(REGISTERED_DAME)';
}else{
$url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header("Location:" . $url);
exit;
if($is_local == true){
if (!empty($_POST['follow'])) {
$res_follow = follow_user($pdo, $userData['userid'], $userid);
if($res_follow === false){
$error_message[] = '更新に失敗しました。(REGISTERED_DAME)';
}else{
$url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header("Location:" . $url);
exit;
}
} elseif (!empty($_POST['unfollow'])) {
$res_unfollow = unfollow_user($pdo, $userData['userid'], $userid);
if($res_unfollow === false){
$error_message[] = '更新に失敗しました。(REGISTERED_DAME)';
}else{
$url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header("Location:" . $url);
exit;
}
}
} elseif (!empty($_POST['unfollow'])) {
$res_unfollow = unfollow_user($pdo, $userData['userid'], $userid);
if($res_unfollow === false){
$error_message[] = '更新に失敗しました。(REGISTERED_DAME)';
}else{
$url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header("Location:" . $url);
exit;
if (!empty($_POST['send_block_submit'])) {
$res_block = block_user($pdo, $userData['userid'], $userid);
if($res_block === false){
$error_message[] = '更新に失敗しました。(REGISTERED_DAME)';
}else{
$url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header("Location:" . $url);
exit;
}
} elseif (!empty($_POST['send_un_block_submit'])) {
$res_unblock = unblock_user($pdo, $userData['userid'], $userid);
if($res_unblock === false){
$error_message[] = '更新に失敗しました。(REGISTERED_DAME)';
}else{
$url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header("Location:" . $url);
exit;
}
}
}
if (!empty($_POST['send_block_submit'])) {
$res_block = block_user($pdo, $userData['userid'], $userid);
if($res_block === false){
$error_message[] = '更新に失敗しました。(REGISTERED_DAME)';
}else{
$url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header("Location:" . $url);
exit;
}
} elseif (!empty($_POST['send_un_block_submit'])) {
$res_unblock = unblock_user($pdo, $userData['userid'], $userid);
if($res_unblock === false){
$error_message[] = '更新に失敗しました。(REGISTERED_DAME)';
}else{
$url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header("Location:" . $url);
exit;
}
}
require('../logout/logout.php');
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/push.js/1.0.12/push.min.js"></script>
<script src="../js/jquery-min.js"></script>
<script src="../js/unsupported.js"></script>
<script src="../js/console_notice.js"></script>
@@ -351,6 +385,9 @@ require('../logout/logout.php');
</div>
<div class="icon">
<img src="<?php echo safetext($userdata['iconname']); ?>" onerror="this.onerror=null;this.src='../img/sysimage/errorimage/icon_404.png'">
<?php if($status !== null){?>
<div class="status <?php echo safetext($status_color); ?>" title = "<?php echo safetext($status); ?>"></div>
<?php }?>
<h2><?php echo replaceProfileEmojiImages(safetext($userData['username'])); ?></h2>
<p>@<?php echo safetext($userData['userid']); ?><?php if(safetext($serversettings["serverinfo"]["server_activitypub"]) === "true"){echo "<span>@".safetext($activity_domain)."</span>";} ?></p>
</div>
@@ -647,6 +684,7 @@ require('../logout/logout.php');
<div id="Big_ImageModal" class="Image_modal">
<div class="modal-content">
<img id="Big_ImageMain" href="">
<div id="NoAI_Footer" class="warning-footer"><span>No AI</span>機械学習への利用を一切拒否します。</div>
</div>
</div>
+3 -2
View File
@@ -3,7 +3,7 @@
-- https://www.phpmyadmin.net/
--
-- ホスト: 127.0.0.1
-- 生成日時: 2025-10-27 15:05:57
-- 生成日時: 2025-12-29 19:07:06
-- サーバのバージョン: 10.4.32-MariaDB
-- PHP のバージョン: 8.2.12
@@ -52,7 +52,8 @@ CREATE TABLE `account` (
`mail_settings` mediumtext NOT NULL,
`encryption_ivkey` varchar(256) NOT NULL,
`other_settings` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`other_settings`)),
`last_ip` varchar(1024) NOT NULL
`last_ip` varchar(1024) NOT NULL,
`last_login_datetime` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- --------------------------------------------------------
+3
View File
@@ -16,6 +16,7 @@ contains_prohibited_url - 投稿禁止URLが含まれている場合に表示さ
this_account_has_been_frozen - Botのアカウントが凍結されている場合に表示されます。
token_input_error - APIのアクセストークンが不正または使用できない際に表示されます。
token_invalid - APIのアクセストークンが無効な時に表示されます。
token_invalid_scope - 利用できないスコープが含まれている場合に表示されます。
db_error_[xxx] - BDでエラーが発生した際に表示されます。
over_rate_limit - 1分間あたりのレート制限を超過したさいに表示されます。
post_not_found - ユーズが存在しない時に表示されます。
@@ -28,6 +29,8 @@ migration_bad_success - アカウントの移行後に移行の完了処理が
already_been_completed - 処理が既に完了している場合に表示されます。
you_cant_it_to_yourself - 自分に対して行えない処理を行おうとした際に表示されます。
could_not_complete - 処理を完了できなかった場合に表示されます。
user_not_frozen_cant_be_banned - APIからユーザーをBANしようとした際に、ユーザーが事前に凍結されていない場合に発生するエラーです。
method_not_allowed - 禁止されたHTTPメゾットで要求があった場合に表示されます。
this_API_is_ws_only - WebsocketAPIがWebsocket以外の方法でアクセスされた場合に表示されます。
----------(UWUZU ERR CODE)----------