Files
Leantime/dev/library.php

68 lines
2.7 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* 2D/3D 数模库 - 元数据接口(首页库表用)
* GET 无参 → 返回 library.json 的全部记录(静态 JSON 也行,这里统一走接口)
* POST {"records":[...]} → 清洗后整体保存(客户端把编辑后的数组传回)
*
* 只允许本站页面调用Sec-Fetch-Site 优先、Referer 兜底,与 api/token.php 同一策略)。
* 注意这只是防顺手篡改的弱校验:库表只存名称/备注等元数据,不含文件内容。
*/
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store');
$fetchSite = $_SERVER['HTTP_SEC_FETCH_SITE'] ?? '';
$referer = $_SERVER['HTTP_REFERER'] ?? '';
$host = $_SERVER['HTTP_HOST'] ?? '';
if ($fetchSite !== '') {
if ($fetchSite !== 'same-origin' && $fetchSite !== 'same-site') json_out(403, ['error' => 'forbidden']);
} elseif (!$host || strpos($referer, $host) === false) {
json_out(403, ['error' => 'forbidden']);
}
function json_out($code, $obj) {
http_response_code($code);
echo json_encode($obj, JSON_UNESCAPED_UNICODE);
exit;
}
$file = __DIR__ . '/library.json';
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
if (is_file($file)) { readfile($file); exit; }
json_out(200, ['records' => []]);
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') json_out(405, ['error' => 'method not allowed']);
$in = json_decode((string)file_get_contents('php://input'), true);
if (!is_array($in) || !isset($in['records']) || !is_array($in['records'])) {
json_out(400, ['error' => 'bad body']);
}
// 清洗path 是链接核心(拒绝 ..、限制字符与长度name/note 纯文本截断
$records = [];
$seen = [];
foreach ($in['records'] as $r) {
if (!is_array($r)) continue;
$path = is_string($r['path'] ?? null) ? trim($r['path']) : '';
$name = is_string($r['name'] ?? null) ? trim($r['name']) : '';
$note = is_string($r['note'] ?? null) ? trim($r['note']) : '';
$type = ($r['type'] ?? '') === '2d' ? '2d' : '3d';
if ($path === '' || strpos($path, '..') !== false || strlen($path) > 300) continue;
if (!preg_match('/^[\x20-\x7e\x{4e00}-\x{9fff}\/\\\\]+$/u', $path)) continue;
if (isset($seen[$path])) continue;
$seen[$path] = true;
$records[] = [
'path' => $path,
'name' => mb_substr($name, 0, 100),
'type' => $type,
'note' => mb_substr($note, 0, 200),
'time' => is_numeric($r['time'] ?? null) ? (int)$r['time'] : time(),
];
}
// 带锁写文件,防止两个查看器上传时并发写坏
$json = json_encode(['records' => $records], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if (file_put_contents($file, $json, LOCK_EX) === false) json_out(500, ['error' => 'write failed']);
json_out(200, ['ok' => true, 'count' => count($records)]);