Files
cinny/src/app/features/settings/account/OidcManageAccount.tsx
T
jaredandClaude Opus 4.8 3e1106b2d9 fix(security): tab-nabbing hardening + /acl self-lockout guard (SEC-3/4)
SEC-3: add `noopener,noreferrer` to the 5 `window.open(_blank)` sites that
don't use the returned handle (UserChips, OidcManageAccount, OtherDevices x2,
Verification), closing reverse tab-nabbing. SSOStage is intentionally excluded —
it needs the window handle + intact opener for its origin-checked SSO
postMessage handshake.

SEC-4: guard the `/acl` slash command against bricking the room.
- Extract the ACL glob helpers (isValidServerPattern/globToRegExp/matchesAnyGlob)
  from RoomServerACL into a shared utils/serverAcl.ts (+ unit test) so the
  command and the settings editor validate identically.
- Default a MISSING allow list to `*` only when the room has NO existing ACL
  (a first `/acl -d x` otherwise sent `allow: []`, which bricks the room); an
  existing ACL's absent/empty allow is preserved, not silently widened.
- Reject invalid globs; fail CLOSED on the universally-catastrophic cases
  (empty allow, or a `*` deny) even when the local domain is unknown; and reject
  any change that would ban this homeserver (self-lockout).

Guard hardened per two review passes (fail-closed on unknown domain; no silent
federation widening).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 21:23:35 -04:00

54 lines
1.9 KiB
TypeScript

import React, { useCallback } from 'react';
import { Box, Chip, Text } from 'folds';
import { SequenceCard } from '../../../components/sequence-card';
import { SequenceCardStyle } from '../styles.css';
import { SettingTile } from '../../../components/setting-tile';
import { useAuthMetadata } from '../../../hooks/useAuthMetadata';
import { useAccountManagementActions } from '../../../hooks/useAccountManagement';
import { withSearchParam } from '../../../pages/pathUtils';
/**
* On OIDC/next-gen-auth servers, profile/password/sessions are managed by the
* authentication service — surface a deep-link to its account page (MSC2965
* account-management URL). Renders nothing on password/legacy-SSO servers, where
* `useAuthMetadata()` is undefined.
*/
export function OidcManageAccount() {
const authMetadata = useAuthMetadata();
const accountManagementActions = useAccountManagementActions();
const open = useCallback(() => {
const authUrl = authMetadata?.account_management_uri ?? authMetadata?.issuer;
if (!authUrl) return;
window.open(
withSearchParam(authUrl, { action: accountManagementActions.profile }),
'_blank',
'noopener,noreferrer',
);
}, [authMetadata, accountManagementActions]);
if (!authMetadata) return null;
return (
<Box direction="Column" gap="100">
<Text size="L400">Account Management</Text>
<SequenceCard
className={SequenceCardStyle}
variant="SurfaceVariant"
direction="Column"
gap="400"
>
<SettingTile
title="Manage account"
description="Your profile, password, and sessions are managed by your single sign-on provider."
after={
<Chip variant="Secondary" radii="Pill" onClick={open}>
<Text size="T200">Open</Text>
</Chip>
}
/>
</SequenceCard>
</Box>
);
}