From 108891744eaa7410e305871212d5b81c1b67a095 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Bouya?= Date: Sat, 12 Jan 2019 12:41:23 +0100 Subject: Refactor websites. This commit refactors websites into module per "vhost". --- virtual/eldiron.nix | 88 +- virtual/modules/databases.nix | 180 --- virtual/modules/databases/default.nix | 180 +++ .../databases/postgresql_run_socket_path.patch | 12 + virtual/modules/gitolite.nix | 84 -- virtual/modules/gitolite/default.nix | 86 ++ virtual/modules/gitweb/default.nix | 30 - virtual/modules/gitweb/gitweb.nix | 64 - virtual/modules/gitweb/theme/git-favicon.png | Bin 1125 -> 0 bytes virtual/modules/gitweb/theme/git-logo.png | Bin 2412 -> 0 bytes virtual/modules/gitweb/theme/gitweb.css | 783 ----------- virtual/modules/gitweb/theme/gitweb.js | 27 - virtual/modules/postgresql_run_socket_path.patch | 12 - virtual/modules/websites/commons/adminer.nix | 64 + virtual/modules/websites/default.nix | 93 +- virtual/modules/websites/tools/cloud/default.nix | 45 + .../cloud/nextcloud-config/mimetypealiases.json | 4 + .../cloud/nextcloud-config/mimetypemapping.json | 4 + virtual/modules/websites/tools/cloud/nextcloud.nix | 267 ++++ virtual/modules/websites/tools/dav/davical.nix | 164 +++ ..._19eb79ebf9250e5f339675319902458c40ed1755.patch | 26 + virtual/modules/websites/tools/dav/default.nix | 33 + virtual/modules/websites/tools/dav/infcloud.nix | 38 + .../modules/websites/tools/dav/infcloud_config.js | 1446 ++++++++++++++++++++ virtual/modules/websites/tools/db/default.nix | 23 + virtual/modules/websites/tools/git/default.nix | 46 + .../modules/websites/tools/git/gitweb/gitweb.nix | 64 + .../tools/git/gitweb/theme/git-favicon.png | Bin 0 -> 1125 bytes .../websites/tools/git/gitweb/theme/git-logo.png | Bin 0 -> 2412 bytes .../websites/tools/git/gitweb/theme/gitweb.css | 783 +++++++++++ .../websites/tools/git/gitweb/theme/gitweb.js | 27 + .../tools/git/mantisbt/mantisbt-plugin-slack.json | 15 + .../mantisbt-plugin-source-integration.json | 15 + ...t-plugin-source-integration_Source.API.php.diff | 12 + .../websites/tools/git/mantisbt/mantisbt.nix | 124 ++ .../tools/git/mantisbt/patches/bug_report.php.diff | 20 + .../git/mantisbt/patches/bug_report_page.php.diff | 53 + .../git/mantisbt/patches/bugnote_add.php.diff | 20 + .../git/mantisbt/patches/bugnote_add_inc.php.diff | 52 + virtual/modules/websites/tools/tools/default.nix | 65 + .../modules/websites/tools/tools/roundcubemail.nix | 110 ++ virtual/modules/websites/tools/tools/tt-rss.json | 14 + .../tools/ttrss-af-feedmod_type_replace.patch | 12 + .../websites/tools/tools/ttrss-af_feedmod.json | 15 + .../websites/tools/tools/ttrss-auth-ldap.json | 15 + .../websites/tools/tools/ttrss-feediron.json | 15 + .../tools/tools/ttrss-feediron_json_reformat.patch | 18 + .../websites/tools/tools/ttrss-ff_instagram.json | 15 + .../websites/tools/tools/ttrss-tumblr_gdpr_ua.json | 15 + virtual/modules/websites/tools/tools/ttrss.nix | 182 +++ virtual/modules/websites/tools/tools/ympd.nix | 35 + virtual/packages.nix | 21 - virtual/packages/adminer.nix | 64 - virtual/packages/davical.nix | 163 --- ..._19eb79ebf9250e5f339675319902458c40ed1755.patch | 26 - virtual/packages/infcloud.nix | 38 - virtual/packages/infcloud_config.js | 1446 -------------------- .../packages/mantisbt-patches/bug_report.php.diff | 20 - .../mantisbt-patches/bug_report_page.php.diff | 53 - .../packages/mantisbt-patches/bugnote_add.php.diff | 20 - .../mantisbt-patches/bugnote_add_inc.php.diff | 52 - virtual/packages/mantisbt-plugin-slack.json | 15 - .../mantisbt-plugin-source-integration.json | 15 - ...t-plugin-source-integration_Source.API.php.diff | 12 - virtual/packages/mantisbt.nix | 124 -- .../packages/nextcloud-config/mimetypealiases.json | 4 - .../packages/nextcloud-config/mimetypemapping.json | 4 - virtual/packages/nextcloud.nix | 267 ---- virtual/packages/roundcubemail.nix | 110 -- virtual/packages/test_goaccess.conf | 99 -- virtual/packages/tt-rss.json | 14 - .../packages/ttrss-af-feedmod_type_replace.patch | 12 - virtual/packages/ttrss-af_feedmod.json | 15 - virtual/packages/ttrss-auth-ldap.json | 15 - virtual/packages/ttrss-feediron.json | 15 - .../packages/ttrss-feediron_json_reformat.patch | 18 - virtual/packages/ttrss-ff_instagram.json | 15 - virtual/packages/ttrss-tumblr_gdpr_ua.json | 15 - virtual/packages/ttrss.nix | 182 --- virtual/packages/ympd.nix | 35 - 80 files changed, 4175 insertions(+), 4209 deletions(-) delete mode 100644 virtual/modules/databases.nix create mode 100644 virtual/modules/databases/default.nix create mode 100644 virtual/modules/databases/postgresql_run_socket_path.patch delete mode 100644 virtual/modules/gitolite.nix create mode 100644 virtual/modules/gitolite/default.nix delete mode 100644 virtual/modules/gitweb/default.nix delete mode 100644 virtual/modules/gitweb/gitweb.nix delete mode 100644 virtual/modules/gitweb/theme/git-favicon.png delete mode 100644 virtual/modules/gitweb/theme/git-logo.png delete mode 100644 virtual/modules/gitweb/theme/gitweb.css delete mode 100644 virtual/modules/gitweb/theme/gitweb.js delete mode 100644 virtual/modules/postgresql_run_socket_path.patch create mode 100644 virtual/modules/websites/commons/adminer.nix create mode 100644 virtual/modules/websites/tools/cloud/default.nix create mode 100644 virtual/modules/websites/tools/cloud/nextcloud-config/mimetypealiases.json create mode 100644 virtual/modules/websites/tools/cloud/nextcloud-config/mimetypemapping.json create mode 100644 virtual/modules/websites/tools/cloud/nextcloud.nix create mode 100644 virtual/modules/websites/tools/dav/davical.nix create mode 100644 virtual/modules/websites/tools/dav/davical_19eb79ebf9250e5f339675319902458c40ed1755.patch create mode 100644 virtual/modules/websites/tools/dav/default.nix create mode 100644 virtual/modules/websites/tools/dav/infcloud.nix create mode 100644 virtual/modules/websites/tools/dav/infcloud_config.js create mode 100644 virtual/modules/websites/tools/db/default.nix create mode 100644 virtual/modules/websites/tools/git/default.nix create mode 100644 virtual/modules/websites/tools/git/gitweb/gitweb.nix create mode 100644 virtual/modules/websites/tools/git/gitweb/theme/git-favicon.png create mode 100644 virtual/modules/websites/tools/git/gitweb/theme/git-logo.png create mode 100644 virtual/modules/websites/tools/git/gitweb/theme/gitweb.css create mode 100644 virtual/modules/websites/tools/git/gitweb/theme/gitweb.js create mode 100644 virtual/modules/websites/tools/git/mantisbt/mantisbt-plugin-slack.json create mode 100644 virtual/modules/websites/tools/git/mantisbt/mantisbt-plugin-source-integration.json create mode 100644 virtual/modules/websites/tools/git/mantisbt/mantisbt-plugin-source-integration_Source.API.php.diff create mode 100644 virtual/modules/websites/tools/git/mantisbt/mantisbt.nix create mode 100644 virtual/modules/websites/tools/git/mantisbt/patches/bug_report.php.diff create mode 100644 virtual/modules/websites/tools/git/mantisbt/patches/bug_report_page.php.diff create mode 100644 virtual/modules/websites/tools/git/mantisbt/patches/bugnote_add.php.diff create mode 100644 virtual/modules/websites/tools/git/mantisbt/patches/bugnote_add_inc.php.diff create mode 100644 virtual/modules/websites/tools/tools/default.nix create mode 100644 virtual/modules/websites/tools/tools/roundcubemail.nix create mode 100644 virtual/modules/websites/tools/tools/tt-rss.json create mode 100644 virtual/modules/websites/tools/tools/ttrss-af-feedmod_type_replace.patch create mode 100644 virtual/modules/websites/tools/tools/ttrss-af_feedmod.json create mode 100644 virtual/modules/websites/tools/tools/ttrss-auth-ldap.json create mode 100644 virtual/modules/websites/tools/tools/ttrss-feediron.json create mode 100644 virtual/modules/websites/tools/tools/ttrss-feediron_json_reformat.patch create mode 100644 virtual/modules/websites/tools/tools/ttrss-ff_instagram.json create mode 100644 virtual/modules/websites/tools/tools/ttrss-tumblr_gdpr_ua.json create mode 100644 virtual/modules/websites/tools/tools/ttrss.nix create mode 100644 virtual/modules/websites/tools/tools/ympd.nix delete mode 100644 virtual/packages.nix delete mode 100644 virtual/packages/adminer.nix delete mode 100644 virtual/packages/davical.nix delete mode 100644 virtual/packages/davical_19eb79ebf9250e5f339675319902458c40ed1755.patch delete mode 100644 virtual/packages/infcloud.nix delete mode 100644 virtual/packages/infcloud_config.js delete mode 100644 virtual/packages/mantisbt-patches/bug_report.php.diff delete mode 100644 virtual/packages/mantisbt-patches/bug_report_page.php.diff delete mode 100644 virtual/packages/mantisbt-patches/bugnote_add.php.diff delete mode 100644 virtual/packages/mantisbt-patches/bugnote_add_inc.php.diff delete mode 100644 virtual/packages/mantisbt-plugin-slack.json delete mode 100644 virtual/packages/mantisbt-plugin-source-integration.json delete mode 100644 virtual/packages/mantisbt-plugin-source-integration_Source.API.php.diff delete mode 100644 virtual/packages/mantisbt.nix delete mode 100644 virtual/packages/nextcloud-config/mimetypealiases.json delete mode 100644 virtual/packages/nextcloud-config/mimetypemapping.json delete mode 100644 virtual/packages/nextcloud.nix delete mode 100644 virtual/packages/roundcubemail.nix delete mode 100644 virtual/packages/test_goaccess.conf delete mode 100644 virtual/packages/tt-rss.json delete mode 100644 virtual/packages/ttrss-af-feedmod_type_replace.patch delete mode 100644 virtual/packages/ttrss-af_feedmod.json delete mode 100644 virtual/packages/ttrss-auth-ldap.json delete mode 100644 virtual/packages/ttrss-feediron.json delete mode 100644 virtual/packages/ttrss-feediron_json_reformat.patch delete mode 100644 virtual/packages/ttrss-ff_instagram.json delete mode 100644 virtual/packages/ttrss-tumblr_gdpr_ua.json delete mode 100644 virtual/packages/ttrss.nix delete mode 100644 virtual/packages/ympd.nix diff --git a/virtual/eldiron.nix b/virtual/eldiron.nix index cefef70..0970521 100644 --- a/virtual/eldiron.nix +++ b/virtual/eldiron.nix @@ -9,11 +9,6 @@ # rsync -e "ssh -i /root/.ssh/id_charon_vpn" -aAXvz --delete --numeric-ids --super --rsync-path="sudo rsync" /var/lib/* immae@immae.eu: eldiron = { config, pkgs, mylibs, myconfig, ... }: with mylibs; - let - mypkgs = pkgs.callPackage ./packages.nix { - inherit checkEnv fetchedGit fetchedGithub; - }; - in { _module.args = { mylibs = import ../libs.nix; @@ -28,22 +23,20 @@ imports = [ ./modules/certificates.nix - ./modules/gitolite.nix - ./modules/gitweb - ./modules/databases.nix + ./modules/gitolite + ./modules/databases ./modules/websites - ./modules/websites/phpfpm ]; services.myGitolite.enable = true; - services.myGitweb.enable = true; services.myDatabases.enable = true; services.myWebsites.production.enable = true; services.myWebsites.integration.enable = true; + services.myWebsites.tools.enable = true; networking = { firewall = { enable = true; - allowedTCPPorts = [ 22 9418 ]; + allowedTCPPorts = [ 22 ]; }; }; @@ -67,74 +60,17 @@ }; }; - environment.systemPackages = let - # FIXME: move it to nextcloud - occ = pkgs.writeScriptBin "nextcloud-occ" '' - #! ${pkgs.stdenv.shell} - cd ${mypkgs.nextcloud.webRoot} - NEXTCLOUD_CONFIG_DIR="${mypkgs.nextcloud.webRoot}/config" \ - exec \ - ${pkgs.php}/bin/php \ - -c ${pkgs.php}/etc/php.ini \ - occ $* - ''; - in [ + environment.systemPackages = [ pkgs.telnet pkgs.htop pkgs.vim - occ ]; - security.acme.certs."eldiron".extraDomains = { - "db-1.immae.eu" = null; - "tools.immae.eu" = null; - "cloud.immae.eu" = null; - "dav.immae.eu" = null; - }; - services.openssh.extraConfig = '' AuthorizedKeysCommand /etc/ssh/ldap_authorized_keys AuthorizedKeysCommandUser nobody ''; - services.ympd = mypkgs.ympd.config // { enable = false; }; - - services.myPhpfpm = { - phpPackage = pkgs.php; - phpOptions = '' - session.save_path = "/var/lib/php/sessions" - session.gc_maxlifetime = 60*60*24*15 - session.cache_expire = 60*24*30 - ''; - extraConfig = '' - log_level = notice - ''; - poolPhpConfigs = { - nextcloud = mypkgs.nextcloud.phpFpm.phpConfig; - }; - poolConfigs = { - adminer = mypkgs.adminer.phpFpm.pool; - nextcloud = mypkgs.nextcloud.phpFpm.pool; - mantisbt = mypkgs.mantisbt.phpFpm.pool; - ttrss = mypkgs.ttrss.phpFpm.pool; - roundcubemail = mypkgs.roundcubemail.phpFpm.pool; - davical = mypkgs.davical.phpFpm.pool; - }; - }; - - system.activationScripts = { - nextcloud = mypkgs.nextcloud.activationScript; - ttrss = mypkgs.ttrss.activationScript; - roundcubemail = mypkgs.roundcubemail.activationScript; - httpd = '' - install -d -m 0755 /var/lib/acme/acme-challenge - install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions - install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions/adminer - install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions/mantisbt - install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions/davical - ''; - }; - environment.etc."ssh/ldap_authorized_keys" = let ldap_authorized_keys = assert checkEnv "NIXOPS_SSHD_LDAP_PASSWORD"; @@ -155,19 +91,5 @@ source = ldap_authorized_keys; }; - systemd.services.tt-rss = { - description = "Tiny Tiny RSS feeds update daemon"; - serviceConfig = { - User = "wwwrun"; - ExecStart = "${pkgs.php}/bin/php ${mypkgs.ttrss.webRoot}/update.php --daemon"; - StandardOutput = "syslog"; - StandardError = "syslog"; - PermissionsStartOnly = true; - }; - - wantedBy = [ "multi-user.target" ]; - requires = ["postgresql.service"]; - after = ["network.target" "postgresql.service"]; - }; }; } diff --git a/virtual/modules/databases.nix b/virtual/modules/databases.nix deleted file mode 100644 index de4ace6..0000000 --- a/virtual/modules/databases.nix +++ /dev/null @@ -1,180 +0,0 @@ -{ lib, pkgs, config, mylibs, ... }: -let - cfg = config.services.myDatabases; -in { - options.services.myDatabases = { - enable = lib.mkEnableOption "my databases service"; - postgresql = { - enable = lib.mkOption { - default = cfg.enable; - example = true; - description = "Whether to enable postgresql database"; - type = lib.types.bool; - }; - }; - - mariadb = { - enable = lib.mkOption { - default = cfg.enable; - example = true; - description = "Whether to enable mariadb database"; - type = lib.types.bool; - }; - }; - - redis = { - enable = lib.mkOption { - default = cfg.enable; - example = true; - description = "Whether to enable redis database"; - type = lib.types.bool; - }; - }; - }; - - config = lib.mkIf cfg.enable { - nixpkgs.config.packageOverrides = oldpkgs: rec { - postgresql = postgresql111; - postgresql111 = oldpkgs.postgresql100.overrideAttrs(old: rec { - passthru = old.passthru // { psqlSchema = "11.0"; }; - name = "postgresql-11.1"; - src = pkgs.fetchurl { - url = "mirror://postgresql/source/v11.1/${name}.tar.bz2"; - sha256 = "026v0sicsh7avzi45waf8shcbhivyxmi7qgn9fd1x0vl520mx0ch"; - }; - configureFlags = old.configureFlags ++ [ "--with-pam" ]; - buildInputs = (old.buildInputs or []) ++ [ pkgs.pam ]; - patches = old.patches ++ [ - ./postgresql_run_socket_path.patch - ]; - }); - mariadb = mariadbPAM; - mariadbPAM = oldpkgs.mariadb.overrideAttrs(old: rec { - cmakeFlags = old.cmakeFlags ++ [ "-DWITH_AUTHENTICATION_PAM=ON" ]; - buildInputs = old.buildInputs ++ [ pkgs.pam ]; - }); - }; - - networking.firewall.allowedTCPPorts = [ 3306 5432 ]; - - # FIXME: initial sync - # FIXME: backup - # FIXME: restart after pam - # FIXME: pam access doesn’t work (because of php module) - # FIXME: ssl - services.mysql = rec { - enable = cfg.mariadb.enable; - package = pkgs.mariadb; - }; - - # Cannot use eldiron: psql complains too much rights on the key, and - # setfacl cannot work properly because of acme prestart script - security.acme.certs."postgresql" = config.services.myCertificates.certConfig // { - user = "postgres"; - group = "postgres"; - plugins = [ "fullchain.pem" "key.pem" "account_key.json" ]; - domain = "db-1.immae.eu"; - postRun = '' - systemctl reload postgresql.service - ''; - }; - - system.activationScripts.postgresql = '' - install -m 0755 -o postgres -g postgres -d /run/postgresql - ''; - - # FIXME: initial sync - services.postgresql = rec { - enable = cfg.postgresql.enable; - package = pkgs.postgresql; - enableTCPIP = true; - extraConfig = '' - max_connections = 100 - wal_level = logical - shared_buffers = 128MB - max_wal_size = 1GB - min_wal_size = 80MB - log_timezone = 'Europe/Paris' - datestyle = 'iso, mdy' - timezone = 'Europe/Paris' - lc_messages = 'en_US.UTF-8' - lc_monetary = 'en_US.UTF-8' - lc_numeric = 'en_US.UTF-8' - lc_time = 'en_US.UTF-8' - default_text_search_config = 'pg_catalog.english' - ssl = on - ssl_cert_file = '/var/lib/acme/postgresql/fullchain.pem' - ssl_key_file = '/var/lib/acme/postgresql/key.pem' - ''; - authentication = '' - local all postgres ident - local all all md5 - hostssl all all samehost md5 - hostssl all all 178.33.252.96/32 md5 - hostssl all all 188.165.209.148/32 md5 - hostssl all all all pam - hostssl replication backup-1 2001:41d0:302:1100::9:e5a9/128 pam pamservice=postgresql_replication - hostssl replication backup-1 54.37.151.137/32 pam pamservice=postgresql_replication - ''; - }; - - security.pam.services = let - pam_ldap = pkgs.pam_ldap; - pam_ldap_mysql = assert mylibs.checkEnv "NIXOPS_MYSQL_PAM_PASSWORD"; - pkgs.writeText "mysql.conf" '' - host ldap.immae.eu - base dc=immae,dc=eu - binddn cn=mysql,cn=pam,ou=services,dc=immae,dc=eu - bindpw ${builtins.getEnv "NIXOPS_MYSQL_PAM_PASSWORD"} - pam_filter memberOf=cn=users,cn=mysql,cn=pam,ou=services,dc=immae,dc=eu - ''; - pam_ldap_postgresql_replication = assert mylibs.checkEnv "NIXOPS_ELDIRON_LDAP_PASSWORD"; - pkgs.writeText "postgresql.conf" '' - host ldap.immae.eu - base dc=immae,dc=eu - binddn cn=eldiron,ou=hosts,dc=immae,dc=eu - bindpw ${builtins.getEnv "NIXOPS_ELDIRON_LDAP_PASSWORD"} - pam_login_attribute cn - ''; - in [ - { - name = "mysql"; - text = '' - # https://mariadb.com/kb/en/mariadb/pam-authentication-plugin/ - auth required ${pam_ldap}/lib/security/pam_ldap.so config=${pam_ldap_mysql} - account required ${pam_ldap}/lib/security/pam_ldap.so config=${pam_ldap_mysql} - ''; - } - { - name = "postgresql"; - text = '' - auth required ${pam_ldap}/lib/security/pam_ldap.so config=${pam_ldap_postgresql_replication} - account required ${pam_ldap}/lib/security/pam_ldap.so config=${pam_ldap_postgresql_replication} - ''; - } - { - name = "postgresql_replication"; - text = '' - auth required ${pam_ldap}/lib/security/pam_ldap.so config=${pam_ldap_postgresql_replication} - account required ${pam_ldap}/lib/security/pam_ldap.so config=${pam_ldap_postgresql_replication} - ''; - } - ]; - - # FIXME: backup - # Nextcloud: 14 - services.redis = rec { - enable = config.services.myDatabases.redis.enable; - bind = "127.0.0.1"; - unixSocket = "/run/redis/redis.sock"; - extraConfig = '' - unixsocketperm 777 - maxclients 1024 - ''; - }; - system.activationScripts.redis = '' - mkdir -p /run/redis - chown redis /run/redis - ''; - }; -} diff --git a/virtual/modules/databases/default.nix b/virtual/modules/databases/default.nix new file mode 100644 index 0000000..de4ace6 --- /dev/null +++ b/virtual/modules/databases/default.nix @@ -0,0 +1,180 @@ +{ lib, pkgs, config, mylibs, ... }: +let + cfg = config.services.myDatabases; +in { + options.services.myDatabases = { + enable = lib.mkEnableOption "my databases service"; + postgresql = { + enable = lib.mkOption { + default = cfg.enable; + example = true; + description = "Whether to enable postgresql database"; + type = lib.types.bool; + }; + }; + + mariadb = { + enable = lib.mkOption { + default = cfg.enable; + example = true; + description = "Whether to enable mariadb database"; + type = lib.types.bool; + }; + }; + + redis = { + enable = lib.mkOption { + default = cfg.enable; + example = true; + description = "Whether to enable redis database"; + type = lib.types.bool; + }; + }; + }; + + config = lib.mkIf cfg.enable { + nixpkgs.config.packageOverrides = oldpkgs: rec { + postgresql = postgresql111; + postgresql111 = oldpkgs.postgresql100.overrideAttrs(old: rec { + passthru = old.passthru // { psqlSchema = "11.0"; }; + name = "postgresql-11.1"; + src = pkgs.fetchurl { + url = "mirror://postgresql/source/v11.1/${name}.tar.bz2"; + sha256 = "026v0sicsh7avzi45waf8shcbhivyxmi7qgn9fd1x0vl520mx0ch"; + }; + configureFlags = old.configureFlags ++ [ "--with-pam" ]; + buildInputs = (old.buildInputs or []) ++ [ pkgs.pam ]; + patches = old.patches ++ [ + ./postgresql_run_socket_path.patch + ]; + }); + mariadb = mariadbPAM; + mariadbPAM = oldpkgs.mariadb.overrideAttrs(old: rec { + cmakeFlags = old.cmakeFlags ++ [ "-DWITH_AUTHENTICATION_PAM=ON" ]; + buildInputs = old.buildInputs ++ [ pkgs.pam ]; + }); + }; + + networking.firewall.allowedTCPPorts = [ 3306 5432 ]; + + # FIXME: initial sync + # FIXME: backup + # FIXME: restart after pam + # FIXME: pam access doesn’t work (because of php module) + # FIXME: ssl + services.mysql = rec { + enable = cfg.mariadb.enable; + package = pkgs.mariadb; + }; + + # Cannot use eldiron: psql complains too much rights on the key, and + # setfacl cannot work properly because of acme prestart script + security.acme.certs."postgresql" = config.services.myCertificates.certConfig // { + user = "postgres"; + group = "postgres"; + plugins = [ "fullchain.pem" "key.pem" "account_key.json" ]; + domain = "db-1.immae.eu"; + postRun = '' + systemctl reload postgresql.service + ''; + }; + + system.activationScripts.postgresql = '' + install -m 0755 -o postgres -g postgres -d /run/postgresql + ''; + + # FIXME: initial sync + services.postgresql = rec { + enable = cfg.postgresql.enable; + package = pkgs.postgresql; + enableTCPIP = true; + extraConfig = '' + max_connections = 100 + wal_level = logical + shared_buffers = 128MB + max_wal_size = 1GB + min_wal_size = 80MB + log_timezone = 'Europe/Paris' + datestyle = 'iso, mdy' + timezone = 'Europe/Paris' + lc_messages = 'en_US.UTF-8' + lc_monetary = 'en_US.UTF-8' + lc_numeric = 'en_US.UTF-8' + lc_time = 'en_US.UTF-8' + default_text_search_config = 'pg_catalog.english' + ssl = on + ssl_cert_file = '/var/lib/acme/postgresql/fullchain.pem' + ssl_key_file = '/var/lib/acme/postgresql/key.pem' + ''; + authentication = '' + local all postgres ident + local all all md5 + hostssl all all samehost md5 + hostssl all all 178.33.252.96/32 md5 + hostssl all all 188.165.209.148/32 md5 + hostssl all all all pam + hostssl replication backup-1 2001:41d0:302:1100::9:e5a9/128 pam pamservice=postgresql_replication + hostssl replication backup-1 54.37.151.137/32 pam pamservice=postgresql_replication + ''; + }; + + security.pam.services = let + pam_ldap = pkgs.pam_ldap; + pam_ldap_mysql = assert mylibs.checkEnv "NIXOPS_MYSQL_PAM_PASSWORD"; + pkgs.writeText "mysql.conf" '' + host ldap.immae.eu + base dc=immae,dc=eu + binddn cn=mysql,cn=pam,ou=services,dc=immae,dc=eu + bindpw ${builtins.getEnv "NIXOPS_MYSQL_PAM_PASSWORD"} + pam_filter memberOf=cn=users,cn=mysql,cn=pam,ou=services,dc=immae,dc=eu + ''; + pam_ldap_postgresql_replication = assert mylibs.checkEnv "NIXOPS_ELDIRON_LDAP_PASSWORD"; + pkgs.writeText "postgresql.conf" '' + host ldap.immae.eu + base dc=immae,dc=eu + binddn cn=eldiron,ou=hosts,dc=immae,dc=eu + bindpw ${builtins.getEnv "NIXOPS_ELDIRON_LDAP_PASSWORD"} + pam_login_attribute cn + ''; + in [ + { + name = "mysql"; + text = '' + # https://mariadb.com/kb/en/mariadb/pam-authentication-plugin/ + auth required ${pam_ldap}/lib/security/pam_ldap.so config=${pam_ldap_mysql} + account required ${pam_ldap}/lib/security/pam_ldap.so config=${pam_ldap_mysql} + ''; + } + { + name = "postgresql"; + text = '' + auth required ${pam_ldap}/lib/security/pam_ldap.so config=${pam_ldap_postgresql_replication} + account required ${pam_ldap}/lib/security/pam_ldap.so config=${pam_ldap_postgresql_replication} + ''; + } + { + name = "postgresql_replication"; + text = '' + auth required ${pam_ldap}/lib/security/pam_ldap.so config=${pam_ldap_postgresql_replication} + account required ${pam_ldap}/lib/security/pam_ldap.so config=${pam_ldap_postgresql_replication} + ''; + } + ]; + + # FIXME: backup + # Nextcloud: 14 + services.redis = rec { + enable = config.services.myDatabases.redis.enable; + bind = "127.0.0.1"; + unixSocket = "/run/redis/redis.sock"; + extraConfig = '' + unixsocketperm 777 + maxclients 1024 + ''; + }; + system.activationScripts.redis = '' + mkdir -p /run/redis + chown redis /run/redis + ''; + }; +} diff --git a/virtual/modules/databases/postgresql_run_socket_path.patch b/virtual/modules/databases/postgresql_run_socket_path.patch new file mode 100644 index 0000000..b558c7b --- /dev/null +++ b/virtual/modules/databases/postgresql_run_socket_path.patch @@ -0,0 +1,12 @@ +diff -Naur postgresql-9.2.0.sockets/src/include/pg_config_manual.h postgresql-9.2.0/src/include/pg_config_manual.h +--- postgresql-9.2.0.sockets/src/include/pg_config_manual.h 2012-09-06 17:26:17.000000000 -0400 ++++ postgresql-9.2.0/src/include/pg_config_manual.h 2012-09-06 18:13:18.183092471 -0400 +@@ -144,7 +144,7 @@ + * here's where to twiddle it. You can also override this at runtime + * with the postmaster's -k switch. + */ +-#define DEFAULT_PGSOCKET_DIR "/tmp" ++#define DEFAULT_PGSOCKET_DIR "/run/postgresql" + + /* + * The random() function is expected to yield values between 0 and diff --git a/virtual/modules/gitolite.nix b/virtual/modules/gitolite.nix deleted file mode 100644 index d6b9c79..0000000 --- a/virtual/modules/gitolite.nix +++ /dev/null @@ -1,84 +0,0 @@ -{ lib, pkgs, config, mylibs, ... }: -let - cfg = config.services.myGitolite; -in { - options.services.myGitolite = { - enable = lib.mkEnableOption "my gitolite service"; - gitoliteDir = lib.mkOption { - type = lib.types.string; - default = "/var/lib/gitolite"; - }; - }; - - config = lib.mkIf cfg.enable { - nixpkgs.config.packageOverrides = oldpkgs: rec { - gitolite = oldpkgs.gitolite.overrideAttrs(old: rec { - name = "gitolite-${version}"; - version = "3.6.10"; - src = pkgs.fetchFromGitHub { - owner = "sitaramc"; - repo = "gitolite"; - rev = "v${version}"; - sha256 = "0p2697mn6rwm03ndlv7q137zczai82n41aplq1g006ii7f12xy8h"; - }; - }); - }; - - services.gitDaemon = { - enable = true; - user = "gitolite"; - group = "gitolite"; - basePath = "${cfg.gitoliteDir}/repositories"; - }; - - system.activationScripts.gitolite = - assert mylibs.checkEnv "NIXOPS_GITOLITE_LDAP_PASSWORD"; - let - gitolite_ldap_groups = mylibs.wrap { - name = "gitolite_ldap_groups.sh"; - file = ./gitolite/gitolite_ldap_groups.sh; - vars = { - LDAP_PASS = builtins.getEnv "NIXOPS_GITOLITE_LDAP_PASSWORD"; - }; - paths = [ pkgs.openldap pkgs.stdenv.shellPackage pkgs.gnugrep pkgs.coreutils ]; - }; - in { - deps = [ "users" ]; - text = '' - if [ -d ${cfg.gitoliteDir} ]; then - ln -sf ${gitolite_ldap_groups} ${cfg.gitoliteDir}/gitolite_ldap_groups.sh - chmod g+rx ${cfg.gitoliteDir} - fi - if [ -f ${cfg.gitoliteDir}/projects.list ]; then - chmod g+r ${cfg.gitoliteDir}/projects.list - fi - ''; - }; - - users.users.wwwrun.extraGroups = [ "gitolite" ]; - - users.users.gitolite.packages = let - python-packages = python-packages: with python-packages; [ - simplejson - urllib3 - ]; - in - [ - (pkgs.python3.withPackages python-packages) - ]; - # FIXME: after initial install, need to - # (1) copy rc file (adjust gitolite_ldap_groups.sh) - # (2) (mark old readonly and) sync repos except gitolite-admin - # rsync -av --exclude=gitolite-admin.git old:/var/lib/gitolite/repositories /var/lib/gitolite/ - # chown -R gitolite:gitolite /var/lib/gitolite - # (3) push force the gitolite-admin to new location (from external point) - # Don't use an existing key, it will take precedence over - # gitolite-admin - # (4) su -u gitolite gitolite setup - services.gitolite = { - enable = true; - # FIXME: key from ./ssh - adminPubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDXqRbiHw7QoHADNIEuo4nUT9fSOIEBMdJZH0bkQAxXyJFyCM1IMz0pxsHV0wu9tdkkr36bPEUj2aV5bkYLBN6nxcV2Y49X8bjOSCPfx3n6Own1h+NeZVBj4ZByrFmqCbTxUJIZ2bZKcWOFncML39VmWdsVhNjg0X4NBBehqXRIKr2gt3E/ESAxTYJFm0BnU0baciw9cN0bsRGqvFgf5h2P48CIAfwhVcGmPQnnAwabnosYQzRWxR0OygH5Kd8mePh6FheIRIigfXsDO8f/jdxwut8buvNIf3m5EBr3tUbTsvM+eV3M5vKGt7sk8T64DVtepTSdOOWtp+47ktsnHOMh immae@immae.eu"; - }; - }; -} diff --git a/virtual/modules/gitolite/default.nix b/virtual/modules/gitolite/default.nix new file mode 100644 index 0000000..78691fa --- /dev/null +++ b/virtual/modules/gitolite/default.nix @@ -0,0 +1,86 @@ +{ lib, pkgs, config, mylibs, ... }: +let + cfg = config.services.myGitolite; +in { + options.services.myGitolite = { + enable = lib.mkEnableOption "my gitolite service"; + gitoliteDir = lib.mkOption { + type = lib.types.string; + default = "/var/lib/gitolite"; + }; + }; + + config = lib.mkIf cfg.enable { + nixpkgs.config.packageOverrides = oldpkgs: rec { + gitolite = oldpkgs.gitolite.overrideAttrs(old: rec { + name = "gitolite-${version}"; + version = "3.6.10"; + src = pkgs.fetchFromGitHub { + owner = "sitaramc"; + repo = "gitolite"; + rev = "v${version}"; + sha256 = "0p2697mn6rwm03ndlv7q137zczai82n41aplq1g006ii7f12xy8h"; + }; + }); + }; + + networking.firewall.allowedTCPPorts = [ 9418 ]; + + services.gitDaemon = { + enable = true; + user = "gitolite"; + group = "gitolite"; + basePath = "${cfg.gitoliteDir}/repositories"; + }; + + system.activationScripts.gitolite = + assert mylibs.checkEnv "NIXOPS_GITOLITE_LDAP_PASSWORD"; + let + gitolite_ldap_groups = mylibs.wrap { + name = "gitolite_ldap_groups.sh"; + file = ./gitolite_ldap_groups.sh; + vars = { + LDAP_PASS = builtins.getEnv "NIXOPS_GITOLITE_LDAP_PASSWORD"; + }; + paths = [ pkgs.openldap pkgs.stdenv.shellPackage pkgs.gnugrep pkgs.coreutils ]; + }; + in { + deps = [ "users" ]; + text = '' + if [ -d ${cfg.gitoliteDir} ]; then + ln -sf ${gitolite_ldap_groups} ${cfg.gitoliteDir}/gitolite_ldap_groups.sh + chmod g+rx ${cfg.gitoliteDir} + fi + if [ -f ${cfg.gitoliteDir}/projects.list ]; then + chmod g+r ${cfg.gitoliteDir}/projects.list + fi + ''; + }; + + users.users.wwwrun.extraGroups = [ "gitolite" ]; + + users.users.gitolite.packages = let + python-packages = python-packages: with python-packages; [ + simplejson + urllib3 + ]; + in + [ + (pkgs.python3.withPackages python-packages) + ]; + # FIXME: after initial install, need to + # (1) copy rc file (adjust gitolite_ldap_groups.sh) + # (2) (mark old readonly and) sync repos except gitolite-admin + # rsync -av --exclude=gitolite-admin.git old:/var/lib/gitolite/repositories /var/lib/gitolite/ + # chown -R gitolite:gitolite /var/lib/gitolite + # (3) push force the gitolite-admin to new location (from external point) + # Don't use an existing key, it will take precedence over + # gitolite-admin + # (4) su -u gitolite gitolite setup + services.gitolite = { + enable = true; + # FIXME: key from ./ssh + adminPubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDXqRbiHw7QoHADNIEuo4nUT9fSOIEBMdJZH0bkQAxXyJFyCM1IMz0pxsHV0wu9tdkkr36bPEUj2aV5bkYLBN6nxcV2Y49X8bjOSCPfx3n6Own1h+NeZVBj4ZByrFmqCbTxUJIZ2bZKcWOFncML39VmWdsVhNjg0X4NBBehqXRIKr2gt3E/ESAxTYJFm0BnU0baciw9cN0bsRGqvFgf5h2P48CIAfwhVcGmPQnnAwabnosYQzRWxR0OygH5Kd8mePh6FheIRIigfXsDO8f/jdxwut8buvNIf3m5EBr3tUbTsvM+eV3M5vKGt7sk8T64DVtepTSdOOWtp+47ktsnHOMh immae@immae.eu"; + }; + }; +} diff --git a/virtual/modules/gitweb/default.nix b/virtual/modules/gitweb/default.nix deleted file mode 100644 index 2a860ba..0000000 --- a/virtual/modules/gitweb/default.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ lib, pkgs, config, mylibs, ... }: -let - # FIXME: add buildbot - gitweb = pkgs.callPackage ./gitweb.nix { gitoliteDir = config.services.myGitolite.gitoliteDir; }; - cfg = config.services.myGitweb; -in { - options.services.myGitweb = { - enable = lib.mkEnableOption "my gitweb service"; - }; - - config = lib.mkIf cfg.enable { - security.acme.certs."eldiron".extraDomains."git.immae.eu" = null; - - nixpkgs.config.packageOverrides = oldpkgs: rec { - gitweb = oldpkgs.gitweb.overrideAttrs(old: { - installPhase = old.installPhase + '' - cp -r ${./theme} $out/gitweb-theme; - ''; - }); - }; - - services.myWebsites.tools.modules = gitweb.apache.modules; - services.myWebsites.tools.vhostConfs.git = { - certName = "eldiron"; - hosts = ["git.immae.eu" ]; - root = gitweb.webRoot; - extraConfig = [ gitweb.apache.vhostConf ]; - }; - }; -} diff --git a/virtual/modules/gitweb/gitweb.nix b/virtual/modules/gitweb/gitweb.nix deleted file mode 100644 index 7b4dcac..0000000 --- a/virtual/modules/gitweb/gitweb.nix +++ /dev/null @@ -1,64 +0,0 @@ -{ gitweb, writeText, gitolite, git, gitoliteDir }: -rec { - varDir = gitoliteDir; - webRoot = gitweb; - config = writeText "gitweb.conf" '' - $git_temp = "/tmp"; - - # The directories where your projects are. Must not end with a - # slash. - $projectroot = "${varDir}/repositories"; - - $projects_list = "${varDir}/projects.list"; - $strict_export = "true"; - - # Base URLs for links displayed in the web interface. - our @git_base_url_list = qw(ssh://gitolite@git.immae.eu https://git.immae.eu); - - $feature{'blame'}{'default'} = [1]; - $feature{'avatar'}{'default'} = ['gravatar']; - $feature{'highlight'}{'default'} = [1]; - - @stylesheets = ("gitweb-theme/gitweb.css"); - $logo = "gitweb-theme/git-logo.png"; - $favicon = "gitweb-theme/git-favicon.png"; - $javascript = "gitweb-theme/gitweb.js"; - $logo_url = "https://git.immae.eu/"; - $projects_list_group_categories = "true"; - $projects_list_description_width = 60; - $project_list_default_category = "__Others__"; - ''; - apache = { - user = "wwwrun"; - group = "wwwrun"; - modules = [ "cgid" ]; - vhostConf = '' - SetEnv GIT_PROJECT_ROOT ${varDir}/repositories/ - ScriptAliasMatch \ - "(?x)^/(.*/(HEAD | \ - info/refs | \ - objects/(info/[^/]+ | \ - [0-9a-f]{2}/[0-9a-f]{38} | \ - pack/pack-[0-9a-f]{40}\.(pack|idx)) | \ - git-(upload|receive)-pack))$" \ - ${git}/libexec/git-core/git-http-backend/$1 - - - Require all granted - - - Require all granted - - - DirectoryIndex gitweb.cgi - Require all granted - AllowOverride None - Options ExecCGI FollowSymLinks - - SetHandler cgi-script - SetEnv GITWEB_CONFIG "${config}" - - - ''; - }; -} diff --git a/virtual/modules/gitweb/theme/git-favicon.png b/virtual/modules/gitweb/theme/git-favicon.png deleted file mode 100644 index 4fa44bb..0000000 Binary files a/virtual/modules/gitweb/theme/git-favicon.png and /dev/null differ diff --git a/virtual/modules/gitweb/theme/git-logo.png b/virtual/modules/gitweb/theme/git-logo.png deleted file mode 100644 index fdaf7b7..0000000 Binary files a/virtual/modules/gitweb/theme/git-logo.png and /dev/null differ diff --git a/virtual/modules/gitweb/theme/gitweb.css b/virtual/modules/gitweb/theme/gitweb.css deleted file mode 100644 index 83e0742..0000000 --- a/virtual/modules/gitweb/theme/gitweb.css +++ /dev/null @@ -1,783 +0,0 @@ -/* Reset -------------------------------------------------------------------------- */ - -/* Based on http://meyerweb.com/eric/tools/css/reset/ */ -/* v1.0 | 20080212 */ - -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, -blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, -font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, -u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, -caption, tbody, tfoot, thead, tr, th, td { - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; - vertical-align: baseline; - background: transparent; -} - -ol, ul { list-style: none; } - -blockquote, q { quotes: none; } - -blockquote:before, blockquote:after, -q:before, q:after { - content: ''; - content: none; -} - -:focus { outline: 0; } - -ins { text-decoration: none; } - -del { text-decoration: line-through; } - -table { - border-collapse: collapse; - border-spacing: 0; -} - -a { outline: none; } - -/* General ----------------------------------------------------------------------------- */ - -html { - position: relative; - min-height: 100%; -} - -body { - font: 13px Helvetica,arial,freesans,clean,sans-serif; - line-height: 1.4; - margin: 0 0 105px; - background-color: #fff; - color: #000000; -} - -/* Monospaced Fonts */ -.sha1, .mode, .diff_tree .list, .pre, .diff, .patchset { - font-family: 'Consolas','Bitstream Vera Sans Mono',monospace; -} - -a:link, a:visited { - color: #4183C4; - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - -td.list a[href*='tree'], td.list a[href*='blob'] { - padding-left: 20px; - display: block; - float: left; - height: 16px; - line-height: 16px; -} - -td.list a[href*='tree'] { - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABq0lEQVQ4y8WTu4oUQRSGv+rtGVuxhwVFdFEEE2c3d0HYTEMTn8DEVxADQTDUF9DMwMxQMBMx8AEWzRQ3cBHd9TI91+2urjq/QbczY2IygSep4nD+79yqnCRWsYQVbWVACvDh5ZXdrLe15dwyT1TjT/sxFFeB6i+VA2B6+cb7kAI4Jf0LO087zjlQI8Y5Qvnj0sHug321XoC1bk+K9eHk6+s7wPMUgKAS88eqb4+Jfg2SHs7lZBvX2Nh+2EUCDGSAcMnJsx9f7NxfAGqXyDzRd5EJO/pMPT1gcviGTnYOVIN5pAAE8v7dLrKL8xnglFk4ws9Afko9HpH3b5Gd2mwb/lOBmgrSdYhJugDUCenxM6xv3p4HCsP8F0LxCsUhCkMURihOyM7fg0osASTFEpu9a4LjGIUCqwcoDiEUrX+E4hRUQb20RiokC1j9vckUhygU7X3QZh7NAVKYL7YBeMkRUfjVCotF2XGIwnghtrJpMywB5G0QZj9P1JNujuWJ1AHLQadRrACPkuZ0SSSWpeStWgDK6tHek5vbiOs48n++XQHurcf0rFng//6NvwG+iB9/4duaTgAAAABJRU5ErkJgggo=) center left no-repeat; -} - -td.list a[href*='blob'] { - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAA6ElEQVQoFQXBMW5TQRgGwNnHnoE0QbiCjoIooUmTU3AuS1BwIoTSUdJBigg3GCWOg9/++zHTop078wIAsPMrE4SL5/1aIyMjIyMjz/m0tbFECFdrPeaQQw75mz/5nZH7fN7aWILmauSYfznmmIfss8vIUx7zZWsTTXM5vpWvTk5Wq9VHQP/gtgOLa0Qpw940vAQdaG6thpOhlOkG0AEuAVGmEkAH+G4YSikxXQM6wDsAMRFAB/ihDNNUmN4DOsAbBAEAdICfpmmaAt4COoj2GgCASbIkZh1NAACznhQt2itnFgAAlF3u/gMDtJXPzQxoswAAAABJRU5ErkJgggo=) center left no-repeat; -} - -i { - font-style: normal; -} - -td, th { - padding: 5px; -} - -.page_nav br { - display: none; -} - -/* Page Header ----------------------------------------------------------------------------- */ - -.page_header { - height: 50px; - line-height: 50px; - position: relative; - padding: 0 27px; - margin-bottom: 20px; - font-size: 20px; - font-family: Helvetica, Arial, Freesans, Clean, sans-serif; - background: #FFFFFF; /* old browsers */ - background: -moz-linear-gradient(top, #FFFFFF 0%, #F5F5F5 100%); /* firefox */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FFFFFF), color-stop(100%,#F5F5F5)); /* webkit */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FFFFFF', endColorstr='#F5F5F5',GradientType=0 ); /* ie */ - background: -o-linear-gradient(top, #FFFFFF 0%, #F5F5F5 100%); - border-bottom: 1px solid #dfdfdf; -} - -.page_header a:link, .page_header a:visited { - color: #4183C4; - text-decoration: none; - padding: 3px; - font-weight: bold; -} - -.page_header a:hover { - font-weight: bold; - padding: 3px; - text-decoration: underline; -} - -.page_header a:first-child { - background: transparent; -} - -.page_header img.logo { - position: relative; - top: 7px; - margin-right: 5px; -} - -/* Page Footer ----------------------------------------------------------------------------- */ - -.page_footer { - position: absolute; - left: 0; - bottom: 0; - width: 100%; - height: 80px; - line-height: 80px; - margin-top: 15px; - background: #f1f1f1; - border-top: 2px solid #ddd; - border-bottom: 1px solid #ddd; -} - -.page_footer_text { - color: #666; - display: inline; - float: left; - margin-left: 25px; - width: 80%; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} - -a.rss_logo { - float: right; - padding: 3px 1px; - width: 35px; - line-height: 10px; - border: 1px solid; - border-color: #fcc7a5 #7d3302 #3e1a01 #ff954e; - color: #ffffff; - background-color: #ff6600; - font-weight: bold; - font-family: sans-serif; - font-size: 80%; - text-align: center; - text-decoration: none; - margin-top: 30px; - margin-left: 5px; -} - -a.rss_logo:hover { - background-color: #ee5500; -} - -.rss_logo { - margin-right: 25px; - background: yellow; -} - -.rss_logo:last-child { - margin-right: 5px; -} - -/* Index include ----------------------------------------------------------------------------- */ - -.index_include { - width: 95%; - margin: 0 auto 15px; - background: -moz-linear-gradient(center top , #FFFFFF 0%, #F5F5F5 100%) repeat scroll 0 0 transparent; - border: 1px solid #DFDFDF; - padding: 8px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -/* Elements ----------------------------------------------------------------------------- */ - -.project_list, -.shortlog, -.tree, -.commit_search, -.history { - width: 95%; - margin: 0 auto 15px auto; - border: 1px solid #d8d8d8; - -moz-box-shadow: 0 0 3px rgba(0,0,0,0.2); - -webkit-box-shadow: 0 0 3px rgba(0,0,0,0.2); - box-shadow: 0 0 3px rgba(0,0,0,0.2); -} - -.project_list th, -.shortlog th, -.tree th, -.commit_search th { - color: #afafaf; - font-weight: normal; -} - -.project_list th { - font-weight: bold; -} - -.project_list tr, -.shortlog tr, -.tree tr, -.commit_search tr { - background: #eaeaea; - height: 2.5em; - text-align: left; - color: #545454; -} - -.project_list tr.dark, .project_list tr.light, -.shortlog tr.dark, .shortlog tr.light, -.tree tr.dark, .tree tr.light, -.commit_search tr.dark, .commit_search tr.light, -.history tr.dark, .history tr.light, -.heads tr.dark, .heads tr.light { - background: #F9F9F9; /* old browsers */ - background: -moz-linear-gradient(top, #F9F9F9 0%, #EFEFEF 100%); /* firefox */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#F9F9F9), color-stop(100%,#EFEFEF)); /* webkit */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#F9F9F9', endColorstr='#EFEFEF',GradientType=0 ); /* ie */ - background: -o-linear-gradient(top, #F9F9F9 0%, #EFEFEF 100%); - height: 2.5em; - border-bottom: 1px solid #e1e1e1; -} - -th .header { - background: transparent; - border: 0; - padding: 0; - font-weight: bold; -} - -.tree { - width: 100%; - margin: 0; -} - -.projsearch { - position: absolute; - right: 4%; - top: 15px; -} - -.projsearch a { - display: none; -} - -.commit_search { - background: #eaeaea; -} - -.page_nav, -.list_head, -.page_path, -.search { - width: 94%; - background: #eaeaea; - color: #545454; - border: 1px solid #d8d8d8; - padding: 5px; - margin: 0 auto 15px auto; -} - -.history { - background: #eaeaea; -} - -.title { - margin: 0 auto 15px auto; - padding: 5px; - width: 95%; -} - -.readme { - background: #eaf2f5; - border: 1px solid #bedce7; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - margin: 0 auto 15px auto; - padding: 15px; - width: 95%; -} - -.readme h1 { - display: block; - font-size: 2em; - font-weight: bold; - margin-bottom: 0.67em; - margin-top: 0; -} - -.readme h2 { - font-size: 1.5em; - font-weight: bold; - margin-bottom: 0.83em; -} - - -.readme h3 { - font-size: 1.17em; - font-weight: bold; - margin-bottom: 1em; -} - -.readme p { - margin-bottom: 1em; -} - -.readme ul { - list-style: disc; - margin-bottom: 1em; - margin-left: 1.5em; -} - -.readme ul ul { - margin-bottom: 0; -} - -.readme ol { - list-style: decimal; - margin-bottom: 1em; - margin-left: 1.5em; -} - -.readme ol ol { - margin-bottom: 0; -} - -.readme pre { - font-family: monospace; - margin: 1em 0; - white-space: pre; -} - -.readme tt, .readme code, .readme kbd, .readme samp { - font-family: monospace; -} - -.readme blockquote { - margin: 1em; -} - -.projects_list, -.tags { - width: 95%; - background: #f0f0f0; - color: #545454; - border: 1px solid #d8d8d8; - padding: 5px; - margin: 0 auto 15px auto; -} - -.heads { - width: 95%; - color: #545454; - border: 1px solid #d8d8d8; - padding: 5px; - margin: 0 auto 15px auto; -} - -.header { - width: 94%; - margin: 0 auto 15px auto; - background: #eaf2f5; - border: 1px solid #bedce7; - padding: 5px; -} - -.header .age { - float: left; - color: #000; - font-weight: bold; - width: 10em; -} - -.title_text { - width: 94%; - background: #eaf2f5; - border: 1px solid #bedce7; - padding: 5px; - margin: 0 auto 0 auto; -} - -.log_body { - width: 94%; - background: #eaf2f5; - border: 1px solid #bedce7; - border-top: 0; - padding: 5px; - margin: 0 auto 15px auto; -} - -.page_body { - line-height: 1.4em; - width: 94%; - background: #f8f8f8; - border: 1px solid #d8d8d8; - padding: 5px; - margin: 15px auto 15px auto; -} - -.diff_tree { - width: 95%; - background: #f0f0f0; - border: 1px solid #d8d8d8; - padding: 5px; - margin: 0 auto 15px auto; -} - -.page_body > .list_head { - width: 98.5%; -} - -.page_body > .diff_tree { - width: 99.5%; -} - -.patch > .header { - width: 99%; -} - -.author .avatar, -.author_date .avatar { - position: relative; - top: 3px; -} - -.object_header .avatar { - border: 1px solid #D8D8D8; - float: right; -} - -.object_header td, -.object_header th { - vertical-align: top; -} - -/* Refs ----------------------------------------------------------------------------- */ - -span.refs span { - color: #707070; - display: inline-block; - margin: 0; - background-color: #eee; - border: 1px solid #ccc; - border-radius: 3px; - height: 18px; - padding: 0 6px; - text-overflow: ellipsis; -} - -span.refs span.ref { - color: #707070; - display: inline-block; - margin: 0; - background-color: #c4c4ff; - border: 1px solid #7878ff; - border-radius: 3px; - height: 18px; - padding: 0 6px; - text-overflow: ellipsis; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIKFSUnpolg7AAAAHJQTFRFAAAAVVWqZmbMVVXVYGDgbW3td3fuc3PzdHT0cHD1d3f6dHT6dnb7dHT7dnb8dnb8dnb9d3f9dnb+eHj+d3f+eHj+d3f+d3f+d3f+eHj+d3f+eHj+d3f+eHj+d3f+d3f+eHj+d3f+d3f+d3f+eHj/////V9oQhQAAACR0Uk5TAAIEBQcNDhMVGCotNTZAT217i5CgobvExtjZ4eLr7vP09ff7uqQ6cgAAAAFiS0dEJcMByQ8AAABUSURBVBjTpc43AoAwDENRh95bgNBM1f3PyOpslD++RSJ61YgH5M2IbIkn4GocSR1MZVBL4t2n4FgkbaxI8Sqph041WknZCWAIrcmEUbpf3lNe0N9u59YFYHnZ78gAAAAASUVORK5CYII=); - background-repeat: no-repeat; - padding-left: 18px; -} - -span.refs span.tag { - color: #707070; - display: inline-block; - margin: 0; - background-color: #ffffab; - border: 1px solid #d9d93b; - border-radius: 3px; - height: 18px; - padding: 0 6px; - text-overflow: ellipsis; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIKFSUZZ+h9RwAAAGZQTFRFAAAAtrYkwMBAwMBAx8c4yso11NQ71NQ51dU52Ng71tY519c719c719c62Ng719c719c62Ng72dk62Ng62Ng72Ng72dk62Ng72Ng62dk62dk72dk62Ng62dk72Ng72Ng72dk7////ou/AnQAAACB0Uk5TAAYHCxESLjRCWWlqa4uNkpissbrO19jc3ufs8vf6/f7atAU2AAAAAWJLR0QhxGwNFgAAAF1JREFUGFeNy0cOgCAABVGw94rY5d//lC7omhhn+ZIh5Gf1xPk0Zi5dAABROIQjSU/fsAXhDkCUljAv8jW2wlQpaixpo4Nj+dtatVpjkSJjLNaizRVpvhBCu/4h391jzw1lU12Z7wAAAABJRU5ErkJggg==); - background-repeat: no-repeat; - padding-left: 18px; -} - -span.refs span.head { - color: #707070; - display: inline-block; - margin: 0; - background-color: #c4ffc4; - border: 1px solid #78ff78; - border-radius: 3px; - height: 18px; - padding: 0 6px; - text-overflow: ellipsis; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIKFSYDsafX/gAAAUpJREFUOMvVkjFLA0EQhd/s7l06MSCihbV/wC5/QBDEIFYWprRIIQQJFqKFQi4kUbBQsFSwtrUQLQULUTBFLCzVIgimCXe7z0q5yIWcqfRVwzDzMTNvgL8mSUqWw3JOtFQJdsIwLDYyjdYgkEmkazl2oVtQWk36nn8AYBYASmFpxmizGtnoqO7Vb+M9KglEkASdpWU872nvVCiPRpuTnz2JIHGyqX3d0kZfR1G0Ht+g/do+FIhOBbLW3n/FNb/28D0puZ+dyL44ur1UoH5yzt2JyIj6UGdDgwrPhYzSagNEszJaeU/lWlylbmnaeGZZICsAppxzi6nt73HK85oQCMknOuarpno+FIjglVjZDXaCS2yDv3rIHlCb88FY0BlUl3hs7ektkhckb5DFWhoz+n12zr7ZPLpYUqLm0oBMn8NUzLhpAgjpWMS/1CcSJ3ykD7Rk1QAAAABJRU5ErkJggg==); - background-repeat: no-repeat; - padding-left: 18px; -} - -span.refs a { - color: #4e4e4e; - font: 11px "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, monospace; - line-height: 18px; -} - -/* Diffs ----------------------------------------------------------------------------- */ - -div.diff.to_file a.path, -div.diff.to_file { - color: #007000; -} - -div.diff.from_file a.path, -div.diff.from_file { - color: #aa0000; -} - -.patch .header { - margin: 0; -} - -.patchset { - overflow-x: auto; - overflow-y: hidden; -} - -.chunk_header { - background: #eaf2f5; - color: #999; -} - -.rem { - background: #ffdddd; -} -.rem .marked { - background: #ffaaaa; -} -.add { - background: #ddffdd; -} -.add .marked { - background: #7dff7d; -} - -.extended_header { - width: 99.5%; -} - -div.chunk_block { - overflow: hidden; -} - -div.chunk_block div.old { - float: left; - width: 50%; - overflow: hidden; - border-right: 5px solid #EAF2F5; -} - -div.chunk_block.rem, -div.chunk_block.add { - background: transparent; -} - -div.chunk_block div.old .add, -div.chunk_block div.old .rem { - padding-right: 3px; -} - -div.chunk_block div.new .add, -div.chunk_block div.new .rem { - padding-left: 3px; -} - -div.chunk_block div.new { - margin-left: 50%; - width: 50%; - border-left: 5px solid #EAF2F5; -} - -/* Category ----------------------------------------------------------------------------- */ - -td.category { - background: #E6F1F6; /* old browsers */ - background: -moz-linear-gradient(top, #C8D8E7 0%, #E6F1F3 100%); /* firefox */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#C8D8E7), color-stop(100%,#E6F1F3)); /* webkit */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#C8D8E7', endColorstr='#E6F1F3',GradientType=0 ); /* ie */ - background: -o-linear-gradient(top, #C8D8E7 0%, #E6F1F3 100%); - font-weight: bold; - border-bottom: 1px solid #D1D1D1; - border-top: 1px solid #D1D1D1; -} - -/* Age ----------------------------------------------------------------------------- */ - -/* noage: "No commits" */ -.project_list td.noage { - color: #cdcdcd; -} - -/* age2: 60*60*24*2 <= age */ -.project_list td.age2, .blame td.age2 { - color: #545454; -} - -/* age1: 60*60*2 <= age < 60*60*24*2 */ -.project_list td.age1 { - color: #009900; -} - -/* age0: age < 60*60*2 */ -.project_list td.age0 { - color: #009900; - font-weight: bold; -} - -/* File status ----------------------------------------------------------------------------- */ - -.diff_tree span.file_status.new { - color: #008000; -} - -table.diff_tree span.file_status.deleted { - color: #c00000; -} - -table.diff_tree span.file_status.moved, -table.diff_tree span.file_status.mode_chnge { - color: #545454; -} - -table.diff_tree span.file_status.copied { - color: #70a070; -} - -span.cntrl { - border: dashed #aaaaaa; - border-width: 1px; - padding: 0px 2px 0px 2px; - margin: 0px 2px 0px 2px; -} - -span.match { - background: #aaffaa; - color: #000; -} - -td.error { - color: red; - background: yellow; -} - -/* blob view */ - -td.pre, div.pre, div.diff { - white-space: pre-wrap; -} - -/* JavaScript-based timezone manipulation */ - -.popup { /* timezone selection UI */ - position: absolute; - /* "top: 0; right: 0;" would be better, if not for bugs in browsers */ - top: 0; left: 0; - border: 1px solid #d8d8d8; - padding: 2px; - background-color: #f0f0f0; - font-style: normal; - color: #545454; - cursor: auto; -} - -.close-button { /* close timezone selection UI without selecting */ - /* float doesn't work within absolutely positioned container, - * if width of container is not set explicitly */ - /* float: right; */ - position: absolute; - top: 0px; right: 0px; - border: 1px solid #ffaaaa; - margin: 1px 1px 1px 1px; - padding-bottom: 2px; - width: 12px; - height: 10px; - font-size: 9px; - font-weight: bold; - text-align: center; - background-color: #ffdddd; - cursor: pointer; -} - -/* Style definition generated by highlight 2.4.5, http://www.andre-simon.de/ */ - -/* Highlighting theme definition: */ - -.num { color:#6ecf36; } -.esc { color:#ff00ff; } -.str { color:#ff00d3; background-color: #edc9ec } -.dstr { color:#818100; } -.slc { color:#838183; font-style:italic; } -.com { color:#838183; font-style:italic; } -.dir { color:#008200; } -.sym { color:#000000; } -.line { color:#555555; } -.kwa { color:#666666; font-weight:bold; } -.kwb { color:#6b3099; } -.kwc { color:#d4663d; } -.kwd { color:#2928ff; } - -/**** Styles supplémentaires *****/ - -.readme div.toc { - float: right; - border: 1px solid black; - background-color: white; -} -.readme div.toc span.toctitle { - display: inline-block; - width: 100%; - text-align: center; - font-weight: bold; -} - -.readme table { - background-color: white; -} - -.readme table thead tr { - background-color: #ccc; -} - -.readme table tbody tr:nth-child(2n) { - background-color: #f8f8f8; -} - -.readme table td, .readme table th { - border: 1px solid black; -} diff --git a/virtual/modules/gitweb/theme/gitweb.js b/virtual/modules/gitweb/theme/gitweb.js deleted file mode 100644 index 72f3cfa..0000000 --- a/virtual/modules/gitweb/theme/gitweb.js +++ /dev/null @@ -1,27 +0,0 @@ -function include(filename, onload) { - var head = document.getElementsByTagName('head')[0]; - var script = document.createElement('script'); - script.src = filename; - script.type = 'text/javascript'; - script.onload = script.onreadystatechange = function() { - if (script.readyState) { - if (script.readyState === 'complete' || script.readyState === 'loaded') { - script.onreadystatechange = null; - onload(); - } - } - else { - onload(); - } - } - head.appendChild(script); -} - -include('static/gitweb.js', function() {}); -include('//code.jquery.com/jquery-3.1.0.min.js', function() { - $("div.title").each(function(index, element) { - if ($(element).text() === "readme" || $(element).text() === " ") { - $(element).hide(); - } - }); -}); diff --git a/virtual/modules/postgresql_run_socket_path.patch b/virtual/modules/postgresql_run_socket_path.patch deleted file mode 100644 index b558c7b..0000000 --- a/virtual/modules/postgresql_run_socket_path.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Naur postgresql-9.2.0.sockets/src/include/pg_config_manual.h postgresql-9.2.0/src/include/pg_config_manual.h ---- postgresql-9.2.0.sockets/src/include/pg_config_manual.h 2012-09-06 17:26:17.000000000 -0400 -+++ postgresql-9.2.0/src/include/pg_config_manual.h 2012-09-06 18:13:18.183092471 -0400 -@@ -144,7 +144,7 @@ - * here's where to twiddle it. You can also override this at runtime - * with the postmaster's -k switch. - */ --#define DEFAULT_PGSOCKET_DIR "/tmp" -+#define DEFAULT_PGSOCKET_DIR "/run/postgresql" - - /* - * The random() function is expected to yield values between 0 and diff --git a/virtual/modules/websites/commons/adminer.nix b/virtual/modules/websites/commons/adminer.nix new file mode 100644 index 0000000..7094e45 --- /dev/null +++ b/virtual/modules/websites/commons/adminer.nix @@ -0,0 +1,64 @@ +{ stdenv, fetchurl, nginx }: +let + adminer = rec { + webRoot = stdenv.mkDerivation rec { + version = "4.7.0"; + name = "adminer-${version}"; + src = fetchurl { + url = "https://www.adminer.org/static/download/${version}/${name}.php"; + sha256 = "1qq2g7rbfh2vrqfm3g0bz0qs057b049n0mhabnsbd1sgnpvnc5z7"; + }; + phases = "installPhase"; + installPhase = '' + mkdir -p $out + cp $src $out/index.php + ''; + }; + phpFpm = rec { + socket = "/var/run/phpfpm/adminer.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 5 + pm.process_idle_timeout = 60 + ;php_admin_flag[log_errors] = on + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = AdminerPHPSESSID + php_admin_value[open_basedir] = "${webRoot}:/tmp" + php_admin_value[session.save_path] = "/var/lib/php/sessions/adminer" + ''; + }; + apache = { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "proxy_fcgi" ]; + vhostConf = '' + Alias /adminer ${webRoot} + + DirectoryIndex index.php + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + ''; + }; + nginxConf = { + alias = webRoot; + index = "index.php"; + extraConfig = '' + include ${nginx}/conf/fastcgi.conf; + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + fastcgi_param HTTP_PROXY ""; + fastcgi_param SCRIPT_FILENAME ${webRoot}/index.php; + fastcgi_pass unix:${phpFpm.socket}; + fastcgi_index index.php; + fastcgi_intercept_errors on; + ''; + }; + }; +in + adminer diff --git a/virtual/modules/websites/default.nix b/virtual/modules/websites/default.nix index b027b81..6b31381 100644 --- a/virtual/modules/websites/default.nix +++ b/virtual/modules/websites/default.nix @@ -91,11 +91,18 @@ in ./aten ./piedsjaloux ./connexionswing + ./tools/db + ./tools/tools + ./tools/dav + ./tools/cloud + ./tools/git # built using: # sed -e "s/services\.httpd/services\.httpdProd/g" .nix-defexpr/channels/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix # And removed users / groups ./apache/httpd_prod.nix ./apache/httpd_inte.nix + # Adapted from base phpfpm + ./phpfpm ]; options.services.myWebsites = { @@ -155,6 +162,12 @@ in phpPackages = oldpkgs.php72Packages.override { inherit php; }; }; + services.myWebsites.tools.databases.enable = true; + services.myWebsites.tools.tools.enable = true; + services.myWebsites.tools.dav.enable = true; + services.myWebsites.tools.cloud.enable = true; + services.myWebsites.tools.git.enable = true; + services.myWebsites.Chloe.production.enable = cfg.production.enable; services.myWebsites.Ludivine.production.enable = cfg.production.enable; services.myWebsites.Aten.production.enable = cfg.production.enable; @@ -227,6 +240,28 @@ in }; }; + system.activationScripts = { + httpd = '' + install -d -m 0755 /var/lib/acme/acme-challenge + install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions + install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions/adminer + install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions/mantisbt + install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions/davical + ''; + }; + + services.myPhpfpm = { + phpPackage = pkgs.php; + phpOptions = '' + session.save_path = "/var/lib/php/sessions" + session.gc_maxlifetime = 60*60*24*15 + session.cache_expire = 60*24*30 + ''; + extraConfig = '' + log_level = notice + ''; + }; + # FIXME: logrotate # FIXME: ipv6 services.httpdProd = makeService "production" config.services.myWebsites.production; @@ -238,63 +273,7 @@ in services.myWebsites.integration.extraConfig = (builtins.filter (x: x != null) (pkgs.lib.attrsets.mapAttrsToList (n: v: v.extraConfig or null) cfg.apacheConfig)); services.httpd = makeService "tools" config.services.myWebsites.tools; - services.myWebsites.tools.modules = - mypkgs.adminer.apache.modules ++ - mypkgs.nextcloud.apache.modules ++ - mypkgs.ympd.apache.modules ++ - mypkgs.mantisbt.apache.modules ++ - mypkgs.ttrss.apache.modules ++ - mypkgs.roundcubemail.apache.modules ++ - pkgs.lib.lists.flatten (pkgs.lib.attrsets.mapAttrsToList (n: v: v.modules or []) cfg.apacheConfig); + services.myWebsites.tools.modules = pkgs.lib.lists.flatten (pkgs.lib.attrsets.mapAttrsToList (n: v: v.modules or []) cfg.apacheConfig); services.myWebsites.tools.extraConfig = (builtins.filter (x: x != null) (pkgs.lib.attrsets.mapAttrsToList (n: v: v.extraConfig or null) cfg.apacheConfig)); - # FIXME: move them all to separate modules - services.myWebsites.tools.vhostConfs.eldiron = { - certName = "eldiron"; - hosts = ["eldiron.immae.eu" ]; - root = ../../www; - extraConfig = [ "DirectoryIndex index.htm" ]; - }; - services.myWebsites.tools.vhostConfs.db-1 = { - certName = "eldiron"; - hosts = ["db-1.immae.eu" ]; - root = null; - extraConfig = [ mypkgs.adminer.apache.vhostConf ]; - }; - services.myWebsites.tools.vhostConfs.tools = { - certName = "eldiron"; - hosts = ["tools.immae.eu" ]; - root = null; - extraConfig = [ - mypkgs.adminer.apache.vhostConf - mypkgs.ympd.apache.vhostConf - mypkgs.ttrss.apache.vhostConf - mypkgs.roundcubemail.apache.vhostConf - ]; - }; - services.myWebsites.tools.vhostConfs.dav = { - certName = "eldiron"; - hosts = ["dav.immae.eu" ]; - root = null; - extraConfig = [ - mypkgs.infcloud.apache.vhostConf - mypkgs.davical.apache.vhostConf - ]; - }; - services.myWebsites.tools.vhostConfs.cloud = { - certName = "eldiron"; - hosts = ["cloud.immae.eu" ]; - root = mypkgs.nextcloud.webRoot; - extraConfig = [ - mypkgs.nextcloud.apache.vhostConf - ]; - }; - services.myWebsites.tools.vhostConfs.git.extraConfig = [ - mypkgs.mantisbt.apache.vhostConf - '' - RewriteEngine on - RewriteCond %{REQUEST_URI} ^/releases - RewriteRule /releases(.*) https://release.immae.eu$1 [P,L] - '' - ]; }; } diff --git a/virtual/modules/websites/tools/cloud/default.nix b/virtual/modules/websites/tools/cloud/default.nix new file mode 100644 index 0000000..7dd5c6e --- /dev/null +++ b/virtual/modules/websites/tools/cloud/default.nix @@ -0,0 +1,45 @@ +{ lib, pkgs, config, mylibs, ... }: +let + nextcloud = pkgs.callPackage ./nextcloud.nix { inherit (mylibs) checkEnv; }; + + cfg = config.services.myWebsites.tools.cloud; +in { + options.services.myWebsites.tools.cloud = { + enable = lib.mkEnableOption "enable cloud website"; + }; + + config = lib.mkIf cfg.enable { + security.acme.certs."eldiron".extraDomains."cloud.immae.eu" = null; + + services.myWebsites.tools.modules = nextcloud.apache.modules; + + services.myWebsites.tools.vhostConfs.cloud = { + certName = "eldiron"; + hosts = ["cloud.immae.eu" ]; + root = nextcloud.webRoot; + extraConfig = [ + nextcloud.apache.vhostConf + ]; + }; + + environment.systemPackages = let + occ = pkgs.writeScriptBin "nextcloud-occ" '' + #! ${pkgs.stdenv.shell} + cd ${nextcloud.webRoot} + NEXTCLOUD_CONFIG_DIR="${nextcloud.webRoot}/config" \ + exec \ + ${pkgs.php}/bin/php \ + -c ${pkgs.php}/etc/php.ini \ + occ $* + ''; + in [ occ ]; + + system.activationScripts.nextcloud = nextcloud.activationScript; + + services.myPhpfpm = { + poolPhpConfigs.nextcloud = nextcloud.phpFpm.phpConfig; + poolConfigs.nextcloud = nextcloud.phpFpm.pool; + }; + + }; +} diff --git a/virtual/modules/websites/tools/cloud/nextcloud-config/mimetypealiases.json b/virtual/modules/websites/tools/cloud/nextcloud-config/mimetypealiases.json new file mode 100644 index 0000000..3806e53 --- /dev/null +++ b/virtual/modules/websites/tools/cloud/nextcloud-config/mimetypealiases.json @@ -0,0 +1,4 @@ +{ + "application/gpx+xml": "gpx", + "x-application/kdbx": "kdbx" +} diff --git a/virtual/modules/websites/tools/cloud/nextcloud-config/mimetypemapping.json b/virtual/modules/websites/tools/cloud/nextcloud-config/mimetypemapping.json new file mode 100644 index 0000000..2db4691 --- /dev/null +++ b/virtual/modules/websites/tools/cloud/nextcloud-config/mimetypemapping.json @@ -0,0 +1,4 @@ +{ + "gpx": ["application/gpx+xml"], + "kdbx": ["x-application/kdbx"] +} diff --git a/virtual/modules/websites/tools/cloud/nextcloud.nix b/virtual/modules/websites/tools/cloud/nextcloud.nix new file mode 100644 index 0000000..b8d8e59 --- /dev/null +++ b/virtual/modules/websites/tools/cloud/nextcloud.nix @@ -0,0 +1,267 @@ +{ stdenv, fetchurl, checkEnv, writeText, lib, phpPackages, php }: +let + nextcloud = let + # FIXME: initial sync + # FIXME: backup + buildApp = { appName, version, url, sha256, installPhase ? "mkdir -p $out && cp -R . $out/" }: + stdenv.mkDerivation rec { + name = "nextcloud-app-${appName}-${version}"; + inherit version; + phases = "unpackPhase installPhase"; + inherit installPhase; + src = fetchurl { inherit url sha256; }; + }; + apps = { + # FIXME: nextcloud complains that he cannot write into config + # directory when an app needs upgrade + # /!\ Attention, just changing the version number is not + # sufficient when the downloaded file doesn’t contain the version + # number in it, sha256 needs to be recomputed + audioplayer = buildApp rec { + appName = "audioplayer"; + version = "2.5.0"; + url = "https://github.com/Rello/${appName}/releases/download/${version}/${appName}-${version}.tar.gz"; + sha256 = "1pg4y51cv3agy28n4gfc8i7x1ya1yijxrmhpblm1n846vhmwdcm8"; + }; + bookmarks = buildApp rec { + appName = "bookmarks"; + version = "0.14.3"; + url = "https://github.com/nextcloud/${appName}/releases/download/v${version}/${appName}-${version}.tar.gz"; + sha256 = "0s7lkcl70izlkihnml1par0cac0wvckllyyga3jkb7k9vdg7d40c"; + }; + calendar = buildApp rec { + appName = "calendar"; + version = "1.6.4"; + url = "https://github.com/nextcloud/${appName}/releases/download/v${version}/${appName}.tar.gz"; + sha256 = "00dijvcvy7snsjslfbyzvpp9anhms22zp1f0zkj89ln33jmana63"; + }; + contacts = buildApp rec { + appName = "contacts"; + version = "3.0.0"; + url = "https://github.com/nextcloud/${appName}/releases/download/v${version}/${appName}.tar.gz"; + sha256 = "0fafy5kgzr5ldr3hxxxgmnw4y3qpjnv5ha1f1dlmqbc65s8frw7s"; + }; + deck = buildApp rec { + appName = "deck"; + version = "0.5.2"; + url = "https://github.com/nextcloud/${appName}/releases/download/v${version}/${appName}.tar.gz"; + sha256 = "1kygzixxdkp3dbma009p3pw0fj8wgcqcv39n7pay78lh6zi3nic7"; + }; + files_markdown = buildApp rec { + appName = "files_markdown"; + version = "2.0.5"; + url = "https://github.com/icewind1991/${appName}/releases/download/v${version}/${appName}.tar.gz"; + sha256 = "1dzvy4c6vff2qmkwqw13dx92xdkafaxgnipswjw44mh0ncc2n9ym"; + }; + gpxedit = buildApp rec { + appName = "gpxedit"; + version = "0.0.10"; + url = "https://gitlab.com/eneiluj/gpxedit-oc/wikis/uploads/33d187268c5f6f6a55350d656305701c/${appName}-${version}.tar.gz"; + sha256 = "0ynpaxm0xhvcj8xax6rm1w0p6j57wbqidhi7bhn268n483gwl2sw"; + }; + gpxpod = buildApp rec { + appName = "gpxpod"; + version = "3.0.0"; + url = "https://gitlab.com/eneiluj/gpxpod-oc/-/archive/v${version}/${appName}-oc-v${version}.tar.gz"; + sha256 = "0smpi4r3z7zfl1612fb30cwm1xmpiq95c81zzqiwzjf288iys74k"; + }; + keeweb = buildApp rec { + appName = "keeweb"; + version = "0.4.0"; + url = "https://github.com/jhass/nextcloud-keeweb/releases/download/v${version}/${appName}-${version}.tar.gz"; + sha256 = "0453kkb0a8vfivmibpwpx4bvhyn64jhns6cdfjacmnvbm6d75nj1"; + }; + notes = buildApp rec { + appName = "notes"; + version = "2.5.1"; + url = "https://github.com/nextcloud/${appName}/releases/download/v${version}/${appName}.tar.gz"; + sha256 = "1albzqqsdirzyw8vhvs7r0qm2wqp8vm9vmxm4crhncd85bk01hmh"; + }; + ocsms = buildApp rec { + appName = "ocsms"; + version = "2.1.0"; + url = "https://github.com/nextcloud/${appName}/releases/download/${version}/${appName}-${version}.tar.gz"; + sha256 = "19xgs82js4sdf6j9478vg9li7za7csvcaa1hbq9nmrq441sbxk9c"; + }; + spreed = buildApp rec { + appName = "spreed"; + version = "5.0.0"; + url = "https://github.com/nextcloud/${appName}/releases/download/v${version}/${appName}-${version}.tar.gz"; + sha256 = "1d48mak1fnf1b28r2687yqamm4pxfg3qyxcj9ny31a6xg2cm0xa7"; + }; + tasks = buildApp rec { + appName = "tasks"; + version = "0.9.8"; + url = "https://github.com/nextcloud/${appName}/releases/download/v${version}/${appName}.tar.gz"; + sha256 = "089m124lfsfk09fqj50x9n7zndq97jp5afgb8s001rpmzym4g6ny"; + }; + }; + in rec { + varDir = "/var/lib/nextcloud"; + config_php = + assert checkEnv "NIXOPS_NEXTCLOUD_PASSWORD_SALT"; + assert checkEnv "NIXOPS_NEXTCLOUD_DB_USER"; + assert checkEnv "NIXOPS_NEXTCLOUD_DB_PASSWORD"; + assert checkEnv "NIXOPS_NEXTCLOUD_INSTANCE_ID"; + assert checkEnv "NIXOPS_NEXTCLOUD_SECRET"; + assert checkEnv "NIXOPS_NEXTCLOUD_REDIS_DB_INDEX"; + writeText "config.php" '' + '${builtins.getEnv "NIXOPS_NEXTCLOUD_INSTANCE_ID"}', + 'datadirectory' => '/var/lib/nextcloud/', + 'passwordsalt' => '${builtins.getEnv "NIXOPS_NEXTCLOUD_PASSWORD_SALT"}', + 'debug' => false, + 'dbtype' => 'pgsql', + 'version' => '15.0.0.10', + 'dbname' => 'webapps', + 'dbhost' => '/run/postgresql', + 'dbtableprefix' => 'oc_', + 'dbuser' => '${builtins.getEnv "NIXOPS_NEXTCLOUD_DB_USER"}', + 'dbpassword' => '${builtins.getEnv "NIXOPS_NEXTCLOUD_DB_PASSWORD"}', + 'installed' => true, + 'maxZipInputSize' => 0, + 'allowZipDownload' => true, + 'forcessl' => true, + 'theme' => ${"''"}, + 'maintenance' => false, + 'trusted_domains' => + array ( + 0 => 'cloud.immae.eu', + ), + 'secret' => '${builtins.getEnv "NIXOPS_NEXTCLOUD_SECRET"}', + 'appstoreenabled' => false, + 'appstore.experimental.enabled' => true, + 'loglevel' => 0, + 'trashbin_retention_obligation' => 'auto', + 'htaccess.RewriteBase' => '/', + 'mail_smtpmode' => 'smtp', + 'mail_smtphost' => 'mail.immae.eu', + 'mail_smtpname' => ${"''"}, + 'mail_smtppassword' => ${"''"}, + 'mail_from_address' => 'owncloud', + 'mail_smtpauth' => false, + 'mail_domain' => 'immae.eu', + 'memcache.local' => '\\OC\\Memcache\\APCu', + 'memcache.locking' => '\\OC\\Memcache\\Redis', + 'filelocking.enabled' => true, + 'redis' => + array ( + 'host' => 'localhost', + 'port' => 6379, + 'dbindex' => ${builtins.getEnv "NIXOPS_NEXTCLOUD_REDIS_DB_INDEX"}, + ), + 'overwrite.cli.url' => 'https://cloud.immae.eu', + 'ldapIgnoreNamingRules' => false, + 'ldapProviderFactory' => '\\OCA\\User_LDAP\\LDAPProviderFactory', + 'config_is_read_only' => true, + ); + ''; + config = stdenv.mkDerivation rec { + name = "nextcloud-config"; + src = ./nextcloud-config; + phases = "installPhase"; + installPhase = '' + mkdir -p $out + cp -r $src/* $out + cp ${config_php} $out/config.php + ''; + }; + webRoot = stdenv.mkDerivation rec { + name = "nextcloud-${version}"; + version = "15.0.0"; + + src = fetchurl { + url = "https://download.nextcloud.com/server/releases/${name}.tar.bz2"; + sha256 = "0y7bk1588n5rmmranmmrkajh50074460hr4v052ahg9mf60wbc2v"; + }; + + installPhase = '' + mkdir -p $out/ + cp -R . $out/ + rm -r $out/config + ln -sf ${config} $out/config + ${builtins.concatStringsSep "\n" ( + lib.attrsets.mapAttrsToList (name: value: "ln -sf ${value} $out/apps/${name}") apps + )} + ''; + + meta = { + description = "Sharing solution for files, calendars, contacts and more"; + homepage = https://nextcloud.com; + maintainers = with lib.maintainers; [ schneefux bachp globin fpletz ]; + license = lib.licenses.agpl3Plus; + platforms = with lib.platforms; unix; + }; + }; + activationScript = { + deps = [ ]; + text = '' + install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir} + install -m 0750 -o ${apache.user} -g ${apache.group} -d ${varDir}/phpSessions + ''; + }; + apache = { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "proxy_fcgi" ]; + vhostConf = '' + SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 + + AcceptPathInfo On + DirectoryIndex index.php + Options FollowSymlinks + Require all granted + AllowOverride all + + + Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains; preload" + + + CGIPassAuth on + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + + + ''; + }; + phpFpm = rec { + basedir = builtins.concatStringsSep ":" ( + [ webRoot varDir config ] + ++ lib.attrsets.mapAttrsToList (name: value: value) apps); + socket = "/var/run/phpfpm/nextcloud.sock"; + phpConfig = '' + extension=${phpPackages.redis}/lib/php/extensions/redis.so + extension=${phpPackages.apcu}/lib/php/extensions/apcu.so + zend_extension=${php}/lib/php/extensions/opcache.so + ''; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 60 + pm.process_idle_timeout = 60 + + php_admin_value[output_buffering] = 0 + php_admin_value[max_execution_time] = 1800 + php_admin_value[zend_extension] = "opcache" + php_value[opcache.enable] = 1 + php_value[opcache.enable_cli] = 1 + php_value[opcache.interned_strings_buffer] = 8 + php_value[opcache.max_accelerated_files] = 10000 + php_value[opcache.memory_consumption] = 128 + php_value[opcache.save_comments] = 1 + php_value[opcache.revalidate_freq] = 1 + php_admin_value[memory_limit] = 512M + + php_admin_value[open_basedir] = "${basedir}:/proc/meminfo:/dev/urandom:/proc/self/fd:/tmp" + php_admin_value[session.save_path] = "${varDir}/phpSessions" + ''; + }; + }; +in + nextcloud diff --git a/virtual/modules/websites/tools/dav/davical.nix b/virtual/modules/websites/tools/dav/davical.nix new file mode 100644 index 0000000..697bd60 --- /dev/null +++ b/virtual/modules/websites/tools/dav/davical.nix @@ -0,0 +1,164 @@ +{ stdenv, fetchurl, gettext, writeText, checkEnv }: +let + awl = stdenv.mkDerivation rec { + version = "0.59"; + name = "awl-${version}"; + src = fetchurl { + url = "https://www.davical.org/downloads/awl_${version}.orig.tar.xz"; + sha256 = "01b7km7ga3ggbpp8axkc55nizgk5c35fl2z93iydb3hwbxmsvnjp"; + }; + unpackCmd = '' + tar --one-top-level -xf $curSrc + ''; + installPhase = '' + mkdir -p $out + cp -ra dba docs inc scripts tests $out + ''; + }; + # FIXME: e-mail sending + davical = rec { + config = + assert checkEnv "NIXOPS_DAVICAL_DB_PASSWORD"; + assert checkEnv "NIXOPS_DAVICAL_LDAP_PASSWORD"; + writeText "davical_config.php" '' + pg_connect[] = "dbname=davical user=davical_app host=db-1.immae.eu password=${builtins.getEnv "NIXOPS_DAVICAL_DB_PASSWORD"}"; + + $c->readonly_webdav_collections = false; + + $c->admin_email ='davical@immae.eu'; + + $c->restrict_setup_to_admin = true; + + $c->collections_always_exist = false; + + $c->external_refresh = 60; + + $c->enable_scheduling = true; + + $c->iMIP = (object) array("send_email" => true); + + $c->authenticate_hook['optional'] = false; + $c->authenticate_hook['call'] = 'LDAP_check'; + $c->authenticate_hook['config'] = array( + 'host' => 'ldap.immae.eu', + 'port' => '389', + 'startTLS' => 'yes', + 'bindDN'=> 'cn=davical,ou=services,dc=immae,dc=eu', + 'passDN'=> '${builtins.getEnv "NIXOPS_DAVICAL_LDAP_PASSWORD"}', + 'protocolVersion' => '3', + 'baseDNUsers'=> array('ou=users,dc=immae,dc=eu', 'ou=group_users,dc=immae,dc=eu'), + 'filterUsers' => 'memberOf=cn=users,cn=davical,ou=services,dc=immae,dc=eu', + 'baseDNGroups' => 'ou=groups,dc=immae,dc=eu', + 'filterGroups' => 'memberOf=cn=groups,cn=davical,ou=services,dc=immae,dc=eu', + 'mapping_field' => array( + "username" => "uid", + "fullname" => "cn", + "email" => "mail", + "modified" => "modifyTimestamp", + ), + 'format_updated'=> array('Y' => array(0,4),'m' => array(4,2),'d'=> array(6,2),'H' => array(8,2),'M'=>array(10,2),'S' => array(12,2)), + /** used to set default value for all users, will be overcharged by ldap if defined also in mapping_field **/ + // 'default_value' => array("date_format_type" => "E","locale" => "fr_FR"), + 'group_mapping_field' => array( + "username" => "cn", + "updated" => "modifyTimestamp", + "fullname" => "givenName", + "displayname" => "givenName", + "members" => "memberUid", + "email" => "mail", + ), + ); + + $c->do_not_sync_from_ldap = array('admin' => true); + include('drivers_ldap.php'); + ''; + webapp = stdenv.mkDerivation rec { + version = "1.1.7"; + name = "davical-${version}"; + src = fetchurl { + url = "https://www.davical.org/downloads/davical_${version}.orig.tar.xz"; + sha256 = "1ar5m2dxr92b204wkdi8z33ir9vz2jbh5k1p74icpv9ywifvjjp9"; + }; + unpackCmd = '' + tar --one-top-level -xf $curSrc + ''; + makeFlags = "all"; + patches = [ ./davical_19eb79ebf9250e5f339675319902458c40ed1755.patch ]; + installPhase = '' + mkdir -p $out + cp -ra config dba docs htdocs inc locale po scripts testing zonedb $out + ln -s ${config} $out/config/config.php + ''; + buildInputs = [ gettext ]; + }; + webRoot = "${webapp}/htdocs"; + apache = { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "proxy_fcgi" ]; + vhostConf = '' + Alias /davical "${webRoot}" + Alias /caldav.php "${webRoot}/caldav.php" + + DirectoryIndex index.php index.html + AcceptPathInfo On + AllowOverride None + Require all granted + + + CGIPassAuth on + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + RewriteEngine On + + Header unset Access-Control-Allow-Origin + Header unset Access-Control-Allow-Methods + Header unset Access-Control-Allow-Headers + Header unset Access-Control-Allow-Credentials + Header unset Access-Control-Expose-Headers + + Header always set Access-Control-Allow-Origin "*" + Header always set Access-Control-Allow-Methods "GET,POST,OPTIONS,PROPFIND,PROPPATCH,REPORT,PUT,MOVE,DELETE,LOCK,UNLOCK" + Header always set Access-Control-Allow-Headers "User-Agent,Authorization,Content-type,Depth,If-match,If-None-Match,Lock-Token,Timeout,Destination,Overwrite,Prefer,X-client,X-Requested-With" + Header always set Access-Control-Allow-Credentials false + Header always set Access-Control-Expose-Headers "Etag,Preference-Applied" + + RewriteCond %{HTTP:Access-Control-Request-Method} !^$ + RewriteCond %{REQUEST_METHOD} OPTIONS + RewriteRule ^(.*)$ $1 [R=200,L] + + + ''; + }; + phpFpm = rec { + basedir = builtins.concatStringsSep ":" [ webapp config awl ]; + socket = "/var/run/phpfpm/davical.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = dynamic + pm.max_children = 60 + pm.start_servers = 2 + pm.min_spare_servers = 1 + pm.max_spare_servers = 10 + + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = DavicalPHPSESSID + php_admin_value[open_basedir] = "${basedir}:/tmp" + php_admin_value[include_path] = "${awl}/inc:${webapp}/inc" + php_admin_value[session.save_path] = "/var/lib/php/sessions/davical" + php_flag[magic_quotes_gpc] = Off + php_flag[register_globals] = Off + php_admin_value[error_reporting] = "E_ALL & ~E_NOTICE" + php_admin_value[default_charset] = "utf-8" + php_flag[magic_quotes_runtime] = Off + ''; + }; + }; +in + davical diff --git a/virtual/modules/websites/tools/dav/davical_19eb79ebf9250e5f339675319902458c40ed1755.patch b/virtual/modules/websites/tools/dav/davical_19eb79ebf9250e5f339675319902458c40ed1755.patch new file mode 100644 index 0000000..2a08a5c --- /dev/null +++ b/virtual/modules/websites/tools/dav/davical_19eb79ebf9250e5f339675319902458c40ed1755.patch @@ -0,0 +1,26 @@ +diff --git a/inc/ui/collection-edit.php b/inc/ui/collection-edit.php +index 3af9edd3b8c4ad9074113273175098841af6a28e..8c1d84012b035f7bc7faedcb24916581a02a5d3e 100644 +--- a/inc/ui/collection-edit.php ++++ b/inc/ui/collection-edit.php +@@ -190,7 +190,7 @@ $privilege_xlate = array( + * @param dbrow $row The row object we read from the database. + * @return string The formatted privileges. + */ +-function collection_privilege_format_function( $value, $column, $row ) { ++function collection_privilege_format_function( $value, $column = NULL, $row = NULL ) { + global $privilege_xlate; + + $privs = bits_to_privilege($value, 'calendar'); +diff --git a/inc/ui/principal-edit.php b/inc/ui/principal-edit.php +index 20dee7fa4ca2235ff2f74be0dfb52cbe937ef822..2e37cd596b597bcce1e59d7c02a1c5fc2a7f88ce 100644 +--- a/inc/ui/principal-edit.php ++++ b/inc/ui/principal-edit.php +@@ -454,7 +454,7 @@ EOTEMPLATE; + * @param dbrow $row The row object we read from the database. + * @return string The formatted privileges. + */ +-function principal_privilege_format_function( $value, $column, $row ) { ++function principal_privilege_format_function( $value, $column = NULL, $row = NULL ) { + global $privilege_xlate; + + $privs = bits_to_privilege($value,'*'); diff --git a/virtual/modules/websites/tools/dav/default.nix b/virtual/modules/websites/tools/dav/default.nix new file mode 100644 index 0000000..201da38 --- /dev/null +++ b/virtual/modules/websites/tools/dav/default.nix @@ -0,0 +1,33 @@ +{ lib, pkgs, config, mylibs, ... }: +let + infcloud = pkgs.callPackage ./infcloud.nix {}; + davical = pkgs.callPackage ./davical.nix { inherit (mylibs) checkEnv; }; + + cfg = config.services.myWebsites.tools.dav; +in { + options.services.myWebsites.tools.dav = { + enable = lib.mkEnableOption "enable dav website"; + }; + + config = lib.mkIf cfg.enable { + security.acme.certs."eldiron".extraDomains."dav.immae.eu" = null; + + services.myWebsites.tools.modules = davical.apache.modules; + + services.myWebsites.tools.vhostConfs.dav = { + certName = "eldiron"; + hosts = ["dav.immae.eu" ]; + root = null; + extraConfig = [ + infcloud.apache.vhostConf + davical.apache.vhostConf + ]; + }; + + services.myPhpfpm.poolConfigs = { + davical = davical.phpFpm.pool; + }; + + }; +} + diff --git a/virtual/modules/websites/tools/dav/infcloud.nix b/virtual/modules/websites/tools/dav/infcloud.nix new file mode 100644 index 0000000..876578b --- /dev/null +++ b/virtual/modules/websites/tools/dav/infcloud.nix @@ -0,0 +1,38 @@ +{ stdenv, fetchzip, ed }: +let + infcloud = rec { + webRoot = stdenv.mkDerivation rec { + version = "0.13.1"; + name = "InfCloud-${version}"; + src = fetchzip { + url = "https://www.inf-it.com/InfCloud_${version}.zip"; + sha256 = "1fjhs0cj0b9fhf5ysfz281mknmmg1z551bas143sxfcqlpa5aiiq"; + }; + buildPhase = '' + ./cache_update.sh + rm config.js + ''; + installPhase = '' + cp -a . $out + ln -s ${./infcloud_config.js} $out/config.js + ''; + buildInputs = [ ed ]; + }; + apache = { + user = "wwwrun"; + group = "wwwrun"; + vhostConf = '' + Alias /carddavmate ${webRoot} + Alias /caldavzap ${webRoot} + Alias /infcloud ${webRoot} + + AllowOverride All + Options FollowSymlinks + Require all granted + DirectoryIndex index.html + + ''; + }; + }; +in + infcloud diff --git a/virtual/modules/websites/tools/dav/infcloud_config.js b/virtual/modules/websites/tools/dav/infcloud_config.js new file mode 100644 index 0000000..ba73860 --- /dev/null +++ b/virtual/modules/websites/tools/dav/infcloud_config.js @@ -0,0 +1,1446 @@ +/* +InfCloud - the open source CalDAV/CardDAV Web Client +Copyright (C) 2011-2015 + Jan Mate + Andrej Lezo + Matej Mihalik + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + + +// NOTE: see readme.txt before you start to configure this client! + + +// NOTE: do not forget to execute the cache_update.sh script every time you +// update this configuration file or any other files (otherwise your browser +// will use the previous version of files stored in HTML5 cache). Alternatively +// you can update the cache.manifest manually - edit the second line beginning +// with "#V 20" to anything else (this file simple needs "some" change) + + +// Supported setup types (use ONE of them): +// a.) globalAccountSettings => username and password is hardcoded +// in config.js, automatic login without the login screen +// - advantages: fast login process = no username/password is required +// - disadvantages: username/password is visible in your config.js, so +// this type of setup is recommended ONLY for intranet/home users +// b.) globalNetworkCheckSettings => standard setup with login screen +// - advantages: username/password is required (no visible +// username/password in config.js) +// - disadvantages: if a user enters wrong username/password then +// the browser will show authentication popup window (it is NOT +// possible to disable it in JavaScript; see the next option) +// c.) globalNetworkAccountSettings => advanced setup with login screen +// - advantages: no authentication popup if you enter wrong username/ +// password, dynamic XML configuration generator (you can generate +// different configurations for your users /by modifying the "auth" +// module configuration or the PHP code itself/) +// - disadvantages: requires PHP >= 5.3 and additional configuration, +// only basic http authentication is supported => always use https! +// +// +// What is a "principal URL"? => Check you server documentation! +// - "principal URL" is NOT "collection URL" +// - this client automatically detects collections for "principal URL" +// - PROPER "principal URL" looks like: +// https://server.com:8443/principals/users/USER/ +// https://server.com:8443/caldav.php/USER/ +// - INVALID principal URL looks like: +// https://server.com:8443/principals/users/USER/collection/ +// => this is a collection URL +// https://server.com:8443/caldav.php/USER/collection/ +// => this is a collection URL +// https://server.com:8443/principals/users/USER +// => missing trailing '/' +// https://server.com:8443/caldav.php/USER +// => missing trailing '/' +// /caldav.php/USER/ +// => relative URL instead of full URL +// +// +// List of properties used in globalAccountSettings, globalNetworkCheckSettings +// and globalNetworkAccountSettings variables (+ in the "auth" module): +// - href +// Depending on the setup type set the value to: +// a.) globalAccountSettings: full "principal URL" +// b.) globalNetworkCheckSettings: "principal URL" WITHOUT the "USER/" part +// c.) globalNetworkAccountSettings: "full URL" to the "auth" directory +// This property is supported in: +// globalAccountSettings +// globalNetworkCheckSettings +// globalNetworkAccountSettings +// - userAuth +// - userName +// Set the username you want to login. +// - userPassword +// Set the password for the given username. +// This property is supported in: +// globalAccountSettings +// - timeOut +// This option sets the timeout for jQuery .ajax call (in miliseconds). +// Example: +// timeOut: 90000 +// This property is supported in: +// globalAccountSettings +// globalNetworkCheckSettings +// globalNetworkAccountSettings +// - lockTimeOut +// NOTE: used only if server supports LOCK requests +// This option sets the LOCK timeout value if resource locking +// is used (in miliseconds). +// Example: +// lockTimeOut: 10000 +// This property is supported in: +// globalAccountSettings +// globalNetworkCheckSettings +// globalNetworkAccountSettings (available in auth module only) +// - checkContentType +// This option enables a content-type checking for server response. +// If enabled then only objects with proper content-type are inserted +// into the interface. +// If you cannot see data in the interface you may try to disable it (useful +// if your server returns wrong value in "propstat/prop/getcontenttype"). +// If undefined then content-type checking is enabled. +// Examples: +// checkContentType: true +// checkContentType: false +// This property is supported in: +// globalAccountSettings +// globalNetworkCheckSettings +// globalNetworkAccountSettings (available in auth module only) +// - settingsAccount +// NOTE: server support for custom DAV properties is REQUIRED! +// This option sets the account where the client properties such as: +// loaded collections, enabled collections, ... are saved during +// the logout and resource/collection synchronisation +// NOTE: set it to true ONLY for ONE account! +// Examples: +// settingsAccount: true +// settingsAccount: false +// This property is supported in: +// globalAccountSettings +// globalNetworkCheckSettings +// globalNetworkAccountSettings (available in auth module only) +// - delegation +// NOTE: server support for this functionality is REQUIRED! +// This option allows you to load delegated (shared) collections. +// If set to true (default) then delegation functionality is enabled, +// and the interface allows you to load delegated collections. +// If false then delegation functionality is completely disabled. +// Examples: +// delegation: true +// delegation: false +// This property is supported in: +// globalAccountSettings +// globalNetworkCheckSettings +// globalNetworkAccountSettings (available in auth module only) +// - additionalResources +// This options sets the list of additional resources (e.g. shared resources +// accessible by all users). If the server supports delegation (see +// the delegation option above) there is no reason to use this option! +// Supported values: +// - array of URL encoded resource names (not collections), such as: +// 'company' +// 'shared_resource' +// If empty (default) or undefined then shared resources are not loaded +// using this option, but may be loaded using the delegation option. +// Examples: +// additionalResources=[] +// additionalResources=['public', 'shared_resource'] +// This property is supported in: +// globalNetworkCheckSettings +// - hrefLabel +// This option sets the server name in the resource header (useful if +// you want to see custom resource header above the collections). +// You can use the following variables in the value: +// %H = full hostname (including the port number) +// %h = full hostname (without the port number) +// %D = full domain name +// %d = only the first and second level domain +// %P = principal name +// %p = principal name without the @domain.com part (if present) +// %U = logged user name +// %u = logged user name without the @domain.com part (if present) +// If undefined, empty or or null then '%d/%p [%u]' is used. +// Examples: +// hrefLabel: '%d/%p [%u]' +// hrefLabel: '%D/%u' +// This property is supported in: +// globalAccountSettings +// globalNetworkCheckSettings +// globalNetworkAccountSettings (available in auth module only) +// - forceReadOnly +// This option sets the list of collections as "read-only". +// Supported values: +// - true +// all collections will be "read-only" +// - array of URL encoded +// - collections, such as: +// '/caldav.php/user/calendar/' +// '/caldav.php/user%40domain.com/calendar/' +// - regexes, such as: +// new RegExp('^/caldav.php/user/calendar[0-9]/$', 'i') +// specifies the list of collections marked as "read-only" +// If null (default) or undefined then server detected privileges are used. +// Examples: +// forceReadOnly: null +// forceReadOnly: true +// forceReadOnly: ['/caldav.php/user/calendar/', +// '/caldav.php/user/calendar2/'] +// forceReadOnly: [new RegExp('^/.*/user/calendar[0-9]/$', 'i')] +// This property is supported in: +// globalAccountSettings +// globalNetworkCheckSettings +// globalNetworkAccountSettings (available in auth module only, with +// different syntax for regexes) +// - ignoreAlarms +// This option sets list of calendar collections with disabled +// alarm functionality. +// Supported values: +// - true +// alarm functionality is disabled for all collections +// - array of URL encoded +// - collections, such as: +// '/caldav.php/user/calendar/' +// '/caldav.php/user%40domain.com/calendar/' +// - regexes, such as: +// new RegExp('^/caldav.php/user/calendar[0-9]/$', 'i') +// specifies the list of collections with disabled alarm functionality. +// If false (default) or undefined then alarm functionality is enabled +// for all collections. +// Examples: +// ignoreAlarms: true +// ignoreAlarms: ['/caldav.php/user/calendar/', +// '/caldav.php/user/calendar2/'] +// ignoreAlarms: [new RegExp('^/.*/user/calendar[0-9]/$', 'i')] +// This property is supported in: +// globalAccountSettings +// globalNetworkCheckSettings +// globalNetworkAccountSettings (available in auth module only, with +// different syntax for regexes) +// - backgroundCalendars +// This options defines a list of background calendars. If there is +// at least one event defined for the given day in a background calendar, +// the background color for that day will be pink/light-red. +// Supported values: +// - array of URL encoded +// - collections, such as: +// '/caldav.php/user/calendar/' +// '/caldav.php/user%40domain.com/calendar/' +// - regexes, such as: +// new RegExp('^/caldav.php/user/calendar[0-9]/$', 'i') +// specifies the list of background calendar collections. +// Examples: +// backgroundCalendars: ['/caldav.php/user/calendar/', +// '/caldav.php/user/calendar2/'] +// backgroundCalendars: [new RegExp('^/.*/user/calendar[0-9]/$', 'i')] +// This property is supported in: +// globalAccountSettings +// globalNetworkCheckSettings +// globalNetworkAccountSettings (available in auth module only, with +// different syntax for regexes) +// Special options not present in configuration examples: +// NOTE: use ONLY if you know what are you doing! +// - crossDomain +// This option sets the crossDomain for jQuery .ajax call. If null (default) +// then the value is autodetected /and the result is shown in the console/ +// - withCredentials +// This option sets the withCredentials for jQuery .ajax call. The default +// value is false and there is NO REASON to change it to true! +// NOTE: if true, Access-Control-Allow-Origin "*" (CORS header) not works! + + +// globalAccountSettings +// Use this option if you want to use automatic login (without a login +// screen) with hardcoded username/password in config.js. Otherwise use +// globalNetworkCheckSettings or globalNetworkAccountSettings (see below). +// NOTE: if this option is used the value must be an array of object(s). +// List of properties used in globalAccountSettings variable: +// - href +// Set this option to the full "principal URL". +// NOTE: the last character in the value must be '/' +// - userAuth +// - userName +// Set the username you want to login. +// - userPassword +// Set the password for the given username. +// NOTE: for description of other properties see comments at the beginning +// of this file. +// NOTE: for minimal/fast setup you need to set only the href and userAuth +// options. It is safe/recommended to keep the remaining options unchanged! +// Example: +//var globalAccountSettings=[ +// { +// href: 'https://server1.com:8443/caldav.php/USERNAME1/', +// userAuth: +// { +// userName: 'USERNAME1', +// userPassword: 'PASSWORD1' +// }, +// timeOut: 90000, +// lockTimeOut: 10000, +// checkContentType: true, +// settingsAccount: true, +// delegation: true, +// hrefLabel: null, +// forceReadOnly: null, +// ignoreAlarms: false, +// backgroundCalendars: [] +// }, +// { +// href: 'https://server2.com:8443/caldav.php/USERNAME2/', +// ... +// ... +// } +//]; + + +// globalNetworkCheckSettings +// Use this option if you want to use standard login screen without +// hardcoded username/password in config.js (used by globalAccountSettings). +// NOTE: if this option is used the value must be an object. +// List of properties used in globalAccountSettings variable: +// - href +// Set this option to the "principal URL" WITHOUT the "USERNAME/" +// part (this options uses the username from the login screen). +// NOTE: the last character in the value must be '/' +// NOTE: for description of other properties see comments at the beginning +// of this file. +// NOTE: for minimal/fast setup you need to set only the href option. It is +// safe/recommended to keep the remaining options unchanged! +// Example href values: +// OS X server http example (see misc/readme_osx.txt for server setup): +// href: 'http://osx.server.com:8008/principals/users/' +// OS X server https example (see misc/readme_osx.txt for server setup): +// href: 'https://osx.server.com:8443/principals/users/' +// Cyrus server https example: +// href: 'https://cyrus.server.com/dav/principals/user/' +// Example: +// Davical example which automatically detects the protocol, server name, +// port, ... (client installed into Davical "htdocs" subdirectory; +// works "out of the box", no additional setup required): +var globalNetworkCheckSettings={ + href: location.protocol+'//'+location.hostname+ + (location.port ? ':'+location.port: '')+ + location.pathname.replace(RegExp('/+[^/]+/*(index\.html)?$'),'')+ + '/caldav.php/', + timeOut: 90000, + lockTimeOut: 10000, + checkContentType: true, + settingsAccount: true, + delegation: true, + additionalResources: [], + hrefLabel: null, + forceReadOnly: null, + ignoreAlarms: false, + backgroundCalendars: [] +} + + +// globalNetworkAccountSettings +// Try this option ONLY if you have working setup using +// globalNetworkCheckSettings and want to fix the authentication popup +// window problem (if invalid username/password is entered)! +// If you use this option then your browser sends username/password to the PHP +// "auth" module ("auth" directory) instead of the DAV server itself. +// The "auth" module then validates your username/password against your server, +// and if the authentication is successful, then it sends back a configuration +// XML (requires additional configuration). The resulting XML is handled +// IDENTICALLY as the globalAccountSettings configuration option. +// NOTE: for the "auth" module configuration see readme.txt! +// NOTE: this option invokes a login screen and disallows access until +// the client gets correct XML configuration file from the server! +// List of properties used in globalNetworkAccountSettings variable: +// - href +// Set this option to the "full URL" of the "auth" directory +// NOTE: the last character in the value must be '/' +// NOTE: for description of other properties see comments at the beginning +// of this file. +// Example href values: +// href: 'https://server.com/client/auth/' +// Example: +// Use this configuration if the "auth" module is located in the client +// installation subdirectory (default): +//var globalNetworkAccountSettings={ +// href: location.protocol+'//'+location.hostname+ +// (location.port ? ':'+location.port : '')+ +// location.pathname.replace(RegExp('index\.html$'),'')+ +// 'auth/', +// timeOut: 30000 +//}; + + +// globalUseJqueryAuth +// Use jQuery .ajax() auth or custom header for HTTP basic auth (default). +// Set this option to true if your server uses digest auth (note: you may +// experience auth popups on some browsers). +// If undefined (or empty), custom header for HTTP basic auth is used. +// Example: +//var globalUseJqueryAuth=false; + + +// globalBackgroundSync +// Enable background synchronization even if the browser window/tab has no +// focus. +// If false, synchronization is performed only if the browser window/tab +// is focused. If undefined or not false, then background sync is enabled. +// Example: +var globalBackgroundSync=true; + + +// globalSyncResourcesInterval +// This option defines how often (in miliseconds) are resources/collections +// asynchronously synchronized. +// Example: +var globalSyncResourcesInterval=120000; + + +// globalEnableRefresh +// This option enables or disables the manual synchronization button in +// the interface. If this option is enabled then users can perform server +// synchronization manually. Enabling this option may cause high server +// load (even DDOS) if users will try to manually synchronize data too +// often (instead of waiting for the automatic synchronization). +// If undefined or false, the synchronization button is disabled. +// NOTE: enable this option only if you really know what are you doing! +// Example: +var globalEnableRefresh=false; + + +// globalEnableKbNavigation +// Enable basic keyboard navigation using arrow keys? +// If undefined or not false, keyboard navigation is enabled. +// Example: +var globalEnableKbNavigation=true; + + +// globalSettingsType +// Where to store user settings such as: active view, enabled/selected +// collections, ... (the client store them into DAV property on the server). +// NOTE: not all servers support storing DAV properties (some servers support +// only subset /or none/ of these URLs). +// Supported values: +// - 'principal-URL', '', null or undefined (default) => settings are stored +// to principal-URL (recommended for most servers) +// - 'addressbook-home-set' => settings are are stored to addressbook-home-set +// - 'calendar-home-set' => settings are stored to calendar-home-set +// Example: +//var globalSettingsType=''; + + +// globalCrossServerSettingsURL +// Settings such as enabled/selected collections are stored on the server +// (see the previous option) in form of full URL +// (e.g.: https://user@server:port/principal/collection/), but even if this +// approach is "correct" (you can use the same principal URL with multiple +// different logins, ...) it causes a problem if your server is accessible +// from multiple URLs (e.g. http://server/ and https://server/). If you want +// to store only the "principal/collection/" part of the URL (instead of the +// full URL) then enable this option. +// Example: +//var globalCrossServerSettingsURL=false; + + +// globalInterfaceLanguage +// Default interface language (note: this option is case sensitive): +// cs_CZ (Čeština [Czech]) +// da_DK (Dansk [Danish]; thanks Niels Bo Andersen) +// de_DE (Deutsch [German]; thanks Marten Gajda and Thomas Scheel) +// en_US (English [English/US]) +// es_ES (Español [Spanish]; thanks Damián Vila) +// fr_FR (Français [French]; thanks John Fischer) +// it_IT (Italiano [Italian]; thanks Luca Ferrario) +// ja_JP (日本語 [Japan]; thanks Muimu Nakayama) +// hu_HU (Magyar [Hungarian]) +// nl_NL (Nederlands [Dutch]; thanks Johan Vromans) +// sk_SK (Slovenčina [Slovak]) +// tr_TR (Türkçe [Turkish]; thanks Selcuk Pultar) +// ru_RU (Русский [Russian]; thanks Александр Симонов) +// uk_UA (Українська [Ukrainian]; thanks Serge Yakimchuck) +// zh_CN (中国 [Chinese]; thanks Fandy) +// Example: +var globalInterfaceLanguage='fr_FR'; + + +// globalInterfaceCustomLanguages +// If defined and not empty then only languages listed here are shown +// at the login screen, otherwise (default) all languages are shown +// NOTE: values in the array must refer to an existing localization +// (see the option above) +// Example: +// globalInterfaceCustomLanguages=['en_US', 'sk_SK']; +var globalInterfaceCustomLanguages=[]; + + +// globalSortAlphabet +// Use JavaScript localeCompare() or custom alphabet for data sorting. +// Custom alphabet is used by default because JavaScript localeCompare() +// not supports collation and often returns "wrong" result. If set to null +// then localeCompare() is used. +// Example: +// var globalSortAlphabet=null; +var globalSortAlphabet=' 0123456789'+ + 'AÀÁÂÄÆÃÅĀBCÇĆČDĎEÈÉÊËĒĖĘĚFGĞHIÌÍÎİÏĪĮJKLŁĹĽMNŃÑŇOÒÓÔÖŐŒØÕŌ'+ + 'PQRŔŘSŚŠȘșŞşẞTŤȚțŢţUÙÚÛÜŰŮŪVWXYÝŸZŹŻŽ'+ + 'aàáâäæãåābcçćčdďeèéêëēėęěfgğhiìíîïīįıjklłĺľmnńñňoòóôöőœøõō'+ + 'pqrŕřsśšßtťuùúûüűůūvwxyýÿzźżžАБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЮЯ'+ + 'Ьабвгґдеєжзиіїйклмнопрстуфхцчшщюяь'; + + +// globalSearchTransformAlphabet +// To support search without diacritics (e.g. search for 'd' will find: 'Ď', 'ď') +// it is required to define something like "character equivalence". +// key = regex text, value = search character +// Example: +var globalSearchTransformAlphabet={ + '[ÀàÁáÂâÄäÆæÃãÅåĀā]': 'a', '[ÇçĆćČč]': 'c', '[Ďď]': 'd', + '[ÈèÉéÊêËëĒēĖėĘęĚě]': 'e', '[Ğğ]': 'g', '[ÌìÍíÎîİıÏïĪīĮį]': 'i', + '[ŁłĹ弾]': 'l', '[ŃńÑñŇň]': 'n', '[ÒòÓóÔôÖöŐőŒœØøÕõŌō]': 'o', + '[ŔŕŘř]': 'r', '[ŚśŠšȘșŞşẞß]': 's', '[ŤťȚțŢţ]': 't', + '[ÙùÚúÛûÜüŰűŮůŪū]': 'u', '[ÝýŸÿ]': 'y', '[ŹźŻżŽž]': 'z' +}; + +// globalResourceAlphabetSorting +// If more than one resource (server account) is configured, sort the +// resources alphabetically? +// Example: +var globalResourceAlphabetSorting=true; + + +// globalNewVersionNotifyUsers +// Update notification will be shown only to users with login names defined +// in this array. +// If undefined (or empty), update notifications will be shown to all users. +// Example: +// globalNewVersionNotifyUsers=['admin', 'peter']; +var globalNewVersionNotifyUsers=[]; + + +// globalDatepickerFormat +// Set the datepicker format (see +// http://docs.jquery.com/UI/Datepicker/formatDate for valid values). +// NOTE: date format is predefined for each localization - use this option +// ONLY if you want to use custom date format (instead of the localization +// predefined one). +// Example: +//var globalDatepickerFormat='dd.mm.yy'; +var globalDatepickerFormat='yy-mm-dd'; + + +// globalDatepickerFirstDayOfWeek +// Set the datepicker first day of the week: Sunday is 0, Monday is 1, etc. +// Example: +var globalDatepickerFirstDayOfWeek=1; + + +// globalHideInfoMessageAfter +// How long are information messages (such as: success, error) displayed +// (in miliseconds). +// Example: +var globalHideInfoMessageAfter=1800; + + +// globalEditorFadeAnimation +// Set the editor fade in/out animation duration when editing or saving data +// (in miliseconds). +// Example: +var globalEditorFadeAnimation=666; + + + + +// ******* CalDAV (CalDavZAP) related settings ******* // + +// globalEventStartPastLimit, globalEventStartFutureLimit, globalTodoPastLimit +// Number of months pre-loaded from past/future in advance for calendars +// and todo lists (if null then date range synchronization is disabled). +// NOTE: interval synchronization is used only if your server supports +// sync-collection REPORT (e.g. DAViCal). +// NOTE: if you experience problems with data loading and your server has +// no time-range filtering support set these variables to null. +// Example: +var globalEventStartPastLimit=3; +var globalEventStartFutureLimit=3; +var globalTodoPastLimit=1; + + +// globalLoadedCalendarCollections +// This option sets the list of calendar collections (down)loaded after login. +// If empty then all calendar collections for the currently logged user are +// loaded. +// NOTE: settings stored on the server (see settingsAccount) overwrite this +// option. +// Example: +var globalLoadedCalendarCollections=[]; + + +// globalLoadedTodoCollections +// This option sets the list of todo collections (down)loaded after login. +// If empty then all todo collections for the currently logged user are loaded. +// NOTE: settings stored on the server (see settingsAccount) overwrite this +// option. +// Example: +var globalLoadedTodoCollections=[]; + + +// globalActiveCalendarCollections +// This options sets the list of calendar collections checked (enabled +// checkbox => data visible in the interface) by default after login. +// If empty then all loaded calendar collections for the currently logged +// user are checked. +// NOTE: only already (down)loaded collections can be checked (see +// the globalLoadedCalendarCollections option). +// NOTE: settings stored on the server (see settingsAccount) overwrite this +// option. +// Example: +var globalActiveCalendarCollections=[]; + + +// globalActiveTodoCollections +// This options sets the list of todo collections checked (enabled +// checkbox => data visible in the interface) by default after login. +// If empty then all loaded todo collections for the currently logged +// user are checked. +// NOTE: only already (down)loaded collections can be checked (see +// the globalLoadedTodoCollections option). +// NOTE: settings stored on the server (see settingsAccount) overwrite this +// option. +// Example: +var globalActiveTodoCollections=[]; + + +// globalCalendarSelected +// This option sets which calendar collection will be pre-selected +// (if you create a new event) by default after login. +// The value must be URL encoded path to a calendar collection, +// for example: 'USER/calendar/' +// If empty or undefined then the first available calendar collection +// is selected automatically. +// NOTE: only already (down)loaded collections can be pre-selected (see +// the globalLoadedCalendarCollections option). +// NOTE: settings stored on the server (see settingsAccount) overwrite this +// option. +// Example: +//var globalCalendarSelected=''; + + +// globalTodoCalendarSelected +// This option sets which todo collection will be pre-selected +// (if you create a new todo) by default after login. +// The value must be URL encoded path to a todo collection, +// for example: 'USER/todo_calendar/' +// If empty or undefined then the first available todo collection +// is selected automatically. +// NOTE: only already (down)loaded collections can be pre-selected (see +// the globalLoadedTodoCollections option). +// NOTE: settings stored on the server (see settingsAccount) overwrite this +// option. +// Example: +//var globalTodoCalendarSelected=''; + + +// globalActiveView +// This options sets the default fullcalendar view option (the default calendar +// view after the first login). +// Supported values: +// - 'month' +// - 'multiWeek' +// - 'agendaWeek' +// - 'agendaDay' +// NOTE: we use custom and enhanced version of fullcalendar! +// Example: +var globalActiveView='multiWeek'; + + +// globalOpenFormMode +// Open new event form on 'single' or 'double' click. +// If undefined or not 'double', then 'single' is used. +// Example: +var globalOpenFormMode='double'; + + +// globalTodoListFilterSelected +// This options sets the list of filters in todo list that are selected +// after login. +// Supported options: +// - 'filterAction' +// - 'filterProgress' (available only if globalAppleRemindersMode is disabled) +// - 'filterCompleted' +// - 'filterCanceled' (available only if globalAppleRemindersMode is disabled) +// NOTE: settings stored on the server (see settingsAccount) overwrite this +// option. +// Example: +var globalTodoListFilterSelected=['filterAction', 'filterProgress']; + + +// globalCalendarStartOfBusiness, globalCalendarEndOfBusiness +// These options set the start and end of business hours with 0.5 hour +// precision. Non-business hours are faded out in the calendar interface. +// If both variables are set to the same value then no fade out occurs. +// Example: +var globalCalendarStartOfBusiness=8; +var globalCalendarEndOfBusiness=17; + + +// globalDefaultEventDuration +// This option sets the default duration (in minutes) for newly created events. +// If undefined or null, globalCalendarEndOfBusiness value will be taken as +// a default end time instead. +// Example: +var globalDefaultEventDuration=120; + + +// globalAMPMFormat +// This option enables to use 12 hours format (AM/PM) for displaying time. +// NOTE: time format is predefined for each localization - use this option +// ONLY if you want to use custom time format (instead of the localization +// predefined one). +// Example: +//var globalAMPMFormat=false; + + +// globalTimeFormatBasic +// This option defines the time format information for events in month and +// multiweek views. If undefined or null then default value is used. +// If defined as empty string no time information is shown in these views. +// See http://arshaw.com/fullcalendar/docs/utilities/formatDate/ for exact +// formating rules. +// Example: +//var globalTimeFormatBasic=''; + + +// globalTimeFormatAgenda +// This option defines the time format information for events in day and +// week views. If undefined or null then default value is used. +// If defined as empty string no time information is shown in these views. +// See http://arshaw.com/fullcalendar/docs/utilities/formatDate/ for exact +// formating rules. +// Example: +//var globalTimeFormatAgenda=''; + + +// globalDisplayHiddenEvents +// This option defined whether events from unechecked calendars are displayed +// with certain transparency (true) or completely hidden (false). +// Example: +var globalDisplayHiddenEvents=false; + + +// globalTimeZoneSupport +// This option enables timezone support in the client. +// NOTE: timezone cannot be specified for all-day events because these don't +// have start and end time. +// If this option is disabled then local time is used. +// Example: +var globalTimeZoneSupport=true; + + +// globalTimeZone +// If timezone support is enabled, this option sets the default timezone. +// See timezones.js or use the following command to get the list of supported +// timezones (defined in timezones.js): +// grep "'[^']\+': {" timezones.js | sed -Ee "s#(\s*'|':\s*\{)##g" +// Example: +var globalTimeZone='Europe/Paris'; + + +// globalTimeZonesEnabled +// This option sets the list of available timezones in the interface (for the +// list of supported timezones see the comment for the previous configuration +// option). +// NOTE: if there is at least one event/todo with a certain timezone defined, +// that timezone is enabled (even if it is not present in this list). +// Example: +// var globalTimeZonesEnabled=['America/New_York', 'Europe/Berlin']; +var globalTimeZonesEnabled=[]; + + +// globalRewriteTimezoneComponent +// This options sets whether the client will enhance/replace (if you edit an +// event or todo) the timezone information using the official IANA timezone +// database information (recommended). +// Example: +var globalRewriteTimezoneComponent=true; + + +// globalRemoveUnknownTimezone +// This options sets whether the client will remove all non-standard timezone +// names from events and todos (if you edit an event or todo) +// (e.g.: /freeassociation.sourceforge.net/Tzfile/Europe/Vienna) +// Example: +var globalRemoveUnknownTimezone=false; + + +// globalShowHiddenAlarms +// This option sets whether the client will show alarm notifications for +// unchecked calendars. If this option is enabled and you uncheck a calendar +// in the calendar list, alarm notifications will be temporary disabled for +// unchecked calendar(s). +// Example: +var globalShowHiddenAlarms=false; + + +// globalIgnoreCompletedOrCancelledAlarms +// This options sets whether the client will show alarm notifications for +// already completed or cancelled todos. If enabled then alarm notification +// for completed and cancelled todos are disabled. +// Example: +var globalIgnoreCompletedOrCancelledAlarms=true; + + +// globalMozillaSupport +// Mozilla automatically treats custom repeating event calculations as if +// the start day of the week is Monday, despite what day is chosen in settings. +// Set this variable to true to use the same approach, ensuring compatible +// event rendering in special cases. +// Example: +var globalMozillaSupport=false; + + +// globalCalendarColorPropertyXmlns +// This options sets the namespace used for storing the "calendar-color" +// property by the client. +// If true, undefined (or empty) "http://apple.com/ns/ical/" is used (Apple +// compatible). If false, then the calendar color modification functionality +// is completely disabled. +// Example: +//var globalCalendarColorPropertyXmlns=true; + + +// globalWeekendDays +// This option sets the list of days considered as weekend days (these +// are faded out in the calendar interface). Non-weekend days are automatically +// considered as business days. +// Sunday is 0, Monday is 1, etc. +// Example: +var globalWeekendDays=[0, 6]; + + +// globalAppleRemindersMode +// If this option is enabled then then client will use the same approach +// for handling repeating reminders (todos) as Apple. It is STRONGLY +// recommended to enabled this option if you use any Apple clients for +// reminders (todos). +// Supported options: +// - 'iOS6' +// - 'iOS7' +// - true (support of the latest iOS version - 'iOS8') +// - false +// If this option is enabled: +// - RFC todo support is SEVERELY limited and the client mimics the behaviour +// of Apple Reminders.app (to ensure maximum compatibility) +// - when a single instance of repeating todo is edited, it becomes an +// autonomous non-repeating todo with NO relation to the original repeating +// todo +// - capabilities of repeating todos are limited - only the first instance +// is ever visible in the interface +// - support for todo DTSTART attribute is disabled +// - support for todo STATUS attribute other than COMPLETED and NEEDS-ACTION +// is disabled +// - [iOS6 only] support for LOCATION and URL attributes is disabled +// Example: +var globalAppleRemindersMode=true; + + +// globalSubscribedCalendars +// This option specifies a list of remote URLs to ics files (e.g.: used +// for distributing holidays information). Subscribed calendars are +// ALWAYS read-only. Remote servers where ics files are hosted MUST +// return proper CORS headers (see readme.txt) otherwise this functionality +// will not work! +// NOTE: subsribed calendars are NOT "shared" calendars. For "shared" +// calendars see the delegation option in globalAccountSettings, +// globalNetworkCheckSettings and globalNetworkAccountSettings. +// List of properties used in globalSubscribedCalendars variable: +// - hrefLabel +// This options defines the header string above the subcsribed calendars. +// - calendars +// This option specifies an array of remote calendar objects with the +// following properties: +// - href +// Set this option to the "full URL" of the remote calendar +// - userAuth +// NOTE: keep empty if remote authentication is not required! +// - userName +// Set the username you want to login. +// - userPassword +// Set the password for the given username. +// - typeList +// Set the list of objects you want to process from remote calendars; +// two options are available: +// - 'vevent' (show remote events in the interface) +// - 'vtodo' (show remote todos in the interface) +// - ignoreAlarm +// Set this option to true if you want to disable alarm notifications +// from the remote calendar. +// - displayName +// Set this option to the name of the calendar you want to see +// in the interface. +// - color +// Set the calendar color you want to see in the interface. +// Example: +//var globalSubscribedCalendars={ +// hrefLabel: 'Subscribed', +// calendars: [ +// { +// href: 'http://something.com/calendar.ics', +// userAuth: { +// userName: '', +// userPassword: '' +// }, +// typeList: ['vevent', 'vtodo'], +// ignoreAlarm: true, +// displayName: 'Remote Calendar 1', +// color: '#ff0000' +// }, +// { +// href: 'http://calendar.com/calendar2.ics', +// ... +// ... +// } +// ] +//}; + + + +// ******* CardDAV (CardDavMATE) related settings ******* // + + +// globalLoadedAddressbookCollections +// This option sets the list of addressbook collections (down)loaded after +// login. If empty then all addressbook collections for the currently logged +// user are loaded. +// NOTE: settings stored on the server (see settingsAccount) overwrite this +// option. +// Example: +var globalLoadedAddressbookCollections=[]; + + +// globalActiveAddressbookCollections +// This options sets the list of addressbook collections checked (enabled +// checkbox => data visible in the interface) by default after login. +// If empty then all loaded addressbook collections for the currently logged +// user are checked. +// NOTE: only already (down)loaded collections can be checked (see +// the globalLoadedAddressbookCollections option). +// NOTE: settings stored on the server (see settingsAccount) overwrite this +// option. +// Example: +var globalActiveAddressbookCollections=[]; + + +// globalAddressbookSelected +// This option sets which addressbook collection will be pre-selected +// (if you create a new contact) by default after login. +// The value must be URL encoded path to an addressbook collection, +// for example: 'USER/addressbook/' +// If empty or undefined then the first available addressbook collection +// is selected automatically. +// NOTE: only already (down)loaded collections can be pre-selected (see +// the globalLoadedAddressbookCollections option). +// NOTE: settings stored on the server (see settingsAccount) overwrite this +// option. +// Example: +//var globalAddressbookSelected=''; + + +// globalCompatibility +// This options is reserved for various compatibility settings. +// NOTE: if this option is used the value must be an object. +// Currently there is only one supported option: +// - anniversaryOutputFormat +// Different clients use different (and incompatible) approach +// to store anniversary date in vCards. Apple stores this attribute as: +// itemX.X-ABDATE;TYPE=pref:2000-01-01\r\n +// itemX.X-ABLabel:_$!!$_\r\n' +// other clients store this attribute as: +// X-ANNIVERSARY:2000-01-01\r\n +// Choose 'apple' or 'other' (lower case) for your 3rd party client +// compatibility. You can chose both: ['apple', 'other'], but it may +// cause many problems in the future, for example: duplicate anniversary +// dates, invalid/old anniversary date in your clients, ...) +// Examples: +// anniversaryOutputFormat: ['other'] +// anniversaryOutputFormat: ['apple', 'other'] +// Example: +var globalCompatibility={anniversaryOutputFormat: ['apple']}; + + +// globalUriHandler{Tel,Email,Url,Profile} +// These options set the URI handlers for TEL, EMAIL, URL and X-SOCIALPROFILE +// vCard attributes. Set them to null (or comment out) to disable. +// NOTE: for globalUriHandlerTel is recommended to use 'tel:', 'callto:' +// or 'skype:'. The globalUriHandlerUrl value is used only if no URI handler +// is defined in the URL. +// NOTE: it is safe to keep these values unchanged! +// Example: +var globalUriHandlerTel='tel:'; +var globalUriHandlerEmail='mailto:'; +var globalUriHandlerUrl='http://'; +var globalUriHandlerProfile={ + 'twitter': 'http://twitter.com/%u', + 'facebook': 'http://www.facebook.com/%u', + 'flickr': 'http://www.flickr.com/photos/%u', + 'linkedin': 'http://www.linkedin.com/in/%u', + 'myspace': 'http://www.myspace.com/%u', + 'sinaweibo': 'http://weibo.com/n/%u' +}; + + +// globalDefaultAddressCountry +// This option sets the default country for new address fields. +// See common.js or use the following command to get the list of +// all supported country codes (defined in common.js): +// grep -E "'[a-z]{2}':\s+\[" common.js | sed -Ee 's#^\s+|\s+\[\s+# #g' +// Example: +var globalDefaultAddressCountry='fr'; + + +// globalAddressCountryEquivalence +// This option sets the processing of the country field specified +// in the vCard ADR attribute. +// By default the address field in vCard looks like: +// ADR;TYPE=WORK:;;1 Waters Edge;Baytown;LA;30314;USA\r\n +// what cause a problem, because the country field is a plain +// text and can contain any value, e.g.: +// USA +// United States of America +// US +// and because the address format can be completely different for +// each country, e.g.: +// China address example: +// [China] +// [Province] [City] +// [Street] +// [Postal] +// Japan address example: +// [Postal] +// [Prefecture] [County/City] +// [Further Divisions] +// [Japan] +// the client needs to correctly detect the country from the ADR +// attribute. Apple solved this problem by using: +// item1.ADR;TYPE=WORK:;;1 Waters Edge;Baytown;LA;30314;USA\r\n +// item1.X-ABADR:us\r\n +// where the second "related" attribute defines the country code +// for the ADR attribute. This client uses the same approach, but +// if the vCard is created by 3rd party clients and the X-ABADR +// is missing, it is possible to define additional "rules" for +// country matching. These rules are specied by the country code +// (for full list of country codes see the comment for pre previous +// option) and a case insensitive regular expression (which matches +// the plain text value in the country field). +// NOTE: if X-ABADR is not present and the country not matches any +// country defined in this option, then globalDefaultAddressCountry +// is used by default. +// Example: +var globalAddressCountryEquivalence=[ + {country: 'de', regex: '^\\W*Deutschland\\W*$'}, + {country: 'sk', regex: '^\\W*Slovensko\\W*$'} +]; + + +// globalAddressCountryFavorites +// This option defines the list of countries which are shown at the top +// of the country list in the interface (for full list of country codes +// see the comment for pre globalDefaultAddressCountry option). +// Example: +// var globalAddressCountryFavorites=['de','sk']; +var globalAddressCountryFavorites=[]; + + +// globalAddrColorPropertyXmlns +// This options sets the namespace used for storing the "addressbook-color" +// property by the client. +// If true, undefined (or empty) "http://inf-it.com/ns/ab/" is used. +// If false, then the addressbook color modification functionality +// is completely disabled, and addressbook colors in the interface are +// generated automatically. +// Example: +//var globalAddrColorPropertyXmlns=true; + + +// globalContactStoreFN +// This option specifies how the FN (formatted name) is stored into vCard. +// The value for this options must be an array of strings, that can contain +// the following variables: +// prefix +// last +// middle +// first +// suffix +// The string element of the array can contain any other characters (usually +// space or colon). Elements are added into FN only if the there is +// a variable match, for example if: +// last='Lastname' +// first='Firstname' +// middle='' (empty) +// and this option is set to: +// ['last', ' middle', ' first'] (space in the second and third element) +// the resulting value for FN will be: 'Lastname Firstname' and not +// 'Lastname Firstname' (two spaces), because the middle name is empty (so +// the second element is completely ignored /not added into FN/). +// NOTE: this attribute is NOT used by this client, and it is also NOT +// possible to directly edit it in the interface. +// Examples: +// var globalContactStoreFN=[' last', ' middle', ' first']; +// var globalContactStoreFN=['last', ', middle', ' ,first']; +var globalContactStoreFN=['prefix',' last',' middle',' first',' suffix']; + + +// globalGroupContactsByCompanies +// This options specifies how contacts are grouped in the interface. +// By default the interface looks like (very simple example): +// A +// Adams Adam +// Anderson Peter +// B +// Brown John +// Baker Josh +// if grouped by company/deparment the result is: +// Company A [Department X] +// Adams Adam +// Brown John +// Company B [Department Y] +// Anderson Peter +// Baker Josh +// If this option is set to true contacts are grouped by company/department, +// otherwise (default) contacts are grouped by letters of the alphabet. +// If undefined or not true, grouping by alphabet letters is used. +// NOTE: see also the globalCollectionDisplay option below. +var globalGroupContactsByCompanies=false; + + +// globalCollectionDisplay +// This options specifies how data columns in the contact list are displayed. +// +// NOTE: columns are displayed ONLY if there is enought horizontal place in +// the browser window (e.g. if you define 5 columns here, but your browser +// window is not wide enough, you will see only first 3 columns instead of 5). +// +// NOTE: see the globalContactDataMinVisiblePercentage option which defines the +// width for columns. +// +// The value must be an array of columns, where each column is represented by +// an object with the following properties: +// label => the value of this option is a string used as column header +// You can use the following localized variables in the label string: +// - {Name} +// - {FirstName} +// - {LastName} +// - {MiddleName} +// - {NickName} +// - {Prefix} +// - {Suffix} +// - {BirthDay} +// - {PhoneticLastName} +// - {PhoneticFirstName} +// - {JobTitle} +// - {Company} +// - {Department} +// - {Categories} +// - {NoteText} +// - {Address}, {AddressWork}, {AddressHome}, {AddressOther} +// - {Phone}, {PhoneWork}, {PhoneHome}, {PhoneCell}, {PhoneMain}, +// {PhonePager}, {PhoneFax}, {PhoneIphone}, {PhoneOther} +// - {Email}, {EmailWork}, {EmailHome}, {EmailMobileme}, {EmailOther} +// - {URL}, {URLWork}, {URLHome}, {URLHomepage}, {URLOther} +// - {Dates}, {DatesAnniversary}, {DatesOther} +// - {Related}, {RelatedManager}, {RelatedAssistant}, {RelatedFather}, +// {RelatedMother}, {RelatedParent}, {RelatedBrother}, {RelatedSister}, +// {RelatedChild}, {RelatedFriend}, {RelatedSpouse}, {RelatedPartner}, +// {RelatedOther} +// - {Profile}, {ProfileTwitter}, {ProfileFacebook}, {ProfileFlickr}, +// {ProfileLinkedin}, {ProfileMyspace}, {ProfileSinaweibo} +// - {IM}, {IMWork}, {IMHome}, {IMMobileme}, {IMOther}, {IMAim}, {IMIcq}, +// {IMIrc}, {IMJabber}, {IMMsn}, {IMYahoo}, {IMFacebook}, {IMGadugadu}, +// {IMGoogletalk}, {IMQq}, {IMSkype} +// value => the value of this option is an array of format strings, or +// an object with the following properties: +// - company (used for company contacts) +// - personal (used for user contacts) +// where the value of these properties is an array of format strings used +// for company or user contacts (you can have different values in the same +// column for personal and company contacts). +// You can use the following simple variables in the format string: +// - {FirstName} +// - {LastName} +// - {MiddleName} +// - {NickName} +// - {Prefix} +// - {Suffix} +// - {BirthDay} +// - {PhoneticLastName} +// - {PhoneticFirstName} +// - {JobTitle} +// - {Company} +// - {Department} +// - {Categories} +// - {NoteText} +// You can also use parametrized variables, where the parameter is enclosed +// in square bracket. Paramatrized variables are useful to extract data +// such as home phone {Phone[type=home]}, extract the second phone number +// {Phone[:1]} (zero based indexing) or extract the third home phone number +// {Phone[type=home][:2]} from the vCard. +// NOTE: if the parametrized variable matches multiple items, e.g.: +// {Phone[type=work]} (if the contact has multiple work phones) then the +// first one is used! +// +// The following parametrized variables are supported (note: you can use +// all of them also without parameters /the first one will be used/): +// - {Address[type=XXX]} or {Address[:NUM]} or {Address[type=XXX][:NUM]} +// where supported values for XXX are: +// - work +// - home +// - other +// - any other custom value +// - {Phone[type=XXX]} or {Phone[:NUM]} or {Phone[type=XXX][:NUM]} +// where supported values for XXX are: +// - work +// - home +// - cell +// - main +// - pager +// - fax +// - iphone +// - other +// - any other custom value +// - {Email[type=XXX]} or {Email[:NUM]} or {Email[type=XXX][:NUM]} +// where supported values for XXX are: +// - work +// - home +// - mobileme +// - other +// - any other custom value +// - {URL[type=XXX]} or {URL[:NUM]} or {URL[type=XXX][:NUM]} +// where supported values for XXX are: +// - work +// - home +// - homepage +// - other +// - any other custom value +// - {Dates[type=XXX]} or {Dates[:NUM]} or {Dates[type=XXX][:NUM]} +// where supported values for XXX are: +// - anniversary +// - other +// - any other custom value +// - {Related[type=XXX]} or {Related[:NUM]} or {Related[type=XXX][:NUM]} +// where supported values for XXX are: +// - manager +// - assistant +// - father +// - mother +// - parent +// - brother +// - sister +// - child +// - friend +// - spouse +// - partner +// - other +// - any other custom value +// - {Profile[type=XXX]} or {Profile[:NUM]} or {Profile[type=XXX][:NUM]} +// where supported values for XXX are: +// - twitter +// - facebook +// - flickr +// - linkedin +// - myspace +// - sinaweibo +// - any other custom value +// - {IM[type=XXX]} or {IM[service-type=YYY]} or {IM[:NUM]} +// where supported values for XXX are: +// - work +// - home +// - mobileme +// - other +// - any other custom value +// and supported values for YYY are: +// - aim +// - icq +// - irc +// - jabber +// - msn +// - yahoo +// - facebook +// - gadugadu +// - googletalk +// - qq +// - skype +// - any other custom value +// +// NOTE: if you want to use the "any other custom value" option (for XXX +// or YYY above) you MUST double escape the following characters: +// =[]{}\ +// for example: +// - for profile type "=XXX=" use: '{Profile[type=\\=XXX\\=]}' +// - for profile type "\XXX\" use: '{Profile[type=\\\\XXX\\\\]}' +// +// NOTE: if you want to use curly brackets in the format string you must +// double escape it, e.g.: ['{Company}', '\\{{Department}\\}'] +// +// The format string (for the value option) is an array to allow full +// customization of the interface. For example if: +// value: ['{LastName} {MiddleName} {FirstName}'] +// and the person has no middle name, then the result in the column +// will be (without quotes): +// "Parker Peter" (note: two space characters) +// but if you use: +// value: ['{LastName}', ' {MiddleName}', ' {FirstName}'] +// then the result will be (without quotes): +// "Parker Peter" (note: only one space character) +// The reason is that only those elements of the array are appended +// into the result where non-empty substitution was performed (so the +// ' {MiddleName}' element in this case is ignored, because the person +// in the example above has no /more precisely has empty/ middle name). +// +// Examples: +// To specify two columns (named "Company" and "Department / LastName"), +// where the first will display the company name, and the second will display +// department for company contacts (with "Dep -" prefix), and lastname for +// personal contacts (with "Name -" prefix) use: +// var globalCollectionDisplay=[ +// { +// label: 'Company', +// value: ['{Company}'] +// }, +// { +// label: 'Department / LastName', +// value: { +// company: ['Dep - {Department}'], +// personal: ['Name - {LastName}'] +// } +// } +// ]; +// To specify 3 columns (named "Categories", "URL" and "IM"), where the first +// will display categories, second will display the third work URL, and third +// will display ICQ IM use: +// var globalCollectionDisplay=[ +// { +// label: 'Categories', +// value: ['{Categories}'] +// }, +// { +// label: 'URL', +// value: ['{URL[type=WORK][:2]}'] +// }, +// { +// label: 'IM', +// value: ['{IM[service-type=ICQ]}'] +// } +// ]; +// +// Recommended settings if globalGroupContactsByCompanies +// is set to false: +// var globalCollectionDisplay=[ +// { +// label: '{Name}', +// value: ['{LastName}', ' {MiddleName}', ' {FirstName}'] +// }, +// { +// label: '{Company} [{Department}]', +// value: ['{Company}', ' [{Department}]'] +// }, +// { +// label: '{JobTitle}', +// value: ['{JobTitle}'] +// }, +// { +// label: '{Email}', +// value: ['{Email[:0]}'] +// }, +// { +// label: '{Phone} 1', +// value: ['{Phone[:0]}'] +// }, +// { +// label: '{Phone} 2', +// value: ['{Phone[:1]}'] +// }, +// { +// label: '{NoteText}', +// value: ['{NoteText}'] +// } +// ]; +// +// Recommended settings if globalGroupContactsByCompanies +// is set to true: +// var globalCollectionDisplay=[ +// { +// label: '{Name}', +// value: { +// personal: ['{LastName}', ' {MiddleName}', ' {FirstName}'], +// company: ['{Company}', ' [{Department}]'] +// } +// }, +// { +// label: '{JobTitle}', +// value: ['{JobTitle}'] +// }, +// { +// label: '{Email}', +// value: ['{Email[:0]}'] +// }, +// { +// label: '{Phone} 1', +// value: ['{Phone[:0]}'] +// }, +// { +// label: '{Phone} 2', +// value: ['{Phone[:1]}'] +// }, +// { +// label: '{NoteText}', +// value: ['{NoteText}'] +// } +// ]; +// +// NOTE: if left undefined, the recommended settings will be used. + + +// globalCollectionSort +// This options sets the ordering of contacts in the interface. In general +// contacts are ordered alphabetically by an internal "sort string" which +// is created for each contact. Here you can specify how this internal string +// is created. The value is a simple array holding only the values from the +// value property defined in the globalCollectionDisplay option. +// If undefined, the definition from globalCollectionDisplay is used. +// Example: +// var globalCollectionSort = [ +// ['{LastName}'], +// ['{FirstName}'], +// ['{MiddleName}'], +// { +// company: ['{Categories}'], +// personal: ['{Company}'] +// } +// ]; +var globalCollectionSort=[ + ['{LastName}'], + ['{FirstName}'], + ['{MiddleName}'] +]; + + +// globalContactDataMinVisiblePercentage +// This option defines how the width for columns are computed. If you set +// it to 1 then 100% of all data in the column will be visible (the column +// width is determined by the longest string in the column). If you set it +// to 0.95 then 95% of data will fit into the column width, and the remaining +// 5% will be truncated (" ..."). +// Example: +var globalContactDataMinVisiblePercentage=0.95; + + diff --git a/virtual/modules/websites/tools/db/default.nix b/virtual/modules/websites/tools/db/default.nix new file mode 100644 index 0000000..20f77c7 --- /dev/null +++ b/virtual/modules/websites/tools/db/default.nix @@ -0,0 +1,23 @@ +{ lib, pkgs, config, mylibs, ... }: +let + adminer = pkgs.callPackage ../../commons/adminer.nix {}; + + cfg = config.services.myWebsites.tools.databases; +in { + options.services.myWebsites.tools.databases = { + enable = lib.mkEnableOption "enable database's website"; + }; + + config = lib.mkIf cfg.enable { + # FIXME: include it in vhostConf ? + security.acme.certs."eldiron".extraDomains."db-1.immae.eu" = null; + + services.myWebsites.tools.modules = adminer.apache.modules; + services.myWebsites.tools.vhostConfs.db-1 = { + certName = "eldiron"; + hosts = ["db-1.immae.eu" ]; + root = null; + extraConfig = [ adminer.apache.vhostConf ]; + }; + }; +} diff --git a/virtual/modules/websites/tools/git/default.nix b/virtual/modules/websites/tools/git/default.nix new file mode 100644 index 0000000..0a63013 --- /dev/null +++ b/virtual/modules/websites/tools/git/default.nix @@ -0,0 +1,46 @@ +{ lib, pkgs, config, mylibs, ... }: +let + mantisbt = pkgs.callPackage ./mantisbt/mantisbt.nix { inherit (mylibs) checkEnv fetchedGithub; }; + gitweb = pkgs.callPackage ./gitweb/gitweb.nix { gitoliteDir = config.services.myGitolite.gitoliteDir; }; + + cfg = config.services.myWebsites.tools.git; +in { + options.services.myWebsites.tools.git = { + enable = lib.mkEnableOption "enable git's website"; + }; + + config = lib.mkIf cfg.enable { + # FIXME: include it in vhostConf ? + security.acme.certs."eldiron".extraDomains."git.immae.eu" = null; + + nixpkgs.config.packageOverrides = oldpkgs: rec { + gitweb = oldpkgs.gitweb.overrideAttrs(old: { + installPhase = old.installPhase + '' + cp -r ${./gitweb/theme} $out/gitweb-theme; + ''; + }); + }; + + services.myWebsites.tools.modules = + gitweb.apache.modules ++ + mantisbt.apache.modules; + + services.myWebsites.tools.vhostConfs.git = { + certName = "eldiron"; + hosts = ["git.immae.eu" ]; + root = gitweb.webRoot; + extraConfig = [ + gitweb.apache.vhostConf + mantisbt.apache.vhostConf + '' + RewriteEngine on + RewriteCond %{REQUEST_URI} ^/releases + RewriteRule /releases(.*) https://release.immae.eu$1 [P,L] + '' + ]; + }; + services.myPhpfpm.poolConfigs = { + mantisbt = mantisbt.phpFpm.pool; + }; + }; +} diff --git a/virtual/modules/websites/tools/git/gitweb/gitweb.nix b/virtual/modules/websites/tools/git/gitweb/gitweb.nix new file mode 100644 index 0000000..7b4dcac --- /dev/null +++ b/virtual/modules/websites/tools/git/gitweb/gitweb.nix @@ -0,0 +1,64 @@ +{ gitweb, writeText, gitolite, git, gitoliteDir }: +rec { + varDir = gitoliteDir; + webRoot = gitweb; + config = writeText "gitweb.conf" '' + $git_temp = "/tmp"; + + # The directories where your projects are. Must not end with a + # slash. + $projectroot = "${varDir}/repositories"; + + $projects_list = "${varDir}/projects.list"; + $strict_export = "true"; + + # Base URLs for links displayed in the web interface. + our @git_base_url_list = qw(ssh://gitolite@git.immae.eu https://git.immae.eu); + + $feature{'blame'}{'default'} = [1]; + $feature{'avatar'}{'default'} = ['gravatar']; + $feature{'highlight'}{'default'} = [1]; + + @stylesheets = ("gitweb-theme/gitweb.css"); + $logo = "gitweb-theme/git-logo.png"; + $favicon = "gitweb-theme/git-favicon.png"; + $javascript = "gitweb-theme/gitweb.js"; + $logo_url = "https://git.immae.eu/"; + $projects_list_group_categories = "true"; + $projects_list_description_width = 60; + $project_list_default_category = "__Others__"; + ''; + apache = { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "cgid" ]; + vhostConf = '' + SetEnv GIT_PROJECT_ROOT ${varDir}/repositories/ + ScriptAliasMatch \ + "(?x)^/(.*/(HEAD | \ + info/refs | \ + objects/(info/[^/]+ | \ + [0-9a-f]{2}/[0-9a-f]{38} | \ + pack/pack-[0-9a-f]{40}\.(pack|idx)) | \ + git-(upload|receive)-pack))$" \ + ${git}/libexec/git-core/git-http-backend/$1 + + + Require all granted + + + Require all granted + + + DirectoryIndex gitweb.cgi + Require all granted + AllowOverride None + Options ExecCGI FollowSymLinks + + SetHandler cgi-script + SetEnv GITWEB_CONFIG "${config}" + + + ''; + }; +} diff --git a/virtual/modules/websites/tools/git/gitweb/theme/git-favicon.png b/virtual/modules/websites/tools/git/gitweb/theme/git-favicon.png new file mode 100644 index 0000000..4fa44bb Binary files /dev/null and b/virtual/modules/websites/tools/git/gitweb/theme/git-favicon.png differ diff --git a/virtual/modules/websites/tools/git/gitweb/theme/git-logo.png b/virtual/modules/websites/tools/git/gitweb/theme/git-logo.png new file mode 100644 index 0000000..fdaf7b7 Binary files /dev/null and b/virtual/modules/websites/tools/git/gitweb/theme/git-logo.png differ diff --git a/virtual/modules/websites/tools/git/gitweb/theme/gitweb.css b/virtual/modules/websites/tools/git/gitweb/theme/gitweb.css new file mode 100644 index 0000000..83e0742 --- /dev/null +++ b/virtual/modules/websites/tools/git/gitweb/theme/gitweb.css @@ -0,0 +1,783 @@ +/* Reset +------------------------------------------------------------------------- */ + +/* Based on http://meyerweb.com/eric/tools/css/reset/ */ +/* v1.0 | 20080212 */ + +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, +blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, +font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, +u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, +caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; + vertical-align: baseline; + background: transparent; +} + +ol, ul { list-style: none; } + +blockquote, q { quotes: none; } + +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} + +:focus { outline: 0; } + +ins { text-decoration: none; } + +del { text-decoration: line-through; } + +table { + border-collapse: collapse; + border-spacing: 0; +} + +a { outline: none; } + +/* General +---------------------------------------------------------------------------- */ + +html { + position: relative; + min-height: 100%; +} + +body { + font: 13px Helvetica,arial,freesans,clean,sans-serif; + line-height: 1.4; + margin: 0 0 105px; + background-color: #fff; + color: #000000; +} + +/* Monospaced Fonts */ +.sha1, .mode, .diff_tree .list, .pre, .diff, .patchset { + font-family: 'Consolas','Bitstream Vera Sans Mono',monospace; +} + +a:link, a:visited { + color: #4183C4; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +td.list a[href*='tree'], td.list a[href*='blob'] { + padding-left: 20px; + display: block; + float: left; + height: 16px; + line-height: 16px; +} + +td.list a[href*='tree'] { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABq0lEQVQ4y8WTu4oUQRSGv+rtGVuxhwVFdFEEE2c3d0HYTEMTn8DEVxADQTDUF9DMwMxQMBMx8AEWzRQ3cBHd9TI91+2urjq/QbczY2IygSep4nD+79yqnCRWsYQVbWVACvDh5ZXdrLe15dwyT1TjT/sxFFeB6i+VA2B6+cb7kAI4Jf0LO087zjlQI8Y5Qvnj0sHug321XoC1bk+K9eHk6+s7wPMUgKAS88eqb4+Jfg2SHs7lZBvX2Nh+2EUCDGSAcMnJsx9f7NxfAGqXyDzRd5EJO/pMPT1gcviGTnYOVIN5pAAE8v7dLrKL8xnglFk4ws9Afko9HpH3b5Gd2mwb/lOBmgrSdYhJugDUCenxM6xv3p4HCsP8F0LxCsUhCkMURihOyM7fg0osASTFEpu9a4LjGIUCqwcoDiEUrX+E4hRUQb20RiokC1j9vckUhygU7X3QZh7NAVKYL7YBeMkRUfjVCotF2XGIwnghtrJpMywB5G0QZj9P1JNujuWJ1AHLQadRrACPkuZ0SSSWpeStWgDK6tHek5vbiOs48n++XQHurcf0rFng//6NvwG+iB9/4duaTgAAAABJRU5ErkJgggo=) center left no-repeat; +} + +td.list a[href*='blob'] { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAA6ElEQVQoFQXBMW5TQRgGwNnHnoE0QbiCjoIooUmTU3AuS1BwIoTSUdJBigg3GCWOg9/++zHTop078wIAsPMrE4SL5/1aIyMjIyMjz/m0tbFECFdrPeaQQw75mz/5nZH7fN7aWILmauSYfznmmIfss8vIUx7zZWsTTXM5vpWvTk5Wq9VHQP/gtgOLa0Qpw940vAQdaG6thpOhlOkG0AEuAVGmEkAH+G4YSikxXQM6wDsAMRFAB/ihDNNUmN4DOsAbBAEAdICfpmmaAt4COoj2GgCASbIkZh1NAACznhQt2itnFgAAlF3u/gMDtJXPzQxoswAAAABJRU5ErkJgggo=) center left no-repeat; +} + +i { + font-style: normal; +} + +td, th { + padding: 5px; +} + +.page_nav br { + display: none; +} + +/* Page Header +---------------------------------------------------------------------------- */ + +.page_header { + height: 50px; + line-height: 50px; + position: relative; + padding: 0 27px; + margin-bottom: 20px; + font-size: 20px; + font-family: Helvetica, Arial, Freesans, Clean, sans-serif; + background: #FFFFFF; /* old browsers */ + background: -moz-linear-gradient(top, #FFFFFF 0%, #F5F5F5 100%); /* firefox */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FFFFFF), color-stop(100%,#F5F5F5)); /* webkit */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FFFFFF', endColorstr='#F5F5F5',GradientType=0 ); /* ie */ + background: -o-linear-gradient(top, #FFFFFF 0%, #F5F5F5 100%); + border-bottom: 1px solid #dfdfdf; +} + +.page_header a:link, .page_header a:visited { + color: #4183C4; + text-decoration: none; + padding: 3px; + font-weight: bold; +} + +.page_header a:hover { + font-weight: bold; + padding: 3px; + text-decoration: underline; +} + +.page_header a:first-child { + background: transparent; +} + +.page_header img.logo { + position: relative; + top: 7px; + margin-right: 5px; +} + +/* Page Footer +---------------------------------------------------------------------------- */ + +.page_footer { + position: absolute; + left: 0; + bottom: 0; + width: 100%; + height: 80px; + line-height: 80px; + margin-top: 15px; + background: #f1f1f1; + border-top: 2px solid #ddd; + border-bottom: 1px solid #ddd; +} + +.page_footer_text { + color: #666; + display: inline; + float: left; + margin-left: 25px; + width: 80%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +a.rss_logo { + float: right; + padding: 3px 1px; + width: 35px; + line-height: 10px; + border: 1px solid; + border-color: #fcc7a5 #7d3302 #3e1a01 #ff954e; + color: #ffffff; + background-color: #ff6600; + font-weight: bold; + font-family: sans-serif; + font-size: 80%; + text-align: center; + text-decoration: none; + margin-top: 30px; + margin-left: 5px; +} + +a.rss_logo:hover { + background-color: #ee5500; +} + +.rss_logo { + margin-right: 25px; + background: yellow; +} + +.rss_logo:last-child { + margin-right: 5px; +} + +/* Index include +---------------------------------------------------------------------------- */ + +.index_include { + width: 95%; + margin: 0 auto 15px; + background: -moz-linear-gradient(center top , #FFFFFF 0%, #F5F5F5 100%) repeat scroll 0 0 transparent; + border: 1px solid #DFDFDF; + padding: 8px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +/* Elements +---------------------------------------------------------------------------- */ + +.project_list, +.shortlog, +.tree, +.commit_search, +.history { + width: 95%; + margin: 0 auto 15px auto; + border: 1px solid #d8d8d8; + -moz-box-shadow: 0 0 3px rgba(0,0,0,0.2); + -webkit-box-shadow: 0 0 3px rgba(0,0,0,0.2); + box-shadow: 0 0 3px rgba(0,0,0,0.2); +} + +.project_list th, +.shortlog th, +.tree th, +.commit_search th { + color: #afafaf; + font-weight: normal; +} + +.project_list th { + font-weight: bold; +} + +.project_list tr, +.shortlog tr, +.tree tr, +.commit_search tr { + background: #eaeaea; + height: 2.5em; + text-align: left; + color: #545454; +} + +.project_list tr.dark, .project_list tr.light, +.shortlog tr.dark, .shortlog tr.light, +.tree tr.dark, .tree tr.light, +.commit_search tr.dark, .commit_search tr.light, +.history tr.dark, .history tr.light, +.heads tr.dark, .heads tr.light { + background: #F9F9F9; /* old browsers */ + background: -moz-linear-gradient(top, #F9F9F9 0%, #EFEFEF 100%); /* firefox */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#F9F9F9), color-stop(100%,#EFEFEF)); /* webkit */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#F9F9F9', endColorstr='#EFEFEF',GradientType=0 ); /* ie */ + background: -o-linear-gradient(top, #F9F9F9 0%, #EFEFEF 100%); + height: 2.5em; + border-bottom: 1px solid #e1e1e1; +} + +th .header { + background: transparent; + border: 0; + padding: 0; + font-weight: bold; +} + +.tree { + width: 100%; + margin: 0; +} + +.projsearch { + position: absolute; + right: 4%; + top: 15px; +} + +.projsearch a { + display: none; +} + +.commit_search { + background: #eaeaea; +} + +.page_nav, +.list_head, +.page_path, +.search { + width: 94%; + background: #eaeaea; + color: #545454; + border: 1px solid #d8d8d8; + padding: 5px; + margin: 0 auto 15px auto; +} + +.history { + background: #eaeaea; +} + +.title { + margin: 0 auto 15px auto; + padding: 5px; + width: 95%; +} + +.readme { + background: #eaf2f5; + border: 1px solid #bedce7; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + margin: 0 auto 15px auto; + padding: 15px; + width: 95%; +} + +.readme h1 { + display: block; + font-size: 2em; + font-weight: bold; + margin-bottom: 0.67em; + margin-top: 0; +} + +.readme h2 { + font-size: 1.5em; + font-weight: bold; + margin-bottom: 0.83em; +} + + +.readme h3 { + font-size: 1.17em; + font-weight: bold; + margin-bottom: 1em; +} + +.readme p { + margin-bottom: 1em; +} + +.readme ul { + list-style: disc; + margin-bottom: 1em; + margin-left: 1.5em; +} + +.readme ul ul { + margin-bottom: 0; +} + +.readme ol { + list-style: decimal; + margin-bottom: 1em; + margin-left: 1.5em; +} + +.readme ol ol { + margin-bottom: 0; +} + +.readme pre { + font-family: monospace; + margin: 1em 0; + white-space: pre; +} + +.readme tt, .readme code, .readme kbd, .readme samp { + font-family: monospace; +} + +.readme blockquote { + margin: 1em; +} + +.projects_list, +.tags { + width: 95%; + background: #f0f0f0; + color: #545454; + border: 1px solid #d8d8d8; + padding: 5px; + margin: 0 auto 15px auto; +} + +.heads { + width: 95%; + color: #545454; + border: 1px solid #d8d8d8; + padding: 5px; + margin: 0 auto 15px auto; +} + +.header { + width: 94%; + margin: 0 auto 15px auto; + background: #eaf2f5; + border: 1px solid #bedce7; + padding: 5px; +} + +.header .age { + float: left; + color: #000; + font-weight: bold; + width: 10em; +} + +.title_text { + width: 94%; + background: #eaf2f5; + border: 1px solid #bedce7; + padding: 5px; + margin: 0 auto 0 auto; +} + +.log_body { + width: 94%; + background: #eaf2f5; + border: 1px solid #bedce7; + border-top: 0; + padding: 5px; + margin: 0 auto 15px auto; +} + +.page_body { + line-height: 1.4em; + width: 94%; + background: #f8f8f8; + border: 1px solid #d8d8d8; + padding: 5px; + margin: 15px auto 15px auto; +} + +.diff_tree { + width: 95%; + background: #f0f0f0; + border: 1px solid #d8d8d8; + padding: 5px; + margin: 0 auto 15px auto; +} + +.page_body > .list_head { + width: 98.5%; +} + +.page_body > .diff_tree { + width: 99.5%; +} + +.patch > .header { + width: 99%; +} + +.author .avatar, +.author_date .avatar { + position: relative; + top: 3px; +} + +.object_header .avatar { + border: 1px solid #D8D8D8; + float: right; +} + +.object_header td, +.object_header th { + vertical-align: top; +} + +/* Refs +---------------------------------------------------------------------------- */ + +span.refs span { + color: #707070; + display: inline-block; + margin: 0; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 3px; + height: 18px; + padding: 0 6px; + text-overflow: ellipsis; +} + +span.refs span.ref { + color: #707070; + display: inline-block; + margin: 0; + background-color: #c4c4ff; + border: 1px solid #7878ff; + border-radius: 3px; + height: 18px; + padding: 0 6px; + text-overflow: ellipsis; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIKFSUnpolg7AAAAHJQTFRFAAAAVVWqZmbMVVXVYGDgbW3td3fuc3PzdHT0cHD1d3f6dHT6dnb7dHT7dnb8dnb8dnb9d3f9dnb+eHj+d3f+eHj+d3f+d3f+d3f+eHj+d3f+eHj+d3f+eHj+d3f+d3f+eHj+d3f+d3f+d3f+eHj/////V9oQhQAAACR0Uk5TAAIEBQcNDhMVGCotNTZAT217i5CgobvExtjZ4eLr7vP09ff7uqQ6cgAAAAFiS0dEJcMByQ8AAABUSURBVBjTpc43AoAwDENRh95bgNBM1f3PyOpslD++RSJ61YgH5M2IbIkn4GocSR1MZVBL4t2n4FgkbaxI8Sqph041WknZCWAIrcmEUbpf3lNe0N9u59YFYHnZ78gAAAAASUVORK5CYII=); + background-repeat: no-repeat; + padding-left: 18px; +} + +span.refs span.tag { + color: #707070; + display: inline-block; + margin: 0; + background-color: #ffffab; + border: 1px solid #d9d93b; + border-radius: 3px; + height: 18px; + padding: 0 6px; + text-overflow: ellipsis; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIKFSUZZ+h9RwAAAGZQTFRFAAAAtrYkwMBAwMBAx8c4yso11NQ71NQ51dU52Ng71tY519c719c719c62Ng719c719c62Ng72dk62Ng62Ng72Ng72dk62Ng72Ng62dk62dk72dk62Ng62dk72Ng72Ng72dk7////ou/AnQAAACB0Uk5TAAYHCxESLjRCWWlqa4uNkpissbrO19jc3ufs8vf6/f7atAU2AAAAAWJLR0QhxGwNFgAAAF1JREFUGFeNy0cOgCAABVGw94rY5d//lC7omhhn+ZIh5Gf1xPk0Zi5dAABROIQjSU/fsAXhDkCUljAv8jW2wlQpaixpo4Nj+dtatVpjkSJjLNaizRVpvhBCu/4h391jzw1lU12Z7wAAAABJRU5ErkJggg==); + background-repeat: no-repeat; + padding-left: 18px; +} + +span.refs span.head { + color: #707070; + display: inline-block; + margin: 0; + background-color: #c4ffc4; + border: 1px solid #78ff78; + border-radius: 3px; + height: 18px; + padding: 0 6px; + text-overflow: ellipsis; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIKFSYDsafX/gAAAUpJREFUOMvVkjFLA0EQhd/s7l06MSCihbV/wC5/QBDEIFYWprRIIQQJFqKFQi4kUbBQsFSwtrUQLQULUTBFLCzVIgimCXe7z0q5yIWcqfRVwzDzMTNvgL8mSUqWw3JOtFQJdsIwLDYyjdYgkEmkazl2oVtQWk36nn8AYBYASmFpxmizGtnoqO7Vb+M9KglEkASdpWU872nvVCiPRpuTnz2JIHGyqX3d0kZfR1G0Ht+g/do+FIhOBbLW3n/FNb/28D0puZ+dyL44ur1UoH5yzt2JyIj6UGdDgwrPhYzSagNEszJaeU/lWlylbmnaeGZZICsAppxzi6nt73HK85oQCMknOuarpno+FIjglVjZDXaCS2yDv3rIHlCb88FY0BlUl3hs7ektkhckb5DFWhoz+n12zr7ZPLpYUqLm0oBMn8NUzLhpAgjpWMS/1CcSJ3ykD7Rk1QAAAABJRU5ErkJggg==); + background-repeat: no-repeat; + padding-left: 18px; +} + +span.refs a { + color: #4e4e4e; + font: 11px "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, monospace; + line-height: 18px; +} + +/* Diffs +---------------------------------------------------------------------------- */ + +div.diff.to_file a.path, +div.diff.to_file { + color: #007000; +} + +div.diff.from_file a.path, +div.diff.from_file { + color: #aa0000; +} + +.patch .header { + margin: 0; +} + +.patchset { + overflow-x: auto; + overflow-y: hidden; +} + +.chunk_header { + background: #eaf2f5; + color: #999; +} + +.rem { + background: #ffdddd; +} +.rem .marked { + background: #ffaaaa; +} +.add { + background: #ddffdd; +} +.add .marked { + background: #7dff7d; +} + +.extended_header { + width: 99.5%; +} + +div.chunk_block { + overflow: hidden; +} + +div.chunk_block div.old { + float: left; + width: 50%; + overflow: hidden; + border-right: 5px solid #EAF2F5; +} + +div.chunk_block.rem, +div.chunk_block.add { + background: transparent; +} + +div.chunk_block div.old .add, +div.chunk_block div.old .rem { + padding-right: 3px; +} + +div.chunk_block div.new .add, +div.chunk_block div.new .rem { + padding-left: 3px; +} + +div.chunk_block div.new { + margin-left: 50%; + width: 50%; + border-left: 5px solid #EAF2F5; +} + +/* Category +---------------------------------------------------------------------------- */ + +td.category { + background: #E6F1F6; /* old browsers */ + background: -moz-linear-gradient(top, #C8D8E7 0%, #E6F1F3 100%); /* firefox */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#C8D8E7), color-stop(100%,#E6F1F3)); /* webkit */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#C8D8E7', endColorstr='#E6F1F3',GradientType=0 ); /* ie */ + background: -o-linear-gradient(top, #C8D8E7 0%, #E6F1F3 100%); + font-weight: bold; + border-bottom: 1px solid #D1D1D1; + border-top: 1px solid #D1D1D1; +} + +/* Age +---------------------------------------------------------------------------- */ + +/* noage: "No commits" */ +.project_list td.noage { + color: #cdcdcd; +} + +/* age2: 60*60*24*2 <= age */ +.project_list td.age2, .blame td.age2 { + color: #545454; +} + +/* age1: 60*60*2 <= age < 60*60*24*2 */ +.project_list td.age1 { + color: #009900; +} + +/* age0: age < 60*60*2 */ +.project_list td.age0 { + color: #009900; + font-weight: bold; +} + +/* File status +---------------------------------------------------------------------------- */ + +.diff_tree span.file_status.new { + color: #008000; +} + +table.diff_tree span.file_status.deleted { + color: #c00000; +} + +table.diff_tree span.file_status.moved, +table.diff_tree span.file_status.mode_chnge { + color: #545454; +} + +table.diff_tree span.file_status.copied { + color: #70a070; +} + +span.cntrl { + border: dashed #aaaaaa; + border-width: 1px; + padding: 0px 2px 0px 2px; + margin: 0px 2px 0px 2px; +} + +span.match { + background: #aaffaa; + color: #000; +} + +td.error { + color: red; + background: yellow; +} + +/* blob view */ + +td.pre, div.pre, div.diff { + white-space: pre-wrap; +} + +/* JavaScript-based timezone manipulation */ + +.popup { /* timezone selection UI */ + position: absolute; + /* "top: 0; right: 0;" would be better, if not for bugs in browsers */ + top: 0; left: 0; + border: 1px solid #d8d8d8; + padding: 2px; + background-color: #f0f0f0; + font-style: normal; + color: #545454; + cursor: auto; +} + +.close-button { /* close timezone selection UI without selecting */ + /* float doesn't work within absolutely positioned container, + * if width of container is not set explicitly */ + /* float: right; */ + position: absolute; + top: 0px; right: 0px; + border: 1px solid #ffaaaa; + margin: 1px 1px 1px 1px; + padding-bottom: 2px; + width: 12px; + height: 10px; + font-size: 9px; + font-weight: bold; + text-align: center; + background-color: #ffdddd; + cursor: pointer; +} + +/* Style definition generated by highlight 2.4.5, http://www.andre-simon.de/ */ + +/* Highlighting theme definition: */ + +.num { color:#6ecf36; } +.esc { color:#ff00ff; } +.str { color:#ff00d3; background-color: #edc9ec } +.dstr { color:#818100; } +.slc { color:#838183; font-style:italic; } +.com { color:#838183; font-style:italic; } +.dir { color:#008200; } +.sym { color:#000000; } +.line { color:#555555; } +.kwa { color:#666666; font-weight:bold; } +.kwb { color:#6b3099; } +.kwc { color:#d4663d; } +.kwd { color:#2928ff; } + +/**** Styles supplémentaires *****/ + +.readme div.toc { + float: right; + border: 1px solid black; + background-color: white; +} +.readme div.toc span.toctitle { + display: inline-block; + width: 100%; + text-align: center; + font-weight: bold; +} + +.readme table { + background-color: white; +} + +.readme table thead tr { + background-color: #ccc; +} + +.readme table tbody tr:nth-child(2n) { + background-color: #f8f8f8; +} + +.readme table td, .readme table th { + border: 1px solid black; +} diff --git a/virtual/modules/websites/tools/git/gitweb/theme/gitweb.js b/virtual/modules/websites/tools/git/gitweb/theme/gitweb.js new file mode 100644 index 0000000..72f3cfa --- /dev/null +++ b/virtual/modules/websites/tools/git/gitweb/theme/gitweb.js @@ -0,0 +1,27 @@ +function include(filename, onload) { + var head = document.getElementsByTagName('head')[0]; + var script = document.createElement('script'); + script.src = filename; + script.type = 'text/javascript'; + script.onload = script.onreadystatechange = function() { + if (script.readyState) { + if (script.readyState === 'complete' || script.readyState === 'loaded') { + script.onreadystatechange = null; + onload(); + } + } + else { + onload(); + } + } + head.appendChild(script); +} + +include('static/gitweb.js', function() {}); +include('//code.jquery.com/jquery-3.1.0.min.js', function() { + $("div.title").each(function(index, element) { + if ($(element).text() === "readme" || $(element).text() === " ") { + $(element).hide(); + } + }); +}); diff --git a/virtual/modules/websites/tools/git/mantisbt/mantisbt-plugin-slack.json b/virtual/modules/websites/tools/git/mantisbt/mantisbt-plugin-slack.json new file mode 100644 index 0000000..54ea38b --- /dev/null +++ b/virtual/modules/websites/tools/git/mantisbt/mantisbt-plugin-slack.json @@ -0,0 +1,15 @@ +{ + "tag": "9286d2e-master", + "meta": { + "name": "mantisbt-plugin-slack", + "url": "https://github.com/mantisbt-plugins/Slack", + "branch": "master" + }, + "github": { + "owner": "mantisbt-plugins", + "repo": "Slack", + "rev": "9286d2eeeb8a986ed949e378711fef5f0bf182dc", + "sha256": "0nn0v4jc967giilkzrppi5svd04m2hnals75xxp0iabcdjnih0mn", + "fetchSubmodules": true + } +} diff --git a/virtual/modules/websites/tools/git/mantisbt/mantisbt-plugin-source-integration.json b/virtual/modules/websites/tools/git/mantisbt/mantisbt-plugin-source-integration.json new file mode 100644 index 0000000..e36a68c --- /dev/null +++ b/virtual/modules/websites/tools/git/mantisbt/mantisbt-plugin-source-integration.json @@ -0,0 +1,15 @@ +{ + "tag": "v2.1.5", + "meta": { + "name": "mantisbt-plugin-source-integration", + "url": "https://github.com/mantisbt-plugins/source-integration", + "branch": "refs/tags/v2.1.5" + }, + "github": { + "owner": "mantisbt-plugins", + "repo": "source-integration", + "rev": "a48039a20abc50864e0e68c0c843b27058404386", + "sha256": "07g6q3hivmnd94r47pp0snk5bv4pa3piwclc9qhj612i4wnsazsk", + "fetchSubmodules": true + } +} diff --git a/virtual/modules/websites/tools/git/mantisbt/mantisbt-plugin-source-integration_Source.API.php.diff b/virtual/modules/websites/tools/git/mantisbt/mantisbt-plugin-source-integration_Source.API.php.diff new file mode 100644 index 0000000..c355144 --- /dev/null +++ b/virtual/modules/websites/tools/git/mantisbt/mantisbt-plugin-source-integration_Source.API.php.diff @@ -0,0 +1,12 @@ +--- b/Source/Source.API.php 2017-09-18 00:50:32.000000000 +0200 ++++ a/Source/Source.API.php 2018-03-04 19:00:25.578889039 +0100 +@@ -452,6 +452,9 @@ + # Allow other plugins to post-process commit data + event_signal( 'EVENT_SOURCE_COMMITS', array( $p_changesets ) ); + event_signal( 'EVENT_SOURCE_FIXED', array( $t_fixed_bugs ) ); ++ foreach( $t_fixed_bugs as $t_bug_id => $t_changeset ) { ++ event_signal( 'EVENT_BUG_ACTION', array('RESOLVE', $t_bug_id) ); ++ } + } + + /** diff --git a/virtual/modules/websites/tools/git/mantisbt/mantisbt.nix b/virtual/modules/websites/tools/git/mantisbt/mantisbt.nix new file mode 100644 index 0000000..009c902 --- /dev/null +++ b/virtual/modules/websites/tools/git/mantisbt/mantisbt.nix @@ -0,0 +1,124 @@ +{ lib, checkEnv, writeText, stdenv, fetchurl, fetchedGithub }: +let + # FIXME: check that source-integration and slack still work + mantisbt = let + plugins = { + slack = stdenv.mkDerivation (fetchedGithub ./mantisbt-plugin-slack.json // rec { + installPhase = '' + sed -i -e "s/return '@' . \\\$username;/return \\\$username;/" Slack.php + cp -a . $out + ''; + }); + source-integration = stdenv.mkDerivation (fetchedGithub ./mantisbt-plugin-source-integration.json // rec { + installPhase = '' + mkdir $out + patch -p1 < ${./mantisbt-plugin-source-integration_Source.API.php.diff} + cp -a Source* $out/ + ''; + }); + }; + in rec { + config = + assert checkEnv "NIXOPS_MANTISBT_DB_PASSWORD"; + assert checkEnv "NIXOPS_MANTISBT_MASTER_SALT"; + assert checkEnv "NIXOPS_MANTISBT_LDAP_PASSWORD"; + writeText "config_inc.php" '' + + DirectoryIndex index.php + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + AllowOverride All + Options FollowSymlinks + Require all granted + + + #Reenable during upgrade + Require all denied + + ''; + }; + phpFpm = rec { + basedir = builtins.concatStringsSep ":" ( + [ webRoot config ] + ++ lib.attrsets.mapAttrsToList (name: value: value) plugins); + socket = "/var/run/phpfpm/mantisbt.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 60 + pm.process_idle_timeout = 60 + + php_admin_value[upload_max_filesize] = 5000000 + + php_admin_value[open_basedir] = "${basedir}:/tmp" + php_admin_value[session.save_path] = "/var/lib/php/sessions/mantisbt" + ''; + }; + }; +in + mantisbt diff --git a/virtual/modules/websites/tools/git/mantisbt/patches/bug_report.php.diff b/virtual/modules/websites/tools/git/mantisbt/patches/bug_report.php.diff new file mode 100644 index 0000000..a520043 --- /dev/null +++ b/virtual/modules/websites/tools/git/mantisbt/patches/bug_report.php.diff @@ -0,0 +1,20 @@ +--- a/bug_report.php 2018-02-10 21:29:27.000000000 +0100 ++++ b/bug_report.php 2018-03-03 15:04:19.622499678 +0100 +@@ -149,6 +149,17 @@ + access_ensure_project_level( config_get( 'update_bug_assign_threshold' ) ); + } + ++# begin captcha check for anon user ++if ( current_user_is_anonymous() && get_gd_version() > 0 ) { ++ $f_captcha = gpc_get_string( 'captcha', '' ); ++ $f_captcha = utf8_strtolower( trim( $f_captcha ) ); ++ ++ $t_securimage = new Securimage(); ++ if( $t_securimage->check( $f_captcha ) == false ) { ++ trigger_error( ERROR_SIGNUP_NOT_MATCHING_CAPTCHA, ERROR ); ++ } ++} ++ + # if a profile was selected then let's use that information + if( 0 != $t_bug_data->profile_id ) { + if( profile_is_global( $t_bug_data->profile_id ) ) { diff --git a/virtual/modules/websites/tools/git/mantisbt/patches/bug_report_page.php.diff b/virtual/modules/websites/tools/git/mantisbt/patches/bug_report_page.php.diff new file mode 100644 index 0000000..80dea91 --- /dev/null +++ b/virtual/modules/websites/tools/git/mantisbt/patches/bug_report_page.php.diff @@ -0,0 +1,53 @@ +--- a/bug_report_page.php 2018-02-10 21:29:27.000000000 +0100 ++++ b/bug_report_page.php 2018-03-03 15:04:19.622499678 +0100 +@@ -708,7 +708,50 @@ + + + + ++ 0 ) { ++ $t_securimage_path = 'vendor/dapphp/securimage'; ++ $t_securimage_show = $t_securimage_path . '/securimage_show.php'; ++ $t_securimage_play = $t_securimage_path . '/securimage_play.swf?' ++ . http_build_query( array( ++ 'audio_file' => $t_securimage_path . '/securimage_play.php', ++ 'bgColor1=' => '#fff', ++ 'bgColor2=' => '#fff', ++ 'iconColor=' => '#777', ++ 'borderWidth=' => 1, ++ 'borderColor=' => '#000', ++ ) ); ++?> ++ ++ CAPTCHA ++ ++ ++ ++ ++ ++ ++ ++ visual captcha ++
++
++ ++ ++ ++ ++
++ ++ ++ ++ + + + diff --git a/virtual/modules/websites/tools/git/mantisbt/patches/bugnote_add.php.diff b/virtual/modules/websites/tools/git/mantisbt/patches/bugnote_add.php.diff new file mode 100644 index 0000000..4509f0a --- /dev/null +++ b/virtual/modules/websites/tools/git/mantisbt/patches/bugnote_add.php.diff @@ -0,0 +1,20 @@ +--- a/bugnote_add.php 2018-02-10 21:29:27.000000000 +0100 ++++ b/bugnote_add.php 2018-03-03 15:13:12.439919511 +0100 +@@ -44,6 +44,17 @@ + + $t_query = array( 'issue_id' => $f_bug_id ); + ++# begin captcha check for anon user ++if ( current_user_is_anonymous() && get_gd_version() > 0 ) { ++ $f_captcha = gpc_get_string( 'captcha', '' ); ++ $f_captcha = utf8_strtolower( trim( $f_captcha ) ); ++ ++ $t_securimage = new Securimage(); ++ if( $t_securimage->check( $f_captcha ) == false ) { ++ trigger_error( ERROR_SIGNUP_NOT_MATCHING_CAPTCHA, ERROR ); ++ } ++} ++ + if( count( $f_files ) > 0 && is_blank( $f_text ) && helper_duration_to_minutes( $f_duration ) == 0 ) { + $t_payload = array( + 'files' => helper_array_transpose( $f_files ) diff --git a/virtual/modules/websites/tools/git/mantisbt/patches/bugnote_add_inc.php.diff b/virtual/modules/websites/tools/git/mantisbt/patches/bugnote_add_inc.php.diff new file mode 100644 index 0000000..a8589c7 --- /dev/null +++ b/virtual/modules/websites/tools/git/mantisbt/patches/bugnote_add_inc.php.diff @@ -0,0 +1,52 @@ +--- a/bugnote_add_inc.php 2018-02-10 21:29:27.000000000 +0100 ++++ b/bugnote_add_inc.php 2018-03-03 15:14:27.332428557 +0100 +@@ -119,6 +119,49 @@ + + + ++ 0 ) { ++ $t_securimage_path = 'vendor/dapphp/securimage'; ++ $t_securimage_show = $t_securimage_path . '/securimage_show.php'; ++ $t_securimage_play = $t_securimage_path . '/securimage_play.swf?' ++ . http_build_query( array( ++ 'audio_file' => $t_securimage_path . '/securimage_play.php', ++ 'bgColor1=' => '#fff', ++ 'bgColor2=' => '#fff', ++ 'iconColor=' => '#777', ++ 'borderWidth=' => 1, ++ 'borderColor=' => '#000', ++ ) ); ++?> ++ ++ CAPTCHA ++ ++ ++ ++ ++ ++ ++ ++ visual captcha ++
++
++ ++ ++ ++ ++
++ ++ ++ ++ + + array("verify_peer" => false)); + $config['smtp_server'] = 'tls://mail.immae.eu'; + + $config['imap_cache'] = 'db'; + $config['messages_cache'] = 'db'; + + $config['support_url'] = '''; + + $config['des_key'] = '${builtins.getEnv "NIXOPS_ROUNDCUBEMAIL_SECRET"}'; + + $config['plugins'] = array(); + + $config['language'] = 'fr_FR'; + + $config['drafts_mbox'] = 'Mail/Drafts'; + $config['junk_mbox'] = 'Mail/Spam'; + $config['sent_mbox'] = 'Mail/sent'; + $config['trash_mbox'] = '''; + $config['default_folders'] = array('INBOX', 'Mail/Drafts', 'Mail/sent', 'Mail/Spam', '''); + $config['draft_autosave'] = 60; + $config['enable_installer'] = false; + $config['log_driver'] = 'stdout'; + $config['temp_dir'] = '${varDir}/cache'; + $config['debug_level'] = 1; + ''; + webRoot = stdenv.mkDerivation rec { + version = "1.3.8"; + name = "roundcubemail-${version}"; + src= fetchurl { + url = "https://github.com/roundcube/roundcubemail/releases/download/${version}/${name}-complete.tar.gz"; + sha256 = "018djad7ygfl9c9f2l2j42qkg31ml3hs2f01f0dk361zckwk77n4"; + }; + buildPhase = '' + sed -i \ + -e "s|RCUBE_INSTALL_PATH . 'temp.*|'${varDir}/cache';|" \ + config/defaults.inc.php + ''; + installPhase = '' + cp -a . $out + ln -s ${config} $out/config/config.inc.php + ${builtins.concatStringsSep "\n" ( + lib.attrsets.mapAttrsToList (name: value: "ln -sf ${value} $out/plugins/${name}") plugins + )} + ''; + }; + apache = { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "proxy_fcgi" ]; + vhostConf = '' + Alias /roundcube "${webRoot}" + + DirectoryIndex index.php + AllowOverride All + Options FollowSymlinks + Require all granted + + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + ''; + }; + phpFpm = rec { + basedir = builtins.concatStringsSep ":" ( + [ webRoot config varDir ] + ++ lib.attrsets.mapAttrsToList (name: value: value) plugins); + socket = "/var/run/phpfpm/roundcubemail.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 60 + pm.process_idle_timeout = 60 + + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = RoundcubemailPHPSESSID + php_admin_value[open_basedir] = "${basedir}:/tmp" + php_admin_value[session.save_path] = "${varDir}/phpSessions" + ''; + }; + }; +in + roundcubemail diff --git a/virtual/modules/websites/tools/tools/tt-rss.json b/virtual/modules/websites/tools/tools/tt-rss.json new file mode 100644 index 0000000..e2731b0 --- /dev/null +++ b/virtual/modules/websites/tools/tools/tt-rss.json @@ -0,0 +1,14 @@ +{ + "tag": "986ca25-master", + "meta": { + "name": "tt-rss", + "url": "https://git.tt-rss.org/fox/tt-rss.git", + "branch": "master" + }, + "git": { + "url": "https://git.tt-rss.org/fox/tt-rss.git", + "rev": "986ca251f995f7754a0470d3e0c44538a545081f", + "sha256": "0xkafkh7l9zazm5d6snlq03kdfxfhkb4c8fdsb32wn8b9bhdzf5s", + "fetchSubmodules": true + } +} diff --git a/virtual/modules/websites/tools/tools/ttrss-af-feedmod_type_replace.patch b/virtual/modules/websites/tools/tools/ttrss-af-feedmod_type_replace.patch new file mode 100644 index 0000000..d622577 --- /dev/null +++ b/virtual/modules/websites/tools/tools/ttrss-af-feedmod_type_replace.patch @@ -0,0 +1,12 @@ +--- a/init.php 2014-06-16 14:21:06.995480038 +0200 ++++ b/init.php 2014-06-16 14:22:00.151027654 +0200 +@@ -147,6 +147,9 @@ + } + } + break; ++ case 'replace': ++ $article['content'] = preg_replace("/".$config['pattern']."/",$config['replacement'],$article['content']); ++ break; + + default: + // unknown type or invalid config diff --git a/virtual/modules/websites/tools/tools/ttrss-af_feedmod.json b/virtual/modules/websites/tools/tools/ttrss-af_feedmod.json new file mode 100644 index 0000000..e57fcce --- /dev/null +++ b/virtual/modules/websites/tools/tools/ttrss-af_feedmod.json @@ -0,0 +1,15 @@ +{ + "tag": "0ea2092-master", + "meta": { + "name": "ttrss-af_feedmod", + "url": "https://github.com/mbirth/ttrss_plugin-af_feedmod", + "branch": "master" + }, + "github": { + "owner": "mbirth", + "repo": "ttrss_plugin-af_feedmod", + "rev": "0ea2092dd34067ecd898802cfca3570023d1ecfe", + "sha256": "02ibf47zcrsc2rr45wsix8gxyyf371davj8n8i0gj1zdq95klvnv", + "fetchSubmodules": true + } +} diff --git a/virtual/modules/websites/tools/tools/ttrss-auth-ldap.json b/virtual/modules/websites/tools/tools/ttrss-auth-ldap.json new file mode 100644 index 0000000..c8aaab5 --- /dev/null +++ b/virtual/modules/websites/tools/tools/ttrss-auth-ldap.json @@ -0,0 +1,15 @@ +{ + "tag": "4d751b0-master", + "meta": { + "name": "ttrss-auth-ldap", + "url": "https://github.com/hydrian/TTRSS-Auth-LDAP", + "branch": "master" + }, + "github": { + "owner": "hydrian", + "repo": "TTRSS-Auth-LDAP", + "rev": "4d751b095c29a8dbe2dc7bb07777742956136e94", + "sha256": "0b9fl86acrzpcv41r7pj3bl8b3n72hpkdywzx9zjyfqv5pskxyim", + "fetchSubmodules": true + } +} diff --git a/virtual/modules/websites/tools/tools/ttrss-feediron.json b/virtual/modules/websites/tools/tools/ttrss-feediron.json new file mode 100644 index 0000000..5dbec92 --- /dev/null +++ b/virtual/modules/websites/tools/tools/ttrss-feediron.json @@ -0,0 +1,15 @@ +{ + "tag": "407168c-master", + "meta": { + "name": "ttrss-feediron", + "url": "https://github.com/m42e/ttrss_plugin-feediron", + "branch": "master" + }, + "github": { + "owner": "m42e", + "repo": "ttrss_plugin-feediron", + "rev": "407168c628880b5ced572cc549db6d50e866d3c8", + "sha256": "17b95ifpcph6m03hjd1mhi8gi1hw9yd3fnffmw66fqr5c9l3zd9r", + "fetchSubmodules": true + } +} diff --git a/virtual/modules/websites/tools/tools/ttrss-feediron_json_reformat.patch b/virtual/modules/websites/tools/tools/ttrss-feediron_json_reformat.patch new file mode 100644 index 0000000..e1c44d9 --- /dev/null +++ b/virtual/modules/websites/tools/tools/ttrss-feediron_json_reformat.patch @@ -0,0 +1,18 @@ +diff --git a/init.php b/init.php +index 3c0f2f9..1aad146 100644 +--- a/init.php ++++ b/init.php +@@ -600,10 +600,11 @@ class Feediron extends Plugin implements IHandler + return false; + } + +- $this->host->set($this, 'json_conf', Feediron_Json::format($json_conf)); ++ $new_conf = json_encode(json_decode($json_conf), JSON_PRETTY_PRINT); ++ $this->host->set($this, 'json_conf', $new_conf); + $json_reply['success'] = true; + $json_reply['message'] = __('Configuration saved.'); +- $json_reply['json_conf'] = Feediron_Json::format($json_conf); ++ $json_reply['json_conf'] = $new_conf; + echo json_encode($json_reply); + } + diff --git a/virtual/modules/websites/tools/tools/ttrss-ff_instagram.json b/virtual/modules/websites/tools/tools/ttrss-ff_instagram.json new file mode 100644 index 0000000..1f241b9 --- /dev/null +++ b/virtual/modules/websites/tools/tools/ttrss-ff_instagram.json @@ -0,0 +1,15 @@ +{ + "tag": "0366ffb-master", + "meta": { + "name": "ttrss-ff_instagram", + "url": "https://github.com/wltb/ff_instagram", + "branch": "master" + }, + "github": { + "owner": "wltb", + "repo": "ff_instagram", + "rev": "0366ffb18c4d490c8fbfba2f5f3367a5af23cfe8", + "sha256": "0vvzl6wi6jmrqknsfddvckjgsgfizz1d923d1nyrpzjfn6bda1vk", + "fetchSubmodules": true + } +} diff --git a/virtual/modules/websites/tools/tools/ttrss-tumblr_gdpr_ua.json b/virtual/modules/websites/tools/tools/ttrss-tumblr_gdpr_ua.json new file mode 100644 index 0000000..eafbcfe --- /dev/null +++ b/virtual/modules/websites/tools/tools/ttrss-tumblr_gdpr_ua.json @@ -0,0 +1,15 @@ +{ + "tag": "287c584-master", + "meta": { + "name": "ttrss-tumblr_gdpr_ua", + "url": "https://github.com/hkockerbeck/ttrss-tumblr-gdpr-ua", + "branch": "master" + }, + "github": { + "owner": "hkockerbeck", + "repo": "ttrss-tumblr-gdpr-ua", + "rev": "287c584e68845d524f920156bff0b2eaa6f65117", + "sha256": "1fviawgcclqky4k4xv1sqzvpb8i74w9f0pclm09m78s8l85wh9py", + "fetchSubmodules": true + } +} diff --git a/virtual/modules/websites/tools/tools/ttrss.nix b/virtual/modules/websites/tools/tools/ttrss.nix new file mode 100644 index 0000000..f7b0f61 --- /dev/null +++ b/virtual/modules/websites/tools/tools/ttrss.nix @@ -0,0 +1,182 @@ +{ lib, php, checkEnv, writeText, stdenv, fetchedGit, fetchedGithub }: +let + ttrss = let + plugins = { + auth_ldap = stdenv.mkDerivation (fetchedGithub ./ttrss-auth-ldap.json // rec { + installPhase = '' + mkdir $out + cp plugins/auth_ldap/init.php $out + ''; + }); + af_feedmod = stdenv.mkDerivation (fetchedGithub ./ttrss-af_feedmod.json // rec { + patches = [ ./ttrss-af-feedmod_type_replace.patch ]; + installPhase = '' + mkdir $out + cp init.php $out + ''; + }); + feediron = stdenv.mkDerivation (fetchedGithub ./ttrss-feediron.json // rec { + patches = [ ./ttrss-feediron_json_reformat.patch ]; + installPhase = '' + mkdir $out + cp -a . $out + ''; + }); + ff_instagram = stdenv.mkDerivation (fetchedGithub ./ttrss-ff_instagram.json // rec { + installPhase = '' + mkdir $out + cp -a . $out + ''; + }); + tumblr_gdpr_ua = stdenv.mkDerivation (fetchedGithub ./ttrss-tumblr_gdpr_ua.json // rec { + installPhase = '' + mkdir $out + cp -a . $out + ''; + }); + }; + in rec { + varDir = "/var/lib/ttrss"; + # FIXME: initial sync + activationScript = { + deps = [ "wrappers" ]; + text = '' + install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir} \ + ${varDir}/lock ${varDir}/cache ${varDir}/feed-icons + install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir}/cache/export/ \ + ${varDir}/cache/feeds/ \ + ${varDir}/cache/images/ \ + ${varDir}/cache/js/ \ + ${varDir}/cache/simplepie/ \ + ${varDir}/cache/upload/ + touch ${varDir}/feed-icons/index.html + install -m 0750 -o ${apache.user} -g ${apache.group} -d ${varDir}/phpSessions + ''; + }; + config = + # FIXME: LOG_DESTINATION syslog? + assert checkEnv "NIXOPS_TTRSS_DB_PASSWORD"; + assert checkEnv "NIXOPS_TTRSS_LDAP_PASSWORD"; + writeText "config.php" '' + + DirectoryIndex index.php + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + AllowOverride All + Options FollowSymlinks + Require all granted + + ''; + }; + phpFpm = rec { + basedir = builtins.concatStringsSep ":" ( + [ webRoot config varDir ] + ++ lib.attrsets.mapAttrsToList (name: value: value) plugins); + socket = "/var/run/phpfpm/ttrss.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 60 + pm.process_idle_timeout = 60 + + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = TtrssPHPSESSID + php_admin_value[open_basedir] = "${basedir}:/tmp" + php_admin_value[session.save_path] = "${varDir}/phpSessions" + ''; + }; + }; +in + ttrss diff --git a/virtual/modules/websites/tools/tools/ympd.nix b/virtual/modules/websites/tools/tools/ympd.nix new file mode 100644 index 0000000..74bf2e5 --- /dev/null +++ b/virtual/modules/websites/tools/tools/ympd.nix @@ -0,0 +1,35 @@ +{}: +let + ympd = rec { + config = { + webPort = "localhost:18001"; + mpd = { + host = "malige.home.immae.eu"; + port = 6600; + }; + }; + apache = { + modules = [ + "proxy_wstunnel" + ]; + vhostConf = '' + + Use LDAPConnect + Require ldap-group cn=users,cn=mpd,ou=services,dc=immae,dc=eu + Require local + + + RedirectMatch permanent "^/mpd$" "/mpd/" + + ProxyPass http://${config.webPort}/ + ProxyPassReverse http://${config.webPort}/ + ProxyPreserveHost on + + + ProxyPass ws://${config.webPort}/ws + + ''; + }; + }; +in + ympd diff --git a/virtual/packages.nix b/virtual/packages.nix deleted file mode 100644 index 1f01ba7..0000000 --- a/virtual/packages.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ callPackage, checkEnv, fetchedGit, fetchedGithub }: -let - nextcloud = callPackage ./packages/nextcloud.nix { inherit checkEnv; }; - adminer = callPackage ./packages/adminer.nix {}; - ympd = callPackage ./packages/ympd.nix {}; - mantisbt = callPackage ./packages/mantisbt.nix { inherit checkEnv fetchedGithub; }; - ttrss = callPackage ./packages/ttrss.nix { inherit checkEnv fetchedGithub fetchedGit; }; - roundcubemail = callPackage ./packages/roundcubemail.nix { inherit checkEnv; }; - infcloud = callPackage ./packages/infcloud.nix {}; - davical = callPackage ./packages/davical.nix { inherit checkEnv; }; -in - { - inherit adminer; - inherit ympd; - inherit nextcloud; - inherit mantisbt; - inherit ttrss; - inherit roundcubemail; - inherit infcloud; - inherit davical; - } diff --git a/virtual/packages/adminer.nix b/virtual/packages/adminer.nix deleted file mode 100644 index 7094e45..0000000 --- a/virtual/packages/adminer.nix +++ /dev/null @@ -1,64 +0,0 @@ -{ stdenv, fetchurl, nginx }: -let - adminer = rec { - webRoot = stdenv.mkDerivation rec { - version = "4.7.0"; - name = "adminer-${version}"; - src = fetchurl { - url = "https://www.adminer.org/static/download/${version}/${name}.php"; - sha256 = "1qq2g7rbfh2vrqfm3g0bz0qs057b049n0mhabnsbd1sgnpvnc5z7"; - }; - phases = "installPhase"; - installPhase = '' - mkdir -p $out - cp $src $out/index.php - ''; - }; - phpFpm = rec { - socket = "/var/run/phpfpm/adminer.sock"; - pool = '' - listen = ${socket} - user = ${apache.user} - group = ${apache.group} - listen.owner = ${apache.user} - listen.group = ${apache.group} - pm = ondemand - pm.max_children = 5 - pm.process_idle_timeout = 60 - ;php_admin_flag[log_errors] = on - ; Needed to avoid clashes in browser cookies (same domain) - php_value[session.name] = AdminerPHPSESSID - php_admin_value[open_basedir] = "${webRoot}:/tmp" - php_admin_value[session.save_path] = "/var/lib/php/sessions/adminer" - ''; - }; - apache = { - user = "wwwrun"; - group = "wwwrun"; - modules = [ "proxy_fcgi" ]; - vhostConf = '' - Alias /adminer ${webRoot} - - DirectoryIndex index.php - - SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" - - - ''; - }; - nginxConf = { - alias = webRoot; - index = "index.php"; - extraConfig = '' - include ${nginx}/conf/fastcgi.conf; - fastcgi_split_path_info ^(.+?\.php)(/.*)$; - fastcgi_param HTTP_PROXY ""; - fastcgi_param SCRIPT_FILENAME ${webRoot}/index.php; - fastcgi_pass unix:${phpFpm.socket}; - fastcgi_index index.php; - fastcgi_intercept_errors on; - ''; - }; - }; -in - adminer diff --git a/virtual/packages/davical.nix b/virtual/packages/davical.nix deleted file mode 100644 index f539ba6..0000000 --- a/virtual/packages/davical.nix +++ /dev/null @@ -1,163 +0,0 @@ -{ stdenv, fetchurl, gettext, writeText, checkEnv }: -let - awl = stdenv.mkDerivation rec { - version = "0.59"; - name = "awl-${version}"; - src = fetchurl { - url = "https://www.davical.org/downloads/awl_${version}.orig.tar.xz"; - sha256 = "01b7km7ga3ggbpp8axkc55nizgk5c35fl2z93iydb3hwbxmsvnjp"; - }; - unpackCmd = '' - tar --one-top-level -xf $curSrc - ''; - installPhase = '' - mkdir -p $out - cp -ra dba docs inc scripts tests $out - ''; - }; - # FIXME: e-mail sending - davical = rec { - config = - assert checkEnv "NIXOPS_DAVICAL_DB_PASSWORD"; - assert checkEnv "NIXOPS_DAVICAL_LDAP_PASSWORD"; - writeText "davical_config.php" '' - pg_connect[] = "dbname=davical user=davical_app host=db-1.immae.eu password=${builtins.getEnv "NIXOPS_DAVICAL_DB_PASSWORD"}"; - - $c->readonly_webdav_collections = false; - - $c->admin_email ='davical@immae.eu'; - - $c->restrict_setup_to_admin = true; - - $c->collections_always_exist = false; - - $c->external_refresh = 60; - - $c->enable_scheduling = true; - - $c->iMIP = (object) array("send_email" => true); - - $c->authenticate_hook['optional'] = false; - $c->authenticate_hook['call'] = 'LDAP_check'; - $c->authenticate_hook['config'] = array( - 'host' => 'ldap.immae.eu', - 'port' => '389', - 'startTLS' => 'yes', - 'bindDN'=> 'cn=davical,ou=services,dc=immae,dc=eu', - 'passDN'=> '${builtins.getEnv "NIXOPS_DAVICAL_LDAP_PASSWORD"}', - 'protocolVersion' => '3', - 'baseDNUsers'=> array('ou=users,dc=immae,dc=eu', 'ou=group_users,dc=immae,dc=eu'), - 'filterUsers' => 'memberOf=cn=users,cn=davical,ou=services,dc=immae,dc=eu', - 'baseDNGroups' => 'ou=groups,dc=immae,dc=eu', - 'filterGroups' => 'memberOf=cn=groups,cn=davical,ou=services,dc=immae,dc=eu', - 'mapping_field' => array( - "username" => "uid", - "fullname" => "cn", - "email" => "mail", - "modified" => "modifyTimestamp", - ), - 'format_updated'=> array('Y' => array(0,4),'m' => array(4,2),'d'=> array(6,2),'H' => array(8,2),'M'=>array(10,2),'S' => array(12,2)), - /** used to set default value for all users, will be overcharged by ldap if defined also in mapping_field **/ - // 'default_value' => array("date_format_type" => "E","locale" => "fr_FR"), - 'group_mapping_field' => array( - "username" => "cn", - "updated" => "modifyTimestamp", - "fullname" => "givenName", - "displayname" => "givenName", - "members" => "memberUid", - "email" => "mail", - ), - ); - - $c->do_not_sync_from_ldap = array('admin' => true); - include('drivers_ldap.php'); - ''; - webapp = stdenv.mkDerivation rec { - version = "1.1.7"; - name = "davical-${version}"; - src = fetchurl { - url = "https://www.davical.org/downloads/davical_${version}.orig.tar.xz"; - sha256 = "1ar5m2dxr92b204wkdi8z33ir9vz2jbh5k1p74icpv9ywifvjjp9"; - }; - unpackCmd = '' - tar --one-top-level -xf $curSrc - ''; - makeFlags = "all"; - patches = [ ./davical_19eb79ebf9250e5f339675319902458c40ed1755.patch ]; - installPhase = '' - mkdir -p $out - cp -ra config dba docs htdocs inc locale po scripts testing zonedb $out - ln -s ${config} $out/config/config.php - ''; - buildInputs = [ gettext ]; - }; - webRoot = "${webapp}/htdocs"; - apache = { - user = "wwwrun"; - group = "wwwrun"; - vhostConf = '' - Alias /davical "${webRoot}" - Alias /caldav.php "${webRoot}/caldav.php" - - DirectoryIndex index.php index.html - AcceptPathInfo On - AllowOverride None - Require all granted - - - CGIPassAuth on - SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" - - - RewriteEngine On - - Header unset Access-Control-Allow-Origin - Header unset Access-Control-Allow-Methods - Header unset Access-Control-Allow-Headers - Header unset Access-Control-Allow-Credentials - Header unset Access-Control-Expose-Headers - - Header always set Access-Control-Allow-Origin "*" - Header always set Access-Control-Allow-Methods "GET,POST,OPTIONS,PROPFIND,PROPPATCH,REPORT,PUT,MOVE,DELETE,LOCK,UNLOCK" - Header always set Access-Control-Allow-Headers "User-Agent,Authorization,Content-type,Depth,If-match,If-None-Match,Lock-Token,Timeout,Destination,Overwrite,Prefer,X-client,X-Requested-With" - Header always set Access-Control-Allow-Credentials false - Header always set Access-Control-Expose-Headers "Etag,Preference-Applied" - - RewriteCond %{HTTP:Access-Control-Request-Method} !^$ - RewriteCond %{REQUEST_METHOD} OPTIONS - RewriteRule ^(.*)$ $1 [R=200,L] - - - ''; - }; - phpFpm = rec { - basedir = builtins.concatStringsSep ":" [ webapp config awl ]; - socket = "/var/run/phpfpm/davical.sock"; - pool = '' - listen = ${socket} - user = ${apache.user} - group = ${apache.group} - listen.owner = ${apache.user} - listen.group = ${apache.group} - pm = dynamic - pm.max_children = 60 - pm.start_servers = 2 - pm.min_spare_servers = 1 - pm.max_spare_servers = 10 - - ; Needed to avoid clashes in browser cookies (same domain) - php_value[session.name] = DavicalPHPSESSID - php_admin_value[open_basedir] = "${basedir}:/tmp" - php_admin_value[include_path] = "${awl}/inc:${webapp}/inc" - php_admin_value[session.save_path] = "/var/lib/php/sessions/davical" - php_flag[magic_quotes_gpc] = Off - php_flag[register_globals] = Off - php_admin_value[error_reporting] = "E_ALL & ~E_NOTICE" - php_admin_value[default_charset] = "utf-8" - php_flag[magic_quotes_runtime] = Off - ''; - }; - }; -in - davical diff --git a/virtual/packages/davical_19eb79ebf9250e5f339675319902458c40ed1755.patch b/virtual/packages/davical_19eb79ebf9250e5f339675319902458c40ed1755.patch deleted file mode 100644 index 2a08a5c..0000000 --- a/virtual/packages/davical_19eb79ebf9250e5f339675319902458c40ed1755.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/inc/ui/collection-edit.php b/inc/ui/collection-edit.php -index 3af9edd3b8c4ad9074113273175098841af6a28e..8c1d84012b035f7bc7faedcb24916581a02a5d3e 100644 ---- a/inc/ui/collection-edit.php -+++ b/inc/ui/collection-edit.php -@@ -190,7 +190,7 @@ $privilege_xlate = array( - * @param dbrow $row The row object we read from the database. - * @return string The formatted privileges. - */ --function collection_privilege_format_function( $value, $column, $row ) { -+function collection_privilege_format_function( $value, $column = NULL, $row = NULL ) { - global $privilege_xlate; - - $privs = bits_to_privilege($value, 'calendar'); -diff --git a/inc/ui/principal-edit.php b/inc/ui/principal-edit.php -index 20dee7fa4ca2235ff2f74be0dfb52cbe937ef822..2e37cd596b597bcce1e59d7c02a1c5fc2a7f88ce 100644 ---- a/inc/ui/principal-edit.php -+++ b/inc/ui/principal-edit.php -@@ -454,7 +454,7 @@ EOTEMPLATE; - * @param dbrow $row The row object we read from the database. - * @return string The formatted privileges. - */ --function principal_privilege_format_function( $value, $column, $row ) { -+function principal_privilege_format_function( $value, $column = NULL, $row = NULL ) { - global $privilege_xlate; - - $privs = bits_to_privilege($value,'*'); diff --git a/virtual/packages/infcloud.nix b/virtual/packages/infcloud.nix deleted file mode 100644 index 876578b..0000000 --- a/virtual/packages/infcloud.nix +++ /dev/null @@ -1,38 +0,0 @@ -{ stdenv, fetchzip, ed }: -let - infcloud = rec { - webRoot = stdenv.mkDerivation rec { - version = "0.13.1"; - name = "InfCloud-${version}"; - src = fetchzip { - url = "https://www.inf-it.com/InfCloud_${version}.zip"; - sha256 = "1fjhs0cj0b9fhf5ysfz281mknmmg1z551bas143sxfcqlpa5aiiq"; - }; - buildPhase = '' - ./cache_update.sh - rm config.js - ''; - installPhase = '' - cp -a . $out - ln -s ${./infcloud_config.js} $out/config.js - ''; - buildInputs = [ ed ]; - }; - apache = { - user = "wwwrun"; - group = "wwwrun"; - vhostConf = '' - Alias /carddavmate ${webRoot} - Alias /caldavzap ${webRoot} - Alias /infcloud ${webRoot} - - AllowOverride All - Options FollowSymlinks - Require all granted - DirectoryIndex index.html - - ''; - }; - }; -in - infcloud diff --git a/virtual/packages/infcloud_config.js b/virtual/packages/infcloud_config.js deleted file mode 100644 index ba73860..0000000 --- a/virtual/packages/infcloud_config.js +++ /dev/null @@ -1,1446 +0,0 @@ -/* -InfCloud - the open source CalDAV/CardDAV Web Client -Copyright (C) 2011-2015 - Jan Mate - Andrej Lezo - Matej Mihalik - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - - -// NOTE: see readme.txt before you start to configure this client! - - -// NOTE: do not forget to execute the cache_update.sh script every time you -// update this configuration file or any other files (otherwise your browser -// will use the previous version of files stored in HTML5 cache). Alternatively -// you can update the cache.manifest manually - edit the second line beginning -// with "#V 20" to anything else (this file simple needs "some" change) - - -// Supported setup types (use ONE of them): -// a.) globalAccountSettings => username and password is hardcoded -// in config.js, automatic login without the login screen -// - advantages: fast login process = no username/password is required -// - disadvantages: username/password is visible in your config.js, so -// this type of setup is recommended ONLY for intranet/home users -// b.) globalNetworkCheckSettings => standard setup with login screen -// - advantages: username/password is required (no visible -// username/password in config.js) -// - disadvantages: if a user enters wrong username/password then -// the browser will show authentication popup window (it is NOT -// possible to disable it in JavaScript; see the next option) -// c.) globalNetworkAccountSettings => advanced setup with login screen -// - advantages: no authentication popup if you enter wrong username/ -// password, dynamic XML configuration generator (you can generate -// different configurations for your users /by modifying the "auth" -// module configuration or the PHP code itself/) -// - disadvantages: requires PHP >= 5.3 and additional configuration, -// only basic http authentication is supported => always use https! -// -// -// What is a "principal URL"? => Check you server documentation! -// - "principal URL" is NOT "collection URL" -// - this client automatically detects collections for "principal URL" -// - PROPER "principal URL" looks like: -// https://server.com:8443/principals/users/USER/ -// https://server.com:8443/caldav.php/USER/ -// - INVALID principal URL looks like: -// https://server.com:8443/principals/users/USER/collection/ -// => this is a collection URL -// https://server.com:8443/caldav.php/USER/collection/ -// => this is a collection URL -// https://server.com:8443/principals/users/USER -// => missing trailing '/' -// https://server.com:8443/caldav.php/USER -// => missing trailing '/' -// /caldav.php/USER/ -// => relative URL instead of full URL -// -// -// List of properties used in globalAccountSettings, globalNetworkCheckSettings -// and globalNetworkAccountSettings variables (+ in the "auth" module): -// - href -// Depending on the setup type set the value to: -// a.) globalAccountSettings: full "principal URL" -// b.) globalNetworkCheckSettings: "principal URL" WITHOUT the "USER/" part -// c.) globalNetworkAccountSettings: "full URL" to the "auth" directory -// This property is supported in: -// globalAccountSettings -// globalNetworkCheckSettings -// globalNetworkAccountSettings -// - userAuth -// - userName -// Set the username you want to login. -// - userPassword -// Set the password for the given username. -// This property is supported in: -// globalAccountSettings -// - timeOut -// This option sets the timeout for jQuery .ajax call (in miliseconds). -// Example: -// timeOut: 90000 -// This property is supported in: -// globalAccountSettings -// globalNetworkCheckSettings -// globalNetworkAccountSettings -// - lockTimeOut -// NOTE: used only if server supports LOCK requests -// This option sets the LOCK timeout value if resource locking -// is used (in miliseconds). -// Example: -// lockTimeOut: 10000 -// This property is supported in: -// globalAccountSettings -// globalNetworkCheckSettings -// globalNetworkAccountSettings (available in auth module only) -// - checkContentType -// This option enables a content-type checking for server response. -// If enabled then only objects with proper content-type are inserted -// into the interface. -// If you cannot see data in the interface you may try to disable it (useful -// if your server returns wrong value in "propstat/prop/getcontenttype"). -// If undefined then content-type checking is enabled. -// Examples: -// checkContentType: true -// checkContentType: false -// This property is supported in: -// globalAccountSettings -// globalNetworkCheckSettings -// globalNetworkAccountSettings (available in auth module only) -// - settingsAccount -// NOTE: server support for custom DAV properties is REQUIRED! -// This option sets the account where the client properties such as: -// loaded collections, enabled collections, ... are saved during -// the logout and resource/collection synchronisation -// NOTE: set it to true ONLY for ONE account! -// Examples: -// settingsAccount: true -// settingsAccount: false -// This property is supported in: -// globalAccountSettings -// globalNetworkCheckSettings -// globalNetworkAccountSettings (available in auth module only) -// - delegation -// NOTE: server support for this functionality is REQUIRED! -// This option allows you to load delegated (shared) collections. -// If set to true (default) then delegation functionality is enabled, -// and the interface allows you to load delegated collections. -// If false then delegation functionality is completely disabled. -// Examples: -// delegation: true -// delegation: false -// This property is supported in: -// globalAccountSettings -// globalNetworkCheckSettings -// globalNetworkAccountSettings (available in auth module only) -// - additionalResources -// This options sets the list of additional resources (e.g. shared resources -// accessible by all users). If the server supports delegation (see -// the delegation option above) there is no reason to use this option! -// Supported values: -// - array of URL encoded resource names (not collections), such as: -// 'company' -// 'shared_resource' -// If empty (default) or undefined then shared resources are not loaded -// using this option, but may be loaded using the delegation option. -// Examples: -// additionalResources=[] -// additionalResources=['public', 'shared_resource'] -// This property is supported in: -// globalNetworkCheckSettings -// - hrefLabel -// This option sets the server name in the resource header (useful if -// you want to see custom resource header above the collections). -// You can use the following variables in the value: -// %H = full hostname (including the port number) -// %h = full hostname (without the port number) -// %D = full domain name -// %d = only the first and second level domain -// %P = principal name -// %p = principal name without the @domain.com part (if present) -// %U = logged user name -// %u = logged user name without the @domain.com part (if present) -// If undefined, empty or or null then '%d/%p [%u]' is used. -// Examples: -// hrefLabel: '%d/%p [%u]' -// hrefLabel: '%D/%u' -// This property is supported in: -// globalAccountSettings -// globalNetworkCheckSettings -// globalNetworkAccountSettings (available in auth module only) -// - forceReadOnly -// This option sets the list of collections as "read-only". -// Supported values: -// - true -// all collections will be "read-only" -// - array of URL encoded -// - collections, such as: -// '/caldav.php/user/calendar/' -// '/caldav.php/user%40domain.com/calendar/' -// - regexes, such as: -// new RegExp('^/caldav.php/user/calendar[0-9]/$', 'i') -// specifies the list of collections marked as "read-only" -// If null (default) or undefined then server detected privileges are used. -// Examples: -// forceReadOnly: null -// forceReadOnly: true -// forceReadOnly: ['/caldav.php/user/calendar/', -// '/caldav.php/user/calendar2/'] -// forceReadOnly: [new RegExp('^/.*/user/calendar[0-9]/$', 'i')] -// This property is supported in: -// globalAccountSettings -// globalNetworkCheckSettings -// globalNetworkAccountSettings (available in auth module only, with -// different syntax for regexes) -// - ignoreAlarms -// This option sets list of calendar collections with disabled -// alarm functionality. -// Supported values: -// - true -// alarm functionality is disabled for all collections -// - array of URL encoded -// - collections, such as: -// '/caldav.php/user/calendar/' -// '/caldav.php/user%40domain.com/calendar/' -// - regexes, such as: -// new RegExp('^/caldav.php/user/calendar[0-9]/$', 'i') -// specifies the list of collections with disabled alarm functionality. -// If false (default) or undefined then alarm functionality is enabled -// for all collections. -// Examples: -// ignoreAlarms: true -// ignoreAlarms: ['/caldav.php/user/calendar/', -// '/caldav.php/user/calendar2/'] -// ignoreAlarms: [new RegExp('^/.*/user/calendar[0-9]/$', 'i')] -// This property is supported in: -// globalAccountSettings -// globalNetworkCheckSettings -// globalNetworkAccountSettings (available in auth module only, with -// different syntax for regexes) -// - backgroundCalendars -// This options defines a list of background calendars. If there is -// at least one event defined for the given day in a background calendar, -// the background color for that day will be pink/light-red. -// Supported values: -// - array of URL encoded -// - collections, such as: -// '/caldav.php/user/calendar/' -// '/caldav.php/user%40domain.com/calendar/' -// - regexes, such as: -// new RegExp('^/caldav.php/user/calendar[0-9]/$', 'i') -// specifies the list of background calendar collections. -// Examples: -// backgroundCalendars: ['/caldav.php/user/calendar/', -// '/caldav.php/user/calendar2/'] -// backgroundCalendars: [new RegExp('^/.*/user/calendar[0-9]/$', 'i')] -// This property is supported in: -// globalAccountSettings -// globalNetworkCheckSettings -// globalNetworkAccountSettings (available in auth module only, with -// different syntax for regexes) -// Special options not present in configuration examples: -// NOTE: use ONLY if you know what are you doing! -// - crossDomain -// This option sets the crossDomain for jQuery .ajax call. If null (default) -// then the value is autodetected /and the result is shown in the console/ -// - withCredentials -// This option sets the withCredentials for jQuery .ajax call. The default -// value is false and there is NO REASON to change it to true! -// NOTE: if true, Access-Control-Allow-Origin "*" (CORS header) not works! - - -// globalAccountSettings -// Use this option if you want to use automatic login (without a login -// screen) with hardcoded username/password in config.js. Otherwise use -// globalNetworkCheckSettings or globalNetworkAccountSettings (see below). -// NOTE: if this option is used the value must be an array of object(s). -// List of properties used in globalAccountSettings variable: -// - href -// Set this option to the full "principal URL". -// NOTE: the last character in the value must be '/' -// - userAuth -// - userName -// Set the username you want to login. -// - userPassword -// Set the password for the given username. -// NOTE: for description of other properties see comments at the beginning -// of this file. -// NOTE: for minimal/fast setup you need to set only the href and userAuth -// options. It is safe/recommended to keep the remaining options unchanged! -// Example: -//var globalAccountSettings=[ -// { -// href: 'https://server1.com:8443/caldav.php/USERNAME1/', -// userAuth: -// { -// userName: 'USERNAME1', -// userPassword: 'PASSWORD1' -// }, -// timeOut: 90000, -// lockTimeOut: 10000, -// checkContentType: true, -// settingsAccount: true, -// delegation: true, -// hrefLabel: null, -// forceReadOnly: null, -// ignoreAlarms: false, -// backgroundCalendars: [] -// }, -// { -// href: 'https://server2.com:8443/caldav.php/USERNAME2/', -// ... -// ... -// } -//]; - - -// globalNetworkCheckSettings -// Use this option if you want to use standard login screen without -// hardcoded username/password in config.js (used by globalAccountSettings). -// NOTE: if this option is used the value must be an object. -// List of properties used in globalAccountSettings variable: -// - href -// Set this option to the "principal URL" WITHOUT the "USERNAME/" -// part (this options uses the username from the login screen). -// NOTE: the last character in the value must be '/' -// NOTE: for description of other properties see comments at the beginning -// of this file. -// NOTE: for minimal/fast setup you need to set only the href option. It is -// safe/recommended to keep the remaining options unchanged! -// Example href values: -// OS X server http example (see misc/readme_osx.txt for server setup): -// href: 'http://osx.server.com:8008/principals/users/' -// OS X server https example (see misc/readme_osx.txt for server setup): -// href: 'https://osx.server.com:8443/principals/users/' -// Cyrus server https example: -// href: 'https://cyrus.server.com/dav/principals/user/' -// Example: -// Davical example which automatically detects the protocol, server name, -// port, ... (client installed into Davical "htdocs" subdirectory; -// works "out of the box", no additional setup required): -var globalNetworkCheckSettings={ - href: location.protocol+'//'+location.hostname+ - (location.port ? ':'+location.port: '')+ - location.pathname.replace(RegExp('/+[^/]+/*(index\.html)?$'),'')+ - '/caldav.php/', - timeOut: 90000, - lockTimeOut: 10000, - checkContentType: true, - settingsAccount: true, - delegation: true, - additionalResources: [], - hrefLabel: null, - forceReadOnly: null, - ignoreAlarms: false, - backgroundCalendars: [] -} - - -// globalNetworkAccountSettings -// Try this option ONLY if you have working setup using -// globalNetworkCheckSettings and want to fix the authentication popup -// window problem (if invalid username/password is entered)! -// If you use this option then your browser sends username/password to the PHP -// "auth" module ("auth" directory) instead of the DAV server itself. -// The "auth" module then validates your username/password against your server, -// and if the authentication is successful, then it sends back a configuration -// XML (requires additional configuration). The resulting XML is handled -// IDENTICALLY as the globalAccountSettings configuration option. -// NOTE: for the "auth" module configuration see readme.txt! -// NOTE: this option invokes a login screen and disallows access until -// the client gets correct XML configuration file from the server! -// List of properties used in globalNetworkAccountSettings variable: -// - href -// Set this option to the "full URL" of the "auth" directory -// NOTE: the last character in the value must be '/' -// NOTE: for description of other properties see comments at the beginning -// of this file. -// Example href values: -// href: 'https://server.com/client/auth/' -// Example: -// Use this configuration if the "auth" module is located in the client -// installation subdirectory (default): -//var globalNetworkAccountSettings={ -// href: location.protocol+'//'+location.hostname+ -// (location.port ? ':'+location.port : '')+ -// location.pathname.replace(RegExp('index\.html$'),'')+ -// 'auth/', -// timeOut: 30000 -//}; - - -// globalUseJqueryAuth -// Use jQuery .ajax() auth or custom header for HTTP basic auth (default). -// Set this option to true if your server uses digest auth (note: you may -// experience auth popups on some browsers). -// If undefined (or empty), custom header for HTTP basic auth is used. -// Example: -//var globalUseJqueryAuth=false; - - -// globalBackgroundSync -// Enable background synchronization even if the browser window/tab has no -// focus. -// If false, synchronization is performed only if the browser window/tab -// is focused. If undefined or not false, then background sync is enabled. -// Example: -var globalBackgroundSync=true; - - -// globalSyncResourcesInterval -// This option defines how often (in miliseconds) are resources/collections -// asynchronously synchronized. -// Example: -var globalSyncResourcesInterval=120000; - - -// globalEnableRefresh -// This option enables or disables the manual synchronization button in -// the interface. If this option is enabled then users can perform server -// synchronization manually. Enabling this option may cause high server -// load (even DDOS) if users will try to manually synchronize data too -// often (instead of waiting for the automatic synchronization). -// If undefined or false, the synchronization button is disabled. -// NOTE: enable this option only if you really know what are you doing! -// Example: -var globalEnableRefresh=false; - - -// globalEnableKbNavigation -// Enable basic keyboard navigation using arrow keys? -// If undefined or not false, keyboard navigation is enabled. -// Example: -var globalEnableKbNavigation=true; - - -// globalSettingsType -// Where to store user settings such as: active view, enabled/selected -// collections, ... (the client store them into DAV property on the server). -// NOTE: not all servers support storing DAV properties (some servers support -// only subset /or none/ of these URLs). -// Supported values: -// - 'principal-URL', '', null or undefined (default) => settings are stored -// to principal-URL (recommended for most servers) -// - 'addressbook-home-set' => settings are are stored to addressbook-home-set -// - 'calendar-home-set' => settings are stored to calendar-home-set -// Example: -//var globalSettingsType=''; - - -// globalCrossServerSettingsURL -// Settings such as enabled/selected collections are stored on the server -// (see the previous option) in form of full URL -// (e.g.: https://user@server:port/principal/collection/), but even if this -// approach is "correct" (you can use the same principal URL with multiple -// different logins, ...) it causes a problem if your server is accessible -// from multiple URLs (e.g. http://server/ and https://server/). If you want -// to store only the "principal/collection/" part of the URL (instead of the -// full URL) then enable this option. -// Example: -//var globalCrossServerSettingsURL=false; - - -// globalInterfaceLanguage -// Default interface language (note: this option is case sensitive): -// cs_CZ (Čeština [Czech]) -// da_DK (Dansk [Danish]; thanks Niels Bo Andersen) -// de_DE (Deutsch [German]; thanks Marten Gajda and Thomas Scheel) -// en_US (English [English/US]) -// es_ES (Español [Spanish]; thanks Damián Vila) -// fr_FR (Français [French]; thanks John Fischer) -// it_IT (Italiano [Italian]; thanks Luca Ferrario) -// ja_JP (日本語 [Japan]; thanks Muimu Nakayama) -// hu_HU (Magyar [Hungarian]) -// nl_NL (Nederlands [Dutch]; thanks Johan Vromans) -// sk_SK (Slovenčina [Slovak]) -// tr_TR (Türkçe [Turkish]; thanks Selcuk Pultar) -// ru_RU (Русский [Russian]; thanks Александр Симонов) -// uk_UA (Українська [Ukrainian]; thanks Serge Yakimchuck) -// zh_CN (中国 [Chinese]; thanks Fandy) -// Example: -var globalInterfaceLanguage='fr_FR'; - - -// globalInterfaceCustomLanguages -// If defined and not empty then only languages listed here are shown -// at the login screen, otherwise (default) all languages are shown -// NOTE: values in the array must refer to an existing localization -// (see the option above) -// Example: -// globalInterfaceCustomLanguages=['en_US', 'sk_SK']; -var globalInterfaceCustomLanguages=[]; - - -// globalSortAlphabet -// Use JavaScript localeCompare() or custom alphabet for data sorting. -// Custom alphabet is used by default because JavaScript localeCompare() -// not supports collation and often returns "wrong" result. If set to null -// then localeCompare() is used. -// Example: -// var globalSortAlphabet=null; -var globalSortAlphabet=' 0123456789'+ - 'AÀÁÂÄÆÃÅĀBCÇĆČDĎEÈÉÊËĒĖĘĚFGĞHIÌÍÎİÏĪĮJKLŁĹĽMNŃÑŇOÒÓÔÖŐŒØÕŌ'+ - 'PQRŔŘSŚŠȘșŞşẞTŤȚțŢţUÙÚÛÜŰŮŪVWXYÝŸZŹŻŽ'+ - 'aàáâäæãåābcçćčdďeèéêëēėęěfgğhiìíîïīįıjklłĺľmnńñňoòóôöőœøõō'+ - 'pqrŕřsśšßtťuùúûüűůūvwxyýÿzźżžАБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЮЯ'+ - 'Ьабвгґдеєжзиіїйклмнопрстуфхцчшщюяь'; - - -// globalSearchTransformAlphabet -// To support search without diacritics (e.g. search for 'd' will find: 'Ď', 'ď') -// it is required to define something like "character equivalence". -// key = regex text, value = search character -// Example: -var globalSearchTransformAlphabet={ - '[ÀàÁáÂâÄäÆæÃãÅåĀā]': 'a', '[ÇçĆćČč]': 'c', '[Ďď]': 'd', - '[ÈèÉéÊêËëĒēĖėĘęĚě]': 'e', '[Ğğ]': 'g', '[ÌìÍíÎîİıÏïĪīĮį]': 'i', - '[ŁłĹ弾]': 'l', '[ŃńÑñŇň]': 'n', '[ÒòÓóÔôÖöŐőŒœØøÕõŌō]': 'o', - '[ŔŕŘř]': 'r', '[ŚśŠšȘșŞşẞß]': 's', '[ŤťȚțŢţ]': 't', - '[ÙùÚúÛûÜüŰűŮůŪū]': 'u', '[ÝýŸÿ]': 'y', '[ŹźŻżŽž]': 'z' -}; - -// globalResourceAlphabetSorting -// If more than one resource (server account) is configured, sort the -// resources alphabetically? -// Example: -var globalResourceAlphabetSorting=true; - - -// globalNewVersionNotifyUsers -// Update notification will be shown only to users with login names defined -// in this array. -// If undefined (or empty), update notifications will be shown to all users. -// Example: -// globalNewVersionNotifyUsers=['admin', 'peter']; -var globalNewVersionNotifyUsers=[]; - - -// globalDatepickerFormat -// Set the datepicker format (see -// http://docs.jquery.com/UI/Datepicker/formatDate for valid values). -// NOTE: date format is predefined for each localization - use this option -// ONLY if you want to use custom date format (instead of the localization -// predefined one). -// Example: -//var globalDatepickerFormat='dd.mm.yy'; -var globalDatepickerFormat='yy-mm-dd'; - - -// globalDatepickerFirstDayOfWeek -// Set the datepicker first day of the week: Sunday is 0, Monday is 1, etc. -// Example: -var globalDatepickerFirstDayOfWeek=1; - - -// globalHideInfoMessageAfter -// How long are information messages (such as: success, error) displayed -// (in miliseconds). -// Example: -var globalHideInfoMessageAfter=1800; - - -// globalEditorFadeAnimation -// Set the editor fade in/out animation duration when editing or saving data -// (in miliseconds). -// Example: -var globalEditorFadeAnimation=666; - - - - -// ******* CalDAV (CalDavZAP) related settings ******* // - -// globalEventStartPastLimit, globalEventStartFutureLimit, globalTodoPastLimit -// Number of months pre-loaded from past/future in advance for calendars -// and todo lists (if null then date range synchronization is disabled). -// NOTE: interval synchronization is used only if your server supports -// sync-collection REPORT (e.g. DAViCal). -// NOTE: if you experience problems with data loading and your server has -// no time-range filtering support set these variables to null. -// Example: -var globalEventStartPastLimit=3; -var globalEventStartFutureLimit=3; -var globalTodoPastLimit=1; - - -// globalLoadedCalendarCollections -// This option sets the list of calendar collections (down)loaded after login. -// If empty then all calendar collections for the currently logged user are -// loaded. -// NOTE: settings stored on the server (see settingsAccount) overwrite this -// option. -// Example: -var globalLoadedCalendarCollections=[]; - - -// globalLoadedTodoCollections -// This option sets the list of todo collections (down)loaded after login. -// If empty then all todo collections for the currently logged user are loaded. -// NOTE: settings stored on the server (see settingsAccount) overwrite this -// option. -// Example: -var globalLoadedTodoCollections=[]; - - -// globalActiveCalendarCollections -// This options sets the list of calendar collections checked (enabled -// checkbox => data visible in the interface) by default after login. -// If empty then all loaded calendar collections for the currently logged -// user are checked. -// NOTE: only already (down)loaded collections can be checked (see -// the globalLoadedCalendarCollections option). -// NOTE: settings stored on the server (see settingsAccount) overwrite this -// option. -// Example: -var globalActiveCalendarCollections=[]; - - -// globalActiveTodoCollections -// This options sets the list of todo collections checked (enabled -// checkbox => data visible in the interface) by default after login. -// If empty then all loaded todo collections for the currently logged -// user are checked. -// NOTE: only already (down)loaded collections can be checked (see -// the globalLoadedTodoCollections option). -// NOTE: settings stored on the server (see settingsAccount) overwrite this -// option. -// Example: -var globalActiveTodoCollections=[]; - - -// globalCalendarSelected -// This option sets which calendar collection will be pre-selected -// (if you create a new event) by default after login. -// The value must be URL encoded path to a calendar collection, -// for example: 'USER/calendar/' -// If empty or undefined then the first available calendar collection -// is selected automatically. -// NOTE: only already (down)loaded collections can be pre-selected (see -// the globalLoadedCalendarCollections option). -// NOTE: settings stored on the server (see settingsAccount) overwrite this -// option. -// Example: -//var globalCalendarSelected=''; - - -// globalTodoCalendarSelected -// This option sets which todo collection will be pre-selected -// (if you create a new todo) by default after login. -// The value must be URL encoded path to a todo collection, -// for example: 'USER/todo_calendar/' -// If empty or undefined then the first available todo collection -// is selected automatically. -// NOTE: only already (down)loaded collections can be pre-selected (see -// the globalLoadedTodoCollections option). -// NOTE: settings stored on the server (see settingsAccount) overwrite this -// option. -// Example: -//var globalTodoCalendarSelected=''; - - -// globalActiveView -// This options sets the default fullcalendar view option (the default calendar -// view after the first login). -// Supported values: -// - 'month' -// - 'multiWeek' -// - 'agendaWeek' -// - 'agendaDay' -// NOTE: we use custom and enhanced version of fullcalendar! -// Example: -var globalActiveView='multiWeek'; - - -// globalOpenFormMode -// Open new event form on 'single' or 'double' click. -// If undefined or not 'double', then 'single' is used. -// Example: -var globalOpenFormMode='double'; - - -// globalTodoListFilterSelected -// This options sets the list of filters in todo list that are selected -// after login. -// Supported options: -// - 'filterAction' -// - 'filterProgress' (available only if globalAppleRemindersMode is disabled) -// - 'filterCompleted' -// - 'filterCanceled' (available only if globalAppleRemindersMode is disabled) -// NOTE: settings stored on the server (see settingsAccount) overwrite this -// option. -// Example: -var globalTodoListFilterSelected=['filterAction', 'filterProgress']; - - -// globalCalendarStartOfBusiness, globalCalendarEndOfBusiness -// These options set the start and end of business hours with 0.5 hour -// precision. Non-business hours are faded out in the calendar interface. -// If both variables are set to the same value then no fade out occurs. -// Example: -var globalCalendarStartOfBusiness=8; -var globalCalendarEndOfBusiness=17; - - -// globalDefaultEventDuration -// This option sets the default duration (in minutes) for newly created events. -// If undefined or null, globalCalendarEndOfBusiness value will be taken as -// a default end time instead. -// Example: -var globalDefaultEventDuration=120; - - -// globalAMPMFormat -// This option enables to use 12 hours format (AM/PM) for displaying time. -// NOTE: time format is predefined for each localization - use this option -// ONLY if you want to use custom time format (instead of the localization -// predefined one). -// Example: -//var globalAMPMFormat=false; - - -// globalTimeFormatBasic -// This option defines the time format information for events in month and -// multiweek views. If undefined or null then default value is used. -// If defined as empty string no time information is shown in these views. -// See http://arshaw.com/fullcalendar/docs/utilities/formatDate/ for exact -// formating rules. -// Example: -//var globalTimeFormatBasic=''; - - -// globalTimeFormatAgenda -// This option defines the time format information for events in day and -// week views. If undefined or null then default value is used. -// If defined as empty string no time information is shown in these views. -// See http://arshaw.com/fullcalendar/docs/utilities/formatDate/ for exact -// formating rules. -// Example: -//var globalTimeFormatAgenda=''; - - -// globalDisplayHiddenEvents -// This option defined whether events from unechecked calendars are displayed -// with certain transparency (true) or completely hidden (false). -// Example: -var globalDisplayHiddenEvents=false; - - -// globalTimeZoneSupport -// This option enables timezone support in the client. -// NOTE: timezone cannot be specified for all-day events because these don't -// have start and end time. -// If this option is disabled then local time is used. -// Example: -var globalTimeZoneSupport=true; - - -// globalTimeZone -// If timezone support is enabled, this option sets the default timezone. -// See timezones.js or use the following command to get the list of supported -// timezones (defined in timezones.js): -// grep "'[^']\+': {" timezones.js | sed -Ee "s#(\s*'|':\s*\{)##g" -// Example: -var globalTimeZone='Europe/Paris'; - - -// globalTimeZonesEnabled -// This option sets the list of available timezones in the interface (for the -// list of supported timezones see the comment for the previous configuration -// option). -// NOTE: if there is at least one event/todo with a certain timezone defined, -// that timezone is enabled (even if it is not present in this list). -// Example: -// var globalTimeZonesEnabled=['America/New_York', 'Europe/Berlin']; -var globalTimeZonesEnabled=[]; - - -// globalRewriteTimezoneComponent -// This options sets whether the client will enhance/replace (if you edit an -// event or todo) the timezone information using the official IANA timezone -// database information (recommended). -// Example: -var globalRewriteTimezoneComponent=true; - - -// globalRemoveUnknownTimezone -// This options sets whether the client will remove all non-standard timezone -// names from events and todos (if you edit an event or todo) -// (e.g.: /freeassociation.sourceforge.net/Tzfile/Europe/Vienna) -// Example: -var globalRemoveUnknownTimezone=false; - - -// globalShowHiddenAlarms -// This option sets whether the client will show alarm notifications for -// unchecked calendars. If this option is enabled and you uncheck a calendar -// in the calendar list, alarm notifications will be temporary disabled for -// unchecked calendar(s). -// Example: -var globalShowHiddenAlarms=false; - - -// globalIgnoreCompletedOrCancelledAlarms -// This options sets whether the client will show alarm notifications for -// already completed or cancelled todos. If enabled then alarm notification -// for completed and cancelled todos are disabled. -// Example: -var globalIgnoreCompletedOrCancelledAlarms=true; - - -// globalMozillaSupport -// Mozilla automatically treats custom repeating event calculations as if -// the start day of the week is Monday, despite what day is chosen in settings. -// Set this variable to true to use the same approach, ensuring compatible -// event rendering in special cases. -// Example: -var globalMozillaSupport=false; - - -// globalCalendarColorPropertyXmlns -// This options sets the namespace used for storing the "calendar-color" -// property by the client. -// If true, undefined (or empty) "http://apple.com/ns/ical/" is used (Apple -// compatible). If false, then the calendar color modification functionality -// is completely disabled. -// Example: -//var globalCalendarColorPropertyXmlns=true; - - -// globalWeekendDays -// This option sets the list of days considered as weekend days (these -// are faded out in the calendar interface). Non-weekend days are automatically -// considered as business days. -// Sunday is 0, Monday is 1, etc. -// Example: -var globalWeekendDays=[0, 6]; - - -// globalAppleRemindersMode -// If this option is enabled then then client will use the same approach -// for handling repeating reminders (todos) as Apple. It is STRONGLY -// recommended to enabled this option if you use any Apple clients for -// reminders (todos). -// Supported options: -// - 'iOS6' -// - 'iOS7' -// - true (support of the latest iOS version - 'iOS8') -// - false -// If this option is enabled: -// - RFC todo support is SEVERELY limited and the client mimics the behaviour -// of Apple Reminders.app (to ensure maximum compatibility) -// - when a single instance of repeating todo is edited, it becomes an -// autonomous non-repeating todo with NO relation to the original repeating -// todo -// - capabilities of repeating todos are limited - only the first instance -// is ever visible in the interface -// - support for todo DTSTART attribute is disabled -// - support for todo STATUS attribute other than COMPLETED and NEEDS-ACTION -// is disabled -// - [iOS6 only] support for LOCATION and URL attributes is disabled -// Example: -var globalAppleRemindersMode=true; - - -// globalSubscribedCalendars -// This option specifies a list of remote URLs to ics files (e.g.: used -// for distributing holidays information). Subscribed calendars are -// ALWAYS read-only. Remote servers where ics files are hosted MUST -// return proper CORS headers (see readme.txt) otherwise this functionality -// will not work! -// NOTE: subsribed calendars are NOT "shared" calendars. For "shared" -// calendars see the delegation option in globalAccountSettings, -// globalNetworkCheckSettings and globalNetworkAccountSettings. -// List of properties used in globalSubscribedCalendars variable: -// - hrefLabel -// This options defines the header string above the subcsribed calendars. -// - calendars -// This option specifies an array of remote calendar objects with the -// following properties: -// - href -// Set this option to the "full URL" of the remote calendar -// - userAuth -// NOTE: keep empty if remote authentication is not required! -// - userName -// Set the username you want to login. -// - userPassword -// Set the password for the given username. -// - typeList -// Set the list of objects you want to process from remote calendars; -// two options are available: -// - 'vevent' (show remote events in the interface) -// - 'vtodo' (show remote todos in the interface) -// - ignoreAlarm -// Set this option to true if you want to disable alarm notifications -// from the remote calendar. -// - displayName -// Set this option to the name of the calendar you want to see -// in the interface. -// - color -// Set the calendar color you want to see in the interface. -// Example: -//var globalSubscribedCalendars={ -// hrefLabel: 'Subscribed', -// calendars: [ -// { -// href: 'http://something.com/calendar.ics', -// userAuth: { -// userName: '', -// userPassword: '' -// }, -// typeList: ['vevent', 'vtodo'], -// ignoreAlarm: true, -// displayName: 'Remote Calendar 1', -// color: '#ff0000' -// }, -// { -// href: 'http://calendar.com/calendar2.ics', -// ... -// ... -// } -// ] -//}; - - - -// ******* CardDAV (CardDavMATE) related settings ******* // - - -// globalLoadedAddressbookCollections -// This option sets the list of addressbook collections (down)loaded after -// login. If empty then all addressbook collections for the currently logged -// user are loaded. -// NOTE: settings stored on the server (see settingsAccount) overwrite this -// option. -// Example: -var globalLoadedAddressbookCollections=[]; - - -// globalActiveAddressbookCollections -// This options sets the list of addressbook collections checked (enabled -// checkbox => data visible in the interface) by default after login. -// If empty then all loaded addressbook collections for the currently logged -// user are checked. -// NOTE: only already (down)loaded collections can be checked (see -// the globalLoadedAddressbookCollections option). -// NOTE: settings stored on the server (see settingsAccount) overwrite this -// option. -// Example: -var globalActiveAddressbookCollections=[]; - - -// globalAddressbookSelected -// This option sets which addressbook collection will be pre-selected -// (if you create a new contact) by default after login. -// The value must be URL encoded path to an addressbook collection, -// for example: 'USER/addressbook/' -// If empty or undefined then the first available addressbook collection -// is selected automatically. -// NOTE: only already (down)loaded collections can be pre-selected (see -// the globalLoadedAddressbookCollections option). -// NOTE: settings stored on the server (see settingsAccount) overwrite this -// option. -// Example: -//var globalAddressbookSelected=''; - - -// globalCompatibility -// This options is reserved for various compatibility settings. -// NOTE: if this option is used the value must be an object. -// Currently there is only one supported option: -// - anniversaryOutputFormat -// Different clients use different (and incompatible) approach -// to store anniversary date in vCards. Apple stores this attribute as: -// itemX.X-ABDATE;TYPE=pref:2000-01-01\r\n -// itemX.X-ABLabel:_$!!$_\r\n' -// other clients store this attribute as: -// X-ANNIVERSARY:2000-01-01\r\n -// Choose 'apple' or 'other' (lower case) for your 3rd party client -// compatibility. You can chose both: ['apple', 'other'], but it may -// cause many problems in the future, for example: duplicate anniversary -// dates, invalid/old anniversary date in your clients, ...) -// Examples: -// anniversaryOutputFormat: ['other'] -// anniversaryOutputFormat: ['apple', 'other'] -// Example: -var globalCompatibility={anniversaryOutputFormat: ['apple']}; - - -// globalUriHandler{Tel,Email,Url,Profile} -// These options set the URI handlers for TEL, EMAIL, URL and X-SOCIALPROFILE -// vCard attributes. Set them to null (or comment out) to disable. -// NOTE: for globalUriHandlerTel is recommended to use 'tel:', 'callto:' -// or 'skype:'. The globalUriHandlerUrl value is used only if no URI handler -// is defined in the URL. -// NOTE: it is safe to keep these values unchanged! -// Example: -var globalUriHandlerTel='tel:'; -var globalUriHandlerEmail='mailto:'; -var globalUriHandlerUrl='http://'; -var globalUriHandlerProfile={ - 'twitter': 'http://twitter.com/%u', - 'facebook': 'http://www.facebook.com/%u', - 'flickr': 'http://www.flickr.com/photos/%u', - 'linkedin': 'http://www.linkedin.com/in/%u', - 'myspace': 'http://www.myspace.com/%u', - 'sinaweibo': 'http://weibo.com/n/%u' -}; - - -// globalDefaultAddressCountry -// This option sets the default country for new address fields. -// See common.js or use the following command to get the list of -// all supported country codes (defined in common.js): -// grep -E "'[a-z]{2}':\s+\[" common.js | sed -Ee 's#^\s+|\s+\[\s+# #g' -// Example: -var globalDefaultAddressCountry='fr'; - - -// globalAddressCountryEquivalence -// This option sets the processing of the country field specified -// in the vCard ADR attribute. -// By default the address field in vCard looks like: -// ADR;TYPE=WORK:;;1 Waters Edge;Baytown;LA;30314;USA\r\n -// what cause a problem, because the country field is a plain -// text and can contain any value, e.g.: -// USA -// United States of America -// US -// and because the address format can be completely different for -// each country, e.g.: -// China address example: -// [China] -// [Province] [City] -// [Street] -// [Postal] -// Japan address example: -// [Postal] -// [Prefecture] [County/City] -// [Further Divisions] -// [Japan] -// the client needs to correctly detect the country from the ADR -// attribute. Apple solved this problem by using: -// item1.ADR;TYPE=WORK:;;1 Waters Edge;Baytown;LA;30314;USA\r\n -// item1.X-ABADR:us\r\n -// where the second "related" attribute defines the country code -// for the ADR attribute. This client uses the same approach, but -// if the vCard is created by 3rd party clients and the X-ABADR -// is missing, it is possible to define additional "rules" for -// country matching. These rules are specied by the country code -// (for full list of country codes see the comment for pre previous -// option) and a case insensitive regular expression (which matches -// the plain text value in the country field). -// NOTE: if X-ABADR is not present and the country not matches any -// country defined in this option, then globalDefaultAddressCountry -// is used by default. -// Example: -var globalAddressCountryEquivalence=[ - {country: 'de', regex: '^\\W*Deutschland\\W*$'}, - {country: 'sk', regex: '^\\W*Slovensko\\W*$'} -]; - - -// globalAddressCountryFavorites -// This option defines the list of countries which are shown at the top -// of the country list in the interface (for full list of country codes -// see the comment for pre globalDefaultAddressCountry option). -// Example: -// var globalAddressCountryFavorites=['de','sk']; -var globalAddressCountryFavorites=[]; - - -// globalAddrColorPropertyXmlns -// This options sets the namespace used for storing the "addressbook-color" -// property by the client. -// If true, undefined (or empty) "http://inf-it.com/ns/ab/" is used. -// If false, then the addressbook color modification functionality -// is completely disabled, and addressbook colors in the interface are -// generated automatically. -// Example: -//var globalAddrColorPropertyXmlns=true; - - -// globalContactStoreFN -// This option specifies how the FN (formatted name) is stored into vCard. -// The value for this options must be an array of strings, that can contain -// the following variables: -// prefix -// last -// middle -// first -// suffix -// The string element of the array can contain any other characters (usually -// space or colon). Elements are added into FN only if the there is -// a variable match, for example if: -// last='Lastname' -// first='Firstname' -// middle='' (empty) -// and this option is set to: -// ['last', ' middle', ' first'] (space in the second and third element) -// the resulting value for FN will be: 'Lastname Firstname' and not -// 'Lastname Firstname' (two spaces), because the middle name is empty (so -// the second element is completely ignored /not added into FN/). -// NOTE: this attribute is NOT used by this client, and it is also NOT -// possible to directly edit it in the interface. -// Examples: -// var globalContactStoreFN=[' last', ' middle', ' first']; -// var globalContactStoreFN=['last', ', middle', ' ,first']; -var globalContactStoreFN=['prefix',' last',' middle',' first',' suffix']; - - -// globalGroupContactsByCompanies -// This options specifies how contacts are grouped in the interface. -// By default the interface looks like (very simple example): -// A -// Adams Adam -// Anderson Peter -// B -// Brown John -// Baker Josh -// if grouped by company/deparment the result is: -// Company A [Department X] -// Adams Adam -// Brown John -// Company B [Department Y] -// Anderson Peter -// Baker Josh -// If this option is set to true contacts are grouped by company/department, -// otherwise (default) contacts are grouped by letters of the alphabet. -// If undefined or not true, grouping by alphabet letters is used. -// NOTE: see also the globalCollectionDisplay option below. -var globalGroupContactsByCompanies=false; - - -// globalCollectionDisplay -// This options specifies how data columns in the contact list are displayed. -// -// NOTE: columns are displayed ONLY if there is enought horizontal place in -// the browser window (e.g. if you define 5 columns here, but your browser -// window is not wide enough, you will see only first 3 columns instead of 5). -// -// NOTE: see the globalContactDataMinVisiblePercentage option which defines the -// width for columns. -// -// The value must be an array of columns, where each column is represented by -// an object with the following properties: -// label => the value of this option is a string used as column header -// You can use the following localized variables in the label string: -// - {Name} -// - {FirstName} -// - {LastName} -// - {MiddleName} -// - {NickName} -// - {Prefix} -// - {Suffix} -// - {BirthDay} -// - {PhoneticLastName} -// - {PhoneticFirstName} -// - {JobTitle} -// - {Company} -// - {Department} -// - {Categories} -// - {NoteText} -// - {Address}, {AddressWork}, {AddressHome}, {AddressOther} -// - {Phone}, {PhoneWork}, {PhoneHome}, {PhoneCell}, {PhoneMain}, -// {PhonePager}, {PhoneFax}, {PhoneIphone}, {PhoneOther} -// - {Email}, {EmailWork}, {EmailHome}, {EmailMobileme}, {EmailOther} -// - {URL}, {URLWork}, {URLHome}, {URLHomepage}, {URLOther} -// - {Dates}, {DatesAnniversary}, {DatesOther} -// - {Related}, {RelatedManager}, {RelatedAssistant}, {RelatedFather}, -// {RelatedMother}, {RelatedParent}, {RelatedBrother}, {RelatedSister}, -// {RelatedChild}, {RelatedFriend}, {RelatedSpouse}, {RelatedPartner}, -// {RelatedOther} -// - {Profile}, {ProfileTwitter}, {ProfileFacebook}, {ProfileFlickr}, -// {ProfileLinkedin}, {ProfileMyspace}, {ProfileSinaweibo} -// - {IM}, {IMWork}, {IMHome}, {IMMobileme}, {IMOther}, {IMAim}, {IMIcq}, -// {IMIrc}, {IMJabber}, {IMMsn}, {IMYahoo}, {IMFacebook}, {IMGadugadu}, -// {IMGoogletalk}, {IMQq}, {IMSkype} -// value => the value of this option is an array of format strings, or -// an object with the following properties: -// - company (used for company contacts) -// - personal (used for user contacts) -// where the value of these properties is an array of format strings used -// for company or user contacts (you can have different values in the same -// column for personal and company contacts). -// You can use the following simple variables in the format string: -// - {FirstName} -// - {LastName} -// - {MiddleName} -// - {NickName} -// - {Prefix} -// - {Suffix} -// - {BirthDay} -// - {PhoneticLastName} -// - {PhoneticFirstName} -// - {JobTitle} -// - {Company} -// - {Department} -// - {Categories} -// - {NoteText} -// You can also use parametrized variables, where the parameter is enclosed -// in square bracket. Paramatrized variables are useful to extract data -// such as home phone {Phone[type=home]}, extract the second phone number -// {Phone[:1]} (zero based indexing) or extract the third home phone number -// {Phone[type=home][:2]} from the vCard. -// NOTE: if the parametrized variable matches multiple items, e.g.: -// {Phone[type=work]} (if the contact has multiple work phones) then the -// first one is used! -// -// The following parametrized variables are supported (note: you can use -// all of them also without parameters /the first one will be used/): -// - {Address[type=XXX]} or {Address[:NUM]} or {Address[type=XXX][:NUM]} -// where supported values for XXX are: -// - work -// - home -// - other -// - any other custom value -// - {Phone[type=XXX]} or {Phone[:NUM]} or {Phone[type=XXX][:NUM]} -// where supported values for XXX are: -// - work -// - home -// - cell -// - main -// - pager -// - fax -// - iphone -// - other -// - any other custom value -// - {Email[type=XXX]} or {Email[:NUM]} or {Email[type=XXX][:NUM]} -// where supported values for XXX are: -// - work -// - home -// - mobileme -// - other -// - any other custom value -// - {URL[type=XXX]} or {URL[:NUM]} or {URL[type=XXX][:NUM]} -// where supported values for XXX are: -// - work -// - home -// - homepage -// - other -// - any other custom value -// - {Dates[type=XXX]} or {Dates[:NUM]} or {Dates[type=XXX][:NUM]} -// where supported values for XXX are: -// - anniversary -// - other -// - any other custom value -// - {Related[type=XXX]} or {Related[:NUM]} or {Related[type=XXX][:NUM]} -// where supported values for XXX are: -// - manager -// - assistant -// - father -// - mother -// - parent -// - brother -// - sister -// - child -// - friend -// - spouse -// - partner -// - other -// - any other custom value -// - {Profile[type=XXX]} or {Profile[:NUM]} or {Profile[type=XXX][:NUM]} -// where supported values for XXX are: -// - twitter -// - facebook -// - flickr -// - linkedin -// - myspace -// - sinaweibo -// - any other custom value -// - {IM[type=XXX]} or {IM[service-type=YYY]} or {IM[:NUM]} -// where supported values for XXX are: -// - work -// - home -// - mobileme -// - other -// - any other custom value -// and supported values for YYY are: -// - aim -// - icq -// - irc -// - jabber -// - msn -// - yahoo -// - facebook -// - gadugadu -// - googletalk -// - qq -// - skype -// - any other custom value -// -// NOTE: if you want to use the "any other custom value" option (for XXX -// or YYY above) you MUST double escape the following characters: -// =[]{}\ -// for example: -// - for profile type "=XXX=" use: '{Profile[type=\\=XXX\\=]}' -// - for profile type "\XXX\" use: '{Profile[type=\\\\XXX\\\\]}' -// -// NOTE: if you want to use curly brackets in the format string you must -// double escape it, e.g.: ['{Company}', '\\{{Department}\\}'] -// -// The format string (for the value option) is an array to allow full -// customization of the interface. For example if: -// value: ['{LastName} {MiddleName} {FirstName}'] -// and the person has no middle name, then the result in the column -// will be (without quotes): -// "Parker Peter" (note: two space characters) -// but if you use: -// value: ['{LastName}', ' {MiddleName}', ' {FirstName}'] -// then the result will be (without quotes): -// "Parker Peter" (note: only one space character) -// The reason is that only those elements of the array are appended -// into the result where non-empty substitution was performed (so the -// ' {MiddleName}' element in this case is ignored, because the person -// in the example above has no /more precisely has empty/ middle name). -// -// Examples: -// To specify two columns (named "Company" and "Department / LastName"), -// where the first will display the company name, and the second will display -// department for company contacts (with "Dep -" prefix), and lastname for -// personal contacts (with "Name -" prefix) use: -// var globalCollectionDisplay=[ -// { -// label: 'Company', -// value: ['{Company}'] -// }, -// { -// label: 'Department / LastName', -// value: { -// company: ['Dep - {Department}'], -// personal: ['Name - {LastName}'] -// } -// } -// ]; -// To specify 3 columns (named "Categories", "URL" and "IM"), where the first -// will display categories, second will display the third work URL, and third -// will display ICQ IM use: -// var globalCollectionDisplay=[ -// { -// label: 'Categories', -// value: ['{Categories}'] -// }, -// { -// label: 'URL', -// value: ['{URL[type=WORK][:2]}'] -// }, -// { -// label: 'IM', -// value: ['{IM[service-type=ICQ]}'] -// } -// ]; -// -// Recommended settings if globalGroupContactsByCompanies -// is set to false: -// var globalCollectionDisplay=[ -// { -// label: '{Name}', -// value: ['{LastName}', ' {MiddleName}', ' {FirstName}'] -// }, -// { -// label: '{Company} [{Department}]', -// value: ['{Company}', ' [{Department}]'] -// }, -// { -// label: '{JobTitle}', -// value: ['{JobTitle}'] -// }, -// { -// label: '{Email}', -// value: ['{Email[:0]}'] -// }, -// { -// label: '{Phone} 1', -// value: ['{Phone[:0]}'] -// }, -// { -// label: '{Phone} 2', -// value: ['{Phone[:1]}'] -// }, -// { -// label: '{NoteText}', -// value: ['{NoteText}'] -// } -// ]; -// -// Recommended settings if globalGroupContactsByCompanies -// is set to true: -// var globalCollectionDisplay=[ -// { -// label: '{Name}', -// value: { -// personal: ['{LastName}', ' {MiddleName}', ' {FirstName}'], -// company: ['{Company}', ' [{Department}]'] -// } -// }, -// { -// label: '{JobTitle}', -// value: ['{JobTitle}'] -// }, -// { -// label: '{Email}', -// value: ['{Email[:0]}'] -// }, -// { -// label: '{Phone} 1', -// value: ['{Phone[:0]}'] -// }, -// { -// label: '{Phone} 2', -// value: ['{Phone[:1]}'] -// }, -// { -// label: '{NoteText}', -// value: ['{NoteText}'] -// } -// ]; -// -// NOTE: if left undefined, the recommended settings will be used. - - -// globalCollectionSort -// This options sets the ordering of contacts in the interface. In general -// contacts are ordered alphabetically by an internal "sort string" which -// is created for each contact. Here you can specify how this internal string -// is created. The value is a simple array holding only the values from the -// value property defined in the globalCollectionDisplay option. -// If undefined, the definition from globalCollectionDisplay is used. -// Example: -// var globalCollectionSort = [ -// ['{LastName}'], -// ['{FirstName}'], -// ['{MiddleName}'], -// { -// company: ['{Categories}'], -// personal: ['{Company}'] -// } -// ]; -var globalCollectionSort=[ - ['{LastName}'], - ['{FirstName}'], - ['{MiddleName}'] -]; - - -// globalContactDataMinVisiblePercentage -// This option defines how the width for columns are computed. If you set -// it to 1 then 100% of all data in the column will be visible (the column -// width is determined by the longest string in the column). If you set it -// to 0.95 then 95% of data will fit into the column width, and the remaining -// 5% will be truncated (" ..."). -// Example: -var globalContactDataMinVisiblePercentage=0.95; - - diff --git a/virtual/packages/mantisbt-patches/bug_report.php.diff b/virtual/packages/mantisbt-patches/bug_report.php.diff deleted file mode 100644 index a520043..0000000 --- a/virtual/packages/mantisbt-patches/bug_report.php.diff +++ /dev/null @@ -1,20 +0,0 @@ ---- a/bug_report.php 2018-02-10 21:29:27.000000000 +0100 -+++ b/bug_report.php 2018-03-03 15:04:19.622499678 +0100 -@@ -149,6 +149,17 @@ - access_ensure_project_level( config_get( 'update_bug_assign_threshold' ) ); - } - -+# begin captcha check for anon user -+if ( current_user_is_anonymous() && get_gd_version() > 0 ) { -+ $f_captcha = gpc_get_string( 'captcha', '' ); -+ $f_captcha = utf8_strtolower( trim( $f_captcha ) ); -+ -+ $t_securimage = new Securimage(); -+ if( $t_securimage->check( $f_captcha ) == false ) { -+ trigger_error( ERROR_SIGNUP_NOT_MATCHING_CAPTCHA, ERROR ); -+ } -+} -+ - # if a profile was selected then let's use that information - if( 0 != $t_bug_data->profile_id ) { - if( profile_is_global( $t_bug_data->profile_id ) ) { diff --git a/virtual/packages/mantisbt-patches/bug_report_page.php.diff b/virtual/packages/mantisbt-patches/bug_report_page.php.diff deleted file mode 100644 index 80dea91..0000000 --- a/virtual/packages/mantisbt-patches/bug_report_page.php.diff +++ /dev/null @@ -1,53 +0,0 @@ ---- a/bug_report_page.php 2018-02-10 21:29:27.000000000 +0100 -+++ b/bug_report_page.php 2018-03-03 15:04:19.622499678 +0100 -@@ -708,7 +708,50 @@ - - - - -+ 0 ) { -+ $t_securimage_path = 'vendor/dapphp/securimage'; -+ $t_securimage_show = $t_securimage_path . '/securimage_show.php'; -+ $t_securimage_play = $t_securimage_path . '/securimage_play.swf?' -+ . http_build_query( array( -+ 'audio_file' => $t_securimage_path . '/securimage_play.php', -+ 'bgColor1=' => '#fff', -+ 'bgColor2=' => '#fff', -+ 'iconColor=' => '#777', -+ 'borderWidth=' => 1, -+ 'borderColor=' => '#000', -+ ) ); -+?> -+ -+ CAPTCHA -+ -+ -+ -+ -+ -+ -+ -+ visual captcha -+
-+
-+ -+ -+ -+ -+
-+ -+ -+ -+ - - - diff --git a/virtual/packages/mantisbt-patches/bugnote_add.php.diff b/virtual/packages/mantisbt-patches/bugnote_add.php.diff deleted file mode 100644 index 4509f0a..0000000 --- a/virtual/packages/mantisbt-patches/bugnote_add.php.diff +++ /dev/null @@ -1,20 +0,0 @@ ---- a/bugnote_add.php 2018-02-10 21:29:27.000000000 +0100 -+++ b/bugnote_add.php 2018-03-03 15:13:12.439919511 +0100 -@@ -44,6 +44,17 @@ - - $t_query = array( 'issue_id' => $f_bug_id ); - -+# begin captcha check for anon user -+if ( current_user_is_anonymous() && get_gd_version() > 0 ) { -+ $f_captcha = gpc_get_string( 'captcha', '' ); -+ $f_captcha = utf8_strtolower( trim( $f_captcha ) ); -+ -+ $t_securimage = new Securimage(); -+ if( $t_securimage->check( $f_captcha ) == false ) { -+ trigger_error( ERROR_SIGNUP_NOT_MATCHING_CAPTCHA, ERROR ); -+ } -+} -+ - if( count( $f_files ) > 0 && is_blank( $f_text ) && helper_duration_to_minutes( $f_duration ) == 0 ) { - $t_payload = array( - 'files' => helper_array_transpose( $f_files ) diff --git a/virtual/packages/mantisbt-patches/bugnote_add_inc.php.diff b/virtual/packages/mantisbt-patches/bugnote_add_inc.php.diff deleted file mode 100644 index a8589c7..0000000 --- a/virtual/packages/mantisbt-patches/bugnote_add_inc.php.diff +++ /dev/null @@ -1,52 +0,0 @@ ---- a/bugnote_add_inc.php 2018-02-10 21:29:27.000000000 +0100 -+++ b/bugnote_add_inc.php 2018-03-03 15:14:27.332428557 +0100 -@@ -119,6 +119,49 @@ - - - -+ 0 ) { -+ $t_securimage_path = 'vendor/dapphp/securimage'; -+ $t_securimage_show = $t_securimage_path . '/securimage_show.php'; -+ $t_securimage_play = $t_securimage_path . '/securimage_play.swf?' -+ . http_build_query( array( -+ 'audio_file' => $t_securimage_path . '/securimage_play.php', -+ 'bgColor1=' => '#fff', -+ 'bgColor2=' => '#fff', -+ 'iconColor=' => '#777', -+ 'borderWidth=' => 1, -+ 'borderColor=' => '#000', -+ ) ); -+?> -+ -+ CAPTCHA -+ -+ -+ -+ -+ -+ -+ -+ visual captcha -+
-+
-+ -+ -+ -+ -+
-+ -+ -+ -+ - - $t_changeset ) { -+ event_signal( 'EVENT_BUG_ACTION', array('RESOLVE', $t_bug_id) ); -+ } - } - - /** diff --git a/virtual/packages/mantisbt.nix b/virtual/packages/mantisbt.nix deleted file mode 100644 index 335cb7d..0000000 --- a/virtual/packages/mantisbt.nix +++ /dev/null @@ -1,124 +0,0 @@ -{ lib, checkEnv, writeText, stdenv, fetchurl, fetchedGithub }: -let - # FIXME: check that source-integration and slack still work - mantisbt = let - plugins = { - slack = stdenv.mkDerivation (fetchedGithub ./mantisbt-plugin-slack.json // rec { - installPhase = '' - sed -i -e "s/return '@' . \\\$username;/return \\\$username;/" Slack.php - cp -a . $out - ''; - }); - source-integration = stdenv.mkDerivation (fetchedGithub ./mantisbt-plugin-source-integration.json // rec { - installPhase = '' - mkdir $out - patch -p1 < ${./mantisbt-plugin-source-integration_Source.API.php.diff} - cp -a Source* $out/ - ''; - }); - }; - in rec { - config = - assert checkEnv "NIXOPS_MANTISBT_DB_PASSWORD"; - assert checkEnv "NIXOPS_MANTISBT_MASTER_SALT"; - assert checkEnv "NIXOPS_MANTISBT_LDAP_PASSWORD"; - writeText "config_inc.php" '' - - DirectoryIndex index.php - - SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" - - - AllowOverride All - Options FollowSymlinks - Require all granted - - - #Reenable during upgrade - Require all denied - - ''; - }; - phpFpm = rec { - basedir = builtins.concatStringsSep ":" ( - [ webRoot config ] - ++ lib.attrsets.mapAttrsToList (name: value: value) plugins); - socket = "/var/run/phpfpm/mantisbt.sock"; - pool = '' - listen = ${socket} - user = ${apache.user} - group = ${apache.group} - listen.owner = ${apache.user} - listen.group = ${apache.group} - pm = ondemand - pm.max_children = 60 - pm.process_idle_timeout = 60 - - php_admin_value[upload_max_filesize] = 5000000 - - php_admin_value[open_basedir] = "${basedir}:/tmp" - php_admin_value[session.save_path] = "/var/lib/php/sessions/mantisbt" - ''; - }; - }; -in - mantisbt diff --git a/virtual/packages/nextcloud-config/mimetypealiases.json b/virtual/packages/nextcloud-config/mimetypealiases.json deleted file mode 100644 index 3806e53..0000000 --- a/virtual/packages/nextcloud-config/mimetypealiases.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "application/gpx+xml": "gpx", - "x-application/kdbx": "kdbx" -} diff --git a/virtual/packages/nextcloud-config/mimetypemapping.json b/virtual/packages/nextcloud-config/mimetypemapping.json deleted file mode 100644 index 2db4691..0000000 --- a/virtual/packages/nextcloud-config/mimetypemapping.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "gpx": ["application/gpx+xml"], - "kdbx": ["x-application/kdbx"] -} diff --git a/virtual/packages/nextcloud.nix b/virtual/packages/nextcloud.nix deleted file mode 100644 index b8d8e59..0000000 --- a/virtual/packages/nextcloud.nix +++ /dev/null @@ -1,267 +0,0 @@ -{ stdenv, fetchurl, checkEnv, writeText, lib, phpPackages, php }: -let - nextcloud = let - # FIXME: initial sync - # FIXME: backup - buildApp = { appName, version, url, sha256, installPhase ? "mkdir -p $out && cp -R . $out/" }: - stdenv.mkDerivation rec { - name = "nextcloud-app-${appName}-${version}"; - inherit version; - phases = "unpackPhase installPhase"; - inherit installPhase; - src = fetchurl { inherit url sha256; }; - }; - apps = { - # FIXME: nextcloud complains that he cannot write into config - # directory when an app needs upgrade - # /!\ Attention, just changing the version number is not - # sufficient when the downloaded file doesn’t contain the version - # number in it, sha256 needs to be recomputed - audioplayer = buildApp rec { - appName = "audioplayer"; - version = "2.5.0"; - url = "https://github.com/Rello/${appName}/releases/download/${version}/${appName}-${version}.tar.gz"; - sha256 = "1pg4y51cv3agy28n4gfc8i7x1ya1yijxrmhpblm1n846vhmwdcm8"; - }; - bookmarks = buildApp rec { - appName = "bookmarks"; - version = "0.14.3"; - url = "https://github.com/nextcloud/${appName}/releases/download/v${version}/${appName}-${version}.tar.gz"; - sha256 = "0s7lkcl70izlkihnml1par0cac0wvckllyyga3jkb7k9vdg7d40c"; - }; - calendar = buildApp rec { - appName = "calendar"; - version = "1.6.4"; - url = "https://github.com/nextcloud/${appName}/releases/download/v${version}/${appName}.tar.gz"; - sha256 = "00dijvcvy7snsjslfbyzvpp9anhms22zp1f0zkj89ln33jmana63"; - }; - contacts = buildApp rec { - appName = "contacts"; - version = "3.0.0"; - url = "https://github.com/nextcloud/${appName}/releases/download/v${version}/${appName}.tar.gz"; - sha256 = "0fafy5kgzr5ldr3hxxxgmnw4y3qpjnv5ha1f1dlmqbc65s8frw7s"; - }; - deck = buildApp rec { - appName = "deck"; - version = "0.5.2"; - url = "https://github.com/nextcloud/${appName}/releases/download/v${version}/${appName}.tar.gz"; - sha256 = "1kygzixxdkp3dbma009p3pw0fj8wgcqcv39n7pay78lh6zi3nic7"; - }; - files_markdown = buildApp rec { - appName = "files_markdown"; - version = "2.0.5"; - url = "https://github.com/icewind1991/${appName}/releases/download/v${version}/${appName}.tar.gz"; - sha256 = "1dzvy4c6vff2qmkwqw13dx92xdkafaxgnipswjw44mh0ncc2n9ym"; - }; - gpxedit = buildApp rec { - appName = "gpxedit"; - version = "0.0.10"; - url = "https://gitlab.com/eneiluj/gpxedit-oc/wikis/uploads/33d187268c5f6f6a55350d656305701c/${appName}-${version}.tar.gz"; - sha256 = "0ynpaxm0xhvcj8xax6rm1w0p6j57wbqidhi7bhn268n483gwl2sw"; - }; - gpxpod = buildApp rec { - appName = "gpxpod"; - version = "3.0.0"; - url = "https://gitlab.com/eneiluj/gpxpod-oc/-/archive/v${version}/${appName}-oc-v${version}.tar.gz"; - sha256 = "0smpi4r3z7zfl1612fb30cwm1xmpiq95c81zzqiwzjf288iys74k"; - }; - keeweb = buildApp rec { - appName = "keeweb"; - version = "0.4.0"; - url = "https://github.com/jhass/nextcloud-keeweb/releases/download/v${version}/${appName}-${version}.tar.gz"; - sha256 = "0453kkb0a8vfivmibpwpx4bvhyn64jhns6cdfjacmnvbm6d75nj1"; - }; - notes = buildApp rec { - appName = "notes"; - version = "2.5.1"; - url = "https://github.com/nextcloud/${appName}/releases/download/v${version}/${appName}.tar.gz"; - sha256 = "1albzqqsdirzyw8vhvs7r0qm2wqp8vm9vmxm4crhncd85bk01hmh"; - }; - ocsms = buildApp rec { - appName = "ocsms"; - version = "2.1.0"; - url = "https://github.com/nextcloud/${appName}/releases/download/${version}/${appName}-${version}.tar.gz"; - sha256 = "19xgs82js4sdf6j9478vg9li7za7csvcaa1hbq9nmrq441sbxk9c"; - }; - spreed = buildApp rec { - appName = "spreed"; - version = "5.0.0"; - url = "https://github.com/nextcloud/${appName}/releases/download/v${version}/${appName}-${version}.tar.gz"; - sha256 = "1d48mak1fnf1b28r2687yqamm4pxfg3qyxcj9ny31a6xg2cm0xa7"; - }; - tasks = buildApp rec { - appName = "tasks"; - version = "0.9.8"; - url = "https://github.com/nextcloud/${appName}/releases/download/v${version}/${appName}.tar.gz"; - sha256 = "089m124lfsfk09fqj50x9n7zndq97jp5afgb8s001rpmzym4g6ny"; - }; - }; - in rec { - varDir = "/var/lib/nextcloud"; - config_php = - assert checkEnv "NIXOPS_NEXTCLOUD_PASSWORD_SALT"; - assert checkEnv "NIXOPS_NEXTCLOUD_DB_USER"; - assert checkEnv "NIXOPS_NEXTCLOUD_DB_PASSWORD"; - assert checkEnv "NIXOPS_NEXTCLOUD_INSTANCE_ID"; - assert checkEnv "NIXOPS_NEXTCLOUD_SECRET"; - assert checkEnv "NIXOPS_NEXTCLOUD_REDIS_DB_INDEX"; - writeText "config.php" '' - '${builtins.getEnv "NIXOPS_NEXTCLOUD_INSTANCE_ID"}', - 'datadirectory' => '/var/lib/nextcloud/', - 'passwordsalt' => '${builtins.getEnv "NIXOPS_NEXTCLOUD_PASSWORD_SALT"}', - 'debug' => false, - 'dbtype' => 'pgsql', - 'version' => '15.0.0.10', - 'dbname' => 'webapps', - 'dbhost' => '/run/postgresql', - 'dbtableprefix' => 'oc_', - 'dbuser' => '${builtins.getEnv "NIXOPS_NEXTCLOUD_DB_USER"}', - 'dbpassword' => '${builtins.getEnv "NIXOPS_NEXTCLOUD_DB_PASSWORD"}', - 'installed' => true, - 'maxZipInputSize' => 0, - 'allowZipDownload' => true, - 'forcessl' => true, - 'theme' => ${"''"}, - 'maintenance' => false, - 'trusted_domains' => - array ( - 0 => 'cloud.immae.eu', - ), - 'secret' => '${builtins.getEnv "NIXOPS_NEXTCLOUD_SECRET"}', - 'appstoreenabled' => false, - 'appstore.experimental.enabled' => true, - 'loglevel' => 0, - 'trashbin_retention_obligation' => 'auto', - 'htaccess.RewriteBase' => '/', - 'mail_smtpmode' => 'smtp', - 'mail_smtphost' => 'mail.immae.eu', - 'mail_smtpname' => ${"''"}, - 'mail_smtppassword' => ${"''"}, - 'mail_from_address' => 'owncloud', - 'mail_smtpauth' => false, - 'mail_domain' => 'immae.eu', - 'memcache.local' => '\\OC\\Memcache\\APCu', - 'memcache.locking' => '\\OC\\Memcache\\Redis', - 'filelocking.enabled' => true, - 'redis' => - array ( - 'host' => 'localhost', - 'port' => 6379, - 'dbindex' => ${builtins.getEnv "NIXOPS_NEXTCLOUD_REDIS_DB_INDEX"}, - ), - 'overwrite.cli.url' => 'https://cloud.immae.eu', - 'ldapIgnoreNamingRules' => false, - 'ldapProviderFactory' => '\\OCA\\User_LDAP\\LDAPProviderFactory', - 'config_is_read_only' => true, - ); - ''; - config = stdenv.mkDerivation rec { - name = "nextcloud-config"; - src = ./nextcloud-config; - phases = "installPhase"; - installPhase = '' - mkdir -p $out - cp -r $src/* $out - cp ${config_php} $out/config.php - ''; - }; - webRoot = stdenv.mkDerivation rec { - name = "nextcloud-${version}"; - version = "15.0.0"; - - src = fetchurl { - url = "https://download.nextcloud.com/server/releases/${name}.tar.bz2"; - sha256 = "0y7bk1588n5rmmranmmrkajh50074460hr4v052ahg9mf60wbc2v"; - }; - - installPhase = '' - mkdir -p $out/ - cp -R . $out/ - rm -r $out/config - ln -sf ${config} $out/config - ${builtins.concatStringsSep "\n" ( - lib.attrsets.mapAttrsToList (name: value: "ln -sf ${value} $out/apps/${name}") apps - )} - ''; - - meta = { - description = "Sharing solution for files, calendars, contacts and more"; - homepage = https://nextcloud.com; - maintainers = with lib.maintainers; [ schneefux bachp globin fpletz ]; - license = lib.licenses.agpl3Plus; - platforms = with lib.platforms; unix; - }; - }; - activationScript = { - deps = [ ]; - text = '' - install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir} - install -m 0750 -o ${apache.user} -g ${apache.group} -d ${varDir}/phpSessions - ''; - }; - apache = { - user = "wwwrun"; - group = "wwwrun"; - modules = [ "proxy_fcgi" ]; - vhostConf = '' - SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 - - AcceptPathInfo On - DirectoryIndex index.php - Options FollowSymlinks - Require all granted - AllowOverride all - - - Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains; preload" - - - CGIPassAuth on - SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" - - - - - ''; - }; - phpFpm = rec { - basedir = builtins.concatStringsSep ":" ( - [ webRoot varDir config ] - ++ lib.attrsets.mapAttrsToList (name: value: value) apps); - socket = "/var/run/phpfpm/nextcloud.sock"; - phpConfig = '' - extension=${phpPackages.redis}/lib/php/extensions/redis.so - extension=${phpPackages.apcu}/lib/php/extensions/apcu.so - zend_extension=${php}/lib/php/extensions/opcache.so - ''; - pool = '' - listen = ${socket} - user = ${apache.user} - group = ${apache.group} - listen.owner = ${apache.user} - listen.group = ${apache.group} - pm = ondemand - pm.max_children = 60 - pm.process_idle_timeout = 60 - - php_admin_value[output_buffering] = 0 - php_admin_value[max_execution_time] = 1800 - php_admin_value[zend_extension] = "opcache" - php_value[opcache.enable] = 1 - php_value[opcache.enable_cli] = 1 - php_value[opcache.interned_strings_buffer] = 8 - php_value[opcache.max_accelerated_files] = 10000 - php_value[opcache.memory_consumption] = 128 - php_value[opcache.save_comments] = 1 - php_value[opcache.revalidate_freq] = 1 - php_admin_value[memory_limit] = 512M - - php_admin_value[open_basedir] = "${basedir}:/proc/meminfo:/dev/urandom:/proc/self/fd:/tmp" - php_admin_value[session.save_path] = "${varDir}/phpSessions" - ''; - }; - }; -in - nextcloud diff --git a/virtual/packages/roundcubemail.nix b/virtual/packages/roundcubemail.nix deleted file mode 100644 index 1aa2d87..0000000 --- a/virtual/packages/roundcubemail.nix +++ /dev/null @@ -1,110 +0,0 @@ -{ lib, checkEnv, writeText, stdenv, fetchurl }: -let - roundcubemail = let - plugins = {}; - in rec { - varDir = "/var/lib/roundcubemail"; - # FIXME: initial sync - activationScript = { - deps = [ "wrappers" ]; - text = '' - install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir} \ - ${varDir}/cache - install -m 0750 -o ${apache.user} -g ${apache.group} -d ${varDir}/phpSessions - ''; - }; - config = - # FIXME: LOG_DESTINATION syslog? - assert checkEnv "NIXOPS_ROUNDCUBEMAIL_PSQL_URL"; - assert checkEnv "NIXOPS_ROUNDCUBEMAIL_SECRET"; - writeText "config.php" '' - array("verify_peer" => false)); - $config['smtp_server'] = 'tls://mail.immae.eu'; - - $config['imap_cache'] = 'db'; - $config['messages_cache'] = 'db'; - - $config['support_url'] = '''; - - $config['des_key'] = '${builtins.getEnv "NIXOPS_ROUNDCUBEMAIL_SECRET"}'; - - $config['plugins'] = array(); - - $config['language'] = 'fr_FR'; - - $config['drafts_mbox'] = 'Mail/Drafts'; - $config['junk_mbox'] = 'Mail/Spam'; - $config['sent_mbox'] = 'Mail/sent'; - $config['trash_mbox'] = '''; - $config['default_folders'] = array('INBOX', 'Mail/Drafts', 'Mail/sent', 'Mail/Spam', '''); - $config['draft_autosave'] = 60; - $config['enable_installer'] = false; - $config['log_driver'] = 'stdout'; - $config['temp_dir'] = '${varDir}/cache'; - $config['debug_level'] = 1; - ''; - webRoot = stdenv.mkDerivation rec { - version = "1.3.8"; - name = "roundcubemail-${version}"; - src= fetchurl { - url = "https://github.com/roundcube/roundcubemail/releases/download/${version}/${name}-complete.tar.gz"; - sha256 = "018djad7ygfl9c9f2l2j42qkg31ml3hs2f01f0dk361zckwk77n4"; - }; - buildPhase = '' - sed -i \ - -e "s|RCUBE_INSTALL_PATH . 'temp.*|'${varDir}/cache';|" \ - config/defaults.inc.php - ''; - installPhase = '' - cp -a . $out - ln -s ${config} $out/config/config.inc.php - ${builtins.concatStringsSep "\n" ( - lib.attrsets.mapAttrsToList (name: value: "ln -sf ${value} $out/plugins/${name}") plugins - )} - ''; - }; - apache = { - user = "wwwrun"; - group = "wwwrun"; - modules = [ "proxy_fcgi" ]; - vhostConf = '' - Alias /roundcube "${webRoot}" - - DirectoryIndex index.php - AllowOverride All - Options FollowSymlinks - Require all granted - - - SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" - - - ''; - }; - phpFpm = rec { - basedir = builtins.concatStringsSep ":" ( - [ webRoot config varDir ] - ++ lib.attrsets.mapAttrsToList (name: value: value) plugins); - socket = "/var/run/phpfpm/roundcubemail.sock"; - pool = '' - listen = ${socket} - user = ${apache.user} - group = ${apache.group} - listen.owner = ${apache.user} - listen.group = ${apache.group} - pm = ondemand - pm.max_children = 60 - pm.process_idle_timeout = 60 - - ; Needed to avoid clashes in browser cookies (same domain) - php_value[session.name] = RoundcubemailPHPSESSID - php_admin_value[open_basedir] = "${basedir}:/tmp" - php_admin_value[session.save_path] = "${varDir}/phpSessions" - ''; - }; - }; -in - roundcubemail diff --git a/virtual/packages/test_goaccess.conf b/virtual/packages/test_goaccess.conf deleted file mode 100644 index d4f243a..0000000 --- a/virtual/packages/test_goaccess.conf +++ /dev/null @@ -1,99 +0,0 @@ -time-format %H:%M:%S -date-format %d/%b/%Y - -#sur immae.eu -#log-format %v %h %^[%d:%t %^] "%r" %s %b "%R" "%u" $^ - -log-format VCOMBINED -#= %v:%^ %h %^[%d:%t %^] "%r" %s %b "%R" "%u" - -html-prefs {"theme":"bright","layout":"vertical"} - -exclude-ip 188.165.209.148 -exclude-ip 178.33.252.96 -exclude-ip 2001:41d0:2:9c94::1 -exclude-ip 2001:41d0:2:9c94:: -exclude-ip 176.9.151.89 -exclude-ip 2a01:4f8:160:3445:: -exclude-ip 82.255.56.72 - -no-query-string true - -keep-db-files true -load-from-disk true -db-path /var/lib/goaccess/cloud.immae.eu - -ignore-panel REFERRERS -ignore-panel KEYPHRASES - -static-file .css -static-file .js -static-file .jpg -static-file .png -static-file .gif -static-file .ico -static-file .jpeg -static-file .pdf -static-file .csv -static-file .mpeg -static-file .mpg -static-file .swf -static-file .woff -static-file .woff2 -static-file .xls -static-file .xlsx -static-file .doc -static-file .docx -static-file .ppt -static-file .pptx -static-file .txt -static-file .zip -static-file .ogg -static-file .mp3 -static-file .mp4 -static-file .exe -static-file .iso -static-file .gz -static-file .rar -static-file .svg -static-file .bmp -static-file .tar -static-file .tgz -static-file .tiff -static-file .tif -static-file .ttf -static-file .flv -#static-file .less -#static-file .ac3 -#static-file .avi -#static-file .bz2 -#static-file .class -#static-file .cue -#static-file .dae -#static-file .dat -#static-file .dts -#static-file .ejs -#static-file .eot -#static-file .eps -#static-file .img -#static-file .jar -#static-file .map -#static-file .mid -#static-file .midi -#static-file .ogv -#static-file .webm -#static-file .mkv -#static-file .odp -#static-file .ods -#static-file .odt -#static-file .otf -#static-file .pict -#static-file .pls -#static-file .ps -#static-file .qt -#static-file .rm -#static-file .svgz -#static-file .wav -#static-file .webp - - diff --git a/virtual/packages/tt-rss.json b/virtual/packages/tt-rss.json deleted file mode 100644 index e2731b0..0000000 --- a/virtual/packages/tt-rss.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "tag": "986ca25-master", - "meta": { - "name": "tt-rss", - "url": "https://git.tt-rss.org/fox/tt-rss.git", - "branch": "master" - }, - "git": { - "url": "https://git.tt-rss.org/fox/tt-rss.git", - "rev": "986ca251f995f7754a0470d3e0c44538a545081f", - "sha256": "0xkafkh7l9zazm5d6snlq03kdfxfhkb4c8fdsb32wn8b9bhdzf5s", - "fetchSubmodules": true - } -} diff --git a/virtual/packages/ttrss-af-feedmod_type_replace.patch b/virtual/packages/ttrss-af-feedmod_type_replace.patch deleted file mode 100644 index d622577..0000000 --- a/virtual/packages/ttrss-af-feedmod_type_replace.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/init.php 2014-06-16 14:21:06.995480038 +0200 -+++ b/init.php 2014-06-16 14:22:00.151027654 +0200 -@@ -147,6 +147,9 @@ - } - } - break; -+ case 'replace': -+ $article['content'] = preg_replace("/".$config['pattern']."/",$config['replacement'],$article['content']); -+ break; - - default: - // unknown type or invalid config diff --git a/virtual/packages/ttrss-af_feedmod.json b/virtual/packages/ttrss-af_feedmod.json deleted file mode 100644 index e57fcce..0000000 --- a/virtual/packages/ttrss-af_feedmod.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "tag": "0ea2092-master", - "meta": { - "name": "ttrss-af_feedmod", - "url": "https://github.com/mbirth/ttrss_plugin-af_feedmod", - "branch": "master" - }, - "github": { - "owner": "mbirth", - "repo": "ttrss_plugin-af_feedmod", - "rev": "0ea2092dd34067ecd898802cfca3570023d1ecfe", - "sha256": "02ibf47zcrsc2rr45wsix8gxyyf371davj8n8i0gj1zdq95klvnv", - "fetchSubmodules": true - } -} diff --git a/virtual/packages/ttrss-auth-ldap.json b/virtual/packages/ttrss-auth-ldap.json deleted file mode 100644 index c8aaab5..0000000 --- a/virtual/packages/ttrss-auth-ldap.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "tag": "4d751b0-master", - "meta": { - "name": "ttrss-auth-ldap", - "url": "https://github.com/hydrian/TTRSS-Auth-LDAP", - "branch": "master" - }, - "github": { - "owner": "hydrian", - "repo": "TTRSS-Auth-LDAP", - "rev": "4d751b095c29a8dbe2dc7bb07777742956136e94", - "sha256": "0b9fl86acrzpcv41r7pj3bl8b3n72hpkdywzx9zjyfqv5pskxyim", - "fetchSubmodules": true - } -} diff --git a/virtual/packages/ttrss-feediron.json b/virtual/packages/ttrss-feediron.json deleted file mode 100644 index 5dbec92..0000000 --- a/virtual/packages/ttrss-feediron.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "tag": "407168c-master", - "meta": { - "name": "ttrss-feediron", - "url": "https://github.com/m42e/ttrss_plugin-feediron", - "branch": "master" - }, - "github": { - "owner": "m42e", - "repo": "ttrss_plugin-feediron", - "rev": "407168c628880b5ced572cc549db6d50e866d3c8", - "sha256": "17b95ifpcph6m03hjd1mhi8gi1hw9yd3fnffmw66fqr5c9l3zd9r", - "fetchSubmodules": true - } -} diff --git a/virtual/packages/ttrss-feediron_json_reformat.patch b/virtual/packages/ttrss-feediron_json_reformat.patch deleted file mode 100644 index e1c44d9..0000000 --- a/virtual/packages/ttrss-feediron_json_reformat.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff --git a/init.php b/init.php -index 3c0f2f9..1aad146 100644 ---- a/init.php -+++ b/init.php -@@ -600,10 +600,11 @@ class Feediron extends Plugin implements IHandler - return false; - } - -- $this->host->set($this, 'json_conf', Feediron_Json::format($json_conf)); -+ $new_conf = json_encode(json_decode($json_conf), JSON_PRETTY_PRINT); -+ $this->host->set($this, 'json_conf', $new_conf); - $json_reply['success'] = true; - $json_reply['message'] = __('Configuration saved.'); -- $json_reply['json_conf'] = Feediron_Json::format($json_conf); -+ $json_reply['json_conf'] = $new_conf; - echo json_encode($json_reply); - } - diff --git a/virtual/packages/ttrss-ff_instagram.json b/virtual/packages/ttrss-ff_instagram.json deleted file mode 100644 index 1f241b9..0000000 --- a/virtual/packages/ttrss-ff_instagram.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "tag": "0366ffb-master", - "meta": { - "name": "ttrss-ff_instagram", - "url": "https://github.com/wltb/ff_instagram", - "branch": "master" - }, - "github": { - "owner": "wltb", - "repo": "ff_instagram", - "rev": "0366ffb18c4d490c8fbfba2f5f3367a5af23cfe8", - "sha256": "0vvzl6wi6jmrqknsfddvckjgsgfizz1d923d1nyrpzjfn6bda1vk", - "fetchSubmodules": true - } -} diff --git a/virtual/packages/ttrss-tumblr_gdpr_ua.json b/virtual/packages/ttrss-tumblr_gdpr_ua.json deleted file mode 100644 index eafbcfe..0000000 --- a/virtual/packages/ttrss-tumblr_gdpr_ua.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "tag": "287c584-master", - "meta": { - "name": "ttrss-tumblr_gdpr_ua", - "url": "https://github.com/hkockerbeck/ttrss-tumblr-gdpr-ua", - "branch": "master" - }, - "github": { - "owner": "hkockerbeck", - "repo": "ttrss-tumblr-gdpr-ua", - "rev": "287c584e68845d524f920156bff0b2eaa6f65117", - "sha256": "1fviawgcclqky4k4xv1sqzvpb8i74w9f0pclm09m78s8l85wh9py", - "fetchSubmodules": true - } -} diff --git a/virtual/packages/ttrss.nix b/virtual/packages/ttrss.nix deleted file mode 100644 index f7b0f61..0000000 --- a/virtual/packages/ttrss.nix +++ /dev/null @@ -1,182 +0,0 @@ -{ lib, php, checkEnv, writeText, stdenv, fetchedGit, fetchedGithub }: -let - ttrss = let - plugins = { - auth_ldap = stdenv.mkDerivation (fetchedGithub ./ttrss-auth-ldap.json // rec { - installPhase = '' - mkdir $out - cp plugins/auth_ldap/init.php $out - ''; - }); - af_feedmod = stdenv.mkDerivation (fetchedGithub ./ttrss-af_feedmod.json // rec { - patches = [ ./ttrss-af-feedmod_type_replace.patch ]; - installPhase = '' - mkdir $out - cp init.php $out - ''; - }); - feediron = stdenv.mkDerivation (fetchedGithub ./ttrss-feediron.json // rec { - patches = [ ./ttrss-feediron_json_reformat.patch ]; - installPhase = '' - mkdir $out - cp -a . $out - ''; - }); - ff_instagram = stdenv.mkDerivation (fetchedGithub ./ttrss-ff_instagram.json // rec { - installPhase = '' - mkdir $out - cp -a . $out - ''; - }); - tumblr_gdpr_ua = stdenv.mkDerivation (fetchedGithub ./ttrss-tumblr_gdpr_ua.json // rec { - installPhase = '' - mkdir $out - cp -a . $out - ''; - }); - }; - in rec { - varDir = "/var/lib/ttrss"; - # FIXME: initial sync - activationScript = { - deps = [ "wrappers" ]; - text = '' - install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir} \ - ${varDir}/lock ${varDir}/cache ${varDir}/feed-icons - install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir}/cache/export/ \ - ${varDir}/cache/feeds/ \ - ${varDir}/cache/images/ \ - ${varDir}/cache/js/ \ - ${varDir}/cache/simplepie/ \ - ${varDir}/cache/upload/ - touch ${varDir}/feed-icons/index.html - install -m 0750 -o ${apache.user} -g ${apache.group} -d ${varDir}/phpSessions - ''; - }; - config = - # FIXME: LOG_DESTINATION syslog? - assert checkEnv "NIXOPS_TTRSS_DB_PASSWORD"; - assert checkEnv "NIXOPS_TTRSS_LDAP_PASSWORD"; - writeText "config.php" '' - - DirectoryIndex index.php - - SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" - - - AllowOverride All - Options FollowSymlinks - Require all granted - - ''; - }; - phpFpm = rec { - basedir = builtins.concatStringsSep ":" ( - [ webRoot config varDir ] - ++ lib.attrsets.mapAttrsToList (name: value: value) plugins); - socket = "/var/run/phpfpm/ttrss.sock"; - pool = '' - listen = ${socket} - user = ${apache.user} - group = ${apache.group} - listen.owner = ${apache.user} - listen.group = ${apache.group} - pm = ondemand - pm.max_children = 60 - pm.process_idle_timeout = 60 - - ; Needed to avoid clashes in browser cookies (same domain) - php_value[session.name] = TtrssPHPSESSID - php_admin_value[open_basedir] = "${basedir}:/tmp" - php_admin_value[session.save_path] = "${varDir}/phpSessions" - ''; - }; - }; -in - ttrss diff --git a/virtual/packages/ympd.nix b/virtual/packages/ympd.nix deleted file mode 100644 index 74bf2e5..0000000 --- a/virtual/packages/ympd.nix +++ /dev/null @@ -1,35 +0,0 @@ -{}: -let - ympd = rec { - config = { - webPort = "localhost:18001"; - mpd = { - host = "malige.home.immae.eu"; - port = 6600; - }; - }; - apache = { - modules = [ - "proxy_wstunnel" - ]; - vhostConf = '' - - Use LDAPConnect - Require ldap-group cn=users,cn=mpd,ou=services,dc=immae,dc=eu - Require local - - - RedirectMatch permanent "^/mpd$" "/mpd/" - - ProxyPass http://${config.webPort}/ - ProxyPassReverse http://${config.webPort}/ - ProxyPreserveHost on - - - ProxyPass ws://${config.webPort}/ws - - ''; - }; - }; -in - ympd -- cgit v1.2.3