2026-02-22 19:57:42 +00:00
|
|
|
{
|
|
|
|
|
lib,
|
|
|
|
|
sLib,
|
|
|
|
|
info,
|
|
|
|
|
...
|
|
|
|
|
}:
|
|
|
|
|
|
|
|
|
|
let
|
|
|
|
|
submodule = isDefault: {
|
|
|
|
|
options = {
|
|
|
|
|
https-only = lib.mkOption {
|
|
|
|
|
type = lib.types.bool;
|
|
|
|
|
default = false; # if isDefault then false else config.default.https-only;
|
|
|
|
|
example = true;
|
|
|
|
|
description = "Whether ${
|
|
|
|
|
if isDefault then "all domains" else "this domain"
|
|
|
|
|
} should be accessed over https only.";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
cookies = lib.mkOption {
|
|
|
|
|
type = lib.types.enum (
|
|
|
|
|
[
|
|
|
|
|
"forever"
|
|
|
|
|
"session"
|
|
|
|
|
"never"
|
|
|
|
|
true
|
|
|
|
|
false
|
|
|
|
|
]
|
|
|
|
|
++ lib.optional (!isDefault) null
|
|
|
|
|
);
|
|
|
|
|
default = if isDefault then "forever" else null;
|
|
|
|
|
example = "session";
|
|
|
|
|
description = ''
|
|
|
|
|
Determines how cookies are handled on this domain:
|
|
|
|
|
forever: Cookies are permitted
|
|
|
|
|
session: Cookies are permitted, but they are deleted when the session ends
|
|
|
|
|
never: Cookies are denied
|
|
|
|
|
true: Equivalent to "session"
|
|
|
|
|
false: Equivalent to "never"
|
|
|
|
|
${if isDefault then "" else "null: Use the default settings"}
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
${if isDefault then null else "ubo"} = lib.mkOption {
|
|
|
|
|
type = lib.types.bool;
|
|
|
|
|
default = true;
|
|
|
|
|
example = false;
|
|
|
|
|
description = "Whether ublock-origin should be enabled on this domain.";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
scripts = lib.mkOption {
|
|
|
|
|
type = (if isDefault then (x: x) else lib.types.nullOr) lib.types.bool;
|
|
|
|
|
default = if isDefault then true else null;
|
|
|
|
|
example = false;
|
|
|
|
|
description = "Whether to allow JavaScript to run on websites.${
|
|
|
|
|
if isDefault then "" else " If null, use the default settings."
|
|
|
|
|
}";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
fonts = lib.mkOption {
|
|
|
|
|
type = (if isDefault then (x: x) else lib.types.nullOr) lib.types.bool;
|
|
|
|
|
default = if isDefault then true else null;
|
|
|
|
|
example = false;
|
|
|
|
|
description = "Whether to allow websites to use remote fonts.";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
popups = lib.mkOption {
|
|
|
|
|
type = (if isDefault then (x: x) else lib.types.nullOr) lib.types.bool;
|
|
|
|
|
default = if isDefault then true else null;
|
|
|
|
|
example = false;
|
|
|
|
|
description = "Whether to allow popups.";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
largeMedia = lib.mkOption {
|
|
|
|
|
type = (if isDefault then (x: x) else lib.types.nullOr) lib.types.bool;
|
|
|
|
|
default = if isDefault then true else null;
|
|
|
|
|
example = false;
|
|
|
|
|
description = "Whether to allow large media.";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
subdomain = {
|
|
|
|
|
allow = lib.mkOption {
|
|
|
|
|
type = lib.types.listOf lib.types.str;
|
|
|
|
|
default = [ ];
|
|
|
|
|
example = [ "google.com" ];
|
|
|
|
|
description = "List of subdomains that ${
|
|
|
|
|
if isDefault then "any" else "this"
|
|
|
|
|
} domain can load resources from.";
|
|
|
|
|
};
|
|
|
|
|
block = lib.mkOption {
|
|
|
|
|
type = lib.types.listOf lib.types.str;
|
|
|
|
|
default = [ ];
|
|
|
|
|
example = [ "google.com" ];
|
|
|
|
|
description = "List of subdomains that ${
|
|
|
|
|
if isDefault then "any" else "this"
|
|
|
|
|
} domain cannot load resources from.";
|
|
|
|
|
};
|
|
|
|
|
noop = lib.mkOption {
|
|
|
|
|
type = lib.types.listOf lib.types.str;
|
|
|
|
|
default = [ ];
|
|
|
|
|
example = [ "google.com" ];
|
|
|
|
|
description = "List of subdomains that ${
|
|
|
|
|
if isDefault then "any" else "this"
|
|
|
|
|
} domain can load resources from, if a static filter does not override this rule.";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
${if isDefault then null else "filters"} = lib.mkOption {
|
|
|
|
|
type = lib.types.listOf lib.types.str;
|
|
|
|
|
default = [ ];
|
|
|
|
|
example = [ "#irritating-popup" ];
|
|
|
|
|
description = "List of ublock filters to apply to this domain.";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
in
|
|
|
|
|
{
|
|
|
|
|
options = {
|
|
|
|
|
per-site = {
|
|
|
|
|
default = lib.mkOption {
|
|
|
|
|
type = lib.types.submodule (submodule true);
|
|
|
|
|
default = { };
|
|
|
|
|
description = "Sets options for all websites.";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
site = lib.mkOption {
|
|
|
|
|
type = lib.types.attrsOf (lib.types.submodule (submodule false));
|
|
|
|
|
default = { };
|
|
|
|
|
description = "Sets options on a per-website basis.";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
preprocess =
|
|
|
|
|
{ per-site, ... }:
|
|
|
|
|
let
|
|
|
|
|
inherit (per-site) default site;
|
|
|
|
|
|
|
|
|
|
behavior =
|
|
|
|
|
if
|
|
|
|
|
builtins.elem default.cookies [
|
|
|
|
|
"forever"
|
|
|
|
|
"session"
|
|
|
|
|
true
|
|
|
|
|
]
|
|
|
|
|
then
|
|
|
|
|
"accept"
|
|
|
|
|
else
|
|
|
|
|
"reject";
|
|
|
|
|
|
|
|
|
|
filterCookies =
|
|
|
|
|
x:
|
2026-02-23 22:08:18 +00:00
|
|
|
sLib.compose [
|
|
|
|
|
builtins.concatLists
|
|
|
|
|
(lib.mapAttrsToList (
|
|
|
|
|
k: v:
|
|
|
|
|
if builtins.elem v.cookies x then
|
|
|
|
|
[ "https://${k}/" ] ++ lib.optional (!v.https-only) "http://${k}/"
|
|
|
|
|
else
|
|
|
|
|
[ ]
|
|
|
|
|
))
|
|
|
|
|
] site;
|
2026-02-22 19:57:42 +00:00
|
|
|
|
|
|
|
|
makeUboConf = domain: config: {
|
|
|
|
|
adminSettings = {
|
|
|
|
|
whitelist = lib.optional (!(config.ubo or true)) domain;
|
|
|
|
|
hostnameSwitchesString =
|
|
|
|
|
lib.optional (config.scripts != null) "no-scripting: ${domain} ${builtins.toJSON (!config.scripts)}"
|
|
|
|
|
++
|
|
|
|
|
lib.optional (config.fonts != null)
|
|
|
|
|
"no-remote-fonts: ${domain} ${builtins.toJSON (!config.fonts)}"
|
|
|
|
|
++ lib.optional (config.popups != null) "no-popups: ${domain} ${builtins.toJSON (!config.popups)}"
|
|
|
|
|
++
|
|
|
|
|
lib.optional (config.largeMedia != null)
|
|
|
|
|
"no-large-media: ${domain} ${builtins.toJSON (!config.largeMedia)}";
|
|
|
|
|
dynamicFilteringString =
|
|
|
|
|
builtins.map (x: "${domain} ${x} * allow") config.subdomain.allow
|
|
|
|
|
++ builtins.map (x: "${domain} ${x} * block") config.subdomain.block
|
|
|
|
|
++ builtins.map (x: "${domain} ${x} * noop") config.subdomain.noop;
|
|
|
|
|
userFilters = builtins.map (x: "${domain}##${x}") (config.filters or [ ]);
|
|
|
|
|
};
|
|
|
|
|
# toOverwrite = {
|
|
|
|
|
# trustedSiteDirectives = lib.optional (!(config.ubo or true)) domain;
|
|
|
|
|
# filters = builtins.map (x: "${domain}##${x}") (config.filters or []);
|
|
|
|
|
# };
|
|
|
|
|
};
|
|
|
|
|
in
|
|
|
|
|
{
|
|
|
|
|
policies = {
|
|
|
|
|
Cookies = {
|
|
|
|
|
Allow = filterCookies [ "forever" ];
|
|
|
|
|
AllowSession = filterCookies [
|
|
|
|
|
"session"
|
|
|
|
|
true
|
|
|
|
|
];
|
|
|
|
|
Block = filterCookies [
|
|
|
|
|
"never"
|
|
|
|
|
false
|
|
|
|
|
];
|
|
|
|
|
Behavior = behavior;
|
|
|
|
|
BehaviorPrivateBrowsing = behavior;
|
|
|
|
|
};
|
|
|
|
|
SanitizeOnShutdown.Cookies = builtins.elem default.cookies [
|
|
|
|
|
"session"
|
|
|
|
|
true
|
|
|
|
|
];
|
|
|
|
|
};
|
2026-02-23 22:08:18 +00:00
|
|
|
extensions.settings."uBlock0@raymondhill.net" = sLib.recursiveMergeAll (
|
|
|
|
|
[ (makeUboConf "*" default) ] ++ lib.mapAttrsToList makeUboConf site
|
|
|
|
|
);
|
2026-02-22 19:57:42 +00:00
|
|
|
};
|
|
|
|
|
}
|