Skip to content

Commit b869302

Browse files
committed
feat(event-stream): update event stream handler to use message signer
1 parent 80b981d commit b869302

File tree

7 files changed

+69
-49
lines changed

7 files changed

+69
-49
lines changed

packages/eventstream-handler-node/src/EventSigningStream.spec.ts

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { EventStreamCodec } from "@aws-sdk/eventstream-codec";
2-
import { Message, MessageHeaders } from "@aws-sdk/types";
2+
import { Message, MessageHeaders, SignedMessage } from "@aws-sdk/types";
33
import { fromUtf8, toUtf8 } from "@aws-sdk/util-utf8";
44

55
import { EventSigningStream } from "./EventSigningStream";
@@ -13,18 +13,17 @@ describe("EventSigningStream", () => {
1313

1414
it("should sign a eventstream payload properly", (done) => {
1515
const eventStreamCodec = new EventStreamCodec(toUtf8, fromUtf8);
16-
const inputChunks: Array<Uint8Array> = (
17-
[
18-
{
19-
headers: {},
20-
body: fromUtf8("foo"),
21-
},
22-
{
23-
headers: {},
24-
body: fromUtf8("bar"),
25-
},
26-
] as Array<Message>
27-
).map((event) => eventStreamCodec.encode(event));
16+
const message1: Message = {
17+
headers: {},
18+
body: fromUtf8("foo"),
19+
};
20+
const message2: Message = {
21+
headers: {},
22+
body: fromUtf8("bar"),
23+
};
24+
const inputChunks: Array<Uint8Array> = ([message1, message2] as Array<Message>).map((event) =>
25+
eventStreamCodec.encode(event)
26+
);
2827
const expected: Array<MessageHeaders> = [
2928
{
3029
":date": { type: "timestamp", value: new Date(1546045446000) },
@@ -41,10 +40,10 @@ describe("EventSigningStream", () => {
4140
},
4241
},
4342
];
44-
const mockEventSigner = jest
43+
const mockMessageSigner = jest
4544
.fn()
46-
.mockReturnValueOnce("7369676e617475726531") //'signature1'
47-
.mockReturnValueOnce("7369676e617475726532"); //'signature2'
45+
.mockReturnValueOnce({ message: message1, signature: "7369676e617475726531" } as SignedMessage) //'signature1'
46+
.mockReturnValueOnce({ message: message2, signature: "7369676e617475726532" } as SignedMessage); //'signature2'
4847
// mock 'new Date()'
4948
let mockDateCount = 0;
5049
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -58,7 +57,10 @@ describe("EventSigningStream", () => {
5857
});
5958
const signingStream = new EventSigningStream({
6059
priorSignature: "initial",
61-
eventSigner: { sign: mockEventSigner },
60+
messageSigner: {
61+
sign: mockMessageSigner,
62+
signMessage: mockMessageSigner,
63+
},
6264
eventStreamCodec,
6365
});
6466
const output: Array<MessageHeaders> = [];
@@ -67,12 +69,12 @@ describe("EventSigningStream", () => {
6769
});
6870
signingStream.on("end", () => {
6971
expect(output).toEqual(expected);
70-
expect(mockEventSigner.mock.calls[0][1].priorSignature).toBe("initial");
71-
expect(mockEventSigner.mock.calls[0][1].signingDate.getTime()).toBe(
72+
expect(mockMessageSigner.mock.calls[0][0].priorSignature).toBe("initial");
73+
expect(mockMessageSigner.mock.calls[0][1].signingDate.getTime()).toBe(
7274
(expected[0][":date"].value as Date).getTime()
7375
);
74-
expect(mockEventSigner.mock.calls[1][1].priorSignature).toBe("7369676e617475726531");
75-
expect(mockEventSigner.mock.calls[1][1].signingDate.getTime()).toBe(
76+
expect(mockMessageSigner.mock.calls[1][0].priorSignature).toBe("7369676e617475726531");
77+
expect(mockMessageSigner.mock.calls[1][1].signingDate.getTime()).toBe(
7678
(expected[1][":date"].value as Date).getTime()
7779
);
7880
done();

packages/eventstream-handler-node/src/EventSigningStream.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
import { EventStreamCodec } from "@aws-sdk/eventstream-codec";
2-
import { EventSigner, MessageHeaders } from "@aws-sdk/types";
2+
import { MessageHeaders, MessageSigner } from "@aws-sdk/types";
33
import { Transform, TransformCallback, TransformOptions } from "stream";
44

55
/**
66
* @internal
77
*/
88
export interface EventSigningStreamOptions extends TransformOptions {
99
priorSignature: string;
10-
eventSigner: EventSigner;
10+
messageSigner: MessageSigner;
1111
eventStreamCodec: EventStreamCodec;
1212
}
1313

1414
/**
1515
* @internal
16-
*
16+
*
1717
* A transform stream that signs the eventstream
1818
*/
1919
export class EventSigningStream extends Transform {
2020
private priorSignature: string;
21-
private eventSigner: EventSigner;
21+
private messageSigner: MessageSigner;
2222
private eventStreamCodec: EventStreamCodec;
2323

2424
constructor(options: EventSigningStreamOptions) {
@@ -30,8 +30,8 @@ export class EventSigningStream extends Transform {
3030
});
3131

3232
this.priorSignature = options.priorSignature;
33-
this.eventSigner = options.eventSigner;
3433
this.eventStreamCodec = options.eventStreamCodec;
34+
this.messageSigner = options.messageSigner;
3535
}
3636

3737
async _transform(chunk: Uint8Array, encoding: string, callback: TransformCallback): Promise<void> {
@@ -40,23 +40,25 @@ export class EventSigningStream extends Transform {
4040
const dateHeader: MessageHeaders = {
4141
":date": { type: "timestamp", value: now },
4242
};
43-
const signature = await this.eventSigner.sign(
43+
const signedMessage = await this.messageSigner.sign(
4444
{
45-
payload: chunk,
46-
headers: this.eventStreamCodec.formatHeaders(dateHeader),
45+
message: {
46+
body: chunk,
47+
headers: dateHeader,
48+
},
49+
priorSignature: this.priorSignature,
4750
},
4851
{
49-
priorSignature: this.priorSignature,
5052
signingDate: now,
5153
}
5254
);
53-
this.priorSignature = signature;
55+
this.priorSignature = signedMessage.signature;
5456
const serializedSigned = this.eventStreamCodec.encode({
5557
headers: {
5658
...dateHeader,
5759
":chunk-signature": {
5860
type: "binary",
59-
value: getSignatureBinary(signature),
61+
value: getSignatureBinary(signedMessage.signature),
6062
},
6163
},
6264
body: chunk,

packages/eventstream-handler-node/src/EventStreamPayloadHandler.spec.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import { EventStreamCodec } from "@aws-sdk/eventstream-codec";
2-
import { Decoder, Encoder, EventSigner, FinalizeHandler, FinalizeHandlerArguments, HttpRequest } from "@aws-sdk/types";
2+
import {
3+
Decoder,
4+
Encoder,
5+
FinalizeHandler,
6+
FinalizeHandlerArguments,
7+
HttpRequest,
8+
MessageSigner,
9+
} from "@aws-sdk/types";
310
import { PassThrough, Readable } from "stream";
411

512
import { EventSigningStream } from "./EventSigningStream";
@@ -9,8 +16,9 @@ jest.mock("./EventSigningStream");
916
jest.mock("@aws-sdk/eventstream-codec");
1017

1118
describe(EventStreamPayloadHandler.name, () => {
12-
const mockSigner: EventSigner = {
19+
const mockMessageSigner: MessageSigner = {
1320
sign: jest.fn(),
21+
signMessage: jest.fn(),
1422
};
1523
const mockUtf8Decoder: Decoder = jest.fn();
1624
const mockUtf8encoder: Encoder = jest.fn();
@@ -27,7 +35,7 @@ describe(EventStreamPayloadHandler.name, () => {
2735

2836
it("should throw if request payload is not a stream", () => {
2937
const handler = new EventStreamPayloadHandler({
30-
eventSigner: () => Promise.resolve(mockSigner),
38+
messageSigner: () => Promise.resolve(mockMessageSigner),
3139
utf8Decoder: mockUtf8Decoder,
3240
utf8Encoder: mockUtf8encoder,
3341
});
@@ -44,7 +52,7 @@ describe(EventStreamPayloadHandler.name, () => {
4452
(mockNextHandler as any).mockImplementationOnce(() => Promise.reject(mockError));
4553

4654
const handler = new EventStreamPayloadHandler({
47-
eventSigner: () => Promise.resolve(mockSigner),
55+
messageSigner: () => Promise.resolve(mockMessageSigner),
4856
utf8Decoder: mockUtf8Decoder,
4957
utf8Encoder: mockUtf8encoder,
5058
});
@@ -74,7 +82,7 @@ describe(EventStreamPayloadHandler.name, () => {
7482
} as any;
7583

7684
const handler = new EventStreamPayloadHandler({
77-
eventSigner: () => Promise.resolve(mockSigner),
85+
messageSigner: () => Promise.resolve(mockMessageSigner),
7886
utf8Decoder: mockUtf8Decoder,
7987
utf8Encoder: mockUtf8encoder,
8088
});
@@ -88,7 +96,7 @@ describe(EventStreamPayloadHandler.name, () => {
8896
expect(EventSigningStream).toHaveBeenCalledWith({
8997
priorSignature,
9098
eventStreamCodec: expect.anything(),
91-
eventSigner: expect.anything(),
99+
messageSigner: expect.anything(),
92100
});
93101
});
94102

@@ -105,7 +113,7 @@ describe(EventStreamPayloadHandler.name, () => {
105113
} as any;
106114

107115
const handler = new EventStreamPayloadHandler({
108-
eventSigner: () => Promise.resolve(mockSigner),
116+
messageSigner: () => Promise.resolve(mockMessageSigner),
109117
utf8Decoder: mockUtf8Decoder,
110118
utf8Encoder: mockUtf8encoder,
111119
});
@@ -119,7 +127,7 @@ describe(EventStreamPayloadHandler.name, () => {
119127
expect(EventSigningStream).toHaveBeenCalledWith({
120128
priorSignature,
121129
eventStreamCodec: expect.anything(),
122-
eventSigner: expect.anything(),
130+
messageSigner: expect.anything(),
123131
});
124132
});
125133

@@ -132,7 +140,7 @@ describe(EventStreamPayloadHandler.name, () => {
132140
headers: { authorization },
133141
} as any;
134142
const handler = new EventStreamPayloadHandler({
135-
eventSigner: () => Promise.resolve(mockSigner),
143+
messageSigner: () => Promise.resolve(mockMessageSigner),
136144
utf8Decoder: mockUtf8Decoder,
137145
utf8Encoder: mockUtf8encoder,
138146
});

packages/eventstream-handler-node/src/EventStreamPayloadHandler.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { EventStreamCodec } from "@aws-sdk/eventstream-codec";
22
import {
33
Decoder,
44
Encoder,
5-
EventSigner,
65
EventStreamPayloadHandler as IEventStreamPayloadHandler,
76
FinalizeHandler,
87
FinalizeHandlerArguments,
@@ -21,7 +20,7 @@ import { EventSigningStream } from "./EventSigningStream";
2120
* @internal
2221
*/
2322
export interface EventStreamPayloadHandlerOptions {
24-
eventSigner: Provider<EventSigner>;
23+
messageSigner: Provider<MessageSigner>;
2524
utf8Encoder: Encoder;
2625
utf8Decoder: Decoder;
2726
}
@@ -36,11 +35,11 @@ export interface EventStreamPayloadHandlerOptions {
3635
* 4. Sign the payload after payload stream starting to flow.
3736
*/
3837
export class EventStreamPayloadHandler implements IEventStreamPayloadHandler {
39-
private readonly eventSigner: Provider<EventSigner>;
38+
private readonly messageSigner: Provider<MessageSigner>;
4039
private readonly eventStreamCodec: EventStreamCodec;
4140

4241
constructor(options: EventStreamPayloadHandlerOptions) {
43-
this.eventSigner = options.eventSigner;
42+
this.messageSigner = options.messageSigner;
4443
this.eventStreamCodec = new EventStreamCodec(options.utf8Encoder, options.utf8Decoder);
4544
}
4645

@@ -79,7 +78,7 @@ export class EventStreamPayloadHandler implements IEventStreamPayloadHandler {
7978
const signingStream = new EventSigningStream({
8079
priorSignature,
8180
eventStreamCodec: this.eventStreamCodec,
82-
eventSigner: await this.eventSigner(),
81+
messageSigner: await this.messageSigner(),
8382
});
8483

8584
pipeline(payloadStream, signingStream, request.body, (err: NodeJS.ErrnoException | null) => {
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1-
import { Decoder, Encoder, EventSigner, EventStreamPayloadHandlerProvider, Provider } from "@aws-sdk/types";
1+
import {
2+
Decoder,
3+
Encoder,
4+
EventSigner,
5+
EventStreamPayloadHandlerProvider,
6+
MessageSigner,
7+
Provider,
8+
} from "@aws-sdk/types";
29

310
import { EventStreamPayloadHandler } from "./EventStreamPayloadHandler";
411

512
/** NodeJS event stream utils provider */
613
export const eventStreamPayloadHandlerProvider: EventStreamPayloadHandlerProvider = (options: {
714
utf8Encoder: Encoder;
815
utf8Decoder: Decoder;
9-
eventSigner: Provider<EventSigner>;
16+
messageSigner: Provider<MessageSigner>;
1017
}) => new EventStreamPayloadHandler(options);

packages/middleware-eventstream/src/configuration.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@ export function resolveEventStreamConfig<T>(
3232
input: T & PreviouslyResolved & EventStreamInputConfig
3333
): T & EventStreamResolvedConfig {
3434
const eventSigner = input.signer;
35+
const messageSigner = input.signer;
3536
const eventStreamPayloadHandler = input.eventStreamPayloadHandlerProvider({
3637
...input,
37-
eventSigner,
38+
messageSigner,
3839
});
3940
return {
4041
...input,

packages/types/src/signature.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,5 @@ export interface SignedMessage {
164164
*/
165165
export interface MessageSigner {
166166
signMessage(message: SignableMessage, args: SigningArguments): Promise<SignedMessage>;
167+
sign(event: SignableMessage, options: SigningArguments): Promise<SignedMessage>;
167168
}

0 commit comments

Comments
 (0)