├── .gitignore ├── .is-minifedi ├── LICENSE ├── README.md ├── TODO ├── config.nix ├── docs ├── INTERNALS.md └── SOFTWARE.md ├── flake.lock ├── flake.nix ├── minifedi ├── nix ├── fedi │ ├── akkoma │ │ └── default.nix │ ├── gotosocial │ │ ├── build.nix │ │ └── default.nix │ └── mastodon │ │ ├── build.nix │ │ ├── default.nix │ │ └── mk-version │ │ ├── default.nix │ │ └── mk-version.sh ├── s6.nix ├── services.nix ├── support-services │ ├── mitmproxy │ │ └── default.nix │ ├── nginx │ │ └── default.nix │ ├── postgres │ │ ├── default.nix │ │ └── postgresql.conf │ └── redis │ │ └── default.nix └── util.nix └── versions └── mastodon ├── glitch-a004718 ├── gemset.nix ├── name.nix ├── source.nix └── yarn-hash.nix └── mastodon-4.1.4 ├── gemset.nix ├── name.nix ├── source.nix └── yarn-hash.nix /.gitignore: -------------------------------------------------------------------------------- 1 | data 2 | cert 3 | .vscode 4 | -------------------------------------------------------------------------------- /.is-minifedi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gaelan/minifedi/120c1f3aeab0285550713e989361a88074a28979/.is-minifedi -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023 Gaelan Steele 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | --- 23 | 24 | Minifedi's build scripts for Mastodon, Akkoma, and GoToSocial are derived from 25 | Nixpkgs, released under the following license: 26 | 27 | Copyright (c) 2003-2023 Eelco Dolstra and the Nixpkgs/NixOS contributors 28 | 29 | Permission is hereby granted, free of charge, to any person obtaining 30 | a copy of this software and associated documentation files (the 31 | "Software"), to deal in the Software without restriction, including 32 | without limitation the rights to use, copy, modify, merge, publish, 33 | distribute, sublicense, and/or sell copies of the Software, and to 34 | permit persons to whom the Software is furnished to do so, subject to 35 | the following conditions: 36 | 37 | The above copyright notice and this permission notice shall be 38 | included in all copies or substantial portions of the Software. 39 | 40 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 41 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 42 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 43 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 44 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 45 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 46 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 47 | 48 | --- 49 | 50 | Minifedi contains nginx configuration file templates derived from configuration 51 | files provided by the Mastodon, Akkoma, and GoToSocial projects, all of which 52 | are licensed under AGPLv3. My position is that these configuration files are 53 | insufficiently creative to be copyrightable, but this is not legal advice. 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Minifedi 2 | 3 | Minifedi is a tool to quickly spin up a bunch of ActivityPub servers for local testing. 4 | 5 | Minifedi is entirely self-contained and needs no changes to your system configuration besides installing Nix; you can install it with a git clone, delete it with `rm -rf`, and your system will be exactly the way it was before. 6 | 7 | ## System Requirements 8 | 9 | - macOS or Linux (any distribution). Tested on x86_64, aarch64 should work. Other architectues probably won't due to poor Nix support, unfortunately. 10 | - Windows isn't natively supported, but might work under WSL. 11 | - A recent version of [Nix](https://nixos.org). 12 | - This doesn't mean you need to be on NixOS; Nix can be installed on more or less any distribution, and is happy to do its own thing without interfering with your system. 13 | - ~4GB free on disk. 14 | - ~4GB free in /tmp. 15 | - On many Linux distributions, this means you'll need ~8GB of RAM. 16 | - You might be able to get away with less if you disable GoToSocial. 17 | - Ports 80 and 443 free. 18 | - This is required because some (all) fedi software is only willing to federate with servers on the standard ports. 19 | - macOS lets any user listen on these ports. On Linux, Minifedi will use sudo to gain the capability required to listen on these ports, then immediately switch back to your user and relinquish all other capabilties. 20 | 21 | ## Warnings 22 | 23 | Minifedi is very new software. I'm fairly sure it won't break your system (it's designed very specifically to not do anything that possibly could) but it might not work either. 24 | 25 | Minifedi is designed for testing only. The assumption is you'll happily throw out everything stored in it when you're done. Don't store anything you care about in an instance run by Minifedi. 26 | 27 | ## Getting Started 28 | 29 | Minifedi's goal is to "just work" on every machine. If the instructions below fail for you, please file an issue; I'll fix it if at all possible. 30 | 31 | 1. Install [Nix](https://nixos.org), if you haven't. 32 | - If you install Nix through your OS package manager, you may need to add yourself to the `nix-users` group and/or ensure the `nix-daemon` service is enabled. 33 | 2. ``` 34 | git clone https://github.com/Gaelan/minifedi.git 35 | cd minifedi 36 | ``` 37 | 3. If you'd like, edit `config.nix` to customize which instances you get. By default, you get one each of Mastodon, Glitch, Akkoma, and GoToSocial, but you're welcome to disable some or run multiple copies of the same type. 38 | 4. `./minifedi start` 39 | 5. Wait for stuff to build then start up; this should take 20-30 minutes. 40 | 6. **Semi-optional:** Run `./minifedi install-cert` in another terminal to add Minifedi's root to your system certificate store. 41 | - This is a change to your system configuration, albeit a small one; as such, we'd like to make it optional. Currently, there are a few caveats if you don't: 42 | - You'll see HTTPS errors in the browser. These can usually be clicked through; if they can't (possible after deleting `data` with software that enforces HSTS, like Mastodon), clear your browser's data for lvh.me and try again. 43 | - GoToSocial won't be able to federate on macOS. (It will on Linux, I think, but I haven't tested this.) 44 | 7. Your instances should be running and accessible at INSTANCENAME.lvh.me (e.g. https://mastodon.lvh.me). 45 | 46 | Each instance is created by default with five users: 47 | 48 | - username `a`, email `a@example.com`, password `MiniFediA1!`, admin 49 | - username `b`, email `b@example.com`, password `MiniFediB1!` 50 | - username `c`, email `c@example.com`, password `MiniFediC1!` 51 | - username `d`, email `d@example.com`, password `MiniFediD1!` 52 | - username `e`, email `e@example.com`, password `MiniFediE1!` 53 | 54 | Enjoy your testing! 55 | 56 | ## Supported Software 57 | 58 | Minifedi currently supports the following: 59 | 60 | - Mastodon 61 | - Akkoma 62 | - GoToSocial 63 | 64 | Forks of the above should work fine as well, as long as they haven't changed anything about the build, installation, or configuration process. 65 | 66 | ## Mitmproxy Integration 67 | 68 | Minifedi has built-in integration with [mitmproxy](https://mitmproxy.org), allowing you to see a lot of every HTTP request an instance sends to another instance. To use this, set `mitmproxy = true;` in your `config.nix`, start minifedi, then go to `http://localhost:8081`. The mitmproxy integration currently requires ports 8080 and 8081 to be open. 69 | 70 | ## How do I… 71 | 72 | ### Reset Minifedi, restoring every instance to its default state? 73 | 74 | ```sh 75 | rm -r data/ 76 | ``` 77 | 78 | ### Use a different version (including a fork) of Mastodon? 79 | 80 | ```sh 81 | ./minifedi mk-mastodon NAME REPO COMMIT-OR-TAG 82 | # eg 83 | ./minifedi mk-mastodon mastodon-4.1.4 https://github.com/Mastodon/Mastodon.git v4.1.4 84 | ``` 85 | 86 | This'll create a directory in `versions/mastodon`, which you can then refer to from your `config.nix`. 87 | 88 | Custom versions for Akkoma and GoToSocial aren't supported yet. 89 | 90 | ### Use Minifedi to test some fedi software I'm hacking on locally? 91 | 92 | There isn't a good solution for this yet, but the plan is that you'll run your software locally however you usually do, with Minifedi's nginx running in front to serve it from a domain accessible to the other instances. 93 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | - figure out how to support local source, and document this 2 | - separate out config into separate file, and document this 3 | - support custom source for akkoma and gts 4 | - data generation? 5 | -------------------------------------------------------------------------------- /config.nix: -------------------------------------------------------------------------------- 1 | { types }: 2 | 3 | { 4 | instances = [ 5 | { 6 | name = "mastodon"; 7 | type = types.mastodon; 8 | version = ./versions/mastodon/mastodon-4.1.4; 9 | } 10 | { 11 | name = "glitch"; 12 | type = types.mastodon; 13 | version = ./versions/mastodon/glitch-a004718; 14 | } 15 | { 16 | name = "akkoma"; 17 | type = types.akkoma; 18 | } 19 | { 20 | name = "gotosocial"; 21 | type = types.gotosocial; 22 | } 23 | ]; 24 | 25 | # Enable logging of all requests between instances. Requires ports 8080 and 26 | # 8081 open. 27 | mitmproxy = false; 28 | } 29 | -------------------------------------------------------------------------------- /docs/INTERNALS.md: -------------------------------------------------------------------------------- 1 | # Minifedi internals 2 | 3 | Quick brain dump of how this all works: 4 | 5 | We run everything as the user, with no containers, VMs, etc. This means we can be lightweight, work natively on both macOS and Linux, and lose many points of failure. 6 | 7 | We use Nix to manage all dependencies and build copies of all the fedi software. We use [s6](https://skarnet.org/software/s6/index.html) to orchestrate all the processes. 8 | 9 | We run one central copy of Postgres and Redis, which all instances use. 10 | 11 | We also run one copy of Nginx, which serves as a proxy in front of every instance. This nginx instance listens on ports 80/443, as some (all?) fedi software won't federate with stuff running anywhere else. We use the domain `lvh.me`, which resolves all subdomains to `127.0.0.1`, to give each instance a distinct hostname. 12 | 13 | To minimize moving parts (what happens if a port is taken?), whenever possible we prefer Unix sockets over TCP for everything but the user-facing (and other-instance-facing) Nginx server. In cases where this isn't supported (GoToSocial's HTTP interface) we choose a deterministic random port based on the instance name and hope it's open. 14 | 15 | We use [mkcert](https://github.com/FiloSottile/mkcert) to generate a root CA, which is then used to sign a wildcard certificate used by Nginx to serve each instance. Each instance is then configured to trust our root, or if that's not possible (Akkoma), disable certificate checking altogether. This cert can optionally be added to the system trust store so the user can access instances through browsers, or they can just click through the HTTPS warning if they'd rather not mess with their settings. 16 | 17 | ## Custom version support 18 | 19 | We allow the user to use any commit of any git repo as the source for a Mastodon instance. How this works is a little tricky, as Nix (especially with language-specifc package managers in the mix) requires several hashes and other bits of metadata to successfully build a project. To abstract this from the user, we provide a `mk-mastodon` script that fetches all this metadata and crates a `versions/mastodon` subdirectory with everything needed to build that version. 20 | 21 | The plan is eventually to support something similar for GoToSocial and Akkoma. For GoToSocial, it should be straightforward enough; it's just need to get done. Akkoma is going to be a little more tricky, as the Nixpkgs build script for Akkoma (which we use) hardcodes various details about its precise dependencies; the easy option would be to only support forks of the latest Akkoma version with no substantial dependency versions, but it'd be nice to do better. 22 | -------------------------------------------------------------------------------- /docs/SOFTWARE.md: -------------------------------------------------------------------------------- 1 | # A survey of fedi software 2 | 3 | …with an eye to features relevant to running it under Minifedi. 4 | 5 | ## Supported 6 | 7 | | Name | Languages | Storage | Optional | Storage socket? | Listen socket? | Customize CA? | Proxied federation? | Make admins? | API? | 8 | | ---------- | ------------------- | ------------------ | ------------------------------- | --------------- | -------------- | --------------------- | ------------------- | ------------------ | ----- | 9 | | Mastodon | Ruby + JS (yarn1) | Postgres + Redis | Elasticsearch | Yes | Yes | Yes (Nixpkgs OpenSSL) | Yes | CLI (no passwords) | Masto | 10 | | Akkoma | Elixir + JS (yarn1) | Postgres | RUM (pg extension), Mellisearch | Yes | Yes | Insecure only | Yes | CLI | Masto | 11 | | GoToSocial | Go + JS (yarn1) | SQLite or Postgres | - | Yes | No | Linux only | Yes | Yes | Masto | 12 | 13 | ## Not yet supported 14 | 15 | | Name | Languages | Storage | Optional | Storage socket? | Listen socket? | Customize CA? | Proxied federation? | Make admins? | API? | 16 | | ------------------ | --------------------------- | ------------------------- | ----------------- | --------------- | ----------------- | ---------------------------------- | ------------------- | ------------------------ | -------------- | 17 | | Misskey | JS (pnpm) | Postgres + Redis | Mellisearch | Probably | Yes | `NODE_EXTRA_CA_CERTS` | Yes | first user | Keylike | 18 | | Foundkey | JS (yarn6) | Postgres + Redis | Mellisearch | Probably | No | `NODE_EXTRA_CA_CERTS` | Yes | first user | Keylike | 19 | | Firefish/Iceshrimp | JS (pnpm) + Rust | Postgres + Redis | many choices | Probably | No | `NODE_EXTRA_CA_CERTS` | Yes | first user | Masto, Keylike | 20 | | Lemmy | Rust + JS (yarn1) | Postgres | - | Probably | No | Linux only unless Nix patches smth | Yes (HTTP_PROXY) | one in config | Lemmy | 21 | | kbin | PHP (Composer) + JS (yarn1) | Postgres + Redis | RabbitMQ, Mercure | Yes | Yes (FastCGI) | Probably (libcurl) | Yes (HTTP_PROXY) | CLI | Kbin | 22 | | PeerTube | JS (yarn1) | Postgres + Redis | - | Probably | no | `NODE_EXTRA_CA_CERTS` | Yes (HTTP_PROXY) | one (named root) | PeerTube | 23 | | Pixelfed | PHP (Composer) | MySQL or Postgres + Redis | - | Yes | Yes (FastCGI) | Probably (libcurl) | Yes (HTTP_PROXY) | CLI | Masto | 24 | | Takahe | Python (pip) | Postgres | - | Probably | Probably (Django) | Yes | Yes (HTTP_PROXY) | email or interactive CLI | Masto | 25 | | Bookwyrm | Python (pip) | Postgres | - | Unclear | Probably (Django) | Yes | Yes (HTTP_PROXY) | CLI-web interactive | - | 26 | | honk | Go | SQLite | - | SQLite only | Yes | Linux only | Yes (HTTP_PROXY) | CLI | honk | 27 | | Friendica? | 28 | | GNU Social? | 29 | | Writefreely? | 30 | | Wordpress? | 31 | | Plume? | 32 | | Mobilizion? | 33 | | Hubzilla? | 34 | | Funkwhale? | 35 | | Owncast? | 36 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1689068808, 9 | "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1688221086, 24 | "narHash": "sha256-cdW6qUL71cNWhHCpMPOJjlw0wzSRP0pVlRn2vqX/VVg=", 25 | "owner": "NixOS", 26 | "repo": "nixpkgs", 27 | "rev": "cd99c2b3c9f160cd004318e0697f90bbd5960825", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "id": "nixpkgs", 32 | "type": "indirect" 33 | } 34 | }, 35 | "root": { 36 | "inputs": { 37 | "flake-utils": "flake-utils", 38 | "nixpkgs": "nixpkgs" 39 | } 40 | }, 41 | "systems": { 42 | "locked": { 43 | "lastModified": 1681028828, 44 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 45 | "owner": "nix-systems", 46 | "repo": "default", 47 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 48 | "type": "github" 49 | }, 50 | "original": { 51 | "owner": "nix-systems", 52 | "repo": "default", 53 | "type": "github" 54 | } 55 | } 56 | }, 57 | "root": "root", 58 | "version": 7 59 | } 60 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs.flake-utils.url = "github:numtide/flake-utils"; 3 | 4 | outputs = { self, flake-utils, nixpkgs }: 5 | flake-utils.lib.eachDefaultSystem (system: 6 | let pkgs = nixpkgs.legacyPackages.${system}; 7 | in { 8 | apps.start = let 9 | config = import ./config.nix { 10 | types = { 11 | mastodon = import ./nix/fedi/mastodon; 12 | akkoma = import ./nix/fedi/akkoma; 13 | gotosocial = import ./nix/fedi/gotosocial; 14 | }; 15 | }; 16 | s6 = (import ./nix/s6.nix { 17 | inherit pkgs; 18 | services = pkgs.lib.attrsets.mapAttrs (_: v: v.service) 19 | (import ./nix/services.nix { inherit pkgs config; }); 20 | path = "service"; 21 | }); 22 | in { 23 | type = "app"; 24 | program = let 25 | script = pkgs.writeShellScript "minifedi" '' 26 | oldpath=$PATH 27 | export PATH=${pkgs.gnugrep}/bin:${pkgs.gnused}/bin:${pkgs.coreutils}/bin 28 | 29 | if ! [[ -e .is-minifedi ]]; then 30 | echo "please run this from the minifedi directory" 31 | exit 1 32 | fi 33 | mkdir -p data 34 | mkdir -p cert 35 | rm -rf data/run 36 | mkdir data/run 37 | mkdir -p data/logs 38 | ${if pkgs.stdenv.isLinux then 39 | "export LOCALE_ARCHIVE=${pkgs.glibcLocales}/lib/locale/locale-archive" 40 | else 41 | ""} 42 | export MINIFEDI_CERT=$(pwd)/cert 43 | export MINIFEDI_DATA=$(pwd)/data 44 | export MINIFEDI_RUN=$(pwd)/data/run 45 | export MINIFEDI_LOG=$(pwd)/data/logs 46 | 47 | echo "Minifedi is starting! Once they're up, instances will be visible at:" 48 | ${pkgs.lib.strings.concatStrings (builtins.map (i: '' 49 | echo "* https://${i.name}.lvh.me" 50 | '') config.instances)} 51 | echo "Instance logs are in ./data/logs." 52 | ${if config.mitmproxy then '' 53 | echo "View requests between instances at http://localhost:8081." 54 | '' else 55 | ""} 56 | 57 | ${if pkgs.stdenv.isLinux then '' 58 | echo "=> You'll probably get prompted for a sudo password now. This is just so we can bind to port 80/443; we will acquire cap_net_bind_service then switch back to being $USER." 59 | exec $(PATH=$oldpath which sudo) -E ${pkgs.libcap}/bin/capsh --keep=1 --user="$USER" --inh='cap_net_bind_service' --addamb='cap_net_bind_service' -- -c ${s6.start} 60 | '' else '' 61 | exec ${s6.start} 62 | ''} 63 | ''; 64 | in "${script}"; 65 | }; 66 | apps.install-cert = { 67 | type = "app"; 68 | program = let 69 | script = pkgs.writeShellScript "minifedi-install-cert" '' 70 | if ! [[ -e .is-minifedi ]]; then 71 | echo "please run this from the minifedi directory" 72 | exit 1 73 | fi 74 | 75 | mkdir -p cert 76 | export MINIFEDI_CERT=$(pwd)/cert 77 | 78 | CAROOT=$MINIFEDI_CERT ${pkgs.mkcert}/bin/mkcert -install 79 | ''; 80 | in "${script}"; 81 | }; 82 | apps.mk-mastodon = { 83 | type = "app"; 84 | program = "${ 85 | import ./nix/fedi/mastodon/mk-version { inherit pkgs; } 86 | }/bin/mk-mastodon"; 87 | }; 88 | }); 89 | } 90 | -------------------------------------------------------------------------------- /minifedi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | if ! type "nix" > /dev/null; then 4 | echo "Minifedi requires Nix. Please install it from your package manager, or following the instructions at https://nixos.org/download.html." 5 | exit 1 6 | fi 7 | 8 | subcommand=$1 9 | shift 10 | 11 | if [ -z "$subcommand" ]; then 12 | echo "subcommand required: start, install-cert, mk-mastodon" 13 | exit 1 14 | fi 15 | 16 | nix --extra-experimental-features "flakes nix-command" run .#$subcommand -- $@ 17 | -------------------------------------------------------------------------------- /nix/fedi/akkoma/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs, name, host, users, proxy, ... }: 2 | let 3 | env = { 4 | MIX_ENV = "prod"; 5 | ERL_EPMD_ADDRESS = "127.0.0.1"; 6 | }; 7 | 8 | static = pkgs.linkFarm "static" { 9 | frontends = pkgs.linkFarm "frontends" { 10 | akkoma = 11 | pkgs.linkFarm "pleroma" { stable = pkgs.akkoma-frontends.akkoma-fe; }; 12 | # admin = 13 | # pkgs.linkFarm "admin" { stable = pkgs.akkoma-frontends.admin-fe; }; 14 | }; 15 | }; 16 | 17 | config = pkgs.writeText "config.exs" '' 18 | import Config 19 | 20 | config :pleroma, Pleroma.Web.Endpoint, 21 | url: [host: "${host}", scheme: "https", port: 443], 22 | http: [ip: {:local, "$MINIFEDI_RUN/${name}/akkoma.sock"}, port: 0], 23 | secret_key_base: "$SECRET_KEY_BASE", 24 | live_view: [signing_salt: "$LIVE_VIEW_SIGNING_SALT"], 25 | signing_salt: "$SIGNING_SALT" 26 | 27 | config :pleroma, :instance, 28 | name: "${name}", 29 | email: "admin@${name}.example", 30 | notify_email: "noreply@${name}.example", 31 | limit: 5000, 32 | registrations_open: true 33 | 34 | config :pleroma, :media_proxy, 35 | enabled: false, 36 | redirect_on_failure: true 37 | 38 | config :pleroma, Pleroma.Repo, 39 | adapter: Ecto.Adapters.Postgres, 40 | username: "${name}", 41 | password: "", 42 | database: "${name}", 43 | socket_dir: "$MINIFEDI_RUN/postgres/" 44 | 45 | # Configure web push notifications 46 | config :web_push_encryption, :vapid_details, 47 | subject: "mailto:a@${name}.example", 48 | public_key: "$WEB_PUSH_PUBLIC_KEY", 49 | private_key: "$WEB_PUSH_PRIVATE_KEY" 50 | 51 | config :pleroma, :database, rum_enabled: false 52 | config :pleroma, :instance, static_dir: "${static}" 53 | config :pleroma, Pleroma.Uploaders.Local, uploads: "$MINIFEDI_DATA/${name}/uploads" 54 | 55 | config :joken, default_signer: "$JWT_SECRET" 56 | 57 | config :pleroma, configurable_from_database: false 58 | 59 | config :tzdata, :data_dir, "$MINIFEDI_DATA/${name}/tzdata" 60 | 61 | config :pleroma, :frontends, 62 | primary: %{ 63 | "name" => "akkoma", 64 | "ref" => "stable" 65 | } 66 | 67 | config :pleroma, :http, 68 | adapter: [ 69 | pools: %{ 70 | default: [ 71 | conn_opts: [ 72 | transport_opts: [ 73 | verify: :verify_none 74 | # cacertfile: "$MINIFEDI_CERT/rootCA.pem" 75 | # ^ won't work if Erlang finds the system cert store 76 | ] 77 | ] 78 | ] 79 | } 80 | ] 81 | 82 | ${if proxy != null then '' 83 | config :pleroma, :http, 84 | proxy_url: "${proxy}" 85 | '' else 86 | ""} 87 | ''; 88 | 89 | path = pkgs.lib.strings.concatStrings (builtins.map (x: "${x}/bin:") [ 90 | pkgs.akkoma 91 | pkgs.elixir 92 | pkgs.s6 93 | pkgs.postgresql 94 | # used by pleroma shell script for rpc 95 | pkgs.gawk 96 | # envsubst 97 | pkgs.gettext 98 | # used to generate keys 99 | pkgs.openssl 100 | ]); 101 | in { 102 | service = pkgs.linkFarm name [{ 103 | name = "run"; 104 | path = pkgs.writeShellScript "run-${name}" '' 105 | set -e 106 | 107 | export PATH=${path}$PATH 108 | 109 | cd ${pkgs.akkoma} 110 | 111 | data=$MINIFEDI_DATA/${name} 112 | run=$MINIFEDI_RUN/${name} 113 | postgres=$MINIFEDI_RUN/postgres 114 | 115 | mkdir -p $data 116 | mkdir -p $data/uploads 117 | mkdir -p $data/tzdata 118 | mkdir -p $run 119 | 120 | exec >$MINIFEDI_LOG/${name}.log 2>$MINIFEDI_LOG/${name}.log 121 | 122 | s6-svwait -U $MINIFEDI_RUN/service/postgres 123 | 124 | ${pkgs.lib.strings.concatStrings (pkgs.lib.attrsets.mapAttrsToList 125 | (k: v: '' 126 | export ${k}=${v} 127 | '') env)} 128 | 129 | if ! [ -e $data/setup-done ]; then 130 | openssl rand -base64 64 | head -c 64 > $data/secret_key_base 131 | openssl rand -base64 64 | head -c 64 > $data/jwt_secret 132 | openssl rand -base64 8 | head -c 8 > $data/signing_salt 133 | openssl rand -base64 8 | head -c 8 > $data/live_view_signing_salt 134 | openssl ecparam -genkey -name prime256v1 | openssl ec -out $data/web_push_keypair.pem 135 | openssl ec -in $data/web_push_keypair.pem -pubout -out $data/web_push_public_key 136 | openssl ec -in $data/web_push_keypair.pem -out $data/web_push_private_key 137 | fi 138 | 139 | export SECRET_KEY_BASE=$(cat $data/secret_key_base) 140 | export JWT_SECRET=$(cat $data/jwt_secret) 141 | export SIGNING_SALT=$(cat $data/jwt_secret) 142 | export LIVE_VIEW_SIGNING_SALT=$(cat $data/live_view_signing_salt) 143 | export WEB_PUSH_PRIVATE_KEY=$(cat $data/web_push_private_key) 144 | export WEB_PUSH_PUBLIC_KEY=$(cat $data/web_push_public_key) 145 | 146 | export RELEASE_COOKIE=$(openssl rand -base64 64) 147 | 148 | cat ${config} | envsubst > $data/config.exs 149 | export AKKOMA_CONFIG_PATH=$data/config.exs 150 | 151 | # elixir takes 2 sigints to exit if it has something on stdin 152 | exec $MINIFEDI_LOG/${name}.log 2>$MINIFEDI_LOG/${name}.log 45 | 46 | s6-svwait -U $MINIFEDI_RUN/service/postgres 47 | 48 | ${pkgs.lib.strings.concatStrings (pkgs.lib.attrsets.mapAttrsToList 49 | (k: v: '' 50 | export ${k}=${v} 51 | '') env)} 52 | 53 | export GTS_DB_ADDRESS=$postgres 54 | export GTS_STORAGE_LOCAL_BASE_PATH=$data/storage 55 | export SSL_CERT_FILE=$MINIFEDI_CERT/rootCA.pem 56 | export NIX_SSL_CERT_FILE=$MINIFEDI_CERT/rootCA.pem 57 | ${if proxy != null then "export HTTP_PROXY=${proxy}" else ""} 58 | ${if proxy != null then "export HTTPS_PROXY=${proxy}" else ""} 59 | ${if proxy != null then "export http_proxy=${proxy}" else ""} 60 | ${if proxy != null then "export https_proxy=${proxy}" else ""} 61 | 62 | env 63 | 64 | if ! [ -e $data/setup-done ]; then 65 | createuser -h$postgres ${name} 66 | createdb -h$postgres ${name} -O${name} 67 | 68 | ${ 69 | pkgs.lib.strings.concatStrings (builtins.map (u: 70 | "gotosocial --config-path ${config} admin account create --username ${u.name} --email ${u.email} --password ${u.password};${ 71 | if u.admin then 72 | "gotosocial --config-path ${config} admin account promote --username ${u.name};" 73 | else 74 | "" 75 | }") users) 76 | } 77 | 78 | touch $data/setup-done 79 | fi 80 | 81 | cd ${pkgs.gotosocial}/share/gotosocial 82 | 83 | exec gotosocial --config-path ${config} server start 84 | ''; 85 | }]; 86 | nginxConfig = '' 87 | server { 88 | listen 443; 89 | listen [::]:443; 90 | server_name ${host}; 91 | location / { 92 | # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758 93 | proxy_pass http://127.0.0.1:${toString port}; 94 | proxy_set_header Host $host; 95 | proxy_set_header Upgrade $http_upgrade; 96 | proxy_set_header Connection "upgrade"; 97 | proxy_set_header X-Forwarded-For $remote_addr; 98 | proxy_set_header X-Forwarded-Proto $scheme; 99 | } 100 | client_max_body_size 40M; 101 | } 102 | ''; 103 | } 104 | -------------------------------------------------------------------------------- /nix/fedi/mastodon/build.nix: -------------------------------------------------------------------------------- 1 | { lib, stdenv, nodejs-slim, mkYarnPackage, fetchFromGitHub, bundlerEnv 2 | , nixosTests, yarn, callPackage, imagemagick, ffmpeg, file, ruby_3_0 3 | , writeShellScript, fetchYarnDeps, fixup_yarn_lock, brotli 4 | 5 | , versionDef }: 6 | 7 | stdenv.mkDerivation rec { 8 | name = import "${versionDef}/name.nix"; 9 | 10 | # Using overrideAttrs on src does not build the gems and modules with the overridden src. 11 | # Putting the callPackage up in the arguments list also does not work. 12 | src = callPackage "${versionDef}/source.nix" { }; 13 | 14 | mastodonGems = bundlerEnv { 15 | name = "gems-${name}"; 16 | ruby = ruby_3_0; 17 | gemdir = src; 18 | # hack: bundix doesn't properly handle deps in non-default groups, so we get 19 | # rpam (which depends on linux-pam) even though pam_authentication isn't 20 | # enabled. just patch it out 21 | gemset = lib.attrsets.filterAttrs 22 | (k: v: k != "rpam2" && k != "devise_pam_authenticatable2") 23 | (import (versionDef + "/gemset.nix")); 24 | # This fix (copied from https://github.com/NixOS/nixpkgs/pull/76765) replaces the gem 25 | # symlinks with directories, resolving this error when running rake: 26 | # /nix/store/451rhxkggw53h7253izpbq55nrhs7iv0-mastodon-gems-3.0.1/lib/ruby/gems/2.6.0/gems/bundler-1.17.3/lib/bundler/settings.rb:6:in `': uninitialized constant Bundler::Settings (NameError) 27 | postBuild = '' 28 | for gem in "$out"/lib/ruby/gems/*/gems/*; do 29 | cp -a "$gem/" "$gem.new" 30 | rm "$gem" 31 | # needed on macOS, otherwise the mv yields permission denied 32 | chmod +w "$gem.new" 33 | mv "$gem.new" "$gem" 34 | done 35 | ''; 36 | }; 37 | 38 | mastodonModules = stdenv.mkDerivation { 39 | name = "modules-${name}"; 40 | inherit src; 41 | 42 | yarnOfflineCache = fetchYarnDeps { 43 | yarnLock = "${src}/yarn.lock"; 44 | sha256 = import "${versionDef}/yarn-hash.nix"; 45 | }; 46 | 47 | nativeBuildInputs = [ 48 | fixup_yarn_lock 49 | nodejs-slim 50 | yarn 51 | mastodonGems 52 | mastodonGems.wrappedRuby 53 | brotli 54 | ]; 55 | 56 | RAILS_ENV = "production"; 57 | NODE_ENV = "production"; 58 | 59 | buildPhase = '' 60 | runHook preBuild 61 | 62 | export HOME=$PWD 63 | # This option is needed for openssl-3 compatibility 64 | # Otherwise we encounter this upstream issue: https://github.com/mastodon/mastodon/issues/17924 65 | export NODE_OPTIONS=--openssl-legacy-provider 66 | fixup_yarn_lock ~/yarn.lock 67 | yarn config --offline set yarn-offline-mirror $yarnOfflineCache 68 | yarn install --offline --frozen-lockfile --ignore-engines --ignore-scripts --no-progress 69 | 70 | patchShebangs ~/bin 71 | patchShebangs ~/node_modules 72 | 73 | # skip running yarn install 74 | rm -rf ~/bin/yarn 75 | 76 | OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder \ 77 | rails assets:precompile 78 | yarn cache clean --offline 79 | rm -rf ~/node_modules/.cache 80 | 81 | # Create missing static gzip and brotli files 82 | gzip --best --keep ~/public/assets/500.html 83 | gzip --best --keep ~/public/packs/report.html 84 | find ~/public/assets -maxdepth 1 -type f -name '.*.json' \ 85 | -exec gzip --best --keep --force {} ';' 86 | brotli --best --keep ~/public/packs/report.html 87 | find ~/public/assets -type f -regextype posix-extended -iregex '.*\.(css|js|json|html)' \ 88 | -exec brotli --best --keep {} ';' 89 | 90 | runHook postBuild 91 | ''; 92 | 93 | installPhase = '' 94 | runHook preInstall 95 | 96 | mkdir -p $out/public 97 | cp -r node_modules $out/node_modules 98 | cp -r public/assets $out/public 99 | cp -r public/packs $out/public 100 | 101 | runHook postInstall 102 | ''; 103 | }; 104 | 105 | propagatedBuildInputs = [ imagemagick ffmpeg file mastodonGems.wrappedRuby ]; 106 | buildInputs = [ mastodonGems nodejs-slim ]; 107 | 108 | buildPhase = '' 109 | runHook preBuild 110 | 111 | ln -s $mastodonModules/node_modules node_modules 112 | ln -s $mastodonModules/public/assets public/assets 113 | ln -s $mastodonModules/public/packs public/packs 114 | 115 | patchShebangs bin/ 116 | for b in $(ls $mastodonGems/bin/) 117 | do 118 | if [ ! -f bin/$b ]; then 119 | ln -s $mastodonGems/bin/$b bin/$b 120 | fi 121 | done 122 | 123 | # Remove execute permissions 124 | chmod 0444 public/emoji/*.svg 125 | 126 | # Create missing static gzip and brotli files 127 | find public -maxdepth 1 -type f -regextype posix-extended -iregex '.*\.(css|js|svg|txt|xml)' \ 128 | -exec gzip --best --keep --force {} ';' \ 129 | -exec brotli --best --keep {} ';' 130 | find public/emoji -type f -name '.*.svg' \ 131 | -exec gzip --best --keep --force {} ';' \ 132 | -exec brotli --best --keep {} ';' 133 | ln -s assets/500.html.gz public/500.html.gz 134 | ln -s assets/500.html.br public/500.html.br 135 | ln -s packs/sw.js.gz public/sw.js.gz 136 | ln -s packs/sw.js.br public/sw.js.br 137 | ln -s packs/sw.js.map.gz public/sw.js.map.gz 138 | ln -s packs/sw.js.map.br public/sw.js.map.br 139 | 140 | rm -rf log 141 | ln -s /var/log/mastodon log 142 | ln -s /tmp tmp 143 | 144 | runHook postBuild 145 | ''; 146 | 147 | installPhase = let 148 | run-streaming = writeShellScript "run-streaming.sh" '' 149 | # NixOS helper script to consistently use the same NodeJS version the package was built with. 150 | ${nodejs-slim}/bin/node ./streaming 151 | ''; 152 | in '' 153 | runHook preInstall 154 | 155 | mkdir -p $out 156 | cp -r * $out/ 157 | ln -s ${run-streaming} $out/run-streaming.sh 158 | 159 | runHook postInstall 160 | ''; 161 | 162 | meta = with lib; { 163 | description = 164 | "Self-hosted, globally interconnected microblogging software based on ActivityPub"; 165 | homepage = "https://joinmastodon.org"; 166 | license = licenses.agpl3Plus; 167 | }; 168 | } 169 | -------------------------------------------------------------------------------- /nix/fedi/mastodon/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs, name, host, users, version, proxy, ... }: 2 | let 3 | mastodon = pkgs.callPackage ./build.nix { versionDef = version; }; 4 | env = { 5 | LOCAL_DOMAIN = host; 6 | WEB_DOMAIN = host; 7 | ALLOWED_PRIVATE_ADDRESSES = "127.0.0.1"; 8 | RAILS_ENV = "production"; 9 | NODE_ENV = "production"; 10 | DB_USER = name; 11 | DB_NAME = name; 12 | REDIS_NAMESPACE = "${name}_"; 13 | EMAIL_DOMAIN_ALLOWLIST = "example.com"; 14 | SMTP_DELIVERY_METHOD = "file"; 15 | }; 16 | s6 = import ../../s6.nix { 17 | inherit pkgs; 18 | services = { 19 | web = pkgs.linkFarm "web" { 20 | run = pkgs.writeShellScript "run-web" '' 21 | cd ${mastodon} 22 | 23 | exec >$MINIFEDI_LOG/${name}/web.log 2>$MINIFEDI_LOG/${name}/web.log 24 | 25 | export SOCKET=$MINIFEDI_RUN/${name}/web.sock 26 | 27 | puma -C config/puma.rb 28 | ''; 29 | }; 30 | sidekiq = pkgs.linkFarm "sidekiq" { 31 | run = pkgs.writeShellScript "run-sidekiq" '' 32 | cd ${mastodon} 33 | exec >$MINIFEDI_LOG/${name}/sidekiq.log 2>$MINIFEDI_LOG/${name}/sidekiq.log 34 | sidekiq 35 | ''; 36 | }; 37 | streaming = pkgs.linkFarm "streaming" { 38 | run = pkgs.writeShellScript "run-sidekiq" '' 39 | cd ${mastodon} 40 | 41 | exec >$MINIFEDI_LOG/${name}/streaming.log 2>$MINIFEDI_LOG/${name}/streaming.log 42 | 43 | export SOCKET=$MINIFEDI_RUN/${name}/streaming.sock 44 | 45 | ${mastodon}/run-streaming.sh 46 | ''; 47 | }; 48 | }; 49 | path = "${name}/service"; 50 | }; 51 | path = pkgs.lib.strings.concatStrings (builtins.map (x: "${x}/bin:") [ 52 | mastodon 53 | pkgs.postgresql 54 | pkgs.s6 55 | # used by mastodon file upload: 56 | pkgs.file 57 | pkgs.imagemagick 58 | # used by sidekiq: 59 | pkgs.ps 60 | ]); 61 | in { 62 | service = pkgs.linkFarm name [{ 63 | name = "run"; 64 | path = pkgs.writeShellScript "run-${name}" '' 65 | set -e 66 | 67 | export PATH=${path}$PATH 68 | 69 | data=$MINIFEDI_DATA/${name} 70 | run=$MINIFEDI_RUN/${name} 71 | log=$MINIFEDI_LOG/${name} 72 | postgres=$MINIFEDI_RUN/postgres 73 | 74 | mkdir -p $data 75 | mkdir -p $data/files 76 | mkdir -p $run 77 | mkdir -p $log 78 | 79 | exec >$log/setup.log 2>$log/setup.log 80 | 81 | cd ${mastodon} 82 | 83 | ${pkgs.lib.strings.concatStrings 84 | (pkgs.lib.attrsets.mapAttrsToList (k: v: "export ${k}=${v};") env)} 85 | 86 | if ! [ -e $data/setup-done ]; then 87 | rake secret > $data/secret_key_base 88 | rake secret > $data/otp_secret 89 | # from nixos 90 | keypair=$(rake webpush:generate_keys) 91 | echo $keypair | grep --only-matching "Private -> [^ ]\+" | sed 's/^Private -> //' > $data/vapid_private_key 92 | echo $keypair | grep --only-matching "Public -> [^ ]\+" | sed 's/^Public -> //' > $data/vapid_public_key 93 | fi 94 | 95 | export SECRET_KEY_BASE=$(cat $data/secret_key_base) 96 | export OTP_SECRET=$(cat $data/otp_secret) 97 | export VAPID_PRIVATE_KEY=$(cat $data/vapid_private_key) 98 | export VAPID_PUBLIC_KEY=$(cat $data/vapid_public_key) 99 | 100 | export DB_HOST=$postgres 101 | export REDIS_URL=unix://$MINIFEDI_RUN/redis/redis.sock 102 | export NIX_SSL_CERT_FILE=$MINIFEDI_CERT/rootCA.pem 103 | export PAPERCLIP_ROOT_PATH=$data/files 104 | ${if proxy != null then "export http_proxy=${proxy}" else ""} 105 | 106 | s6-svwait -U $MINIFEDI_RUN/service/postgres 107 | 108 | if ! [ -e $data/setup-done ]; then 109 | createdb -h$postgres ${name} 110 | createuser -h$postgres ${name} 111 | 112 | rails db:schema:load 113 | rails db:seed 114 | 115 | touch $data/setup-done 116 | 117 | ${ 118 | pkgs.lib.strings.concatStrings (builtins.map (u: 119 | "tootctl accounts create ${u.name} --email=${u.email} --confirmed ${ 120 | if u.admin then "--role Owner" else "" 121 | };") users) 122 | } 123 | rails runner "${ 124 | pkgs.lib.strings.concatStrings (builtins.map (u: 125 | "Account.find_local('${u.name}').user.update!(password: '${u.password}');") 126 | users) 127 | }" 128 | fi 129 | 130 | exec ${s6.start} 131 | ''; 132 | }]; 133 | nginxConfig = '' 134 | map $http_upgrade ${"$"}${name}_connection_upgrade { 135 | default upgrade; 136 | ${"''"} close; 137 | } 138 | 139 | upstream ${name}_backend { 140 | server unix:$MINIFEDI_RUN/${name}/web.sock fail_timeout=0; 141 | } 142 | 143 | upstream ${name}_streaming { 144 | server unix:$MINIFEDI_RUN/${name}/streaming.sock fail_timeout=0; 145 | } 146 | 147 | server { 148 | listen 443 ssl http2; 149 | listen [::]:443 ssl http2; 150 | server_name ${host}; 151 | 152 | ssl_protocols TLSv1.2 TLSv1.3; 153 | ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA; 154 | ssl_prefer_server_ciphers on; 155 | ssl_session_cache shared:SSL:10m; 156 | ssl_session_tickets off; 157 | 158 | # Uncomment these lines once you acquire a certificate: 159 | ssl_certificate $MINIFEDI_DATA/nginx/fullchain.pem; 160 | ssl_certificate_key $MINIFEDI_DATA/nginx/key.pem; 161 | 162 | keepalive_timeout 70; 163 | sendfile on; 164 | client_max_body_size 99m; 165 | 166 | root ${mastodon}/public; 167 | 168 | gzip on; 169 | gzip_disable "msie6"; 170 | gzip_vary on; 171 | gzip_proxied any; 172 | gzip_comp_level 6; 173 | gzip_buffers 16 8k; 174 | gzip_http_version 1.1; 175 | 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; 176 | 177 | location / { 178 | try_files $uri @proxy; 179 | } 180 | 181 | # If Docker is used for deployment and Rails serves static files, 182 | # then needed must replace line `try_files $uri =404;` with `try_files $uri @proxy;`. 183 | location = /sw.js { 184 | add_header Cache-Control "public, max-age=604800, must-revalidate"; 185 | add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; 186 | try_files $uri =404; 187 | } 188 | 189 | location ~ ^/assets/ { 190 | add_header Cache-Control "public, max-age=2419200, must-revalidate"; 191 | add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; 192 | try_files $uri =404; 193 | } 194 | 195 | location ~ ^/avatars/ { 196 | add_header Cache-Control "public, max-age=2419200, must-revalidate"; 197 | add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; 198 | try_files $uri =404; 199 | } 200 | 201 | location ~ ^/emoji/ { 202 | add_header Cache-Control "public, max-age=2419200, must-revalidate"; 203 | add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; 204 | try_files $uri =404; 205 | } 206 | 207 | location ~ ^/headers/ { 208 | add_header Cache-Control "public, max-age=2419200, must-revalidate"; 209 | add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; 210 | try_files $uri =404; 211 | } 212 | 213 | location ~ ^/packs/ { 214 | add_header Cache-Control "public, max-age=2419200, must-revalidate"; 215 | add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; 216 | try_files $uri =404; 217 | } 218 | 219 | location ~ ^/shortcuts/ { 220 | add_header Cache-Control "public, max-age=2419200, must-revalidate"; 221 | add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; 222 | try_files $uri =404; 223 | } 224 | 225 | location ~ ^/sounds/ { 226 | add_header Cache-Control "public, max-age=2419200, must-revalidate"; 227 | add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; 228 | try_files $uri =404; 229 | } 230 | 231 | location /system/ { 232 | add_header Cache-Control "public, max-age=2419200, immutable"; 233 | add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; 234 | 235 | alias $MINIFEDI_DATA/${name}/files/; 236 | 237 | try_files $uri =404; 238 | } 239 | 240 | location ^~ /api/v1/streaming { 241 | proxy_set_header Host $host; 242 | proxy_set_header X-Real-IP $remote_addr; 243 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 244 | proxy_set_header X-Forwarded-Proto $scheme; 245 | proxy_set_header Proxy ""; 246 | 247 | proxy_pass http://${name}_streaming; 248 | proxy_buffering off; 249 | proxy_redirect off; 250 | proxy_http_version 1.1; 251 | proxy_set_header Upgrade $http_upgrade; 252 | proxy_set_header Connection ${"$"}${name}_connection_upgrade; 253 | 254 | add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; 255 | 256 | tcp_nodelay on; 257 | } 258 | 259 | location @proxy { 260 | proxy_set_header Host $host; 261 | proxy_set_header X-Real-IP $remote_addr; 262 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 263 | proxy_set_header X-Forwarded-Proto $scheme; 264 | proxy_set_header Proxy ""; 265 | proxy_pass_header Server; 266 | 267 | proxy_pass http://${name}_backend; 268 | proxy_buffering on; 269 | proxy_redirect off; 270 | proxy_http_version 1.1; 271 | proxy_set_header Upgrade $http_upgrade; 272 | proxy_set_header Connection ${"$"}${name}_connection_upgrade; 273 | 274 | # proxy_cache CACHE; 275 | # proxy_cache_valid 200 7d; 276 | # proxy_cache_valid 410 24h; 277 | # proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; 278 | add_header X-Cached $upstream_cache_status; 279 | 280 | tcp_nodelay on; 281 | } 282 | 283 | error_page 404 500 501 502 503 504 /500.html; 284 | } 285 | ''; 286 | } 287 | -------------------------------------------------------------------------------- /nix/fedi/mastodon/mk-version/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs }: 2 | let 3 | binPath = pkgs.lib.makeBinPath (with pkgs; [ 4 | bundix 5 | coreutils 6 | diffutils 7 | nix-prefetch-github 8 | nix-prefetch-git 9 | gnused 10 | jq 11 | prefetch-yarn-deps 12 | ]); 13 | in pkgs.runCommand "mk-mastodon" { 14 | nativeBuildInputs = [ pkgs.makeWrapper ]; 15 | } '' 16 | mkdir -p $out/bin 17 | cp ${./mk-version.sh} $out/bin/mk-mastodon 18 | patchShebangs $out/bin/mk-mastodon 19 | wrapProgram $out/bin/mk-mastodon --prefix PATH : ${binPath} 20 | '' 21 | -------------------------------------------------------------------------------- /nix/fedi/mastodon/mk-version/mk-version.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Derived from the update script for nixpkgs#mastodon. MIT-licensed. 4 | 5 | set -e 6 | 7 | NAME=$1 8 | REPO=$2 9 | REV=$3 10 | 11 | if [[ -z "$REV" ]]; then 12 | echo "Usage: minifedi mk-mastodon NAME REPO REV" 13 | echo "NAME can be anything, but generally it's something like mastodon-4.1.4 or glitch-12abcdef" 14 | echo "REPO is a git clone URL" 15 | echo "REV is a git commit or tag (not a branch)" 16 | exit 1 17 | fi 18 | 19 | rm -rf versions/mastodon/$NAME 20 | mkdir -p versions/mastodon/$NAME 21 | cd versions/mastodon/$NAME 22 | 23 | TARGET_DIR="$PWD" 24 | 25 | WORK_DIR=$(mktemp -d) 26 | 27 | # Check that working directory was created. 28 | if [[ -z "$WORK_DIR" || ! -d "$WORK_DIR" ]]; then 29 | echo "Could not create temporary directory" 30 | exit 1 31 | fi 32 | 33 | # Delete the working directory on exit. 34 | function cleanup { 35 | rm -rf "$WORK_DIR" 36 | } 37 | trap cleanup EXIT 38 | 39 | echo "Fetching source code" 40 | JSON=$(nix-prefetch-git $REPO $REV) 41 | SHA=$(echo "$JSON" | jq -r .sha256) 42 | 43 | echo "Creating version.nix" 44 | echo "\"$NAME\"" > name.nix 45 | 46 | cat > source.nix << EOF 47 | # This file was generated by minifedi mk-mastodon. 48 | { fetchgit, applyPatches }: fetchgit { 49 | url = "$REPO"; 50 | rev = "$REV"; 51 | sha256 = "$SHA"; 52 | } 53 | EOF 54 | SOURCE_DIR="$(nix-build --no-out-link -E '(import {}).callPackage ./source.nix {}')" 55 | 56 | echo "Creating gemset.nix" 57 | bundix --lockfile="$SOURCE_DIR/Gemfile.lock" --gemfile="$SOURCE_DIR/Gemfile" 58 | echo "" >> "$TARGET_DIR/gemset.nix" # Create trailing newline to please EditorConfig checks 59 | 60 | echo "Creating yarn-hash.nix" 61 | echo '"'$(prefetch-yarn-deps "$SOURCE_DIR/yarn.lock")'"' > "$TARGET_DIR/yarn-hash.nix" 62 | 63 | git add . -------------------------------------------------------------------------------- /nix/s6.nix: -------------------------------------------------------------------------------- 1 | { pkgs, services, path }: 2 | 3 | let scandir = pkgs.linkFarm "service" services; 4 | in { 5 | start = pkgs.writeShellScript "s6-start" '' 6 | cp -RL ${scandir} $MINIFEDI_RUN/${path} 7 | chmod -R +w $MINIFEDI_RUN/${path} 8 | exec ${pkgs.s6}/bin/s6-svscan $MINIFEDI_RUN/${path} 9 | ''; 10 | } 11 | -------------------------------------------------------------------------------- /nix/services.nix: -------------------------------------------------------------------------------- 1 | { pkgs, config }: 2 | let 3 | instances = config.instances; 4 | util = import ./util.nix { inherit pkgs; }; 5 | evaldInstances = builtins.listToAttrs (builtins.map (inst: 6 | pkgs.lib.attrsets.nameValuePair inst.name (inst.type ({ 7 | inherit pkgs util; 8 | host = "${inst.name}.lvh.me"; 9 | users = [ 10 | { 11 | name = "a"; 12 | email = "a@example.com"; 13 | password = "MiniFediA1!"; 14 | admin = true; 15 | } 16 | { 17 | name = "b"; 18 | email = "b@example.com"; 19 | password = "MiniFediB1!"; 20 | admin = false; 21 | } 22 | { 23 | name = "c"; 24 | email = "c@example.com"; 25 | password = "MiniFediC1!"; 26 | admin = false; 27 | } 28 | { 29 | name = "d"; 30 | email = "d@example.com"; 31 | password = "MiniFediD1!"; 32 | admin = false; 33 | } 34 | { 35 | name = "e"; 36 | email = "e@example.com"; 37 | password = "MiniFediE1!"; 38 | admin = false; 39 | } 40 | ]; 41 | proxy = if config.mitmproxy then "http://localhost:8080" else null; 42 | } // inst))) instances); 43 | in evaldInstances // { 44 | postgres = import ./support-services/postgres { inherit pkgs; }; 45 | redis = import ./support-services/redis { inherit pkgs; }; 46 | nginx = import ./support-services/nginx { 47 | inherit pkgs; 48 | instances = evaldInstances; 49 | }; 50 | } // pkgs.lib.attrsets.optionalAttrs config.mitmproxy { 51 | mitmproxy = import ./support-services/mitmproxy { inherit pkgs; }; 52 | } 53 | -------------------------------------------------------------------------------- /nix/support-services/mitmproxy/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs }: { 2 | service = pkgs.linkFarm "mitmproxy" { 3 | run = pkgs.writeShellScript "run-mitmproxy" '' 4 | set -e 5 | 6 | mkdir -p $MINIFEDI_DATA/mitmproxy 7 | 8 | exec >$MINIFEDI_LOG/mitmproxy.log 2>$MINIFEDI_LOG/mitmproxy.log 9 | 10 | if ! [[ -e $MINIFEDI_DATA/mitmproxy/fullchain.pem ]]; then 11 | CAROOT=$MINIFEDI_CERT ${pkgs.mkcert}/bin/mkcert -cert-file $MINIFEDI_DATA/mitmproxy/cert.pem -key-file $MINIFEDI_DATA/mitmproxy/key.pem *.lvh.me 12 | cat $MINIFEDI_DATA/mitmproxy/key.pem $MINIFEDI_DATA/mitmproxy/cert.pem $MINIFEDI_CERT/rootCA.pem > $MINIFEDI_DATA/mitmproxy/fullchain.pem 13 | fi 14 | 15 | exec ${pkgs.mitmproxy}/bin/mitmweb --certs $MINIFEDI_DATA/mitmproxy/fullchain.pem -k -v 16 | ''; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /nix/support-services/nginx/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs, instances }: 2 | let 3 | config = pkgs.writeText "nginx.conf" '' 4 | events {} 5 | 6 | pid $MINIFEDI_RUN/nginx/nginx.pid; 7 | 8 | daemon off; 9 | 10 | error_log stderr info; 11 | 12 | http { 13 | include ${pkgs.nginx}/conf/mime.types; 14 | 15 | access_log $MINIFEDI_DATA/nginx/access.log; 16 | 17 | server { 18 | listen 80; 19 | listen [::]:80; 20 | location / { return 301 https://$host$request_uri; } 21 | } 22 | 23 | ${ 24 | pkgs.lib.concatStrings (builtins.map (x: x.nginxConfig) 25 | (pkgs.lib.attrsets.attrValues instances)) 26 | } 27 | } 28 | ''; 29 | in { 30 | service = pkgs.linkFarm "nginx" { 31 | run = pkgs.writeShellScript "run-nginx" '' 32 | set -e 33 | 34 | PATH=${pkgs.gettext}/bin:$PATH 35 | 36 | mkdir -p $MINIFEDI_DATA/nginx 37 | mkdir -p $MINIFEDI_RUN/nginx 38 | 39 | exec >$MINIFEDI_LOG/nginx.log 2>$MINIFEDI_LOG/web.log 40 | 41 | if ! [[ -e $MINIFEDI_DATA/nginx/fullchain.pem ]]; then 42 | CAROOT=$MINIFEDI_CERT ${pkgs.mkcert}/bin/mkcert -cert-file $MINIFEDI_DATA/nginx/cert.pem -key-file $MINIFEDI_DATA/nginx/key.pem *.lvh.me 43 | cat $MINIFEDI_DATA/nginx/cert.pem $MINIFEDI_CERT/rootCA.pem > $MINIFEDI_DATA/nginx/fullchain.pem 44 | fi 45 | 46 | cd $MINIFEDI_DATA 47 | cat ${config} | envsubst '$MINIFEDI_DATA $MINIFEDI_RUN' > $MINIFEDI_DATA/nginx/nginx.conf 48 | exec ${pkgs.nginx}/bin/nginx -c $MINIFEDI_DATA/nginx/nginx.conf -e $MINIFEDI_DATA/nginx/error.log 49 | ''; 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /nix/support-services/postgres/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs }: 2 | 3 | { 4 | service = pkgs.linkFarm "postgres" { 5 | run = pkgs.writeShellScript "run-postgres-outer" '' 6 | exec >$MINIFEDI_LOG/postgres.log 2>$MINIFEDI_LOG/postgres.log 7 | 8 | exec ${pkgs.s6}/bin/s6-notifyoncheck ${ 9 | pkgs.writeShellScript "run-postgres-inner" '' 10 | export PATH=${pkgs.gettext}/bin:$PATH 11 | 12 | mkdir -p $MINIFEDI_DATA/postgres 13 | mkdir -p $MINIFEDI_RUN/postgres 14 | cd $MINIFEDI_DATA/postgres 15 | export PGDATA=$(pwd)/data 16 | [[ -e $PGDATA ]] || ${pkgs.postgresql}/bin/initdb 17 | cat ${./postgresql.conf} | envsubst > $PGDATA/postgresql.conf 18 | exec ${pkgs.postgresql}/bin/postgres 19 | '' 20 | } 21 | ''; 22 | 23 | data = pkgs.linkFarm "data" { 24 | check = pkgs.writeShellScript "check-postgres" '' 25 | ${pkgs.postgresql}/bin/pg_isready -h $MINIFEDI_RUN/postgres 26 | ''; 27 | }; 28 | 29 | notification-fd = pkgs.writeText "notification-fd" "3"; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /nix/support-services/postgres/postgresql.conf: -------------------------------------------------------------------------------- 1 | listen_addresses = '' 2 | unix_socket_directories = '$MINIFEDI_RUN/postgres/' -------------------------------------------------------------------------------- /nix/support-services/redis/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs }: 2 | let 3 | config = pkgs.writeText "redis.conf" '' 4 | port 0 5 | protected-mode yes 6 | ''; 7 | in { 8 | service = pkgs.linkFarm "redis" { 9 | run = pkgs.writeShellScript "run-redis" '' 10 | set -e 11 | 12 | mkdir -p $MINIFEDI_DATA/redis 13 | mkdir -p $MINIFEDI_RUN/redis 14 | 15 | exec >$MINIFEDI_LOG/redis.log 2>$MINIFEDI_LOG/redis.log 16 | 17 | cd $MINIFEDI_RUN/redis 18 | exec ${pkgs.redis}/bin/redis-server ${config} --unixsocket $MINIFEDI_RUN/redis/redis.sock 19 | ''; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /nix/util.nix: -------------------------------------------------------------------------------- 1 | { pkgs }: 2 | 3 | rec { 4 | portFromString = string: 5 | let 6 | hash = builtins.hashString "sha256" string; 7 | portHex = builtins.substring 0 4 hash; 8 | portHexChars = pkgs.lib.strings.stringToCharacters portHex; 9 | hexDigitToNum = n: 10 | let 11 | map = { 12 | "0" = 0; 13 | "1" = 1; 14 | "2" = 2; 15 | "3" = 3; 16 | "4" = 4; 17 | "5" = 5; 18 | "6" = 6; 19 | "7" = 7; 20 | "8" = 8; 21 | "9" = 9; 22 | "a" = 10; 23 | "b" = 11; 24 | "c" = 12; 25 | "d" = 13; 26 | "e" = 14; 27 | "f" = 15; 28 | }; 29 | in map.${n}; 30 | portFromHash = 31 | pkgs.lib.lists.foldl (prev: n: (hexDigitToNum n) + (prev * 16)) 0 32 | portHexChars; 33 | in if portFromHash <= 1024 then 34 | portFromString "retry_${string}" 35 | else 36 | portFromHash; 37 | } 38 | -------------------------------------------------------------------------------- /versions/mastodon/glitch-a004718/gemset.nix: -------------------------------------------------------------------------------- 1 | { 2 | actioncable = { 3 | dependencies = ["actionpack" "activesupport" "nio4r" "websocket-driver"]; 4 | groups = ["default"]; 5 | platforms = []; 6 | source = { 7 | remotes = ["https://rubygems.org"]; 8 | sha256 = "1d72cqx1h9c0yl1vc8xakvji00krg118ih6lwqlg5nbw50gbx25c"; 9 | type = "gem"; 10 | }; 11 | version = "7.0.6"; 12 | }; 13 | actionmailbox = { 14 | dependencies = ["actionpack" "activejob" "activerecord" "activestorage" "activesupport" "mail" "net-imap" "net-pop" "net-smtp"]; 15 | groups = ["default"]; 16 | platforms = []; 17 | source = { 18 | remotes = ["https://rubygems.org"]; 19 | sha256 = "12xkyfdpr7ljnd31yhc2kzl0rqrlwxzpg4qcn4yb2h364hwc6fh8"; 20 | type = "gem"; 21 | }; 22 | version = "7.0.6"; 23 | }; 24 | actionmailer = { 25 | dependencies = ["actionpack" "actionview" "activejob" "activesupport" "mail" "net-imap" "net-pop" "net-smtp" "rails-dom-testing"]; 26 | groups = ["default" "development"]; 27 | platforms = []; 28 | source = { 29 | remotes = ["https://rubygems.org"]; 30 | sha256 = "01x11ijfg56585vj7a7az0235idnxcnyjp1nb1jvkm08jjll5d1k"; 31 | type = "gem"; 32 | }; 33 | version = "7.0.6"; 34 | }; 35 | actionpack = { 36 | dependencies = ["actionview" "activesupport" "rack" "rack-test" "rails-dom-testing" "rails-html-sanitizer"]; 37 | groups = ["default" "development" "pam_authentication" "production" "test"]; 38 | platforms = []; 39 | source = { 40 | remotes = ["https://rubygems.org"]; 41 | sha256 = "0d66w1d9rhvafd0dilqyr1ymsvr060l8hi0xvwij7cyvzzxrlrbc"; 42 | type = "gem"; 43 | }; 44 | version = "7.0.6"; 45 | }; 46 | actiontext = { 47 | dependencies = ["actionpack" "activerecord" "activestorage" "activesupport" "globalid" "nokogiri"]; 48 | groups = ["default"]; 49 | platforms = []; 50 | source = { 51 | remotes = ["https://rubygems.org"]; 52 | sha256 = "0bpyfh8g0mzgkb8bxvf245mwnx1awbr1y6dxcdckyhsjjgrfynfl"; 53 | type = "gem"; 54 | }; 55 | version = "7.0.6"; 56 | }; 57 | actionview = { 58 | dependencies = ["activesupport" "builder" "erubi" "rails-dom-testing" "rails-html-sanitizer"]; 59 | groups = ["default" "development" "pam_authentication" "production" "test"]; 60 | platforms = []; 61 | source = { 62 | remotes = ["https://rubygems.org"]; 63 | sha256 = "1icfh9pgjpd29apzn07cnqa9nlpvjv7i4vrygack5gp7hp54l8m7"; 64 | type = "gem"; 65 | }; 66 | version = "7.0.6"; 67 | }; 68 | active_model_serializers = { 69 | dependencies = ["actionpack" "activemodel" "case_transform" "jsonapi-renderer"]; 70 | groups = ["default"]; 71 | platforms = []; 72 | source = { 73 | remotes = ["https://rubygems.org"]; 74 | sha256 = "0xdp7cpj3yj3wl4vj0nqq44kzjavlxi1wq3cf9zp0whkir0ym0gy"; 75 | type = "gem"; 76 | }; 77 | version = "0.10.13"; 78 | }; 79 | activejob = { 80 | dependencies = ["activesupport" "globalid"]; 81 | groups = ["default" "development"]; 82 | platforms = []; 83 | source = { 84 | remotes = ["https://rubygems.org"]; 85 | sha256 = "1gawwb6550ra1xgbrki03aq4q5wafa3xfrpdr3cva4ghy3qqn53q"; 86 | type = "gem"; 87 | }; 88 | version = "7.0.6"; 89 | }; 90 | activemodel = { 91 | dependencies = ["activesupport"]; 92 | groups = ["default" "development"]; 93 | platforms = []; 94 | source = { 95 | remotes = ["https://rubygems.org"]; 96 | sha256 = "072iv0d3vpbp0xijg4jj99sjil1rykmqfj9addxj76bm5mbzwcaj"; 97 | type = "gem"; 98 | }; 99 | version = "7.0.6"; 100 | }; 101 | activerecord = { 102 | dependencies = ["activemodel" "activesupport"]; 103 | groups = ["default" "development"]; 104 | platforms = []; 105 | source = { 106 | remotes = ["https://rubygems.org"]; 107 | sha256 = "1l0rn43bhyzlfa4wwcfz016vb4lkzvl0jf5zibkjy4sppxxixzrq"; 108 | type = "gem"; 109 | }; 110 | version = "7.0.6"; 111 | }; 112 | activestorage = { 113 | dependencies = ["actionpack" "activejob" "activerecord" "activesupport" "marcel" "mini_mime"]; 114 | groups = ["default"]; 115 | platforms = []; 116 | source = { 117 | remotes = ["https://rubygems.org"]; 118 | sha256 = "036mv935r5mmh7fljz10lyr43c5y5bn8b6h7gdkv8spfgwzihw4j"; 119 | type = "gem"; 120 | }; 121 | version = "7.0.6"; 122 | }; 123 | activesupport = { 124 | dependencies = ["concurrent-ruby" "i18n" "minitest" "tzinfo"]; 125 | groups = ["default" "development" "pam_authentication" "production" "test"]; 126 | platforms = []; 127 | source = { 128 | remotes = ["https://rubygems.org"]; 129 | sha256 = "1cjsf26656996hv48wgv2mkwxf0fy1qc68ikgzq7mzfq2mmvmayk"; 130 | type = "gem"; 131 | }; 132 | version = "7.0.6"; 133 | }; 134 | addressable = { 135 | dependencies = ["public_suffix"]; 136 | groups = ["default" "development" "test"]; 137 | platforms = []; 138 | source = { 139 | remotes = ["https://rubygems.org"]; 140 | sha256 = "15s8van7r2ad3dq6i03l3z4hqnvxcq75a3h72kxvf9an53sqma20"; 141 | type = "gem"; 142 | }; 143 | version = "2.8.4"; 144 | }; 145 | aes_key_wrap = { 146 | groups = ["default"]; 147 | platforms = []; 148 | source = { 149 | remotes = ["https://rubygems.org"]; 150 | sha256 = "19bn0y70qm6mfj4y1m0j3s8ggh6dvxwrwrj5vfamhdrpddsz8ddr"; 151 | type = "gem"; 152 | }; 153 | version = "1.1.0"; 154 | }; 155 | airbrussh = { 156 | dependencies = ["sshkit"]; 157 | groups = ["default" "development"]; 158 | platforms = []; 159 | source = { 160 | remotes = ["https://rubygems.org"]; 161 | sha256 = "0x55y3ynkda76pwnsvrrjlvxfcc7yn1irad8radll9c9cif41jqv"; 162 | type = "gem"; 163 | }; 164 | version = "1.4.1"; 165 | }; 166 | android_key_attestation = { 167 | groups = ["default"]; 168 | platforms = []; 169 | source = { 170 | remotes = ["https://rubygems.org"]; 171 | sha256 = "02spc1sh7zsljl02v9d5rdb717b628vw2k7jkkplifyjk4db0zj6"; 172 | type = "gem"; 173 | }; 174 | version = "0.3.0"; 175 | }; 176 | annotate = { 177 | dependencies = ["activerecord" "rake"]; 178 | groups = ["development"]; 179 | platforms = []; 180 | source = { 181 | remotes = ["https://rubygems.org"]; 182 | sha256 = "1lw0fxb5mirsdp3bp20gjyvs7clvi19jbxnrm2ihm20kzfhvlqcs"; 183 | type = "gem"; 184 | }; 185 | version = "3.2.0"; 186 | }; 187 | ast = { 188 | groups = ["default" "development"]; 189 | platforms = []; 190 | source = { 191 | remotes = ["https://rubygems.org"]; 192 | sha256 = "04nc8x27hlzlrr5c2gn7mar4vdr0apw5xg22wp6m8dx3wqr04a0y"; 193 | type = "gem"; 194 | }; 195 | version = "2.4.2"; 196 | }; 197 | attr_encrypted = { 198 | dependencies = ["encryptor"]; 199 | groups = ["default"]; 200 | platforms = []; 201 | source = { 202 | remotes = ["https://rubygems.org"]; 203 | sha256 = "034x6mbrv9apd83v99v9pm8vl3d17w5bbwws26gr4wv95fylmgnc"; 204 | type = "gem"; 205 | }; 206 | version = "4.0.0"; 207 | }; 208 | attr_required = { 209 | groups = ["default"]; 210 | platforms = []; 211 | source = { 212 | remotes = ["https://rubygems.org"]; 213 | sha256 = "1g22axmi2rhhy7w8c3x6gppsawxqavbrnxpnmphh22fk7cwi0kh2"; 214 | type = "gem"; 215 | }; 216 | version = "1.0.1"; 217 | }; 218 | awrence = { 219 | groups = ["default"]; 220 | platforms = []; 221 | source = { 222 | remotes = ["https://rubygems.org"]; 223 | sha256 = "0gj8f8c54r9cabkm41s59sa1ca5wpbipw7gq3sfl87x9296227fx"; 224 | type = "gem"; 225 | }; 226 | version = "1.2.1"; 227 | }; 228 | aws-eventstream = { 229 | groups = ["default"]; 230 | platforms = []; 231 | source = { 232 | remotes = ["https://rubygems.org"]; 233 | sha256 = "1pyis1nvnbjxk12a43xvgj2gv0mvp4cnkc1gzw0v1018r61399gz"; 234 | type = "gem"; 235 | }; 236 | version = "1.2.0"; 237 | }; 238 | aws-partitions = { 239 | groups = ["default"]; 240 | platforms = []; 241 | source = { 242 | remotes = ["https://rubygems.org"]; 243 | sha256 = "0plbj6d69j3vi8zwg9q8hkr77b7p7kg8bfqpvv9ghv2zay3igp3v"; 244 | type = "gem"; 245 | }; 246 | version = "1.780.0"; 247 | }; 248 | aws-sdk-core = { 249 | dependencies = ["aws-eventstream" "aws-partitions" "aws-sigv4" "jmespath"]; 250 | groups = ["default"]; 251 | platforms = []; 252 | source = { 253 | remotes = ["https://rubygems.org"]; 254 | sha256 = "1fbbzcszpdjy2yzxfvl5fzgn0jgznkwxvqpb46nxv69gqhv3dpsg"; 255 | type = "gem"; 256 | }; 257 | version = "3.175.0"; 258 | }; 259 | aws-sdk-kms = { 260 | dependencies = ["aws-sdk-core" "aws-sigv4"]; 261 | groups = ["default"]; 262 | platforms = []; 263 | source = { 264 | remotes = ["https://rubygems.org"]; 265 | sha256 = "0dkgcgvif4hjlq5jhixd2hf17pm2pib7p3jxg9g92pybsff9rk7c"; 266 | type = "gem"; 267 | }; 268 | version = "1.67.0"; 269 | }; 270 | aws-sdk-s3 = { 271 | dependencies = ["aws-sdk-core" "aws-sdk-kms" "aws-sigv4"]; 272 | groups = ["default"]; 273 | platforms = []; 274 | source = { 275 | remotes = ["https://rubygems.org"]; 276 | sha256 = "17ya49rwjzimqhzsj6vlc4xfvj2sixy04kr4b6ddg3r6y0jrsixi"; 277 | type = "gem"; 278 | }; 279 | version = "1.126.0"; 280 | }; 281 | aws-sigv4 = { 282 | dependencies = ["aws-eventstream"]; 283 | groups = ["default"]; 284 | platforms = []; 285 | source = { 286 | remotes = ["https://rubygems.org"]; 287 | sha256 = "11hkna2av47bl0yprgp8k4ya70rc3m2ib5w10fn0piplgkkmhz7m"; 288 | type = "gem"; 289 | }; 290 | version = "1.5.2"; 291 | }; 292 | bcrypt = { 293 | groups = ["default" "pam_authentication"]; 294 | platforms = []; 295 | source = { 296 | remotes = ["https://rubygems.org"]; 297 | sha256 = "048z3fvcknqx7ikkhrcrykxlqmf9bzc7l0y5h1cnvrc9n2qf0k8m"; 298 | type = "gem"; 299 | }; 300 | version = "3.1.18"; 301 | }; 302 | better_errors = { 303 | dependencies = ["erubi" "rack" "rouge"]; 304 | groups = ["development"]; 305 | platforms = []; 306 | source = { 307 | remotes = ["https://rubygems.org"]; 308 | sha256 = "0wqazisnn6hn1wsza412xribpw5wzx6b5z5p4mcpfgizr6xg367p"; 309 | type = "gem"; 310 | }; 311 | version = "2.10.1"; 312 | }; 313 | better_html = { 314 | dependencies = ["actionview" "activesupport" "ast" "erubi" "parser" "smart_properties"]; 315 | groups = ["default" "development"]; 316 | platforms = []; 317 | source = { 318 | remotes = ["https://rubygems.org"]; 319 | sha256 = "1y090dmgjxr3yzxi3pg5jgirkmyfdrmjhabmzmhg5i8ssiqr2gdz"; 320 | type = "gem"; 321 | }; 322 | version = "2.0.1"; 323 | }; 324 | bindata = { 325 | groups = ["default"]; 326 | platforms = []; 327 | source = { 328 | remotes = ["https://rubygems.org"]; 329 | sha256 = "04y4zgh4bbcb8wmkxwfqg4saky1d1f3xw8z6yk543q13h8ky8rz5"; 330 | type = "gem"; 331 | }; 332 | version = "2.4.15"; 333 | }; 334 | binding_of_caller = { 335 | dependencies = ["debug_inspector"]; 336 | groups = ["development"]; 337 | platforms = []; 338 | source = { 339 | remotes = ["https://rubygems.org"]; 340 | sha256 = "078n2dkpgsivcf0pr50981w95nfc2bsrp3wpf9wnxz1qsp8jbb9s"; 341 | type = "gem"; 342 | }; 343 | version = "1.0.0"; 344 | }; 345 | blurhash = { 346 | groups = ["default"]; 347 | platforms = []; 348 | source = { 349 | remotes = ["https://rubygems.org"]; 350 | sha256 = "057afgqy73n8vm7k3cr4pbwm1hhqnm58lp4x7bgm5wzbs39m7xf8"; 351 | type = "gem"; 352 | }; 353 | version = "0.1.7"; 354 | }; 355 | bootsnap = { 356 | dependencies = ["msgpack"]; 357 | groups = ["default"]; 358 | platforms = []; 359 | source = { 360 | remotes = ["https://rubygems.org"]; 361 | sha256 = "1vcg52gwl64xhhal6kwk1pc01y1klzdlnv1awyk89kb91z010x7q"; 362 | type = "gem"; 363 | }; 364 | version = "1.16.0"; 365 | }; 366 | brakeman = { 367 | groups = ["development"]; 368 | platforms = []; 369 | source = { 370 | remotes = ["https://rubygems.org"]; 371 | sha256 = "1l2584f7cm7lmwihm1l449rk6vl4wlx3s7x317cm2inapzjhiybg"; 372 | type = "gem"; 373 | }; 374 | version = "6.0.0"; 375 | }; 376 | browser = { 377 | groups = ["default"]; 378 | platforms = []; 379 | source = { 380 | remotes = ["https://rubygems.org"]; 381 | sha256 = "0g4bcpax07kqqr9cp7cjc7i0pcij4nqpn1rdsg2wdwhzf00m6x32"; 382 | type = "gem"; 383 | }; 384 | version = "5.3.1"; 385 | }; 386 | brpoplpush-redis_script = { 387 | dependencies = ["concurrent-ruby" "redis"]; 388 | groups = ["default"]; 389 | platforms = []; 390 | source = { 391 | remotes = ["https://rubygems.org"]; 392 | sha256 = "1nd5zj5yqmhv9lrsqz8s2dqq28v4ywy95qrw7nzhhf89dl4dq49l"; 393 | type = "gem"; 394 | }; 395 | version = "0.1.3"; 396 | }; 397 | builder = { 398 | groups = ["default" "development" "pam_authentication" "production" "test"]; 399 | platforms = []; 400 | source = { 401 | remotes = ["https://rubygems.org"]; 402 | sha256 = "045wzckxpwcqzrjr353cxnyaxgf0qg22jh00dcx7z38cys5g1jlr"; 403 | type = "gem"; 404 | }; 405 | version = "3.2.4"; 406 | }; 407 | bundler-audit = { 408 | dependencies = ["thor"]; 409 | groups = ["development"]; 410 | platforms = []; 411 | source = { 412 | remotes = ["https://rubygems.org"]; 413 | sha256 = "0gdx0019vj04n1512shhdx7hwphzqmdpw4vva2k551nd47y1dixx"; 414 | type = "gem"; 415 | }; 416 | version = "0.9.1"; 417 | }; 418 | capistrano = { 419 | dependencies = ["airbrussh" "i18n" "rake" "sshkit"]; 420 | groups = ["development"]; 421 | platforms = []; 422 | source = { 423 | remotes = ["https://rubygems.org"]; 424 | sha256 = "14pflh85rrs2l8k0m286j4vaab5vad2sfqq9dncqb31z05vy29mn"; 425 | type = "gem"; 426 | }; 427 | version = "3.17.3"; 428 | }; 429 | capistrano-bundler = { 430 | dependencies = ["capistrano"]; 431 | groups = ["default" "development"]; 432 | platforms = []; 433 | source = { 434 | remotes = ["https://rubygems.org"]; 435 | sha256 = "09rndb1fa9r7mhb2sc6p3k0pcarhg8mv0kfmvd1zdb0ciwwp7514"; 436 | type = "gem"; 437 | }; 438 | version = "2.1.0"; 439 | }; 440 | capistrano-rails = { 441 | dependencies = ["capistrano" "capistrano-bundler"]; 442 | groups = ["development"]; 443 | platforms = []; 444 | source = { 445 | remotes = ["https://rubygems.org"]; 446 | sha256 = "05lk7y4qyzadzzshjyhgfgx00ggqliq7n561wkx8m331wljv7kx7"; 447 | type = "gem"; 448 | }; 449 | version = "1.6.3"; 450 | }; 451 | capistrano-rbenv = { 452 | dependencies = ["capistrano" "sshkit"]; 453 | groups = ["development"]; 454 | platforms = []; 455 | source = { 456 | remotes = ["https://rubygems.org"]; 457 | sha256 = "1x9m1i5zd0wx122zw3m40zprlmxk9d47bd6w61k81wr4qsvkk3rw"; 458 | type = "gem"; 459 | }; 460 | version = "2.2.0"; 461 | }; 462 | capistrano-yarn = { 463 | dependencies = ["capistrano"]; 464 | groups = ["development"]; 465 | platforms = []; 466 | source = { 467 | remotes = ["https://rubygems.org"]; 468 | sha256 = "1zdg2s061vl5b8114n909mrjb2hc1qx0i4wqx9nacsrcjgyp07l9"; 469 | type = "gem"; 470 | }; 471 | version = "2.0.2"; 472 | }; 473 | capybara = { 474 | dependencies = ["addressable" "matrix" "mini_mime" "nokogiri" "rack" "rack-test" "regexp_parser" "xpath"]; 475 | groups = ["test"]; 476 | platforms = []; 477 | source = { 478 | remotes = ["https://rubygems.org"]; 479 | sha256 = "114qm5f5vhwaaw9rj1h2lcamh46zl13v1m18jiw68zl961gwmw6n"; 480 | type = "gem"; 481 | }; 482 | version = "3.39.2"; 483 | }; 484 | case_transform = { 485 | dependencies = ["activesupport"]; 486 | groups = ["default"]; 487 | platforms = []; 488 | source = { 489 | remotes = ["https://rubygems.org"]; 490 | sha256 = "0fzyws6spn5arqf6q604dh9mrj84a36k5hsc8z7jgcpfvhc49bg2"; 491 | type = "gem"; 492 | }; 493 | version = "0.2"; 494 | }; 495 | cbor = { 496 | groups = ["default"]; 497 | platforms = []; 498 | source = { 499 | remotes = ["https://rubygems.org"]; 500 | sha256 = "0511idr8xps9625nh3kxr68sdy6l3xy2kcz7r57g47fxb1v18jj3"; 501 | type = "gem"; 502 | }; 503 | version = "0.5.9.6"; 504 | }; 505 | charlock_holmes = { 506 | groups = ["default"]; 507 | platforms = []; 508 | source = { 509 | remotes = ["https://rubygems.org"]; 510 | sha256 = "0hybw8jw9ryvz5zrki3gc9r88jqy373m6v46ynxsdzv1ysiyr40p"; 511 | type = "gem"; 512 | }; 513 | version = "0.7.7"; 514 | }; 515 | chewy = { 516 | dependencies = ["activesupport" "elasticsearch" "elasticsearch-dsl"]; 517 | groups = ["default"]; 518 | platforms = []; 519 | source = { 520 | remotes = ["https://rubygems.org"]; 521 | sha256 = "087ybm1384f5sscvqwk3pcswxycy4y5q11m6587fidqvdc0ipkma"; 522 | type = "gem"; 523 | }; 524 | version = "7.3.3"; 525 | }; 526 | chunky_png = { 527 | groups = ["default"]; 528 | platforms = []; 529 | source = { 530 | remotes = ["https://rubygems.org"]; 531 | sha256 = "1znw5x86hmm9vfhidwdsijz8m38pqgmv98l9ryilvky0aldv7mc9"; 532 | type = "gem"; 533 | }; 534 | version = "1.4.0"; 535 | }; 536 | climate_control = { 537 | groups = ["test"]; 538 | platforms = []; 539 | source = { 540 | remotes = ["https://rubygems.org"]; 541 | sha256 = "0q11v0iabvr6rif0d025xh078ili5frrihlj0m04zfg7lgvagxji"; 542 | type = "gem"; 543 | }; 544 | version = "0.2.0"; 545 | }; 546 | cocoon = { 547 | groups = ["default"]; 548 | platforms = []; 549 | source = { 550 | remotes = ["https://rubygems.org"]; 551 | sha256 = "038z97pkhvsqbh6cmyyzj58ya968p24k7r0f0rx7sa2kjvk193yh"; 552 | type = "gem"; 553 | }; 554 | version = "1.2.15"; 555 | }; 556 | color_diff = { 557 | groups = ["default"]; 558 | platforms = []; 559 | source = { 560 | remotes = ["https://rubygems.org"]; 561 | sha256 = "01dpvqlzybpb3pkcwd9ik5sbjw283618ywvdphxslhiy8ps3kp4r"; 562 | type = "gem"; 563 | }; 564 | version = "0.1"; 565 | }; 566 | concurrent-ruby = { 567 | groups = ["default" "development" "pam_authentication" "production" "test"]; 568 | platforms = []; 569 | source = { 570 | remotes = ["https://rubygems.org"]; 571 | sha256 = "0krcwb6mn0iklajwngwsg850nk8k9b35dhmc2qkbdqvmifdi2y9q"; 572 | type = "gem"; 573 | }; 574 | version = "1.2.2"; 575 | }; 576 | connection_pool = { 577 | groups = ["default" "test"]; 578 | platforms = []; 579 | source = { 580 | remotes = ["https://rubygems.org"]; 581 | sha256 = "1x32mcpm2cl5492kd6lbjbaf17qsssmpx9kdyr7z1wcif2cwyh0g"; 582 | type = "gem"; 583 | }; 584 | version = "2.4.1"; 585 | }; 586 | cose = { 587 | dependencies = ["cbor" "openssl-signature_algorithm"]; 588 | groups = ["default"]; 589 | platforms = []; 590 | source = { 591 | remotes = ["https://rubygems.org"]; 592 | sha256 = "00c6x4ha7qiaaf88qdbyf240mk146zz78rbm4qwyaxmwlmk7q933"; 593 | type = "gem"; 594 | }; 595 | version = "1.3.0"; 596 | }; 597 | crack = { 598 | dependencies = ["rexml"]; 599 | groups = ["default" "test"]; 600 | platforms = []; 601 | source = { 602 | remotes = ["https://rubygems.org"]; 603 | sha256 = "1cr1kfpw3vkhysvkk3wg7c54m75kd68mbm9rs5azdjdq57xid13r"; 604 | type = "gem"; 605 | }; 606 | version = "0.4.5"; 607 | }; 608 | crass = { 609 | groups = ["default" "development" "pam_authentication" "production" "test"]; 610 | platforms = []; 611 | source = { 612 | remotes = ["https://rubygems.org"]; 613 | sha256 = "0pfl5c0pyqaparxaqxi6s4gfl21bdldwiawrc0aknyvflli60lfw"; 614 | type = "gem"; 615 | }; 616 | version = "1.0.6"; 617 | }; 618 | css_parser = { 619 | dependencies = ["addressable"]; 620 | groups = ["default"]; 621 | platforms = []; 622 | source = { 623 | remotes = ["https://rubygems.org"]; 624 | sha256 = "04q1vin8slr3k8mp76qz0wqgap6f9kdsbryvgfq9fljhrm463kpj"; 625 | type = "gem"; 626 | }; 627 | version = "1.14.0"; 628 | }; 629 | date = { 630 | groups = ["default" "development"]; 631 | platforms = []; 632 | source = { 633 | remotes = ["https://rubygems.org"]; 634 | sha256 = "03skfikihpx37rc27vr3hwrb057gxnmdzxhmzd4bf4jpkl0r55w1"; 635 | type = "gem"; 636 | }; 637 | version = "3.3.3"; 638 | }; 639 | debug_inspector = { 640 | groups = ["default" "development"]; 641 | platforms = []; 642 | source = { 643 | remotes = ["https://rubygems.org"]; 644 | sha256 = "01l678ng12rby6660pmwagmyg8nccvjfgs3487xna7ay378a59ga"; 645 | type = "gem"; 646 | }; 647 | version = "1.1.0"; 648 | }; 649 | devise = { 650 | dependencies = ["bcrypt" "orm_adapter" "railties" "responders" "warden"]; 651 | groups = ["default" "pam_authentication"]; 652 | platforms = []; 653 | source = { 654 | remotes = ["https://rubygems.org"]; 655 | sha256 = "0vpd7d61d4pfmyb2plnnv82wmczzlhw4k4gjhd2fv4r6vq8ilqqi"; 656 | type = "gem"; 657 | }; 658 | version = "4.9.2"; 659 | }; 660 | devise-two-factor = { 661 | dependencies = ["activesupport" "attr_encrypted" "devise" "railties" "rotp"]; 662 | groups = ["default"]; 663 | platforms = []; 664 | source = { 665 | remotes = ["https://rubygems.org"]; 666 | sha256 = "1nk43p339zyp4y5vab3w3s0zbjd4xfs8qn0ymxdnz6d961dbbdm8"; 667 | type = "gem"; 668 | }; 669 | version = "4.1.0"; 670 | }; 671 | devise_pam_authenticatable2 = { 672 | dependencies = ["devise" "rpam2"]; 673 | groups = ["pam_authentication"]; 674 | platforms = []; 675 | source = { 676 | remotes = ["https://rubygems.org"]; 677 | sha256 = "13ipl52pkhc6vxp8ca31viwv01237bi2bfk3b1fixq1x46nf87p2"; 678 | type = "gem"; 679 | }; 680 | version = "9.2.0"; 681 | }; 682 | diff-lcs = { 683 | groups = ["default" "test"]; 684 | platforms = []; 685 | source = { 686 | remotes = ["https://rubygems.org"]; 687 | sha256 = "0rwvjahnp7cpmracd8x732rjgnilqv2sx7d1gfrysslc3h039fa9"; 688 | type = "gem"; 689 | }; 690 | version = "1.5.0"; 691 | }; 692 | discard = { 693 | dependencies = ["activerecord"]; 694 | groups = ["default"]; 695 | platforms = []; 696 | source = { 697 | remotes = ["https://rubygems.org"]; 698 | sha256 = "1xavjhccyyzn9z6fz3034vgvzprc983mbrq6n9sc0drfw7m3vrip"; 699 | type = "gem"; 700 | }; 701 | version = "1.2.1"; 702 | }; 703 | docile = { 704 | groups = ["default" "test"]; 705 | platforms = []; 706 | source = { 707 | remotes = ["https://rubygems.org"]; 708 | sha256 = "1lxqxgq71rqwj1lpl9q1mbhhhhhhdkkj7my341f2889pwayk85sz"; 709 | type = "gem"; 710 | }; 711 | version = "1.4.0"; 712 | }; 713 | domain_name = { 714 | dependencies = ["unf"]; 715 | groups = ["default"]; 716 | platforms = []; 717 | source = { 718 | remotes = ["https://rubygems.org"]; 719 | sha256 = "0lcqjsmixjp52bnlgzh4lg9ppsk52x9hpwdjd53k8jnbah2602h0"; 720 | type = "gem"; 721 | }; 722 | version = "0.5.20190701"; 723 | }; 724 | doorkeeper = { 725 | dependencies = ["railties"]; 726 | groups = ["default"]; 727 | platforms = []; 728 | source = { 729 | remotes = ["https://rubygems.org"]; 730 | sha256 = "1q2pywgyn6cbnm0fh3dln5z1qgd1g8hvb4x8rppjc1bpfxnfhi13"; 731 | type = "gem"; 732 | }; 733 | version = "5.6.6"; 734 | }; 735 | dotenv = { 736 | groups = ["default"]; 737 | platforms = []; 738 | source = { 739 | remotes = ["https://rubygems.org"]; 740 | sha256 = "1n0pi8x8ql5h1mijvm8lgn6bhq4xjb5a500p5r1krq4s6j9lg565"; 741 | type = "gem"; 742 | }; 743 | version = "2.8.1"; 744 | }; 745 | dotenv-rails = { 746 | dependencies = ["dotenv" "railties"]; 747 | groups = ["default"]; 748 | platforms = []; 749 | source = { 750 | remotes = ["https://rubygems.org"]; 751 | sha256 = "0v0gcbxzypcvy6fqq4gp80jb310xvdwj5n8qw9ci67g5yjvq2nxh"; 752 | type = "gem"; 753 | }; 754 | version = "2.8.1"; 755 | }; 756 | ed25519 = { 757 | groups = ["default"]; 758 | platforms = []; 759 | source = { 760 | remotes = ["https://rubygems.org"]; 761 | sha256 = "0zb2dr2ihb1qiknn5iaj1ha1w9p7lj9yq5waasndlfadz225ajji"; 762 | type = "gem"; 763 | }; 764 | version = "1.3.0"; 765 | }; 766 | elasticsearch = { 767 | dependencies = ["elasticsearch-api" "elasticsearch-transport"]; 768 | groups = ["default"]; 769 | platforms = []; 770 | source = { 771 | remotes = ["https://rubygems.org"]; 772 | sha256 = "0havyxmvl157a653prspnbhgdchlx44xqxl170v1im5ggxwavcaq"; 773 | type = "gem"; 774 | }; 775 | version = "7.13.3"; 776 | }; 777 | elasticsearch-api = { 778 | dependencies = ["multi_json"]; 779 | groups = ["default"]; 780 | platforms = []; 781 | source = { 782 | remotes = ["https://rubygems.org"]; 783 | sha256 = "0bmssarkk7lqkjdn8c9j7jvxcnn4hg1zcmhsky8bfvc99k33b3w8"; 784 | type = "gem"; 785 | }; 786 | version = "7.13.3"; 787 | }; 788 | elasticsearch-dsl = { 789 | groups = ["default"]; 790 | platforms = []; 791 | source = { 792 | remotes = ["https://rubygems.org"]; 793 | sha256 = "174m3fwm3mawbkjg2xbmqvljq7ava4s95m8vpg5khcvfj506wxfk"; 794 | type = "gem"; 795 | }; 796 | version = "0.1.10"; 797 | }; 798 | elasticsearch-transport = { 799 | dependencies = ["faraday" "multi_json"]; 800 | groups = ["default"]; 801 | platforms = []; 802 | source = { 803 | remotes = ["https://rubygems.org"]; 804 | sha256 = "0blfii8qvj0m6bg9sbfynxc40in7zfmw2wpi4clv7d9gclk053db"; 805 | type = "gem"; 806 | }; 807 | version = "7.13.3"; 808 | }; 809 | encryptor = { 810 | groups = ["default"]; 811 | platforms = []; 812 | source = { 813 | remotes = ["https://rubygems.org"]; 814 | sha256 = "0s8rvfl0vn8w7k1sgkc234060jh468s3zd45xa64p1jdmfa3zwmb"; 815 | type = "gem"; 816 | }; 817 | version = "3.0.0"; 818 | }; 819 | erubi = { 820 | groups = ["default" "development" "pam_authentication" "production" "test"]; 821 | platforms = []; 822 | source = { 823 | remotes = ["https://rubygems.org"]; 824 | sha256 = "08s75vs9cxlc4r1q2bjg4br8g9wc5lc5x5vl0vv4zq5ivxsdpgi7"; 825 | type = "gem"; 826 | }; 827 | version = "1.12.0"; 828 | }; 829 | et-orbi = { 830 | dependencies = ["tzinfo"]; 831 | groups = ["default"]; 832 | platforms = []; 833 | source = { 834 | remotes = ["https://rubygems.org"]; 835 | sha256 = "1d2z4ky2v15dpcz672i2p7lb2nc793dasq3yq3660h2az53kss9v"; 836 | type = "gem"; 837 | }; 838 | version = "1.2.7"; 839 | }; 840 | excon = { 841 | groups = ["default"]; 842 | platforms = []; 843 | source = { 844 | remotes = ["https://rubygems.org"]; 845 | sha256 = "08r6qgbpkxxsihjmlspk3l1sr69q5hx35p1l4wp7rmkbzys89867"; 846 | type = "gem"; 847 | }; 848 | version = "0.100.0"; 849 | }; 850 | fabrication = { 851 | groups = ["test"]; 852 | platforms = []; 853 | source = { 854 | remotes = ["https://rubygems.org"]; 855 | sha256 = "0bxssmjp49whzq2zv7w751gr4nkdaiwcxd1vda0byigwyrnj6f5q"; 856 | type = "gem"; 857 | }; 858 | version = "2.30.0"; 859 | }; 860 | faker = { 861 | dependencies = ["i18n"]; 862 | groups = ["test"]; 863 | platforms = []; 864 | source = { 865 | remotes = ["https://rubygems.org"]; 866 | sha256 = "1i3l58jrcapkp70v3swr0x4s6bj1101920al50wsaaj9dv0vhvm7"; 867 | type = "gem"; 868 | }; 869 | version = "3.2.0"; 870 | }; 871 | faraday = { 872 | 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"]; 873 | groups = ["default"]; 874 | platforms = []; 875 | source = { 876 | remotes = ["https://rubygems.org"]; 877 | sha256 = "1c760q0ks4vj4wmaa7nh1dgvgqiwaw0mjr7v8cymy7i3ffgjxx90"; 878 | type = "gem"; 879 | }; 880 | version = "1.10.3"; 881 | }; 882 | faraday-em_http = { 883 | groups = ["default"]; 884 | platforms = []; 885 | source = { 886 | remotes = ["https://rubygems.org"]; 887 | sha256 = "12cnqpbak4vhikrh2cdn94assh3yxza8rq2p9w2j34bqg5q4qgbs"; 888 | type = "gem"; 889 | }; 890 | version = "1.0.0"; 891 | }; 892 | faraday-em_synchrony = { 893 | groups = ["default"]; 894 | platforms = []; 895 | source = { 896 | remotes = ["https://rubygems.org"]; 897 | sha256 = "1vgrbhkp83sngv6k4mii9f2s9v5lmp693hylfxp2ssfc60fas3a6"; 898 | type = "gem"; 899 | }; 900 | version = "1.0.0"; 901 | }; 902 | faraday-excon = { 903 | groups = ["default"]; 904 | platforms = []; 905 | source = { 906 | remotes = ["https://rubygems.org"]; 907 | sha256 = "0h09wkb0k0bhm6dqsd47ac601qiaah8qdzjh8gvxfd376x1chmdh"; 908 | type = "gem"; 909 | }; 910 | version = "1.1.0"; 911 | }; 912 | faraday-httpclient = { 913 | groups = ["default"]; 914 | platforms = []; 915 | source = { 916 | remotes = ["https://rubygems.org"]; 917 | sha256 = "0fyk0jd3ks7fdn8nv3spnwjpzx2lmxmg2gh4inz3by1zjzqg33sc"; 918 | type = "gem"; 919 | }; 920 | version = "1.0.1"; 921 | }; 922 | faraday-multipart = { 923 | dependencies = ["multipart-post"]; 924 | groups = ["default"]; 925 | platforms = []; 926 | source = { 927 | remotes = ["https://rubygems.org"]; 928 | sha256 = "09871c4hd7s5ws1wl4gs7js1k2wlby6v947m2bbzg43pnld044lh"; 929 | type = "gem"; 930 | }; 931 | version = "1.0.4"; 932 | }; 933 | faraday-net_http = { 934 | groups = ["default"]; 935 | platforms = []; 936 | source = { 937 | remotes = ["https://rubygems.org"]; 938 | sha256 = "1fi8sda5hc54v1w3mqfl5yz09nhx35kglyx72w7b8xxvdr0cwi9j"; 939 | type = "gem"; 940 | }; 941 | version = "1.0.1"; 942 | }; 943 | faraday-net_http_persistent = { 944 | groups = ["default"]; 945 | platforms = []; 946 | source = { 947 | remotes = ["https://rubygems.org"]; 948 | sha256 = "0dc36ih95qw3rlccffcb0vgxjhmipsvxhn6cw71l7ffs0f7vq30b"; 949 | type = "gem"; 950 | }; 951 | version = "1.2.0"; 952 | }; 953 | faraday-patron = { 954 | groups = ["default"]; 955 | platforms = []; 956 | source = { 957 | remotes = ["https://rubygems.org"]; 958 | sha256 = "19wgsgfq0xkski1g7m96snv39la3zxz6x7nbdgiwhg5v82rxfb6w"; 959 | type = "gem"; 960 | }; 961 | version = "1.0.0"; 962 | }; 963 | faraday-rack = { 964 | groups = ["default"]; 965 | platforms = []; 966 | source = { 967 | remotes = ["https://rubygems.org"]; 968 | sha256 = "1h184g4vqql5jv9s9im6igy00jp6mrah2h14py6mpf9bkabfqq7g"; 969 | type = "gem"; 970 | }; 971 | version = "1.0.0"; 972 | }; 973 | faraday-retry = { 974 | groups = ["default"]; 975 | platforms = []; 976 | source = { 977 | remotes = ["https://rubygems.org"]; 978 | sha256 = "153i967yrwnswqgvnnajgwp981k9p50ys1h80yz3q94rygs59ldd"; 979 | type = "gem"; 980 | }; 981 | version = "1.0.3"; 982 | }; 983 | fast_blank = { 984 | groups = ["default"]; 985 | platforms = []; 986 | source = { 987 | remotes = ["https://rubygems.org"]; 988 | sha256 = "1shpmamyzyhyxmv95r96ja5rylzaw60r19647d0fdm7y2h2c77r6"; 989 | type = "gem"; 990 | }; 991 | version = "1.0.1"; 992 | }; 993 | fastimage = { 994 | groups = ["default"]; 995 | platforms = []; 996 | source = { 997 | remotes = ["https://rubygems.org"]; 998 | sha256 = "1pd7pamzhdz2w0fbcvsfn2nyslznvphnwj16zw35g2b28zd2xyzx"; 999 | type = "gem"; 1000 | }; 1001 | version = "2.2.7"; 1002 | }; 1003 | ffi = { 1004 | groups = ["default"]; 1005 | platforms = []; 1006 | source = { 1007 | remotes = ["https://rubygems.org"]; 1008 | sha256 = "1862ydmclzy1a0cjbvm8dz7847d9rch495ib0zb64y84d3xd4bkg"; 1009 | type = "gem"; 1010 | }; 1011 | version = "1.15.5"; 1012 | }; 1013 | ffi-compiler = { 1014 | dependencies = ["ffi" "rake"]; 1015 | groups = ["default"]; 1016 | platforms = []; 1017 | source = { 1018 | remotes = ["https://rubygems.org"]; 1019 | sha256 = "0c2caqm9wqnbidcb8dj4wd3s902z15qmgxplwyfyqbwa0ydki7q1"; 1020 | type = "gem"; 1021 | }; 1022 | version = "1.0.1"; 1023 | }; 1024 | fog-core = { 1025 | dependencies = ["builder" "excon" "formatador" "mime-types"]; 1026 | groups = ["default"]; 1027 | platforms = []; 1028 | source = { 1029 | remotes = ["https://rubygems.org"]; 1030 | sha256 = "1agd6xgzk0rxrsjdpn94v4hy89s0nm2cs4zg2p880w2dan9xgrak"; 1031 | type = "gem"; 1032 | }; 1033 | version = "2.1.0"; 1034 | }; 1035 | fog-json = { 1036 | dependencies = ["fog-core" "multi_json"]; 1037 | groups = ["default"]; 1038 | platforms = []; 1039 | source = { 1040 | remotes = ["https://rubygems.org"]; 1041 | sha256 = "1zj8llzc119zafbmfa4ai3z5s7c4vp9akfs0f9l2piyvcarmlkyx"; 1042 | type = "gem"; 1043 | }; 1044 | version = "1.2.0"; 1045 | }; 1046 | fog-openstack = { 1047 | dependencies = ["fog-core" "fog-json" "ipaddress"]; 1048 | groups = ["default"]; 1049 | platforms = []; 1050 | source = { 1051 | remotes = ["https://rubygems.org"]; 1052 | sha256 = "11j18h61d3p0pcp9k5346lbj1lahab1dqybkrx9338932lmjn7ap"; 1053 | type = "gem"; 1054 | }; 1055 | version = "0.3.10"; 1056 | }; 1057 | formatador = { 1058 | groups = ["default"]; 1059 | platforms = []; 1060 | source = { 1061 | remotes = ["https://rubygems.org"]; 1062 | sha256 = "0mprf1dwznz5ld0q1jpbyl59fwnwk6azspnd0am7zz7kfg3pxhv5"; 1063 | type = "gem"; 1064 | }; 1065 | version = "0.3.0"; 1066 | }; 1067 | fugit = { 1068 | dependencies = ["et-orbi" "raabro"]; 1069 | groups = ["default"]; 1070 | platforms = []; 1071 | source = { 1072 | remotes = ["https://rubygems.org"]; 1073 | sha256 = "1cm2lrvhrpqq19hbdsxf4lq2nkb2qdldbdxh3gvi15l62dlb5zqq"; 1074 | type = "gem"; 1075 | }; 1076 | version = "1.8.1"; 1077 | }; 1078 | fuubar = { 1079 | dependencies = ["rspec-core" "ruby-progressbar"]; 1080 | groups = ["test"]; 1081 | platforms = []; 1082 | source = { 1083 | remotes = ["https://rubygems.org"]; 1084 | sha256 = "1028vn7j3kc5qqwswrf3has3qm4j9xva70xmzb3n29i89f0afwmj"; 1085 | type = "gem"; 1086 | }; 1087 | version = "2.5.1"; 1088 | }; 1089 | globalid = { 1090 | dependencies = ["activesupport"]; 1091 | groups = ["default" "development"]; 1092 | platforms = []; 1093 | source = { 1094 | remotes = ["https://rubygems.org"]; 1095 | sha256 = "0kqm5ndzaybpnpxqiqkc41k4ksyxl41ln8qqr6kb130cdxsf2dxk"; 1096 | type = "gem"; 1097 | }; 1098 | version = "1.1.0"; 1099 | }; 1100 | haml = { 1101 | dependencies = ["temple" "thor" "tilt"]; 1102 | groups = ["default" "development"]; 1103 | platforms = []; 1104 | source = { 1105 | remotes = ["https://rubygems.org"]; 1106 | sha256 = "1vcr5wcvfbsq91302playk3i98wdisspkybcmajl04agv4k8xr68"; 1107 | type = "gem"; 1108 | }; 1109 | version = "6.1.1"; 1110 | }; 1111 | haml-rails = { 1112 | dependencies = ["actionpack" "activesupport" "haml" "railties"]; 1113 | groups = ["default"]; 1114 | platforms = []; 1115 | source = { 1116 | remotes = ["https://rubygems.org"]; 1117 | sha256 = "1sjrdwc4azzfpsp2xk0365z031482gcrs0c54d5wx0igkqca0fr7"; 1118 | type = "gem"; 1119 | }; 1120 | version = "2.1.0"; 1121 | }; 1122 | haml_lint = { 1123 | dependencies = ["haml" "parallel" "rainbow" "rubocop" "sysexits"]; 1124 | groups = ["development"]; 1125 | platforms = []; 1126 | source = { 1127 | remotes = ["https://rubygems.org"]; 1128 | sha256 = "1fwa7gpxc7crzf5nqc40n2ciqpdk57y213asl6kkbzxnjfl0v319"; 1129 | type = "gem"; 1130 | }; 1131 | version = "0.48.0"; 1132 | }; 1133 | hashdiff = { 1134 | groups = ["default" "test"]; 1135 | platforms = []; 1136 | source = { 1137 | remotes = ["https://rubygems.org"]; 1138 | sha256 = "1nynpl0xbj0nphqx1qlmyggq58ms1phf5i03hk64wcc0a17x1m1c"; 1139 | type = "gem"; 1140 | }; 1141 | version = "1.0.1"; 1142 | }; 1143 | hashie = { 1144 | groups = ["default"]; 1145 | platforms = []; 1146 | source = { 1147 | remotes = ["https://rubygems.org"]; 1148 | sha256 = "1nh3arcrbz1rc1cr59qm53sdhqm137b258y8rcb4cvd3y98lwv4x"; 1149 | type = "gem"; 1150 | }; 1151 | version = "5.0.0"; 1152 | }; 1153 | hcaptcha = { 1154 | dependencies = ["json"]; 1155 | groups = ["default"]; 1156 | platforms = []; 1157 | source = { 1158 | remotes = ["https://rubygems.org"]; 1159 | sha256 = "0fh6391zlv2ikvzqj2gymb70k1avk1j9da8bzgw0scsz2wqq98m2"; 1160 | type = "gem"; 1161 | }; 1162 | version = "7.1.0"; 1163 | }; 1164 | highline = { 1165 | groups = ["default" "development"]; 1166 | platforms = []; 1167 | source = { 1168 | remotes = ["https://rubygems.org"]; 1169 | sha256 = "1f8cr014j7mdqpdb9q17fp5vb5b8n1pswqaif91s3ylg5x3pygfn"; 1170 | type = "gem"; 1171 | }; 1172 | version = "2.1.0"; 1173 | }; 1174 | hiredis = { 1175 | groups = ["default"]; 1176 | platforms = []; 1177 | source = { 1178 | remotes = ["https://rubygems.org"]; 1179 | sha256 = "04jj8k7lxqxw24sp0jiravigdkgsyrpprxpxm71ba93x1wr2w1bz"; 1180 | type = "gem"; 1181 | }; 1182 | version = "0.6.3"; 1183 | }; 1184 | hkdf = { 1185 | groups = ["default"]; 1186 | platforms = []; 1187 | source = { 1188 | remotes = ["https://rubygems.org"]; 1189 | sha256 = "04fixg0a51n4vy0j6c1hvisa2yl33m3jrrpxpb5sq6j511vjriil"; 1190 | type = "gem"; 1191 | }; 1192 | version = "0.3.0"; 1193 | }; 1194 | htmlentities = { 1195 | groups = ["default"]; 1196 | platforms = []; 1197 | source = { 1198 | remotes = ["https://rubygems.org"]; 1199 | sha256 = "1nkklqsn8ir8wizzlakncfv42i32wc0w9hxp00hvdlgjr7376nhj"; 1200 | type = "gem"; 1201 | }; 1202 | version = "4.3.4"; 1203 | }; 1204 | http = { 1205 | dependencies = ["addressable" "http-cookie" "http-form_data" "llhttp-ffi"]; 1206 | groups = ["default"]; 1207 | platforms = []; 1208 | source = { 1209 | remotes = ["https://rubygems.org"]; 1210 | sha256 = "1bzb8p31kzv6q5p4z5xq88mnqk414rrw0y5rkhpnvpl29x5c3bpw"; 1211 | type = "gem"; 1212 | }; 1213 | version = "5.1.1"; 1214 | }; 1215 | http-cookie = { 1216 | dependencies = ["domain_name"]; 1217 | groups = ["default"]; 1218 | platforms = []; 1219 | source = { 1220 | remotes = ["https://rubygems.org"]; 1221 | sha256 = "13rilvlv8kwbzqfb644qp6hrbsj82cbqmnzcvqip1p6vqx36sxbk"; 1222 | type = "gem"; 1223 | }; 1224 | version = "1.0.5"; 1225 | }; 1226 | http-form_data = { 1227 | groups = ["default"]; 1228 | platforms = []; 1229 | source = { 1230 | remotes = ["https://rubygems.org"]; 1231 | sha256 = "1wx591jdhy84901pklh1n9sgh74gnvq1qyqxwchni1yrc49ynknc"; 1232 | type = "gem"; 1233 | }; 1234 | version = "2.3.0"; 1235 | }; 1236 | http_accept_language = { 1237 | groups = ["default"]; 1238 | platforms = []; 1239 | source = { 1240 | remotes = ["https://rubygems.org"]; 1241 | sha256 = "0d0nlfz9vm4jr1l6q0chx4rp2hrnrfbx3gadc1dz930lbbaz0hq0"; 1242 | type = "gem"; 1243 | }; 1244 | version = "2.1.1"; 1245 | }; 1246 | httpclient = { 1247 | groups = ["default"]; 1248 | platforms = []; 1249 | source = { 1250 | remotes = ["https://rubygems.org"]; 1251 | sha256 = "19mxmvghp7ki3klsxwrlwr431li7hm1lczhhj8z4qihl2acy8l99"; 1252 | type = "gem"; 1253 | }; 1254 | version = "2.8.3"; 1255 | }; 1256 | httplog = { 1257 | dependencies = ["rack" "rainbow"]; 1258 | groups = ["default"]; 1259 | platforms = []; 1260 | source = { 1261 | remotes = ["https://rubygems.org"]; 1262 | sha256 = "0zjsgrlvwpqsnrza4ijlxjld4550c661sgbqp2j2wp638nlnls1a"; 1263 | type = "gem"; 1264 | }; 1265 | version = "1.6.2"; 1266 | }; 1267 | i18n = { 1268 | dependencies = ["concurrent-ruby"]; 1269 | groups = ["default" "development" "pam_authentication" "production" "test"]; 1270 | platforms = []; 1271 | source = { 1272 | remotes = ["https://rubygems.org"]; 1273 | sha256 = "0qaamqsh5f3szhcakkak8ikxlzxqnv49n2p7504hcz2l0f4nj0wx"; 1274 | type = "gem"; 1275 | }; 1276 | version = "1.14.1"; 1277 | }; 1278 | i18n-tasks = { 1279 | dependencies = ["activesupport" "ast" "better_html" "erubi" "highline" "i18n" "parser" "rails-i18n" "rainbow" "terminal-table"]; 1280 | groups = ["development"]; 1281 | platforms = []; 1282 | source = { 1283 | remotes = ["https://rubygems.org"]; 1284 | sha256 = "19zkcsqwzc3i6vizj26mxxww6m5grv9zmp6yxyswbqq9kyzb081z"; 1285 | type = "gem"; 1286 | }; 1287 | version = "1.0.12"; 1288 | }; 1289 | idn-ruby = { 1290 | groups = ["default"]; 1291 | platforms = []; 1292 | source = { 1293 | remotes = ["https://rubygems.org"]; 1294 | sha256 = "0dy04jx3n1ddz744b80mg7hp87miysnjp0h21lqr43hpmhdglxih"; 1295 | type = "gem"; 1296 | }; 1297 | version = "0.1.5"; 1298 | }; 1299 | ipaddress = { 1300 | groups = ["default"]; 1301 | platforms = []; 1302 | source = { 1303 | remotes = ["https://rubygems.org"]; 1304 | sha256 = "1x86s0s11w202j6ka40jbmywkrx8fhq8xiy8mwvnkhllj57hqr45"; 1305 | type = "gem"; 1306 | }; 1307 | version = "0.8.3"; 1308 | }; 1309 | jmespath = { 1310 | groups = ["default"]; 1311 | platforms = []; 1312 | source = { 1313 | remotes = ["https://rubygems.org"]; 1314 | sha256 = "1cdw9vw2qly7q7r41s7phnac264rbsdqgj4l0h4nqgbjb157g393"; 1315 | type = "gem"; 1316 | }; 1317 | version = "1.6.2"; 1318 | }; 1319 | json = { 1320 | groups = ["default" "development"]; 1321 | platforms = []; 1322 | source = { 1323 | remotes = ["https://rubygems.org"]; 1324 | sha256 = "0nalhin1gda4v8ybk6lq8f407cgfrj6qzn234yra4ipkmlbfmal6"; 1325 | type = "gem"; 1326 | }; 1327 | version = "2.6.3"; 1328 | }; 1329 | json-canonicalization = { 1330 | groups = ["default"]; 1331 | platforms = []; 1332 | source = { 1333 | remotes = ["https://rubygems.org"]; 1334 | sha256 = "1rvsalsrs8njk2gqxgq0ydg5cd02jqdawskbq2ccz663qxz8wwq5"; 1335 | type = "gem"; 1336 | }; 1337 | version = "0.3.2"; 1338 | }; 1339 | json-jwt = { 1340 | dependencies = ["activesupport" "aes_key_wrap" "bindata" "httpclient"]; 1341 | groups = ["default"]; 1342 | platforms = []; 1343 | source = { 1344 | remotes = ["https://rubygems.org"]; 1345 | sha256 = "04315mf4p9qa97grdfqv922paghzdfrbb982ap0p99rqwla4znv6"; 1346 | type = "gem"; 1347 | }; 1348 | version = "1.15.3"; 1349 | }; 1350 | json-ld = { 1351 | dependencies = ["htmlentities" "json-canonicalization" "link_header" "multi_json" "rack" "rdf"]; 1352 | groups = ["default"]; 1353 | platforms = []; 1354 | source = { 1355 | remotes = ["https://rubygems.org"]; 1356 | sha256 = "1z3kqacjmqs02vwwqm9di7sw7f7nchxx99v84myrrzmh64c6zfcq"; 1357 | type = "gem"; 1358 | }; 1359 | version = "3.2.5"; 1360 | }; 1361 | json-ld-preloaded = { 1362 | dependencies = ["json-ld" "rdf"]; 1363 | groups = ["default"]; 1364 | platforms = []; 1365 | source = { 1366 | remotes = ["https://rubygems.org"]; 1367 | sha256 = "004s52m37b2kbw8dv4rdfm2d90h1023z1mw9zfcs0x87v8aq7zyn"; 1368 | type = "gem"; 1369 | }; 1370 | version = "3.2.2"; 1371 | }; 1372 | json-schema = { 1373 | dependencies = ["addressable"]; 1374 | groups = ["test"]; 1375 | platforms = []; 1376 | source = { 1377 | remotes = ["https://rubygems.org"]; 1378 | sha256 = "155rygs093i8i04i38a97hs5icmqk2jkkhx76w31yxyr3bxfbgx3"; 1379 | type = "gem"; 1380 | }; 1381 | version = "4.0.0"; 1382 | }; 1383 | jsonapi-renderer = { 1384 | groups = ["default"]; 1385 | platforms = []; 1386 | source = { 1387 | remotes = ["https://rubygems.org"]; 1388 | sha256 = "0ys4drd0k9rw5ixf8n8fx8v0pjh792w4myh0cpdspd317l1lpi5m"; 1389 | type = "gem"; 1390 | }; 1391 | version = "0.2.2"; 1392 | }; 1393 | jwt = { 1394 | groups = ["default"]; 1395 | platforms = []; 1396 | source = { 1397 | remotes = ["https://rubygems.org"]; 1398 | sha256 = "16z11alz13vfc4zs5l3fk6n51n2jw9lskvc4h4prnww0y797qd87"; 1399 | type = "gem"; 1400 | }; 1401 | version = "2.7.1"; 1402 | }; 1403 | kaminari = { 1404 | dependencies = ["activesupport" "kaminari-actionview" "kaminari-activerecord" "kaminari-core"]; 1405 | groups = ["default"]; 1406 | platforms = []; 1407 | source = { 1408 | remotes = ["https://rubygems.org"]; 1409 | sha256 = "0gia8irryvfhcr6bsr64kpisbgdbqjsqfgrk12a11incmpwny1y4"; 1410 | type = "gem"; 1411 | }; 1412 | version = "1.2.2"; 1413 | }; 1414 | kaminari-actionview = { 1415 | dependencies = ["actionview" "kaminari-core"]; 1416 | groups = ["default"]; 1417 | platforms = []; 1418 | source = { 1419 | remotes = ["https://rubygems.org"]; 1420 | sha256 = "02f9ghl3a9b5q7l079d3yzmqjwkr4jigi7sldbps992rigygcc0k"; 1421 | type = "gem"; 1422 | }; 1423 | version = "1.2.2"; 1424 | }; 1425 | kaminari-activerecord = { 1426 | dependencies = ["activerecord" "kaminari-core"]; 1427 | groups = ["default"]; 1428 | platforms = []; 1429 | source = { 1430 | remotes = ["https://rubygems.org"]; 1431 | sha256 = "0c148z97s1cqivzbwrak149z7kl1rdmj7dxk6rpkasimmdxsdlqd"; 1432 | type = "gem"; 1433 | }; 1434 | version = "1.2.2"; 1435 | }; 1436 | kaminari-core = { 1437 | groups = ["default"]; 1438 | platforms = []; 1439 | source = { 1440 | remotes = ["https://rubygems.org"]; 1441 | sha256 = "1zw3pg6kj39y7jxakbx7if59pl28lhk98fx71ks5lr3hfgn6zliv"; 1442 | type = "gem"; 1443 | }; 1444 | version = "1.2.2"; 1445 | }; 1446 | kt-paperclip = { 1447 | dependencies = ["activemodel" "activesupport" "marcel" "mime-types" "terrapin"]; 1448 | groups = ["default"]; 1449 | platforms = []; 1450 | source = { 1451 | remotes = ["https://rubygems.org"]; 1452 | sha256 = "0qrv9xyxxhxr482p25f3m7nfghw66i8jl02hy9b6pwam8m1knngp"; 1453 | type = "gem"; 1454 | }; 1455 | version = "7.2.0"; 1456 | }; 1457 | language_server-protocol = { 1458 | groups = ["default" "development"]; 1459 | platforms = []; 1460 | source = { 1461 | remotes = ["https://rubygems.org"]; 1462 | sha256 = "0gvb1j8xsqxms9mww01rmdl78zkd72zgxaap56bhv8j45z05hp1x"; 1463 | type = "gem"; 1464 | }; 1465 | version = "3.17.0.3"; 1466 | }; 1467 | launchy = { 1468 | dependencies = ["addressable"]; 1469 | groups = ["default" "development"]; 1470 | platforms = []; 1471 | source = { 1472 | remotes = ["https://rubygems.org"]; 1473 | sha256 = "06r43899384das2bkbrpsdxsafyyqa94il7111053idfalb4984a"; 1474 | type = "gem"; 1475 | }; 1476 | version = "2.5.2"; 1477 | }; 1478 | letter_opener = { 1479 | dependencies = ["launchy"]; 1480 | groups = ["development"]; 1481 | platforms = []; 1482 | source = { 1483 | remotes = ["https://rubygems.org"]; 1484 | sha256 = "1y5d4ip4l12v58bgazadl45iv3a5j7jp2gwg96b6jy378zn42a1d"; 1485 | type = "gem"; 1486 | }; 1487 | version = "1.8.1"; 1488 | }; 1489 | letter_opener_web = { 1490 | dependencies = ["actionmailer" "letter_opener" "railties" "rexml"]; 1491 | groups = ["development"]; 1492 | platforms = []; 1493 | source = { 1494 | remotes = ["https://rubygems.org"]; 1495 | sha256 = "0vvvaz2ngaxv0s6sj25gdvp73vd8pfl8q3jharadg18p3va0m1ik"; 1496 | type = "gem"; 1497 | }; 1498 | version = "2.0.0"; 1499 | }; 1500 | link_header = { 1501 | groups = ["default"]; 1502 | platforms = []; 1503 | source = { 1504 | remotes = ["https://rubygems.org"]; 1505 | sha256 = "1yamrdq4rywmnpdhbygnkkl9fdy249fg5r851nrkkxr97gj5rihm"; 1506 | type = "gem"; 1507 | }; 1508 | version = "0.0.8"; 1509 | }; 1510 | llhttp-ffi = { 1511 | dependencies = ["ffi-compiler" "rake"]; 1512 | groups = ["default"]; 1513 | platforms = []; 1514 | source = { 1515 | remotes = ["https://rubygems.org"]; 1516 | sha256 = "00dh6zmqdj59rhcya0l4b9aaxq6n8xizfbil93k0g06gndyk5xz5"; 1517 | type = "gem"; 1518 | }; 1519 | version = "0.4.0"; 1520 | }; 1521 | lograge = { 1522 | dependencies = ["actionpack" "activesupport" "railties" "request_store"]; 1523 | groups = ["production"]; 1524 | platforms = []; 1525 | source = { 1526 | remotes = ["https://rubygems.org"]; 1527 | sha256 = "15pjm9pa5m3mbv9xvfgfr16q4jyaznsg8y63jz9x4jqr8npw0vx3"; 1528 | type = "gem"; 1529 | }; 1530 | version = "0.12.0"; 1531 | }; 1532 | loofah = { 1533 | dependencies = ["crass" "nokogiri"]; 1534 | groups = ["default" "development" "pam_authentication" "production" "test"]; 1535 | platforms = []; 1536 | source = { 1537 | remotes = ["https://rubygems.org"]; 1538 | sha256 = "1p744kjpb5zk2ihklbykzii77alycjc04vpnm2ch2f3cp65imlj3"; 1539 | type = "gem"; 1540 | }; 1541 | version = "2.21.3"; 1542 | }; 1543 | mail = { 1544 | dependencies = ["mini_mime" "net-imap" "net-pop" "net-smtp"]; 1545 | groups = ["default" "development"]; 1546 | platforms = []; 1547 | source = { 1548 | remotes = ["https://rubygems.org"]; 1549 | sha256 = "1bf9pysw1jfgynv692hhaycfxa8ckay1gjw5hz3madrbrynryfzc"; 1550 | type = "gem"; 1551 | }; 1552 | version = "2.8.1"; 1553 | }; 1554 | marcel = { 1555 | groups = ["default"]; 1556 | platforms = []; 1557 | source = { 1558 | remotes = ["https://rubygems.org"]; 1559 | sha256 = "0kky3yiwagsk8gfbzn3mvl2fxlh3b39v6nawzm4wpjs6xxvvc4x0"; 1560 | type = "gem"; 1561 | }; 1562 | version = "1.0.2"; 1563 | }; 1564 | mario-redis-lock = { 1565 | dependencies = ["redis"]; 1566 | groups = ["default"]; 1567 | platforms = []; 1568 | source = { 1569 | remotes = ["https://rubygems.org"]; 1570 | sha256 = "1v9wdjcjqzpns2migxp4a5b4w82mipi0fwihbqz3q2qj2qm7wc17"; 1571 | type = "gem"; 1572 | }; 1573 | version = "1.2.1"; 1574 | }; 1575 | matrix = { 1576 | groups = ["default" "test"]; 1577 | platforms = []; 1578 | source = { 1579 | remotes = ["https://rubygems.org"]; 1580 | sha256 = "1h2cgkpzkh3dd0flnnwfq6f3nl2b1zff9lvqz8xs853ssv5kq23i"; 1581 | type = "gem"; 1582 | }; 1583 | version = "0.4.2"; 1584 | }; 1585 | memory_profiler = { 1586 | groups = ["development"]; 1587 | platforms = []; 1588 | source = { 1589 | remotes = ["https://rubygems.org"]; 1590 | sha256 = "1c81d68r4wx0ckbmqxlfqc2qpd94jwcmqdm0xgr0s46r48pv9k9q"; 1591 | type = "gem"; 1592 | }; 1593 | version = "1.0.1"; 1594 | }; 1595 | method_source = { 1596 | groups = ["default" "development" "pam_authentication" "production" "test"]; 1597 | platforms = []; 1598 | source = { 1599 | remotes = ["https://rubygems.org"]; 1600 | sha256 = "1pnyh44qycnf9mzi1j6fywd5fkskv3x7nmsqrrws0rjn5dd4ayfp"; 1601 | type = "gem"; 1602 | }; 1603 | version = "1.0.0"; 1604 | }; 1605 | mime-types = { 1606 | dependencies = ["mime-types-data"]; 1607 | groups = ["default"]; 1608 | platforms = []; 1609 | source = { 1610 | remotes = ["https://rubygems.org"]; 1611 | sha256 = "0ipw892jbksbxxcrlx9g5ljq60qx47pm24ywgfbyjskbcl78pkvb"; 1612 | type = "gem"; 1613 | }; 1614 | version = "3.4.1"; 1615 | }; 1616 | mime-types-data = { 1617 | groups = ["default"]; 1618 | platforms = []; 1619 | source = { 1620 | remotes = ["https://rubygems.org"]; 1621 | sha256 = "1pky3vzaxlgm9gw5wlqwwi7wsw3jrglrfflrppvvnsrlaiz043z9"; 1622 | type = "gem"; 1623 | }; 1624 | version = "3.2023.0218.1"; 1625 | }; 1626 | mini_mime = { 1627 | groups = ["default" "development" "test"]; 1628 | platforms = []; 1629 | source = { 1630 | remotes = ["https://rubygems.org"]; 1631 | sha256 = "0lbim375gw2dk6383qirz13hgdmxlan0vc5da2l072j3qw6fqjm5"; 1632 | type = "gem"; 1633 | }; 1634 | version = "1.1.2"; 1635 | }; 1636 | mini_portile2 = { 1637 | groups = ["default" "development" "pam_authentication" "production" "test"]; 1638 | platforms = []; 1639 | source = { 1640 | remotes = ["https://rubygems.org"]; 1641 | sha256 = "0z7f38iq37h376n9xbl4gajdrnwzq284c9v1py4imw3gri2d5cj6"; 1642 | type = "gem"; 1643 | }; 1644 | version = "2.8.2"; 1645 | }; 1646 | minitest = { 1647 | groups = ["default" "development" "pam_authentication" "production" "test"]; 1648 | platforms = []; 1649 | source = { 1650 | remotes = ["https://rubygems.org"]; 1651 | sha256 = "1kg9wh7jlc9zsr3hkhpzkbn0ynf4np5ap9m2d8xdrb8shy0y6pmb"; 1652 | type = "gem"; 1653 | }; 1654 | version = "5.18.1"; 1655 | }; 1656 | msgpack = { 1657 | groups = ["default"]; 1658 | platforms = []; 1659 | source = { 1660 | remotes = ["https://rubygems.org"]; 1661 | sha256 = "06n7556vxr3awh92xy1k5bli98bvq4pjm08mnl68ay4fzln7lcsg"; 1662 | type = "gem"; 1663 | }; 1664 | version = "1.7.1"; 1665 | }; 1666 | multi_json = { 1667 | groups = ["default"]; 1668 | platforms = []; 1669 | source = { 1670 | remotes = ["https://rubygems.org"]; 1671 | sha256 = "0pb1g1y3dsiahavspyzkdy39j4q377009f6ix0bh1ag4nqw43l0z"; 1672 | type = "gem"; 1673 | }; 1674 | version = "1.15.0"; 1675 | }; 1676 | multipart-post = { 1677 | groups = ["default"]; 1678 | platforms = []; 1679 | source = { 1680 | remotes = ["https://rubygems.org"]; 1681 | sha256 = "0lgyysrpl50wgcb9ahg29i4p01z0irb3p9lirygma0kkfr5dgk9x"; 1682 | type = "gem"; 1683 | }; 1684 | version = "2.3.0"; 1685 | }; 1686 | net-http = { 1687 | dependencies = ["uri"]; 1688 | groups = ["default"]; 1689 | platforms = []; 1690 | source = { 1691 | remotes = ["https://rubygems.org"]; 1692 | sha256 = "0y55ib1v2b8prqfi9ij7hca60b1j94s2bzr6vskwi3i5735472wq"; 1693 | type = "gem"; 1694 | }; 1695 | version = "0.3.2"; 1696 | }; 1697 | net-imap = { 1698 | dependencies = ["date" "net-protocol"]; 1699 | groups = ["default" "development"]; 1700 | platforms = []; 1701 | source = { 1702 | remotes = ["https://rubygems.org"]; 1703 | sha256 = "1k1qyjr9lkk5y3483k6wk6d9h1jx4v5hzby1mf0pj3b4kr2arxbm"; 1704 | type = "gem"; 1705 | }; 1706 | version = "0.3.6"; 1707 | }; 1708 | net-ldap = { 1709 | groups = ["default"]; 1710 | platforms = []; 1711 | source = { 1712 | remotes = ["https://rubygems.org"]; 1713 | sha256 = "0xqcffn3c1564c4fizp10dzw2v5g2pabdzrcn25hq05bqhsckbar"; 1714 | type = "gem"; 1715 | }; 1716 | version = "0.18.0"; 1717 | }; 1718 | net-pop = { 1719 | dependencies = ["net-protocol"]; 1720 | groups = ["default" "development"]; 1721 | platforms = []; 1722 | source = { 1723 | remotes = ["https://rubygems.org"]; 1724 | sha256 = "1wyz41jd4zpjn0v1xsf9j778qx1vfrl24yc20cpmph8k42c4x2w4"; 1725 | type = "gem"; 1726 | }; 1727 | version = "0.1.2"; 1728 | }; 1729 | net-protocol = { 1730 | dependencies = ["timeout"]; 1731 | groups = ["default" "development"]; 1732 | platforms = []; 1733 | source = { 1734 | remotes = ["https://rubygems.org"]; 1735 | sha256 = "0dxckrlw4q1lcn3qg4mimmjazmg9bma5gllv72f8js3p36fb3b91"; 1736 | type = "gem"; 1737 | }; 1738 | version = "0.2.1"; 1739 | }; 1740 | net-scp = { 1741 | dependencies = ["net-ssh"]; 1742 | groups = ["default" "development"]; 1743 | platforms = []; 1744 | source = { 1745 | remotes = ["https://rubygems.org"]; 1746 | sha256 = "1si2nq9l6jy5n2zw1q59a5gaji7v9vhy8qx08h4fg368906ysbdk"; 1747 | type = "gem"; 1748 | }; 1749 | version = "4.0.0"; 1750 | }; 1751 | net-smtp = { 1752 | dependencies = ["net-protocol"]; 1753 | groups = ["default" "development"]; 1754 | platforms = []; 1755 | source = { 1756 | remotes = ["https://rubygems.org"]; 1757 | sha256 = "1c6md06hm5bf6rv53sk54dl2vg038pg8kglwv3rayx0vk2mdql9x"; 1758 | type = "gem"; 1759 | }; 1760 | version = "0.3.3"; 1761 | }; 1762 | net-ssh = { 1763 | groups = ["default" "development"]; 1764 | platforms = []; 1765 | source = { 1766 | remotes = ["https://rubygems.org"]; 1767 | sha256 = "0yx0pb5fmziz92bw8qzbh8vf20lr56nd3s6q8h0gsgr307lki687"; 1768 | type = "gem"; 1769 | }; 1770 | version = "7.1.0"; 1771 | }; 1772 | nio4r = { 1773 | groups = ["default"]; 1774 | platforms = []; 1775 | source = { 1776 | remotes = ["https://rubygems.org"]; 1777 | sha256 = "0w9978zwjf1qhy3amkivab0f9syz6a7k0xgydjidaf7xc831d78f"; 1778 | type = "gem"; 1779 | }; 1780 | version = "2.5.9"; 1781 | }; 1782 | nokogiri = { 1783 | dependencies = ["mini_portile2" "racc"]; 1784 | groups = ["default" "development" "pam_authentication" "production" "test"]; 1785 | platforms = []; 1786 | source = { 1787 | remotes = ["https://rubygems.org"]; 1788 | sha256 = "1jw8a20a9k05fpz3q24im19b97idss3179z76yn5scc5b8lk2rl7"; 1789 | type = "gem"; 1790 | }; 1791 | version = "1.15.3"; 1792 | }; 1793 | oj = { 1794 | groups = ["default"]; 1795 | platforms = []; 1796 | source = { 1797 | remotes = ["https://rubygems.org"]; 1798 | sha256 = "1s6ipcar6sgwipnc577d4x80ypq2s35k9142jn3l89lh53888mmg"; 1799 | type = "gem"; 1800 | }; 1801 | version = "3.15.0"; 1802 | }; 1803 | omniauth = { 1804 | dependencies = ["hashie" "rack"]; 1805 | groups = ["default"]; 1806 | platforms = []; 1807 | source = { 1808 | remotes = ["https://rubygems.org"]; 1809 | sha256 = "1jn9j54l5h7xcba2vjq74l1dk0xrwvsjxam4qhylpi52nw0h5502"; 1810 | type = "gem"; 1811 | }; 1812 | version = "1.9.2"; 1813 | }; 1814 | omniauth-cas = { 1815 | dependencies = ["addressable" "nokogiri" "omniauth"]; 1816 | groups = ["default"]; 1817 | platforms = []; 1818 | source = { 1819 | remotes = ["https://rubygems.org"]; 1820 | sha256 = "0kzlh1nac4yz70917cdcsk0r23gy5h7i0x5kbmkvkpbgk6gvrb0z"; 1821 | type = "gem"; 1822 | }; 1823 | version = "2.0.0"; 1824 | }; 1825 | omniauth-rails_csrf_protection = { 1826 | dependencies = ["actionpack" "omniauth"]; 1827 | groups = ["default"]; 1828 | platforms = []; 1829 | source = { 1830 | remotes = ["https://rubygems.org"]; 1831 | sha256 = "0xgkxwg17w39q3yjqcj0fm6hdkw37qm1l82dvm9zxn6q2pbzm2zv"; 1832 | type = "gem"; 1833 | }; 1834 | version = "0.1.2"; 1835 | }; 1836 | omniauth-saml = { 1837 | dependencies = ["omniauth" "ruby-saml"]; 1838 | groups = ["default"]; 1839 | platforms = []; 1840 | source = { 1841 | remotes = ["https://rubygems.org"]; 1842 | sha256 = "0gxl14lbksnjkl8dfn23lsjkk63md77icm5racrh6fsp5n4ni9d4"; 1843 | type = "gem"; 1844 | }; 1845 | version = "1.10.3"; 1846 | }; 1847 | omniauth_openid_connect = { 1848 | dependencies = ["omniauth" "openid_connect"]; 1849 | groups = ["default"]; 1850 | platforms = []; 1851 | source = { 1852 | remotes = ["https://rubygems.org"]; 1853 | sha256 = "08yl0x203k6nrshc70zawfqh79ap1c3fyka9zwwy61cvn7sih4sz"; 1854 | type = "gem"; 1855 | }; 1856 | version = "0.6.1"; 1857 | }; 1858 | openid_connect = { 1859 | dependencies = ["activemodel" "attr_required" "json-jwt" "net-smtp" "rack-oauth2" "swd" "tzinfo" "validate_email" "validate_url" "webfinger"]; 1860 | groups = ["default"]; 1861 | platforms = []; 1862 | source = { 1863 | remotes = ["https://rubygems.org"]; 1864 | sha256 = "1k9kdivp45v6vhzdrnl5fzhd378gjj2hl4w9bazbqnfm15rsnzc8"; 1865 | type = "gem"; 1866 | }; 1867 | version = "1.4.2"; 1868 | }; 1869 | openssl = { 1870 | groups = ["default"]; 1871 | platforms = []; 1872 | source = { 1873 | remotes = ["https://rubygems.org"]; 1874 | sha256 = "0c649921vg2l939z5cc3jwd8p1v49099pdhxfk7sb9qqx5wi5873"; 1875 | type = "gem"; 1876 | }; 1877 | version = "3.1.0"; 1878 | }; 1879 | openssl-signature_algorithm = { 1880 | dependencies = ["openssl"]; 1881 | groups = ["default"]; 1882 | platforms = []; 1883 | source = { 1884 | remotes = ["https://rubygems.org"]; 1885 | sha256 = "103yjl68wqhl5kxaciir5jdnyi7iv9yckishdr52s5knh9g0pd53"; 1886 | type = "gem"; 1887 | }; 1888 | version = "1.3.0"; 1889 | }; 1890 | orm_adapter = { 1891 | groups = ["default" "pam_authentication"]; 1892 | platforms = []; 1893 | source = { 1894 | remotes = ["https://rubygems.org"]; 1895 | sha256 = "1fg9jpjlzf5y49qs9mlpdrgs5rpcyihq1s4k79nv9js0spjhnpda"; 1896 | type = "gem"; 1897 | }; 1898 | version = "0.5.0"; 1899 | }; 1900 | ox = { 1901 | groups = ["default"]; 1902 | platforms = []; 1903 | source = { 1904 | remotes = ["https://rubygems.org"]; 1905 | sha256 = "0i1qq88cwh9pccg59whg50rpkgdfrijn4q6k5p3clwrjqgm56lrd"; 1906 | type = "gem"; 1907 | }; 1908 | version = "2.14.16"; 1909 | }; 1910 | parallel = { 1911 | groups = ["default" "development"]; 1912 | platforms = []; 1913 | source = { 1914 | remotes = ["https://rubygems.org"]; 1915 | sha256 = "0jcc512l38c0c163ni3jgskvq1vc3mr8ly5pvjijzwvfml9lf597"; 1916 | type = "gem"; 1917 | }; 1918 | version = "1.23.0"; 1919 | }; 1920 | parser = { 1921 | dependencies = ["ast" "racc"]; 1922 | groups = ["default" "development"]; 1923 | platforms = []; 1924 | source = { 1925 | remotes = ["https://rubygems.org"]; 1926 | sha256 = "1swigds85jddb5gshll1g8lkmbcgbcp9bi1d4nigwvxki8smys0h"; 1927 | type = "gem"; 1928 | }; 1929 | version = "3.2.2.3"; 1930 | }; 1931 | parslet = { 1932 | groups = ["default"]; 1933 | platforms = []; 1934 | source = { 1935 | remotes = ["https://rubygems.org"]; 1936 | sha256 = "01pnw6ymz6nynklqvqxs4bcai25kcvnd5x4id9z3vd1rbmlk0lfl"; 1937 | type = "gem"; 1938 | }; 1939 | version = "2.0.0"; 1940 | }; 1941 | pastel = { 1942 | dependencies = ["tty-color"]; 1943 | groups = ["default"]; 1944 | platforms = []; 1945 | source = { 1946 | remotes = ["https://rubygems.org"]; 1947 | sha256 = "0xash2gj08dfjvq4hy6l1z22s5v30fhizwgs10d6nviggpxsj7a8"; 1948 | type = "gem"; 1949 | }; 1950 | version = "0.8.0"; 1951 | }; 1952 | pg = { 1953 | groups = ["default"]; 1954 | platforms = []; 1955 | source = { 1956 | remotes = ["https://rubygems.org"]; 1957 | sha256 = "1zcvxmfa8hxkhpp59fhxyxy1arp70f11zi1jh9c7bsdfspifb7kb"; 1958 | type = "gem"; 1959 | }; 1960 | version = "1.5.3"; 1961 | }; 1962 | pghero = { 1963 | dependencies = ["activerecord"]; 1964 | groups = ["default"]; 1965 | platforms = []; 1966 | source = { 1967 | remotes = ["https://rubygems.org"]; 1968 | sha256 = "002v32dzyyr29xd9cdsqp55g5gx19skvq9b4a4hr9lrs4i1xsavm"; 1969 | type = "gem"; 1970 | }; 1971 | version = "3.3.3"; 1972 | }; 1973 | posix-spawn = { 1974 | groups = ["default"]; 1975 | platforms = []; 1976 | source = { 1977 | remotes = ["https://rubygems.org"]; 1978 | sha256 = "0cmb0svalqcxfzlzc5fvrci12b79x7bakasr8gkl3q5rz6di1q52"; 1979 | type = "gem"; 1980 | }; 1981 | version = "0.3.15"; 1982 | }; 1983 | premailer = { 1984 | dependencies = ["addressable" "css_parser" "htmlentities"]; 1985 | groups = ["default"]; 1986 | platforms = []; 1987 | source = { 1988 | remotes = ["https://rubygems.org"]; 1989 | sha256 = "10rzwdz43yy20lwzsr2as6aivhvwjvqh4nd48sa0ga57sizf1fb4"; 1990 | type = "gem"; 1991 | }; 1992 | version = "1.21.0"; 1993 | }; 1994 | premailer-rails = { 1995 | dependencies = ["actionmailer" "net-smtp" "premailer"]; 1996 | groups = ["default"]; 1997 | platforms = []; 1998 | source = { 1999 | remotes = ["https://rubygems.org"]; 2000 | sha256 = "0004f73kgrglida336fqkgx906m6n05nnfc17mypzg5rc78iaf61"; 2001 | type = "gem"; 2002 | }; 2003 | version = "1.12.0"; 2004 | }; 2005 | private_address_check = { 2006 | groups = ["default"]; 2007 | platforms = []; 2008 | source = { 2009 | remotes = ["https://rubygems.org"]; 2010 | sha256 = "05phz0vscfh9chv90yc9091pifw3cpwkh76flnhrmvja1q3na4cy"; 2011 | type = "gem"; 2012 | }; 2013 | version = "0.5.0"; 2014 | }; 2015 | public_suffix = { 2016 | groups = ["default" "development" "test"]; 2017 | platforms = []; 2018 | source = { 2019 | remotes = ["https://rubygems.org"]; 2020 | sha256 = "0hz0bx2qs2pwb0bwazzsah03ilpf3aai8b7lk7s35jsfzwbkjq35"; 2021 | type = "gem"; 2022 | }; 2023 | version = "5.0.1"; 2024 | }; 2025 | puma = { 2026 | dependencies = ["nio4r"]; 2027 | groups = ["default"]; 2028 | platforms = []; 2029 | source = { 2030 | remotes = ["https://rubygems.org"]; 2031 | sha256 = "1v7fmv0n4bhdcwh60dgza44iqai5pg34f5pzm4vh4i5fwx7mpqxh"; 2032 | type = "gem"; 2033 | }; 2034 | version = "6.3.0"; 2035 | }; 2036 | pundit = { 2037 | dependencies = ["activesupport"]; 2038 | groups = ["default"]; 2039 | platforms = []; 2040 | source = { 2041 | remotes = ["https://rubygems.org"]; 2042 | sha256 = "1wb03yzy1j41822rbfh9nn77im3zh1f5v8di05cd8rsrdpws542b"; 2043 | type = "gem"; 2044 | }; 2045 | version = "2.3.0"; 2046 | }; 2047 | raabro = { 2048 | groups = ["default"]; 2049 | platforms = []; 2050 | source = { 2051 | remotes = ["https://rubygems.org"]; 2052 | sha256 = "10m8bln9d00dwzjil1k42i5r7l82x25ysbi45fwyv4932zsrzynl"; 2053 | type = "gem"; 2054 | }; 2055 | version = "1.4.0"; 2056 | }; 2057 | racc = { 2058 | groups = ["default" "development" "pam_authentication" "production" "test"]; 2059 | platforms = []; 2060 | source = { 2061 | remotes = ["https://rubygems.org"]; 2062 | sha256 = "11v3l46mwnlzlc371wr3x6yylpgafgwdf0q7hc7c1lzx6r414r5g"; 2063 | type = "gem"; 2064 | }; 2065 | version = "1.7.1"; 2066 | }; 2067 | rack = { 2068 | groups = ["default" "development" "pam_authentication" "production" "test"]; 2069 | platforms = []; 2070 | source = { 2071 | remotes = ["https://rubygems.org"]; 2072 | sha256 = "16w217k9z02c4hqizym8dkj6bqmmzx4qdvqpnskgzf174a5pwdxk"; 2073 | type = "gem"; 2074 | }; 2075 | version = "2.2.7"; 2076 | }; 2077 | rack-attack = { 2078 | dependencies = ["rack"]; 2079 | groups = ["default"]; 2080 | platforms = []; 2081 | source = { 2082 | remotes = ["https://rubygems.org"]; 2083 | sha256 = "049s3y3dpl6dn478g912y6f9nzclnnkl30psrbc2w5kaihj5szhq"; 2084 | type = "gem"; 2085 | }; 2086 | version = "6.6.1"; 2087 | }; 2088 | rack-cors = { 2089 | dependencies = ["rack"]; 2090 | groups = ["default"]; 2091 | platforms = []; 2092 | source = { 2093 | remotes = ["https://rubygems.org"]; 2094 | sha256 = "02lvkg1nb4z3zc2nry545dap7a64bb9h2k8waxfz0jkabkgnpimw"; 2095 | type = "gem"; 2096 | }; 2097 | version = "2.0.1"; 2098 | }; 2099 | rack-oauth2 = { 2100 | dependencies = ["activesupport" "attr_required" "httpclient" "json-jwt" "rack"]; 2101 | groups = ["default"]; 2102 | platforms = []; 2103 | source = { 2104 | remotes = ["https://rubygems.org"]; 2105 | sha256 = "1fknwsxz4429w1hndl6y30cmm2n34wmmaaj2hhp6jrm8ssfsfwjf"; 2106 | type = "gem"; 2107 | }; 2108 | version = "1.21.3"; 2109 | }; 2110 | rack-proxy = { 2111 | dependencies = ["rack"]; 2112 | groups = ["default"]; 2113 | platforms = []; 2114 | source = { 2115 | remotes = ["https://rubygems.org"]; 2116 | sha256 = "1a62439xwn5v6hsl9s11hdk4wj58czhcbg7lminv23mnkc0ca147"; 2117 | type = "gem"; 2118 | }; 2119 | version = "0.7.6"; 2120 | }; 2121 | rack-test = { 2122 | dependencies = ["rack"]; 2123 | groups = ["default" "development" "pam_authentication" "production" "test"]; 2124 | platforms = []; 2125 | source = { 2126 | remotes = ["https://rubygems.org"]; 2127 | sha256 = "1ysx29gk9k14a14zsp5a8czys140wacvp91fja8xcja0j1hzqq8c"; 2128 | type = "gem"; 2129 | }; 2130 | version = "2.1.0"; 2131 | }; 2132 | rails = { 2133 | dependencies = ["actioncable" "actionmailbox" "actionmailer" "actionpack" "actiontext" "actionview" "activejob" "activemodel" "activerecord" "activestorage" "activesupport" "railties"]; 2134 | groups = ["default"]; 2135 | platforms = []; 2136 | source = { 2137 | remotes = ["https://rubygems.org"]; 2138 | sha256 = "08glp6jhq5yh8i5jjxzqa3aqx819l6ci6m68bx1asmimla0x9ysx"; 2139 | type = "gem"; 2140 | }; 2141 | version = "7.0.6"; 2142 | }; 2143 | rails-controller-testing = { 2144 | dependencies = ["actionpack" "actionview" "activesupport"]; 2145 | groups = ["test"]; 2146 | platforms = []; 2147 | source = { 2148 | remotes = ["https://rubygems.org"]; 2149 | sha256 = "151f303jcvs8s149mhx2g5mn67487x0blrf9dzl76q1nb7dlh53l"; 2150 | type = "gem"; 2151 | }; 2152 | version = "1.0.5"; 2153 | }; 2154 | rails-dom-testing = { 2155 | dependencies = ["activesupport" "nokogiri"]; 2156 | groups = ["default" "development" "pam_authentication" "production" "test"]; 2157 | platforms = []; 2158 | source = { 2159 | remotes = ["https://rubygems.org"]; 2160 | sha256 = "1lfq2a7kp2x64dzzi5p4cjcbiv62vxh9lyqk2f0rqq3fkzrw8h5i"; 2161 | type = "gem"; 2162 | }; 2163 | version = "2.0.3"; 2164 | }; 2165 | rails-html-sanitizer = { 2166 | dependencies = ["loofah" "nokogiri"]; 2167 | groups = ["default" "development" "pam_authentication" "production" "test"]; 2168 | platforms = []; 2169 | source = { 2170 | remotes = ["https://rubygems.org"]; 2171 | sha256 = "1pm4z853nyz1bhhqr7fzl44alnx4bjachcr6rh6qjj375sfz3sc6"; 2172 | type = "gem"; 2173 | }; 2174 | version = "1.6.0"; 2175 | }; 2176 | rails-i18n = { 2177 | dependencies = ["i18n" "railties"]; 2178 | groups = ["default" "development"]; 2179 | platforms = []; 2180 | source = { 2181 | remotes = ["https://rubygems.org"]; 2182 | sha256 = "1bbh5gsw46djmrgddwaq3wsjmj9rsh5dk13wkclwxf1rg9jpkn3g"; 2183 | type = "gem"; 2184 | }; 2185 | version = "7.0.7"; 2186 | }; 2187 | rails-settings-cached = { 2188 | dependencies = ["rails"]; 2189 | groups = ["default"]; 2190 | platforms = []; 2191 | source = { 2192 | fetchSubmodules = false; 2193 | rev = "86328ef0bd04ce21cc0504ff5e334591e8c2ccab"; 2194 | sha256 = "06r637gimh5miq2i6ywxn9gp7nqk8n8555yw8239mykalbzda69h"; 2195 | type = "git"; 2196 | url = "https://github.com/mastodon/rails-settings-cached.git"; 2197 | }; 2198 | version = "0.6.6"; 2199 | }; 2200 | railties = { 2201 | dependencies = ["actionpack" "activesupport" "method_source" "rake" "thor" "zeitwerk"]; 2202 | groups = ["default" "development" "pam_authentication" "production" "test"]; 2203 | platforms = []; 2204 | source = { 2205 | remotes = ["https://rubygems.org"]; 2206 | sha256 = "0dcabk5bl5flmspnb9d2qcvclcaw0nd5yr9w6m5pzsmylg3y63pv"; 2207 | type = "gem"; 2208 | }; 2209 | version = "7.0.6"; 2210 | }; 2211 | rainbow = { 2212 | groups = ["default" "development"]; 2213 | platforms = []; 2214 | source = { 2215 | remotes = ["https://rubygems.org"]; 2216 | sha256 = "0smwg4mii0fm38pyb5fddbmrdpifwv22zv3d3px2xx497am93503"; 2217 | type = "gem"; 2218 | }; 2219 | version = "3.1.1"; 2220 | }; 2221 | rake = { 2222 | groups = ["default" "development" "pam_authentication" "production" "test"]; 2223 | platforms = []; 2224 | source = { 2225 | remotes = ["https://rubygems.org"]; 2226 | sha256 = "15whn7p9nrkxangbs9hh75q585yfn66lv0v2mhj6q6dl6x8bzr2w"; 2227 | type = "gem"; 2228 | }; 2229 | version = "13.0.6"; 2230 | }; 2231 | rdf = { 2232 | dependencies = ["link_header"]; 2233 | groups = ["default"]; 2234 | platforms = []; 2235 | source = { 2236 | remotes = ["https://rubygems.org"]; 2237 | sha256 = "1jx4xyip4inrhr099zac8ah5232g70rv39mm19p85sgpwg80a6ip"; 2238 | type = "gem"; 2239 | }; 2240 | version = "3.2.11"; 2241 | }; 2242 | rdf-normalize = { 2243 | dependencies = ["rdf"]; 2244 | groups = ["default"]; 2245 | platforms = []; 2246 | source = { 2247 | remotes = ["https://rubygems.org"]; 2248 | sha256 = "1rn9j5skl04403b5sxhpq2j9m9k7vl0wjwvycs6piknn7ahrfxh9"; 2249 | type = "gem"; 2250 | }; 2251 | version = "0.6.0"; 2252 | }; 2253 | redcarpet = { 2254 | groups = ["default"]; 2255 | platforms = []; 2256 | source = { 2257 | remotes = ["https://rubygems.org"]; 2258 | sha256 = "1sg9sbf9pm91l7lac7fs4silabyn0vflxwaa2x3lrzsm0ff8ilca"; 2259 | type = "gem"; 2260 | }; 2261 | version = "3.6.0"; 2262 | }; 2263 | redis = { 2264 | groups = ["default" "test"]; 2265 | platforms = []; 2266 | source = { 2267 | remotes = ["https://rubygems.org"]; 2268 | sha256 = "0fikjg6j12ka6hh36dxzhfkpqqmilzjfzcdf59iwkzsgd63f0ziq"; 2269 | type = "gem"; 2270 | }; 2271 | version = "4.8.1"; 2272 | }; 2273 | redis-namespace = { 2274 | dependencies = ["redis"]; 2275 | groups = ["default"]; 2276 | platforms = []; 2277 | source = { 2278 | remotes = ["https://rubygems.org"]; 2279 | sha256 = "0f92i9cwlp6xj6fyn7qn4qsaqvxfw4wqvayll7gbd26qnai1l6p9"; 2280 | type = "gem"; 2281 | }; 2282 | version = "1.11.0"; 2283 | }; 2284 | redlock = { 2285 | dependencies = ["redis"]; 2286 | groups = ["default"]; 2287 | platforms = []; 2288 | source = { 2289 | remotes = ["https://rubygems.org"]; 2290 | sha256 = "0xvjwfzq7rqj4k311kidwmv5app3i7glz4miys6ixqy6c8yylz3c"; 2291 | type = "gem"; 2292 | }; 2293 | version = "1.3.2"; 2294 | }; 2295 | regexp_parser = { 2296 | groups = ["default" "development" "test"]; 2297 | platforms = []; 2298 | source = { 2299 | remotes = ["https://rubygems.org"]; 2300 | sha256 = "136br91alxdwh1s85z912dwz23qlhm212vy6i3wkinz3z8mkxxl3"; 2301 | type = "gem"; 2302 | }; 2303 | version = "2.8.1"; 2304 | }; 2305 | request_store = { 2306 | dependencies = ["rack"]; 2307 | groups = ["default" "production"]; 2308 | platforms = []; 2309 | source = { 2310 | remotes = ["https://rubygems.org"]; 2311 | sha256 = "13ppgmsbrqah08j06bybd3cddv6dml79yzyjn7r8j1src78h98h7"; 2312 | type = "gem"; 2313 | }; 2314 | version = "1.5.1"; 2315 | }; 2316 | responders = { 2317 | dependencies = ["actionpack" "railties"]; 2318 | groups = ["default" "pam_authentication"]; 2319 | platforms = []; 2320 | source = { 2321 | remotes = ["https://rubygems.org"]; 2322 | sha256 = "0m9s0mkkprrz02gxhq0ijlwjy0nx1j5yrjf8ssjnhyagnx03lyrx"; 2323 | type = "gem"; 2324 | }; 2325 | version = "3.1.0"; 2326 | }; 2327 | rexml = { 2328 | groups = ["default" "development" "test"]; 2329 | platforms = []; 2330 | source = { 2331 | remotes = ["https://rubygems.org"]; 2332 | sha256 = "08ximcyfjy94pm1rhcx04ny1vx2sk0x4y185gzn86yfsbzwkng53"; 2333 | type = "gem"; 2334 | }; 2335 | version = "3.2.5"; 2336 | }; 2337 | rotp = { 2338 | groups = ["default"]; 2339 | platforms = []; 2340 | source = { 2341 | remotes = ["https://rubygems.org"]; 2342 | sha256 = "10mmzc85y7andsich586ndykw678qn1ns2wpjxrg0sc0gr4w3pig"; 2343 | type = "gem"; 2344 | }; 2345 | version = "6.2.2"; 2346 | }; 2347 | rouge = { 2348 | groups = ["default" "development"]; 2349 | platforms = []; 2350 | source = { 2351 | remotes = ["https://rubygems.org"]; 2352 | sha256 = "0pym2zjwl6dwdfvbn7rbvmds32r70jx9qddhvvi6pqy6987ack1v"; 2353 | type = "gem"; 2354 | }; 2355 | version = "4.1.2"; 2356 | }; 2357 | rpam2 = { 2358 | groups = ["default" "pam_authentication"]; 2359 | platforms = []; 2360 | source = { 2361 | remotes = ["https://rubygems.org"]; 2362 | sha256 = "1zvli3s4z1hf2l7gyfickm5i3afjrnycc3ihbiax6ji6arpbyf33"; 2363 | type = "gem"; 2364 | }; 2365 | version = "4.0.2"; 2366 | }; 2367 | rqrcode = { 2368 | dependencies = ["chunky_png" "rqrcode_core"]; 2369 | groups = ["default"]; 2370 | platforms = []; 2371 | source = { 2372 | remotes = ["https://rubygems.org"]; 2373 | sha256 = "1hggzz8i1l62pkkiybhiqv6ypxw7q844sddrrbbfczjcnj5sivi3"; 2374 | type = "gem"; 2375 | }; 2376 | version = "2.2.0"; 2377 | }; 2378 | rqrcode_core = { 2379 | groups = ["default"]; 2380 | platforms = []; 2381 | source = { 2382 | remotes = ["https://rubygems.org"]; 2383 | sha256 = "06ld6386hbdhy5h0k09axmgn424kavpc8f27k1vjhknjhbf8jjfg"; 2384 | type = "gem"; 2385 | }; 2386 | version = "1.2.0"; 2387 | }; 2388 | rspec-core = { 2389 | dependencies = ["rspec-support"]; 2390 | groups = ["default" "test"]; 2391 | platforms = []; 2392 | source = { 2393 | remotes = ["https://rubygems.org"]; 2394 | sha256 = "0l95bnjxdabrn79hwdhn2q1n7mn26pj7y1w5660v5qi81x458nqm"; 2395 | type = "gem"; 2396 | }; 2397 | version = "3.12.2"; 2398 | }; 2399 | rspec-expectations = { 2400 | dependencies = ["diff-lcs" "rspec-support"]; 2401 | groups = ["default" "test"]; 2402 | platforms = []; 2403 | source = { 2404 | remotes = ["https://rubygems.org"]; 2405 | sha256 = "05j44jfqlv7j2rpxb5vqzf9hfv7w8ba46wwgxwcwd8p0wzi1hg89"; 2406 | type = "gem"; 2407 | }; 2408 | version = "3.12.3"; 2409 | }; 2410 | rspec-mocks = { 2411 | dependencies = ["diff-lcs" "rspec-support"]; 2412 | groups = ["default" "test"]; 2413 | platforms = []; 2414 | source = { 2415 | remotes = ["https://rubygems.org"]; 2416 | sha256 = "1hfm17xakfvwya236graj6c2arr4sb9zasp35q5fykhyz8mhs0w2"; 2417 | type = "gem"; 2418 | }; 2419 | version = "3.12.5"; 2420 | }; 2421 | rspec-rails = { 2422 | dependencies = ["actionpack" "activesupport" "railties" "rspec-core" "rspec-expectations" "rspec-mocks" "rspec-support"]; 2423 | groups = ["test"]; 2424 | platforms = []; 2425 | source = { 2426 | remotes = ["https://rubygems.org"]; 2427 | sha256 = "086qdyz7c4s5dslm6j06mq7j4jmj958whc3yinhabnqqmz7i463d"; 2428 | type = "gem"; 2429 | }; 2430 | version = "6.0.3"; 2431 | }; 2432 | rspec-sidekiq = { 2433 | dependencies = ["rspec-core" "sidekiq"]; 2434 | groups = ["test"]; 2435 | platforms = []; 2436 | source = { 2437 | remotes = ["https://rubygems.org"]; 2438 | sha256 = "1spzw3sc2p0n9qfb89y1v8igd60y7c5z9w2hjqqbbgbyjvy0agp8"; 2439 | type = "gem"; 2440 | }; 2441 | version = "3.1.0"; 2442 | }; 2443 | rspec-support = { 2444 | groups = ["default" "test"]; 2445 | platforms = []; 2446 | source = { 2447 | remotes = ["https://rubygems.org"]; 2448 | sha256 = "12y52zwwb3xr7h91dy9k3ndmyyhr3mjcayk0nnarnrzz8yr48kfx"; 2449 | type = "gem"; 2450 | }; 2451 | version = "3.12.0"; 2452 | }; 2453 | rspec_chunked = { 2454 | groups = ["test"]; 2455 | platforms = []; 2456 | source = { 2457 | remotes = ["https://rubygems.org"]; 2458 | sha256 = "0h4bsj3m7vb47qnx5bry4v0xscrb3lhg1f1vyxl524znb3i2qqzv"; 2459 | type = "gem"; 2460 | }; 2461 | version = "0.6"; 2462 | }; 2463 | rubocop = { 2464 | dependencies = ["json" "language_server-protocol" "parallel" "parser" "rainbow" "regexp_parser" "rexml" "rubocop-ast" "ruby-progressbar" "unicode-display_width"]; 2465 | groups = ["development"]; 2466 | platforms = []; 2467 | source = { 2468 | remotes = ["https://rubygems.org"]; 2469 | sha256 = "1vklabd0510isqhikx4bfx5qn9g8pyj8h9jxryayp2wj8mx4kg74"; 2470 | type = "gem"; 2471 | }; 2472 | version = "1.54.1"; 2473 | }; 2474 | rubocop-ast = { 2475 | dependencies = ["parser"]; 2476 | groups = ["default" "development"]; 2477 | platforms = []; 2478 | source = { 2479 | remotes = ["https://rubygems.org"]; 2480 | sha256 = "188bs225kkhrb17dsf3likdahs2p1i1sqn0pr3pvlx50g6r2mnni"; 2481 | type = "gem"; 2482 | }; 2483 | version = "1.29.0"; 2484 | }; 2485 | rubocop-capybara = { 2486 | dependencies = ["rubocop"]; 2487 | groups = ["development"]; 2488 | platforms = []; 2489 | source = { 2490 | remotes = ["https://rubygems.org"]; 2491 | sha256 = "01fn05a87g009ch1sh00abdmgjab87i995msap26vxq1a5smdck6"; 2492 | type = "gem"; 2493 | }; 2494 | version = "2.18.0"; 2495 | }; 2496 | rubocop-factory_bot = { 2497 | dependencies = ["rubocop"]; 2498 | groups = ["default" "development"]; 2499 | platforms = []; 2500 | source = { 2501 | remotes = ["https://rubygems.org"]; 2502 | sha256 = "0kqchl8f67k2g56sq2h1sm2wb6br5gi47s877hlz94g5086f77n1"; 2503 | type = "gem"; 2504 | }; 2505 | version = "2.23.1"; 2506 | }; 2507 | rubocop-performance = { 2508 | dependencies = ["rubocop" "rubocop-ast"]; 2509 | groups = ["development"]; 2510 | platforms = []; 2511 | source = { 2512 | remotes = ["https://rubygems.org"]; 2513 | sha256 = "0bp02784v0qm8qcswi169s0ar6216rwk516v3idzpbxznpqp97ac"; 2514 | type = "gem"; 2515 | }; 2516 | version = "1.18.0"; 2517 | }; 2518 | rubocop-rails = { 2519 | dependencies = ["activesupport" "rack" "rubocop"]; 2520 | groups = ["development"]; 2521 | platforms = []; 2522 | source = { 2523 | remotes = ["https://rubygems.org"]; 2524 | sha256 = "05r46ds0dm44fb4p67hbz721zck8mdwblzssz2y25yh075hvs36j"; 2525 | type = "gem"; 2526 | }; 2527 | version = "2.20.2"; 2528 | }; 2529 | rubocop-rspec = { 2530 | dependencies = ["rubocop" "rubocop-capybara" "rubocop-factory_bot"]; 2531 | groups = ["development"]; 2532 | platforms = []; 2533 | source = { 2534 | remotes = ["https://rubygems.org"]; 2535 | sha256 = "00rsflhijcr0q838fgbdmk7knm5kcjpimn6x0k9qmiw15hi96x1d"; 2536 | type = "gem"; 2537 | }; 2538 | version = "2.22.0"; 2539 | }; 2540 | ruby-progressbar = { 2541 | groups = ["default" "development" "test"]; 2542 | platforms = []; 2543 | source = { 2544 | remotes = ["https://rubygems.org"]; 2545 | sha256 = "0cwvyb7j47m7wihpfaq7rc47zwwx9k4v7iqd9s1xch5nm53rrz40"; 2546 | type = "gem"; 2547 | }; 2548 | version = "1.13.0"; 2549 | }; 2550 | ruby-saml = { 2551 | dependencies = ["nokogiri" "rexml"]; 2552 | groups = ["default"]; 2553 | platforms = []; 2554 | source = { 2555 | remotes = ["https://rubygems.org"]; 2556 | sha256 = "18vnbzin5ypxrgcs9lllg7x311b69dyrdw2w1pwz84438hmxm79s"; 2557 | type = "gem"; 2558 | }; 2559 | version = "1.15.0"; 2560 | }; 2561 | ruby2_keywords = { 2562 | groups = ["default"]; 2563 | platforms = []; 2564 | source = { 2565 | remotes = ["https://rubygems.org"]; 2566 | sha256 = "1vz322p8n39hz3b4a9gkmz9y7a5jaz41zrm2ywf31dvkqm03glgz"; 2567 | type = "gem"; 2568 | }; 2569 | version = "0.0.5"; 2570 | }; 2571 | rubyzip = { 2572 | groups = ["default"]; 2573 | platforms = []; 2574 | source = { 2575 | remotes = ["https://rubygems.org"]; 2576 | sha256 = "0grps9197qyxakbpw02pda59v45lfgbgiyw48i0mq9f2bn9y6mrz"; 2577 | type = "gem"; 2578 | }; 2579 | version = "2.3.2"; 2580 | }; 2581 | rufus-scheduler = { 2582 | dependencies = ["fugit"]; 2583 | groups = ["default"]; 2584 | platforms = []; 2585 | source = { 2586 | remotes = ["https://rubygems.org"]; 2587 | sha256 = "14lr8c2sswn0sisvrfi4448pmr34za279k3zlxgh581rl1y0gjjz"; 2588 | type = "gem"; 2589 | }; 2590 | version = "3.9.1"; 2591 | }; 2592 | safety_net_attestation = { 2593 | dependencies = ["jwt"]; 2594 | groups = ["default"]; 2595 | platforms = []; 2596 | source = { 2597 | remotes = ["https://rubygems.org"]; 2598 | sha256 = "1khq0y5w7lf2b9a220298hphf3pakd216jc9a4x4a9pdwxs2vgln"; 2599 | type = "gem"; 2600 | }; 2601 | version = "0.4.0"; 2602 | }; 2603 | sanitize = { 2604 | dependencies = ["crass" "nokogiri"]; 2605 | groups = ["default"]; 2606 | platforms = []; 2607 | source = { 2608 | remotes = ["https://rubygems.org"]; 2609 | sha256 = "1kymrjdpbmn4yaml3aaqyj1dzj8gqmm9h030dc2rj5mvja7fpi28"; 2610 | type = "gem"; 2611 | }; 2612 | version = "6.0.2"; 2613 | }; 2614 | scenic = { 2615 | dependencies = ["activerecord" "railties"]; 2616 | groups = ["default"]; 2617 | platforms = []; 2618 | source = { 2619 | remotes = ["https://rubygems.org"]; 2620 | sha256 = "04sd4jmgnwpilr3k061x87yyryya2mj15a8602fip49lfxza5548"; 2621 | type = "gem"; 2622 | }; 2623 | version = "1.7.0"; 2624 | }; 2625 | semantic_range = { 2626 | groups = ["default"]; 2627 | platforms = []; 2628 | source = { 2629 | remotes = ["https://rubygems.org"]; 2630 | sha256 = "1dlp97vg95plrsaaqj7x8l7z9vsjbhnqk4rw1l30gy26lmxpfrih"; 2631 | type = "gem"; 2632 | }; 2633 | version = "3.0.0"; 2634 | }; 2635 | sidekiq = { 2636 | dependencies = ["connection_pool" "rack" "redis"]; 2637 | groups = ["default" "test"]; 2638 | platforms = []; 2639 | source = { 2640 | remotes = ["https://rubygems.org"]; 2641 | sha256 = "0iv7vgqyrpymiwvc3ca24sl4lda8m627p657p0v4xzdpzincrnbr"; 2642 | type = "gem"; 2643 | }; 2644 | version = "6.5.9"; 2645 | }; 2646 | sidekiq-bulk = { 2647 | dependencies = ["sidekiq"]; 2648 | groups = ["default"]; 2649 | platforms = []; 2650 | source = { 2651 | remotes = ["https://rubygems.org"]; 2652 | sha256 = "08nyxzmgf742irafy3l4fj09d4s5pyvsh0dzlh8y4hl51rgkh4xv"; 2653 | type = "gem"; 2654 | }; 2655 | version = "0.2.0"; 2656 | }; 2657 | sidekiq-scheduler = { 2658 | dependencies = ["rufus-scheduler" "sidekiq" "tilt"]; 2659 | groups = ["default"]; 2660 | platforms = []; 2661 | source = { 2662 | remotes = ["https://rubygems.org"]; 2663 | sha256 = "0p5jjs3x2pa2fy494xs39xbq642pri13809dcr1l3hjsm56qvp1h"; 2664 | type = "gem"; 2665 | }; 2666 | version = "5.0.3"; 2667 | }; 2668 | sidekiq-unique-jobs = { 2669 | dependencies = ["brpoplpush-redis_script" "concurrent-ruby" "redis" "sidekiq" "thor"]; 2670 | groups = ["default"]; 2671 | platforms = []; 2672 | source = { 2673 | remotes = ["https://rubygems.org"]; 2674 | sha256 = "02f91b24hrrn688wqvxb13lwvcgqb7g9k3sxylnydd6v89wr8mcg"; 2675 | type = "gem"; 2676 | }; 2677 | version = "7.1.29"; 2678 | }; 2679 | simple-navigation = { 2680 | dependencies = ["activesupport"]; 2681 | groups = ["default"]; 2682 | platforms = []; 2683 | source = { 2684 | remotes = ["https://rubygems.org"]; 2685 | sha256 = "1wc1rapwhqymcjfxmlgam4cvbyhnzfxada2damq88ij2p77pjz4q"; 2686 | type = "gem"; 2687 | }; 2688 | version = "4.4.0"; 2689 | }; 2690 | simple_form = { 2691 | dependencies = ["actionpack" "activemodel"]; 2692 | groups = ["default"]; 2693 | platforms = []; 2694 | source = { 2695 | remotes = ["https://rubygems.org"]; 2696 | sha256 = "0z4df65w9qpri315lpvzazdxa9xb7yj0j3d77q06wf0jnpvw4mzs"; 2697 | type = "gem"; 2698 | }; 2699 | version = "5.2.0"; 2700 | }; 2701 | simplecov = { 2702 | dependencies = ["docile" "simplecov-html" "simplecov_json_formatter"]; 2703 | groups = ["test"]; 2704 | platforms = []; 2705 | source = { 2706 | remotes = ["https://rubygems.org"]; 2707 | sha256 = "198kcbrjxhhzca19yrdcd6jjj9sb51aaic3b0sc3pwjghg3j49py"; 2708 | type = "gem"; 2709 | }; 2710 | version = "0.22.0"; 2711 | }; 2712 | simplecov-html = { 2713 | groups = ["default" "test"]; 2714 | platforms = []; 2715 | source = { 2716 | remotes = ["https://rubygems.org"]; 2717 | sha256 = "0yx01bxa8pbf9ip4hagqkp5m0mqfnwnw2xk8kjraiywz4lrss6jb"; 2718 | type = "gem"; 2719 | }; 2720 | version = "0.12.3"; 2721 | }; 2722 | simplecov_json_formatter = { 2723 | groups = ["default" "test"]; 2724 | platforms = []; 2725 | source = { 2726 | remotes = ["https://rubygems.org"]; 2727 | sha256 = "0a5l0733hj7sk51j81ykfmlk2vd5vaijlq9d5fn165yyx3xii52j"; 2728 | type = "gem"; 2729 | }; 2730 | version = "0.1.4"; 2731 | }; 2732 | smart_properties = { 2733 | groups = ["default" "development"]; 2734 | platforms = []; 2735 | source = { 2736 | remotes = ["https://rubygems.org"]; 2737 | sha256 = "0jrqssk9qhwrpq41arm712226vpcr458xv6xaqbk8cp94a0kycpr"; 2738 | type = "gem"; 2739 | }; 2740 | version = "1.17.0"; 2741 | }; 2742 | sprockets = { 2743 | dependencies = ["concurrent-ruby" "rack"]; 2744 | groups = ["default"]; 2745 | platforms = []; 2746 | source = { 2747 | remotes = ["https://rubygems.org"]; 2748 | sha256 = "182jw5a0fbqah5w9jancvfmjbk88h8bxdbwnl4d3q809rpxdg8ay"; 2749 | type = "gem"; 2750 | }; 2751 | version = "3.7.2"; 2752 | }; 2753 | sprockets-rails = { 2754 | dependencies = ["actionpack" "activesupport" "sprockets"]; 2755 | groups = ["default"]; 2756 | platforms = []; 2757 | source = { 2758 | remotes = ["https://rubygems.org"]; 2759 | sha256 = "1b9i14qb27zs56hlcc2hf139l0ghbqnjpmfi0054dxycaxvk5min"; 2760 | type = "gem"; 2761 | }; 2762 | version = "3.4.2"; 2763 | }; 2764 | sshkit = { 2765 | dependencies = ["net-scp" "net-ssh"]; 2766 | groups = ["default" "development"]; 2767 | platforms = []; 2768 | source = { 2769 | remotes = ["https://rubygems.org"]; 2770 | sha256 = "14a717mr2cmpgld5fcdd124cvlc5b634f96rhwlnmmc4m8bbkcp9"; 2771 | type = "gem"; 2772 | }; 2773 | version = "1.21.5"; 2774 | }; 2775 | stackprof = { 2776 | groups = ["development"]; 2777 | platforms = []; 2778 | source = { 2779 | remotes = ["https://rubygems.org"]; 2780 | sha256 = "0bhdgfb0pmw9mav1kw9fn0ka012sa0i3h5ppvqssw5xq48nhxnr8"; 2781 | type = "gem"; 2782 | }; 2783 | version = "0.2.25"; 2784 | }; 2785 | stoplight = { 2786 | dependencies = ["redlock"]; 2787 | groups = ["default"]; 2788 | platforms = []; 2789 | source = { 2790 | remotes = ["https://rubygems.org"]; 2791 | sha256 = "0rmhhqvvrn7874r9cjf4wpv36vnxvxsrgb1kfgdk3dalg4rig7q6"; 2792 | type = "gem"; 2793 | }; 2794 | version = "3.0.1"; 2795 | }; 2796 | strong_migrations = { 2797 | dependencies = ["activerecord"]; 2798 | groups = ["default"]; 2799 | platforms = []; 2800 | source = { 2801 | remotes = ["https://rubygems.org"]; 2802 | sha256 = "0wz4zhsp4xia8zcpi98v4sgjlv2prd515l8jz4f7j0wk45dfkjs1"; 2803 | type = "gem"; 2804 | }; 2805 | version = "0.8.0"; 2806 | }; 2807 | swd = { 2808 | dependencies = ["activesupport" "attr_required" "httpclient"]; 2809 | groups = ["default"]; 2810 | platforms = []; 2811 | source = { 2812 | remotes = ["https://rubygems.org"]; 2813 | sha256 = "12b3q2sw42nnilfb51nlqdv07f31vdv2j595kd99asnkw4cjlf5w"; 2814 | type = "gem"; 2815 | }; 2816 | version = "1.3.0"; 2817 | }; 2818 | sysexits = { 2819 | groups = ["default" "development"]; 2820 | platforms = []; 2821 | source = { 2822 | remotes = ["https://rubygems.org"]; 2823 | sha256 = "0qjng6pllznmprzx8vb0zg0c86hdrkyjs615q41s9fjpmv2430jr"; 2824 | type = "gem"; 2825 | }; 2826 | version = "1.2.0"; 2827 | }; 2828 | temple = { 2829 | groups = ["default" "development"]; 2830 | platforms = []; 2831 | source = { 2832 | remotes = ["https://rubygems.org"]; 2833 | sha256 = "09p32vp94sa1mbr0if0adf02yzc4ns00lsmpwns2xbkncwpzrqm4"; 2834 | type = "gem"; 2835 | }; 2836 | version = "0.10.2"; 2837 | }; 2838 | terminal-table = { 2839 | dependencies = ["unicode-display_width"]; 2840 | groups = ["default" "development"]; 2841 | platforms = []; 2842 | source = { 2843 | remotes = ["https://rubygems.org"]; 2844 | sha256 = "14dfmfjppmng5hwj7c5ka6qdapawm3h6k9lhn8zj001ybypvclgr"; 2845 | type = "gem"; 2846 | }; 2847 | version = "3.0.2"; 2848 | }; 2849 | terrapin = { 2850 | dependencies = ["climate_control"]; 2851 | groups = ["default"]; 2852 | platforms = []; 2853 | source = { 2854 | remotes = ["https://rubygems.org"]; 2855 | sha256 = "0p18f05r0c5s70571gqig3z2ym74wx79s6rd45sprp207bqskzn9"; 2856 | type = "gem"; 2857 | }; 2858 | version = "0.6.0"; 2859 | }; 2860 | thor = { 2861 | groups = ["default" "development" "pam_authentication" "production" "test"]; 2862 | platforms = []; 2863 | source = { 2864 | remotes = ["https://rubygems.org"]; 2865 | sha256 = "0k7j2wn14h1pl4smibasw0bp66kg626drxb59z7rzflch99cd4rg"; 2866 | type = "gem"; 2867 | }; 2868 | version = "1.2.2"; 2869 | }; 2870 | tilt = { 2871 | groups = ["default" "development"]; 2872 | platforms = []; 2873 | source = { 2874 | remotes = ["https://rubygems.org"]; 2875 | sha256 = "0bmjgbv8158klwp2r3klxjwaj93nh1sbl4xvj9wsha0ic478avz7"; 2876 | type = "gem"; 2877 | }; 2878 | version = "2.2.0"; 2879 | }; 2880 | timeout = { 2881 | groups = ["default" "development"]; 2882 | platforms = []; 2883 | source = { 2884 | remotes = ["https://rubygems.org"]; 2885 | sha256 = "1d9cvm0f4zdpwa795v3zv4973y5zk59j7s1x3yn90jjrhcz1yvfd"; 2886 | type = "gem"; 2887 | }; 2888 | version = "0.4.0"; 2889 | }; 2890 | tpm-key_attestation = { 2891 | dependencies = ["bindata" "openssl" "openssl-signature_algorithm"]; 2892 | groups = ["default"]; 2893 | platforms = []; 2894 | source = { 2895 | remotes = ["https://rubygems.org"]; 2896 | sha256 = "0v8y5dibsyskv1ncdgszhxwzq0gzmvb0zl7sgmx0xvsgy86dhcz1"; 2897 | type = "gem"; 2898 | }; 2899 | version = "0.12.0"; 2900 | }; 2901 | tty-color = { 2902 | groups = ["default"]; 2903 | platforms = []; 2904 | source = { 2905 | remotes = ["https://rubygems.org"]; 2906 | sha256 = "0aik4kmhwwrmkysha7qibi2nyzb4c8kp42bd5vxnf8sf7b53g73g"; 2907 | type = "gem"; 2908 | }; 2909 | version = "0.6.0"; 2910 | }; 2911 | tty-cursor = { 2912 | groups = ["default"]; 2913 | platforms = []; 2914 | source = { 2915 | remotes = ["https://rubygems.org"]; 2916 | sha256 = "0j5zw041jgkmn605ya1zc151bxgxl6v192v2i26qhxx7ws2l2lvr"; 2917 | type = "gem"; 2918 | }; 2919 | version = "0.7.1"; 2920 | }; 2921 | tty-prompt = { 2922 | dependencies = ["pastel" "tty-reader"]; 2923 | groups = ["default"]; 2924 | platforms = []; 2925 | source = { 2926 | remotes = ["https://rubygems.org"]; 2927 | sha256 = "1j4y8ik82azjxshgd4i1v4wwhsv3g9cngpygxqkkz69qaa8cxnzw"; 2928 | type = "gem"; 2929 | }; 2930 | version = "0.23.1"; 2931 | }; 2932 | tty-reader = { 2933 | dependencies = ["tty-cursor" "tty-screen" "wisper"]; 2934 | groups = ["default"]; 2935 | platforms = []; 2936 | source = { 2937 | remotes = ["https://rubygems.org"]; 2938 | sha256 = "1cf2k7w7d84hshg4kzrjvk9pkyc2g1m3nx2n1rpmdcf0hp4p4af6"; 2939 | type = "gem"; 2940 | }; 2941 | version = "0.9.0"; 2942 | }; 2943 | tty-screen = { 2944 | groups = ["default"]; 2945 | platforms = []; 2946 | source = { 2947 | remotes = ["https://rubygems.org"]; 2948 | sha256 = "18jr6s1cg8yb26wzkqa6874q0z93rq0y5aw092kdqazk71y6a235"; 2949 | type = "gem"; 2950 | }; 2951 | version = "0.8.1"; 2952 | }; 2953 | twitter-text = { 2954 | dependencies = ["idn-ruby" "unf"]; 2955 | groups = ["default"]; 2956 | platforms = []; 2957 | source = { 2958 | remotes = ["https://rubygems.org"]; 2959 | sha256 = "1dnmp0bj3l01nbb52zby2c7hrazcdwfg846knkrjdfl0yfmv793z"; 2960 | type = "gem"; 2961 | }; 2962 | version = "3.1.0"; 2963 | }; 2964 | tzinfo = { 2965 | dependencies = ["concurrent-ruby"]; 2966 | groups = ["default" "development" "pam_authentication" "production" "test"]; 2967 | platforms = []; 2968 | source = { 2969 | remotes = ["https://rubygems.org"]; 2970 | sha256 = "16w2g84dzaf3z13gxyzlzbf748kylk5bdgg3n1ipvkvvqy685bwd"; 2971 | type = "gem"; 2972 | }; 2973 | version = "2.0.6"; 2974 | }; 2975 | tzinfo-data = { 2976 | dependencies = ["tzinfo"]; 2977 | groups = ["default"]; 2978 | platforms = []; 2979 | source = { 2980 | remotes = ["https://rubygems.org"]; 2981 | sha256 = "0m2d0gpsgqnv29j5h2d6g57g0rayvd460b8s2vjr8sn46bqf89m5"; 2982 | type = "gem"; 2983 | }; 2984 | version = "1.2023.3"; 2985 | }; 2986 | unf = { 2987 | dependencies = ["unf_ext"]; 2988 | groups = ["default"]; 2989 | platforms = []; 2990 | source = { 2991 | remotes = ["https://rubygems.org"]; 2992 | sha256 = "0bh2cf73i2ffh4fcpdn9ir4mhq8zi50ik0zqa1braahzadx536a9"; 2993 | type = "gem"; 2994 | }; 2995 | version = "0.1.4"; 2996 | }; 2997 | unf_ext = { 2998 | groups = ["default"]; 2999 | platforms = []; 3000 | source = { 3001 | remotes = ["https://rubygems.org"]; 3002 | sha256 = "1yj2nz2l101vr1x9w2k83a0fag1xgnmjwp8w8rw4ik2rwcz65fch"; 3003 | type = "gem"; 3004 | }; 3005 | version = "0.0.8.2"; 3006 | }; 3007 | unicode-display_width = { 3008 | groups = ["default" "development"]; 3009 | platforms = []; 3010 | source = { 3011 | remotes = ["https://rubygems.org"]; 3012 | sha256 = "1gi82k102q7bkmfi7ggn9ciypn897ylln1jk9q67kjhr39fj043a"; 3013 | type = "gem"; 3014 | }; 3015 | version = "2.4.2"; 3016 | }; 3017 | uri = { 3018 | groups = ["default"]; 3019 | platforms = []; 3020 | source = { 3021 | remotes = ["https://rubygems.org"]; 3022 | sha256 = "0fa49cdssxllj1j37a56kq27wsibx5lmqxkqdk1rz3452y0bsydy"; 3023 | type = "gem"; 3024 | }; 3025 | version = "0.12.2"; 3026 | }; 3027 | validate_email = { 3028 | dependencies = ["activemodel" "mail"]; 3029 | groups = ["default"]; 3030 | platforms = []; 3031 | source = { 3032 | remotes = ["https://rubygems.org"]; 3033 | sha256 = "1r1fz29l699arka177c9xw7409d1a3ff95bf7a6pmc97slb91zlx"; 3034 | type = "gem"; 3035 | }; 3036 | version = "0.1.6"; 3037 | }; 3038 | validate_url = { 3039 | dependencies = ["activemodel" "public_suffix"]; 3040 | groups = ["default"]; 3041 | platforms = []; 3042 | source = { 3043 | remotes = ["https://rubygems.org"]; 3044 | sha256 = "0lblym140w5n88ijyfgcvkxvpfj8m6z00rxxf2ckmmhk0x61dzkj"; 3045 | type = "gem"; 3046 | }; 3047 | version = "1.0.15"; 3048 | }; 3049 | warden = { 3050 | dependencies = ["rack"]; 3051 | groups = ["default" "pam_authentication"]; 3052 | platforms = []; 3053 | source = { 3054 | remotes = ["https://rubygems.org"]; 3055 | sha256 = "1l7gl7vms023w4clg02pm4ky9j12la2vzsixi2xrv9imbn44ys26"; 3056 | type = "gem"; 3057 | }; 3058 | version = "1.2.9"; 3059 | }; 3060 | webauthn = { 3061 | dependencies = ["android_key_attestation" "awrence" "bindata" "cbor" "cose" "openssl" "safety_net_attestation" "tpm-key_attestation"]; 3062 | groups = ["default"]; 3063 | platforms = []; 3064 | source = { 3065 | remotes = ["https://rubygems.org"]; 3066 | sha256 = "1ri09bf640kkw4v6k2g90q2nw1mx2hsghhngaqgb7958q8id8xrz"; 3067 | type = "gem"; 3068 | }; 3069 | version = "3.0.0"; 3070 | }; 3071 | webfinger = { 3072 | dependencies = ["activesupport" "httpclient"]; 3073 | groups = ["default"]; 3074 | platforms = []; 3075 | source = { 3076 | remotes = ["https://rubygems.org"]; 3077 | sha256 = "18jj50b44a471ig7hw1ax90wxaaz40acmrf6cm7m2iyshlffy53q"; 3078 | type = "gem"; 3079 | }; 3080 | version = "1.2.0"; 3081 | }; 3082 | webmock = { 3083 | dependencies = ["addressable" "crack" "hashdiff"]; 3084 | groups = ["test"]; 3085 | platforms = []; 3086 | source = { 3087 | remotes = ["https://rubygems.org"]; 3088 | sha256 = "1myj44wvbbqvv18ragv3ihl0h61acgnfwrnj3lccdgp49bgmbjal"; 3089 | type = "gem"; 3090 | }; 3091 | version = "3.18.1"; 3092 | }; 3093 | webpacker = { 3094 | dependencies = ["activesupport" "rack-proxy" "railties" "semantic_range"]; 3095 | groups = ["default"]; 3096 | platforms = []; 3097 | source = { 3098 | remotes = ["https://rubygems.org"]; 3099 | sha256 = "0fh4vijqiq1h7w28llk67y9csc0m4wkdivrsl4fsxg279v6j5z3i"; 3100 | type = "gem"; 3101 | }; 3102 | version = "5.4.4"; 3103 | }; 3104 | webpush = { 3105 | dependencies = ["hkdf" "jwt"]; 3106 | groups = ["default"]; 3107 | platforms = []; 3108 | source = { 3109 | fetchSubmodules = false; 3110 | rev = "f14a4d52e201128b1b00245d11b6de80d6cfdcd9"; 3111 | sha256 = "1gz34809xwyaqprxmjdyvzsxc63rdnmxn8w44iqkhpi3dzmkacmp"; 3112 | type = "git"; 3113 | url = "https://github.com/ClearlyClaire/webpush.git"; 3114 | }; 3115 | version = "0.3.8"; 3116 | }; 3117 | websocket-driver = { 3118 | dependencies = ["websocket-extensions"]; 3119 | groups = ["default"]; 3120 | platforms = []; 3121 | source = { 3122 | remotes = ["https://rubygems.org"]; 3123 | sha256 = "0a3bwxd9v3ghrxzjc4vxmf4xa18c6m4xqy5wb0yk5c6b9psc7052"; 3124 | type = "gem"; 3125 | }; 3126 | version = "0.7.5"; 3127 | }; 3128 | websocket-extensions = { 3129 | groups = ["default"]; 3130 | platforms = []; 3131 | source = { 3132 | remotes = ["https://rubygems.org"]; 3133 | sha256 = "0hc2g9qps8lmhibl5baa91b4qx8wqw872rgwagml78ydj8qacsqw"; 3134 | type = "gem"; 3135 | }; 3136 | version = "0.1.5"; 3137 | }; 3138 | wisper = { 3139 | groups = ["default"]; 3140 | platforms = []; 3141 | source = { 3142 | remotes = ["https://rubygems.org"]; 3143 | sha256 = "1rpsi0ziy78cj82sbyyywby4d0aw0a5q84v65qd28vqn79fbq5yf"; 3144 | type = "gem"; 3145 | }; 3146 | version = "2.0.1"; 3147 | }; 3148 | xorcist = { 3149 | groups = ["default"]; 3150 | platforms = []; 3151 | source = { 3152 | remotes = ["https://rubygems.org"]; 3153 | sha256 = "1dbbiy8xlcfvn9ais37xfb5rci4liwakkmxzbkp72wmvlgcrf339"; 3154 | type = "gem"; 3155 | }; 3156 | version = "1.1.3"; 3157 | }; 3158 | xpath = { 3159 | dependencies = ["nokogiri"]; 3160 | groups = ["default" "test"]; 3161 | platforms = []; 3162 | source = { 3163 | remotes = ["https://rubygems.org"]; 3164 | sha256 = "0bh8lk9hvlpn7vmi6h4hkcwjzvs2y0cmkk3yjjdr8fxvj6fsgzbd"; 3165 | type = "gem"; 3166 | }; 3167 | version = "3.2.0"; 3168 | }; 3169 | zeitwerk = { 3170 | groups = ["default" "development" "pam_authentication" "production" "test"]; 3171 | platforms = []; 3172 | source = { 3173 | remotes = ["https://rubygems.org"]; 3174 | sha256 = "0ck6bj7wa73dkdh13735jl06k6cfny98glxjkas82aivlmyzqqbk"; 3175 | type = "gem"; 3176 | }; 3177 | version = "2.6.8"; 3178 | }; 3179 | } 3180 | 3181 | -------------------------------------------------------------------------------- /versions/mastodon/glitch-a004718/name.nix: -------------------------------------------------------------------------------- 1 | "glitch-a004718" 2 | -------------------------------------------------------------------------------- /versions/mastodon/glitch-a004718/source.nix: -------------------------------------------------------------------------------- 1 | # This file was generated by minifedi mk-mastodon. 2 | { fetchgit, applyPatches }: fetchgit { 3 | url = "https://github.com/glitch-soc/Mastodon.git"; 4 | rev = "a004718"; 5 | sha256 = "09i3y408dv5bp1axqnn1v25yg5l9hqj85x524bai5a186wh0pcqh"; 6 | } 7 | -------------------------------------------------------------------------------- /versions/mastodon/glitch-a004718/yarn-hash.nix: -------------------------------------------------------------------------------- 1 | "095dcrfc01ywk1g4mq7irm7jm0zzawapacfmbm5b7cv929pvbkkd" 2 | -------------------------------------------------------------------------------- /versions/mastodon/mastodon-4.1.4/name.nix: -------------------------------------------------------------------------------- 1 | "mastodon-4.1.4" 2 | -------------------------------------------------------------------------------- /versions/mastodon/mastodon-4.1.4/source.nix: -------------------------------------------------------------------------------- 1 | # This file was generated by minifedi mk-mastodon. 2 | { fetchgit, applyPatches }: fetchgit { 3 | url = "https://github.com/Mastodon/Mastodon.git"; 4 | rev = "v4.1.4"; 5 | sha256 = "170xjvd5m6cmlamq0pw3nd3dnxjcmmvxw5yqwp11rh0xq8xw2hpi"; 6 | } 7 | -------------------------------------------------------------------------------- /versions/mastodon/mastodon-4.1.4/yarn-hash.nix: -------------------------------------------------------------------------------- 1 | "1q2wy0l04796p3h4d3j11ciyxrjadj6vw61ig0fsapcadgyyaykv" 2 | --------------------------------------------------------------------------------