mirror of
https://github.com/priyanshujain/margin-mail.git
synced 2026-10-04 20:17:05 +00:00
71 lines
4.6 KiB
JavaScript
71 lines
4.6 KiB
JavaScript
import { execFileSync } from "node:child_process";
|
|
import { access, copyFile, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
import { homedir } from "node:os";
|
|
import { join, resolve } from "node:path";
|
|
|
|
const signing = process.env.MARGIN_SIGNING_DIR || join(homedir(), ".margin-signing");
|
|
const appProfile = join(signing, "studio.margin.mail.provisionprofile");
|
|
const extensionProfile = join(signing, "studio.margin.mail.autofill.provisionprofile");
|
|
const present = await Promise.all([appProfile, extensionProfile].map(async (path) => {
|
|
try { await access(path); return true; } catch (error) {
|
|
if (error.code === "ENOENT") return false;
|
|
throw error;
|
|
}
|
|
}));
|
|
if (!present.every(Boolean)) {
|
|
console.error("Email OTP AutoFill is unavailable: both Margin Mail provisioning profiles are required.");
|
|
process.exit(0);
|
|
}
|
|
const identity = process.env.APPLE_SIGNING_IDENTITY;
|
|
if (!identity || identity === "-") throw new Error("Email OTP AutoFill requires a Developer ID signing identity.");
|
|
const plist = (path) => JSON.parse(execFileSync("plutil", ["-convert", "json", "-o", "-", path], { encoding: "utf8" }));
|
|
const profile = (path, identifier) => {
|
|
const xml = execFileSync("security", ["cms", "-D", "-i", path]);
|
|
const entitlements = JSON.parse(execFileSync("plutil", ["-extract", "Entitlements", "json", "-o", "-", "-"], { input: xml, encoding: "utf8" }));
|
|
const expiry = execFileSync("plutil", ["-extract", "ExpirationDate", "raw", "-o", "-", "-"], { input: xml, encoding: "utf8" }).trim();
|
|
if (entitlements["com.apple.application-identifier"] !== `TQV87WLXK3.${identifier}` ||
|
|
entitlements["com.apple.developer.team-identifier"] !== "TQV87WLXK3" ||
|
|
entitlements["com.apple.developer.authentication-services.autofill-credential-provider"] !== true ||
|
|
!entitlements["com.apple.security.application-groups"]?.some((group) =>
|
|
group === "TQV87WLXK3.*" || group === "TQV87WLXK3.studio.margin.mail") ||
|
|
!(new Date(expiry).getTime() > Date.now())) {
|
|
throw new Error(`Invalid or expired AutoFill profile for ${identifier}.`);
|
|
}
|
|
return entitlements;
|
|
};
|
|
const appEntitlements = profile(appProfile, "studio.margin.mail");
|
|
const extensionEntitlements = profile(extensionProfile, "studio.margin.mail.autofill");
|
|
const metadata = JSON.parse(execFileSync("cargo", ["metadata", "--no-deps", "--format-version", "1", "--manifest-path", "src-tauri/Cargo.toml"], { encoding: "utf8" }));
|
|
const output = join(metadata.target_directory, ".tauri", "autofill");
|
|
const contents = join(output, "MarginMailAutoFill.appex", "Contents");
|
|
await mkdir(join(contents, "MacOS"), { recursive: true });
|
|
const config = JSON.parse(await readFile("src-tauri/tauri.conf.json", "utf8"));
|
|
const info = plist("native/autofill/Info.plist");
|
|
info.CFBundleShortVersionString = config.version;
|
|
info.CFBundleVersion = config.bundle.macOS.bundleVersion || config.version;
|
|
const writePlist = async (path, value) => {
|
|
await writeFile(path, JSON.stringify(value));
|
|
execFileSync("plutil", ["-convert", "xml1", path]);
|
|
};
|
|
await writePlist(join(contents, "Info.plist"), info);
|
|
await copyFile(extensionProfile, join(contents, "embedded.provisionprofile"));
|
|
for (const [name, authorized] of [["host", appEntitlements], ["extension", extensionEntitlements]]) {
|
|
const value = plist(name === "host" ? "native/autofill/host.entitlements" : "native/autofill/autofill.entitlements");
|
|
value["com.apple.application-identifier"] = authorized["com.apple.application-identifier"];
|
|
value["com.apple.developer.team-identifier"] = authorized["com.apple.developer.team-identifier"];
|
|
await writePlist(join(output, `${name}.entitlements`), value);
|
|
}
|
|
const arch = process.arch === "arm64" ? "arm64" : "x86_64";
|
|
execFileSync("xcrun", ["swiftc", "-O", "-parse-as-library", "-application-extension", "-module-name", "MarginMailAutoFill",
|
|
"-target", `${arch}-apple-macosx15.0`, "-Xlinker", "-e", "-Xlinker", "_NSExtensionMain",
|
|
"native/autofill/CredentialProvider.swift", "-o", join(contents, "MacOS", "MarginMailAutoFill")], { stdio: ["ignore", "ignore", "inherit"] });
|
|
const extension = join(output, "MarginMailAutoFill.appex");
|
|
execFileSync("codesign", ["--force", "--sign", identity, "--options", "runtime", "--timestamp", "--entitlements", join(output, "extension.entitlements"), extension], { stdio: ["ignore", "ignore", "inherit"] });
|
|
execFileSync("codesign", ["--verify", "--strict", extension], { stdio: ["ignore", "ignore", "inherit"] });
|
|
const overlay = join(output, "tauri.conf.json");
|
|
await writeFile(overlay, JSON.stringify({ bundle: { macOS: {
|
|
entitlements: join(output, "host.entitlements"),
|
|
files: { "PlugIns/MarginMailAutoFill.appex": extension, "embedded.provisionprofile": resolve(appProfile) },
|
|
} } }));
|
|
console.log(overlay);
|