1import * as NodeServices from "@effect/platform-node/NodeServices";
2import { assert, it } from "@effect/vitest";
3import * as HostProcess from "@t3tools/shared/HostProcess";
4import * as Effect from "effect/Effect";
5import * as FileSystem from "effect/FileSystem";
6import * as PlatformError from "effect/PlatformError";
7import { safariPermissionCheck } from "./SafariPermission.ts";
8
9it.effect("detects Safari access becoming available without reading or importing cookies", () =>
10 Effect.gen(function* () {
11 const fs = yield* FileSystem.FileSystem;
12 const home = yield* fs.makeTempDirectoryScoped({ prefix: "t3-safari-access-" });
13 const directory = `${home}/Library/Containers/com.apple.Safari/Data/Library/Cookies`;
14 yield* fs.makeDirectory(directory, { recursive: true });
15 const jar = `${directory}/Cookies.binarycookies`;
16 yield* fs.writeFileString(jar, "not a valid cookie database");
17 let allowed = false;
18 const guardedFs = FileSystem.FileSystem.of({
19 ...fs,
20 open: (path, options) =>
21 allowed
22 ? fs.open(path, options)
23 : Effect.fail(
24 PlatformError.systemError({
25 _tag: "Unknown",
26 module: "FileSystem",
27 method: "open",
28 cause: Object.assign(new Error("operation not permitted"), { code: "EPERM" }),
29 }),
30 ),
31 });
32 const check = yield* safariPermissionCheck.pipe(
33 Effect.provideService(HostProcess.Environment, { HOME: home }),
34 Effect.provideService(HostProcess.Platform, "darwin"),
35 Effect.provideService(FileSystem.FileSystem, guardedFs),
36 );
37 assert.isFalse(yield* Effect.promise(check));
38 allowed = true;
39 assert.isTrue(yield* Effect.promise(check));
40 yield* fs.remove(jar);
41 assert.isFalse(yield* Effect.promise(check));
42 }).pipe(Effect.provide(NodeServices.layer), Effect.scoped),
43);
44
45it.effect("recognizes access when cookies exist only in a named Safari profile", () =>
46 Effect.gen(function* () {
47 const fs = yield* FileSystem.FileSystem;
48 const home = yield* fs.makeTempDirectoryScoped({ prefix: "t3-safari-named-access-" });
49 const check = yield* safariPermissionCheck.pipe(
50 Effect.provideService(HostProcess.Environment, { HOME: home }),
51 Effect.provideService(HostProcess.Platform, "darwin"),
52 );
53 assert.isFalse(yield* Effect.promise(check));
54 const directory = `${home}/Library/Containers/com.apple.Safari/Data/Library/WebKit/WebsiteDataStore/12345678-1234-1234-1234-123456789abc/Cookies`;
55 yield* fs.makeDirectory(directory, { recursive: true });
56 yield* fs.writeFileString(`${directory}/Cookies.binarycookies`, "not parsed");
57 assert.isTrue(yield* Effect.promise(check));
58 }).pipe(Effect.provide(NodeServices.layer), Effect.scoped),
59);