raindancers-cloudfront 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -90,11 +90,12 @@ function generateCodeChallenge(verifier) {
|
|
|
90
90
|
return hash.digest('base64url');
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
function generateState(originalPath) {
|
|
93
|
+
function generateState(originalPath, host) {
|
|
94
94
|
var randomPart = Math.random().toString(36).substring(2) + Date.now().toString(36);
|
|
95
95
|
var stateObj = {
|
|
96
96
|
r: randomPart,
|
|
97
|
-
p: originalPath
|
|
97
|
+
p: originalPath,
|
|
98
|
+
h: host
|
|
98
99
|
};
|
|
99
100
|
return btoa(JSON.stringify(stateObj)).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
|
100
101
|
}
|
|
@@ -136,8 +137,8 @@ function getOriginalPath(request) {
|
|
|
136
137
|
return request.uri + '?' + qs;
|
|
137
138
|
}
|
|
138
139
|
|
|
139
|
-
function redirectToAuth(originalPath) {
|
|
140
|
-
var state = generateState(originalPath);
|
|
140
|
+
function redirectToAuth(originalPath, host) {
|
|
141
|
+
var state = generateState(originalPath, host);
|
|
141
142
|
var codeVerifier = generateCodeVerifier();
|
|
142
143
|
var codeChallenge = generateCodeChallenge(codeVerifier);
|
|
143
144
|
var domainAttr = COOKIE_DOMAIN ? '; Domain=' + COOKIE_DOMAIN : '';
|
|
@@ -169,17 +170,18 @@ async function handler(event) {
|
|
|
169
170
|
}
|
|
170
171
|
|
|
171
172
|
var cookies = request.cookies;
|
|
173
|
+
var host = request.headers.host ? request.headers.host.value : '';
|
|
172
174
|
|
|
173
175
|
// Check for session cookie (supports both __Secure- with domain and __Host- without)
|
|
174
176
|
var sessionCookie = cookies['__Secure-auth_session'] || cookies['__Host-auth_session'];
|
|
175
177
|
if (!sessionCookie) {
|
|
176
|
-
return redirectToAuth(getOriginalPath(request));
|
|
178
|
+
return redirectToAuth(getOriginalPath(request), host);
|
|
177
179
|
}
|
|
178
180
|
|
|
179
181
|
var token = sessionCookie.value;
|
|
180
182
|
|
|
181
183
|
if (!token || token.length === 0) {
|
|
182
|
-
return redirectToAuth(getOriginalPath(request));
|
|
184
|
+
return redirectToAuth(getOriginalPath(request), host);
|
|
183
185
|
}
|
|
184
186
|
|
|
185
187
|
try {
|
|
@@ -187,19 +189,19 @@ async function handler(event) {
|
|
|
187
189
|
var parts = token.split('.');
|
|
188
190
|
|
|
189
191
|
if (parts.length !== 3) {
|
|
190
|
-
return redirectToAuth(originalPath);
|
|
192
|
+
return redirectToAuth(originalPath, host);
|
|
191
193
|
}
|
|
192
194
|
|
|
193
195
|
var isValid = await validateHmacSignature(token);
|
|
194
196
|
if (!isValid) {
|
|
195
|
-
return redirectToAuth(originalPath);
|
|
197
|
+
return redirectToAuth(originalPath, host);
|
|
196
198
|
}
|
|
197
199
|
|
|
198
200
|
var payload = JSON.parse(base64urlDecode(parts[1]));
|
|
199
201
|
var now = Math.floor(Date.now() / 1000);
|
|
200
202
|
|
|
201
203
|
if (payload.exp && payload.exp < now) {
|
|
202
|
-
return redirectToAuth(originalPath);
|
|
204
|
+
return redirectToAuth(originalPath, host);
|
|
203
205
|
}
|
|
204
206
|
|
|
205
207
|
// Check if session is revoked (denylist approach)
|
|
@@ -209,7 +211,7 @@ async function handler(event) {
|
|
|
209
211
|
var isRevoked = await kvsHandle.get('revoked:' + jti);
|
|
210
212
|
if (isRevoked) {
|
|
211
213
|
console.log('Session revoked: ' + jti);
|
|
212
|
-
return redirectToAuth(originalPath);
|
|
214
|
+
return redirectToAuth(originalPath, host);
|
|
213
215
|
}
|
|
214
216
|
} catch (e) {
|
|
215
217
|
console.log('KVS error checking revocation: ' + e);
|
|
@@ -218,6 +220,6 @@ async function handler(event) {
|
|
|
218
220
|
|
|
219
221
|
return request;
|
|
220
222
|
} catch (e) {
|
|
221
|
-
return redirectToAuth(getOriginalPath(request));
|
|
223
|
+
return redirectToAuth(getOriginalPath(request), host);
|
|
222
224
|
}
|
|
223
225
|
}
|
|
@@ -82,11 +82,12 @@ function generateCodeChallenge(verifier) {
|
|
|
82
82
|
return hash.digest('base64url');
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
function generateState(originalPath) {
|
|
85
|
+
function generateState(originalPath, host) {
|
|
86
86
|
var randomPart = Math.random().toString(36).substring(2) + Date.now().toString(36);
|
|
87
87
|
var stateObj = {
|
|
88
88
|
r: randomPart,
|
|
89
|
-
p: originalPath
|
|
89
|
+
p: originalPath,
|
|
90
|
+
h: host
|
|
90
91
|
};
|
|
91
92
|
return btoa(JSON.stringify(stateObj)).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
|
92
93
|
}
|
|
@@ -128,8 +129,8 @@ function getOriginalPath(request) {
|
|
|
128
129
|
return request.uri + '?' + qs;
|
|
129
130
|
}
|
|
130
131
|
|
|
131
|
-
function redirectToAuth(originalPath) {
|
|
132
|
-
var state = generateState(originalPath);
|
|
132
|
+
function redirectToAuth(originalPath, host) {
|
|
133
|
+
var state = generateState(originalPath, host);
|
|
133
134
|
var codeVerifier = generateCodeVerifier();
|
|
134
135
|
var codeChallenge = generateCodeChallenge(codeVerifier);
|
|
135
136
|
var domainAttr = COOKIE_DOMAIN ? '; Domain=' + COOKIE_DOMAIN : '';
|
|
@@ -162,18 +163,19 @@ async function checkAuth(event, decodedPayload, requiredRoles, roleMatchMode) {
|
|
|
162
163
|
}
|
|
163
164
|
var cookies = request.cookies;
|
|
164
165
|
var originalPath = getOriginalPath(request);
|
|
166
|
+
var host = request.headers.host ? request.headers.host.value : '';
|
|
165
167
|
var sessionCookie = cookies['__Secure-auth_session'] || cookies['__Host-auth_session'];
|
|
166
168
|
if (!sessionCookie) {
|
|
167
169
|
return {
|
|
168
170
|
pass: false,
|
|
169
|
-
response: redirectToAuth(originalPath)
|
|
171
|
+
response: redirectToAuth(originalPath, host)
|
|
170
172
|
};
|
|
171
173
|
}
|
|
172
174
|
var token = sessionCookie.value;
|
|
173
175
|
if (!token || token.length === 0) {
|
|
174
176
|
return {
|
|
175
177
|
pass: false,
|
|
176
|
-
response: redirectToAuth(originalPath)
|
|
178
|
+
response: redirectToAuth(originalPath, host)
|
|
177
179
|
};
|
|
178
180
|
}
|
|
179
181
|
try {
|
|
@@ -181,14 +183,14 @@ async function checkAuth(event, decodedPayload, requiredRoles, roleMatchMode) {
|
|
|
181
183
|
if (parts.length !== 3) {
|
|
182
184
|
return {
|
|
183
185
|
pass: false,
|
|
184
|
-
response: redirectToAuth(originalPath)
|
|
186
|
+
response: redirectToAuth(originalPath, host)
|
|
185
187
|
};
|
|
186
188
|
}
|
|
187
189
|
var isValid = await validateHmacSignature(token);
|
|
188
190
|
if (!isValid) {
|
|
189
191
|
return {
|
|
190
192
|
pass: false,
|
|
191
|
-
response: redirectToAuth(originalPath)
|
|
193
|
+
response: redirectToAuth(originalPath, host)
|
|
192
194
|
};
|
|
193
195
|
}
|
|
194
196
|
var payload = JSON.parse(base64urlDecode(parts[1]));
|
|
@@ -196,7 +198,7 @@ async function checkAuth(event, decodedPayload, requiredRoles, roleMatchMode) {
|
|
|
196
198
|
if (payload.exp && payload.exp < now) {
|
|
197
199
|
return {
|
|
198
200
|
pass: false,
|
|
199
|
-
response: redirectToAuth(originalPath)
|
|
201
|
+
response: redirectToAuth(originalPath, host)
|
|
200
202
|
};
|
|
201
203
|
}
|
|
202
204
|
var jti = payload.jti;
|
|
@@ -206,7 +208,7 @@ async function checkAuth(event, decodedPayload, requiredRoles, roleMatchMode) {
|
|
|
206
208
|
if (isRevoked) {
|
|
207
209
|
return {
|
|
208
210
|
pass: false,
|
|
209
|
-
response: redirectToAuth(originalPath)
|
|
211
|
+
response: redirectToAuth(originalPath, host)
|
|
210
212
|
};
|
|
211
213
|
}
|
|
212
214
|
} catch (e) {}
|
|
@@ -250,7 +252,7 @@ async function checkAuth(event, decodedPayload, requiredRoles, roleMatchMode) {
|
|
|
250
252
|
} catch (e) {
|
|
251
253
|
return {
|
|
252
254
|
pass: false,
|
|
253
|
-
response: redirectToAuth(originalPath)
|
|
255
|
+
response: redirectToAuth(originalPath, host)
|
|
254
256
|
};
|
|
255
257
|
}
|
|
256
258
|
}
|
|
@@ -328,15 +328,20 @@ def lambda_handler(event, context):
|
|
|
328
328
|
|
|
329
329
|
logger.info(f'CSRF validation passed, proceeding with token exchange')
|
|
330
330
|
|
|
331
|
-
# Decode state to get original path
|
|
331
|
+
# Decode state to get original path and host
|
|
332
332
|
redirect_path = '/'
|
|
333
333
|
try:
|
|
334
334
|
# Decode base64url state
|
|
335
335
|
state_padded = state + '=' * (4 - len(state) % 4)
|
|
336
336
|
state_decoded = base64.urlsafe_b64decode(state_padded.replace('-', '+').replace('_', '/')).decode('utf-8')
|
|
337
337
|
state_obj = json.loads(state_decoded)
|
|
338
|
-
|
|
339
|
-
|
|
338
|
+
original_path = state_obj.get('p', '/')
|
|
339
|
+
original_host = state_obj.get('h', '')
|
|
340
|
+
if original_host:
|
|
341
|
+
redirect_path = f'https://{original_host}{original_path}'
|
|
342
|
+
else:
|
|
343
|
+
redirect_path = original_path
|
|
344
|
+
logger.info(f'Decoded redirect target from state: {redirect_path}')
|
|
340
345
|
except Exception as e:
|
|
341
346
|
logger.warning(f'Could not decode state, using default redirect: {str(e)}')
|
|
342
347
|
redirect_path = '/'
|