fix: standardize punctuation

This commit is contained in:
Linus Rath
2026-04-16 19:07:42 +02:00
parent 6b57118add
commit 8bdadc7ba3
107 changed files with 452 additions and 448 deletions
+2 -2
View File
@@ -35,7 +35,7 @@ function OAuthCallbackInner() {
const savedState = sessionStorage.getItem("oauth_state");
if (savedState) {
// Classic flow sessionStorage has the PKCE state (same-tab OAuth)
// Classic flow - sessionStorage has the PKCE state (same-tab OAuth)
if (!state || state !== savedState) {
setError("invalid_state");
return;
@@ -76,7 +76,7 @@ function OAuthCallbackInner() {
setError("token_exchange_failed");
});
} else if (state) {
// Server-side SSO flow state was stored in encrypted httpOnly cookie
// Server-side SSO flow - state was stored in encrypted httpOnly cookie
const ssoPrefix = getPathPrefix(params.locale as string);
loginWithServerSso(code, state)
.then((success) => {
+2 -2
View File
@@ -255,7 +255,7 @@ export default function LoginPage() {
try {
window.top!.location.href = authorize_url;
} catch {
// Cross-origin restriction fall back to current frame
// Cross-origin restriction - fall back to current frame
window.location.href = authorize_url;
}
} else {
@@ -759,7 +759,7 @@ export default function LoginPage() {
)}
</Button>
<p className="text-center text-xs text-muted-foreground">
Dev mode logging in as dev@localhost
Dev mode - logging in as dev@localhost
</p>
</div>
) : oauthOnly ? (
+3 -3
View File
@@ -256,7 +256,7 @@ export default function Home() {
// Restore conversation thread (mobile only). We can clear it directly,
// but reopening requires the thread group; if the user pressed forward
// to return to a thread, we silently skip back navigation always works.
// to return to a thread, we silently skip - back navigation always works.
if ((state.threadId ?? null) !== ctx.conversationThreadId) {
if (state.threadId === null) {
setConversationThread(null);
@@ -826,7 +826,7 @@ export default function Home() {
if (archiveMode === 'year') {
await moveThreadToMailbox(client, emailToArchive.id, yearMailbox.id);
} else {
// archiveMode === 'month' find or create month subfolder under year
// archiveMode === 'month' - find or create month subfolder under year
const yearId = yearMailbox.originalId || yearMailbox.id;
let monthMailbox = mailboxes.find(
m => m.name === month && m.parentId === yearId
@@ -1255,7 +1255,7 @@ export default function Home() {
// Handle back navigation from viewer on mobile.
// Delegate to the browser history stack so this button is equivalent to
// the OS back button / mouse back button popstate then restores the
// the OS back button / mouse back button - popstate then restores the
// previous snapshot via handleNavRestore. The viewer is only reachable
// from a state that pushed history, so back() always lands on an app entry.
const handleMobileBack = () => {
+1 -1
View File
@@ -139,7 +139,7 @@ export default function AdminLogsPage() {
}
function formatDetail(detail: Record<string, unknown>): string {
if (!detail || Object.keys(detail).length === 0) return '';
if (!detail || Object.keys(detail).length === 0) return '-';
if (detail.reason) return String(detail.reason);
if (detail.key) return `${detail.key}: ${JSON.stringify(detail.old)}${JSON.stringify(detail.new)}`;
if (detail.changes && Array.isArray(detail.changes)) {
+1 -1
View File
@@ -117,7 +117,7 @@ export default function AdminMarketplacePage() {
setMessage({ type: 'error', text: data.error || 'Installation failed' });
}
} catch {
setMessage({ type: 'error', text: 'Installation failed network error' });
setMessage({ type: 'error', text: 'Installation failed - network error' });
} finally {
setInstalling(null);
}
+4 -4
View File
@@ -99,8 +99,8 @@ export default function AdminDashboardPage() {
setWarnings(w);
}
const jmapUrl = config?.jmapServerUrl || '';
const jmapHostname = jmapUrl !== '' ? (() => { try { return new URL(jmapUrl).hostname; } catch { return jmapUrl; } })() : '';
const jmapUrl = config?.jmapServerUrl || '-';
const jmapHostname = jmapUrl !== '-' ? (() => { try { return new URL(jmapUrl).hostname; } catch { return jmapUrl; } })() : '-';
return (
<div className="max-w-3xl space-y-8">
@@ -127,9 +127,9 @@ export default function AdminDashboardPage() {
{/* Server Info */}
<SettingsSection title="Server" description="Application and connection details">
<SettingItem label="Application">
<span className="text-sm text-foreground">{config?.appName || ''}</span>
<span className="text-sm text-foreground">{config?.appName || '-'}</span>
</SettingItem>
<SettingItem label="JMAP Server" description={jmapUrl !== '' ? jmapUrl : undefined}>
<SettingItem label="JMAP Server" description={jmapUrl !== '-' ? jmapUrl : undefined}>
<span className="text-sm text-foreground">{jmapHostname}</span>
</SettingItem>
<SettingItem label="JMAP Connection">
+1 -1
View File
@@ -231,7 +231,7 @@ export default function PluginConfigPage() {
onChange={(e) => setFormValues(prev => ({ ...prev, [key]: e.target.value }))}
className="w-full h-9 px-3 rounded-md border border-input bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring"
>
<option value=""> Select </option>
<option value="">- Select -</option>
{field.options.map(opt => (
<option key={opt.value} value={opt.value}>{opt.label}</option>
))}
+1 -1
View File
@@ -4,7 +4,7 @@ import { readAuditLog } from '@/lib/admin/audit';
import { logger } from '@/lib/logger';
/**
* GET /api/admin/audit Get paginated audit log entries (admin-protected)
* GET /api/admin/audit - Get paginated audit log entries (admin-protected)
*/
export async function GET(request: NextRequest) {
try {
+3 -3
View File
@@ -30,7 +30,7 @@ async function checkStalwartAdmin(request: NextRequest): Promise<boolean> {
}
/**
* POST /api/admin/auth Login
* POST /api/admin/auth - Login
*/
export async function POST(request: NextRequest) {
try {
@@ -92,7 +92,7 @@ export async function POST(request: NextRequest) {
}
/**
* GET /api/admin/auth Check session status
* GET /api/admin/auth - Check session status
* Also checks if the user is a Stalwart admin (admin panel enabled even without password).
*/
export async function GET(request: NextRequest) {
@@ -136,7 +136,7 @@ export async function GET(request: NextRequest) {
}
/**
* DELETE /api/admin/auth Logout
* DELETE /api/admin/auth - Logout
*/
export async function DELETE(request: NextRequest) {
try {
+1 -1
View File
@@ -14,7 +14,7 @@ const MIME_TYPES: Record<string, string> = {
};
/**
* GET /api/admin/branding/[filename] Serve uploaded branding images
* GET /api/admin/branding/[filename] - Serve uploaded branding images
*
* This endpoint is public (no admin auth) so browsers can load images.
* Only files in the branding directory are served; directory traversal is prevented.
+2 -2
View File
@@ -33,7 +33,7 @@ function sanitizeFilename(name: string): string {
}
/**
* POST /api/admin/branding Upload a branding image file
* POST /api/admin/branding - Upload a branding image file
*
* Expects multipart/form-data with:
* - file: the image file
@@ -105,7 +105,7 @@ export async function POST(request: NextRequest) {
}
/**
* DELETE /api/admin/branding Remove an uploaded branding file
* DELETE /api/admin/branding - Remove an uploaded branding file
*
* Expects JSON body: { slot: string }
*/
+1 -1
View File
@@ -5,7 +5,7 @@ import { auditLog } from '@/lib/admin/audit';
import { logger } from '@/lib/logger';
/**
* POST /api/admin/change-password Change admin password
* POST /api/admin/change-password - Change admin password
*/
export async function POST(request: NextRequest) {
try {
+3 -3
View File
@@ -6,7 +6,7 @@ import { CONFIG_ENV_MAP } from '@/lib/admin/types';
import { logger } from '@/lib/logger';
/**
* GET /api/admin/config Get full config with sources (admin-protected)
* GET /api/admin/config - Get full config with sources (admin-protected)
*/
export async function GET() {
try {
@@ -26,7 +26,7 @@ export async function GET() {
}
/**
* PATCH /api/admin/config Update config overrides (admin-protected)
* PATCH /api/admin/config - Update config overrides (admin-protected)
*/
export async function PATCH(request: NextRequest) {
try {
@@ -64,7 +64,7 @@ export async function PATCH(request: NextRequest) {
}
/**
* DELETE /api/admin/config Remove admin override for a key (revert to env/default)
* DELETE /api/admin/config - Remove admin override for a key (revert to env/default)
*/
export async function DELETE(request: NextRequest) {
try {
+2 -2
View File
@@ -17,7 +17,7 @@ import { sanitizeThemeCSS, validateThemeCSSSafety } from '@/lib/theme-loader';
const DIRECTORY_URL = process.env.EXTENSION_DIRECTORY_URL || 'http://localhost:3001';
/**
* GET /api/admin/marketplace Search/browse the extension directory
* GET /api/admin/marketplace - Search/browse the extension directory
* Proxies to the extension directory API
*/
export async function GET(request: NextRequest) {
@@ -75,7 +75,7 @@ export async function GET(request: NextRequest) {
}
/**
* POST /api/admin/marketplace Install an extension from the directory
* POST /api/admin/marketplace - Install an extension from the directory
* Body: { slug: string, version: string, type: 'plugin' | 'theme' }
*/
export async function POST(request: NextRequest) {
+1 -1
View File
@@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from 'next/server';
import { getPluginBundle, getPlugin } from '@/lib/admin/plugin-registry';
/**
* GET /api/admin/plugins/[id]/bundle Serve plugin JS bundle
* GET /api/admin/plugins/[id]/bundle - Serve plugin JS bundle
*
* Public endpoint so the client-side plugin loader can fetch bundles.
* Only serves plugins that exist in the registry and are enabled.
+3 -3
View File
@@ -4,7 +4,7 @@ import { getPluginConfig, setPluginConfig, deletePluginConfigKey } from '@/lib/a
import { requireAdminAuth } from '@/lib/admin/session';
/**
* GET /api/admin/plugins/[id]/config Read all config for a plugin
* GET /api/admin/plugins/[id]/config - Read all config for a plugin
*
* Returns the full config object for admin-configured plugin settings.
* This endpoint is accessible from the client-side plugin API.
@@ -35,7 +35,7 @@ export async function GET(
}
/**
* PUT /api/admin/plugins/[id]/config Set a config key
* PUT /api/admin/plugins/[id]/config - Set a config key
*
* Body: { key: string, value: unknown }
* Requires admin authentication (checked via admin session).
@@ -83,7 +83,7 @@ export async function PUT(
}
/**
* DELETE /api/admin/plugins/[id]/config Delete a config key
* DELETE /api/admin/plugins/[id]/config - Delete a config key
*
* Body: { key: string }
*/
+4 -4
View File
@@ -23,7 +23,7 @@ const SUSPICIOUS_JS_PATTERNS = [
];
/**
* GET /api/admin/plugins List all admin-managed plugins
* GET /api/admin/plugins - List all admin-managed plugins
*/
export async function GET() {
try {
@@ -41,7 +41,7 @@ export async function GET() {
}
/**
* POST /api/admin/plugins Upload and install a plugin ZIP
* POST /api/admin/plugins - Upload and install a plugin ZIP
*/
export async function POST(request: NextRequest) {
try {
@@ -181,7 +181,7 @@ export async function POST(request: NextRequest) {
}
/**
* PATCH /api/admin/plugins Update plugin metadata (enable/disable)
* PATCH /api/admin/plugins - Update plugin metadata (enable/disable)
* Body: { id: string, enabled: boolean }
*/
export async function PATCH(request: NextRequest) {
@@ -218,7 +218,7 @@ export async function PATCH(request: NextRequest) {
}
/**
* DELETE /api/admin/plugins Remove a plugin
* DELETE /api/admin/plugins - Remove a plugin
* Body: { id: string }
*/
export async function DELETE(request: NextRequest) {
+2 -2
View File
@@ -6,7 +6,7 @@ import { logger } from '@/lib/logger';
import type { SettingsPolicy } from '@/lib/admin/types';
/**
* GET /api/admin/policy Get settings policy (NOT admin-protected users read this)
* GET /api/admin/policy - Get settings policy (NOT admin-protected - users read this)
*/
export async function GET() {
try {
@@ -22,7 +22,7 @@ export async function GET() {
}
/**
* PUT /api/admin/policy Update settings policy (admin-protected)
* PUT /api/admin/policy - Update settings policy (admin-protected)
*/
export async function PUT(request: NextRequest) {
try {
+1 -1
View File
@@ -5,7 +5,7 @@ import { getStalwartCredentials } from '@/lib/stalwart/credentials';
/**
* GET /api/admin/stalwart-check
* Check if the currently logged-in user is a Stalwart admin.
* Probes the admin-only principal-list endpoint if the user can access it, they're an admin.
* Probes the admin-only principal-list endpoint - if the user can access it, they're an admin.
*/
export async function GET(request: NextRequest) {
try {
+1 -1
View File
@@ -3,7 +3,7 @@ import { getThemeCSS, getThemeRegistry } from '@/lib/admin/plugin-registry';
import { logger } from '@/lib/logger';
/**
* GET /api/admin/themes/[id]/css Serve theme CSS to clients
* GET /api/admin/themes/[id]/css - Serve theme CSS to clients
*/
export async function GET(
_request: NextRequest,
+4 -4
View File
@@ -14,7 +14,7 @@ import { MAX_THEME_SIZE } from '@/lib/plugin-types';
import { sanitizeThemeCSS, validateThemeCSSSafety } from '@/lib/theme-loader';
/**
* GET /api/admin/themes List all admin-managed themes
* GET /api/admin/themes - List all admin-managed themes
*/
export async function GET() {
try {
@@ -32,7 +32,7 @@ export async function GET() {
}
/**
* POST /api/admin/themes Upload and install a theme ZIP
* POST /api/admin/themes - Upload and install a theme ZIP
*/
export async function POST(request: NextRequest) {
try {
@@ -151,7 +151,7 @@ export async function POST(request: NextRequest) {
}
/**
* PATCH /api/admin/themes Update theme metadata (enable/disable)
* PATCH /api/admin/themes - Update theme metadata (enable/disable)
* Body: { id: string, enabled: boolean }
*/
export async function PATCH(request: NextRequest) {
@@ -188,7 +188,7 @@ export async function PATCH(request: NextRequest) {
}
/**
* DELETE /api/admin/themes Remove a theme
* DELETE /api/admin/themes - Remove a theme
* Body: { id: string }
*/
export async function DELETE(request: NextRequest) {
+1 -1
View File
@@ -95,7 +95,7 @@ export async function GET(request: NextRequest) {
}
/**
* PUT retrieve full credentials (including password) for session restoration.
* PUT - retrieve full credentials (including password) for session restoration.
* Protected by multiple Sec-Fetch-* headers to ensure only same-origin
* browser fetch() requests succeed. Non-browser clients cannot forge these.
*/
+1 -1
View File
@@ -66,7 +66,7 @@ async function findTokenEndpoint(serverUrl: string): Promise<string | null> {
return url;
}
} catch {
// Network error endpoint not reachable
// Network error - endpoint not reachable
}
}
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -3,10 +3,10 @@ import { getPluginRegistry, getThemeRegistry } from '@/lib/admin/plugin-registry
import { logger } from '@/lib/logger';
/**
* GET /api/plugins Public endpoint for clients to discover server-managed plugins & themes
* GET /api/plugins - Public endpoint for clients to discover server-managed plugins & themes
*
* Returns all enabled plugins and themes so the client can sync them to IndexedDB.
* No admin auth required this is how regular users receive plugins/themes.
* No admin auth required - this is how regular users receive plugins/themes.
*/
export async function GET() {
try {
+1 -1
View File
@@ -135,7 +135,7 @@ export async function POST(request: NextRequest) {
return NextResponse.json({ error: 'Identity mismatch' }, { status: 403 });
}
// Enforce admin policy strip locked settings so users can't override them
// Enforce admin policy - strip locked settings so users can't override them
await configManager.ensureLoaded();
const policy = configManager.getPolicy();
const filteredSettings = { ...settings };