|
|
@@ -815,9 +815,10 @@ router.get('/books/:id', optionalAuth, async (ctx: Context) => {
|
|
|
try {
|
|
|
const bookId = ctx.params.id as string;
|
|
|
const userId = ctx.state.user?.userId || TEST_USER_ID;
|
|
|
+ const userIdNum = parseInt(userId as string);
|
|
|
const filterPublic = ctx.query.filterPublic === 'true';
|
|
|
-
|
|
|
- const book = await bookStore.getById(bookId, filterPublic, parseInt(userId as string));
|
|
|
+
|
|
|
+ const book = await bookStore.getById(bookId, filterPublic, userIdNum);
|
|
|
|
|
|
if (!book) {
|
|
|
ctx.status = 404;
|
|
|
@@ -825,6 +826,18 @@ router.get('/books/:id', optionalAuth, async (ctx: Context) => {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ // 归属校验:与列表接口(getAllByUser)保持一致,避免"列表看不到但详情能进"的不一致。
|
|
|
+ // 可见条件:本人创建(userId 匹配) / 游客书(userId 为 null) / 已公开发布。
|
|
|
+ // 否则视为不存在(404),不暴露他人的私有书。
|
|
|
+ const ownerId = (book as any).userId;
|
|
|
+ const isOwner = ownerId === userIdNum || ownerId === null || ownerId === undefined;
|
|
|
+ const isVisible = isOwner || (book as any).isPublished === true;
|
|
|
+ if (!isVisible) {
|
|
|
+ ctx.status = 404;
|
|
|
+ ctx.body = { code: 1, message: '书籍不存在' };
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
ctx.body = { code: 0, message: 'success', data: { book } };
|
|
|
} catch (error) {
|
|
|
console.error('查询失败:', error);
|