v42 第 42 批:十一条反馈(界面 9 条 + CalDAV 两处新根因)
CalDAV(用户「还是不行,thunderbird 提示找不到日历」): - 🔴 `.well-known/caldav` 原来**只回 301**。Thunderbird 建账号时常是 **带鉴权直接 PROPFIND** 这个地址(把它当 DAV 服务入口探),而它对这一跳的 301 **不跟随** ⇒ 判定"这里没有 CalDAV" ⇒ 找不到日历。 ⇒ 按方法分流:带鉴权 PROPFIND → 直接 207 给发现内容(principal / home-set / 日历本清单,一步到位);其余仍是 301。carddav 同修。 - 🔴 `Location` 由**相对** `/dav/` 改成**绝对 URL**(按真实 HTTP_HOST 拼, 协议从 HTTPS / X-Forwarded-Proto 取)。TB 在服务发现这一跳对相对跳转不可靠。 - 线上终验:匿名 GET 301+绝对URL;带鉴权 PROPFIND 直接 207(含 principal/home-set); Depth:0 只回自身;Depth:1 列出 12 本日历。 界面九条: - ① 新建旅程不再带入旧数据(真根因:`_list_body.php` 的 `foreach ($rows as $t)` 循环后 `$t` 残留,而 `form.php` 读的正是 `$t` ⇒ 弹框被填上列表最后一趟的数据)。 修:循环变量改 `$row` + `form.php` 契约兼容(`$tIn` 优先)。 - ②③④ 行程弹框里的 AntD 时间控件 / 出行方式联动车牌与车次 / 高德地址联想全部失效 (真根因:AJAX 片段里的内联 `<script>` **既不执行也不保留**)。 ⇒ 加 `runInlineScripts()` 把片段内联脚本抠出来执行; 另修 `app.js`:`if (!hasMonth) return` 的短路让 `window.fbBootAntd` 从未被定义, 把它提到所有 return 之前。 - ④b⑤ 标签改「照片」「时间范围」。 - ⑥ 简介补"还没有简介,点这里写一句"的占位(简介本身一直在,是那条 summary 为空)。 - ⑦ 资源编辑复用新建弹框(`#resAddCard`),并在其底栏补「共享」「附件」入口 (第 7 条改动后这两个能力一度无入口)。 - ⑧ 纪念日「月/日」→「日期」+ AntD 纯日期控件(新增 mountAntdDate / [data-antd-date]), 存储契约仍是 month + day。 - ⑨ 编辑纪念日弹框关不掉(关闭逻辑原来只在 days/index.php,而 days/edit 是整页) ⇒ 搬进 days/form.php 自包含。 验证:e2e 1510/0;v42 真机 33/0;DAV·TB 35/0;DAV 反向 8/0; b23 55/0;b28 39/0;b32 26/0;b32 反向 5/0;v31 DAV 28/0;b31 反向 8/0; 部署断言空跑 337/0;完整流水线 PUSH_RC=0。
This commit is contained in:
+47
-1
@@ -82,8 +82,54 @@ $path = (string)parse_url((string)($_SERVER['REQUEST_URI'] ?? '/carddav/'), PH
|
||||
* 三种客户端一次都满足。
|
||||
*/
|
||||
if ($path === '/.well-known/carddav') {
|
||||
/* 🔴🔴 v42(用户第 10 条):与 dav.php 完全同一套修法 ——
|
||||
带鉴权的 PROPFIND 直接给发现内容(207),其余仍是 301 到**绝对 URL**。
|
||||
(Thunderbird 建账号时常带鉴权 PROPFIND 这个地址,
|
||||
只回 301 它不跟 ⇒ 「找不到通讯录」。) */
|
||||
$cdWantPropfind = (strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET')) === 'PROPFIND');
|
||||
$cdHasAuth = !empty($user) && $pass !== null && $pass !== '';
|
||||
if ($cdWantPropfind && $cdHasAuth) {
|
||||
$cdWho = Auth::davAuth($user, $pass);
|
||||
if (!$cdWho) {
|
||||
header('WWW-Authenticate: Basic realm="FamilyBook DAV"');
|
||||
cd_fail(401, '需要 DAV 口令(在「个人设置 → DAV 同步」页生成,不是登录密码)。');
|
||||
}
|
||||
$cdFamily = (int)$cdWho['family_id'];
|
||||
$cdMe = (int)$cdWho['person_id'];
|
||||
$cdParts = [
|
||||
'<d:response><d:href>' . CardDav::x(CardDav::HOME_PATH) . '</d:href><d:propstat><d:prop>'
|
||||
. '<d:resourcetype><d:collection/></d:resourcetype>'
|
||||
. '<d:displayname>' . CardDav::x('家书通讯录') . '</d:displayname>'
|
||||
. '<d:current-user-principal><d:href>' . CardDav::x(CardDav::PRINCIPAL_PATH)
|
||||
. '</d:href></d:current-user-principal>'
|
||||
. '<d:principal-URL><d:href>' . CardDav::x(CardDav::PRINCIPAL_PATH)
|
||||
. '</d:href></d:principal-URL>'
|
||||
. '<card:addressbook-home-set><d:href>' . CardDav::x(CardDav::HOME_PATH)
|
||||
. '</d:href></card:addressbook-home-set>'
|
||||
. '</d:prop></d:propstat></d:response>',
|
||||
];
|
||||
foreach (CardDav::books($cdFamily, $cdMe) as $cdB) {
|
||||
$cdParts[] = '<d:response><d:href>' . CardDav::x(CardDav::hrefOf($cdB)) . '</d:href>'
|
||||
. '<d:propstat><d:prop>'
|
||||
. '<d:resourcetype><d:collection/><card:addressbook/></d:resourcetype>'
|
||||
. '<d:displayname>' . CardDav::x((string)$cdB['name']) . '</d:displayname>'
|
||||
. '</d:prop></d:propstat></d:response>';
|
||||
}
|
||||
header('Content-Type: application/xml; charset=utf-8');
|
||||
http_response_code(207);
|
||||
echo '<?xml version="1.0" encoding="utf-8"?>' . "\n"
|
||||
. '<d:multistatus xmlns:d="DAV:" xmlns:card="urn:ietf:params:xml:ns:carddav" '
|
||||
. 'xmlns:c="urn:ietf:params:xml:ns:caldav">'
|
||||
. implode('', $cdParts) . '</d:multistatus>';
|
||||
exit;
|
||||
}
|
||||
http_response_code(301);
|
||||
header('Location: /carddav/');
|
||||
$wkHost = (string)($_SERVER['HTTP_HOST'] ?? '');
|
||||
$wkProto = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
||||
if ($wkProto === 'http' && !empty($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
|
||||
$wkProto = (string)$_SERVER['HTTP_X_FORWARDED_PROTO'];
|
||||
}
|
||||
header('Location: ' . (($wkHost !== '') ? ($wkProto . '://' . $wkHost . '/carddav/') : '/carddav/'));
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user