Skip to content

Commit b46deb6

Browse files
committed
silent-auth-everytime-test
1 parent 21e8068 commit b46deb6

1 file changed

Lines changed: 68 additions & 121 deletions

File tree

src/components/TestIframe.js

Lines changed: 68 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,6 @@ function generateCodeVerifier() {
8989
return result;
9090
}
9191

92-
function generateCodeChallenge(verifier) {
93-
return crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier))
94-
.then(arrayBuffer => {
95-
const base64Url = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)))
96-
.replace(/=/g, '')
97-
.replace(/\+/g, '-')
98-
.replace(/\//g, '_');
99-
return base64Url;
100-
});
101-
}
10292

10393
function TestIframe() {
10494
const sdk = useDescope();
@@ -107,131 +97,88 @@ function TestIframe() {
10797
const silentAuthCheckedRef = useRef(false);
10898
const [silentAuthStatus, setSilentAuthStatus] = useState(null);
10999

110-
// Silent authentication check using iframe for OIDC federation
111100
useEffect(() => {
112-
const checkSilentAuth = async () => {
113-
try {
114-
console.log('Starting silent authentication check with iframe...');
115-
116-
const codeVerifier = generateCodeVerifier();
117-
const codeChallenge = await generateCodeChallenge(codeVerifier);
118-
const state = generateCodeVerifier();
119-
sessionStorage.setItem('silent-auth-verifier', codeVerifier);
120-
sessionStorage.setItem('silent-auth-state', state);
121-
122-
// Set up message listener for iframe response BEFORE creating iframe
123-
const messageHandler = async (event) => {
124-
console.log('Message received:', event.data, 'from origin:', event.origin);
101+
if (isSessionLoading) return;
125102

126-
if (event.origin !== window.location.origin) {
127-
console.log('Ignoring message from different origin');
128-
return;
129-
}
103+
if (isAuthenticated) {
104+
silentAuthCheckedRef.current = true;
105+
setSilentAuthChecked(true);
106+
setSilentAuthStatus('User already authenticated');
107+
return;
108+
}
130109

131-
if (event.data.type === 'silent-auth-result') {
132-
console.log('Silent auth result received:', event.data);
110+
if (silentAuthCheckedRef.current) return;
133111

134-
const expectedState = sessionStorage.getItem('silent-auth-state');
135-
sessionStorage.removeItem('silent-auth-state');
136-
if (event.data.state !== expectedState) {
137-
console.log('State mismatch — ignoring response');
138-
return;
139-
}
112+
const checkSilentAuth = async () => {
113+
const state = generateCodeVerifier();
114+
sessionStorage.setItem('silent-auth-state', state);
115+
116+
const done = (status) => {
117+
const iframe = document.getElementById('silent-auth-iframe');
118+
if (iframe && iframe.parentNode) document.body.removeChild(iframe);
119+
window.removeEventListener('message', messageHandler);
120+
silentAuthCheckedRef.current = true;
121+
setSilentAuthStatus(status);
122+
setSilentAuthChecked(true);
123+
};
140124

141-
// Clean up
142-
const iframe = document.getElementById('silent-auth-iframe');
143-
if (iframe && iframe.parentNode) {
144-
document.body.removeChild(iframe);
145-
}
146-
window.removeEventListener('message', messageHandler);
147-
silentAuthCheckedRef.current = true;
125+
const messageHandler = async (event) => {
126+
if (event.origin !== window.location.origin) return;
127+
if (event.data.type !== 'silent-auth-result') return;
128+
129+
const expectedState = sessionStorage.getItem('silent-auth-state');
130+
sessionStorage.removeItem('silent-auth-state');
131+
if (event.data.state !== expectedState) {
132+
console.log('Silent auth: state mismatch, ignoring');
133+
return;
134+
}
135+
136+
if (event.data.code) {
137+
try {
138+
await sdk.oauth.exchange(event.data.code);
139+
done('Authenticated via custom domain');
140+
} catch (err) {
141+
console.log('Silent auth: exchange failed', err);
142+
done('No existing session');
143+
}
144+
} else {
145+
done('No existing session');
146+
}
147+
};
148148

149-
if (event.data.code) {
150-
// Exchange code for token using Descope SDK
151-
try {
152-
console.log('Exchanging code for token...');
153-
const storedVerifier = sessionStorage.getItem('silent-auth-verifier');
154-
sessionStorage.removeItem('silent-auth-verifier');
155-
await sdk.oauth.exchange(event.data.code, storedVerifier);
156-
setSilentAuthStatus('User authenticated via custom domain');
157-
console.log('Silent auth successful - user is logged in');
158-
} catch (error) {
159-
console.log('Failed to exchange code:', error);
160-
setSilentAuthStatus('No existing session found');
161-
}
162-
} else if (event.data.error) {
163-
console.log('Silent auth returned error:', event.data.error);
164-
setSilentAuthStatus('No existing session found');
165-
}
149+
window.addEventListener('message', messageHandler);
166150

167-
silentAuthCheckedRef.current = true;
168-
setSilentAuthChecked(true);
169-
}
170-
};
151+
const iframe = document.createElement('iframe');
152+
iframe.style.display = 'none';
153+
iframe.id = 'silent-auth-iframe';
171154

172-
window.addEventListener('message', messageHandler);
173-
console.log('Message listener added');
155+
const projectId = 'Puse136yK1TiyR4tmmaVToRDQs9icEIl';
156+
const customDomain = 'https://auth.reuven.descope.org';
157+
const redirectUri = `${window.location.origin}/silent-callback`;
174158

175-
// Create hidden iframe for silent auth
176-
const iframe = document.createElement('iframe');
177-
iframe.style.display = 'none';
178-
iframe.id = 'silent-auth-iframe';
159+
iframe.src = `${customDomain}/oauth2/v1/authorize?` +
160+
`response_type=code` +
161+
`&client_id=${projectId}` +
162+
`&redirect_uri=${encodeURIComponent(redirectUri)}` +
163+
`&oidc_error_redirect_uri=${encodeURIComponent(redirectUri)}` +
164+
`&state=${state}` +
165+
`&prompt=none` +
166+
`&scope=openid profile email`;
179167

180-
const projectId = 'Puse136yK1TiyR4tmmaVToRDQs9icEIl';
181-
const customDomain = 'https://auth.reuven.descope.org';
182-
const redirectUri = `${window.location.origin}/silent-callback`;
168+
document.body.appendChild(iframe);
183169

184-
// Construct OIDC authorization URL with PKCE and prompt=none for silent auth
185-
const authUrl = `${customDomain}/oauth2/v1/authorize?` +
186-
`response_type=code` +
187-
`&client_id=${projectId}` +
188-
`&redirect_uri=${encodeURIComponent(redirectUri)}` +
189-
`&oidc_error_redirect_uri=${encodeURIComponent(redirectUri)}` +
190-
`&state=${state}` +
191-
`&code_challenge=${codeChallenge}` +
192-
`&code_challenge_method=S256` +
193-
`&prompt=none` +
194-
`&scope=openid profile email`;
195-
196-
console.log('Silent auth URL:', authUrl);
197-
198-
// Set timeout in case iframe doesn't respond
199-
setTimeout(() => {
200-
if (!silentAuthCheckedRef.current) {
201-
console.log('Silent auth timed out');
202-
window.removeEventListener('message', messageHandler);
203-
const iframe = document.getElementById('silent-auth-iframe');
204-
if (iframe && iframe.parentNode) {
205-
document.body.removeChild(iframe);
206-
}
207-
silentAuthCheckedRef.current = true;
208-
setSilentAuthStatus('Silent auth timeout');
209-
setSilentAuthChecked(true);
210-
}
211-
}, 10000);
212-
213-
// Add iframe to page and start silent auth
214-
document.body.appendChild(iframe);
215-
console.log('Iframe added to page, loading URL...');
216-
iframe.src = authUrl;
217-
218-
} catch (error) {
219-
console.error('Silent auth error:', error);
220-
setSilentAuthStatus('Silent auth failed');
221-
setSilentAuthChecked(true);
222-
}
170+
setTimeout(() => {
171+
if (!silentAuthCheckedRef.current) done('Silent auth timeout');
172+
}, 10000);
223173
};
224174

225-
// Only run silent auth check once on mount and if not already authenticated
226-
if (!isSessionLoading && !silentAuthChecked && !isAuthenticated) {
227-
checkSilentAuth();
228-
} else if (!isSessionLoading && (isAuthenticated || silentAuthChecked)) {
175+
checkSilentAuth().catch((err) => {
176+
console.error('Silent auth error:', err);
177+
silentAuthCheckedRef.current = true;
178+
setSilentAuthStatus('Silent auth failed');
229179
setSilentAuthChecked(true);
230-
if (isAuthenticated) {
231-
setSilentAuthStatus('User already authenticated');
232-
}
233-
}
234-
}, [sdk, isSessionLoading, silentAuthChecked, isAuthenticated]);
180+
});
181+
}, [sdk, isSessionLoading, isAuthenticated]);
235182

236183
const runSSO = async () => {
237184
const d = await sdk.saml.start('descope.com', 'http://localhost:3000');

0 commit comments

Comments
 (0)