From 076087fc369fa6ef51220525649fbd972a9babda Mon Sep 17 00:00:00 2001 From: Gaelan Steele Date: Sun, 9 Jul 2023 13:51:39 -0700 Subject: [PATCH] Init, with Mastodon and Akkoma support. --- .gitignore | 2 + .is-minifedi | 0 flake.lock | 25 + flake.nix | 80 + nix/fedi/akkoma/default.nix | 214 ++ nix/fedi/mastodon/build.nix | 168 + nix/fedi/mastodon/default.nix | 277 ++ nix/fedi/mastodon/gemset.nix | 3190 +++++++++++++++++ nix/fedi/mastodon/source.nix | 11 + nix/fedi/mastodon/version.nix | 1 + nix/s6.nix | 10 + nix/services.nix | 20 + nix/support-services/nginx/default.nix | 49 + nix/support-services/postgres/default.nix | 29 + nix/support-services/postgres/postgresql.conf | 2 + nix/support-services/redis/default.nix | 19 + nix/util.nix | 0 17 files changed, 4097 insertions(+) create mode 100644 .gitignore create mode 100644 .is-minifedi create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 nix/fedi/akkoma/default.nix create mode 100644 nix/fedi/mastodon/build.nix create mode 100644 nix/fedi/mastodon/default.nix create mode 100644 nix/fedi/mastodon/gemset.nix create mode 100644 nix/fedi/mastodon/source.nix create mode 100644 nix/fedi/mastodon/version.nix create mode 100644 nix/s6.nix create mode 100644 nix/services.nix create mode 100644 nix/support-services/nginx/default.nix create mode 100644 nix/support-services/postgres/default.nix create mode 100644 nix/support-services/postgres/postgresql.conf create mode 100644 nix/support-services/redis/default.nix create mode 100644 nix/util.nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b899b09 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +data +cert \ No newline at end of file diff --git a/.is-minifedi b/.is-minifedi new file mode 100644 index 0000000..e69de29 diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..777504d --- /dev/null +++ b/flake.lock @@ -0,0 +1,25 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1688221086, + "narHash": "sha256-cdW6qUL71cNWhHCpMPOJjlw0wzSRP0pVlRn2vqX/VVg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "cd99c2b3c9f160cd004318e0697f90bbd5960825", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..9a43118 --- /dev/null +++ b/flake.nix @@ -0,0 +1,80 @@ +{ + outputs = { self, nixpkgs }: { + # nixosModules.base = {pkgs, ...}: { + # system.stateVersion = "22.05"; + + # # Configure networking + # networking.useDHCP = false; + # networking.interfaces.eth0.useDHCP = true; + + # # Create user "test" + # services.getty.autologinUser = "test"; + # users.users.test.isNormalUser = true; + + # # Enable passwordless ‘sudo’ for the "test" user + # users.users.test.extraGroups = ["wheel"]; + # security.sudo.wheelNeedsPassword = false; + # }; + # nixosModules.vm = {...}: { + # # Make VM output to the terminal instead of a separate window + # virtualisation.vmVariant.virtualisation.graphics = false; + # }; + # nixosConfigurations.darwinVM = nixpkgs.lib.nixosSystem { + # system = "x86_64-linux"; + # modules = [ + # (builtins.trace (builtins.attrNames self) self.nixosModules.base) + # self.nixosModules.vm + # { + # virtualisation.vmVariant.virtualisation.host.pkgs = nixpkgs.legacyPackages.x86_64-darwin; + # } + # ]; + # }; + # packages.x86_64-darwin.darwinVM = self.nixosConfigurations.darwinVM.config.system.build.vm; + apps.x86_64-darwin.default = let + pkgs = nixpkgs.legacyPackages.x86_64-darwin; + s6 = (import ./nix/s6.nix { + inherit pkgs; + services = pkgs.lib.attrsets.mapAttrs (_: v: v.service) + (import ./nix/services.nix { inherit pkgs; }); + path = "service"; + }); + in { + type = "app"; + program = let + script = pkgs.writeShellScript "minifedi" '' + export PATH=${pkgs.gnugrep}/bin:${pkgs.gnused}/bin:${pkgs.coreutils}/bin + + if ! [[ -e .is-minifedi ]]; then + echo "please run this from the minifedi directory" + exit 1 + fi + mkdir -p data + mkdir -p cert + rm -rf data/run + mkdir data/run + export MINIFEDI_CERT=$(pwd)/cert + export MINIFEDI_DATA=$(pwd)/data + export MINIFEDI_RUN=$(pwd)/data/run + exec ${s6.start} + ''; + in "${script}"; + }; + apps.x86_64-darwin.install-cert = + let pkgs = nixpkgs.legacyPackages.x86_64-darwin; + in { + type = "app"; + program = let + script = pkgs.writeShellScript "minifedi-install-cert" '' + if ! [[ -e .is-minifedi ]]; then + echo "please run this from the minifedi directory" + exit 1 + fi + + mkdir -p cert + + CAROOT=$MINIFEDI_CERT ${pkgs.mkcert}/bin/mkcert -install + ''; + in "${script}"; + }; + }; +} diff --git a/nix/fedi/akkoma/default.nix b/nix/fedi/akkoma/default.nix new file mode 100644 index 0000000..974d815 --- /dev/null +++ b/nix/fedi/akkoma/default.nix @@ -0,0 +1,214 @@ +{ pkgs, name, }: +let + env = { + MIX_ENV = "prod"; + ERL_EPMD_ADDRESS = "127.0.0.1"; + }; + + static = pkgs.linkFarm "static" { + frontends = pkgs.linkFarm "frontends" { + akkoma = + pkgs.linkFarm "pleroma" { stable = pkgs.akkoma-frontends.akkoma-fe; }; + # admin = + # pkgs.linkFarm "admin" { stable = pkgs.akkoma-frontends.admin-fe; }; + }; + }; + + config = pkgs.writeText "config.exs" '' + import Config + + config :pleroma, Pleroma.Web.Endpoint, + url: [host: "${name}.lvh.me", scheme: "https", port: 443], + http: [ip: {:local, "$MINIFEDI_RUN/${name}/akkoma.sock"}, port: 0], + secret_key_base: "$SECRET_KEY_BASE", + live_view: [signing_salt: "$LIVE_VIEW_SIGNING_SALT"], + signing_salt: "$SIGNING_SALT" + + config :pleroma, :instance, + name: "${name}", + email: "a@${name}.example", + notify_email: "noreply@${name}.example", + limit: 5000, + registrations_open: true + + config :pleroma, :media_proxy, + enabled: false, + redirect_on_failure: true + #base_url: "https://cache.pleroma.social" + + config :pleroma, Pleroma.Repo, + adapter: Ecto.Adapters.Postgres, + username: "${name}", + password: "", + database: "${name}", + socket_dir: "$MINIFEDI_RUN/postgres/" + + # Configure web push notifications + config :web_push_encryption, :vapid_details, + subject: "mailto:a@${name}.example", + public_key: "$WEB_PUSH_PUBLIC_KEY", + private_key: "$WEB_PUSH_PRIVATE_KEY" + + config :pleroma, :database, rum_enabled: false + config :pleroma, :instance, static_dir: "${static}" + config :pleroma, Pleroma.Uploaders.Local, uploads: "$MINIFEDI_DATA/${name}/uploads" + + config :joken, default_signer: "$JWT_SECRET" + + config :pleroma, configurable_from_database: false + + config :tzdata, :data_dir, "$MINIFEDI_DATA/${name}/tzdata" + + config :pleroma, :frontends, + primary: %{ + "name" => "akkoma", + "ref" => "stable" + } + + config :pleroma, :http, adapter: [pools: %{default: [conn_opts: [transport_opts: [cacertfile: "$MINIFEDI_CERT/rootCA.pem"]]]}] + ''; + # admin: %{ + # "name" => "admin", + # "ref" => "stable" + # } + + path = pkgs.lib.strings.concatStrings (builtins.map (x: "${x}/bin:") [ + pkgs.akkoma + pkgs.elixir + pkgs.s6 + pkgs.postgresql + # used by pleroma shell script for rpc + pkgs.gawk + # envsubst + pkgs.gettext + # used to generate keys + pkgs.openssl + ]); +in { + service = pkgs.linkFarm name [{ + name = "run"; + path = pkgs.writeShellScript "run-${name}" '' + set -e + + export PATH=${path}$PATH + + cd ${pkgs.akkoma} + + data=$MINIFEDI_DATA/${name} + run=$MINIFEDI_RUN/${name} + postgres=$MINIFEDI_RUN/postgres + + mkdir -p $data + mkdir -p $data/uploads + mkdir -p $data/tzdata + mkdir -p $run + + s6-svwait -U $MINIFEDI_RUN/service/postgres + + ${pkgs.lib.strings.concatStrings (pkgs.lib.attrsets.mapAttrsToList + (k: v: '' + export ${k}=${v} + '') env)} + + if ! [ -e $data/setup-done ]; then + openssl rand -base64 64 | head -c 64 > $data/secret_key_base + openssl rand -base64 64 | head -c 64 > $data/jwt_secret + openssl rand -base64 8 | head -c 8 > $data/signing_salt + openssl rand -base64 8 | head -c 8 > $data/live_view_signing_salt + openssl ecparam -genkey -name prime256v1 | openssl ec -out $data/web_push_keypair.pem + openssl ec -in $data/web_push_keypair.pem -pubout -out $data/web_push_public_key + openssl ec -in $data/web_push_keypair.pem -out $data/web_push_private_key + fi + + export SECRET_KEY_BASE=$(cat $data/secret_key_base) + export JWT_SECRET=$(cat $data/jwt_secret) + export SIGNING_SALT=$(cat $data/jwt_secret) + export LIVE_VIEW_SIGNING_SALT=$(cat $data/live_view_signing_salt) + export WEB_PUSH_PRIVATE_KEY=$(cat $data/web_push_private_key) + export WEB_PUSH_PUBLIC_KEY=$(cat $data/web_push_public_key) + + export RELEASE_COOKIE=$(openssl rand -base64 64) + + cat ${config} | envsubst > $data/config.exs + export AKKOMA_CONFIG_PATH=$data/config.exs + + if ! [ -e $data/setup-done ]; then + createuser -h$postgres ${name} + createdb -h$postgres ${name} -O${name} + + psql -h$postgres -d${name} -c 'CREATE EXTENSION IF NOT EXISTS citext;' + psql -h$postgres -d${name} -c 'CREATE EXTENSION IF NOT EXISTS pg_trgm;' + psql -h$postgres -d${name} -c 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp";' + + pleroma_ctl migrate + + export PLEROMA_CTL_RPC_DISABLED=true + pleroma_ctl user new a a@${name}.example --assume-yes --password Aa12345! --admin + pleroma_ctl user new b b@${name}.example --assume-yes --password Bb12345! + pleroma_ctl user new c c@${name}.example --assume-yes --password Cc12345! + pleroma_ctl user new d d@${name}.example --assume-yes --password Dd12345! + pleroma_ctl user new e e@${name}.example --assume-yes --password Ee12345! + + touch $data/setup-done + fi + + # elixir takes 2 sigints to exit if it has something on stdin + exec ': uninitialized constant Bundler::Settings (NameError) + postBuild = '' + for gem in "$out"/lib/ruby/gems/*/gems/*; do + cp -a "$gem/" "$gem.new" + rm "$gem" + # needed on macOS, otherwise the mv yields permission denied + chmod +w "$gem.new" + mv "$gem.new" "$gem" + done + ''; + }; + + mastodonModules = stdenv.mkDerivation { + pname = "${pname}-modules"; + inherit src version; + + yarnOfflineCache = fetchYarnDeps { + yarnLock = "${src}/yarn.lock"; + sha256 = "sha256-e3rl/WuKXaUdeDEYvo1sSubuIwtBjkbguCYdAijwXOA="; + }; + + nativeBuildInputs = [ + fixup_yarn_lock + nodejs-slim + yarn + mastodonGems + mastodonGems.wrappedRuby + brotli + ]; + + RAILS_ENV = "production"; + NODE_ENV = "production"; + + buildPhase = '' + runHook preBuild + + export HOME=$PWD + # This option is needed for openssl-3 compatibility + # Otherwise we encounter this upstream issue: https://github.com/mastodon/mastodon/issues/17924 + export NODE_OPTIONS=--openssl-legacy-provider + fixup_yarn_lock ~/yarn.lock + yarn config --offline set yarn-offline-mirror $yarnOfflineCache + yarn install --offline --frozen-lockfile --ignore-engines --ignore-scripts --no-progress + + patchShebangs ~/bin + patchShebangs ~/node_modules + + # skip running yarn install + rm -rf ~/bin/yarn + + OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder \ + rails assets:precompile + yarn cache clean --offline + rm -rf ~/node_modules/.cache + + # Create missing static gzip and brotli files + gzip --best --keep ~/public/assets/500.html + gzip --best --keep ~/public/packs/report.html + find ~/public/assets -maxdepth 1 -type f -name '.*.json' \ + -exec gzip --best --keep --force {} ';' + brotli --best --keep ~/public/packs/report.html + find ~/public/assets -type f -regextype posix-extended -iregex '.*\.(css|js|json|html)' \ + -exec brotli --best --keep {} ';' + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out/public + cp -r node_modules $out/node_modules + cp -r public/assets $out/public + cp -r public/packs $out/public + + runHook postInstall + ''; + }; + + propagatedBuildInputs = [ imagemagick ffmpeg file mastodonGems.wrappedRuby ]; + buildInputs = [ mastodonGems nodejs-slim ]; + + buildPhase = '' + runHook preBuild + + ln -s $mastodonModules/node_modules node_modules + ln -s $mastodonModules/public/assets public/assets + ln -s $mastodonModules/public/packs public/packs + + patchShebangs bin/ + for b in $(ls $mastodonGems/bin/) + do + if [ ! -f bin/$b ]; then + ln -s $mastodonGems/bin/$b bin/$b + fi + done + + # Remove execute permissions + chmod 0444 public/emoji/*.svg + + # Create missing static gzip and brotli files + find public -maxdepth 1 -type f -regextype posix-extended -iregex '.*\.(css|js|svg|txt|xml)' \ + -exec gzip --best --keep --force {} ';' \ + -exec brotli --best --keep {} ';' + find public/emoji -type f -name '.*.svg' \ + -exec gzip --best --keep --force {} ';' \ + -exec brotli --best --keep {} ';' + ln -s assets/500.html.gz public/500.html.gz + ln -s assets/500.html.br public/500.html.br + ln -s packs/sw.js.gz public/sw.js.gz + ln -s packs/sw.js.br public/sw.js.br + ln -s packs/sw.js.map.gz public/sw.js.map.gz + ln -s packs/sw.js.map.br public/sw.js.map.br + + rm -rf log + ln -s /var/log/mastodon log + ln -s /tmp tmp + + runHook postBuild + ''; + + installPhase = let + run-streaming = writeShellScript "run-streaming.sh" '' + # NixOS helper script to consistently use the same NodeJS version the package was built with. + ${nodejs-slim}/bin/node ./streaming + ''; + in '' + runHook preInstall + + mkdir -p $out + cp -r * $out/ + ln -s ${run-streaming} $out/run-streaming.sh + + runHook postInstall + ''; + + meta = with lib; { + description = + "Self-hosted, globally interconnected microblogging software based on ActivityPub"; + homepage = "https://joinmastodon.org"; + license = licenses.agpl3Plus; + }; +} diff --git a/nix/fedi/mastodon/default.nix b/nix/fedi/mastodon/default.nix new file mode 100644 index 0000000..91d4431 --- /dev/null +++ b/nix/fedi/mastodon/default.nix @@ -0,0 +1,277 @@ +{ pkgs, name }: +let + mastodon = pkgs.callPackage ./build.nix { }; + env = { + LOCAL_DOMAIN = "${name}.lvh.me"; + WEB_DOMAIN = "${name}.lvh.me"; + ALLOWED_PRIVATE_ADDRESSES = "127.0.0.1"; + RAILS_ENV = "production"; + NODE_ENV = "production"; + DB_USER = name; + DB_NAME = name; + REDIS_NAMESPACE = "${name}_"; + EMAIL_DOMAIN_ALLOWLIST = "${name}.example"; + SMTP_DELIVERY_METHOD = "file"; + }; + s6 = import ../../s6.nix { + inherit pkgs; + services = { + web = pkgs.linkFarm "web" { + run = pkgs.writeShellScript "run-web" '' + cd ${mastodon} + + export SOCKET=$MINIFEDI_RUN/${name}/web.sock + + puma -C config/puma.rb + ''; + }; + sidekiq = pkgs.linkFarm "sidekiq" { + run = pkgs.writeShellScript "run-sidekiq" '' + cd ${mastodon} + sidekiq + ''; + }; + streaming = pkgs.linkFarm "sidekiq" { + run = pkgs.writeShellScript "run-sidekiq" '' + cd ${mastodon} + + export SOCKET=$MINIFEDI_RUN/${name}/streaming.sock + + ${mastodon}/run-streaming.sh + ''; + }; + }; + path = "${name}/service"; + }; + path = pkgs.lib.strings.concatStrings (builtins.map (x: "${x}/bin:") [ + mastodon + pkgs.postgresql + pkgs.s6 + # used by mastodon file upload: + pkgs.file + pkgs.imagemagick + # used by sidekiq: + pkgs.ps + ]); +in { + service = pkgs.linkFarm name [{ + name = "run"; + path = pkgs.writeShellScript "run-${name}" '' + set -e + + export PATH=${path}$PATH + + data=$MINIFEDI_DATA/${name} + run=$MINIFEDI_RUN/${name} + postgres=$MINIFEDI_RUN/postgres + + mkdir -p $data + mkdir -p $data/files + mkdir -p $run + + cd ${mastodon} + + ${pkgs.lib.strings.concatStrings (pkgs.lib.attrsets.mapAttrsToList + (k: v: '' + export ${k}=${v} + '') env)} + + if ! [ -e $data/setup-done ]; then + rake secret > $data/secret_key_base + rake secret > $data/otp_secret + # from nixos + keypair=$(rake webpush:generate_keys) + echo $keypair | grep --only-matching "Private -> [^ ]\+" | sed 's/^Private -> //' > $data/vapid_private_key + echo $keypair | grep --only-matching "Public -> [^ ]\+" | sed 's/^Public -> //' > $data/vapid_public_key + fi + + export SECRET_KEY_BASE=$(cat $data/secret_key_base) + export OTP_SECRET=$(cat $data/otp_secret) + export VAPID_PRIVATE_KEY=$(cat $data/vapid_private_key) + export VAPID_PUBLIC_KEY=$(cat $data/vapid_public_key) + + export DB_HOST=$postgres + export REDIS_URL=unix://$MINIFEDI_RUN/redis/redis.sock + export NIX_SSL_CERT_FILE=$MINIFEDI_CERT/rootCA.pem + export PAPERCLIP_ROOT_PATH=$data/files + + s6-svwait -U $MINIFEDI_RUN/service/postgres + + if ! [ -e $data/setup-done ]; then + createdb -h$postgres ${name} + createuser -h$postgres ${name} + + rails db:schema:load + rails db:seed + + touch $data/setup-done + + tootctl accounts create a --email=a@${name}.example --confirmed --role Owner + rails runner "Account.find_local('a').user.update!(password: 'Aa12345!')" + tootctl accounts create b --email=b@${name}.example --confirmed + rails runner "Account.find_local('b').user.update!(password: 'Bb12345!')" + tootctl accounts create c --email=c@${name}.example --confirmed + rails runner "Account.find_local('c').user.update!(password: 'Cc12345!')" + tootctl accounts create d --email=d@${name}.example --confirmed + rails runner "Account.find_local('d').user.update!(password: 'Dd12345!')" + tootctl accounts create e --email=e@${name}.example --confirmed + rails runner "Account.find_local('e').user.update!(password: 'Ee12345!')" + fi + + exec ${s6.start} + ''; + }]; + nginxConfig = '' + map $http_upgrade ${"$"}${name}_connection_upgrade { + default upgrade; + ${"''"} close; + } + + upstream ${name}_backend { + server unix:$MINIFEDI_RUN/${name}/web.sock fail_timeout=0; + } + + upstream ${name}_streaming { + server unix:$MINIFEDI_RUN/${name}/streaming.sock fail_timeout=0; + } + + server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name ${name}.lvh.me; + + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_tickets off; + + # Uncomment these lines once you acquire a certificate: + ssl_certificate $MINIFEDI_DATA/nginx/fullchain.pem; + ssl_certificate_key $MINIFEDI_DATA/nginx/key.pem; + + keepalive_timeout 70; + sendfile on; + client_max_body_size 99m; + + root ${mastodon}/public; + + gzip on; + gzip_disable "msie6"; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml image/x-icon; + + location / { + try_files $uri @proxy; + } + + # If Docker is used for deployment and Rails serves static files, + # then needed must replace line `try_files $uri =404;` with `try_files $uri @proxy;`. + location = /sw.js { + add_header Cache-Control "public, max-age=604800, must-revalidate"; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; + try_files $uri =404; + } + + location ~ ^/assets/ { + add_header Cache-Control "public, max-age=2419200, must-revalidate"; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; + try_files $uri =404; + } + + location ~ ^/avatars/ { + add_header Cache-Control "public, max-age=2419200, must-revalidate"; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; + try_files $uri =404; + } + + location ~ ^/emoji/ { + add_header Cache-Control "public, max-age=2419200, must-revalidate"; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; + try_files $uri =404; + } + + location ~ ^/headers/ { + add_header Cache-Control "public, max-age=2419200, must-revalidate"; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; + try_files $uri =404; + } + + location ~ ^/packs/ { + add_header Cache-Control "public, max-age=2419200, must-revalidate"; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; + try_files $uri =404; + } + + location ~ ^/shortcuts/ { + add_header Cache-Control "public, max-age=2419200, must-revalidate"; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; + try_files $uri =404; + } + + location ~ ^/sounds/ { + add_header Cache-Control "public, max-age=2419200, must-revalidate"; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; + try_files $uri =404; + } + + location /system/ { + add_header Cache-Control "public, max-age=2419200, immutable"; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; + + alias $MINIFEDI_DATA/${name}/files/; + + try_files $uri =404; + } + + location ^~ /api/v1/streaming { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Proxy ""; + + proxy_pass http://${name}_streaming; + proxy_buffering off; + proxy_redirect off; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection ${"$"}${name}_connection_upgrade; + + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; + + tcp_nodelay on; + } + + location @proxy { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Proxy ""; + proxy_pass_header Server; + + proxy_pass http://${name}_backend; + proxy_buffering on; + proxy_redirect off; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection ${"$"}${name}_connection_upgrade; + + # proxy_cache CACHE; + # proxy_cache_valid 200 7d; + # proxy_cache_valid 410 24h; + # proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; + add_header X-Cached $upstream_cache_status; + + tcp_nodelay on; + } + + error_page 404 500 501 502 503 504 /500.html; + } + ''; +} diff --git a/nix/fedi/mastodon/gemset.nix b/nix/fedi/mastodon/gemset.nix new file mode 100644 index 0000000..2097dfc --- /dev/null +++ b/nix/fedi/mastodon/gemset.nix @@ -0,0 +1,3190 @@ +{ + actioncable = { + dependencies = ["actionpack" "activesupport" "nio4r" "websocket-driver"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1y9lj7ra9xf4q4mryydmd498grsndqmz1zwasb4ai9gv62igvw3s"; + type = "gem"; + }; + version = "6.1.7.2"; + }; + actionmailbox = { + dependencies = ["actionpack" "activejob" "activerecord" "activestorage" "activesupport" "mail"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0bzacsr93sxv90nljv3ajw54nmyz1v9k2v2wx1pxsi0jasqg5fvn"; + type = "gem"; + }; + version = "6.1.7.2"; + }; + actionmailer = { + dependencies = ["actionpack" "actionview" "activejob" "activesupport" "mail" "rails-dom-testing"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1rjddp1a5l4amsbibhnf7g2rb69qvq0nc0a2dvr6r57bpkf82hj4"; + type = "gem"; + }; + version = "6.1.7.2"; + }; + actionpack = { + dependencies = ["actionview" "activesupport" "rack" "rack-test" "rails-dom-testing" "rails-html-sanitizer"]; + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0c2y6sqpan68lrx78pvhbxb2917m75s808r6cg1kyygwvg31niza"; + type = "gem"; + }; + version = "6.1.7.2"; + }; + actiontext = { + dependencies = ["actionpack" "activerecord" "activestorage" "activesupport" "nokogiri"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1jx8wi961i34v7x0j3h4wjw3qbyx9bkzb598vg42kidzk2f90dyj"; + type = "gem"; + }; + version = "6.1.7.2"; + }; + actionview = { + dependencies = ["activesupport" "builder" "erubi" "rails-dom-testing" "rails-html-sanitizer"]; + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "10g5gk8h4mfhvgqylzbf591fqf5p78ca35cb97p9bclpv9jfy0za"; + type = "gem"; + }; + version = "6.1.7.2"; + }; + active_model_serializers = { + dependencies = ["actionpack" "activemodel" "case_transform" "jsonapi-renderer"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0xdp7cpj3yj3wl4vj0nqq44kzjavlxi1wq3cf9zp0whkir0ym0gy"; + type = "gem"; + }; + version = "0.10.13"; + }; + active_record_query_trace = { + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "19888wjdpqvr2kaci6v6jyjw9pjf682zb1iyx2lz12mpdmy3500n"; + type = "gem"; + }; + version = "1.8"; + }; + activejob = { + dependencies = ["activesupport" "globalid"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0ililjwy4x52a6x5fidh1iyllf6vx49nz93fd2hxypc5bpryx9mz"; + type = "gem"; + }; + version = "6.1.7.2"; + }; + activemodel = { + dependencies = ["activesupport"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0nn17y72fhsynwn11bqg75bazqp6r1g8mpwwyv64harwvh3fh5qj"; + type = "gem"; + }; + version = "6.1.7.2"; + }; + activerecord = { + dependencies = ["activemodel" "activesupport"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1k69m3b0lb4jx20jx8vsvdqm1ki1r6riq9haabyddkcpvmgz1wh7"; + type = "gem"; + }; + version = "6.1.7.2"; + }; + activestorage = { + dependencies = ["actionpack" "activejob" "activerecord" "activesupport" "marcel" "mini_mime"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0c3cvc01azfkccg5hsl96wafsxb5hf1nva3cn8rif2mlwx17p8n3"; + type = "gem"; + }; + version = "6.1.7.2"; + }; + activesupport = { + dependencies = ["concurrent-ruby" "i18n" "minitest" "tzinfo" "zeitwerk"]; + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "14pjq2k761qaywaznpqq8ziivjk2ks1ma2cjwdflkxqgndxjmsr2"; + type = "gem"; + }; + version = "6.1.7.2"; + }; + addressable = { + dependencies = ["public_suffix"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1ypdmpdn20hxp5vwxz3zc04r5xcwqc25qszdlg41h8ghdqbllwmw"; + type = "gem"; + }; + version = "2.8.1"; + }; + aes_key_wrap = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "19bn0y70qm6mfj4y1m0j3s8ggh6dvxwrwrj5vfamhdrpddsz8ddr"; + type = "gem"; + }; + version = "1.1.0"; + }; + airbrussh = { + dependencies = ["sshkit"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0x55y3ynkda76pwnsvrrjlvxfcc7yn1irad8radll9c9cif41jqv"; + type = "gem"; + }; + version = "1.4.1"; + }; + android_key_attestation = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "02spc1sh7zsljl02v9d5rdb717b628vw2k7jkkplifyjk4db0zj6"; + type = "gem"; + }; + version = "0.3.0"; + }; + annotate = { + dependencies = ["activerecord" "rake"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1lw0fxb5mirsdp3bp20gjyvs7clvi19jbxnrm2ihm20kzfhvlqcs"; + type = "gem"; + }; + version = "3.2.0"; + }; + ast = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "04nc8x27hlzlrr5c2gn7mar4vdr0apw5xg22wp6m8dx3wqr04a0y"; + type = "gem"; + }; + version = "2.4.2"; + }; + attr_encrypted = { + dependencies = ["encryptor"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0ncv2az1zlj33bsllr6q1qdvbw42gv91lxq0ryclbv8l8xh841jg"; + type = "gem"; + }; + version = "3.1.0"; + }; + attr_required = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1g22axmi2rhhy7w8c3x6gppsawxqavbrnxpnmphh22fk7cwi0kh2"; + type = "gem"; + }; + version = "1.0.1"; + }; + awrence = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0gj8f8c54r9cabkm41s59sa1ca5wpbipw7gq3sfl87x9296227fx"; + type = "gem"; + }; + version = "1.2.1"; + }; + aws-eventstream = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1pyis1nvnbjxk12a43xvgj2gv0mvp4cnkc1gzw0v1018r61399gz"; + type = "gem"; + }; + version = "1.2.0"; + }; + aws-partitions = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1nz23laxgrxbv5svswi3bksmbhz86j691n4099qp4049i5a5cx91"; + type = "gem"; + }; + version = "1.701.0"; + }; + aws-sdk-core = { + dependencies = ["aws-eventstream" "aws-partitions" "aws-sigv4" "jmespath"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0zc4zhv2wq7s5p8c9iaplama1lpg2kwldg81j83c8w4xydf1wd2r"; + type = "gem"; + }; + version = "3.170.0"; + }; + aws-sdk-kms = { + dependencies = ["aws-sdk-core" "aws-sigv4"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "070s86pxrbq98iddq6shdq7g0lrzgsdqnsnc5l4kygvqimliq4dr"; + type = "gem"; + }; + version = "1.62.0"; + }; + aws-sdk-s3 = { + dependencies = ["aws-sdk-core" "aws-sdk-kms" "aws-sigv4"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1sg212jsj6ydyrr6r284mgqcl83kln2hfd9nlyisf3pj5lbdjd1c"; + type = "gem"; + }; + version = "1.119.0"; + }; + aws-sigv4 = { + dependencies = ["aws-eventstream"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "11hkna2av47bl0yprgp8k4ya70rc3m2ib5w10fn0piplgkkmhz7m"; + type = "gem"; + }; + version = "1.5.2"; + }; + bcrypt = { + groups = ["default" "pam_authentication"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1rakdhrnlclrpy7sihi9ipwdh7fjkkvzga171464lq6rzp07cf65"; + type = "gem"; + }; + version = "3.1.17"; + }; + better_errors = { + dependencies = ["coderay" "erubi" "rack"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "11220lfzhsyf5fcril3qd689kgg46qlpiiaj00hc9mh4mcbc3vrr"; + type = "gem"; + }; + version = "2.9.1"; + }; + better_html = { + dependencies = ["actionview" "activesupport" "ast" "erubi" "parser" "smart_properties"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1y090dmgjxr3yzxi3pg5jgirkmyfdrmjhabmzmhg5i8ssiqr2gdz"; + type = "gem"; + }; + version = "2.0.1"; + }; + bindata = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0mz9hz5clknznw8i5f3l2zb9103mlgh96djdhlvlfpf2chkr0s1z"; + type = "gem"; + }; + version = "2.4.14"; + }; + binding_of_caller = { + dependencies = ["debug_inspector"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "078n2dkpgsivcf0pr50981w95nfc2bsrp3wpf9wnxz1qsp8jbb9s"; + type = "gem"; + }; + version = "1.0.0"; + }; + blurhash = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "057afgqy73n8vm7k3cr4pbwm1hhqnm58lp4x7bgm5wzbs39m7xf8"; + type = "gem"; + }; + version = "0.1.7"; + }; + bootsnap = { + dependencies = ["msgpack"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1vcg52gwl64xhhal6kwk1pc01y1klzdlnv1awyk89kb91z010x7q"; + type = "gem"; + }; + version = "1.16.0"; + }; + brakeman = { + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0lcxxlrzgpi9z2mr2v19xda6fdysmn5psa9bsp2rksa915v91fds"; + type = "gem"; + }; + version = "5.4.0"; + }; + browser = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0q1yzvbqp0mykswipq3w00ljw9fgkhjfrij3hkwi7cx85r14n6gw"; + type = "gem"; + }; + version = "4.2.0"; + }; + brpoplpush-redis_script = { + dependencies = ["concurrent-ruby" "redis"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1nd5zj5yqmhv9lrsqz8s2dqq28v4ywy95qrw7nzhhf89dl4dq49l"; + type = "gem"; + }; + version = "0.1.3"; + }; + builder = { + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "045wzckxpwcqzrjr353cxnyaxgf0qg22jh00dcx7z38cys5g1jlr"; + type = "gem"; + }; + version = "3.2.4"; + }; + bullet = { + dependencies = ["activesupport" "uniform_notifier"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0hyz68j0z0j24vcrs43swmlykhzypayv34kzrsbxda5lbi83gynm"; + type = "gem"; + }; + version = "7.0.7"; + }; + bundler-audit = { + dependencies = ["thor"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0gdx0019vj04n1512shhdx7hwphzqmdpw4vva2k551nd47y1dixx"; + type = "gem"; + }; + version = "0.9.1"; + }; + byebug = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0nx3yjf4xzdgb8jkmk2344081gqr22pgjqnmjg2q64mj5d6r9194"; + type = "gem"; + }; + version = "11.1.3"; + }; + capistrano = { + dependencies = ["airbrussh" "i18n" "rake" "sshkit"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1673k8yzy4gl96f1xjj6zf1r2pgm2h042vdsiw03wqx4ygbq2las"; + type = "gem"; + }; + version = "3.17.1"; + }; + capistrano-bundler = { + dependencies = ["capistrano"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "168kyi0gv2s84jm533m8rg0dii50flr06n6s2ci6kzsib3n9n8dr"; + type = "gem"; + }; + version = "2.0.1"; + }; + capistrano-rails = { + dependencies = ["capistrano" "capistrano-bundler"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1iyhs77bff09g18dlz0li5f44khjwpqc09gk5hzcnf5v9yvijpg9"; + type = "gem"; + }; + version = "1.6.2"; + }; + capistrano-rbenv = { + dependencies = ["capistrano" "sshkit"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1x9m1i5zd0wx122zw3m40zprlmxk9d47bd6w61k81wr4qsvkk3rw"; + type = "gem"; + }; + version = "2.2.0"; + }; + capistrano-yarn = { + dependencies = ["capistrano"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1zdg2s061vl5b8114n909mrjb2hc1qx0i4wqx9nacsrcjgyp07l9"; + type = "gem"; + }; + version = "2.0.2"; + }; + capybara = { + dependencies = ["addressable" "matrix" "mini_mime" "nokogiri" "rack" "rack-test" "regexp_parser" "xpath"]; + groups = ["test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "123198zk2ak8mziwa5jc3ckgpmsg08zn064n3aywnqm9s1bwjv3v"; + type = "gem"; + }; + version = "3.38.0"; + }; + case_transform = { + dependencies = ["activesupport"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0fzyws6spn5arqf6q604dh9mrj84a36k5hsc8z7jgcpfvhc49bg2"; + type = "gem"; + }; + version = "0.2"; + }; + cbor = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0511idr8xps9625nh3kxr68sdy6l3xy2kcz7r57g47fxb1v18jj3"; + type = "gem"; + }; + version = "0.5.9.6"; + }; + charlock_holmes = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0hybw8jw9ryvz5zrki3gc9r88jqy373m6v46ynxsdzv1ysiyr40p"; + type = "gem"; + }; + version = "0.7.7"; + }; + chewy = { + dependencies = ["activesupport" "elasticsearch" "elasticsearch-dsl"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1jfdz0z27p839m09xmw5anrw5jp3jd5hd5gnx4vlk6kk520cy6sf"; + type = "gem"; + }; + version = "7.2.4"; + }; + chunky_png = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1znw5x86hmm9vfhidwdsijz8m38pqgmv98l9ryilvky0aldv7mc9"; + type = "gem"; + }; + version = "1.4.0"; + }; + climate_control = { + groups = ["test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0q11v0iabvr6rif0d025xh078ili5frrihlj0m04zfg7lgvagxji"; + type = "gem"; + }; + version = "0.2.0"; + }; + cocoon = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "038z97pkhvsqbh6cmyyzj58ya968p24k7r0f0rx7sa2kjvk193yh"; + type = "gem"; + }; + version = "1.2.15"; + }; + coderay = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0jvxqxzply1lwp7ysn94zjhh57vc14mcshw1ygw14ib8lhc00lyw"; + type = "gem"; + }; + version = "1.1.3"; + }; + color_diff = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "01dpvqlzybpb3pkcwd9ik5sbjw283618ywvdphxslhiy8ps3kp4r"; + type = "gem"; + }; + version = "0.1"; + }; + concurrent-ruby = { + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1qnsflsbjj38im8xq35g0vihlz96h09wjn2dad5g543l3vvrkrx5"; + type = "gem"; + }; + version = "1.2.0"; + }; + connection_pool = { + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1nj4r58m5cpfdsijj6gjfs3yzcnxq2halagjk07wjcrgj6z8ayb7"; + type = "gem"; + }; + version = "2.3.0"; + }; + cose = { + dependencies = ["cbor" "openssl-signature_algorithm"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0cf29s40xf6a9k0idswfbabkswr0k5iqfrg61v40bzfrv0fdg440"; + type = "gem"; + }; + version = "1.2.1"; + }; + crack = { + dependencies = ["rexml"]; + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1cr1kfpw3vkhysvkk3wg7c54m75kd68mbm9rs5azdjdq57xid13r"; + type = "gem"; + }; + version = "0.4.5"; + }; + crass = { + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0pfl5c0pyqaparxaqxi6s4gfl21bdldwiawrc0aknyvflli60lfw"; + type = "gem"; + }; + version = "1.0.6"; + }; + css_parser = { + dependencies = ["addressable"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1107j3frhmcd95wcsz0rypchynnzhnjiyyxxcl6dlmr2lfy08z4b"; + type = "gem"; + }; + version = "1.12.0"; + }; + date = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "03skfikihpx37rc27vr3hwrb057gxnmdzxhmzd4bf4jpkl0r55w1"; + type = "gem"; + }; + version = "3.3.3"; + }; + debug_inspector = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1lswmjwxf1clzaimikhiwd9s1n07qkyz7a9xwng64j4fxsajykqp"; + type = "gem"; + }; + version = "1.0.0"; + }; + devise = { + dependencies = ["bcrypt" "orm_adapter" "railties" "responders" "warden"]; + groups = ["default" "pam_authentication"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0gl0b4jqf7ysv3rg99sgxa5y9va2k13p0si3a88pr7m8g6z8pm7x"; + type = "gem"; + }; + version = "4.8.1"; + }; + devise-two-factor = { + dependencies = ["activesupport" "attr_encrypted" "devise" "railties" "rotp"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "04f5rb8fg4cvzm32v413z3h53wc0fgxg927q8rqd546hdrlx4j35"; + type = "gem"; + }; + version = "4.0.2"; + }; + diff-lcs = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0rwvjahnp7cpmracd8x732rjgnilqv2sx7d1gfrysslc3h039fa9"; + type = "gem"; + }; + version = "1.5.0"; + }; + discard = { + dependencies = ["activerecord"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1xavjhccyyzn9z6fz3034vgvzprc983mbrq6n9sc0drfw7m3vrip"; + type = "gem"; + }; + version = "1.2.1"; + }; + docile = { + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1lxqxgq71rqwj1lpl9q1mbhhhhhhdkkj7my341f2889pwayk85sz"; + type = "gem"; + }; + version = "1.4.0"; + }; + domain_name = { + dependencies = ["unf"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0lcqjsmixjp52bnlgzh4lg9ppsk52x9hpwdjd53k8jnbah2602h0"; + type = "gem"; + }; + version = "0.5.20190701"; + }; + doorkeeper = { + dependencies = ["railties"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0fxrvqv3l5w9p20s129rg41zc6agf1n4yrmganancnvykbkygki2"; + type = "gem"; + }; + version = "5.6.4"; + }; + dotenv = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1n0pi8x8ql5h1mijvm8lgn6bhq4xjb5a500p5r1krq4s6j9lg565"; + type = "gem"; + }; + version = "2.8.1"; + }; + dotenv-rails = { + dependencies = ["dotenv" "railties"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0v0gcbxzypcvy6fqq4gp80jb310xvdwj5n8qw9ci67g5yjvq2nxh"; + type = "gem"; + }; + version = "2.8.1"; + }; + ed25519 = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0zb2dr2ihb1qiknn5iaj1ha1w9p7lj9yq5waasndlfadz225ajji"; + type = "gem"; + }; + version = "1.3.0"; + }; + elasticsearch = { + dependencies = ["elasticsearch-api" "elasticsearch-transport"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0havyxmvl157a653prspnbhgdchlx44xqxl170v1im5ggxwavcaq"; + type = "gem"; + }; + version = "7.13.3"; + }; + elasticsearch-api = { + dependencies = ["multi_json"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0bmssarkk7lqkjdn8c9j7jvxcnn4hg1zcmhsky8bfvc99k33b3w8"; + type = "gem"; + }; + version = "7.13.3"; + }; + elasticsearch-dsl = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "174m3fwm3mawbkjg2xbmqvljq7ava4s95m8vpg5khcvfj506wxfk"; + type = "gem"; + }; + version = "0.1.10"; + }; + elasticsearch-transport = { + dependencies = ["faraday" "multi_json"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0blfii8qvj0m6bg9sbfynxc40in7zfmw2wpi4clv7d9gclk053db"; + type = "gem"; + }; + version = "7.13.3"; + }; + encryptor = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0s8rvfl0vn8w7k1sgkc234060jh468s3zd45xa64p1jdmfa3zwmb"; + type = "gem"; + }; + version = "3.0.0"; + }; + erubi = { + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "08s75vs9cxlc4r1q2bjg4br8g9wc5lc5x5vl0vv4zq5ivxsdpgi7"; + type = "gem"; + }; + version = "1.12.0"; + }; + et-orbi = { + dependencies = ["tzinfo"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1d2z4ky2v15dpcz672i2p7lb2nc793dasq3yq3660h2az53kss9v"; + type = "gem"; + }; + version = "1.2.7"; + }; + excon = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "08idrrnpwzr87wc5yhyv6id1f6zigr3nfn45mff01605b0zghdby"; + type = "gem"; + }; + version = "0.95.0"; + }; + fabrication = { + groups = ["development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0bxssmjp49whzq2zv7w751gr4nkdaiwcxd1vda0byigwyrnj6f5q"; + type = "gem"; + }; + version = "2.30.0"; + }; + faker = { + dependencies = ["i18n"]; + groups = ["test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1b8772jybi0vxzbcs5zw17k40z661c8adn2rd6vqqr7ay71bzl09"; + type = "gem"; + }; + version = "3.1.1"; + }; + faraday = { + dependencies = ["faraday-em_http" "faraday-em_synchrony" "faraday-excon" "faraday-httpclient" "faraday-multipart" "faraday-net_http" "faraday-net_http_persistent" "faraday-patron" "faraday-rack" "faraday-retry" "ruby2_keywords"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0y32gj994ll3zlcqjmwp78r7s03iiwayij6fz2pjpkfywgvp71s6"; + type = "gem"; + }; + version = "1.9.3"; + }; + faraday-em_http = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "12cnqpbak4vhikrh2cdn94assh3yxza8rq2p9w2j34bqg5q4qgbs"; + type = "gem"; + }; + version = "1.0.0"; + }; + faraday-em_synchrony = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1vgrbhkp83sngv6k4mii9f2s9v5lmp693hylfxp2ssfc60fas3a6"; + type = "gem"; + }; + version = "1.0.0"; + }; + faraday-excon = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0h09wkb0k0bhm6dqsd47ac601qiaah8qdzjh8gvxfd376x1chmdh"; + type = "gem"; + }; + version = "1.1.0"; + }; + faraday-httpclient = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0fyk0jd3ks7fdn8nv3spnwjpzx2lmxmg2gh4inz3by1zjzqg33sc"; + type = "gem"; + }; + version = "1.0.1"; + }; + faraday-multipart = { + dependencies = ["multipart-post"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "03qfi9020ynf7hkdiaq01sd2mllvw7fg4qiin3pk028b4wv23j3j"; + type = "gem"; + }; + version = "1.0.3"; + }; + faraday-net_http = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1fi8sda5hc54v1w3mqfl5yz09nhx35kglyx72w7b8xxvdr0cwi9j"; + type = "gem"; + }; + version = "1.0.1"; + }; + faraday-net_http_persistent = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0dc36ih95qw3rlccffcb0vgxjhmipsvxhn6cw71l7ffs0f7vq30b"; + type = "gem"; + }; + version = "1.2.0"; + }; + faraday-patron = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "19wgsgfq0xkski1g7m96snv39la3zxz6x7nbdgiwhg5v82rxfb6w"; + type = "gem"; + }; + version = "1.0.0"; + }; + faraday-rack = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1h184g4vqql5jv9s9im6igy00jp6mrah2h14py6mpf9bkabfqq7g"; + type = "gem"; + }; + version = "1.0.0"; + }; + faraday-retry = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "153i967yrwnswqgvnnajgwp981k9p50ys1h80yz3q94rygs59ldd"; + type = "gem"; + }; + version = "1.0.3"; + }; + fast_blank = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1shpmamyzyhyxmv95r96ja5rylzaw60r19647d0fdm7y2h2c77r6"; + type = "gem"; + }; + version = "1.0.1"; + }; + fastimage = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0nnggg20za5vamdpkgrxxa32z33d8hf0g2bciswkhqnc6amb3yjr"; + type = "gem"; + }; + version = "2.2.6"; + }; + ffi = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1862ydmclzy1a0cjbvm8dz7847d9rch495ib0zb64y84d3xd4bkg"; + type = "gem"; + }; + version = "1.15.5"; + }; + ffi-compiler = { + dependencies = ["ffi" "rake"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0c2caqm9wqnbidcb8dj4wd3s902z15qmgxplwyfyqbwa0ydki7q1"; + type = "gem"; + }; + version = "1.0.1"; + }; + fog-core = { + dependencies = ["builder" "excon" "formatador" "mime-types"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1agd6xgzk0rxrsjdpn94v4hy89s0nm2cs4zg2p880w2dan9xgrak"; + type = "gem"; + }; + version = "2.1.0"; + }; + fog-json = { + dependencies = ["fog-core" "multi_json"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1zj8llzc119zafbmfa4ai3z5s7c4vp9akfs0f9l2piyvcarmlkyx"; + type = "gem"; + }; + version = "1.2.0"; + }; + fog-openstack = { + dependencies = ["fog-core" "fog-json" "ipaddress"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "11j18h61d3p0pcp9k5346lbj1lahab1dqybkrx9338932lmjn7ap"; + type = "gem"; + }; + version = "0.3.10"; + }; + formatador = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0mprf1dwznz5ld0q1jpbyl59fwnwk6azspnd0am7zz7kfg3pxhv5"; + type = "gem"; + }; + version = "0.3.0"; + }; + fugit = { + dependencies = ["et-orbi" "raabro"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0g7m38n4f5cjqa4gf4fycw6fqvf6m5hhsx4jawryv3bi4hls07d1"; + type = "gem"; + }; + version = "1.7.1"; + }; + fuubar = { + dependencies = ["rspec-core" "ruby-progressbar"]; + groups = ["development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1028vn7j3kc5qqwswrf3has3qm4j9xva70xmzb3n29i89f0afwmj"; + type = "gem"; + }; + version = "2.5.1"; + }; + gitlab-omniauth-openid-connect = { + dependencies = ["addressable" "omniauth" "openid_connect"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1pp9cf6b68pky9bndmals070kibab525wjn9igx9pc5h8z1jv5bd"; + type = "gem"; + }; + version = "0.10.1"; + }; + globalid = { + dependencies = ["activesupport"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0kqm5ndzaybpnpxqiqkc41k4ksyxl41ln8qqr6kb130cdxsf2dxk"; + type = "gem"; + }; + version = "1.1.0"; + }; + hamlit = { + dependencies = ["temple" "thor" "tilt"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "06imnwpzvpagwn0b9a8kwv7hncii32flmafz20z95hd77hhr6ab7"; + type = "gem"; + }; + version = "2.13.0"; + }; + hamlit-rails = { + dependencies = ["actionpack" "activesupport" "hamlit" "railties"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0v75yd6x0nwky83smd9hw5ym9h0pi32jrzbnvq55pzj0rc95gg2p"; + type = "gem"; + }; + version = "0.2.3"; + }; + hashdiff = { + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1nynpl0xbj0nphqx1qlmyggq58ms1phf5i03hk64wcc0a17x1m1c"; + type = "gem"; + }; + version = "1.0.1"; + }; + hashie = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1nh3arcrbz1rc1cr59qm53sdhqm137b258y8rcb4cvd3y98lwv4x"; + type = "gem"; + }; + version = "5.0.0"; + }; + highline = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0yclf57n2j3cw8144ania99h1zinf8q3f5zrhqa754j6gl95rp9d"; + type = "gem"; + }; + version = "2.0.3"; + }; + hiredis = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "04jj8k7lxqxw24sp0jiravigdkgsyrpprxpxm71ba93x1wr2w1bz"; + type = "gem"; + }; + version = "0.6.3"; + }; + hkdf = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "04fixg0a51n4vy0j6c1hvisa2yl33m3jrrpxpb5sq6j511vjriil"; + type = "gem"; + }; + version = "0.3.0"; + }; + htmlentities = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1nkklqsn8ir8wizzlakncfv42i32wc0w9hxp00hvdlgjr7376nhj"; + type = "gem"; + }; + version = "4.3.4"; + }; + http = { + dependencies = ["addressable" "http-cookie" "http-form_data" "llhttp-ffi"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1bzb8p31kzv6q5p4z5xq88mnqk414rrw0y5rkhpnvpl29x5c3bpw"; + type = "gem"; + }; + version = "5.1.1"; + }; + http-cookie = { + dependencies = ["domain_name"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "13rilvlv8kwbzqfb644qp6hrbsj82cbqmnzcvqip1p6vqx36sxbk"; + type = "gem"; + }; + version = "1.0.5"; + }; + http-form_data = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1wx591jdhy84901pklh1n9sgh74gnvq1qyqxwchni1yrc49ynknc"; + type = "gem"; + }; + version = "2.3.0"; + }; + http_accept_language = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0d0nlfz9vm4jr1l6q0chx4rp2hrnrfbx3gadc1dz930lbbaz0hq0"; + type = "gem"; + }; + version = "2.1.1"; + }; + httpclient = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "19mxmvghp7ki3klsxwrlwr431li7hm1lczhhj8z4qihl2acy8l99"; + type = "gem"; + }; + version = "2.8.3"; + }; + httplog = { + dependencies = ["rack" "rainbow"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0zjsgrlvwpqsnrza4ijlxjld4550c661sgbqp2j2wp638nlnls1a"; + type = "gem"; + }; + version = "1.6.2"; + }; + i18n = { + dependencies = ["concurrent-ruby"]; + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1vdcchz7jli1p0gnc669a7bj3q1fv09y9ppf0y3k0vb1jwdwrqwi"; + type = "gem"; + }; + version = "1.12.0"; + }; + i18n-tasks = { + dependencies = ["activesupport" "ast" "better_html" "erubi" "highline" "i18n" "parser" "rails-i18n" "rainbow" "terminal-table"]; + groups = ["development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "19zkcsqwzc3i6vizj26mxxww6m5grv9zmp6yxyswbqq9kyzb081z"; + type = "gem"; + }; + version = "1.0.12"; + }; + idn-ruby = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0dy04jx3n1ddz744b80mg7hp87miysnjp0h21lqr43hpmhdglxih"; + type = "gem"; + }; + version = "0.1.5"; + }; + ipaddress = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1x86s0s11w202j6ka40jbmywkrx8fhq8xiy8mwvnkhllj57hqr45"; + type = "gem"; + }; + version = "0.8.3"; + }; + jmespath = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1cdw9vw2qly7q7r41s7phnac264rbsdqgj4l0h4nqgbjb157g393"; + type = "gem"; + }; + version = "1.6.2"; + }; + json = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0nalhin1gda4v8ybk6lq8f407cgfrj6qzn234yra4ipkmlbfmal6"; + type = "gem"; + }; + version = "2.6.3"; + }; + json-canonicalization = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "179h6jfdsp9dmzyma7s7ykv1ia43r6z8x96j335q99p6mc5sk5qv"; + type = "gem"; + }; + version = "0.3.0"; + }; + json-jwt = { + dependencies = ["activesupport" "aes_key_wrap" "bindata" "httpclient"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "04315mf4p9qa97grdfqv922paghzdfrbb982ap0p99rqwla4znv6"; + type = "gem"; + }; + version = "1.15.3"; + }; + json-ld = { + dependencies = ["htmlentities" "json-canonicalization" "link_header" "multi_json" "rack" "rdf"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1aq71is278w69brhg4yp0f4ldxmy2nyj45c1rfbf73qi945mrbln"; + type = "gem"; + }; + version = "3.2.3"; + }; + json-ld-preloaded = { + dependencies = ["json-ld" "rdf"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "004s52m37b2kbw8dv4rdfm2d90h1023z1mw9zfcs0x87v8aq7zyn"; + type = "gem"; + }; + version = "3.2.2"; + }; + json-schema = { + dependencies = ["addressable"]; + groups = ["test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0gdvm83yaa5n8hwapwzxwfcmbypiq2i0zfx4mzz67wg55p2cnli4"; + type = "gem"; + }; + version = "3.0.0"; + }; + jsonapi-renderer = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0ys4drd0k9rw5ixf8n8fx8v0pjh792w4myh0cpdspd317l1lpi5m"; + type = "gem"; + }; + version = "0.2.2"; + }; + jwt = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0kcmnx6rgjyd7sznai9ccns2nh7p7wnw3mi8a7vf2wkm51azwddq"; + type = "gem"; + }; + version = "2.5.0"; + }; + kaminari = { + dependencies = ["activesupport" "kaminari-actionview" "kaminari-activerecord" "kaminari-core"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0gia8irryvfhcr6bsr64kpisbgdbqjsqfgrk12a11incmpwny1y4"; + type = "gem"; + }; + version = "1.2.2"; + }; + kaminari-actionview = { + dependencies = ["actionview" "kaminari-core"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "02f9ghl3a9b5q7l079d3yzmqjwkr4jigi7sldbps992rigygcc0k"; + type = "gem"; + }; + version = "1.2.2"; + }; + kaminari-activerecord = { + dependencies = ["activerecord" "kaminari-core"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0c148z97s1cqivzbwrak149z7kl1rdmj7dxk6rpkasimmdxsdlqd"; + type = "gem"; + }; + version = "1.2.2"; + }; + kaminari-core = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1zw3pg6kj39y7jxakbx7if59pl28lhk98fx71ks5lr3hfgn6zliv"; + type = "gem"; + }; + version = "1.2.2"; + }; + kt-paperclip = { + dependencies = ["activemodel" "activesupport" "marcel" "mime-types" "terrapin"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "08ngapld22knlkyn0dhhddkfm4vfj0lgmwj4y6x4mhi2hzfwxcxr"; + type = "gem"; + }; + version = "7.1.1"; + }; + launchy = { + dependencies = ["addressable"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1xdyvr5j0gjj7b10kgvh8ylxnwk3wx19my42wqn9h82r4p246hlm"; + type = "gem"; + }; + version = "2.5.0"; + }; + letter_opener = { + dependencies = ["launchy"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1y5d4ip4l12v58bgazadl45iv3a5j7jp2gwg96b6jy378zn42a1d"; + type = "gem"; + }; + version = "1.8.1"; + }; + letter_opener_web = { + dependencies = ["actionmailer" "letter_opener" "railties" "rexml"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0vvvaz2ngaxv0s6sj25gdvp73vd8pfl8q3jharadg18p3va0m1ik"; + type = "gem"; + }; + version = "2.0.0"; + }; + link_header = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1yamrdq4rywmnpdhbygnkkl9fdy249fg5r851nrkkxr97gj5rihm"; + type = "gem"; + }; + version = "0.0.8"; + }; + llhttp-ffi = { + dependencies = ["ffi-compiler" "rake"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "00dh6zmqdj59rhcya0l4b9aaxq6n8xizfbil93k0g06gndyk5xz5"; + type = "gem"; + }; + version = "0.4.0"; + }; + lograge = { + dependencies = ["actionpack" "activesupport" "railties" "request_store"]; + groups = ["production"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "15pjm9pa5m3mbv9xvfgfr16q4jyaznsg8y63jz9x4jqr8npw0vx3"; + type = "gem"; + }; + version = "0.12.0"; + }; + loofah = { + dependencies = ["crass" "nokogiri"]; + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "08qhzck271anrx9y6qa6mh8hwwdzsgwld8q0000rcd7yvvpnjr3c"; + type = "gem"; + }; + version = "2.19.1"; + }; + mail = { + dependencies = ["mini_mime" "net-imap" "net-pop" "net-smtp"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0n0pijrc465zzrv5flxc41375zwaz9yfc2n0r80zjwarc1ixkdx1"; + type = "gem"; + }; + version = "2.8.0.1"; + }; + makara = { + dependencies = ["activerecord"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0a6x6w1ij484s1z0wp667d6v0zb8bylhhr3av10yz60a2nz4r1l7"; + type = "gem"; + }; + version = "0.5.1"; + }; + marcel = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0kky3yiwagsk8gfbzn3mvl2fxlh3b39v6nawzm4wpjs6xxvvc4x0"; + type = "gem"; + }; + version = "1.0.2"; + }; + mario-redis-lock = { + dependencies = ["redis"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1v9wdjcjqzpns2migxp4a5b4w82mipi0fwihbqz3q2qj2qm7wc17"; + type = "gem"; + }; + version = "1.2.1"; + }; + matrix = { + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1h2cgkpzkh3dd0flnnwfq6f3nl2b1zff9lvqz8xs853ssv5kq23i"; + type = "gem"; + }; + version = "0.4.2"; + }; + memory_profiler = { + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1c81d68r4wx0ckbmqxlfqc2qpd94jwcmqdm0xgr0s46r48pv9k9q"; + type = "gem"; + }; + version = "1.0.1"; + }; + method_source = { + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1pnyh44qycnf9mzi1j6fywd5fkskv3x7nmsqrrws0rjn5dd4ayfp"; + type = "gem"; + }; + version = "1.0.0"; + }; + mime-types = { + dependencies = ["mime-types-data"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0ipw892jbksbxxcrlx9g5ljq60qx47pm24ywgfbyjskbcl78pkvb"; + type = "gem"; + }; + version = "3.4.1"; + }; + mime-types-data = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "003gd7mcay800k2q4pb2zn8lwwgci4bhi42v2jvlidm8ksx03i6q"; + type = "gem"; + }; + version = "3.2022.0105"; + }; + mini_mime = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0lbim375gw2dk6383qirz13hgdmxlan0vc5da2l072j3qw6fqjm5"; + type = "gem"; + }; + version = "1.1.2"; + }; + mini_portile2 = { + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1af4yarhbbx62f7qsmgg5fynrik0s36wjy3difkawy536xg343mp"; + type = "gem"; + }; + version = "2.8.1"; + }; + minitest = { + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1kjy67qajw4rnkbjs5jyk7kc3lyhz5613fwj1i8f6ppdk4zampy0"; + type = "gem"; + }; + version = "5.17.0"; + }; + msgpack = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1q03pb0vq8388s431nbxabsfxnch6p304c8vnjlk0zzpcv713yr3"; + type = "gem"; + }; + version = "1.6.0"; + }; + multi_json = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0pb1g1y3dsiahavspyzkdy39j4q377009f6ix0bh1ag4nqw43l0z"; + type = "gem"; + }; + version = "1.15.0"; + }; + multipart-post = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1zgw9zlwh2a6i1yvhhc4a84ry1hv824d6g2iw2chs3k5aylpmpfj"; + type = "gem"; + }; + version = "2.1.1"; + }; + net-imap = { + dependencies = ["date" "net-protocol"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1d996zf3g8xz244791b0qsl9vr7zg4lqnnmf9k2kshr9lki5jam8"; + type = "gem"; + }; + version = "0.3.4"; + }; + net-ldap = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1ycw0qsw3hap8svakl0i30jkj0ffd4lpyrn17a1j0w8mz5ainmsj"; + type = "gem"; + }; + version = "0.17.1"; + }; + net-pop = { + dependencies = ["net-protocol"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1wyz41jd4zpjn0v1xsf9j778qx1vfrl24yc20cpmph8k42c4x2w4"; + type = "gem"; + }; + version = "0.1.2"; + }; + net-protocol = { + dependencies = ["timeout"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0dxckrlw4q1lcn3qg4mimmjazmg9bma5gllv72f8js3p36fb3b91"; + type = "gem"; + }; + version = "0.2.1"; + }; + net-scp = { + dependencies = ["net-ssh"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1q4kxfvx1v4awv8kgincishi7h16dj9sn74gz8x92i81668j1wgm"; + type = "gem"; + }; + version = "4.0.0.rc1"; + }; + net-smtp = { + dependencies = ["net-protocol"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1c6md06hm5bf6rv53sk54dl2vg038pg8kglwv3rayx0vk2mdql9x"; + type = "gem"; + }; + version = "0.3.3"; + }; + net-ssh = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1qp3i8bi7ji1np0530bp2p9zrrn6galvmbsivxwpkjdpjdyn19sr"; + type = "gem"; + }; + version = "7.0.1"; + }; + nio4r = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0xk64wghkscs6bv2n22853k2nh39d131c6rfpnlw12mbjnnv9v1v"; + type = "gem"; + }; + version = "2.5.8"; + }; + nokogiri = { + dependencies = ["mini_portile2" "racc"]; + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0qr6psd9qgv83pklpw7cpmshkcasnv8d777ksmvwsacwfvvkmnxj"; + type = "gem"; + }; + version = "1.14.1"; + }; + nsa = { + dependencies = ["activesupport" "concurrent-ruby" "sidekiq" "statsd-ruby"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1jzs1n71pi6najhs9h8jx156gzgk3h9bwjr60vazizwdz3mm69ia"; + type = "gem"; + }; + version = "0.2.8"; + }; + oj = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0lggrhlihxyfgiqqr9b2fqdxc4d2zff2czq30m3rgn8a0b2gsv90"; + type = "gem"; + }; + version = "3.13.23"; + }; + omniauth = { + dependencies = ["hashie" "rack"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1jn9j54l5h7xcba2vjq74l1dk0xrwvsjxam4qhylpi52nw0h5502"; + type = "gem"; + }; + version = "1.9.2"; + }; + omniauth-cas = { + dependencies = ["addressable" "nokogiri" "omniauth"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0kzlh1nac4yz70917cdcsk0r23gy5h7i0x5kbmkvkpbgk6gvrb0z"; + type = "gem"; + }; + version = "2.0.0"; + }; + omniauth-rails_csrf_protection = { + dependencies = ["actionpack" "omniauth"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0xgkxwg17w39q3yjqcj0fm6hdkw37qm1l82dvm9zxn6q2pbzm2zv"; + type = "gem"; + }; + version = "0.1.2"; + }; + omniauth-saml = { + dependencies = ["omniauth" "ruby-saml"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0gxl14lbksnjkl8dfn23lsjkk63md77icm5racrh6fsp5n4ni9d4"; + type = "gem"; + }; + version = "1.10.3"; + }; + openid_connect = { + dependencies = ["activemodel" "attr_required" "json-jwt" "net-smtp" "rack-oauth2" "swd" "tzinfo" "validate_email" "validate_url" "webfinger"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1k9kdivp45v6vhzdrnl5fzhd378gjj2hl4w9bazbqnfm15rsnzc8"; + type = "gem"; + }; + version = "1.4.2"; + }; + openssl = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1azzx975qr078isvg8i0hmsr2l98kgnlfrnbb2jdm9b5kwifx1h4"; + type = "gem"; + }; + version = "3.0.0"; + }; + openssl-signature_algorithm = { + dependencies = ["openssl"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0rwjga70kbg0rmwgksb2if34ndh9cy0fgrimkx3hjz9c68ssvpxg"; + type = "gem"; + }; + version = "1.2.1"; + }; + orm_adapter = { + groups = ["default" "pam_authentication"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1fg9jpjlzf5y49qs9mlpdrgs5rpcyihq1s4k79nv9js0spjhnpda"; + type = "gem"; + }; + version = "0.5.0"; + }; + ox = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1g9ivy30jx7hjl8l3il47dmc9xgla8dj762v5cw0mgzpd9rq6vr4"; + type = "gem"; + }; + version = "2.14.14"; + }; + parallel = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "07vnk6bb54k4yc06xnwck7php50l09vvlw1ga8wdz0pia461zpzb"; + type = "gem"; + }; + version = "1.22.1"; + }; + parser = { + dependencies = ["ast"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0zk8mdyr0322r11d63rcp5jhz4lakxilhvyvdv0ql5dw4lb83623"; + type = "gem"; + }; + version = "3.2.0.0"; + }; + parslet = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "01pnw6ymz6nynklqvqxs4bcai25kcvnd5x4id9z3vd1rbmlk0lfl"; + type = "gem"; + }; + version = "2.0.0"; + }; + pastel = { + dependencies = ["tty-color"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0xash2gj08dfjvq4hy6l1z22s5v30fhizwgs10d6nviggpxsj7a8"; + type = "gem"; + }; + version = "0.8.0"; + }; + pg = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1wd6nl81nbdwck04hccsm7wf23ghpi8yddd9j4rbwyvyj0sbsff1"; + type = "gem"; + }; + version = "1.4.5"; + }; + pghero = { + dependencies = ["activerecord"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0wi1mls8r6r43dy5m6dsdqk28q564164h97pp7a111pgkbdmxf83"; + type = "gem"; + }; + version = "3.1.0"; + }; + pkg-config = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "02fw2pzrmvwp67nbndpy8a2ln74fd8kmsiffw77z7g1mp58ww651"; + type = "gem"; + }; + version = "1.5.1"; + }; + posix-spawn = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0cmb0svalqcxfzlzc5fvrci12b79x7bakasr8gkl3q5rz6di1q52"; + type = "gem"; + }; + version = "0.3.15"; + }; + premailer = { + dependencies = ["addressable" "css_parser" "htmlentities"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0dfknfwwlzmb594acgi6v080ngxbnhshn3gzvdh5x2vx1aqvwc5r"; + type = "gem"; + }; + version = "1.18.0"; + }; + premailer-rails = { + dependencies = ["actionmailer" "net-smtp" "premailer"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0004f73kgrglida336fqkgx906m6n05nnfc17mypzg5rc78iaf61"; + type = "gem"; + }; + version = "1.12.0"; + }; + private_address_check = { + groups = ["production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "05phz0vscfh9chv90yc9091pifw3cpwkh76flnhrmvja1q3na4cy"; + type = "gem"; + }; + version = "0.5.0"; + }; + pry = { + dependencies = ["coderay" "method_source"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0m445x8fwcjdyv2bc0glzss2nbm1ll51bq45knixapc7cl3dzdlr"; + type = "gem"; + }; + version = "0.14.1"; + }; + pry-byebug = { + dependencies = ["byebug" "pry"]; + groups = ["development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1y41al94ks07166qbp2200yzyr5y60hm7xaiw4lxpgsm4b1pbyf8"; + type = "gem"; + }; + version = "3.10.1"; + }; + pry-rails = { + dependencies = ["pry"]; + groups = ["development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1cf4ii53w2hdh7fn8vhqpzkymmchjbwij4l3m7s6fsxvb9bn51j6"; + type = "gem"; + }; + version = "0.3.9"; + }; + public_suffix = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0hz0bx2qs2pwb0bwazzsah03ilpf3aai8b7lk7s35jsfzwbkjq35"; + type = "gem"; + }; + version = "5.0.1"; + }; + puma = { + dependencies = ["nio4r"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0qzq0c791kacv68hgk9zqsd1p7zx1y1rr9j10rn9yphibb8jj436"; + type = "gem"; + }; + version = "5.6.5"; + }; + pundit = { + dependencies = ["activesupport"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1wb03yzy1j41822rbfh9nn77im3zh1f5v8di05cd8rsrdpws542b"; + type = "gem"; + }; + version = "2.3.0"; + }; + raabro = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "10m8bln9d00dwzjil1k42i5r7l82x25ysbi45fwyv4932zsrzynl"; + type = "gem"; + }; + version = "1.4.0"; + }; + racc = { + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "09jgz6r0f7v84a7jz9an85q8vvmp743dqcsdm3z9c8rqcqv6pljq"; + type = "gem"; + }; + version = "1.6.2"; + }; + rack = { + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0qvp6h2abmlsl4sqjsvac03cr2mxq6143gbx4kq52rpazp021qsb"; + type = "gem"; + }; + version = "2.2.6.2"; + }; + rack-attack = { + dependencies = ["rack"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "049s3y3dpl6dn478g912y6f9nzclnnkl30psrbc2w5kaihj5szhq"; + type = "gem"; + }; + version = "6.6.1"; + }; + rack-cors = { + dependencies = ["rack"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0jvs0mq8jrsz86jva91mgql16daprpa3qaipzzfvngnnqr5680j7"; + type = "gem"; + }; + version = "1.1.1"; + }; + rack-oauth2 = { + dependencies = ["activesupport" "attr_required" "httpclient" "json-jwt" "rack"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1fknwsxz4429w1hndl6y30cmm2n34wmmaaj2hhp6jrm8ssfsfwjf"; + type = "gem"; + }; + version = "1.21.3"; + }; + rack-proxy = { + dependencies = ["rack"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1a62439xwn5v6hsl9s11hdk4wj58czhcbg7lminv23mnkc0ca147"; + type = "gem"; + }; + version = "0.7.6"; + }; + rack-test = { + dependencies = ["rack"]; + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0rjl709krgf499dhjdapg580l2qaj9d91pwzk8ck8fpnazlx1bdd"; + type = "gem"; + }; + version = "2.0.2"; + }; + rails = { + dependencies = ["actioncable" "actionmailbox" "actionmailer" "actionpack" "actiontext" "actionview" "activejob" "activemodel" "activerecord" "activestorage" "activesupport" "railties" "sprockets-rails"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1b7ggchi3d7pwzmj8jn9fhbazr5fr4dy304f0hz7kqbg23s9c1ym"; + type = "gem"; + }; + version = "6.1.7.2"; + }; + rails-controller-testing = { + dependencies = ["actionpack" "actionview" "activesupport"]; + groups = ["test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "151f303jcvs8s149mhx2g5mn67487x0blrf9dzl76q1nb7dlh53l"; + type = "gem"; + }; + version = "1.0.5"; + }; + rails-dom-testing = { + dependencies = ["activesupport" "nokogiri"]; + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1lfq2a7kp2x64dzzi5p4cjcbiv62vxh9lyqk2f0rqq3fkzrw8h5i"; + type = "gem"; + }; + version = "2.0.3"; + }; + rails-html-sanitizer = { + dependencies = ["loofah"]; + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0ygav4xyq943qqyhjmi3mzirn180j565mc9h5j4css59x1sn0cmz"; + type = "gem"; + }; + version = "1.5.0"; + }; + rails-i18n = { + dependencies = ["i18n" "railties"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "05mcgv748vppnm3fnml37wjy3dw61wj8vfw14ldaj1yx1bmkhb07"; + type = "gem"; + }; + version = "6.0.0"; + }; + rails-settings-cached = { + dependencies = ["rails"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0wyhyls0aqb1iw7mnaldg39w3mnbi3anmpbvb52rjwkpj2mchhnc"; + type = "gem"; + }; + version = "0.6.6"; + }; + railties = { + dependencies = ["actionpack" "activesupport" "method_source" "rake" "thor"]; + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0mm3nf3y715ln6v8k6g4351ggkr1bcwc5637vr979yw8vsmdi42k"; + type = "gem"; + }; + version = "6.1.7.2"; + }; + rainbow = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0smwg4mii0fm38pyb5fddbmrdpifwv22zv3d3px2xx497am93503"; + type = "gem"; + }; + version = "3.1.1"; + }; + rake = { + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "15whn7p9nrkxangbs9hh75q585yfn66lv0v2mhj6q6dl6x8bzr2w"; + type = "gem"; + }; + version = "13.0.6"; + }; + rdf = { + dependencies = ["link_header"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0799a5hqh7rjkqnbfb5cq62m2dx4zlnnag3xy1l4jyjywsk7v5kv"; + type = "gem"; + }; + version = "3.2.9"; + }; + rdf-normalize = { + dependencies = ["rdf"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1dngmsk9wg1vws56pl87dys0ns4bcn9arf8ip6zxa0gypr3ifq3m"; + type = "gem"; + }; + version = "0.5.1"; + }; + redcarpet = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1sg9sbf9pm91l7lac7fs4silabyn0vflxwaa2x3lrzsm0ff8ilca"; + type = "gem"; + }; + version = "3.6.0"; + }; + redis = { + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "03r9739q3vq38g456snf3rk9hadf955bs5im6qs6m69h19mrz2yw"; + type = "gem"; + }; + version = "4.5.1"; + }; + redis-namespace = { + dependencies = ["redis"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "154dfnrjpbv7fhwhfrcnp6jn9qv5qaj3mvlvbgkl7qy5qsknw71c"; + type = "gem"; + }; + version = "1.10.0"; + }; + redlock = { + dependencies = ["redis"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0xvjwfzq7rqj4k311kidwmv5app3i7glz4miys6ixqy6c8yylz3c"; + type = "gem"; + }; + version = "1.3.2"; + }; + regexp_parser = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0zjg29w5zvar7by1kqck3zilbdzm5iz3jp5d1zn3970krskfazh2"; + type = "gem"; + }; + version = "2.6.2"; + }; + request_store = { + dependencies = ["rack"]; + groups = ["default" "production"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "13ppgmsbrqah08j06bybd3cddv6dml79yzyjn7r8j1src78h98h7"; + type = "gem"; + }; + version = "1.5.1"; + }; + responders = { + dependencies = ["actionpack" "railties"]; + groups = ["default" "pam_authentication"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "14kjykc6rpdh24sshg9savqdajya2dislc1jmbzg91w9967f4gv1"; + type = "gem"; + }; + version = "3.0.1"; + }; + rexml = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "08ximcyfjy94pm1rhcx04ny1vx2sk0x4y185gzn86yfsbzwkng53"; + type = "gem"; + }; + version = "3.2.5"; + }; + rotp = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "11q7rkjx40yi6lpylgl2jkpy162mjw7mswrcgcax86vgpbpjx6i3"; + type = "gem"; + }; + version = "6.2.0"; + }; + rqrcode = { + dependencies = ["chunky_png" "rqrcode_core"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0s97q1rqmw7rzsdr500hr4f2k6s24n8qk1klciz5q94zvdrygx3p"; + type = "gem"; + }; + version = "2.1.2"; + }; + rqrcode_core = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "06ld6386hbdhy5h0k09axmgn424kavpc8f27k1vjhknjhbf8jjfg"; + type = "gem"; + }; + version = "1.2.0"; + }; + rspec-core = { + dependencies = ["rspec-support"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "118hkfw9b11hvvalr7qlylwal5h8dihagm9xg7k4gskg7587hca6"; + type = "gem"; + }; + version = "3.11.0"; + }; + rspec-expectations = { + dependencies = ["diff-lcs" "rspec-support"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "001ihayil7jpfxdlxlhakvz02kx0nk5m1w0bz6z8izdx0nc8bh53"; + type = "gem"; + }; + version = "3.11.0"; + }; + rspec-mocks = { + dependencies = ["diff-lcs" "rspec-support"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "07vagjxdm5a6s103y8zkcnja6avpl8r196hrpiffmg7sk83dqdsm"; + type = "gem"; + }; + version = "3.11.1"; + }; + rspec-rails = { + dependencies = ["actionpack" "activesupport" "railties" "rspec-core" "rspec-expectations" "rspec-mocks" "rspec-support"]; + groups = ["development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1cqw7bhj4a4rhh1x9i5gjm9r91ckhjyngw0zcr7jw2jnfis10d7l"; + type = "gem"; + }; + version = "5.1.2"; + }; + rspec-sidekiq = { + dependencies = ["rspec-core" "sidekiq"]; + groups = ["test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1spzw3sc2p0n9qfb89y1v8igd60y7c5z9w2hjqqbbgbyjvy0agp8"; + type = "gem"; + }; + version = "3.1.0"; + }; + rspec-support = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1c01iicvrjk6vv744jgh0y4kk9d0kg2rd2ihdyzvg5p06xm2fpzq"; + type = "gem"; + }; + version = "3.11.1"; + }; + rspec_junit_formatter = { + dependencies = ["rspec-core"]; + groups = ["test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "059bnq1gcwl9g93cqf13zpz38zk7jxaa43anzz06qkmfwrsfdpa0"; + type = "gem"; + }; + version = "0.6.0"; + }; + rubocop = { + dependencies = ["json" "parallel" "parser" "rainbow" "regexp_parser" "rexml" "rubocop-ast" "ruby-progressbar" "unicode-display_width"]; + groups = ["development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0f4n844yr2jrbddf79cam8qg41k2gkpyjjgd4zgbd8df1ijbld6p"; + type = "gem"; + }; + version = "1.44.1"; + }; + rubocop-ast = { + dependencies = ["parser"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1pdzabz95hv3z5sfbkfqa8bdybsfl13gv7rjb32v3ss8klq99lbd"; + type = "gem"; + }; + version = "1.24.1"; + }; + rubocop-capybara = { + dependencies = ["rubocop"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1h4qcjkz0365qlhi7y1ni94qj14k397cad566zygm20p15ypbp5v"; + type = "gem"; + }; + version = "2.17.0"; + }; + rubocop-performance = { + dependencies = ["rubocop" "rubocop-ast"]; + groups = ["development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1n7g0vg06ldjaq4f8c11c7yqy99zng1qdrkkk4kfziippy24yxnc"; + type = "gem"; + }; + version = "1.16.0"; + }; + rubocop-rails = { + dependencies = ["activesupport" "rack" "rubocop"]; + groups = ["development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1nxyifly45y7dfiaf0ql8aq7xykrg0sh1l7dxmn3sb9p2jd18140"; + type = "gem"; + }; + version = "2.17.4"; + }; + rubocop-rspec = { + dependencies = ["rubocop" "rubocop-capybara"]; + groups = ["development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1vmmin3ymgq7bhv2hl4pd0zpwawy709p816axc4vi67w61b4bij1"; + type = "gem"; + }; + version = "2.18.1"; + }; + ruby-progressbar = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "02nmaw7yx9kl7rbaan5pl8x5nn0y4j5954mzrkzi9i3dhsrps4nc"; + type = "gem"; + }; + version = "1.11.0"; + }; + ruby-saml = { + dependencies = ["nokogiri" "rexml"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1706dyk5jdma75bnl9rhmx8vgzjw12ixnj3y32inmpcgzgsvs76k"; + type = "gem"; + }; + version = "1.13.0"; + }; + ruby2_keywords = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1vz322p8n39hz3b4a9gkmz9y7a5jaz41zrm2ywf31dvkqm03glgz"; + type = "gem"; + }; + version = "0.0.5"; + }; + rufus-scheduler = { + dependencies = ["fugit"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1as4yrb8y5lq49div8p3vqgwrrhdgwnvx4m73y3712nmnlpx6cws"; + type = "gem"; + }; + version = "3.8.2"; + }; + safety_net_attestation = { + dependencies = ["jwt"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1khq0y5w7lf2b9a220298hphf3pakd216jc9a4x4a9pdwxs2vgln"; + type = "gem"; + }; + version = "0.4.0"; + }; + sanitize = { + dependencies = ["crass" "nokogiri"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1ga8yzc9zj45m92ycwnzhzahkwvc3dp3lym5m3f3880hs4jhh7l3"; + type = "gem"; + }; + version = "6.0.1"; + }; + scenic = { + dependencies = ["activerecord" "railties"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "04sd4jmgnwpilr3k061x87yyryya2mj15a8602fip49lfxza5548"; + type = "gem"; + }; + version = "1.7.0"; + }; + semantic_range = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1dlp97vg95plrsaaqj7x8l7z9vsjbhnqk4rw1l30gy26lmxpfrih"; + type = "gem"; + }; + version = "3.0.0"; + }; + sidekiq = { + dependencies = ["connection_pool" "rack" "redis"]; + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1z2fx4fzgnw4rzj3h1h4sk6qbkp7p2rdr58b2spxgkcsdzg0i5hh"; + type = "gem"; + }; + version = "6.5.8"; + }; + sidekiq-bulk = { + dependencies = ["sidekiq"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "08nyxzmgf742irafy3l4fj09d4s5pyvsh0dzlh8y4hl51rgkh4xv"; + type = "gem"; + }; + version = "0.2.0"; + }; + sidekiq-scheduler = { + dependencies = ["redis" "rufus-scheduler" "sidekiq" "tilt"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0ij0m4m4zi3ffn1csdrj4g96l4vpqlsw3rrgjxda9yqsq4ylf624"; + type = "gem"; + }; + version = "4.0.3"; + }; + sidekiq-unique-jobs = { + dependencies = ["brpoplpush-redis_script" "concurrent-ruby" "redis" "sidekiq" "thor"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "02f91b24hrrn688wqvxb13lwvcgqb7g9k3sxylnydd6v89wr8mcg"; + type = "gem"; + }; + version = "7.1.29"; + }; + simple-navigation = { + dependencies = ["activesupport"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1wc1rapwhqymcjfxmlgam4cvbyhnzfxada2damq88ij2p77pjz4q"; + type = "gem"; + }; + version = "4.4.0"; + }; + simple_form = { + dependencies = ["actionpack" "activemodel"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0z4df65w9qpri315lpvzazdxa9xb7yj0j3d77q06wf0jnpvw4mzs"; + type = "gem"; + }; + version = "5.2.0"; + }; + simplecov = { + dependencies = ["docile" "simplecov-html" "simplecov_json_formatter"]; + groups = ["test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "198kcbrjxhhzca19yrdcd6jjj9sb51aaic3b0sc3pwjghg3j49py"; + type = "gem"; + }; + version = "0.22.0"; + }; + simplecov-html = { + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0yx01bxa8pbf9ip4hagqkp5m0mqfnwnw2xk8kjraiywz4lrss6jb"; + type = "gem"; + }; + version = "0.12.3"; + }; + simplecov_json_formatter = { + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0a5l0733hj7sk51j81ykfmlk2vd5vaijlq9d5fn165yyx3xii52j"; + type = "gem"; + }; + version = "0.1.4"; + }; + smart_properties = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0jrqssk9qhwrpq41arm712226vpcr458xv6xaqbk8cp94a0kycpr"; + type = "gem"; + }; + version = "1.17.0"; + }; + sprockets = { + dependencies = ["concurrent-ruby" "rack"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "182jw5a0fbqah5w9jancvfmjbk88h8bxdbwnl4d3q809rpxdg8ay"; + type = "gem"; + }; + version = "3.7.2"; + }; + sprockets-rails = { + dependencies = ["actionpack" "activesupport" "sprockets"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1b9i14qb27zs56hlcc2hf139l0ghbqnjpmfi0054dxycaxvk5min"; + type = "gem"; + }; + version = "3.4.2"; + }; + sshkit = { + dependencies = ["net-scp" "net-ssh"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1szshiw7bzizi380z1hkdbwhjdaixb5bgbx7c3wf7970mjdashkd"; + type = "gem"; + }; + version = "1.21.2"; + }; + stackprof = { + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "02r3a3ny27ljj19bzmxscw2vlmk7sw1p4ppbl2i69g17khi0p4sw"; + type = "gem"; + }; + version = "0.2.23"; + }; + statsd-ruby = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "028136c463nbravckxb1qi5c5nnv9r6vh2cyhiry423lac4xz79n"; + type = "gem"; + }; + version = "1.5.0"; + }; + stoplight = { + dependencies = ["redlock"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0rmhhqvvrn7874r9cjf4wpv36vnxvxsrgb1kfgdk3dalg4rig7q6"; + type = "gem"; + }; + version = "3.0.1"; + }; + strong_migrations = { + dependencies = ["activerecord"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0yk45ri2rnp00x4mdsvwdzdd9yziqxj5v9sjk74nzw0y927y3m1w"; + type = "gem"; + }; + version = "0.7.9"; + }; + swd = { + dependencies = ["activesupport" "attr_required" "httpclient"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "12b3q2sw42nnilfb51nlqdv07f31vdv2j595kd99asnkw4cjlf5w"; + type = "gem"; + }; + version = "1.3.0"; + }; + temple = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "060zzj7c2kicdfk6cpnn40n9yjnhfrr13d0rsbdhdij68chp2861"; + type = "gem"; + }; + version = "0.8.2"; + }; + terminal-table = { + dependencies = ["unicode-display_width"]; + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "14dfmfjppmng5hwj7c5ka6qdapawm3h6k9lhn8zj001ybypvclgr"; + type = "gem"; + }; + version = "3.0.2"; + }; + terrapin = { + dependencies = ["climate_control"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0p18f05r0c5s70571gqig3z2ym74wx79s6rd45sprp207bqskzn9"; + type = "gem"; + }; + version = "0.6.0"; + }; + thor = { + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0inl77jh4ia03jw3iqm5ipr76ghal3hyjrd6r8zqsswwvi9j2xdi"; + type = "gem"; + }; + version = "1.2.1"; + }; + tilt = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "186nfbcsk0l4l86gvng1fw6jq6p6s7rc0caxr23b3pnbfb20y63v"; + type = "gem"; + }; + version = "2.0.11"; + }; + timeout = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0lnh0kr7f43m1cjzc2jvggfsl1rzsaj2rd3pn6vp7mcqliymzaza"; + type = "gem"; + }; + version = "0.3.1"; + }; + tpm-key_attestation = { + dependencies = ["bindata" "openssl" "openssl-signature_algorithm"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0kyq8z36953snxksv2xmc71znw7zykzis5r23hx3k06dij71vxsy"; + type = "gem"; + }; + version = "0.11.0"; + }; + tty-color = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0aik4kmhwwrmkysha7qibi2nyzb4c8kp42bd5vxnf8sf7b53g73g"; + type = "gem"; + }; + version = "0.6.0"; + }; + tty-cursor = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0j5zw041jgkmn605ya1zc151bxgxl6v192v2i26qhxx7ws2l2lvr"; + type = "gem"; + }; + version = "0.7.1"; + }; + tty-prompt = { + dependencies = ["pastel" "tty-reader"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1j4y8ik82azjxshgd4i1v4wwhsv3g9cngpygxqkkz69qaa8cxnzw"; + type = "gem"; + }; + version = "0.23.1"; + }; + tty-reader = { + dependencies = ["tty-cursor" "tty-screen" "wisper"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1cf2k7w7d84hshg4kzrjvk9pkyc2g1m3nx2n1rpmdcf0hp4p4af6"; + type = "gem"; + }; + version = "0.9.0"; + }; + tty-screen = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "18jr6s1cg8yb26wzkqa6874q0z93rq0y5aw092kdqazk71y6a235"; + type = "gem"; + }; + version = "0.8.1"; + }; + twitter-text = { + dependencies = ["idn-ruby" "unf"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1dnmp0bj3l01nbb52zby2c7hrazcdwfg846knkrjdfl0yfmv793z"; + type = "gem"; + }; + version = "3.1.0"; + }; + tzinfo = { + dependencies = ["concurrent-ruby"]; + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "16w2g84dzaf3z13gxyzlzbf748kylk5bdgg3n1ipvkvvqy685bwd"; + type = "gem"; + }; + version = "2.0.6"; + }; + tzinfo-data = { + dependencies = ["tzinfo"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0drm9pygji01pyimxq65ngdvgpn228g7fhffmrqw0xn7l2rdhclp"; + type = "gem"; + }; + version = "1.2022.7"; + }; + unf = { + dependencies = ["unf_ext"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0bh2cf73i2ffh4fcpdn9ir4mhq8zi50ik0zqa1braahzadx536a9"; + type = "gem"; + }; + version = "0.1.4"; + }; + unf_ext = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1yj2nz2l101vr1x9w2k83a0fag1xgnmjwp8w8rw4ik2rwcz65fch"; + type = "gem"; + }; + version = "0.0.8.2"; + }; + unicode-display_width = { + groups = ["default" "development" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1gi82k102q7bkmfi7ggn9ciypn897ylln1jk9q67kjhr39fj043a"; + type = "gem"; + }; + version = "2.4.2"; + }; + uniform_notifier = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1dfvqixshwvm82b9qwdidvnkavdj7s0fbdbmyd4knkl6l3j9xcwr"; + type = "gem"; + }; + version = "1.16.0"; + }; + validate_email = { + dependencies = ["activemodel" "mail"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1r1fz29l699arka177c9xw7409d1a3ff95bf7a6pmc97slb91zlx"; + type = "gem"; + }; + version = "0.1.6"; + }; + validate_url = { + dependencies = ["activemodel" "public_suffix"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0lblym140w5n88ijyfgcvkxvpfj8m6z00rxxf2ckmmhk0x61dzkj"; + type = "gem"; + }; + version = "1.0.15"; + }; + warden = { + dependencies = ["rack"]; + groups = ["default" "pam_authentication"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1l7gl7vms023w4clg02pm4ky9j12la2vzsixi2xrv9imbn44ys26"; + type = "gem"; + }; + version = "1.2.9"; + }; + webauthn = { + dependencies = ["android_key_attestation" "awrence" "bindata" "cbor" "cose" "openssl" "safety_net_attestation" "tpm-key_attestation"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1gs21q8krknb3db4s87l7xhzihp46ldsf6ql6689g2j0489l6da1"; + type = "gem"; + }; + version = "2.5.2"; + }; + webfinger = { + dependencies = ["activesupport" "httpclient"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "18jj50b44a471ig7hw1ax90wxaaz40acmrf6cm7m2iyshlffy53q"; + type = "gem"; + }; + version = "1.2.0"; + }; + webmock = { + dependencies = ["addressable" "crack" "hashdiff"]; + groups = ["test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1myj44wvbbqvv18ragv3ihl0h61acgnfwrnj3lccdgp49bgmbjal"; + type = "gem"; + }; + version = "3.18.1"; + }; + webpacker = { + dependencies = ["activesupport" "rack-proxy" "railties" "semantic_range"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0fh4vijqiq1h7w28llk67y9csc0m4wkdivrsl4fsxg279v6j5z3i"; + type = "gem"; + }; + version = "5.4.4"; + }; + webpush = { + dependencies = ["hkdf" "jwt"]; + groups = ["default"]; + platforms = []; + source = { + fetchSubmodules = false; + rev = "f14a4d52e201128b1b00245d11b6de80d6cfdcd9"; + sha256 = "1gz34809xwyaqprxmjdyvzsxc63rdnmxn8w44iqkhpi3dzmkacmp"; + type = "git"; + url = "https://github.com/ClearlyClaire/webpush.git"; + }; + version = "0.3.8"; + }; + websocket-driver = { + dependencies = ["websocket-extensions"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0a3bwxd9v3ghrxzjc4vxmf4xa18c6m4xqy5wb0yk5c6b9psc7052"; + type = "gem"; + }; + version = "0.7.5"; + }; + websocket-extensions = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0hc2g9qps8lmhibl5baa91b4qx8wqw872rgwagml78ydj8qacsqw"; + type = "gem"; + }; + version = "0.1.5"; + }; + wisper = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1rpsi0ziy78cj82sbyyywby4d0aw0a5q84v65qd28vqn79fbq5yf"; + type = "gem"; + }; + version = "2.0.1"; + }; + xorcist = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1dbbiy8xlcfvn9ais37xfb5rci4liwakkmxzbkp72wmvlgcrf339"; + type = "gem"; + }; + version = "1.1.3"; + }; + xpath = { + dependencies = ["nokogiri"]; + groups = ["default" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0bh8lk9hvlpn7vmi6h4hkcwjzvs2y0cmkk3yjjdr8fxvj6fsgzbd"; + type = "gem"; + }; + version = "3.2.0"; + }; + zeitwerk = { + groups = ["default" "development" "pam_authentication" "production" "test"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "09pqhdi6q4sqv0p1gnjpbcy4az0yv8hrpykjngdgh9qiqd87nfdv"; + type = "gem"; + }; + version = "2.6.6"; + }; +} + diff --git a/nix/fedi/mastodon/source.nix b/nix/fedi/mastodon/source.nix new file mode 100644 index 0000000..1daa150 --- /dev/null +++ b/nix/fedi/mastodon/source.nix @@ -0,0 +1,11 @@ +# This file was generated by pkgs.mastodon.updateScript. +{ fetchgit, applyPatches }: let + src = fetchgit { + url = "https://github.com/mastodon/mastodon.git"; + rev = "v4.1.2"; + sha256 = "18yzpc2rz9sa04y2sdxzsfkndbqqsfqvji47imwc3yj40l8hciws"; + }; +in applyPatches { + inherit src; + patches = []; +} diff --git a/nix/fedi/mastodon/version.nix b/nix/fedi/mastodon/version.nix new file mode 100644 index 0000000..d80cafc --- /dev/null +++ b/nix/fedi/mastodon/version.nix @@ -0,0 +1 @@ +"4.1.2" diff --git a/nix/s6.nix b/nix/s6.nix new file mode 100644 index 0000000..1da016e --- /dev/null +++ b/nix/s6.nix @@ -0,0 +1,10 @@ +{ pkgs, services, path }: + +let scandir = pkgs.linkFarm "service" services; +in { + start = pkgs.writeShellScript "s6-start" '' + cp -RL ${scandir} $MINIFEDI_RUN/${path} + chmod -R +w $MINIFEDI_RUN/${path} + exec ${pkgs.s6}/bin/s6-svscan $MINIFEDI_RUN/${path} + ''; +} diff --git a/nix/services.nix b/nix/services.nix new file mode 100644 index 0000000..db6bcf5 --- /dev/null +++ b/nix/services.nix @@ -0,0 +1,20 @@ +{ pkgs }: +let + instances = { + mastodon = import ./fedi/mastodon { + inherit pkgs; + name = "mastodon"; + }; + akkoma = import ./fedi/akkoma { + inherit pkgs; + name = "akkoma"; + }; + }; +in instances // { + postgres = import ./support-services/postgres { inherit pkgs; }; + redis = import ./support-services/redis { inherit pkgs; }; + nginx = import ./support-services/nginx { + inherit pkgs; + inherit instances; + }; +} diff --git a/nix/support-services/nginx/default.nix b/nix/support-services/nginx/default.nix new file mode 100644 index 0000000..02d2cdb --- /dev/null +++ b/nix/support-services/nginx/default.nix @@ -0,0 +1,49 @@ +{ pkgs, instances }: +let + config = pkgs.writeText "nginx.conf" '' + events {} + + pid $MINIFEDI_RUN/nginx/nginx.pid; + + daemon off; + + error_log stderr info; + + http { + include ${pkgs.nginx}/conf/mime.types; + + access_log $MINIFEDI_DATA/nginx/access.log; + + server { + listen 80; + listen [::]:80; + location / { return 301 https://$host$request_uri; } + } + + ${ + pkgs.lib.concatStrings (builtins.map (x: x.nginxConfig) + (pkgs.lib.attrsets.attrValues instances)) + } + } + ''; +in { + service = pkgs.linkFarm "nginx" { + run = pkgs.writeShellScript "run-nginx" '' + set -e + + PATH=${pkgs.gettext}/bin:$PATH + + mkdir -p $MINIFEDI_DATA/nginx + mkdir -p $MINIFEDI_RUN/nginx + + if ! [[ -e $MINIFEDI_DATA/nginx/fullchain.pem ]]; then + CAROOT=$MINIFEDI_CERT ${pkgs.mkcert}/bin/mkcert -cert-file $MINIFEDI_DATA/nginx/cert.pem -key-file $MINIFEDI_DATA/nginx/key.pem *.lvh.me + cat $MINIFEDI_DATA/nginx/cert.pem $MINIFEDI_CERT/rootCA.pem > $MINIFEDI_DATA/nginx/fullchain.pem + fi + + cd $MINIFEDI_DATA + cat ${config} | envsubst '$MINIFEDI_DATA $MINIFEDI_RUN' > $MINIFEDI_DATA/nginx/nginx.conf + ${pkgs.nginx}/bin/nginx -c $MINIFEDI_DATA/nginx/nginx.conf -e $MINIFEDI_DATA/nginx/error.log + ''; + }; +} diff --git a/nix/support-services/postgres/default.nix b/nix/support-services/postgres/default.nix new file mode 100644 index 0000000..36d9132 --- /dev/null +++ b/nix/support-services/postgres/default.nix @@ -0,0 +1,29 @@ +{ pkgs }: + +{ + service = pkgs.linkFarm "postgres" { + run = pkgs.writeShellScript "run-postgres-outer" '' + exec ${pkgs.s6}/bin/s6-notifyoncheck ${ + pkgs.writeShellScript "run-postgres-inner" '' + export PATH=${pkgs.gettext}/bin:$PATH + + mkdir -p $MINIFEDI_DATA/postgres + mkdir -p $MINIFEDI_RUN/postgres + cd $MINIFEDI_DATA/postgres + export PGDATA=$(pwd)/data + [[ -e $PGDATA ]] || ${pkgs.postgresql}/bin/initdb + cat ${./postgresql.conf} | envsubst > $PGDATA/postgresql.conf + exec ${pkgs.postgresql}/bin/postgres + '' + } + ''; + + data = pkgs.linkFarm "data" { + check = pkgs.writeShellScript "check-postgres" '' + ${pkgs.postgresql}/bin/pg_isready -h $MINIFEDI_RUN/postgres + ''; + }; + + notification-fd = pkgs.writeText "notification-fd" "3"; + }; +} diff --git a/nix/support-services/postgres/postgresql.conf b/nix/support-services/postgres/postgresql.conf new file mode 100644 index 0000000..715c26d --- /dev/null +++ b/nix/support-services/postgres/postgresql.conf @@ -0,0 +1,2 @@ +listen_addresses = '' +unix_socket_directories = '$MINIFEDI_RUN/postgres/' \ No newline at end of file diff --git a/nix/support-services/redis/default.nix b/nix/support-services/redis/default.nix new file mode 100644 index 0000000..4da9158 --- /dev/null +++ b/nix/support-services/redis/default.nix @@ -0,0 +1,19 @@ +{ pkgs }: +let + config = pkgs.writeText "redis.conf" '' + port 0 + protected-mode yes + ''; +in { + service = pkgs.linkFarm "nginx" { + run = pkgs.writeShellScript "run-nginx" '' + set -e + + mkdir -p $MINIFEDI_DATA/redis + mkdir -p $MINIFEDI_RUN/redis + + cd $MINIFEDI_RUN/redis + ${pkgs.redis}/bin/redis-server ${config} --unixsocket $MINIFEDI_RUN/redis/redis.sock + ''; + }; +} diff --git a/nix/util.nix b/nix/util.nix new file mode 100644 index 0000000..e69de29