@@ -57,21 +57,47 @@ export const ALLOWED_ORIGINS = getAllowedOrigins();
57
57
* Used to verify requests are coming from our frontend
58
58
*/
59
59
export function generateRequestToken ( req ) {
60
- // Try to use x-forwarded-host or origin's hostname instead of host to handle domain mapping
61
- // This handles the case where the request goes through a reverse proxy or domain mapping
60
+ // Try to determine the effective host that matches what the client would use
62
61
let effectiveHost = req . headers [ "host" ] ;
63
62
64
- // If there's an origin header, extract its hostname
65
- // as it will match the client's window.location.host
63
+ // First try to use origin header (best match for client's window.location.host)
66
64
if ( req . headers . origin ) {
67
65
try {
68
66
const originUrl = new URL ( req . headers . origin ) ;
69
67
effectiveHost = originUrl . host ;
70
68
} catch ( e ) {
71
- // Fall back to host header if origin parsing fails
72
69
console . log ( "Error parsing origin:" , e . message ) ;
73
70
}
74
71
}
72
+ // If no origin, try referer (can also contain the original hostname)
73
+ else if ( req . headers . referer ) {
74
+ try {
75
+ const refererUrl = new URL ( req . headers . referer ) ;
76
+ effectiveHost = refererUrl . host ;
77
+ } catch ( e ) {
78
+ console . log ( "Error parsing referer:" , e . message ) ;
79
+ }
80
+ }
81
+ // Fall back to x-forwarded-host which might be set by proxies
82
+ else if ( req . headers [ "x-forwarded-host" ] ) {
83
+ effectiveHost = req . headers [ "x-forwarded-host" ] ;
84
+ }
85
+
86
+ // For account endpoints specifically, try to extract the host from the requestToken
87
+ // This is a special case for the accounts endpoint where the origin header might be missing
88
+ if ( req . url ?. includes ( "/accounts/" ) && req . headers [ "x-request-token" ] ) {
89
+ try {
90
+ const decodedToken = Buffer . from ( req . headers [ "x-request-token" ] , "base64" ) . toString ( ) ;
91
+ const parts = decodedToken . split ( ":" ) ;
92
+ // If the token has the expected format with 3 parts, use the host from the token
93
+ if ( parts . length === 3 ) {
94
+ // User-agent:host:connect-demo
95
+ effectiveHost = parts [ 1 ] ;
96
+ }
97
+ } catch ( e ) {
98
+ console . log ( "Error extracting host from token:" , e . message ) ;
99
+ }
100
+ }
75
101
76
102
const baseString = `${ req . headers [ "user-agent" ] } :${ effectiveHost } :connect-demo` ;
77
103
return Buffer . from ( baseString ) . toString ( "base64" ) ;
@@ -90,6 +116,10 @@ export function setCorsHeaders(req, res, methods = "GET, POST, OPTIONS") {
90
116
) ;
91
117
res . setHeader ( "Access-Control-Allow-Methods" , methods ) ;
92
118
res . setHeader ( "Access-Control-Allow-Headers" , "Content-Type, X-Request-Token" ) ;
119
+
120
+ // Set COOP header to allow popups to communicate with the parent window
121
+ // This is important for OAuth flows in the Connect integration
122
+ res . setHeader ( "Cross-Origin-Opener-Policy" , "same-origin-allow-popups" ) ;
93
123
}
94
124
95
125
/**
0 commit comments