apple / apple/app-store-server-library-node

NotificationHistoryResponseValidator uses the response validator for history items and accepts malformed item fields

Open Beginner friendly
#448 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
382
Forks
79
Avg merge
1d 7h
Merged PRs (30d)
9

Description

### Description

`NotificationHistoryResponseValidator.notificationHistoryResponseItemValidator` is initialized with `new NotificationHistoryResponseValidator()` instead of `new NotificationHistoryResponseItemValidator()`.

As a result, each entry in `notificationHistory` is checked for response-level fields (`paginationToken`, `hasMore` and `notificationHistory`) rather than its own `signedPayload` and `sendAttempts` fields. Since the response-level fields are optional, malformed item objects can pass validation without their actual fields being inspected.

The correct item validator already exists and validates both `signedPayload` and the nested `sendAttempts` array, but the parent response validator does not use it.

### Reproduction

From the repository root, after building the package:

```js
const {
NotificationHistoryResponseValidator,
} = require('./dist/models/NotificationHistoryResponse.js');
const {
NotificationHistoryResponseItemValidator,
} = require('./dist/models/NotificationHistoryResponseItem.js');

const responseValidator = new NotificationHistoryResponseValidator();
const itemValidator = new NotificationHistoryResponseItemValidator();

for (const item of [
{ signedPayload: 123 },
{ sendAttempts: 'not-an-array' },
{ sendAttempts: [{ attemptDate: 'not-a-number' }] },
]) {
console.log(
responseValidator.validate({ notificationHistory: [item] }),
itemValidator.validate(item)
);
}
```

All three cases print `true false`: the outer response validator accepts the object while the correct item validator rejects it.

### Expected behavior

If a history item contains an invalid `signedPayload`, `sendAttempts`, or nested send-attempt field, validating the containing `NotificationHistoryResponse` should return false.

### Impact

`AppStoreServerAPIClient.getNotificationHistory` uses this response validator, so malformed history entries can pass the client's runtime response validation and reach callers under an incompatible TypeScript type.

This is a response-shape validation problem. The item validator is not responsible for verifying the cryptographic signature of `signedPayload`.

### Suggested change

Import and instantiate the existing item validator:

```ts
import {
NotificationHistoryResponseItem,
NotificationHistoryResponseItemValidator,
} from './NotificationHistoryResponseItem';

// Inside NotificationHistoryResponseValidator:
static readonly notificationHistoryResponseItemValidator =
new NotificationHistoryResponseItemValidator();
```

Add regression coverage showing that malformed item fields cause the containing response to fail validation, while valid items and omitted optional fields remain accepted.

Contributor guide

Open the contributing guide

Research direction

Start in NotificationHistoryResponse.ts and compare its notificationHistory item validator with NotificationHistoryResponseItem.ts, then run the build and the reproduction from the issue. Add regression coverage for malformed signedPayload, sendAttempts, and nested attempt fields, while confirming valid items and omitted optional fields remain accepted.

Written by the indexing model from the issue text.

Assessment

Tech stack
nodejs, typescript
Domain
api, testing
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
88/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.