|
|
@@ -126,11 +126,11 @@ describe('auth API', () => {
|
|
|
expect(opts.header.Authorization).toBe('Bearer my-jwt-token')
|
|
|
})
|
|
|
|
|
|
- test('X-User-Id header is set', async () => {
|
|
|
+ test('X-User-Id header is NOT sent (removed for security)', async () => {
|
|
|
mockSuccess({ code: 200 })
|
|
|
global.uni._storage.userId = '99'
|
|
|
await api.getUserInfo()
|
|
|
- expect(lastRequest().header['X-User-Id']).toBe('99')
|
|
|
+ expect(lastRequest().header['X-User-Id']).toBeUndefined()
|
|
|
})
|
|
|
|
|
|
test('rejects on non-200 code', async () => {
|
|
|
@@ -415,10 +415,10 @@ describe('rewards & wishes API', () => {
|
|
|
expect(lastRequest().data.memberId).toBe(5)
|
|
|
})
|
|
|
|
|
|
- test('getPendingWishes sends POST with familyId', async () => {
|
|
|
+ test('getPendingWishes sends POST with empty body', async () => {
|
|
|
mockSuccess({ code: 200 })
|
|
|
- await api.getPendingWishes(1)
|
|
|
- expect(lastRequest().data.familyId).toBe(1)
|
|
|
+ await api.getPendingWishes()
|
|
|
+ expect(lastRequest().data).toEqual({})
|
|
|
})
|
|
|
|
|
|
test('getWishes sends POST with params', async () => {
|
|
|
@@ -446,6 +446,49 @@ describe('rewards & wishes API', () => {
|
|
|
})
|
|
|
})
|
|
|
|
|
|
+// --------------- identity parameter hardening ---------------
|
|
|
+// 前端不再向后端发送可伪造的 userId / familyId / childId(仅 memberId),
|
|
|
+// 身份一律由后端从 JWT 推导。以下断言锁定这一不变量。
|
|
|
+
|
|
|
+describe('identity parameter hardening', () => {
|
|
|
+ beforeEach(() => {
|
|
|
+ global.uni._storage.token = 'test-token'
|
|
|
+ })
|
|
|
+
|
|
|
+ test('request() does NOT send X-User-Id header', async () => {
|
|
|
+ mockSuccess({ code: 200 })
|
|
|
+ await api.getPendingWishes()
|
|
|
+ const opts = lastRequest()
|
|
|
+ expect(opts.header['X-User-Id']).toBeUndefined()
|
|
|
+ })
|
|
|
+
|
|
|
+ test('getMyAssessmentResults sends empty body, no userId', async () => {
|
|
|
+ mockSuccess({ code: 200 })
|
|
|
+ await api.getMyAssessmentResults()
|
|
|
+ const opts = lastRequest()
|
|
|
+ expect(opts.data).toEqual({})
|
|
|
+ expect(opts.data.userId).toBeUndefined()
|
|
|
+ })
|
|
|
+
|
|
|
+ test('getChildAssessmentResults sends empty body, no userId', async () => {
|
|
|
+ mockSuccess({ code: 200 })
|
|
|
+ await api.getChildAssessmentResults()
|
|
|
+ const opts = lastRequest()
|
|
|
+ expect(opts.data).toEqual({})
|
|
|
+ expect(opts.data.userId).toBeUndefined()
|
|
|
+ })
|
|
|
+
|
|
|
+ test('getTodayTasksByCategory sends only memberId and category', async () => {
|
|
|
+ mockSuccess({ code: 200 })
|
|
|
+ await api.getTodayTasksByCategory(7, 'wisdom')
|
|
|
+ const opts = lastRequest()
|
|
|
+ expect(opts.data.memberId).toBe(7)
|
|
|
+ expect(opts.data.category).toBe('wisdom')
|
|
|
+ expect(opts.data.childId).toBeUndefined()
|
|
|
+ expect(opts.data.userId).toBeUndefined()
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
// --------------- guide / packages module ---------------
|
|
|
|
|
|
describe('guide & packages API', () => {
|