{ config, lib, ... }: with lib; let cfg = config.services.piped; in { options.services.piped = { enable = mkEnableOption "piped"; frontendDomain = mkOption {type = types.str;}; backendDomain = mkOption { type = types.nullOr types.str; default = null; description = "Set to null to use project default backend"; }; proxyDomain = mkOption {type = types.str;}; #rydProxyDomain = mkOption { type = types.str; }; disableNginx = mkOption { type = types.bool; default = false; description = "Don't run nginx to serve frontend/backend/proxy"; }; disableFrontend = mkOption { type = types.bool; default = false; description = "Don't host frontend"; }; disableBackend = mkOption { type = types.bool; default = false; description = "Don't host backend"; }; disableProxy = mkOption { type = types.bool; default = false; description = "Don't host proxy"; }; disablePostgres = mkOption { type = types.bool; default = false; description = "Manually configure postgres instead"; }; postgresHost = mkOption { type = types.str; default = "127.0.0.1"; description = "Host postgres is on"; }; postgresPort = mkOption { type = types.number; default = 5432; description = "Port postgres is on"; }; postgresDB = mkOption { type = types.str; default = "piped"; description = "Database name for piped"; }; postgresUsername = mkOption { type = types.str; default = "piped"; description = "Host postgres is on"; }; postgresPassword = mkOption { type = types.str; default = "password"; description = "Password to use for postgres"; }; postgresPasswordFile = mkOption { type = types.nullOr types.str; default = null; description = "Password file to use for postgres, loaded at runtime"; }; proxyIPv4Only = mkOption { type = types.bool; default = false; description = "Only use IPv4 querying youtube's servers for proxy"; }; proxyNginxExtraConfig = mkOption { type = types.lines; default = '' proxy_buffering on; proxy_buffers 1024 16k; proxy_set_header X-Forwarded-For ""; proxy_set_header CF-Connecting-IP ""; proxy_hide_header "alt-svc"; sendfile on; sendfile_max_chunk 512k; tcp_nopush on; aio threads=default; aio_write on; directio 16m; proxy_hide_header Cache-Control; proxy_hide_header etag; proxy_http_version 1.1; proxy_set_header Connection keep-alive; proxy_max_temp_file_size 32m; access_log off; ''; description = "Extra config for nginx on piped-proxy"; }; httpWorkers = mkOption { type = types.number; default = 2; description = "Number of workers for HTTP backend tasks"; }; feedRetentionDays = mkOption { type = types.number; default = 30; description = "Days feed is stored for"; }; subscriptionRetentionDays = mkOption { type = types.number; default = 30; description = "Days subscriptions are stored for unauthenticated users"; }; sponsorblockServers = mkOption { type = types.listOf types.str; default = ["https://sponsor.ajay.app" "https://sponsorblock.kavin.rocks"]; description = "Days subscriptions are stored for unauthenticated users"; }; disableRegistrations = mkOption { type = types.bool; default = true; description = "Disable user registrations"; }; disableLBRYStreams = mkOption { type = types.bool; default = false; description = "Disable showing streams provided by LBRY Youtube Partnership"; }; enableCompromisedPasswordCheck = mkOption { type = types.bool; default = true; description = "Use the haveibeenpwned API to check if user password have been compromised"; }; enableCaptcha = mkOption { type = types.bool; default = true; description = "Enable captcha for registrations"; }; sentryDSN = mkOption { type = types.str; default = ""; description = "Public DSN for sentry error reporting"; }; captchaAPIURL = mkOption { type = types.str; default = ""; description = "API URL for Captcha"; }; # TODO: Key & KeyFile should be only one or the other used captchaAPIKey = mkOption { type = types.str; default = ""; description = "API Key for Captcha"; }; captchaAPIKeyFile = mkOption { type = types.str; default = ""; description = "API Key File for Captcha"; }; # TODO: run this, requires a go app and Tor server for proxy #enableRYDServer = mkOption { # type = types.bool; # default = true; # description = "Run a RYD Proxy Server to use"; #}; disableRYD = mkOption { type = types.bool; #default = if cfg.enableRYDServer then false else true; default = false; description = "Disables querying a Return YouTube Dislike server"; }; rydAPIURL = mkOption { type = types.str; #default = if cfg.enableRYDServer then cfg.rydProxyDomain else "https://ryd-proxy.kavin.rocks"; default = "https://ryd-proxy.kavin.rocks"; description = "API URL for a Return YouTube Dislike server"; }; # for Piped's Federation Shenanigan # https://github.com/TeamPiped/piped-federation#how-to-join enableFederation = mkOption { type = types.bool; default = false; description = "Enable federation of something"; }; matrixServerAddr = mkOption { type = types.str; default = ""; description = "Matrix server address for federation"; }; # TODO: make so only one of these options can be used matrixToken = mkOption { type = types.str; default = ""; description = "Matrix access token"; }; matrixTokenFile = mkOption { type = types.str; default = ""; description = "Matrix access token file"; }; internalBackendPort = mkOption { type = types.number; default = 3001; }; internalProxyPort = mkOption { type = types.number; default = 3002; }; }; config = mkIf (cfg.enable && (!cfg.disableBackend || !cfg.disableProxy)) { users.users."piped" = { isSystemUser = true; group = "piped"; }; users.groups.piped = {}; }; }