a11y: label the language trigger + settings icon; record security/menu audit
- aria-label on the language dropdown trigger (flag-only) and the header settings icon (title-only) so screen readers announce them. - AGENTS: final security scan (audit 35->13, zod 4/nostrify 0.50, APK manifest and CSP verified) + menu/a11y conclusions.
This commit is contained in:
parent
37fa5c1f58
commit
93abe599f9
3 changed files with 23 additions and 1 deletions
20
AGENTS.md
20
AGENTS.md
|
|
@ -2342,6 +2342,26 @@ Rules:
|
||||||
On **failure** the job restores the lockfile and schedules a retry in **~3 days**
|
On **failure** the job restores the lockfile and schedules a retry in **~3 days**
|
||||||
(a failed run no longer burns the whole 20-day window); every notification now
|
(a failed run no longer burns the whole 20-day window); every notification now
|
||||||
includes the **OSV total** ("N packages affected by M known vulnerabilities").
|
includes the **OSV total** ("N packages affected by M known vulnerabilities").
|
||||||
|
**Final security scan (2026-10-26):** researched the app-relevant advisories and
|
||||||
|
fixed them — **zod 3.25 → 4.6.7** (only `AppProvider` imports zod; no
|
||||||
|
zod-3-isms, zero TS changes) plus **@nostrify/nostrify 0.50.5 /
|
||||||
|
@nostrify/react 0.2.31 / @nostrify/types 0.36.9** (0.50 moved to zod 4), and the
|
||||||
|
safe `npm audit fix` transitives (react-router 6.30.6, dompurify 3.4.17,
|
||||||
|
lodash 4.18.1, @modelcontextprotocol/sdk 1.32.2). **npm audit: 35 → 13** (2
|
||||||
|
critical, 1 high). Remaining: **vitest/tinypool** (dev-only, fix = vitest 5
|
||||||
|
major), **xlsx** (no fix; we only *write* XLSX — parse CVEs don't apply),
|
||||||
|
**react-router** open-redirect (moderate; fix = v7 major — revisit), and
|
||||||
|
build-only tailwind/postcss/capacitor-cli. APK manifest is minimal
|
||||||
|
(INTERNET + coarse/fine location); `network_security_config` permits cleartext
|
||||||
|
**loopback only** (Citrine); CSP is strong (`default-src 'none'`, no
|
||||||
|
`unsafe-eval`, `object-src 'none'`, `frame-ancestors 'none'`); no tracked
|
||||||
|
secrets; the only `dangerouslySetInnerHTML` is shadcn's chart CSS-vars (static,
|
||||||
|
not user input). **Menu/a11y pass (same date):** added `aria-label`s to the
|
||||||
|
language trigger and the header settings icon (they had only `title`/a flag);
|
||||||
|
the desktop nav's `max-w-[1700px]` + `overflow-x-auto scrollbar-hide` +
|
||||||
|
`whitespace-nowrap` keeps the trailing **More** reachable, the mobile bottom
|
||||||
|
nav + burger append the full catalog, dropdowns have max-height + internal
|
||||||
|
scroll, and interactive targets meet the 44px rule. No other menu bugs found.
|
||||||
|
|
||||||
### Community relay — self-hosted Newlay (2026-10-12)
|
### Community relay — self-hosted Newlay (2026-10-12)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,8 @@ export function LanguageToggle({ compact = false, inline = false, className, var
|
||||||
<Button
|
<Button
|
||||||
variant={variant}
|
variant={variant}
|
||||||
size={compact ? 'icon' : 'default'}
|
size={compact ? 'icon' : 'default'}
|
||||||
|
aria-label={t('settings.selectLanguage')}
|
||||||
|
title={t('settings.selectLanguage')}
|
||||||
className={cn(
|
className={cn(
|
||||||
'gap-2',
|
'gap-2',
|
||||||
compact ? 'w-10 h-10' : 'px-3',
|
compact ? 'w-10 h-10' : 'px-3',
|
||||||
|
|
|
||||||
|
|
@ -773,7 +773,7 @@ export function Layout({ children, noPadding }: LayoutProps) {
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
<Link to="/settings">
|
<Link to="/settings">
|
||||||
<Button variant="ghost" size="icon" title={t('nav.settings')}>
|
<Button variant="ghost" size="icon" title={t('nav.settings')} aria-label={t('nav.settings')}>
|
||||||
<Settings className="h-5 w-5" />
|
<Settings className="h-5 w-5" />
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue