forked from baron/baron-sso
모바일 fallback 변경. .env유출 가능성 차단
This commit is contained in:
97
userfront-e2e/tests/runtime-env-mobile.spec.ts
Normal file
97
userfront-e2e/tests/runtime-env-mobile.spec.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { expect, test, type Page } from '@playwright/test';
|
||||
|
||||
type SigninCase = {
|
||||
path: '/ko/signin' | '/en/signin';
|
||||
theme: 'light' | 'dark';
|
||||
};
|
||||
|
||||
const signinCases: SigninCase[] = [
|
||||
{ path: '/ko/signin', theme: 'light' },
|
||||
{ path: '/ko/signin', theme: 'dark' },
|
||||
{ path: '/en/signin', theme: 'light' },
|
||||
{ path: '/en/signin', theme: 'dark' },
|
||||
];
|
||||
|
||||
async function mockPublicApis(page: Page): Promise<void> {
|
||||
await page.route('**/api/v1/**', async (route) => {
|
||||
const requestUrl = new URL(route.request().url());
|
||||
if (requestUrl.pathname.endsWith('/api/v1/user/me')) {
|
||||
await route.fulfill({
|
||||
status: 401,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({ error: 'unauthorized' }),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestUrl.pathname.endsWith('/api/v1/auth/tenant-info')) {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({}),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({ ok: true }),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function expectFlutterCanvasRendered(page: Page): Promise<void> {
|
||||
const canvas = page.locator('canvas').first();
|
||||
await expect(canvas).toBeVisible({ timeout: 30_000 });
|
||||
const box = await canvas.boundingBox();
|
||||
expect(box?.width ?? 0).toBeGreaterThan(100);
|
||||
expect(box?.height ?? 0).toBeGreaterThan(100);
|
||||
}
|
||||
|
||||
async function seedAuthTheme(page: Page, theme: SigninCase['theme']): Promise<void> {
|
||||
await page.addInitScript((themeValue) => {
|
||||
window.localStorage.setItem('userfront_auth_theme', themeValue);
|
||||
window.localStorage.setItem('flutter.userfront_auth_theme', themeValue);
|
||||
}, theme);
|
||||
}
|
||||
|
||||
test.describe('UserFront signin runtime matrix', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await mockPublicApis(page);
|
||||
});
|
||||
|
||||
for (const entry of signinCases) {
|
||||
test(`${entry.path} renders in ${entry.theme} theme`, async ({ page }) => {
|
||||
await seedAuthTheme(page, entry.theme);
|
||||
await page.goto(entry.path);
|
||||
await expect(page).toHaveURL(new RegExp(`${entry.path}(?:\\?.*)?$`));
|
||||
await expectFlutterCanvasRendered(page);
|
||||
});
|
||||
}
|
||||
|
||||
test('signin uses configured BACKEND_URL for public API requests', async ({
|
||||
page,
|
||||
}) => {
|
||||
const expectedBackendOrigin = process.env.EXPECTED_BACKEND_ORIGIN;
|
||||
test.skip(!expectedBackendOrigin, 'set EXPECTED_BACKEND_ORIGIN');
|
||||
|
||||
const requestedApiOrigins = new Set<string>();
|
||||
page.on('request', (request) => {
|
||||
const requestUrl = new URL(request.url());
|
||||
if (requestUrl.pathname.startsWith('/api/v1/')) {
|
||||
requestedApiOrigins.add(requestUrl.origin);
|
||||
}
|
||||
});
|
||||
|
||||
for (const entry of signinCases) {
|
||||
await seedAuthTheme(page, entry.theme);
|
||||
await page.goto(entry.path);
|
||||
await expectFlutterCanvasRendered(page);
|
||||
await expect
|
||||
.poll(() => [...requestedApiOrigins], { timeout: 30_000 })
|
||||
.toContain(expectedBackendOrigin);
|
||||
expect(requestedApiOrigins).not.toContain('https://sso.example.test');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
import { expect, test, type BrowserContext, type Page } from '@playwright/test';
|
||||
|
||||
const USERFRONT_BASE_URL = process.env.USERFRONT_BASE_URL ?? 'https://sso-test.hmac.kr';
|
||||
const USERFRONT_BASE_URL = process.env.USERFRONT_BASE_URL ?? 'https://sso.example.test';
|
||||
const ADMINFRONT_URL = process.env.ADMINFRONT_URL ?? 'http://localhost:5173';
|
||||
const LOGIN_ID = process.env.E2E_LOGIN_ID ?? '';
|
||||
const PASSWORD = process.env.E2E_PASSWORD ?? '';
|
||||
@@ -134,7 +134,7 @@ async function loginAdminFront(context: BrowserContext): Promise<Page> {
|
||||
if (/\/login$/.test(page.url())) {
|
||||
const authorizeUrl = await page.evaluate(() => {
|
||||
const origin = window.location.origin;
|
||||
const authority = 'https://sso-test.hmac.kr/oidc';
|
||||
const authority = `${USERFRONT_BASE_URL}/oidc`;
|
||||
const params = new URLSearchParams({
|
||||
client_id: 'adminfront',
|
||||
redirect_uri: `${origin}/auth/callback`,
|
||||
|
||||
Reference in New Issue
Block a user