76 lines
2.7 KiB
TypeScript
76 lines
2.7 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
test('OAuth Flow for tenant-admin-app', async ({ page }) => {
|
|
const code_challenge = 'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk';
|
|
const code_verifier = 'E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM';
|
|
const redirect_uri = 'http://localhost:8000/auth/callback';
|
|
const state = 'teststate';
|
|
const scope = 'tenant:read tenant:write tenant:admin';
|
|
|
|
const authorizeUrl = `/api/v1/oauth/authorize?response_type=code&client_id=tenant-admin-app&redirect_uri=${encodeURIComponent(redirect_uri)}&scope=${encodeURIComponent(scope)}&code_challenge=${code_challenge}&code_challenge_method=S256&state=${state}`;
|
|
|
|
// Navigate to authorize - should immediately redirect to callback
|
|
await page.goto(authorizeUrl);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Log response if no redirect
|
|
const currentUrl = page.url();
|
|
if (currentUrl.includes('/authorize')) {
|
|
const response = await page.content();
|
|
console.log('No redirect, response:', response.substring(0, 500)); // First 500 chars
|
|
}
|
|
|
|
// Wait for redirect to callback and parse params
|
|
await expect(page).toHaveURL(new RegExp(`${redirect_uri}\\?.*`));
|
|
const urlObj = new URL(currentUrl);
|
|
const code = urlObj.searchParams.get('code') || '';
|
|
const receivedState = urlObj.searchParams.get('state') || '';
|
|
|
|
expect(receivedState).toBe(state);
|
|
expect(code).not.toBeNull();
|
|
|
|
console.log('Authorization code:', code);
|
|
|
|
// Token exchange via fetch
|
|
const tokenParams = {
|
|
code: code!,
|
|
redirect_uri,
|
|
code_verifier
|
|
};
|
|
const tokenResponse = await page.evaluate(async (params) => {
|
|
const response = await fetch('/api/v1/oauth/token', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
},
|
|
body: new URLSearchParams({
|
|
grant_type: 'authorization_code',
|
|
client_id: 'tenant-admin-app',
|
|
code: params.code,
|
|
redirect_uri: params.redirect_uri,
|
|
code_verifier: params.code_verifier,
|
|
}).toString(),
|
|
});
|
|
return await response.json();
|
|
}, tokenParams);
|
|
|
|
console.log('Token response:', tokenResponse);
|
|
expect(tokenResponse.access_token).toBeTruthy();
|
|
|
|
const accessToken = tokenResponse.access_token;
|
|
|
|
// Call /tenant/me with token
|
|
const meResponse = await page.evaluate(async (token) => {
|
|
const response = await fetch('/api/v1/tenant/me', {
|
|
headers: {
|
|
'Authorization': `Bearer ${token}`,
|
|
'Accept': 'application/json',
|
|
},
|
|
});
|
|
return await response.json();
|
|
}, accessToken);
|
|
|
|
console.log('/tenant/me response:', meResponse);
|
|
expect(meResponse).toHaveProperty('id');
|
|
expect(meResponse.email).toBe('demo@example.com');
|
|
}); |