@@ -4,22 +4,24 @@ import { HttpRequest } from "@aws-sdk/protocol-http";
4
4
5
5
describe ( "SigningHandler" , ( ) => {
6
6
const noOpSigner : RequestSigner = {
7
- sign : ( request : HttpRequest ) =>
7
+ sign : ( request : HttpRequest , options : { signingDate : Date } ) =>
8
8
Promise . resolve ( {
9
9
...request ,
10
10
headers : {
11
11
...request . headers ,
12
- signed : "true"
12
+ signed : "true" ,
13
+ signingDateTime : options . signingDate . getTime ( )
13
14
}
14
15
} )
15
16
} as any ;
16
- const noOpNext = jest . fn ( ) ;
17
+ const noOpNext = jest . fn ( ) . mockReturnValue ( { response : "" } ) ;
17
18
18
19
beforeEach ( ( ) => {
19
20
( noOpNext as any ) . mockClear ( ) ;
20
21
} ) ;
21
22
22
23
it ( "should sign the request and pass it to the next handler" , async ( ) => {
24
+ expect . assertions ( 2 ) ;
23
25
const signingHandler = awsAuthMiddleware ( { signer : noOpSigner } as any ) (
24
26
noOpNext ,
25
27
{ } as any
@@ -35,4 +37,119 @@ describe("SigningHandler", () => {
35
37
expect ( calls . length ) . toBe ( 1 ) ;
36
38
expect ( calls [ 0 ] [ 0 ] . request . headers . signed ) . toBe ( "true" ) ;
37
39
} ) ;
40
+
41
+ it ( "should add systemClockOffset while signing the request" , async ( ) => {
42
+ expect . assertions ( 3 ) ;
43
+ const systemClockOffset = 1000000 ;
44
+ const now = Date . now ( ) ;
45
+ const signingHandler = awsAuthMiddleware ( {
46
+ signer : noOpSigner ,
47
+ systemClockOffset
48
+ } as any ) ( noOpNext , { } as any ) ;
49
+ await signingHandler ( {
50
+ input : { } ,
51
+ request : new HttpRequest ( {
52
+ headers : { }
53
+ } )
54
+ } ) ;
55
+
56
+ const { calls } = ( noOpNext as any ) . mock ;
57
+ expect ( calls . length ) . toBe ( 1 ) ;
58
+ expect ( calls [ 0 ] [ 0 ] . request . headers . signed ) . toBe ( "true" ) ;
59
+ // Using greater than to ensure there are no timing issues
60
+ expect ( calls [ 0 ] [ 0 ] . request . headers . signingDateTime ) . toBeGreaterThan (
61
+ now + systemClockOffset - 1
62
+ ) ;
63
+ } ) ;
64
+
65
+ describe ( "update systemClockOffset if there is clockSkew" , ( ) => {
66
+ // Set up clockSkew as abs(newSystemClockOffset - systemClockOffset) > 300000
67
+ const clockSkewPresent = [
68
+ { current : 100000 , new : 500000 } ,
69
+ { current : - 100000 , new : 250000 } ,
70
+ { current : 200000 , new : - 150000 } ,
71
+ { current : - 100000 , new : - 450000 }
72
+ ] ;
73
+
74
+ clockSkewPresent . forEach ( systemClockOffsetVal => {
75
+ it ( `current systemClockOffset: ${ systemClockOffsetVal . current } , new systemClockOffset: ${ systemClockOffsetVal . new } ` , async ( ) => {
76
+ expect . assertions ( 3 ) ;
77
+ const systemClockOffset = systemClockOffsetVal . current ;
78
+ const newSystemClockOffset = systemClockOffsetVal . new ;
79
+ const options = {
80
+ signer : noOpSigner ,
81
+ systemClockOffset
82
+ } ;
83
+ const signingHandler = awsAuthMiddleware ( options as any ) (
84
+ noOpNext ,
85
+ { } as any
86
+ ) ;
87
+ noOpNext . mockReturnValue ( {
88
+ response : {
89
+ headers : {
90
+ date : new Date ( Date . now ( ) + newSystemClockOffset ) . toString ( )
91
+ }
92
+ }
93
+ } ) ;
94
+
95
+ await signingHandler ( {
96
+ input : { } ,
97
+ request : new HttpRequest ( {
98
+ headers : { }
99
+ } )
100
+ } ) ;
101
+
102
+ const { calls } = ( noOpNext as any ) . mock ;
103
+ expect ( calls . length ) . toBe ( 1 ) ;
104
+ expect ( calls [ 0 ] [ 0 ] . request . headers . signed ) . toBe ( "true" ) ;
105
+ expect ( options . systemClockOffset ) . not . toBe ( systemClockOffset ) ;
106
+ } ) ;
107
+ } ) ;
108
+ } ) ;
109
+
110
+ describe ( "do not update systemClockOffset if there is no clockSkew" , ( ) => {
111
+ // Do not set up clockSkew as abs(newSystemClockOffset - systemClockOffset) < 300000
112
+ const clockSkewNotPresent = [
113
+ { current : 100000 , new : 250000 } ,
114
+ { current : - 100000 , new : 50000 } ,
115
+ { current : 50000 , new : - 150000 } ,
116
+ { current : - 100000 , new : - 150000 }
117
+ ] ;
118
+
119
+ clockSkewNotPresent . forEach ( systemClockOffsetVal => {
120
+ it ( `current systemClockOffset: ${ systemClockOffsetVal . current } , new systemClockOffset: ${ systemClockOffsetVal . new } ` , async ( ) => {
121
+ expect . assertions ( 3 ) ;
122
+ const systemClockOffset = systemClockOffsetVal . current ;
123
+ const newSystemClockOffset = systemClockOffsetVal . new ;
124
+ const options = {
125
+ signer : noOpSigner ,
126
+ systemClockOffset
127
+ } ;
128
+
129
+ const signingHandler = awsAuthMiddleware ( options as any ) (
130
+ noOpNext ,
131
+ { } as any
132
+ ) ;
133
+ noOpNext . mockReturnValue ( {
134
+ response : {
135
+ headers : {
136
+ date : new Date ( Date . now ( ) + newSystemClockOffset ) . toString ( )
137
+ }
138
+ }
139
+ } ) ;
140
+
141
+ await signingHandler ( {
142
+ input : { } ,
143
+ request : new HttpRequest ( {
144
+ headers : { }
145
+ } )
146
+ } ) ;
147
+
148
+ const { calls } = ( noOpNext as any ) . mock ;
149
+ expect ( calls . length ) . toBe ( 1 ) ;
150
+ expect ( calls [ 0 ] [ 0 ] . request . headers . signed ) . toBe ( "true" ) ;
151
+ expect ( options . systemClockOffset ) . toBe ( systemClockOffset ) ;
152
+ } ) ;
153
+ } ) ;
154
+ } ) ;
38
155
} ) ;
0 commit comments