@@ -5,15 +5,21 @@ import {
5
5
createKeysForAuthStorage ,
6
6
} from 'aws-amplify/adapter-core' ;
7
7
8
- import { IS_SIGNING_OUT_COOKIE_NAME } from '../../../src/auth/constant' ;
8
+ import {
9
+ IS_SIGNING_OUT_COOKIE_NAME ,
10
+ IS_SIGNING_OUT_REDIRECTING_COOKIE_NAME ,
11
+ } from '../../../src/auth/constant' ;
9
12
import { handleSignOutCallbackRequest } from '../../../src/auth/handlers/handleSignOutCallbackRequest' ;
10
13
import { CreateAuthRoutesHandlersInput } from '../../../src/auth/types' ;
11
14
import {
12
15
appendSetCookieHeaders ,
16
+ createAuthFlowProofCookiesRemoveOptions ,
17
+ createRedirectionIntermediary ,
13
18
createTokenCookiesRemoveOptions ,
14
19
createTokenRemoveCookies ,
15
20
getCookieValuesFromRequest ,
16
21
getRedirectOrDefault ,
22
+ resolveRedirectSignOutUrl ,
17
23
revokeAuthNTokens ,
18
24
} from '../../../src/auth/utils' ;
19
25
@@ -32,6 +38,13 @@ const mockGetCookieValuesFromRequest = jest.mocked(getCookieValuesFromRequest);
32
38
const mockRevokeAuthNTokens = jest . mocked ( revokeAuthNTokens ) ;
33
39
const mockCreateKeysForAuthStorage = jest . mocked ( createKeysForAuthStorage ) ;
34
40
const mockGetRedirectOrDefault = jest . mocked ( getRedirectOrDefault ) ;
41
+ const mockCreateAuthFlowProofCookiesRemoveOptions = jest . mocked (
42
+ createAuthFlowProofCookiesRemoveOptions ,
43
+ ) ;
44
+ const mockCreateRedirectionIntermediary = jest . mocked (
45
+ createRedirectionIntermediary ,
46
+ ) ;
47
+ const mockResolveRedirectSignOutUrl = jest . mocked ( resolveRedirectSignOutUrl ) ;
35
48
36
49
describe ( 'handleSignOutCallbackRequest' , ( ) => {
37
50
const mockRequest = new Request (
@@ -57,6 +70,9 @@ describe('handleSignOutCallbackRequest', () => {
57
70
mockGetCookieValuesFromRequest . mockClear ( ) ;
58
71
mockRevokeAuthNTokens . mockClear ( ) ;
59
72
mockGetRedirectOrDefault . mockClear ( ) ;
73
+ mockCreateAuthFlowProofCookiesRemoveOptions . mockClear ( ) ;
74
+ mockCreateRedirectionIntermediary . mockClear ( ) ;
75
+ mockResolveRedirectSignOutUrl . mockClear ( ) ;
60
76
} ) ;
61
77
62
78
it ( `returns a 400 response when the request does not have the "${ IS_SIGNING_OUT_COOKIE_NAME } " cookie` , async ( ) => {
@@ -68,6 +84,7 @@ describe('handleSignOutCallbackRequest', () => {
68
84
userPoolClientId : mockUserPoolClientId ,
69
85
oAuthConfig : mockOAuthConfig ,
70
86
setCookieOptions : mockSetCookieOptions ,
87
+ origin : 'https://example.com' ,
71
88
} ) ;
72
89
73
90
// verify the response
@@ -76,9 +93,88 @@ describe('handleSignOutCallbackRequest', () => {
76
93
// verify the calls to dependencies
77
94
expect ( mockGetCookieValuesFromRequest ) . toHaveBeenCalledWith ( mockRequest , [
78
95
IS_SIGNING_OUT_COOKIE_NAME ,
96
+ IS_SIGNING_OUT_REDIRECTING_COOKIE_NAME ,
79
97
] ) ;
80
98
} ) ;
81
99
100
+ it ( `returns a 200 response with the intermediate redirect HTML when the request has the "${ IS_SIGNING_OUT_COOKIE_NAME } " and "${ IS_SIGNING_OUT_REDIRECTING_COOKIE_NAME } " cookies` , async ( ) => {
101
+ mockGetCookieValuesFromRequest . mockReturnValueOnce ( {
102
+ [ IS_SIGNING_OUT_COOKIE_NAME ] : 'true' ,
103
+ [ IS_SIGNING_OUT_REDIRECTING_COOKIE_NAME ] : 'true' ,
104
+ } ) ;
105
+ const mockCreateTokenRemoveCookiesResult = [
106
+ {
107
+ name : IS_SIGNING_OUT_REDIRECTING_COOKIE_NAME ,
108
+ value : '' ,
109
+ } ,
110
+ ] ;
111
+ mockCreateTokenRemoveCookies . mockReturnValueOnce (
112
+ mockCreateTokenRemoveCookiesResult ,
113
+ ) ;
114
+ const mockCreateTokenCookiesRemoveOptionsResult = {
115
+ path : '/' ,
116
+ maxAge : - 1 ,
117
+ domain : mockSetCookieOptions . domain ,
118
+ } ;
119
+ mockCreateAuthFlowProofCookiesRemoveOptions . mockReturnValueOnce (
120
+ mockCreateTokenCookiesRemoveOptionsResult ,
121
+ ) ;
122
+ const mockResolveRedirectSignOutUrlResult =
123
+ 'https://example.com/sign-out-callback' ;
124
+ mockResolveRedirectSignOutUrl . mockReturnValueOnce (
125
+ mockResolveRedirectSignOutUrlResult ,
126
+ ) ;
127
+ const mockCreateOnSignInCompleteRedirectIntermediateResult =
128
+ '<html><head><meta http-equiv="refresh" content="0;url=/"></head></html>' ;
129
+ mockCreateRedirectionIntermediary . mockReturnValueOnce (
130
+ mockCreateOnSignInCompleteRedirectIntermediateResult ,
131
+ ) ;
132
+ mockAppendSetCookieHeaders . mockImplementationOnce ( headers => {
133
+ headers . append (
134
+ 'Set-Cookie' ,
135
+ 'mock_cookie1=; Domain=.example.com; Path=/' ,
136
+ ) ;
137
+ headers . append (
138
+ 'Set-Cookie' ,
139
+ 'mock_cookie2=; Domain=.example.com; Path=/' ,
140
+ ) ;
141
+ } ) ;
142
+
143
+ const response = await handleSignOutCallbackRequest ( {
144
+ request : mockRequest ,
145
+ handlerInput : mockHandlerInput ,
146
+ userPoolClientId : mockUserPoolClientId ,
147
+ oAuthConfig : mockOAuthConfig ,
148
+ setCookieOptions : mockSetCookieOptions ,
149
+ origin : 'https://example.com' ,
150
+ } ) ;
151
+
152
+ // verify the response
153
+ expect ( response . status ) . toBe ( 200 ) ;
154
+ expect ( response . headers . get ( 'Content-Type' ) ) . toBe ( 'text/html' ) ;
155
+ expect ( response . headers . get ( 'Set-Cookie' ) ) . toBe (
156
+ 'mock_cookie1=; Domain=.example.com; Path=/, mock_cookie2=; Domain=.example.com; Path=/' ,
157
+ ) ;
158
+ expect ( await response . text ( ) ) . toBe (
159
+ mockCreateOnSignInCompleteRedirectIntermediateResult ,
160
+ ) ;
161
+
162
+ // verify the calls to dependencies
163
+ expect ( mockCreateTokenRemoveCookies ) . toHaveBeenCalledWith ( [
164
+ IS_SIGNING_OUT_REDIRECTING_COOKIE_NAME ,
165
+ ] ) ;
166
+ expect ( mockCreateAuthFlowProofCookiesRemoveOptions ) . toHaveBeenCalledWith (
167
+ mockSetCookieOptions ,
168
+ ) ;
169
+ expect ( mockResolveRedirectSignOutUrl ) . toHaveBeenCalledWith (
170
+ 'https://example.com' ,
171
+ mockOAuthConfig ,
172
+ ) ;
173
+ expect ( mockCreateRedirectionIntermediary ) . toHaveBeenCalledWith ( {
174
+ redirectTo : mockResolveRedirectSignOutUrlResult ,
175
+ } ) ;
176
+ } ) ;
177
+
82
178
it ( 'returns a 302 response to redirect to handlerInput.redirectOnSignOutComplete when the request cookies do not have a username' , async ( ) => {
83
179
mockGetCookieValuesFromRequest
84
180
. mockReturnValueOnce ( {
@@ -92,6 +188,7 @@ describe('handleSignOutCallbackRequest', () => {
92
188
userPoolClientId : mockUserPoolClientId ,
93
189
oAuthConfig : mockOAuthConfig ,
94
190
setCookieOptions : mockSetCookieOptions ,
191
+ origin : 'https://example.com' ,
95
192
} ) ;
96
193
97
194
// verify the response
@@ -101,6 +198,7 @@ describe('handleSignOutCallbackRequest', () => {
101
198
// verify the calls to dependencies
102
199
expect ( mockGetCookieValuesFromRequest ) . toHaveBeenCalledWith ( mockRequest , [
103
200
IS_SIGNING_OUT_COOKIE_NAME ,
201
+ IS_SIGNING_OUT_REDIRECTING_COOKIE_NAME ,
104
202
] ) ;
105
203
expect ( mockGetCookieValuesFromRequest ) . toHaveBeenCalledWith ( mockRequest , [
106
204
`${ AUTH_KEY_PREFIX } .${ mockUserPoolClientId } .LastAuthUser` ,
@@ -126,6 +224,7 @@ describe('handleSignOutCallbackRequest', () => {
126
224
userPoolClientId : mockUserPoolClientId ,
127
225
oAuthConfig : mockOAuthConfig ,
128
226
setCookieOptions : mockSetCookieOptions ,
227
+ origin : 'https://example.com' ,
129
228
} ) ;
130
229
131
230
// verify the response
@@ -136,6 +235,7 @@ describe('handleSignOutCallbackRequest', () => {
136
235
// verify the calls to dependencies
137
236
expect ( mockGetCookieValuesFromRequest ) . toHaveBeenCalledWith ( mockRequest , [
138
237
IS_SIGNING_OUT_COOKIE_NAME ,
238
+ IS_SIGNING_OUT_REDIRECTING_COOKIE_NAME ,
139
239
] ) ;
140
240
expect ( mockGetCookieValuesFromRequest ) . toHaveBeenCalledWith ( mockRequest , [
141
241
`${ AUTH_KEY_PREFIX } .${ mockUserPoolClientId } .LastAuthUser` ,
@@ -167,6 +267,7 @@ describe('handleSignOutCallbackRequest', () => {
167
267
userPoolClientId : mockUserPoolClientId ,
168
268
oAuthConfig : mockOAuthConfig ,
169
269
setCookieOptions : mockSetCookieOptions ,
270
+ origin : 'https://example.com' ,
170
271
} ) ;
171
272
172
273
// verify the response
@@ -176,6 +277,7 @@ describe('handleSignOutCallbackRequest', () => {
176
277
// verify the calls to dependencies
177
278
expect ( mockGetCookieValuesFromRequest ) . toHaveBeenCalledWith ( mockRequest , [
178
279
IS_SIGNING_OUT_COOKIE_NAME ,
280
+ IS_SIGNING_OUT_REDIRECTING_COOKIE_NAME ,
179
281
] ) ;
180
282
expect ( mockGetCookieValuesFromRequest ) . toHaveBeenCalledWith ( mockRequest , [
181
283
`${ AUTH_KEY_PREFIX } .${ mockUserPoolClientId } .LastAuthUser` ,
@@ -257,6 +359,7 @@ describe('handleSignOutCallbackRequest', () => {
257
359
userPoolClientId : mockUserPoolClientId ,
258
360
oAuthConfig : mockOAuthConfig ,
259
361
setCookieOptions : mockSetCookieOptions ,
362
+ origin : 'https://example.com' ,
260
363
} ) ;
261
364
262
365
// verify the calls to dependencies
@@ -269,6 +372,7 @@ describe('handleSignOutCallbackRequest', () => {
269
372
// verify the calls to dependencies
270
373
expect ( mockGetCookieValuesFromRequest ) . toHaveBeenCalledWith ( mockRequest , [
271
374
IS_SIGNING_OUT_COOKIE_NAME ,
375
+ IS_SIGNING_OUT_REDIRECTING_COOKIE_NAME ,
272
376
] ) ;
273
377
expect ( mockGetCookieValuesFromRequest ) . toHaveBeenCalledWith ( mockRequest , [
274
378
`${ AUTH_KEY_PREFIX } .${ mockUserPoolClientId } .LastAuthUser` ,
0 commit comments