mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-02 04:52:50 +08:00
fix(guest): deny operator personal-data reads to guests
GET /recommend/songs, /personal/fm, and /user/playlists read the operator's own logged-in music account; gate them with requireNotGuest so login-less guests cannot see the operator's recommendations, FM, or playlists. Generic search/browse stays open. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
365352cdd3
commit
952f1fbad3
2 files changed
+26
-3
No files matched your search
@@ -128,7 +128,7 @@ export function createMusicRouter(
|
||||
}
|
||||
});
|
||||
|
||||
router.get("/recommend/songs", async (req, res) => {
|
||||
router.get("/recommend/songs", requireNotGuest, async (req, res) => {
|
||||
try {
|
||||
const provider = getProvider(req.query.platform as string);
|
||||
if (!provider.getDailyRecommendSongs) {
|
||||
@@ -143,7 +143,7 @@ export function createMusicRouter(
|
||||
}
|
||||
});
|
||||
|
||||
router.get("/personal/fm", async (req, res) => {
|
||||
router.get("/personal/fm", requireNotGuest, async (req, res) => {
|
||||
try {
|
||||
const provider = getProvider(req.query.platform as string);
|
||||
if (!provider.getPersonalFm) {
|
||||
@@ -158,7 +158,7 @@ export function createMusicRouter(
|
||||
}
|
||||
});
|
||||
|
||||
router.get("/user/playlists", async (req, res) => {
|
||||
router.get("/user/playlists", requireNotGuest, async (req, res) => {
|
||||
try {
|
||||
const provider = getProvider(req.query.platform as string);
|
||||
if (!provider.getUserPlaylists) {
|
||||
|
||||
@@ -199,6 +199,29 @@ describe("permission enforcement on action routes", () => {
|
||||
});
|
||||
});
|
||||
|
||||
// The operator's personal-account reads (their recommendations, FM, and
|
||||
// playlists) must never leak to login-less guests. These routes are gated
|
||||
// with requireNotGuest; generic search/browse stays open.
|
||||
describe("operator personal-data reads are denied to guests", () => {
|
||||
const personalRoutes = [
|
||||
"/api/music/recommend/songs",
|
||||
"/api/music/personal/fm",
|
||||
"/api/music/user/playlists",
|
||||
];
|
||||
|
||||
for (const route of personalRoutes) {
|
||||
it(`GET ${route} is 403 for a guest`, async () => {
|
||||
const app = makeApp(guest());
|
||||
expect((await request(app).get(route)).status).toBe(403);
|
||||
});
|
||||
|
||||
it(`GET ${route} is NOT 403 for a member`, async () => {
|
||||
const app = makeApp(member([], "all"));
|
||||
expect((await request(app).get(route)).status).not.toBe(403);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe("read-only routes stay open", () => {
|
||||
it("GET /api/auth/status not gated", async () => {
|
||||
const app = makeApp(member([], "all"));
|
||||
|
||||
Reference in new issue
Block a user