feat(core): sync framework security hardening and accessibility improvements

- add util.Go with panic recovery for background goroutines
- add util.EscapeLike and explicit ESCAPE clause for SQL LIKE queries
- add DummyCheckPassword and subtle.ConstantTimeCompare against timing attacks
- enforce session ID rotation upon login/oauth callback to prevent session fixation
- add sliding window login failure rate limiting and oauth state rate limiting
- fix redis client capture race in pubsub listeners and wait on stop channel
- adjust global --primary to oklch(51.1% 0.262 276.966) for WCAG AA contrast
- fix semantic heading levels and missing aria-labels across UI components
- document security, concurrency, and a11y standards in AGENTS.md
This commit is contained in:
ryan
2026-08-27 23:01:28 +08:00
parent b66cf3ae9c
commit ae3b792e16
63 changed files with 570 additions and 176 deletions
@@ -104,9 +104,9 @@ export function UserDetailSheet({
<div className='p-6 space-y-6'>
<div className='space-y-4'>
<h4 className='text-xs font-semibold text-muted-foreground uppercase tracking-wider px-1'>
<p className='text-xs font-semibold text-muted-foreground uppercase tracking-wider px-1'>
{t('personalInfo')}
</h4>
</p>
<div className='rounded-lg border divide-y bg-background/50'>
<div className='flex items-center justify-between gap-4 p-3.5 text-sm'>
<span className='flex items-center gap-2 text-[10px] text-muted-foreground'>
@@ -167,9 +167,9 @@ export function UserDetailSheet({
</div>
<div className='space-y-4'>
<h4 className='text-xs font-semibold text-muted-foreground uppercase tracking-wider px-1'>
<p className='text-xs font-semibold text-muted-foreground uppercase tracking-wider px-1'>
{t('systemRecords')}
</h4>
</p>
<div className='rounded-lg border divide-y bg-background/50'>
<div className='flex items-center justify-between p-3.5 text-sm'>
<span className='text-[10px]'>
@@ -26,6 +26,7 @@ import { cn } from '@/lib/utils';
export function UserFilterBar() {
const t = useTranslations('admin.users');
const tCommon = useTranslations('common');
const {
total,
loading,
@@ -223,6 +224,7 @@ export function UserFilterBar() {
<Button
variant='ghost'
size='icon'
aria-label={tCommon('previousPage')}
className='h-5.5 w-6 rounded-none rounded-l-md disabled:opacity-30'
onClick={() => setPage(Math.max(1, page - 1))}
disabled={page <= 1 || loading}
@@ -235,6 +237,7 @@ export function UserFilterBar() {
<Button
variant='ghost'
size='icon'
aria-label={tCommon('nextPage')}
className='h-5.5 w-6 rounded-none rounded-r-md disabled:opacity-30'
onClick={() => setPage(Math.min(totalPages, page + 1))}
disabled={page >= totalPages || loading}