Web UI: feature updates across all modules
Broad UI improvements spanning auth, branding, notifications, agents, analytics, approvals, audit-log, bundles, configuration, console-admin, dashboard, deployments, doctor, environments, evidence, feed-mirror, graph, integration-hub, issuer-trust, lineage, notify, offline-kit, policy, promotions, quota, registry, release-orchestrator, releases, sbom, scans, secret-detection, security, settings, setup-wizard, system-health, topology, triage, trust-admin, unknowns, vex-hub, vulnerabilities, and watchlist features. Adds new shared components (page-action-outlet, stella-action-card, stella-form-field), scripts feature module, audit-trust component, e2e test helpers, and release page e2e specs. Updates auth session model, branding service, color tokens, form styles, and i18n translations. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,18 +3,18 @@ import { expect, test } from '@playwright/test';
|
||||
const mockConfig = {
|
||||
authority: {
|
||||
issuer: 'https://authority.local',
|
||||
clientId: 'stella-ops-ui',
|
||||
authorizeEndpoint: 'https://authority.local/connect/authorize',
|
||||
tokenEndpoint: 'https://authority.local/connect/token',
|
||||
logoutEndpoint: 'https://authority.local/connect/logout',
|
||||
redirectUri: 'http://127.0.0.1:4400/auth/callback',
|
||||
postLogoutRedirectUri: 'http://127.0.0.1:4400/',
|
||||
clientId: 'stella-ops-ui',
|
||||
authorizeEndpoint: 'https://authority.local/connect/authorize',
|
||||
tokenEndpoint: 'https://authority.local/connect/token',
|
||||
logoutEndpoint: 'https://authority.local/connect/logout',
|
||||
redirectUri: 'http://127.0.0.1:4400/auth/callback',
|
||||
postLogoutRedirectUri: 'http://127.0.0.1:4400/',
|
||||
scope:
|
||||
'openid profile email ui.read authority:tenants.read advisory:read vex:read exceptions:read exceptions:approve aoc:verify findings:read orch:read vuln:view vuln:investigate vuln:operate vuln:audit',
|
||||
audience: 'https://scanner.local',
|
||||
dpopAlgorithms: ['ES256'],
|
||||
refreshLeewaySeconds: 60,
|
||||
},
|
||||
audience: 'https://scanner.local',
|
||||
dpopAlgorithms: ['ES256'],
|
||||
refreshLeewaySeconds: 60,
|
||||
},
|
||||
apiBaseUrls: {
|
||||
authority: 'https://authority.local',
|
||||
scanner: 'https://scanner.local',
|
||||
@@ -73,7 +73,7 @@ test('sign-in flow builds Authority authorization URL', async ({ page }) => {
|
||||
expect(authorizeUrl.searchParams.get('client_id')).toBe('stella-ops-ui');
|
||||
|
||||
});
|
||||
|
||||
|
||||
test('callback without pending state surfaces error message', async ({ page }) => {
|
||||
await page.route('https://authority.local/**', (route) =>
|
||||
route.fulfill({ status: 400, body: 'blocked' })
|
||||
@@ -81,3 +81,48 @@ test('callback without pending state surfaces error message', async ({ page }) =
|
||||
await page.goto('/auth/callback?code=test-code&state=missing');
|
||||
await expect(page.getByText(/unable to complete the sign-in flow/i)).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
test('session-expired banner shows when persisted session has expired tokens', async ({ page }) => {
|
||||
// Seed an expired full session into sessionStorage before Angular boots.
|
||||
// Only set the full session key — omit the metadata key so trySilentRefresh
|
||||
// exits early (no subjectHint) and the 'expired' status stays visible.
|
||||
await page.addInitScript(() => {
|
||||
const expiredSession = {
|
||||
tokens: {
|
||||
accessToken: 'expired-token',
|
||||
expiresAtEpochMs: Date.now() - 60_000, // expired 1 min ago
|
||||
refreshToken: 'expired-refresh',
|
||||
scope: 'openid ui.read',
|
||||
tokenType: 'Bearer',
|
||||
},
|
||||
identity: {
|
||||
subject: 'user-expired',
|
||||
name: 'Expired User',
|
||||
roles: ['ui.read'],
|
||||
},
|
||||
dpopKeyThumbprint: 'thumb-expired',
|
||||
issuedAtEpochMs: Date.now() - 3600_000,
|
||||
tenantId: 'tenant-test',
|
||||
scopes: ['ui.read'],
|
||||
audiences: ['console'],
|
||||
authenticationTimeEpochMs: Date.now() - 3600_000,
|
||||
freshAuthActive: false,
|
||||
freshAuthExpiresAtEpochMs: null,
|
||||
};
|
||||
try {
|
||||
window.sessionStorage.setItem(
|
||||
'stellaops.auth.session.full',
|
||||
JSON.stringify(expiredSession)
|
||||
);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
(window as any).__stellaopsTestSession = undefined;
|
||||
});
|
||||
|
||||
await page.goto('/');
|
||||
const banner = page.getByRole('alert');
|
||||
await expect(banner).toBeVisible({ timeout: 10_000 });
|
||||
await expect(banner).toContainText('session has expired');
|
||||
await expect(page.getByRole('button', { name: /sign in again/i })).toBeVisible();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user