Extract the social login window into its own module
social-service.ts exceeded 500 lines and mixed the Electron browser-login window concern with the social domain logic. Move openSocialLoginWindow and its navigation policy into social-login-window.ts and re-export the public types. Behaviour unchanged; unit and e2e suites remain green.
This commit is contained in:
1 parent
ae5e08869f
commit
bc0865ede7
2 files changed
+50
-47
No files matched your search
@@ -0,0 +1,47 @@
|
||||
import { BrowserWindow, session } from "electron";
|
||||
|
||||
export interface SocialLoginWindowInput {
|
||||
title: string;
|
||||
loginUrl: string;
|
||||
partitionKey: string;
|
||||
allowedHosts: string[];
|
||||
sandboxEnabled: boolean;
|
||||
}
|
||||
|
||||
export type SocialLoginWindowLauncher = (input: SocialLoginWindowInput) => void;
|
||||
|
||||
export function openSocialLoginWindow(input: SocialLoginWindowInput): void {
|
||||
const socialSession = session.fromPartition(input.partitionKey);
|
||||
socialSession.setPermissionRequestHandler((_webContents, _permission, callback) => callback(false));
|
||||
socialSession.setPermissionCheckHandler(() => false);
|
||||
|
||||
const win = new BrowserWindow({
|
||||
width: 1280,
|
||||
height: 860,
|
||||
title: input.title,
|
||||
webPreferences: {
|
||||
session: socialSession,
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true,
|
||||
sandbox: input.sandboxEnabled,
|
||||
},
|
||||
});
|
||||
attachNavigationPolicy(win, input.allowedHosts);
|
||||
win.loadURL(input.loginUrl);
|
||||
}
|
||||
|
||||
function attachNavigationPolicy(win: BrowserWindow, allowedHosts: string[]): void {
|
||||
win.webContents.setWindowOpenHandler(() => ({ action: "deny" }));
|
||||
const guard = (event: Electron.Event, url: string) => {
|
||||
if (!isAllowedNavigation(allowedHosts, url)) event.preventDefault();
|
||||
};
|
||||
win.webContents.on("will-navigate", guard);
|
||||
win.webContents.on("will-redirect", guard);
|
||||
}
|
||||
|
||||
function isAllowedNavigation(allowedHosts: string[], url: string): boolean {
|
||||
const parsed = new URL(url);
|
||||
if (parsed.protocol !== "https:") return false;
|
||||
const host = parsed.hostname.toLowerCase();
|
||||
return allowedHosts.some((entry) => host === entry || host.endsWith(`.${entry}`));
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { DatabaseSync } from "node:sqlite";
|
||||
import { BrowserWindow, session } from "electron";
|
||||
import type {
|
||||
CreateScheduledPostInput,
|
||||
CreateSocialAccountInput,
|
||||
@@ -11,6 +10,7 @@ import { createId } from "../../shared/ids";
|
||||
import { ApprovalService } from "./approval-service";
|
||||
import { AuditService } from "./audit-service";
|
||||
import { SocialAuditService } from "./social-audit-service";
|
||||
import { openSocialLoginWindow, type SocialLoginWindowLauncher } from "./social-login-window";
|
||||
import {
|
||||
SOCIAL_BROWSER_ACTION,
|
||||
SocialBrowserPolicyService,
|
||||
@@ -73,15 +73,7 @@ interface GrantScope {
|
||||
riskCeiling: RiskLevel;
|
||||
}
|
||||
|
||||
export interface SocialLoginWindowInput {
|
||||
title: string;
|
||||
loginUrl: string;
|
||||
partitionKey: string;
|
||||
allowedHosts: string[];
|
||||
sandboxEnabled: boolean;
|
||||
}
|
||||
|
||||
export type SocialLoginWindowLauncher = (input: SocialLoginWindowInput) => void;
|
||||
export type { SocialLoginWindowInput, SocialLoginWindowLauncher } from "./social-login-window";
|
||||
|
||||
export class SocialService {
|
||||
private readonly audit: AuditService;
|
||||
@@ -488,40 +480,4 @@ function loginEvidenceMetadata(input: {
|
||||
actorType: "employee",
|
||||
actorId: input.actorId,
|
||||
};
|
||||
}
|
||||
|
||||
function openSocialLoginWindow(input: SocialLoginWindowInput): void {
|
||||
const socialSession = session.fromPartition(input.partitionKey);
|
||||
socialSession.setPermissionRequestHandler((_webContents, _permission, callback) => callback(false));
|
||||
socialSession.setPermissionCheckHandler(() => false);
|
||||
|
||||
const win = new BrowserWindow({
|
||||
width: 1280,
|
||||
height: 860,
|
||||
title: input.title,
|
||||
webPreferences: {
|
||||
session: socialSession,
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true,
|
||||
sandbox: input.sandboxEnabled,
|
||||
},
|
||||
});
|
||||
attachNavigationPolicy(win, input.allowedHosts);
|
||||
win.loadURL(input.loginUrl);
|
||||
}
|
||||
|
||||
function attachNavigationPolicy(win: BrowserWindow, allowedHosts: string[]): void {
|
||||
win.webContents.setWindowOpenHandler(() => ({ action: "deny" }));
|
||||
const guard = (event: Electron.Event, url: string) => {
|
||||
if (!isAllowedNavigation(allowedHosts, url)) event.preventDefault();
|
||||
};
|
||||
win.webContents.on("will-navigate", guard);
|
||||
win.webContents.on("will-redirect", guard);
|
||||
}
|
||||
|
||||
function isAllowedNavigation(allowedHosts: string[], url: string): boolean {
|
||||
const parsed = new URL(url);
|
||||
if (parsed.protocol !== "https:") return false;
|
||||
const host = parsed.hostname.toLowerCase();
|
||||
return allowedHosts.some((entry) => host === entry || host.endsWith(`.${entry}`));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user