Inline base64 source maps had been checked into tracked src files. This strips those comments from the repository without changing runtime behavior or adding ongoing guardrails, per the requested one-time cleanup scope. Constraint: Keep this change limited to tracked source cleanup only Rejected: Add CI/source verification guard | user requested one-time cleanup only Confidence: high Scope-risk: narrow Reversibility: clean Directive: If these directives reappear, fix the producing transform instead of reintroducing repo-side cleanup code Tested: rg -n "sourceMappingURL" ., bun run smoke, bun run verify:privacy, bun run test:provider, npm run test:provider-recommendation Not-tested: bun run typecheck (repository has many pre-existing unrelated failures) Co-authored-by: anandh8x <test@example.com>
74 lines
3.0 KiB
TypeScript
74 lines
3.0 KiB
TypeScript
import React from 'react';
|
|
import { getIsInteractive } from '../../bootstrap/state.js';
|
|
import { ManagedSettingsSecurityDialog } from '../../components/ManagedSettingsSecurityDialog/ManagedSettingsSecurityDialog.js';
|
|
import { extractDangerousSettings, hasDangerousSettings, hasDangerousSettingsChanged } from '../../components/ManagedSettingsSecurityDialog/utils.js';
|
|
import { render } from '../../ink.js';
|
|
import { KeybindingSetup } from '../../keybindings/KeybindingProviderSetup.js';
|
|
import { AppStateProvider } from '../../state/AppState.js';
|
|
import { gracefulShutdownSync } from '../../utils/gracefulShutdown.js';
|
|
import { getBaseRenderOptions } from '../../utils/renderOptions.js';
|
|
import type { SettingsJson } from '../../utils/settings/types.js';
|
|
import { logEvent } from '../analytics/index.js';
|
|
export type SecurityCheckResult = 'approved' | 'rejected' | 'no_check_needed';
|
|
|
|
/**
|
|
* Check if new remote managed settings contain dangerous settings that require user approval.
|
|
* Shows a blocking dialog if dangerous settings have changed or been added.
|
|
*
|
|
* @param cachedSettings The current cached settings (may be null for first run)
|
|
* @param newSettings The new settings fetched from the API
|
|
* @returns 'approved' if user accepts, 'rejected' if user declines, 'no_check_needed' if no dangerous changes
|
|
*/
|
|
export async function checkManagedSettingsSecurity(cachedSettings: SettingsJson | null, newSettings: SettingsJson | null): Promise<SecurityCheckResult> {
|
|
// If new settings don't have dangerous settings, no check needed
|
|
if (!newSettings || !hasDangerousSettings(extractDangerousSettings(newSettings))) {
|
|
return 'no_check_needed';
|
|
}
|
|
|
|
// If dangerous settings haven't changed, no check needed
|
|
if (!hasDangerousSettingsChanged(cachedSettings, newSettings)) {
|
|
return 'no_check_needed';
|
|
}
|
|
|
|
// Skip dialog in non-interactive mode (consistent with trust dialog behavior)
|
|
if (!getIsInteractive()) {
|
|
return 'no_check_needed';
|
|
}
|
|
|
|
// Log that dialog is being shown
|
|
logEvent('tengu_managed_settings_security_dialog_shown', {});
|
|
|
|
// Show blocking dialog
|
|
return new Promise<SecurityCheckResult>(resolve => {
|
|
void (async () => {
|
|
const {
|
|
unmount
|
|
} = await render(<AppStateProvider>
|
|
<KeybindingSetup>
|
|
<ManagedSettingsSecurityDialog settings={newSettings} onAccept={() => {
|
|
logEvent('tengu_managed_settings_security_dialog_accepted', {});
|
|
unmount();
|
|
void resolve('approved');
|
|
}} onReject={() => {
|
|
logEvent('tengu_managed_settings_security_dialog_rejected', {});
|
|
unmount();
|
|
void resolve('rejected');
|
|
}} />
|
|
</KeybindingSetup>
|
|
</AppStateProvider>, getBaseRenderOptions(false));
|
|
})();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Handle the security check result by exiting if rejected
|
|
* Returns true if we should continue, false if we should stop
|
|
*/
|
|
export function handleSecurityCheckResult(result: SecurityCheckResult): boolean {
|
|
if (result === 'rejected') {
|
|
gracefulShutdownSync(1);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|